Skip to content

Commit e7484a6

Browse files
ramaroesilvacwhanseechedey-lskandersolaradriesse
authored
Adds faiman_rad and ross models to get_cell_temperature(). (#2631)
* Adds faiman_rad and ross models to get_cell_temperature(). * Addresses flake8 formatting issues. * Updates contribution md file. * Adds test for ross option, placeholder for faiman_rad. * Corrects flake8 issues. * Adds missing wind_speed=None when testing get_cell_temperature for ross. * Corrects wrong function naming. * Adds missing input to functions within tests. * Corrects test + flake8 issue. * Minor update in documentation + flake8 issue. * Another flake8 issue handled. * Improve faiman_rad test and completes get_cell_temperature doc. * Addresses flake8. * Update whatsnew doc. * Defines ir_down as weather variable Within faiman_rad. * Handles flake8 issues. * Corrects bug in test. * Handles flake8. * move whatsnew note * undo edit to v0.14.0.rst * Apply suggestions from code review Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com> * replace ir_down with longwave_down * finish replacing ir_down with longwave_down * undo edits to temperature.py * temperature.faiman_rad doesn't use longwave_down yet * Apply suggestions from code review Co-authored-by: Anton Driesse <anton.driesse@pvperformancelabs.com> * Update tests/test_pvsystem.py Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> --------- Co-authored-by: Cliff Hansen <cwhanse@sandia.gov> Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com> Co-authored-by: Anton Driesse <anton.driesse@pvperformancelabs.com>
1 parent fa888c6 commit e7484a6

3 files changed

Lines changed: 86 additions & 11 deletions

File tree

docs/sphinx/source/whatsnew/v0.15.1.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Enhancements
2929
~~~~~~~~~~~~
3030
* Use ``k`` and ``cap_adjustment`` from :py:func:`pvlib.pvsystem.Array.module_parameters` in :py:func:`pvlib.pvsystem.PVSystem.pvwatts_dc`
3131
(:issue:`2714`, :pull:`2715`)
32+
* Include `ross` and `faiman_rad` in the allowed models within
33+
:py:meth:`pvlib.pvsystem.PVSystem.get_cell_temperature` (:issue:`2625`, :pull:`2631`)
3234
* Accelerate the internals of :py:func:`~pvlib.solarpostion.ephemeris`. (:pull:`2626`)
3335

3436
Documentation
@@ -84,5 +86,6 @@ Contributors
8486
* Rohan Saxena (:ghuser:`r0hansaxena`)
8587
* Marco Fumagalli (:ghuser:`fuma900`)
8688
* Jean-Baptiste Pasquier (:ghuser:`pasquierjb`)
89+
* Rodrigo Amaro e Silva (:ghuser:`ramaroesilva`)
8790
* James Fulton (:ghuser:`dfulu`)
8891

pvlib/pvsystem.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ def get_iam(self, aoi, iam_model='physical'):
414414

415415
@_unwrap_single_value
416416
def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
417-
effective_irradiance=None):
417+
effective_irradiance=None, longwave_down=None):
418418
"""
419419
Determine cell temperature using the method specified by ``model``.
420420
@@ -431,12 +431,17 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
431431
432432
model : str
433433
Supported models include ``'sapm'``, ``'pvsyst'``,
434-
``'faiman'``, ``'fuentes'``, and ``'noct_sam'``
434+
``'faiman'``, ``'faiman_rad'``, ``'fuentes'``, ``'noct_sam'``,
435+
and ``'ross'``
435436
436437
effective_irradiance : numeric or tuple of numeric, optional
437438
The irradiance that is converted to photocurrent in W/m^2.
438439
Only used for some models.
439440
441+
longwave_down: numeric or tuple of numeric, optional
442+
Downwelling long-wave radiation from the sky, measured on a
443+
horizontal surface in W/m^2. Only used in ``'faiman_rad'`` model.
444+
440445
Returns
441446
-------
442447
numeric or tuple of numeric
@@ -459,14 +464,18 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
459464
# Not used for all models, but Array.get_cell_temperature handles it
460465
effective_irradiance = self._validate_per_array(effective_irradiance,
461466
system_wide=True)
467+
longwave_down = self._validate_per_array(longwave_down,
468+
system_wide=True)
462469

463470
return tuple(
464471
array.get_cell_temperature(poa_global, temp_air, wind_speed,
465-
model, effective_irradiance)
466-
for array, poa_global, temp_air, wind_speed, effective_irradiance
472+
model, effective_irradiance,
473+
longwave_down)
474+
for array, poa_global, temp_air, wind_speed, effective_irradiance,
475+
longwave_down
467476
in zip(
468477
self.arrays, poa_global, temp_air, wind_speed,
469-
effective_irradiance
478+
effective_irradiance, longwave_down
470479
)
471480
)
472481

@@ -1208,7 +1217,7 @@ def get_iam(self, aoi, iam_model='physical'):
12081217
raise ValueError(model + ' is not a valid IAM model')
12091218

12101219
def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
1211-
effective_irradiance=None):
1220+
effective_irradiance=None, longwave_down=None):
12121221
"""
12131222
Determine cell temperature using the method specified by ``model``.
12141223
@@ -1222,15 +1231,21 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
12221231
12231232
wind_speed : numeric
12241233
Wind speed [m/s]
1234+
When ``model='ross'``, this input is ignored
12251235
12261236
model : str
12271237
Supported models include ``'sapm'``, ``'pvsyst'``,
1228-
``'faiman'``, ``'fuentes'``, and ``'noct_sam'``
1238+
``'faiman'``, ``'faiman_rad'``, ``'fuentes'``, ``'noct_sam'``,
1239+
and ``'ross'``
12291240
12301241
effective_irradiance : numeric, optional
12311242
The irradiance that is converted to photocurrent in W/m^2.
12321243
Only used for some models.
12331244
1245+
longwave_down: numeric, optional
1246+
Downwelling long-wave radiation from the sky, measured on a
1247+
horizontal surface in W/m^2. Only used in ``'faiman_rad'`` model.
1248+
12341249
Returns
12351250
-------
12361251
numeric
@@ -1239,8 +1254,9 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
12391254
See Also
12401255
--------
12411256
pvlib.temperature.sapm_cell, pvlib.temperature.pvsyst_cell,
1242-
pvlib.temperature.faiman, pvlib.temperature.fuentes,
1243-
pvlib.temperature.noct_sam
1257+
pvlib.temperature.faiman, pvlib.temperature.faiman_rad,
1258+
pvlib.temperature.fuentes, pvlib.temperature.noct_sam,
1259+
pvlib.temperature.ross
12441260
12451261
Notes
12461262
-----
@@ -1271,6 +1287,13 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
12711287
required = tuple()
12721288
optional = _build_kwargs(['u0', 'u1'],
12731289
self.temperature_model_parameters)
1290+
elif model == 'faiman_rad':
1291+
func = functools.partial(temperature.faiman_rad,
1292+
ir_down=longwave_down)
1293+
required = ()
1294+
optional = _build_kwargs(['u0', 'u1',
1295+
'sky_view', 'emissivity'],
1296+
self.temperature_model_parameters)
12741297
elif model == 'fuentes':
12751298
func = temperature.fuentes
12761299
required = _build_tcell_args(['noct_installed'])
@@ -1287,11 +1310,21 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
12871310
optional = _build_kwargs(['transmittance_absorptance',
12881311
'array_height', 'mount_standoff'],
12891312
self.temperature_model_parameters)
1313+
elif model == 'ross':
1314+
func = temperature.ross
1315+
required = ()
1316+
# either noct or k must be defined
1317+
optional = _build_kwargs(['noct', 'k'],
1318+
self.temperature_model_parameters)
12901319
else:
12911320
raise ValueError(f'{model} is not a valid cell temperature model')
12921321

