Skip to content

Commit f98e9ce

Browse files
adriessecwhanse
authored andcommitted
Improve clarity of code in pvsyst_celltemp (names and doc) (#651)
* Improve clarity of code through changes to variables names and docstring. * Incorporate constructive feedback. * Final polish on the docstrings and tests * Move temp before wind in PVSystem method * Add default wind_speed in PVSystem.
1 parent cc51ea3 commit f98e9ce

File tree

3 files changed

+51
-47
lines changed

3 files changed

+51
-47
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,4 @@ Contributors
101101
* Cameron Stark (:ghuser:`camerontstark`)
102102
* Jonathan Gaffiot (:ghuser:`jgaffiot`)
103103
* Marc Anoma (:ghuser:`anomam`)
104+
* Anton Driesse (:ghuser:`adriesse`)

pvlib/pvsystem.py

+38-35
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
}
4747

4848

49-
TEMP_MODELS = {
49+
TEMP_MODEL_PARAMS = {
5050
'sapm': {'open_rack_cell_glassback': (-3.47, -.0594, 3),
5151
'roof_mount_cell_glassback': (-2.98, -.0471, 1),
5252
'open_rack_cell_polymerback': (-3.56, -.0750, 3),
@@ -521,7 +521,7 @@ def sapm_effective_irradiance(self, poa_direct, poa_diffuse,
521521
poa_direct, poa_diffuse, airmass_absolute, aoi,
522522
self.module_parameters, reference_irradiance=reference_irradiance)
523523

524-
def pvsyst_celltemp(self, poa_global, wind_speed, temp_air):
524+
def pvsyst_celltemp(self, poa_global, temp_air, wind_speed=1.0):
525525
"""Uses :py:func:`pvsyst_celltemp` to calculate module temperatures
526526
based on ``self.racking_model`` and the input parameters.
527527
@@ -535,8 +535,8 @@ def pvsyst_celltemp(self, poa_global, wind_speed, temp_air):
535535
"""
536536
kwargs = _build_kwargs(['eta_m', 'alpha_absorption'],
537537
self.module_parameters)
538-
return pvsyst_celltemp(poa_global, wind_speed, temp_air,
539-
temp_model=self.racking_model, **kwargs)
538+
return pvsyst_celltemp(poa_global, temp_air, wind_speed,
539+
model_params=self.racking_model, **kwargs)
540540

541541
def first_solar_spectral_loss(self, pw, airmass_absolute):
542542

@@ -1887,7 +1887,7 @@ def sapm_celltemp(poa_global, wind_speed, temp_air,
18871887
sapm
18881888
'''
18891889

1890-
temp_models = TEMP_MODELS['sapm']
1890+
temp_models = TEMP_MODEL_PARAMS['sapm']
18911891

18921892
if isinstance(model, str):
18931893
model = temp_models[model.lower()]
@@ -1908,30 +1908,37 @@ def sapm_celltemp(poa_global, wind_speed, temp_air,
19081908
return pd.DataFrame({'temp_cell': temp_cell, 'temp_module': temp_module})
19091909

19101910

1911-
def pvsyst_celltemp(poa_global, wind_speed, temp_air, eta_m=0.1,
1912-
alpha_absorption=0.9, temp_model="freestanding"):
1911+
def pvsyst_celltemp(poa_global, temp_air, wind_speed=1.0, eta_m=0.1,
1912+
alpha_absorption=0.9, model_params='freestanding'):
19131913
"""
1914-
Calculate cell temperature using the PVSyst model.
1914+
Calculate cell temperature using an emperical heat loss factor model
1915+
as implemented in PVsyst.
1916+
1917+
The heat loss factors provided through the 'model_params' argument
1918+
represent the combined effect of convection, radiation and conduction,
1919+
and their values are experimentally determined.
19151920
19161921
Parameters
19171922
----------
19181923
poa_global : numeric
19191924
Total incident irradiance in W/m^2.
19201925
1921-
wind_speed : numeric
1922-
Wind speed in m/s at a height of 10 meters.
1923-
19241926
temp_air : numeric
19251927
Ambient dry bulb temperature in degrees C.
19261928
1927-
eta_m : numeric
1929+
wind_speed : numeric, default 1.0
1930+
Wind speed in m/s measured at the same height for which the wind loss
1931+
factor was determined. The default value is 1.0, which is the wind
1932+
speed at module height used to determine NOCT.
1933+
1934+
eta_m : numeric, default 0.1
19281935
Module external efficiency as a fraction, i.e., DC power / poa_global.
19291936
1930-
alpha_absorption : float
1931-
Absorption coefficient, default is 0.9.
1937+
alpha_absorption : numeric, default 0.9
1938+
Absorption coefficient
19321939
1933-
temp_model : string, tuple, or list, default 'freestanding' (no dict)
1934-
Model to be used.
1940+
model_params : string, tuple, or list (no dict), default 'freestanding'
1941+
Heat loss factors to be used.
19351942
19361943
If string, can be:
19371944
@@ -1944,12 +1951,12 @@ def pvsyst_celltemp(poa_global, wind_speed, temp_air, eta_m=0.1,
19441951
19451952
If tuple/list, supply parameters in the following order:
19461953
1947-
* natural_convenction_coeff : float
1948-
Natural convection coefficient. Freestanding default is 29,
1949-
fully insulated arrays is 15.
1954+
* constant_loss_factor : float
1955+
Combined heat loss factor coefficient. Freestanding
1956+
default is 29, fully insulated arrays is 15.
19501957
1951-
* forced_convection_coeff : float
1952-
Forced convection coefficient, default is 0.
1958+
* wind_loss_factor : float
1959+
Combined heat loss factor influenced by wind. Default is 0.
19531960
19541961
Returns
19551962
-------
@@ -1965,25 +1972,21 @@ def pvsyst_celltemp(poa_global, wind_speed, temp_air, eta_m=0.1,
19651972
photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.
19661973
"""
19671974

1968-
temp_models = TEMP_MODELS['pvsyst']
1975+
pvsyst_presets = TEMP_MODEL_PARAMS['pvsyst']
19691976

1970-
if isinstance(temp_model, str):
1971-
natural_convenction_coeff, forced_convection_coeff = temp_models[
1972-
temp_model.lower()
1973-
]
1974-
elif isinstance(temp_model, (tuple, list)):
1975-
natural_convenction_coeff, forced_convection_coeff = temp_model
1977+
if isinstance(model_params, str):
1978+
model_params = model_params.lower()
1979+
constant_loss_factor, wind_loss_factor = pvsyst_presets[model_params]
1980+
elif isinstance(model_params, (tuple, list)):
1981+
constant_loss_factor, wind_loss_factor = model_params
19761982
else:
19771983
raise TypeError(
1978-
"Please format temp_model as a str, or tuple/list."
1984+
"Please provide model_params as a str, or tuple/list."
19791985
)
19801986

1981-
combined_convection_coeff = (
1982-
forced_convection_coeff * wind_speed
1983-
) + natural_convenction_coeff
1984-
1985-
absorption_coeff = alpha_absorption * poa_global * (1 - eta_m)
1986-
temp_difference = absorption_coeff / combined_convection_coeff
1987+
total_loss_factor = wind_loss_factor * wind_speed + constant_loss_factor
1988+
heat_input = poa_global * alpha_absorption * (1 - eta_m)
1989+
temp_difference = heat_input / total_loss_factor
19871990
temp_cell = temp_air + temp_difference
19881991

19891992
return temp_cell

pvlib/test/test_pvsystem.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -1079,32 +1079,32 @@ def test_PVSystem_sapm_celltemp(mocker):
10791079

10801080

10811081
def test_pvsyst_celltemp_default():
1082-
default = pvsystem.pvsyst_celltemp(900, 5, 20, 0.1)
1082+
default = pvsystem.pvsyst_celltemp(900, 20, 5)
10831083
assert_allclose(default, 45.137, 0.001)
10841084

10851085

10861086
def test_pvsyst_celltemp_non_model():
1087-
tup_non_model = pvsystem.pvsyst_celltemp(900, 5, 20, 0.1,
1088-
temp_model=(23.5, 6.25))
1087+
tup_non_model = pvsystem.pvsyst_celltemp(900, 20, 5, 0.1,
1088+
model_params=(23.5, 6.25))
10891089
assert_allclose(tup_non_model, 33.315, 0.001)
10901090

1091-
list_non_model = pvsystem.pvsyst_celltemp(900, 5, 20, 0.1,
1092-
temp_model=[26.5, 7.68])
1091+
list_non_model = pvsystem.pvsyst_celltemp(900, 20, 5, 0.1,
1092+
model_params=[26.5, 7.68])
10931093
assert_allclose(list_non_model, 31.233, 0.001)
10941094

10951095

10961096
def test_pvsyst_celltemp_model_wrong_type():
10971097
with pytest.raises(TypeError):
10981098
pvsystem.pvsyst_celltemp(
1099-
900, 5, 20, 0.1,
1100-
temp_model={"won't": 23.5, "work": 7.68})
1099+
900, 20, 5, 0.1,
1100+
model_params={"won't": 23.5, "work": 7.68})
11011101

11021102

11031103
def test_pvsyst_celltemp_model_non_option():
11041104
with pytest.raises(KeyError):
11051105
pvsystem.pvsyst_celltemp(
1106-
900, 5, 20, 0.1,
1107-
temp_model="not_an_option")
1106+
900, 20, 5, 0.1,
1107+
model_params="not_an_option")
11081108

11091109

11101110
def test_pvsyst_celltemp_with_index():
@@ -1113,7 +1113,7 @@ def test_pvsyst_celltemp_with_index():
11131113
irrads = pd.Series([0, 500, 0], index=times)
11141114
winds = pd.Series([10, 5, 0], index=times)
11151115

1116-
pvtemps = pvsystem.pvsyst_celltemp(irrads, winds, temps)
1116+
pvtemps = pvsystem.pvsyst_celltemp(irrads, temps, wind_speed=winds)
11171117
expected = pd.Series([0.0, 23.96551, 5.0], index=times)
11181118
assert_series_equal(expected, pvtemps)
11191119

@@ -1131,9 +1131,9 @@ def test_PVSystem_pvsyst_celltemp(mocker):
11311131
irrad = 800
11321132
temp = 45
11331133
wind = 0.5
1134-
out = system.pvsyst_celltemp(irrad, wind, temp)
1134+
out = system.pvsyst_celltemp(irrad, temp, wind_speed=wind)
11351135
pvsystem.pvsyst_celltemp.assert_called_once_with(
1136-
irrad, wind, temp, eta_m, alpha_absorption, racking_model)
1136+
irrad, temp, wind, eta_m, alpha_absorption, racking_model)
11371137
assert isinstance(out, float)
11381138
assert out < 90 and out > 70
11391139

0 commit comments

Comments
 (0)