Skip to content

Commit

Permalink
add orgill hollands decomposition (#1730)
Browse files Browse the repository at this point in the history
* add orgill hollands decomposition

* Fix Stickler

* Update pvlib/irradiance.py

correct spelling to 'boland'

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

* Update pvlib/irradiance.py

correct citation formating

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

* Update pvlib/irradiance.py

correct citation formatting

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

* Update pvlib/irradiance.py

correct spelling 'boland'

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

* Update irradiance.py

adding dni_extra argument per cliff's suggestion.

* Remove edits to boland

* Fix references and add output description

* Update decomposition.rst

Update docs

* Update test_irradiance.py

Adding a test

* Update test_irradiance.py

fixing the perilous outcome of copy/pasting the test_boland function.

* Update v0.10.0.rst

Adding Orgill Hollands model to list of enhancements.

---------

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>
Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>
  • Loading branch information
3 people committed Jun 29, 2023
1 parent cfd6e78 commit fa9dc9b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/sphinx/source/reference/irradiance/decomposition.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ DNI estimation models
irradiance.dirint
irradiance.dirindex
irradiance.erbs
irradiance.orgill_hollands
irradiance.boland
irradiance.campbell_norman
irradiance.gti_dirint
Expand Down
4 changes: 2 additions & 2 deletions docs/sphinx/source/whatsnew/v0.10.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ Deprecations

Enhancements
~~~~~~~~~~~~
* Added a new irradiance decomposition model :py:func:`pvlib.irradiance.orgill_hollands`. (:pull:`1730`)
* The return values of :py:func:`pvlib.pvsystem.calcparams_desoto`,
:py:func:`pvlib.pvsystem.calcparams_cec`, and
:py:func:`pvlib.pvsystem.calcparams_pvsyst` are all numeric types and have
the same Python type as the `effective_irradiance` and `temp_cell` parameters. (:issue:`1626`, :pull:`1700`)

* Added `map_variables` parameter to :py:func:`pvlib.iotools.read_srml`
and :py:func:`pvlib.iotools.read_srml_month_from_solardat` (:pull:`1773`)
* Allow passing keyword arguments to :py:func:`scipy:scipy.optimize.brentq` and
Expand All @@ -45,7 +45,6 @@ Enhancements
(:issue:`1249`, :pull:`1764`)
* Improved `ModelChainResult.__repr__` (:pull:`1236`)


Bug fixes
~~~~~~~~~

Expand All @@ -71,6 +70,7 @@ Requirements
Contributors
~~~~~~~~~~~~
* Taos Transue (:ghuser:`reepoi`)
* Nicholas Riedel-Lyngskær (:ghuser:`nicorie`)
* Adam R. Jensen (:ghuser:`AdamRJensen`)
* Echedey Luis (:ghuser:`echedey-ls`)
* Cliff Hansen (:ghuser:`cwhanse`)
Expand Down
90 changes: 90 additions & 0 deletions pvlib/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -2227,6 +2227,8 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
--------
dirint
disc
orgill_hollands
boland
"""

dni_extra = get_extra_radiation(datetime_or_doy)
Expand Down Expand Up @@ -2265,6 +2267,93 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
return data


def orgill_hollands(ghi, zenith, datetime_or_doy, dni_extra=None,
min_cos_zenith=0.065, max_zenith=87):
"""Estimate DNI and DHI from GHI using the Orgill and Hollands model.
The Orgill and Hollands model [1]_ estimates the diffuse fraction DF from
global horizontal irradiance through an empirical relationship between
hourly DF observations (in Toronto, Canada) and the ratio of GHI to
extraterrestrial irradiance, Kt.
Parameters
----------
ghi: numeric
Global horizontal irradiance in W/m^2.
zenith: numeric
True (not refraction-corrected) zenith angles in decimal degrees.
datetime_or_doy : int, float, array, pd.DatetimeIndex
Day of year or array of days of year e.g.
pd.DatetimeIndex.dayofyear, or pd.DatetimeIndex.
dni_extra : None or numeric, default None
Extraterrestrial direct normal irradiance. [W/m2]
min_cos_zenith : numeric, default 0.065
Minimum value of cos(zenith) to allow when calculating global
clearness index `kt`. Equivalent to zenith = 86.273 degrees.
max_zenith : numeric, default 87
Maximum value of zenith to allow in DNI calculation. DNI will be
set to 0 for times with zenith values greater than `max_zenith`.
Returns
-------
data : OrderedDict or DataFrame
Contains the following keys/columns:
* ``dni``: the modeled direct normal irradiance in W/m^2.
* ``dhi``: the modeled diffuse horizontal irradiance in
W/m^2.
* ``kt``: Ratio of global to extraterrestrial irradiance
on a horizontal plane.
References
----------
.. [1] Orgill, J.F., Hollands, K.G.T., Correlation equation for hourly
diffuse radiation on a horizontal surface, Solar Energy 19(4), pp 357–359,
1977. Eqs. 3(a), 3(b) and 3(c)
:doi:`10.1016/0038-092X(77)90006-8`
See Also
--------
dirint
disc
erbs
boland
"""
if dni_extra is None:
dni_extra = get_extra_radiation(datetime_or_doy)

kt = clearness_index(ghi, zenith, dni_extra, min_cos_zenith=min_cos_zenith,
max_clearness_index=1)

# For Kt < 0.35, set the diffuse fraction
df = 1 - 0.249*kt

# For Kt >= 0.35 and Kt <= 0.75, set the diffuse fraction
df = np.where((kt >= 0.35) & (kt <= 0.75),
1.557 - 1.84*kt, df)

# For Kt > 0.75, set the diffuse fraction
df = np.where(kt > 0.75, 0.177, df)

dhi = df * ghi

dni = (ghi - dhi) / tools.cosd(zenith)
bad_values = (zenith > max_zenith) | (ghi < 0) | (dni < 0)
dni = np.where(bad_values, 0, dni)
# ensure that closure relationship remains valid
dhi = np.where(bad_values, ghi, dhi)

data = OrderedDict()
data['dni'] = dni
data['dhi'] = dhi
data['kt'] = kt

if isinstance(datetime_or_doy, pd.DatetimeIndex):
data = pd.DataFrame(data, index=datetime_or_doy)

return data


def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613,
min_cos_zenith=0.065, max_zenith=87):
r"""
Expand Down Expand Up @@ -2326,6 +2415,7 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613,
dirint
disc
erbs
orgill_hollands
Notes
-----
Expand Down
16 changes: 16 additions & 0 deletions pvlib/tests/test_irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,22 @@ def test_boland():
assert np.allclose(out, expected)


def test_orgill_hollands():
index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
ghi = pd.Series([0, 50, 1000, 1000], index=index)
zenith = pd.Series([120, 85, 10, 10], index=index)
expected = pd.DataFrame(np.array(
[[0.0, 0.0, 0.0],
[108.731366, 40.5234370, 0.405723511],
[776.155771, 235.635779, 0.718132729],
[835.696102, 177.000000, 0.768214312]]),
columns=['dni', 'dhi', 'kt'], index=index)

out = irradiance.orgill_hollands(ghi, zenith, index)

assert np.allclose(out, expected)


def test_erbs_min_cos_zenith_max_zenith():
# map out behavior under difficult conditions with various
# limiting kwargs settings
Expand Down

0 comments on commit fa9dc9b

Please sign in to comment.