3
3
Clear sky
4
4
=========
5
5
6
- Clear sky expectations are essential to many PV modeling tasks.
7
- Here, we briefly review the clear sky modeling capabilities of pvlib-python.
6
+ Clear sky irradiance data is essential to many PV modeling tasks. Here, we
7
+ review the clear sky modeling capabilities of pvlib-python. The
8
+ :ref: `location ` section demonstrates the easiest way to obtain a time
9
+ series of clear sky data for a location. The :ref: `ineichen ` and
10
+ :ref: `simplified_solis ` sections detail the clear sky algorithms and
11
+ input data.
12
+
13
+ We'll need these imports for the examples below.
8
14
9
15
.. ipython :: python
10
16
11
- import datetime
12
17
import itertools
13
18
import pandas as pd
14
19
import matplotlib.pyplot as plt
@@ -23,23 +28,26 @@ Here, we briefly review the clear sky modeling capabilities of pvlib-python.
23
28
from pvlib.location import Location
24
29
25
30
31
+ .. _location :
32
+
26
33
Location
27
34
--------
28
35
29
- The easiest way to get clear sky data is to use a
36
+ The easiest way to obtain a time series of clear sky irradiance is to use a
30
37
:py:class: `~pvlib.location.Location ` object's
31
38
:py:meth: `~pvlib.location.Location.get_clearsky ` method. The
32
39
:py:meth: `~pvlib.location.Location.get_clearsky ` method does the dirty
33
40
work of calculating solar position, extraterrestrial irradiance,
34
41
airmass, and atmospheric pressure, as appropriate, leaving the user to
35
- only specify the most important parameters. We encourage users to
36
- examine the source code .
42
+ only specify the most important parameters: time and atmospheric
43
+ attenuation .
37
44
38
45
.. ipython :: python
39
46
40
47
tus = Location(32.2 , - 111 , ' US/Arizona' , 700 , ' Tucson' )
41
- times = pd.DatetimeIndex(start = ' 2016-07-01' , end = ' 2016-07-04' , freq = ' 1min' , tz = tus.tz)
42
- cs = tus.get_clearsky(times) # ineichen with lookup table by default
48
+ times = pd.DatetimeIndex(start = ' 2016-07-01' , end = ' 2016-07-04' ,
49
+ freq = ' 1min' , tz = tus.tz)
50
+ cs = tus.get_clearsky(times) # ineichen with climatology table by default
43
51
cs.plot();
44
52
plt.ylabel(' Irradiance $W/m^2$' );
45
53
@savefig location -basic.png width=6in
@@ -67,11 +75,16 @@ functions that do the computation.
67
75
plt.ylabel(' Irradiance $W/m^2$' );
68
76
69
77
78
+ See the sections below for more detail on the clear sky models.
79
+
80
+
81
+ .. _ineichen :
82
+
70
83
Ineichen
71
84
--------
72
85
73
- The Ineichen and Perez (2002) clear sky model parameterizes irradiance
74
- in terms of the Linke turbidity.
86
+ The Ineichen and Perez clear sky model parameterizes irradiance
87
+ in terms of the Linke turbidity [ Ine02 ]_ .
75
88
76
89
Turbidity data
77
90
^^^^^^^^^^^^^^
@@ -90,23 +103,25 @@ the year. You could run it in a loop to create plots for all months.
90
103
filepath = os.path.join(pvlib_path, ' data' , ' LinkeTurbidities.mat' )
91
104
92
105
mat = scipy.io.loadmat(filepath)
93
- linke_turbidity_table = mat[' LinkeTurbidity' ] / 20
106
+ linke_turbidity_table = mat[' LinkeTurbidity' ] / 20 .
94
107
95
108
month = 1
96
- plt.figure(figsize = (20 ,10 ));
97
109
plt.imshow(linke_turbidity_table[:, :, month- 1 ], vmin = 1 , vmax = 5 );
98
110
plt.title(calendar.month_name[1 + month]);
111
+ plt.colorbar(shrink = 0.5 );
112
+ plt.tight_layout();
99
113
@savefig turbidity -1.png width=10in
100
- plt.colorbar ();
114
+ plt.show ();
101
115
102
116
.. ipython :: python
103
117
104
118
month = 7
105
- plt.figure(figsize = (20 ,10 ));
106
119
plt.imshow(linke_turbidity_table[:, :, month- 1 ], vmin = 1 , vmax = 5 );
107
120
plt.title(calendar.month_name[month]);
121
+ plt.colorbar(shrink = 0.5 );
122
+ plt.tight_layout();
108
123
@savefig turbidity -7.png width=10in
109
- plt.colorbar ();
124
+ plt.show ();
110
125
111
126
The :py:func: `~pvlib.clearsky.lookup_linke_turbidity ` function takes a
112
127
time, latitude, and longitude and gets the corresponding climatological
@@ -141,10 +156,18 @@ the variability of the data set.
141
156
@savefig turbidity -yes-interp.png width=6in
142
157
plt.ylabel(' Linke Turbidity' );
143
158
159
+ Examples
160
+ ^^^^^^^^
161
+
162
+ .. ipython :: python
163
+
164
+
144
165
145
166
Validation
146
167
^^^^^^^^^^
147
168
169
+ See [Ine02 ]_, [Ren12 ]_.
170
+
148
171
Will Holmgren compared pvlib's Ineichen model and climatological
149
172
turbidity to `SoDa's McClear service
150
173
<http://www.soda-pro.com/web-services/radiation/cams-mcclear> `_ in
@@ -155,11 +178,13 @@ and its `html rendering
155
178
<https://forecasting.energy.arizona.edu/media/ineichen_vs_mcclear.html> `_.
156
179
157
180
181
+ .. _simplified_solis :
182
+
158
183
Simplified Solis
159
184
----------------
160
185
161
186
The Simplified Solis model parameterizes irradiance in terms of
162
- precipitable water and aerosol optical depth.
187
+ precipitable water and aerosol optical depth [ Ine08ss ]_ .
163
188
164
189
Aerosol and precipitable water data
165
190
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -170,80 +195,88 @@ Ground based aerosol data can be obtained from
170
195
`Aeronet <http://aeronet.gsfc.nasa.gov >`_. Precipitable water can be obtained
171
196
from `radiosondes <http://weather.uwyo.edu/upperair/sounding.html >`_,
172
197
`ESRL GPS-MET <http://gpsmet.noaa.gov/cgi-bin/gnuplots/rti.cgi >`_, or
173
- derived from surface relative humidity using the
174
- :py:func: `pvlib.atmosphere.gueymard94_pw ` function .
198
+ derived from surface relative humidity using functions such as
199
+ :py:func: `pvlib.atmosphere.gueymard94_pw `.
175
200
Numerous gridded products from satellites, weather models, and climate models
176
201
contain one or both of aerosols and precipitable water.
177
202
178
- Note that aerosol optical depth is a function of wavelength, so be sure
179
- that you understand the aerosol data that you're looking at. The
180
- Simplified Solis model requires AOD at 700 nm. Models exist to convert
181
- AOD between different wavelengths, as well as convert Linke turbidity to
182
- AOD.
203
+ Aerosol optical depth is a function of wavelength, and the Simplified
204
+ Solis model requires AOD at 700 nm. Models exist to convert AOD between
205
+ different wavelengths, as well as convert Linke turbidity to AOD and PW
206
+ [ Ine08con ]_, [ Ine16 ]_.
207
+
183
208
209
+ Examples
210
+ ^^^^^^^^
184
211
212
+ A clear sky time series using basic pvlib functions.
185
213
186
214
.. ipython :: python
187
215
216
+ latitude, longitude, tz, altitude, name = 32.2 , - 111 , ' US/Arizona' , 700 , ' Tucson'
217
+ times = pd.date_range(start = ' 2014-01-01' , end = ' 2014-01-02' , freq = ' 1Min' , tz = tz)
218
+ solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
219
+
220
+ apparent_elevation = solpos[' apparent_elevation' ]
188
221
aod700 = 0.1
189
222
precipitable_water = 1
190
- apparent_elevation = pd.Series(np.linspace(- 10 , 90 , 101 ))
191
- pressure = 101325
192
- dni_extra = 1364
223
+ pressure = pvlib.atmosphere.alt2pres(altitude)
224
+ dni_extra = pvlib.irradiance.extraradiation(apparent_elevation.index.dayofyear)
193
225
194
- solis = clearsky.simplified_solis(apparent_elevation, aod700,
195
- precipitable_water, pressure, dni_extra)
196
- ax = solis.plot()
197
- ax.set_xlabel(' apparent elevation (deg)' );
198
- ax.set_ylabel(' irradiance (W/m**2)' );
199
- @savefig solis -vs-elevation.png width=6in
226
+ solis = clearsky.simplified_solis(apparent_elevation, aod700, precipitable_water,
227
+ pressure, dni_extra)
228
+ ax = solis.plot();
229
+ ax.set_ylabel(' Irradiance $W/m^2$' );
200
230
ax.legend(loc = 2 );
231
+ @savefig solis -vs-time-0.1-1.png width=6in
232
+ plt.show();
201
233
202
234
203
- .. ipython :: python
204
-
205
- from pvlib.location import Location
235
+ Irradiance as a function of solar elevation.
206
236
207
- tus = Location(32.2 , - 111 , ' US/Arizona' , 700 , ' Tucson' )
208
- times = pd.date_range(start = datetime.datetime(2014 ,1 ,1 ), end = datetime.datetime(2014 ,1 ,2 ), freq = ' 1Min' ).tz_localize(tus.tz)
209
- solpos = pvlib.solarposition.get_solarposition(times, tus.latitude, tus.longitude)
210
- ephem_data = solpos
237
+ .. ipython :: python
211
238
239
+ apparent_elevation = pd.Series(np.linspace(- 10 , 90 , 101 ))
212
240
aod700 = 0.1
213
241
precipitable_water = 1
214
- apparent_elevation = solpos[' apparent_elevation' ]
215
- pressure = pvlib.atmosphere.alt2pres(tus.altitude)
216
- dni_extra = pvlib.irradiance.extraradiation(apparent_elevation.index.dayofyear)
242
+ pressure = 101325
243
+ dni_extra = 1364
217
244
218
- solis = clearsky.simplified_solis(apparent_elevation, aod700, precipitable_water, pressure, dni_extra)
219
- @savefig solis -vs-time.png width=6in
220
- solis.plot();
245
+ solis = clearsky.simplified_solis(apparent_elevation, aod700,
246
+ precipitable_water, pressure, dni_extra)
247
+ ax = solis.plot()
248
+ ax.set_xlabel(' Apparent elevation (deg)' );
249
+ ax.set_ylabel(' Irradiance $W/m^2$' );
250
+ ax.set_title(' Irradiance vs Solar Elevation' )
251
+ @savefig solis -vs-elevation.png width=6in
252
+ ax.legend(loc = 2 );
221
253
222
254
255
+ Grid with a clear sky irradiance for a few PW and AOD values.
223
256
224
257
.. ipython :: python
225
258
226
- times = pd.date_range(start = datetime.datetime(2014 ,9 ,1 ), end = datetime.datetime(2014 ,9 ,2 ), freq = ' 1Min' ).tz_localize(tus.tz)
227
- solpos = pvlib.solarposition.get_solarposition(times, tus.latitude, tus.longitude)
228
- ephem_data = solpos
259
+ times = pd.date_range(start = ' 2014-09-01' , end = ' 2014-09-02' , freq = ' 1Min' , tz = tz)
260
+ solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
229
261
230
262
apparent_elevation = solpos[' apparent_elevation' ]
231
- pressure = pvlib.atmosphere.alt2pres(tus. altitude)
263
+ pressure = pvlib.atmosphere.alt2pres(altitude)
232
264
dni_extra = pvlib.irradiance.extraradiation(apparent_elevation.index.dayofyear)
233
-
234
265
aod700 = [0.01 , 0.1 ]
235
266
precipitable_water = [0.5 , 5 ]
236
267
237
- for aod, pw in itertools.product(aod700, precipitable_water):
268
+ fig, axes = plt.subplots(ncols = 2 , nrows = 2 , sharex = True , sharey = True , squeeze = True )
269
+ axes = axes.flatten()
270
+
271
+ for (aod, pw), ax in zip (itertools.chain(itertools.product(aod700, precipitable_water)), axes):
238
272
solis = clearsky.simplified_solis(apparent_elevation, aod, pw,
239
273
pressure, dni_extra)
240
- fig, ax = plt.subplots()
241
274
solis.plot(ax = ax, title = ' aod700={} , pw={} ' .format(aod, pw))
242
- ax.set_ylim(0 , 1100 )
243
- file = ' aod{} _pw{} .png' .format(aod, pw)
244
- @savefig file width =6in
245
- plt.show()
246
275
276
+ @savefig solis -grid.png width=10in
277
+ plt.show();
278
+
279
+ Contour plots of irradiance as a function of both PW and AOD.
247
280
248
281
.. ipython :: python
249
282
265
298
266
299
def plot_solis (key ):
267
300
irrad = solis[key]
268
- fig, ax = plt.subplots(figsize = ( 12 , 9 ) )
301
+ fig, ax = plt.subplots()
269
302
im = ax.contour(aod700, precipitable_water, irrad[:, :], n, cmap = cmap, vmin = vmin, vmax = vmax)
270
303
imf = ax.contourf(aod700, precipitable_water, irrad[:, :], n, cmap = cmap, vmin = vmin, vmax = vmax)
271
304
ax.set_xlabel(' AOD' )
@@ -277,20 +310,45 @@ AOD.
277
310
.. ipython :: python
278
311
279
312
plot_solis(' ghi' )
280
- @savefig solis -ghi.png width=6in
313
+ @savefig solis -ghi.png width=10in
281
314
plt.show()
282
315
283
316
plot_solis(' dni' )
284
- @savefig solis -dni.png width=6in
317
+ @savefig solis -dni.png width=10in
285
318
plt.show()
286
319
287
320
plot_solis(' dhi' )
288
- @savefig solis -dhi.png width=6in
321
+ @savefig solis -dhi.png width=10in
289
322
plt.show()
290
323
291
324
292
325
Validation
293
326
^^^^^^^^^^
294
327
328
+ See [Ine16 ]_.
329
+
295
330
We encourage users to compare the pvlib implementation to Ineichen's
296
331
`Excel tool <http://www.unige.ch/energie/fr/equipe/ineichen/solis-tool/ >`_.
332
+
333
+
334
+ References
335
+ ----------
336
+
337
+ .. [Ine02 ] P. Ineichen and R. Perez, "A New airmass independent formulation for
338
+ the Linke turbidity coefficient", Solar Energy, 73, pp. 151-157,
339
+ 2002.
340
+
341
+ .. [Ine08ss ] P. Ineichen, "A broadband simplified version of the
342
+ Solis clear sky model," Solar Energy, 82, 758-762 (2008).
343
+
344
+ .. [Ine16 ] P. Ineichen, "Validation of models that estimate the clear
345
+ sky global and beam solar irradiance," Solar Energy, 132,
346
+ 332-344 (2016).
347
+
348
+ .. [Ine08con ] P. Ineichen, "Conversion function between the Linke turbidity
349
+ and the atmospheric water vapor and aerosol content", Solar Energy,
350
+ 82, 1095 (2008).
351
+
352
+ .. [Ren12 ] M. Reno, C. Hansen, and J. Stein, "Global Horizontal Irradiance Clear
353
+ Sky Models: Implementation and Analysis", Sandia National
354
+ Laboratories, SAND2012-2389, 2012.
0 commit comments