From 5cfe247fd15d1d43e4644472de6e1dbee7df9273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Wed, 10 May 2023 16:42:07 -0600 Subject: [PATCH 01/13] add orgill hollands decomposition --- pvlib/irradiance.py | 78 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index c5c3b1c095..60dbed6442 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2193,6 +2193,8 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87): -------- dirint disc + orgill_hollands + bolland """ dni_extra = get_extra_radiation(datetime_or_doy) @@ -2230,6 +2232,82 @@ 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, min_cos_zenith=0.065, + max_zenith=87): + """ + Estimate DNI and DHI from GHI using the Orgill and Hollands [1] 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. + 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 + ------- + None. + + 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) + + See also + -------- + dirint + disc + erbs + bolland + + """ + 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 campbell_norman(zenith, transmittance, pressure=101325.0, dni_extra=1367.0): From f4849ce2a9f59a1384c3ca9b25d2b12a71db903d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Wed, 10 May 2023 18:00:18 -0600 Subject: [PATCH 02/13] Fix Stickler --- pvlib/irradiance.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 60dbed6442..020f7ef3f9 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2232,16 +2232,16 @@ 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, min_cos_zenith=0.065, + +def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87): - """ - Estimate DNI and DHI from GHI using the Orgill and Hollands [1] 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. - + """Estimate DNI and DHI from GHI using the Orgill and Hollands [1] 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 @@ -2257,18 +2257,18 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, 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 ------- None. 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. + radiation on a horizontal surface, Solar Energy 19(4), pp 357–359, 1977. Eqs. 3(a), 3(b) and 3(c) - - See also + + See Also -------- dirint disc @@ -2286,7 +2286,7 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, # 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) + 1.557 - 1.84*kt, df) # For Kt > 0.75, set the diffuse fraction df = np.where(kt > 0.75, 0.177, df) @@ -2309,6 +2309,7 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, return data + def campbell_norman(zenith, transmittance, pressure=101325.0, dni_extra=1367.0): ''' From 7c5e72d21fa4b771a698fced636eaaae5c526d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 25 May 2023 13:04:03 +0200 Subject: [PATCH 03/13] Update pvlib/irradiance.py correct spelling to 'boland' Co-authored-by: Cliff Hansen --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 020f7ef3f9..2df3de2ade 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2194,7 +2194,7 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87): dirint disc orgill_hollands - bolland + boland """ dni_extra = get_extra_radiation(datetime_or_doy) From 097fe52e2b5666d1129a265394a320e03a41af44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 25 May 2023 13:04:47 +0200 Subject: [PATCH 04/13] Update pvlib/irradiance.py correct citation formating Co-authored-by: Cliff Hansen --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 2df3de2ade..febf92110a 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2235,9 +2235,9 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87): def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87): - """Estimate DNI and DHI from GHI using the Orgill and Hollands [1] model. + """Estimate DNI and DHI from GHI using the Orgill and Hollands model. - The Orgill and Hollands model [1] estimates the diffuse fraction DF from + 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. From 92fea798182e77615a354244d44efa0a16a68621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 25 May 2023 13:05:16 +0200 Subject: [PATCH 05/13] Update pvlib/irradiance.py correct citation formatting Co-authored-by: Cliff Hansen --- pvlib/irradiance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index febf92110a..ce31b9317c 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2264,9 +2264,9 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, 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) + .. [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) See Also -------- From decabb4fb698e661b6d80f05be8240a04fd80e98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 25 May 2023 13:06:05 +0200 Subject: [PATCH 06/13] Update pvlib/irradiance.py correct spelling 'boland' Co-authored-by: Cliff Hansen --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index ce31b9317c..384a3640f0 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2273,7 +2273,7 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, dirint disc erbs - bolland + boland """ dni_extra = get_extra_radiation(datetime_or_doy) From b8b4b3a255f642e9dd25bfcd2824f301a018bed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 25 May 2023 13:23:38 +0200 Subject: [PATCH 07/13] Update irradiance.py adding dni_extra argument per cliff's suggestion. --- pvlib/irradiance.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 384a3640f0..b75b68427a 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2233,8 +2233,8 @@ 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, min_cos_zenith=0.065, - max_zenith=87): +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 @@ -2251,6 +2251,8 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, 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. @@ -2264,9 +2266,9 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, 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) + .. [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) See Also -------- @@ -2276,7 +2278,8 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, boland """ - dni_extra = get_extra_radiation(datetime_or_doy) + 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) From f8b7dd90e42d146474e7206084024bab1fcc5e1a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:44:25 +0200 Subject: [PATCH 08/13] Remove edits to boland --- pvlib/irradiance.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 8015edc9fa..d71f095bd1 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2360,6 +2360,7 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613, \mathit{DF} = \frac{1}{1 + \exp\left(a \left(k_t - b\right)\right)} + Parameters ---------- ghi: numeric @@ -2402,9 +2403,11 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613, :doi:`10.1002/1099-095X(200103)12:2%3C103::AID-ENV447%3E3.0.CO;2-2` See also + -------- dirint disc erbs + orgill_hollands Notes ----- @@ -2433,7 +2436,6 @@ def boland(ghi, solar_zenith, datetime_or_doy, a_coeff=8.645, b_coeff=0.613, dni = (ghi - dhi) / tools.cosd(solar_zenith) bad_values = (solar_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) From b3d5cf0f6321402b213278613b02ab621e289d5c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:48:04 +0200 Subject: [PATCH 09/13] Fix references and add output description --- pvlib/irradiance.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index d71f095bd1..beec6dd0b2 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -2296,13 +2296,21 @@ def orgill_hollands(ghi, zenith, datetime_or_doy, dni_extra=None, Returns ------- - None. + 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) + 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 -------- From 150c22ecc8722542fe5b2ab18a761853ae07caa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Thu, 22 Jun 2023 10:25:35 +0200 Subject: [PATCH 10/13] Update decomposition.rst Update docs --- docs/sphinx/source/reference/irradiance/decomposition.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sphinx/source/reference/irradiance/decomposition.rst b/docs/sphinx/source/reference/irradiance/decomposition.rst index 0677d6ac95..08724be38e 100644 --- a/docs/sphinx/source/reference/irradiance/decomposition.rst +++ b/docs/sphinx/source/reference/irradiance/decomposition.rst @@ -12,6 +12,7 @@ DNI estimation models irradiance.dirint irradiance.dirindex irradiance.erbs + irradiance.orgill_hollands irradiance.boland irradiance.campbell_norman irradiance.gti_dirint From ecfb0e86a3bfdfac6fb723a1aa72e3458ec3d251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Sun, 25 Jun 2023 20:09:30 +0200 Subject: [PATCH 11/13] Update test_irradiance.py Adding a test --- pvlib/tests/test_irradiance.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index d0158dad1a..9d0eae6731 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -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.405724], + [776.155771, 235.635779, 0.718133], + [835.696102, 177.000000, 0.768214]]), + columns=['dni', 'dhi', 'kt'], index=index) + + out = irradiance.boland(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 From 121856418b03b7ec7ae03e929e630f35ab27b9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Sun, 25 Jun 2023 20:50:51 +0200 Subject: [PATCH 12/13] Update test_irradiance.py fixing the perilous outcome of copy/pasting the test_boland function. --- pvlib/tests/test_irradiance.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 9d0eae6731..ab1af612a7 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -827,12 +827,12 @@ def test_orgill_hollands(): 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.405724], - [776.155771, 235.635779, 0.718133], - [835.696102, 177.000000, 0.768214]]), + [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.boland(ghi, zenith, index) + out = irradiance.orgill_hollands(ghi, zenith, index) assert np.allclose(out, expected) From 0b42c440286316b5811d48e503fc51fd6c460739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicholas=20Riedel-Lyngsk=C3=A6r?= <51864101+nicorie@users.noreply.github.com> Date: Wed, 28 Jun 2023 13:02:43 +0200 Subject: [PATCH 13/13] Update v0.10.0.rst Adding Orgill Hollands model to list of enhancements. --- docs/sphinx/source/whatsnew/v0.10.0.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.10.0.rst b/docs/sphinx/source/whatsnew/v0.10.0.rst index a4406072f8..ad7e941e70 100644 --- a/docs/sphinx/source/whatsnew/v0.10.0.rst +++ b/docs/sphinx/source/whatsnew/v0.10.0.rst @@ -21,7 +21,7 @@ Deprecations Enhancements ~~~~~~~~~~~~ - +* Added a new irradiance decomposition model :py:func:`pvlib.irradiance.orgill_hollands`. (:pull:`1730`) Bug fixes ~~~~~~~~~ @@ -45,3 +45,5 @@ Requirements Contributors ~~~~~~~~~~~~ * Taos Transue (:ghuser:`reepoi`) +* Nicholas Riedel-Lyngskær (:ghuser:`nicorie`) +