Skip to content

Commit f821a73

Browse files
CameronTStarkcwhanse
authored andcommitted
initial implementation of pvsyst_celltemp function (#552) (#628)
* initial implementation of pvsyst_celltemp function (#552) * Reformat for stickler-ci * Add error tests for pvsyst_celltemp * Remove unused variables per stickler-ci * Add pvsystem.pvsyst_celltemp function to docs * correct api title * formatting changes per wholmgren and cwhanse * Additional formatting improvements * Fix symbol in Reference
1 parent d6b22c3 commit f821a73

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

docs/sphinx/source/api.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,15 @@ PVWatts model
268268
pvsystem.pvwatts_dc
269269
pvsystem.pvwatts_ac
270270
pvsystem.pvwatts_losses
271+
pvsystem.pvwatts_losses
272+
273+
PVsyst model
274+
------------
275+
276+
.. autosummary::
277+
:toctree: generated/
278+
279+
pvsystem.pvsyst_celltemp
271280

272281
Other
273282
-----

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Enhancements
5757
* Add warning message when :py:func:`pvlib.spa` is reloaded. (:issue:`401`)
5858
* Add option for :py:func:`pvlib.irradiance.disc` to use relative airmass
5959
by supplying `pressure=None`. (:issue:`449`)
60+
* Created :py:func:`pvlib.pvsystem.pvsyst_celltemp` to implement PVsyst's cell temperature model. (:issue:`552`)
6061

6162

6263
Bug fixes
@@ -86,4 +87,5 @@ Contributors
8687
* Cliff Hansen (:ghuser:`cwhanse`)
8788
* Mark Mikofski (:ghuser:`mikofski`)
8889
* Anton Driesse (:ghuser:`adriesse`)
90+
* Cameron Stark (:ghuser:`camerontstark`)
8991
* Jonathan Gaffiot (:ghuser:`jgaffiot`)

pvlib/pvsystem.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1887,6 +1887,87 @@ def sapm_celltemp(poa_global, wind_speed, temp_air,
18871887
return pd.DataFrame({'temp_cell': temp_cell, 'temp_module': temp_module})
18881888

18891889

1890+
def pvsyst_celltemp(poa_global, wind_speed, temp_air, eta_m=0.1,
1891+
alpha_absorption=0.9, temp_model="freestanding"):
1892+
"""
1893+
Calculate cell temperature using the PVSyst model.
1894+
1895+
Parameters
1896+
----------
1897+
poa_global : numeric
1898+
Total incident irradiance in W/m^2.
1899+
1900+
wind_speed : numeric
1901+
Wind speed in m/s at a height of 10 meters.
1902+
1903+
temp_air : numeric
1904+
Ambient dry bulb temperature in degrees C.
1905+
1906+
eta_m : numeric
1907+
Module external efficiency as a fraction, i.e., DC power / poa_global.
1908+
1909+
alpha_absorption : float
1910+
Absorption coefficient, default is 0.9.
1911+
1912+
temp_model : string, tuple, or list, default 'freestanding' (no dict)
1913+
Model to be used.
1914+
1915+
If string, can be:
1916+
1917+
* 'freestanding' (default)
1918+
Modules with rear surfaces exposed to open air (e.g. rack
1919+
mounted).
1920+
* 'insulated'
1921+
Modules with rear surfaces in close proximity to another
1922+
surface (e.g. roof mounted).
1923+
1924+
If tuple/list, supply parameters in the following order:
1925+
1926+
* natural_convenction_coeff : float
1927+
Natural convection coefficient. Freestanding default is 29,
1928+
fully insulated arrays is 15.
1929+
1930+
* forced_convection_coeff : float
1931+
Forced convection coefficient, default is 0.
1932+
1933+
Returns
1934+
-------
1935+
temp_cell : numeric or Series
1936+
Cell temperature in degrees Celsius
1937+
1938+
References
1939+
----------
1940+
[1]"PVsyst 6 Help", Files.pvsyst.com, 2018. [Online]. Available:
1941+
http://files.pvsyst.com/help/index.html. [Accessed: 10- Dec- 2018].
1942+
1943+
[2] Faiman, D. (2008). "Assessing the outdoor operating temperature of
1944+
photovoltaic modules." Progress in Photovoltaics 16(4): 307-315.
1945+
"""
1946+
1947+
temp_models = {"freestanding": (29.0, 0), "insulated": (15.0, 0)}
1948+
1949+
if isinstance(temp_model, str):
1950+
natural_convenction_coeff, forced_convection_coeff = temp_models[
1951+
temp_model.lower()
1952+
]
1953+
elif isinstance(temp_model, (tuple, list)):
1954+
natural_convenction_coeff, forced_convection_coeff = temp_model
1955+
else:
1956+
raise TypeError(
1957+
"Please format temp_model as a str, or tuple/list."
1958+
)
1959+
1960+
combined_convection_coeff = (
1961+
forced_convection_coeff * wind_speed
1962+
) + natural_convenction_coeff
1963+
1964+
absorption_coeff = alpha_absorption * poa_global * (1 - eta_m)
1965+
temp_difference = absorption_coeff / combined_convection_coeff
1966+
temp_cell = temp_air + temp_difference
1967+
1968+
return temp_cell
1969+
1970+
18901971
def sapm_spectral_loss(airmass_absolute, module):
18911972
"""
18921973
Calculates the SAPM spectral loss coefficient, F1.

pvlib/test/test_pvsystem.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,46 @@ def test_PVSystem_sapm_celltemp(mocker):
10781078
assert out.shape == (1, 2)
10791079

10801080

1081+
def test_pvsyst_celltemp_default():
1082+
default = pvsystem.pvsyst_celltemp(900, 5, 20, 0.1)
1083+
assert_allclose(default, 45.137, 0.001)
1084+
1085+
1086+
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))
1089+
assert_allclose(tup_non_model, 33.315, 0.001)
1090+
1091+
list_non_model = pvsystem.pvsyst_celltemp(900, 5, 20, 0.1,
1092+
temp_model=[26.5, 7.68])
1093+
assert_allclose(list_non_model, 31.233, 0.001)
1094+
1095+
1096+
def test_pvsyst_celltemp_model_wrong_type():
1097+
with pytest.raises(TypeError):
1098+
pvsystem.pvsyst_celltemp(
1099+
900, 5, 20, 0.1,
1100+
temp_model={"won't": 23.5, "work": 7.68})
1101+
1102+
1103+
def test_pvsyst_celltemp_model_non_option():
1104+
with pytest.raises(KeyError):
1105+
pvsystem.pvsyst_celltemp(
1106+
900, 5, 20, 0.1,
1107+
temp_model="not_an_option")
1108+
1109+
1110+
def test_pvsyst_celltemp_with_index():
1111+
times = pd.DatetimeIndex(start="2015-01-01", end="2015-01-02", freq="12H")
1112+
temps = pd.Series([0, 10, 5], index=times)
1113+
irrads = pd.Series([0, 500, 0], index=times)
1114+
winds = pd.Series([10, 5, 0], index=times)
1115+
1116+
pvtemps = pvsystem.pvsyst_celltemp(irrads, winds, temps)
1117+
expected = pd.Series([0.0, 23.96551, 5.0], index=times)
1118+
assert_series_equal(expected, pvtemps)
1119+
1120+
10811121
def test_adrinverter(sam_data):
10821122
inverters = sam_data['adrinverter']
10831123
testinv = 'Ablerex_Electronics_Co___Ltd___' \

0 commit comments

Comments
 (0)