Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.13.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Enhancements
MERRA-2 reanalysis data. (:pull:`2572`)
* Add :py:func:`~pvlib.spectrum.spectral_factor_polo`, a function for estimating
spectral mismatch factors for vertical PV façades. (:issue:`2406`, :pull:`2491`)
* Includes `ross` and `faiman_rad` in the allowed models within
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Includes `ross` and `faiman_rad` in the allowed models within
* Include `ross` and `faiman_rad` in the allowed models within

`pvlib.pvsystem.PVSystem.get_cell_temperature` (:issue:`2625`, :pull:`2631`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`pvlib.pvsystem.PVSystem.get_cell_temperature` (:issue:`2625`, :pull:`2631`)
:py:meth:`pvlib.pvsystem.PVSystem.get_cell_temperature` (:issue:`2625`, :pull:`2631`)


Documentation
~~~~~~~~~~~~~
Expand Down Expand Up @@ -87,3 +89,4 @@ Contributors
* Anton Driesse (:ghuser:`adriesse`)
* Rajiv Daxini (:ghuser:`RDaxini`)
* Kevin Anderson (:ghuser:`kandersolar`)
* Rodrigo Amaro e Silva (:ghuser:`ramaroesilva`)
33 changes: 26 additions & 7 deletions pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,

model : str
Supported models include ``'sapm'``, ``'pvsyst'``,
``'faiman'``, ``'fuentes'``, and ``'noct_sam'``
``'faiman'``, ``'faiman_rad'``, ``'fuentes'``, ``'noct_sam'``,
and ``'ross'``

effective_irradiance : numeric or tuple of numeric, optional
The irradiance that is converted to photocurrent in W/m^2.
Expand Down Expand Up @@ -1217,11 +1218,12 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
Ambient dry bulb temperature [C]

wind_speed : numeric
Wind speed [m/s]
Wind speed [m/s], although can be ``None`` for ``'ross'`` model
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add this to the corresponding PVSystem description too?


model : str
Supported models include ``'sapm'``, ``'pvsyst'``,
``'faiman'``, ``'fuentes'``, and ``'noct_sam'``
``'faiman'``, ``'faiman_rad'``, ``'fuentes'``, ``'noct_sam'``,
and ``'ross'``

effective_irradiance : numeric, optional
The irradiance that is converted to photocurrent in W/m^2.
Expand All @@ -1235,8 +1237,9 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
See Also
--------
pvlib.temperature.sapm_cell, pvlib.temperature.pvsyst_cell,
pvlib.temperature.faiman, pvlib.temperature.fuentes,
pvlib.temperature.noct_sam
pvlib.temperature.faiman, pvlib.temperature.faiman_rad,
pvlib.temperature.fuentes, pvlib.temperature.noct_sam,
pvlib.temperature.ross

Notes
-----
Expand Down Expand Up @@ -1267,6 +1270,12 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
required = tuple()
optional = _build_kwargs(['u0', 'u1'],
self.temperature_model_parameters)
elif model == 'faiman_rad':
func = temperature.faiman_rad
required = ()
optional = _build_kwargs(['ir_down', 'u0', 'u1',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ir_down being a value in temperature_model_parameters seems wrong to me. Shouldn't it be an optional time series input like effective_irradiance is?

'sky_view', 'emissivity'],
self.temperature_model_parameters)
elif model == 'fuentes':
func = temperature.fuentes
required = _build_tcell_args(['noct_installed'])
Expand All @@ -1283,11 +1292,21 @@ def get_cell_temperature(self, poa_global, temp_air, wind_speed, model,
optional = _build_kwargs(['transmittance_absorptance',
'array_height', 'mount_standoff'],
self.temperature_model_parameters)
elif model == 'ross':
func = temperature.ross
required = ()
# either noct or k must be defined
optional = _build_kwargs(['noct', 'k'],
self.temperature_model_parameters)
else:
raise ValueError(f'{model} is not a valid cell temperature model')

temperature_cell = func(poa_global, temp_air, wind_speed,
*required, **optional)
if model == 'ross':
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although wind speed was kept as an input requested by get_cell_temperature, here such a differentiation is needed since ross is apparently the only model not using wind.

temperature_cell = func(poa_global, temp_air,
*required, **optional)
else:
temperature_cell = func(poa_global, temp_air, wind_speed,
*required, **optional)
return temperature_cell

def dc_ohms_from_percent(self):
Expand Down
37 changes: 37 additions & 0 deletions tests/test_pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,43 @@ def test_PVSystem_faiman_celltemp(mocker):
assert_allclose(out, 56.4, atol=1e-1)


def test_PVSystem_faiman_rad_celltemp(mocker):
ir_down = 50 # arbitrary value
# default values, u0 and u1 being adjusted in same proportion as in
# https://www.osti.gov/servlets/purl/1884890/ (not suggested, just example)
u0, u1 = 25.0*0.86, 6.84*0.88
sky_view = 1.0
emissivity = 0.88

temp_model_params = {'ir_down': ir_down, 'u0': u0, 'u1': u1,
'sky_view': sky_view, 'emissivity': emissivity}
system = pvsystem.PVSystem(temperature_model_parameters=temp_model_params)
mocker.spy(temperature, 'faiman_rad')
temps = 25
irrads = 1000
winds = 1
out = system.get_cell_temperature(irrads, temps, winds, model='faiman_rad')
temperature.faiman_rad.assert_called_once_with(irrads, temps, winds,
ir_down, u0, u1,
sky_view, emissivity)
assert_allclose(out, 48.6, atol=1e-1)


def test_PVSystem_ross_celltemp(mocker):
# example value (could use equivalent noct as alternative input)
k = 0.0208 # free-standing system

temp_model_params = {'k': k}
system = pvsystem.PVSystem(temperature_model_parameters=temp_model_params)
mocker.spy(temperature, 'ross')
temps = 25
irrads = 1000
winds = None
out = system.get_cell_temperature(irrads, temps, winds, model='ross')
temperature.ross.assert_called_once_with(irrads, temps, k=k)
assert_allclose(out, 45.8, atol=1e-1)


def test_PVSystem_noct_celltemp(mocker):
poa_global, temp_air, wind_speed, noct, module_efficiency = (
1000., 25., 1., 45., 0.2)
Expand Down