0
# Temperature Models
1
2
Calculate PV cell and module temperatures using various models including SAPM, Faiman, Ross, Fuentes, and PVsyst approaches. Accurate temperature modeling is essential for realistic PV system performance predictions.
3
4
## Capabilities
5
6
### SAPM Temperature Models
7
8
Sandia Array Performance Model temperature calculations for cells and modules.
9
10
```python { .api }
11
def sapm_cell(poa_global, temp_air, wind_speed, a, b, deltaT,
12
irrad_ref=1000, temp_ref=25):
13
"""
14
Calculate cell temperature using SAPM model.
15
16
Parameters:
17
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
18
- temp_air: numeric, ambient air temperature (C)
19
- wind_speed: numeric, wind speed (m/s)
20
- a: numeric, SAPM module parameter (dimensionless)
21
- b: numeric, SAMP module parameter (s/m)
22
- deltaT: numeric, SAPM module parameter (C)
23
- irrad_ref: numeric, reference irradiance (W/m^2)
24
- temp_ref: numeric, reference temperature (C)
25
26
Returns:
27
numeric, cell temperature (C)
28
"""
29
30
def sapm_module(poa_global, temp_air, wind_speed, a, b):
31
"""
32
Calculate module back-of-module temperature using SAPM model.
33
34
Parameters:
35
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
36
- temp_air: numeric, ambient air temperature (C)
37
- wind_speed: numeric, wind speed (m/s)
38
- a: numeric, SAPM module parameter (dimensionless)
39
- b: numeric, SAPM module parameter (s/m)
40
41
Returns:
42
numeric, module back-of-module temperature (C)
43
"""
44
45
def sapm_cell_from_module(module_temperature, poa_global, deltaT,
46
irrad_ref=1000, temp_ref=25):
47
"""
48
Calculate cell temperature from module temperature using SAMP model.
49
50
Parameters:
51
- module_temperature: numeric, module back-of-module temperature (C)
52
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
53
- deltaT: numeric, SAPM module parameter (C)
54
- irrad_ref: numeric, reference irradiance (W/m^2)
55
- temp_ref: numeric, reference temperature (C)
56
57
Returns:
58
numeric, cell temperature (C)
59
"""
60
```
61
62
### PVsyst Temperature Model
63
64
Temperature model used in PVsyst software.
65
66
```python { .api }
67
def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0,
68
eta_m=0.1, alpha_absorption=0.9):
69
"""
70
Calculate cell temperature using PVsyst model.
71
72
Parameters:
73
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
74
- temp_air: numeric, ambient air temperature (C)
75
- wind_speed: numeric, wind speed (m/s)
76
- u_c: numeric, combined heat loss coefficient (W/m^2/C)
77
- u_v: numeric, wind-dependent heat loss coefficient (W*s/m^3/C)
78
- eta_m: numeric, module efficiency under STC
79
- alpha_absorption: numeric, absorption coefficient
80
81
Returns:
82
numeric, cell temperature (C)
83
"""
84
```
85
86
### Faiman Temperature Model
87
88
Simple temperature model based on energy balance.
89
90
```python { .api }
91
def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84):
92
"""
93
Calculate cell temperature using Faiman model.
94
95
Parameters:
96
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
97
- temp_air: numeric, ambient air temperature (C)
98
- wind_speed: numeric, wind speed (m/s)
99
- u0: numeric, combined heat loss coefficient (W/m^2/C)
100
- u1: numeric, wind-dependent heat loss coefficient (W*s/m^3/C)
101
102
Returns:
103
numeric, cell temperature (C)
104
"""
105
106
def faiman_rad(poa_global, temp_air, wind_speed=1.0, ir_down=None,
107
u0=25.0, u1=6.84, emissivity=0.85, temp_sky=None):
108
"""
109
Calculate cell temperature using Faiman model with radiative cooling.
110
111
Parameters:
112
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
113
- temp_air: numeric, ambient air temperature (C)
114
- wind_speed: numeric, wind speed (m/s)
115
- ir_down: numeric, downwelling longwave irradiance (W/m^2)
116
- u0: numeric, combined heat loss coefficient (W/m^2/C)
117
- u1: numeric, wind-dependent heat loss coefficient (W*s/m^3/C)
118
- emissivity: numeric, module emissivity (0-1)
119
- temp_sky: numeric, sky temperature (C)
120
121
Returns:
122
numeric, cell temperature (C)
123
"""
124
```
125
126
### Ross Temperature Model
127
128
Simple temperature model based on NOCT (Nominal Operating Cell Temperature).
129
130
```python { .api }
131
def ross(poa_global, temp_air, noct):
132
"""
133
Calculate cell temperature using Ross model.
134
135
Parameters:
136
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
137
- temp_air: numeric, ambient air temperature (C)
138
- noct: numeric, nominal operating cell temperature (C)
139
140
Returns:
141
numeric, cell temperature (C)
142
"""
143
```
144
145
### Fuentes Temperature Model
146
147
Temperature model accounting for module mounting configuration.
148
149
```python { .api }
150
def fuentes(poa_global, temp_air, wind_speed, noct_installed,
151
module_height=5, wind_height=9.144):
152
"""
153
Calculate cell temperature using Fuentes model.
154
155
Parameters:
156
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
157
- temp_air: numeric, ambient air temperature (C)
158
- wind_speed: numeric, wind speed (m/s)
159
- noct_installed: numeric, NOCT for installed module configuration (C)
160
- module_height: numeric, module mounting height (m)
161
- wind_height: numeric, wind measurement height (m)
162
163
Returns:
164
numeric, cell temperature (C)
165
"""
166
```
167
168
### NOCT Model from SAM
169
170
NOCT-based temperature model used in SAM software.
171
172
```python { .api }
173
def noct_sam(poa_global, temp_air, wind_speed, noct, module_efficiency,
174
effective_irradiance):
175
"""
176
Calculate cell temperature using SAM NOCT model.
177
178
Parameters:
179
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
180
- temp_air: numeric, ambient air temperature (C)
181
- wind_speed: numeric, wind speed (m/s)
182
- noct: numeric, nominal operating cell temperature (C)
183
- module_efficiency: numeric, module efficiency under STC
184
- effective_irradiance: numeric, effective irradiance (W/m^2)
185
186
Returns:
187
numeric, cell temperature (C)
188
"""
189
```
190
191
### Generic Linear Temperature Model
192
193
Configurable linear temperature model with custom coefficients.
194
195
```python { .api }
196
def generic_linear(poa_global, temp_air, wind_speed, u_const, du_wind,
197
eta_m, alpha_absorption):
198
"""
199
Calculate cell temperature using generic linear model.
200
201
Parameters:
202
- poa_global: numeric, plane-of-array global irradiance (W/m^2)
203
- temp_air: numeric, ambient air temperature (C)
204
- wind_speed: numeric, wind speed (m/s)
205
- u_const: numeric, constant heat loss coefficient (W/m^2/C)
206
- du_wind: numeric, wind-dependent heat loss coefficient (W*s/m^3/C)
207
- eta_m: numeric, module efficiency under STC
208
- alpha_absorption: numeric, solar absorption coefficient
209
210
Returns:
211
numeric, cell temperature (C)
212
"""
213
214
class GenericLinearModel:
215
"""
216
Generic linear temperature model class.
217
218
Parameters:
219
- u_const: numeric, constant heat loss coefficient (W/m^2/C)
220
- du_wind: numeric, wind-dependent heat loss coefficient (W*s/m^3/C)
221
- eta_m: numeric, module efficiency under STC
222
- alpha_absorption: numeric, solar absorption coefficient
223
"""
224
225
def __init__(self, u_const, du_wind, eta_m, alpha_absorption):
226
pass
227
228
def __call__(self, poa_global, temp_air, wind_speed):
229
"""Calculate cell temperature."""
230
pass
231
```
232
233
### Prilliman Cooling Model
234
235
Model for cell temperature cooling due to wind effects.
236
237
```python { .api }
238
def prilliman(temp_cell, wind_speed, unit_mass=11.1, coefficients=None):
239
"""
240
Calculate cell temperature cooling using Prilliman model.
241
242
Parameters:
243
- temp_cell: numeric, initial cell temperature (C)
244
- wind_speed: numeric, wind speed (m/s)
245
- unit_mass: numeric, module mass per unit area (kg/m^2)
246
- coefficients: array-like, model coefficients
247
248
Returns:
249
numeric, cooled cell temperature (C)
250
"""
251
```
252
253
## Temperature Model Parameters
254
255
```python { .api }
256
TEMPERATURE_MODEL_PARAMETERS = {
257
'sapm': {
258
'open_rack_glass_glass': {'a': -3.47, 'b': -0.0594, 'deltaT': 3},
259
'close_mount_glass_glass': {'a': -2.98, 'b': -0.0471, 'deltaT': 1},
260
'open_rack_glass_polymer': {'a': -3.56, 'b': -0.0750, 'deltaT': 3},
261
'insulated_back_glass_polymer': {'a': -2.81, 'b': -0.0455, 'deltaT': 0}
262
},
263
'pvsyst': {
264
'freestanding': {'u_c': 29.0, 'u_v': 0.0},
265
'insulated': {'u_c': 15.0, 'u_v': 0.0}
266
},
267
'faiman': {
268
'open_rack': {'u0': 25.0, 'u1': 6.84},
269
'close_mount': {'u0': 15.0, 'u1': 2.3}
270
}
271
}
272
```
273
274
## Usage Examples
275
276
### Comparing Temperature Models
277
278
```python
279
import pvlib
280
from pvlib import temperature
281
import numpy as np
282
import pandas as pd
283
284
# Environmental conditions
285
poa_global = 800 # W/m^2
286
temp_air = 25 # °C
287
wind_speed = 3 # m/s
288
289
# SAPM model (open rack, glass-glass)
290
temp_sapm = temperature.sapm_cell(
291
poa_global=poa_global,
292
temp_air=temp_air,
293
wind_speed=wind_speed,
294
a=-3.47,
295
b=-0.0594,
296
deltaT=3
297
)
298
299
# PVsyst model (freestanding)
300
temp_pvsyst = temperature.pvsyst_cell(
301
poa_global=poa_global,
302
temp_air=temp_air,
303
wind_speed=wind_speed,
304
u_c=29.0,
305
u_v=0.0
306
)
307
308
# Faiman model (open rack)
309
temp_faiman = temperature.faiman(
310
poa_global=poa_global,
311
temp_air=temp_air,
312
wind_speed=wind_speed,
313
u0=25.0,
314
u1=6.84
315
)
316
317
# Ross model (using typical NOCT)
318
temp_ross = temperature.ross(
319
poa_global=poa_global,
320
temp_air=temp_air,
321
noct=45
322
)
323
324
print("Temperature Model Comparison:")
325
print(f"Ambient air temperature: {temp_air}°C")
326
print(f"POA irradiance: {poa_global} W/m²")
327
print(f"Wind speed: {wind_speed} m/s")
328
print()
329
print(f"SAPM: {temp_sapm:.1f}°C")
330
print(f"PVsyst: {temp_pvsyst:.1f}°C")
331
print(f"Faiman: {temp_faiman:.1f}°C")
332
print(f"Ross: {temp_ross:.1f}°C")
333
```
334
335
### Temperature vs. Irradiance
336
337
```python
338
import pvlib
339
from pvlib import temperature
340
import numpy as np
341
import matplotlib.pyplot as plt
342
343
# Environmental conditions
344
temp_air = 25
345
wind_speed = 2
346
irradiance = np.linspace(0, 1200, 13)
347
348
# Calculate temperatures using different models
349
temps_sapm = temperature.sapm_cell(
350
irradiance, temp_air, wind_speed,
351
a=-3.47, b=-0.0594, deltaT=3
352
)
353
354
temps_faiman = temperature.faiman(
355
irradiance, temp_air, wind_speed,
356
u0=25.0, u1=6.84
357
)
358
359
temps_ross = temperature.ross(
360
irradiance, temp_air, noct=45
361
)
362
363
# Print results
364
print("Irradiance vs Cell Temperature:")
365
print("Irr(W/m²) SAPM(°C) Faiman(°C) Ross(°C)")
366
for i, irr in enumerate(irradiance):
367
print(f"{irr:8.0f} {temps_sapm[i]:7.1f} {temps_faiman[i]:9.1f} {temps_ross[i]:7.1f}")
368
```
369
370
### Wind Speed Effects
371
372
```python
373
import pvlib
374
from pvlib import temperature
375
import numpy as np
376
377
# Fixed conditions
378
poa_global = 800
379
temp_air = 30
380
wind_speeds = np.array([0, 1, 2, 3, 5, 8, 10])
381
382
# Calculate temperatures for different wind speeds
383
temps_sapm = temperature.sapm_cell(
384
poa_global, temp_air, wind_speeds,
385
a=-3.47, b=-0.0594, deltaT=3
386
)
387
388
temps_faiman = temperature.faiman(
389
poa_global, temp_air, wind_speeds,
390
u0=25.0, u1=6.84
391
)
392
393
# PVsyst model (wind-independent by default)
394
temps_pvsyst = temperature.pvsyst_cell(
395
poa_global, temp_air, wind_speeds
396
)
397
398
print("Wind Speed Effects on Cell Temperature:")
399
print("Wind(m/s) SAPM(°C) Faiman(°C) PVsyst(°C)")
400
for i, ws in enumerate(wind_speeds):
401
print(f"{ws:8.1f} {temps_sapm[i]:7.1f} {temps_faiman[i]:9.1f} {temps_pvsyst[i]:9.1f}")
402
```
403
404
### Module Mounting Effects
405
406
```python
407
import pvlib
408
from pvlib import temperature
409
410
# Fixed conditions
411
poa_global = 800
412
temp_air = 25
413
wind_speed = 3
414
415
# Different mounting configurations using SAPM parameters
416
mounting_configs = {
417
'open_rack_glass_glass': {'a': -3.47, 'b': -0.0594, 'deltaT': 3},
418
'close_mount_glass_glass': {'a': -2.98, 'b': -0.0471, 'deltaT': 1},
419
'open_rack_glass_polymer': {'a': -3.56, 'b': -0.0750, 'deltaT': 3},
420
'insulated_back_glass_polymer': {'a': -2.81, 'b': -0.0455, 'deltaT': 0}
421
}
422
423
print("Module Mounting Configuration Effects:")
424
print("Configuration Cell Temp(°C)")
425
for config_name, params in mounting_configs.items():
426
temp_cell = temperature.sapm_cell(
427
poa_global, temp_air, wind_speed, **params
428
)
429
print(f"{config_name:<30} {temp_cell:11.1f}")
430
```
431
432
### Daily Temperature Profile
433
434
```python
435
import pvlib
436
from pvlib import temperature, solarposition, clearsky, atmosphere
437
import pandas as pd
438
439
# Location and date
440
lat, lon = 40.0583, -74.4057 # Princeton, NJ
441
date = '2023-07-15' # Summer day
442
times = pd.date_range(f'{date} 00:00', f'{date} 23:00',
443
freq='H', tz='US/Eastern')
444
445
# Solar position
446
solar_pos = solarposition.get_solarposition(times, lat, lon)
447
448
# Clear sky irradiance
449
airmass = atmosphere.get_relative_airmass(solar_pos['zenith'])
450
airmass_abs = atmosphere.get_absolute_airmass(airmass)
451
clear_sky = clearsky.ineichen(
452
solar_pos['apparent_zenith'], airmass_abs, linke_turbidity=3.0
453
)
454
455
# Environmental conditions (simplified daily patterns)
456
temp_air = 20 + 10 * np.sin(np.pi * (times.hour - 6) / 12) # Daily temp cycle
457
temp_air = np.maximum(temp_air, 15) # Minimum 15°C
458
wind_speed = 2 + np.random.normal(0, 0.5, len(times)) # Variable wind
459
wind_speed = np.maximum(wind_speed, 0.5) # Minimum wind
460
461
# Calculate cell temperatures
462
temp_cell = temperature.sapm_cell(
463
poa_global=clear_sky['ghi'],
464
temp_air=temp_air,
465
wind_speed=wind_speed,
466
a=-3.47, b=-0.0594, deltaT=3
467
)
468
469
# Show results for daylight hours
470
print("Daily Temperature Profile:")
471
print("Time Air(°C) GHI(W/m²) Wind(m/s) Cell(°C)")
472
for i in range(6, 19): # 6 AM to 6 PM
473
time_str = times[i].strftime('%H:%M')
474
air_temp = temp_air[i]
475
ghi = clear_sky['ghi'].iloc[i]
476
wind = wind_speed[i]
477
cell = temp_cell[i]
478
print(f"{time_str} {air_temp:5.1f} {ghi:7.0f} {wind:5.1f} {cell:5.1f}")
479
```