functiile procesului solar

Upload: avramus

Post on 06-Jan-2016

243 views

Category:

Documents


0 download

DESCRIPTION

curs

TRANSCRIPT

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