0
# Irradiance Modeling
1
2
Calculate solar irradiance components and perform irradiance decomposition and transposition modeling. Essential for determining the solar resource available to PV systems on tilted and tracked surfaces.
3
4
## Capabilities
5
6
### Total Irradiance on Tilted Surfaces
7
8
Calculate complete plane-of-array (POA) irradiance on tilted surfaces using various sky diffuse models.
9
10
```python { .api }
11
def get_total_irradiance(surface_tilt, surface_azimuth, solar_zenith,
12
solar_azimuth, dni, ghi, dhi, dni_extra=None,
13
airmass=None, albedo=0.25, surface_type=None,
14
model='haydavies', model_perez='allsitescomposite1990',
15
**kwargs):
16
"""
17
Calculate total irradiance on a tilted surface.
18
19
Parameters:
20
- surface_tilt: float, surface tilt angle in degrees from horizontal
21
- surface_azimuth: float, surface azimuth angle in degrees from north
22
- solar_zenith: numeric, solar zenith angle in degrees
23
- solar_azimuth: numeric, solar azimuth angle in degrees
24
- dni: numeric, direct normal irradiance (W/m^2)
25
- ghi: numeric, global horizontal irradiance (W/m^2)
26
- dhi: numeric, diffuse horizontal irradiance (W/m^2)
27
- dni_extra: numeric, extraterrestrial direct normal irradiance
28
- airmass: numeric, relative airmass
29
- albedo: numeric, ground reflectance (0-1)
30
- surface_type: str, surface type for albedo lookup
31
- model: str, sky diffuse model ('isotropic', 'klucher', 'haydavies', 'reindl', 'king', 'perez')
32
- model_perez: str, Perez model variant
33
34
Returns:
35
OrderedDict with keys:
36
- poa_global: total plane-of-array irradiance
37
- poa_direct: direct component on plane-of-array
38
- poa_diffuse: total diffuse component on plane-of-array
39
- poa_sky_diffuse: sky diffuse component
40
- poa_ground_diffuse: ground-reflected diffuse component
41
"""
42
```
43
44
### Sky Diffuse Irradiance Models
45
46
Calculate sky diffuse irradiance on tilted surfaces using various models.
47
48
```python { .api }
49
def get_sky_diffuse(surface_tilt, surface_azimuth, solar_zenith,
50
solar_azimuth, dni, ghi, dhi, dni_extra=None,
51
airmass=None, model='haydavies', **kwargs):
52
"""
53
Calculate sky diffuse irradiance on tilted surface.
54
55
Parameters:
56
- surface_tilt: float, degrees from horizontal
57
- surface_azimuth: float, degrees from north
58
- solar_zenith: numeric, degrees
59
- solar_azimuth: numeric, degrees
60
- dni: numeric, W/m^2
61
- ghi: numeric, W/m^2
62
- dhi: numeric, W/m^2
63
- dni_extra: numeric, extraterrestrial DNI
64
- airmass: numeric, relative airmass
65
- model: str, sky diffuse model
66
67
Returns:
68
numeric, sky diffuse irradiance on tilted surface
69
"""
70
71
def isotropic(surface_tilt, dhi):
72
"""
73
Isotropic sky diffuse model.
74
75
Parameters:
76
- surface_tilt: numeric, degrees from horizontal
77
- dhi: numeric, diffuse horizontal irradiance
78
79
Returns:
80
numeric, sky diffuse irradiance on tilted surface
81
"""
82
83
def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
84
solar_zenith, solar_azimuth, projection_ratio=None):
85
"""
86
Hay-Davies sky diffuse model.
87
88
Parameters:
89
- surface_tilt: numeric, degrees from horizontal
90
- surface_azimuth: numeric, degrees from north
91
- dhi: numeric, diffuse horizontal irradiance
92
- dni: numeric, direct normal irradiance
93
- dni_extra: numeric, extraterrestrial direct normal irradiance
94
- solar_zenith: numeric, degrees
95
- solar_azimuth: numeric, degrees
96
- projection_ratio: numeric, optional beam projection ratio
97
98
Returns:
99
numeric, sky diffuse irradiance on tilted surface
100
"""
101
102
def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
103
solar_zenith, solar_azimuth, airmass,
104
model='allsitescomposite1990'):
105
"""
106
Perez sky diffuse model.
107
108
Parameters:
109
- surface_tilt: numeric, degrees from horizontal
110
- surface_azimuth: numeric, degrees from north
111
- dhi: numeric, diffuse horizontal irradiance
112
- dni: numeric, direct normal irradiance
113
- dni_extra: numeric, extraterrestrial direct normal irradiance
114
- solar_zenith: numeric, degrees
115
- solar_azimuth: numeric, degrees
116
- airmass: numeric, relative airmass
117
- model: str, Perez model variant
118
119
Returns:
120
numeric, sky diffuse irradiance on tilted surface
121
"""
122
123
def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
124
solar_zenith, solar_azimuth):
125
"""
126
Reindl sky diffuse model.
127
128
Parameters:
129
- surface_tilt: numeric, degrees from horizontal
130
- surface_azimuth: numeric, degrees from north
131
- dhi: numeric, diffuse horizontal irradiance
132
- dni: numeric, direct normal irradiance
133
- ghi: numeric, global horizontal irradiance
134
- dni_extra: numeric, extraterrestrial direct normal irradiance
135
- solar_zenith: numeric, degrees
136
- solar_azimuth: numeric, degrees
137
138
Returns:
139
numeric, sky diffuse irradiance on tilted surface
140
"""
141
142
def klucher(surface_tilt, surface_azimuth, dhi, ghi, solar_zenith,
143
solar_azimuth):
144
"""
145
Klucher sky diffuse model.
146
147
Parameters:
148
- surface_tilt: numeric, degrees from horizontal
149
- surface_azimuth: numeric, degrees from north
150
- dhi: numeric, diffuse horizontal irradiance
151
- ghi: numeric, global horizontal irradiance
152
- solar_zenith: numeric, degrees
153
- solar_azimuth: numeric, degrees
154
155
Returns:
156
numeric, sky diffuse irradiance on tilted surface
157
"""
158
159
def king(surface_tilt, dhi, ghi, solar_zenith):
160
"""
161
King sky diffuse model.
162
163
Parameters:
164
- surface_tilt: numeric, degrees from horizontal
165
- dhi: numeric, diffuse horizontal irradiance
166
- ghi: numeric, global horizontal irradiance
167
- solar_zenith: numeric, degrees
168
169
Returns:
170
numeric, sky diffuse irradiance on tilted surface
171
"""
172
```
173
174
### Ground-Reflected Diffuse Irradiance
175
176
Calculate ground-reflected diffuse irradiance component.
177
178
```python { .api }
179
def get_ground_diffuse(surface_tilt, ghi, albedo=0.25, surface_type=None):
180
"""
181
Calculate ground-reflected diffuse irradiance.
182
183
Parameters:
184
- surface_tilt: numeric, degrees from horizontal
185
- ghi: numeric, global horizontal irradiance
186
- albedo: numeric, ground reflectance (0-1)
187
- surface_type: str, surface type for albedo lookup
188
189
Returns:
190
numeric, ground-reflected diffuse irradiance
191
"""
192
```
193
194
### Angle of Incidence
195
196
Calculate angle of incidence of direct solar radiation on tilted surfaces.
197
198
```python { .api }
199
def aoi(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
200
"""
201
Calculate angle of incidence.
202
203
Parameters:
204
- surface_tilt: numeric, degrees from horizontal
205
- surface_azimuth: numeric, degrees from north
206
- solar_zenith: numeric, degrees
207
- solar_azimuth: numeric, degrees
208
209
Returns:
210
numeric, angle of incidence in degrees
211
"""
212
213
def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
214
"""
215
Calculate angle of incidence projection (cosine of AOI).
216
217
Parameters:
218
- surface_tilt: numeric, degrees from horizontal
219
- surface_azimuth: numeric, degrees from north
220
- solar_zenith: numeric, degrees
221
- solar_azimuth: numeric, degrees
222
223
Returns:
224
numeric, cosine of angle of incidence
225
"""
226
```
227
228
### Irradiance Decomposition Models
229
230
Decompose global horizontal irradiance into direct and diffuse components.
231
232
```python { .api }
233
def disc(ghi, solar_zenith, datetime_or_doy, pressure=101325,
234
min_cos_zenith=0.065, max_zenith=87):
235
"""
236
DISC irradiance decomposition model.
237
238
Parameters:
239
- ghi: numeric, global horizontal irradiance
240
- solar_zenith: numeric, degrees
241
- datetime_or_doy: DatetimeIndex or numeric day of year
242
- pressure: numeric, pascals
243
- min_cos_zenith: float, minimum cosine zenith threshold
244
- max_zenith: float, maximum zenith angle threshold
245
246
Returns:
247
OrderedDict with keys: dni, dhi, kt
248
"""
249
250
def dirint(ghi, solar_zenith, times, pressure=101325,
251
use_delta_kt_prime=True, temp_dew=None, min_cos_zenith=0.065,
252
max_zenith=87, max_delta_kt_prime=0.15, max_kt=0.82):
253
"""
254
DIRINT irradiance decomposition model.
255
256
Parameters:
257
- ghi: numeric, global horizontal irradiance
258
- solar_zenith: numeric, degrees
259
- times: DatetimeIndex
260
- pressure: numeric, pascals
261
- use_delta_kt_prime: bool, use delta kt prime modification
262
- temp_dew: numeric, dew point temperature
263
- min_cos_zenith: float, minimum cosine zenith threshold
264
- max_zenith: float, maximum zenith angle threshold
265
- max_delta_kt_prime: float, maximum delta kt prime
266
- max_kt: float, maximum clearness index
267
268
Returns:
269
OrderedDict with keys: dni, dhi, kt
270
"""
271
272
def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
273
"""
274
Erbs irradiance decomposition model.
275
276
Parameters:
277
- ghi: numeric, global horizontal irradiance
278
- zenith: numeric, solar zenith angle in degrees
279
- datetime_or_doy: DatetimeIndex or numeric day of year
280
- min_cos_zenith: float, minimum cosine zenith threshold
281
- max_zenith: float, maximum zenith angle threshold
282
283
Returns:
284
OrderedDict with keys: dni, dhi, kt
285
"""
286
287
def dirindex(ghi, ghi_clear, dni_clear, zenith, times, pressure=101325,
288
min_cos_zenith=0.065, max_zenith=87):
289
"""
290
DIRINDEX irradiance decomposition model.
291
292
Parameters:
293
- ghi: numeric, measured global horizontal irradiance
294
- ghi_clear: numeric, clear sky global horizontal irradiance
295
- dni_clear: numeric, clear sky direct normal irradiance
296
- zenith: numeric, solar zenith angle in degrees
297
- times: DatetimeIndex
298
- pressure: numeric, atmospheric pressure in pascals
299
- min_cos_zenith: float, minimum cosine zenith threshold
300
- max_zenith: float, maximum zenith angle threshold
301
302
Returns:
303
OrderedDict with keys: dni, dhi, kt
304
"""
305
```
306
307
### Extraterrestrial Radiation
308
309
Calculate extraterrestrial solar radiation.
310
311
```python { .api }
312
def get_extra_radiation(datetime_or_doy, solar_constant=1366.1,
313
method='spencer', epoch_year=2014):
314
"""
315
Calculate extraterrestrial radiation.
316
317
Parameters:
318
- datetime_or_doy: DatetimeIndex or numeric day of year
319
- solar_constant: float, solar constant in W/m^2
320
- method: str, calculation method ('spencer', 'asce', 'nrel')
321
- epoch_year: int, epoch year for NREL method
322
323
Returns:
324
numeric, extraterrestrial radiation in W/m^2
325
"""
326
```
327
328
### Clearness Index
329
330
Calculate atmospheric clearness index.
331
332
```python { .api }
333
def clearness_index(ghi, solar_zenith, extra_radiation,
334
min_cos_zenith=0.065, max_clearness_index=2.0):
335
"""
336
Calculate clearness index.
337
338
Parameters:
339
- ghi: numeric, global horizontal irradiance
340
- solar_zenith: numeric, degrees
341
- extra_radiation: numeric, extraterrestrial radiation
342
- min_cos_zenith: float, minimum cosine zenith threshold
343
- max_clearness_index: float, maximum clearness index
344
345
Returns:
346
numeric, clearness index
347
"""
348
349
def clearsky_index(ghi, ghi_clear, max_clearsky_index=2.0):
350
"""
351
Calculate clearsky index.
352
353
Parameters:
354
- ghi: numeric, global horizontal irradiance
355
- ghi_clear: numeric, clear sky global horizontal irradiance
356
- max_clearsky_index: float, maximum clearsky index
357
358
Returns:
359
numeric, clearsky index
360
"""
361
```
362
363
## Usage Examples
364
365
### Basic POA Irradiance Calculation
366
367
```python
368
import pvlib
369
from pvlib import irradiance, solarposition
370
import pandas as pd
371
372
# Location and time
373
lat, lon = 40.0583, -74.4057
374
times = pd.date_range('2023-06-21', periods=24, freq='H', tz='US/Eastern')
375
376
# Solar position
377
solar_pos = solarposition.get_solarposition(times, lat, lon)
378
379
# Sample irradiance data (normally from measurements or clear sky model)
380
dni = 800
381
ghi = 900
382
dhi = 100
383
384
# Surface parameters
385
surface_tilt = 30
386
surface_azimuth = 180
387
388
# Calculate POA irradiance
389
poa = irradiance.get_total_irradiance(
390
surface_tilt=surface_tilt,
391
surface_azimuth=surface_azimuth,
392
solar_zenith=solar_pos['zenith'],
393
solar_azimuth=solar_pos['azimuth'],
394
dni=dni,
395
ghi=ghi,
396
dhi=dhi,
397
model='perez'
398
)
399
400
print(poa['poa_global'].head())
401
```
402
403
### Irradiance Decomposition
404
405
```python
406
import pvlib
407
from pvlib import irradiance, solarposition
408
import pandas as pd
409
410
# Sample data
411
times = pd.date_range('2023-06-21', periods=24, freq='H', tz='US/Eastern')
412
lat, lon = 40.0583, -74.4057
413
ghi = [0, 0, 0, 50, 200, 400, 600, 750, 850, 900, 950, 980,
414
950, 900, 800, 650, 450, 250, 100, 25, 0, 0, 0, 0]
415
416
# Solar position
417
solar_pos = solarposition.get_solarposition(times, lat, lon)
418
419
# Decompose GHI into DNI and DHI using DISC model
420
decomp = irradiance.disc(
421
ghi=ghi,
422
solar_zenith=solar_pos['zenith'],
423
datetime_or_doy=times
424
)
425
426
print("DNI:", decomp['dni'].head())
427
print("DHI:", decomp['dhi'].head())
428
```
429
430
### Comparing Sky Diffuse Models
431
432
```python
433
import pvlib
434
from pvlib import irradiance
435
import numpy as np
436
437
# Parameters
438
surface_tilt = 30
439
surface_azimuth = 180
440
solar_zenith = 45
441
solar_azimuth = 180
442
dni = 700
443
ghi = 800
444
dhi = 100
445
dni_extra = 1000
446
airmass = 1.5
447
448
# Compare different sky diffuse models
449
models = ['isotropic', 'haydavies', 'reindl', 'king', 'perez']
450
results = {}
451
452
for model in models:
453
sky_diffuse = irradiance.get_sky_diffuse(
454
surface_tilt=surface_tilt,
455
surface_azimuth=surface_azimuth,
456
solar_zenith=solar_zenith,
457
solar_azimuth=solar_azimuth,
458
dni=dni,
459
ghi=ghi,
460
dhi=dhi,
461
dni_extra=dni_extra,
462
airmass=airmass,
463
model=model
464
)
465
results[model] = sky_diffuse
466
467
print("Sky diffuse model comparison:")
468
for model, value in results.items():
469
print(f"{model}: {value:.1f} W/m²")
470
```