functiile procesului solar
DESCRIPTION
cursTRANSCRIPT
Option Private Module
Funciile procesului solar
Option Private Module
' Funciile procesului solar
'*****************************************************************************************************************
' Constante
Public Const SOLAR_CONST = 1367# ' constanta solar [W/m2]Public Const Pi = 3.14159265359 ' piPublic Const MEGA = 1000000# ' un milionPublic Const DTOR = Pi / 180# ' factor de conversie grade n radianiPublic Const RTOD = 180# / Pi ' factor de conversie radiani n grade' Moduri de urmrire
Private Const TR_NONE = 0
Private Const TR_1_AXIS = 1
Private Const TR_2_AXIS = 2
Private Const TR_AZIMUTH = 3
'*****************************************************************************************************************
' arc cosinus
Function Acos(x)
If (x > 0.9999995) Then
Acos = 0
ElseIf (x < -0.9999995) Then
Acos = Pi
Else
Acos = Atn(-x / Sqr(-x * x + 1)) + 1.5708
End If
End Function
'*****************************************************************************************************************
' arc tangent 2 - returneaz arc tangent de y/x, n domeniul [-pi,pi]
Function Atan2(x, y)
' Calcul arc tangent
If (Abs(x) < 0.0000005) Then
If (y > 0) Then
Atan2 = Pi / 2#
Else
Atan2 = -Pi / 2#
End If
Else
Atan2 = Atn(y / x)
' Calcul cadran
If (x < 0) Then
If (y < 0) Then
Atan2 = Atan2 - Pi
Else
Atan2 = Atan2 + Pi
End If
End If
End If
End Function
'*****************************************************************************************************************
1. Y12=GetDeclination(X12) apelul funciei
( Declinaie [radiani]
' nDay = X12 // (i) ziua anuluiFunction GetDeclination(nDay)
GetDeclination = DTOR * 23.45 * Sin(2# * Pi * (284# + nDay) / 365#)
End Function
'*****************************************************************************************************************
2. Z12=GetAlbedo(H12) apelul funciei( Calcul albedo pe baza temperaturii medii
' Adoptam pentru albedo valoarea 0.7 daca temperatura < -5C si 0.2 peste 0 si o interpolare lineara intre aceste valori
Temp = H12
Function GetAlbedo(Temp)
Const LowTemp = -5
Const LowAlbedo = 0.7
Const HighTemp = 0
Const HighAlbedo = 0.2
If (Temp < LowTemp) Then
GetAlbedo = LowAlbedo
ElseIf (Temp > HighTemp) Then
GetAlbedo = HighAlbedo
Else
GetAlbedo = (LowAlbedo * (HighTemp - Temp) + HighAlbedo * (Temp - LowTemp)) / (HighTemp - LowTemp)
End If
End Function
'*****************************************************************************************************************
3. AA12=getsunsethourangle(Lat_rad;Y12) apelul funciei' Unghiul orei apusului (s [radiani]
' Lat = Lat_rad // (i) latitudinea staiei [radian]
' Decl = Y12 // (i) declinaia staiei [radian]
Function GetSunsetHourAngle(Lat, Decl)
CosSunset = -Tan(Lat) * Tan(Decl)
If (CosSunset > 1#) Then
GetSunsetHourAngle = 0#
ElseIf (CosSunset < -1#) Then
GetSunsetHourAngle = Pi
Else
GetSunsetHourAngle = Acos(CosSunset)
End If
End Function
'*****************************************************************************************************************
4.1 AC12=GetNExtra(X12)/1000 apelul funciei' Iradiaia extraterestr normal [W/m2]
' nDay // (i) ziua anului
Function GetNExtra(nDay)
GetNExtra = SOLAR_CONST * (1# + 0.033 * Cos(2# * Pi * nDay / 365#))
End Function
'*****************************************************************************************************************
4. AD12=GetHExtra_integ(AA12; Lat_rad; Y12; GetNExtra(X12))/1000000 apelul funciei' H0 Iradiaia extraterestr pe o suprafa orizontal integrat de la unghiul orar -w la unghiul orar w.
w = AA12 // unghiul orar al apusului
Lat = Lat_rad // latitudinea
Decl = Y12 // declianatia
Nextra = GetNExtra(X12)/1000000
Function GetHExtra_integ (w, Lat, Decl, NExtra)
HExtra = Sin(Decl) * Sin(Lat) * w + Cos(Decl) * Cos(Lat) * Sin(w)
HExtra = HExtra * NExtra * 86400# / 2# / Pi
GetHExtra_integ = 2# * HExtra
End Function
'*****************************************************************************************************************
5.1 Call CalcSunPositionHourAngle(SunZenith, SunAzimuth, Decl, HAngle, Lat) apelul procedurii
' Poziia soarelui: zenit i azimut funcie de declinaie i unghiul orar
' Not: n Braun i Mitchell, convenia pentru unghiul azimutului solar este:
' punctele aproape de ecuator si pozitiv spre vest. Pentru un punct
' aflat la ecuator 0 points south. In emisfera nordica aceasta
' conventie este echivalenta cu cea din SCL. In emisfera sudica
' Azimuth_SCL = PI - Azimuth_BM (modulo 2*PI), prin urmare sinAzimuth este
' acelasi cosAzimuth isi schimba semnul
'
' void CalcSunPositionHourAngle
' double *Zenith = SunZenith /* (o) unghiul zenital solar [radian] */
' double *Azimuth = SunAzimuth /* (o) unghiul azimutal solar [radian] */
' double Decl = Decl /* (i) declinaie [radian] */
' double HourAngle = HAngle /* (i) unghiul orar [radian] */
' double Lat = Lat /* (i) latitudine [radian] */
Sub CalcSunPositionHourAngle (Zenith As Double, Azimuth As Double, Decl As Double, HourAngle As Double, Lat As Double)
' Declaraii
Dim cosZenith As Double, sinAzimuth As Double, cosAzimuth As Double
' Calcul unghi zenital
cosZenith = Cos(Lat) * Cos(Decl) * Cos(HourAngle) + Sin(Lat) * Sin(Decl)
If (cosZenith > 1#) Then cosZenith = 1#
If (cosZenith < -1#) Then cosZenith = -1#
Zenith = Acos(cosZenith)
' Calcul unghi azimutal
sinAzimuth = Sin(HourAngle) * Cos(Decl)
cosAzimuth = Cos(HourAngle) * Cos(Decl) * Sin(Lat) - Sin(Decl) * Cos(Lat)
Azimuth = Atan2(cosAzimuth, sinAzimuth)
End Sub
'*****************************************************************************************************************
5.2.1 BMAzimuth(SunAzimuth, Lat) sau BMAzimuth(TrackAzimuth, Lat) apelul funciei' Aceast funcie convertete unghiurile din convenia SCL convention n convenia Braun and Mitchell
' Reversul conversiei este identic cu conversia direct
Function BMAzimuth(Azimuth As Double, Lat As Double) As Double
Azimutul dup Braun i Mitchell este egal cu azimutul SCL n nord, pi minus azimutul SCL n sud
If (Lat >= 0) Then
BMAzimuth = Azimuth
Else
BMAzimuth = Pi - Azimuth
End If
' Azimutul trebuie s fie ntre -pi i pi
While (BMAzimuth < -Pi)
BMAzimuth = BMAzimuth + 2# * Pi
Wend
While (BMAzimuth > Pi)
BMAzimuth = BMAzimuth - 2# * Pi
Wend
End Function
'*****************************************************************************************************************
5.2.2 GetCosIncidenceAngle(SunZenith, SunAzimuth, SurfSlope, SurfAzimuth) apelul funciei
' Cosinusul unghiului de inciden pe o suprafa nclinat cu orice orientare
Function GetCosIncidenceAngle (SunZenith, SunAzimuth, SurfaceSlope, SurfaceAzimuth)
CosInc = Cos(SunZenith) * Cos(SurfaceSlope) + Sin(SunZenith) * Sin(SurfaceSlope) * Cos(SunAzimuth - SurfaceAzimuth)
CosInc = Application.Min(CosInc, 1#)
CosInc = Application.Max(CosInc, -1#)
GetCosIncidenceAngle = CosInc
End Function
'*****************************************************************************************************************
5.2 Call Track(SurfSlope, SurfAzimuth, cosIncidenceAngle, SunZenith, SunAzimuth, Mode, TrackSlope, TrackAzim, Lat)' Calculul pantei suprafeei, azimutul i unghiul de inciden pentru diferite suprafae fixe sau de urmrire
' double SurfSlope /* (o) Panta suprafeei de urmrire */
' double SurfAzimuth /* (o) Azimutul suprafeei de urmrire */
' double cosIncidenceAngle /* (o) Cosinusul unghiului de inciden al radiaiei directe pe suprafaa de urmrire */
' double SunZenith /* (i) Unghiul zenital solar [radian] */
' double SunAzimuth /* (i) Unghiul azimutal slar [radian] */
' int Mode /* (i) Modul de urmrire */
' double TrackSlope /* (i) Panta axei de urmrire [radian] */
' double TrackAzimuth /* (i) Azimutul axei de urmrire [radian] */
Sub Track (SurfSlope As Double, SurfAzimuth As Double, cosIncidenceAngle As Double, SunZenith As Double, SunAzimuth _
As Double, Mode As Integer, TrackSlope As Double, TrackAzimuth As Double, Lat As Double)
' Conversie a azimutului n convenia Braun i Mitchell
Dim BMSurfAzimuth As Double, BMSunAzimuth As Double, BMTrackAzimuth As Double
BMSunAzimuth = BMAzimuth(SunAzimuth, Lat)
BMTrackAzimuth = BMAzimuth(TrackAzimuth, Lat)
Select Case Mode
' Fr urmrire
Case TR_NONE:
SurfSlope = TrackSlope
BMSurfAzimuth = BMTrackAzimuth
' O singur ax urmrit
Case TR_1_AXIS:
' Axa orizontal
If (TrackSlope = 0#) Then
' Prima dat se convertete unghiul pentru valori ntre -pi/2 i pi/2
While (BMTrackAzimuth < -Pi / 2#)
BMTrackAzimuth = BMTrackAzimuth + Pi
Wend
While (BMTrackAzimuth > Pi / 2#)
BMTrackAzimuth = BMTrackAzimuth - Pi
Wend
If (BMSunAzimuth >= BMTrackAzimuth) Then
BMSurfAzimuth = BMTrackAzimuth + Pi / 2
Else
BMSurfAzimuth = BMTrackAzimuth - Pi / 2
End If
SurfSlope = Atn(Tan(SunZenith) * Cos(BMSurfAzimuth - BMSunAzimuth))
If (SurfSlope < 0#) Then
' SurfSlope = SurfSlope + Pi
SurfSlope = -SurfSlope
End If
' Ax nclinat, suprafaa paralel cu axa
Else
Dim Aux As Double
Aux = GetCosIncidenceAngle(SunZenith, BMSunAzimuth, TrackSlope, BMTrackAzimuth)
BMSurfAzimuth = BMTrackAzimuth + Atn(Sin(SunZenith) * Sin(BMSunAzimuth - BMTrackAzimuth) / Aux / Sin(TrackSlope))
If ((BMSurfAzimuth - BMTrackAzimuth) * (BMSunAzimuth - BMTrackAzimuth) < 0) Then
If (BMSunAzimuth >= BMTrackAzimuth) Then
BMSurfAzimuth = BMSurfAzimuth + Pi
Else
BMBMSurfAzimuth = BMSurfAzimuth - Pi
End If
End If
SurfSlope = Atn(Tan(TrackSlope) / Cos(BMSurfAzimuth - BMTrackAzimuth))
If (SurfSlope < 0#) Then
SurfSlope = SurfSlope + Pi
End If
End If
' Azimutul urmriri (axa vartical)
Case TR_AZIMUTH:
SurfSlope = TrackSlope
BMSurfAzimuth = BMSunAzimuth
' Urmarire n doua axe
Case TR_2_AXIS:
SurfSlope = SunZenith
BMSurfAzimuth = BMSunAzimuth
' n caz de eroare
Case Else:
MsgBox "Error: invalid tracking value"
End Select
' Conversie la convenia SCL
SurfAzimuth = BMAzimuth(BMSurfAzimuth, Lat)
' Calculul unghiului de inciden
cosIncidenceAngle = GetCosIncidenceAngle(SunZenith, SunAzimuth, SurfSlope, SurfAzimuth)
End Sub
'*****************************************************************************************************************
5. AG12=GetMonthlyTrackingRadiation(Lat_rad;TrackModeIndex;Slope_rad;Azim_rad;X12;AE12*1000000;Z12) /1000000
' Calculul mediei lunare a radiaiei zilnice pe o suprafa nclinat, given the monthly mean
' se dau media lunar a radiaiei zilnice pe o suprafa orizontal, numrul de luni,
' albedo, modul de urmrire i orientara suprafeei de urmrire
' GetMonthlyTrackingRadiation /* media lunar a radiaiei zilnice pe o suprafa de urmrire [J] */' double Lat = Lat_rad /* latitudine [radian] */
' int Mode = TrackModeIndex /* mod de urmrire */
' double TrackSlope = Slope_rad /* panta urmririi [radian] */
' double TrackAzim = Azim_rad /* azimutul urmririi [radian] */
' int Day = X12 /* ziua medie a lunii */
' double Hglobar = AE12*1000000 /* media lunar a radiaiei zilnice pe o suprafa [J] */
' double Albedobar = Z12 /* medie lunar a albedo [0-1] */
Function GetMonthlyTrackingRadiation (Lat As Double, Mode As Integer, TrackSlope As Double, TrackAzim As Double, Day As _ Integer, Hglobar As Double, Albedobar As Double)
' ( Calcul declinaie Dim Decl As Double
Decl = GetDeclination(Day)
' (s Calcul unghi orar apus [radian] Dim Sunset As Double
Sunset = GetSunsetHourAngle(Lat, Decl)
' H0 Calcul Hextra radiaie extraterestr zilnic
Dim HExtra As Double
HExtra = GetNExtra(Day) * 24 * 3600# / Pi * (Cos(Lat) * Cos(Decl) * Sin(Sunset) + Sunset * Sin(Lat) * Sin(Decl))
' Calcul Ktbar medie lunar a indicelui de luminozitate
Dim KTbar As Double
If (HExtra > 0#) Then
KTbar = Hglobar / HExtra
Else
KTbar = 0.8
End If
' Algoritm de corecie empiric, cnd (KTbar) este n afara domeniului [0.3,0.8]:
' Calcul (Hdirbar) presupunnd Hbar = HExtra*KTbar, apoi Hdifbar ca Hbar - Hdirbar.
' Aceast corecie este necesar pentru lunile apropiate de noaptea polar deasupra cercului polar, unde metoda zilei medii nu poate prezice
o valoare destul de mare a (HExtra), prin urmare conduce spre valori foarte mari ale lui (KTbar)
' Corecia lui Ktbar pentru valori n afara domeniului
If (KTbar > 0.8) Then KTbar = 0.8
If (KTbar < 0.3) Then KTbar = 0.3
' Calcul Hdirbar radiaia direct orizontal corespunzatoare lui KTbar, apoi radiaia difuz = radiaia global - radiaia direct
pentru (s < 81,40
pentru (s > 81,40 Dim Hdifbar As Double, Hdirbar As Double
If (Sunset 0#) Then
Dim rd As Double, rt As Double
rd = Pi / 24# * (cosHAngle - CosSunset) / Den
rt = rd * (a + b * cosHAngle)
Hglo(h) = rt
Hdif(h) = rd
rttot = rttot + rt
rdtot = rdtot + rd
Else
Hglo(h) = 0#
Hdif(h) = 0#
End If
Next h
' Calculul matricelor celor 24 de valori ale radiaiei globale, difuze i directe zilnice
For h = 0 To 23
If (rttot > 0#) Then Hglo(h) = Hglo(h) * Hglobar / rttot
If (rdtot > 0#) Then Hdif(h) = Hdif(h) * Hdifbar / rdtot
Hdir(h) = Hglo(h) - Hdif(h)
Next h
Dim Tglobar As Double
Tglobar = 0#
' Calculul celor 24 de valori ale radiaiei pe planul nclinat i nsumarea acestora
For h = 0 To 23
' Calculul poziiei soarelui
Dim SunZenith As Double, SunAzimuth As Double
HAngle = DTOR * 15# * (h + 0.5 - 12#)
Call CalcSunPositionHourAngle(SunZenith, SunAzimuth, Decl, HAngle, Lat)
' Cazul n care Soarele este sub orizont
If (SunZenith < Pi / 2#) Then
' Calculul orientrii suprafeei
Dim SurfSlope As Double, SurfAzimuth As Double, cosIncidenceAngle As Double
Call Track(SurfSlope, SurfAzimuth, cosIncidenceAngle, SunZenith, SunAzimuth, Mode, TrackSlope, TrackAzim, Lat)
' Calcul Rbbar
Dim rb As Double
rb = cosIncidenceAngle / Cos(SunZenith)
If (rb < 0#) Then rb = 0#
' Calculul radiaiei pe planul nclinat
Tglobar = Tglobar + Hdir(h) * rb + Hdif(h) * (1# + Cos(SurfSlope)) / 2# + Albedobar * Hglo(h) * (1# - Cos(SurfSlope)) / 2#
End If
Next h
' Cazul nopii polare: Tglobar = 0
If (Tglobar = 0#) Then
Tglobar = Hglobar
End If
' ntoarce valoarea GetMonthlyTrackingRadiation = Tglobar
End Function
'*****************************************************************************************************************
6. AH12=GetDailyDiffuseFraction(AF12)' Calculul fraciuni de radiaie difuz zilnic, cunoscnd indicele de luminozitate zilnic
Function GetDailyDiffuseFraction(DailyClearnessIndex)
kt = DailyClearnessIndex
If (kt 1#) Then GetHourlyToDailyTotalRadRatio = 1#
End Function
'*****************************************************************************************************************
11. BB12=GetHourlyToDailyDiffuseRadRatio(0;AA12)
' rd,n Calculul raportului dintre radiaia difuz orar i zilnic (cnd soarle este la amiaz, ( = 0)
Function GetHourlyToDailyDiffuseRadRatio(HourAngle, SunsetHourAngle)
If (HourAngle < SunsetHourAngle) Then
sinSunset = Sin(SunsetHourAngle)
CosSunset = Cos(SunsetHourAngle)
cosHAngle = Cos(HourAngle)
GetHourlyToDailyDiffuseRadRatio = Pi / 24 * (cosHAngle - CosSunset) / (sinSunset - SunsetHourAngle * CosSunset)
If (GetHourlyToDailyDiffuseRadRatio > 1#) Then GetHourlyToDailyDiffuseRadRatio = 1#
Else
GetHourlyToDailyDiffuseRadRatio = 1#
End If
End Function
'*****************************************************************************************************************
_1175794285.unknown
_1178456831.unknown
_1178462792.unknown
_1178990422.unknown
_1178994150.unknown
_1178985641.unknown
_1178985414.unknown
_1178458532.unknown
_1178457709.unknown
_1178458215.unknown
_1175795251.unknown
_1178391606.unknown
_1175795011.unknown
_1175795075.unknown
_1175794351.unknown
_1175791633.unknown
_1175793830.unknown
_1175794129.unknown
_1175793471.unknown
_1175723195.unknown
_1175791028.unknown
_1175791579.unknown
_1175720445.unknown