1293-
temperature_cell = func(poa_global, temp_air, wind_speed,
1294-
*required, **optional)
1322+
if model == 'ross':
1323+
temperature_cell = func(poa_global, temp_air,
1324+
*required, **optional)
1325+
else:
1326+
temperature_cell = func(poa_global, temp_air, wind_speed,
1327+
*required, **optional)
12951328
return temperature_cell
12961329

12971330
def dc_ohms_from_percent(self):

tests/test_pvsystem.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,45 @@ def test_PVSystem_faiman_celltemp(mocker):
494494
assert_allclose(out, 56.4, atol=1e-1)
495495

496496

497+
def test_PVSystem_faiman_rad_celltemp(mocker):
498+
longwave_down = 50 # arbitrary value
499+
# default values, u0 and u1 being adjusted in same proportion as in
500+
# https://www.osti.gov/servlets/purl/1884890/ (not suggested, just example)
501+
u0, u1 = 25.0*0.86, 6.84*0.88
502+
sky_view = 1.0
503+
emissivity = 0.88
504+
505+
temp_model_params = {'u0': u0, 'u1': u1, 'sky_view': sky_view,
506+
'emissivity': emissivity}
507+
system = pvsystem.PVSystem(temperature_model_parameters=temp_model_params)
508+
mocker.spy(temperature, 'faiman_rad')
509+
temps = 25
510+
irrads = 1000
511+
winds = 1
512+
out = system.get_cell_temperature(irrads, temps, winds,
513+
model='faiman_rad',
514+
longwave_down=longwave_down)
515+
temperature.faiman_rad.assert_called_once_with(irrads, temps, winds,
516+
longwave_down, u0, u1,
517+
sky_view, emissivity)
518+
assert_allclose(out, 48.6, atol=1e-1)
519+
520+
521+
def test_PVSystem_ross_celltemp(mocker):
522+
# example value (could use equivalent noct as alternative input)
523+
k = 0.0208 # free-standing system
524+
525+
temp_model_params = {'k': k}
526+
system = pvsystem.PVSystem(temperature_model_parameters=temp_model_params)
527+
m = mocker.spy(temperature, 'ross')
528+
temps = 25
529+
irrads = 1000
530+
winds = None
531+
out = system.get_cell_temperature(irrads, temps, winds, model='ross')
532+
m.assert_called_once_with(irrads, temps, k=k)
533+
assert_allclose(out, 45.8, atol=1e-1)
534+
535+
497536
def test_PVSystem_noct_celltemp(mocker):
498537
poa_global, temp_air, wind_speed, noct, module_efficiency = (
499538
1000., 25., 1., 45., 0.2)

0 commit comments

Comments
 (0)