Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ PV temperature models
temperature.sapm_cell
temperature.sapm_module
temperature.pvsyst_cell
temperature.faiman

Single diode models
-------------------
Expand Down
6 changes: 4 additions & 2 deletions docs/sphinx/source/whatsnew/v0.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand All @@ -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
~~~~~~~~~
Expand Down
66 changes: 66 additions & 0 deletions pvlib/temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,69 @@ 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=6.84):
'''
Calculate cell/module temperature using an empirical heat loss factor
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.

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 one
determined by Faiman for 7 silicon modules. [W/(m^2 C)].

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
-------
numeric, values in degrees Celsius

Notes
-----
All arguments may be scalars or vectors. If multiple arguments
Copy link
Member

Choose a reason for hiding this comment

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

The Note doesn't hurt but I don't think it's needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

I also considered about using array-like, but that depends on the conclusion and transition plan for #765. (Only one definition of 'array-like' should apply at one time.)

are vectors they must be the same length.

References
----------
[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

# 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
39 changes: 39 additions & 0 deletions pvlib/test/test_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down