From ae13a1832ceed0ee97ae3c24496798145275740f Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Wed, 11 Dec 2019 22:50:35 +0100 Subject: [PATCH 1/3] First functional function. --- pvlib/temperature.py | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pvlib/temperature.py b/pvlib/temperature.py index f43d372a3a..3015c217af 100644 --- a/pvlib/temperature.py +++ b/pvlib/temperature.py @@ -269,3 +269,61 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, heat_input = poa_global * alpha_absorption * (1 - eta_m) temp_difference = heat_input / total_loss_factor return temp_air + temp_difference + + +def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=5.0): + ''' + Calculate cell/module temperature using an empirical heat loss factor + model as proposed by Faiman [2] and adopted in the IEC 61853 standards [1]. + + Usage of this model in the IEC 61853 standard does not distinguish + between cell and module temperature. + + Parameters + ---------- + poa_global : numeric + Total incident irradiance [W/m^2]. + + temp_air : numeric + Ambient dry bulb temperature [C]. + + wind_speed : numeric, default 1.0 + Wind speed in m/s measured at the same height for which the wind loss + factor was determined. The default value 1.0 m/s is the wind + speed at module height used to determine NOCT. [m/s] + + u_c : numeric, default 25.0 + Combined heat loss factor coefficient. The default value is + just a round number that is somewhat realistic. [W/(m^2 C)]. + + u_v : numeric, default 5.0 + Combined heat loss factor influenced by wind. The default value is + just a round number that is somewhat realistic. [(W/m^2 C)(m/s)]. + + Returns + ------- + numeric, values in degrees Celsius + + Notes + ----- + If multiple arguments are vectors they must be the same length. + + References + ---------- + [1] IEC 61853... + + [2] Faiman, D. (2008). "Assessing the outdoor operating temperature of + photovoltaic modules." Progress in Photovoltaics 16(4): 307-315. + ''' + # Contributed by Anton Driesse (@adriesse), PV Performance Labs. Dec., 2019 + + # The following lines may seem odd since u0 & u1 are probably scalar, + # but it serves an indirect and easy way of allowing lists and + # tuples for the other function arguments. + u0 = np.asanyarray(u0) + u1 = np.asanyarray(u1) + + total_loss_factor = u0 + u1 * wind_speed + heat_input = poa_global + temp_difference = heat_input / total_loss_factor + return temp_air + temp_difference From 18476c9092346b51630075085bbbbb50b8e01998 Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Thu, 12 Dec 2019 11:47:43 +0100 Subject: [PATCH 2/3] Fixed defaults and docstring; added tests and sphinx entries. --- docs/sphinx/source/api.rst | 1 + docs/sphinx/source/whatsnew/v0.7.0.rst | 6 ++-- pvlib/temperature.py | 30 ++++++++++++-------- pvlib/test/test_temperature.py | 39 ++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 13 deletions(-) diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index b9c7a82651..bf4a44d58b 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -233,6 +233,7 @@ PV temperature models temperature.sapm_cell temperature.sapm_module temperature.pvsyst_cell + temperature.faiman Single diode models ------------------- diff --git a/docs/sphinx/source/whatsnew/v0.7.0.rst b/docs/sphinx/source/whatsnew/v0.7.0.rst index 6de109c500..42ebb25817 100644 --- a/docs/sphinx/source/whatsnew/v0.7.0.rst +++ b/docs/sphinx/source/whatsnew/v0.7.0.rst @@ -119,8 +119,12 @@ Other API Changes Enhancements ~~~~~~~~~~~~ +* Created one new temperature model function: + :py:func:`pvlib.temperature.faiman`. (:issue:`750`) * Created two new incidence angle modifier (IAM) functions: :py:func:`pvlib.iam.martin_ruiz` and :py:func:`pvlib.iam.interp`. (:issue:`751`) +* Created one new incidence angle modifier (IAM) function for diffuse irradiance: + :py:func:`pvlib.iam.martin_ruiz_diffuse`. (:issue:`751`) * Add the `martin_ruiz` IAM function as an option for `ModelChain.aoi_model`. * Updated the file for module parameters for the CEC model, from the SAM file dated 2017-6-5 to the SAM file dated 2019-03-05. (:issue:`761`) @@ -138,8 +142,6 @@ Enhancements * Add `timeout` to :py:func:`pvlib.iotools.get_psm3`. * Add :py:func:`~pvlib.scaling.wvm`, a port of the wavelet variability model for computing reductions in variability due to a spatially distributed plant. -* Created one new incidence angle modifier (IAM) function for diffuse irradiance: - :py:func:`pvlib.iam.martin_ruiz_diffuse`. (:issue:`751`) Bug fixes ~~~~~~~~~ diff --git a/pvlib/temperature.py b/pvlib/temperature.py index 3015c217af..964eb2fb82 100644 --- a/pvlib/temperature.py +++ b/pvlib/temperature.py @@ -271,10 +271,11 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, return temp_air + temp_difference -def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=5.0): +def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84): ''' Calculate cell/module temperature using an empirical heat loss factor - model as proposed by Faiman [2] and adopted in the IEC 61853 standards [1]. + model as proposed by Faiman [1] and adopted in the IEC 61853 + standards [2] and [3]. Usage of this model in the IEC 61853 standard does not distinguish between cell and module temperature. @@ -293,12 +294,12 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=5.0): speed at module height used to determine NOCT. [m/s] u_c : numeric, default 25.0 - Combined heat loss factor coefficient. The default value is - just a round number that is somewhat realistic. [W/(m^2 C)]. + Combined heat loss factor coefficient. The default value is one + determined by Faiman for 7 silicon modules. [W/(m^2 C)]. - u_v : numeric, default 5.0 - Combined heat loss factor influenced by wind. The default value is - just a round number that is somewhat realistic. [(W/m^2 C)(m/s)]. + u_v : numeric, default 6.84 + Combined heat loss factor influenced by wind. The default value is one + determined by Faiman for 7 silicon modules. [(W/m^2 C)(m/s)]. Returns ------- @@ -306,14 +307,21 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=5.0): Notes ----- - If multiple arguments are vectors they must be the same length. + All arguments may be scalars or vectors. If multiple arguments + are vectors they must be the same length. References ---------- - [1] IEC 61853... - - [2] Faiman, D. (2008). "Assessing the outdoor operating temperature of + [1] Faiman, D. (2008). "Assessing the outdoor operating temperature of photovoltaic modules." Progress in Photovoltaics 16(4): 307-315. + + [2] "IEC 61853-2 Photovoltaic (PV) module performance testing and energy + rating - Part 2: Spectral responsivity, incidence angle and module + operating temperature measurements". IEC, Geneva, 2018. + + [3] "IEC 61853-3 Photovoltaic (PV) module performance testing and energy + rating - Part 3: Energy rating of PV modules". IEC, Geneva, 2018. + ''' # Contributed by Anton Driesse (@adriesse), PV Performance Labs. Dec., 2019 diff --git a/pvlib/test/test_temperature.py b/pvlib/test/test_temperature.py index c3112d85a6..7027c979a0 100644 --- a/pvlib/test/test_temperature.py +++ b/pvlib/test/test_temperature.py @@ -90,6 +90,45 @@ def test_pvsyst_cell_series(): assert_series_equal(expected, result) +def test_faiman_default(): + result = temperature.faiman(900, 20, 5) + assert_allclose(result, 35.203, 0.001) + + +def test_faiman_kwargs(): + result = temperature.faiman(900, 20, wind_speed=5.0, u0=22.0, u1=6.) + assert_allclose(result, 37.308, 0.001) + + +def test_faiman_list(): + temps = [0, 10, 5] + irrads = [0, 500, 0] + winds = [10, 5, 0] + result = temperature.faiman(irrads, temps, wind_speed=winds) + expected = np.array([0.0, 18.446, 5.0]) + assert_allclose(expected, result, 3) + + +def test_faiman_ndarray(): + temps = np.array([0, 10, 5]) + irrads = np.array([0, 500, 0]) + winds = np.array([10, 5, 0]) + result = temperature.faiman(irrads, temps, wind_speed=winds) + expected = np.array([0.0, 18.446, 5.0]) + assert_allclose(expected, result, 3) + + +def test_faiman_series(): + times = pd.date_range(start="2015-01-01", end="2015-01-02", freq="12H") + temps = pd.Series([0, 10, 5], index=times) + irrads = pd.Series([0, 500, 0], index=times) + winds = pd.Series([10, 5, 0], index=times) + + result = temperature.faiman(irrads, temps, wind_speed=winds) + expected = pd.Series([0.0, 18.446, 5.0], index=times) + assert_series_equal(expected, result) + + def test__temperature_model_params(): params = temperature._temperature_model_params('sapm', 'open_rack_glass_glass') From 189be46519c2101aaf7c5020a04060d9ae60cf0d Mon Sep 17 00:00:00 2001 From: Anton Driesse Date: Fri, 13 Dec 2019 13:00:27 +0100 Subject: [PATCH 3/3] Small but important docstring changes. --- pvlib/temperature.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pvlib/temperature.py b/pvlib/temperature.py index 964eb2fb82..326c67726a 100644 --- a/pvlib/temperature.py +++ b/pvlib/temperature.py @@ -273,7 +273,7 @@ def pvsyst_cell(poa_global, temp_air, wind_speed=1.0, u_c=29.0, u_v=0.0, def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84): ''' - Calculate cell/module temperature using an empirical heat loss factor + Calculate cell or module temperature using an empirical heat loss factor model as proposed by Faiman [1] and adopted in the IEC 61853 standards [2] and [3]. @@ -293,11 +293,11 @@ def faiman(poa_global, temp_air, wind_speed=1.0, u0=25.0, u1=6.84): factor was determined. The default value 1.0 m/s is the wind speed at module height used to determine NOCT. [m/s] - u_c : numeric, default 25.0 + u0 : numeric, default 25.0 Combined heat loss factor coefficient. The default value is one determined by Faiman for 7 silicon modules. [W/(m^2 C)]. - u_v : numeric, default 6.84 + u1 : numeric, default 6.84 Combined heat loss factor influenced by wind. The default value is one determined by Faiman for 7 silicon modules. [(W/m^2 C)(m/s)].