20
20
from pvlib import solarposition
21
21
22
22
23
- def ineichen (time , latitude , longitude , altitude = 0 , linke_turbidity = None ,
24
- solarposition_method = 'nrel_numpy' , zenith_data = None ,
25
- airmass_model = 'young1994' , airmass_data = None ,
26
- interp_turbidity = True ):
23
+ def ineichen (apparent_zenith , airmass_absolute , linke_turbidity ,
24
+ dni_extra = 1364. , altitude = 0 ):
27
25
'''
28
- Determine clear sky GHI, DNI, and DHI from Ineichen/Perez model
26
+ Determine clear sky GHI, DNI, and DHI from Ineichen/Perez model.
29
27
30
- Implements the Ineichen and Perez clear sky model for global horizontal
31
- irradiance (GHI), direct normal irradiance (DNI), and calculates
32
- the clear-sky diffuse horizontal (DHI) component as the difference
33
- between GHI and DNI*cos(zenith) as presented in [1, 2]. A report on clear
34
- sky models found the Ineichen/Perez model to have excellent performance
35
- with a minimal input data set [3].
28
+ Implements the Ineichen and Perez clear sky model for global
29
+ horizontal irradiance (GHI), direct normal irradiance (DNI), and
30
+ calculates the clear-sky diffuse horizontal (DHI) component as the
31
+ difference between GHI and DNI*cos(zenith) as presented in [1, 2]. A
32
+ report on clear sky models found the Ineichen/Perez model to have
33
+ excellent performance with a minimal input data set [3].
36
34
37
35
Default values for montly Linke turbidity provided by SoDa [4, 5].
38
36
39
37
Parameters
40
38
-----------
41
- time : pandas.DatetimeIndex
42
-
43
- latitude : float
44
-
45
- longitude : float
39
+ apparent_zenith: numeric
46
40
47
- altitude : float
41
+ airmass_absolute: numeric
48
42
49
- linke_turbidity : None or float
50
- If None, uses ``LinkeTurbidities.mat`` lookup table.
43
+ linke_turbidity: numeric
51
44
52
- solarposition_method : string
53
- Sets the solar position algorithm.
54
- See solarposition.get_solarposition()
55
-
56
- zenith_data : None or Series
57
- If None, ephemeris data will be calculated using ``solarposition_method``.
58
-
59
- airmass_model : string
60
- See pvlib.airmass.relativeairmass().
45
+ dni_extra: numeric
46
+ Extraterrestrial irradiance. The units of ``dni_extra``
47
+ determine the units of the output.
61
48
62
- airmass_data : None or Series
63
- If None, absolute air mass data will be calculated using
64
- ``airmass_model`` and location.alitude.
65
-
66
- interp_turbidity : bool
67
- If ``True``, interpolates the monthly Linke turbidity values
68
- found in ``LinkeTurbidities.mat`` to daily values.
49
+ altitude: numeric
69
50
70
51
Returns
71
52
--------
72
- DataFrame with the following columns: ``ghi, dni, dhi``.
73
-
74
- Notes
75
- -----
76
- If you are using this function
77
- in a loop, it may be faster to load LinkeTurbidities.mat outside of
78
- the loop and feed it in as a keyword argument, rather than
79
- having the function open and process the file each time it is called.
53
+ clearsky : DataFrame (if Series input) or OrderedDict of arrays
54
+ DataFrame/OrderedDict contains the columns/keys
55
+ ``'dhi', 'dni', 'ghi'``.
80
56
81
57
References
82
58
----------
83
-
84
59
[1] P. Ineichen and R. Perez, "A New airmass independent formulation for
85
- the Linke turbidity coefficient", Solar Energy, vol 73, pp. 151-157, 2002.
60
+ the Linke turbidity coefficient", Solar Energy, vol 73, pp. 151-157,
61
+ 2002.
86
62
87
63
[2] R. Perez et. al., "A New Operational Model for Satellite-Derived
88
64
Irradiances: Description and Validation", Solar Energy, vol 73, pp.
@@ -98,97 +74,66 @@ def ineichen(time, latitude, longitude, altitude=0, linke_turbidity=None,
98
74
[5] J. Remund, et. al., "Worldwide Linke Turbidity Information", Proc.
99
75
ISES Solar World Congress, June 2003. Goteborg, Sweden.
100
76
'''
101
- # Initial implementation of this algorithm by Matthew Reno.
102
- # Ported to python by Rob Andrews
103
- # Added functionality by Will Holmgren (@wholmgren)
104
-
105
- I0 = irradiance .extraradiation (time .dayofyear )
106
-
107
- if zenith_data is None :
108
- ephem_data = solarposition .get_solarposition (time ,
109
- latitude = latitude ,
110
- longitude = longitude ,
111
- altitude = altitude ,
112
- method = solarposition_method )
113
- time = ephem_data .index # fixes issue with time possibly not being tz-aware
114
- try :
115
- ApparentZenith = ephem_data ['apparent_zenith' ]
116
- except KeyError :
117
- ApparentZenith = ephem_data ['zenith' ]
118
- logger .warning ('could not find apparent_zenith. using zenith' )
119
- else :
120
- ApparentZenith = zenith_data
121
- #ApparentZenith[ApparentZenith >= 90] = 90 # can cause problems in edge cases
122
-
123
77
124
- if linke_turbidity is None :
125
- TL = lookup_linke_turbidity (time , latitude , longitude ,
126
- interp_turbidity = interp_turbidity )
127
- else :
128
- TL = linke_turbidity
78
+ # Dan's note on the TL correction: By my reading of the publication
79
+ # on pages 151-157, Ineichen and Perez introduce (among other
80
+ # things) three things. 1) Beam model in eqn. 8, 2) new turbidity
81
+ # factor in eqn 9 and appendix A, and 3) Global horizontal model in
82
+ # eqn. 11. They do NOT appear to use the new turbidity factor (item
83
+ # 2 above) in either the beam or GHI models. The phrasing of
84
+ # appendix A seems as if there are two separate corrections, the
85
+ # first correction is used to correct the beam/GHI models, and the
86
+ # second correction is used to correct the revised turibidity
87
+ # factor. In my estimation, there is no need to correct the
88
+ # turbidity factor used in the beam/GHI models.
89
+
90
+ # Create the corrected TL for TL < 2
91
+ # TLcorr = TL;
92
+ # TLcorr(TL < 2) = TLcorr(TL < 2) - 0.25 .* (2-TLcorr(TL < 2)) .^ (0.5);
93
+
94
+ # This equation is found in Solar Energy 73, pg 311. Full ref: Perez
95
+ # et. al., Vol. 73, pp. 307-317 (2002). It is slightly different
96
+ # than the equation given in Solar Energy 73, pg 156. We used the
97
+ # equation from pg 311 because of the existence of known typos in
98
+ # the pg 156 publication (notably the fh2-(TL-1) should be fh2 *
99
+ # (TL-1)).
129
100
130
- # Get the absolute airmass assuming standard local pressure (per
131
- # alt2pres) using Kasten and Young's 1989 formula for airmass.
101
+ cos_zenith = tools .cosd (apparent_zenith )
132
102
133
- if airmass_data is None :
134
- AMabsolute = atmosphere .absoluteairmass (airmass_relative = atmosphere .relativeairmass (ApparentZenith , airmass_model ),
135
- pressure = atmosphere .alt2pres (altitude ))
136
- else :
137
- AMabsolute = airmass_data
103
+ tl = linke_turbidity
138
104
139
105
fh1 = np .exp (- altitude / 8000. )
140
106
fh2 = np .exp (- altitude / 1250. )
141
107
cg1 = 5.09e-05 * altitude + 0.868
142
108
cg2 = 3.92e-05 * altitude + 0.0387
143
- logger .debug ('fh1=%s, fh2=%s, cg1=%s, cg2=%s' , fh1 , fh2 , cg1 , cg2 )
144
-
145
- # Dan's note on the TL correction: By my reading of the publication on
146
- # pages 151-157, Ineichen and Perez introduce (among other things) three
147
- # things. 1) Beam model in eqn. 8, 2) new turbidity factor in eqn 9 and
148
- # appendix A, and 3) Global horizontal model in eqn. 11. They do NOT appear
149
- # to use the new turbidity factor (item 2 above) in either the beam or GHI
150
- # models. The phrasing of appendix A seems as if there are two separate
151
- # corrections, the first correction is used to correct the beam/GHI models,
152
- # and the second correction is used to correct the revised turibidity
153
- # factor. In my estimation, there is no need to correct the turbidity
154
- # factor used in the beam/GHI models.
155
-
156
- # Create the corrected TL for TL < 2
157
- # TLcorr = TL;
158
- # TLcorr(TL < 2) = TLcorr(TL < 2) - 0.25 .* (2-TLcorr(TL < 2)) .^ (0.5);
159
-
160
- # This equation is found in Solar Energy 73, pg 311.
161
- # Full ref: Perez et. al., Vol. 73, pp. 307-317 (2002).
162
- # It is slightly different than the equation given in Solar Energy 73, pg 156.
163
- # We used the equation from pg 311 because of the existence of known typos
164
- # in the pg 156 publication (notably the fh2-(TL-1) should be fh2 * (TL-1)).
165
-
166
- cos_zenith = tools .cosd (ApparentZenith )
167
-
168
- clearsky_GHI = ( cg1 * I0 * cos_zenith *
169
- np .exp (- cg2 * AMabsolute * (fh1 + fh2 * (TL - 1 ))) *
170
- np .exp (0.01 * AMabsolute ** 1.8 ) )
171
- clearsky_GHI [clearsky_GHI < 0 ] = 0
172
109
173
- # BncI == "normal beam clear sky radiation"
110
+ ghi = (cg1 * dni_extra * cos_zenith *
111
+ np .exp (- cg2 * airmass_absolute * (fh1 + fh2 * (tl - 1 ))) *
112
+ np .exp (0.01 * airmass_absolute ** 1.8 ))
113
+ ghi = np .maximum (ghi , 0 )
114
+
115
+ # BncI = "normal beam clear sky radiation"
174
116
b = 0.664 + 0.163 / fh1
175
- BncI = b * I0 * np .exp ( - 0.09 * AMabsolute * (TL - 1 ) )
176
- logger .debug ('b=%s' , b )
117
+ BncI = b * dni_extra * np .exp (- 0.09 * airmass_absolute * (tl - 1 ))
177
118
178
119
# "empirical correction" SE 73, 157 & SE 73, 312.
179
- BncI_2 = ( clearsky_GHI *
180
- ( 1 - (0.1 - 0.2 * np .exp (- TL ))/ (0.1 + 0.882 / fh1 ) ) /
181
- cos_zenith )
120
+ BncI_2 = (ghi *
121
+ ( 1 - (0.1 - 0.2 * np .exp (- tl ))/ (0.1 + 0.882 / fh1 )) /
122
+ cos_zenith )
182
123
183
- clearsky_DNI = np .minimum (BncI , BncI_2 )
124
+ dni = np .minimum (BncI , BncI_2 )
184
125
185
- clearsky_DHI = clearsky_GHI - clearsky_DNI * cos_zenith
126
+ dhi = ghi - dni * cos_zenith
186
127
187
- df_out = pd .DataFrame ({'ghi' :clearsky_GHI , 'dni' :clearsky_DNI ,
188
- 'dhi' :clearsky_DHI })
189
- df_out .fillna (0 , inplace = True )
128
+ irrads = OrderedDict ()
129
+ irrads ['ghi' ] = ghi
130
+ irrads ['dni' ] = dni
131
+ irrads ['dhi' ] = dhi
190
132
191
- return df_out
133
+ if isinstance (dni , pd .Series ):
134
+ irrads = pd .DataFrame .from_dict (irrads )
135
+
136
+ return irrads
192
137
193
138
194
139
def lookup_linke_turbidity (time , latitude , longitude , filepath = None ,
@@ -360,16 +305,15 @@ def simplified_solis(apparent_elevation, aod700=0.1, precipitable_water=1.,
360
305
or 101325 and 41000 Pascals.
361
306
362
307
dni_extra: numeric
363
- Extraterrestrial irradiance.
308
+ Extraterrestrial irradiance. The units of ``dni_extra``
309
+ determine the units of the output.
364
310
365
311
Returns
366
312
--------
367
313
clearsky : DataFrame (if Series input) or OrderedDict of arrays
368
314
DataFrame/OrderedDict contains the columns/keys
369
315
``'dhi', 'dni', 'ghi'``.
370
316
371
- The units of ``dni_extra`` determine the units of the output.
372
-
373
317
References
374
318
----------
375
319
.. [1] P. Ineichen, "A broadband simplified version of the
0 commit comments