Skip to content

Commit 4f3b7e4

Browse files
wholmgrencwhanse
authored andcommitted
limit cos(aoi) in diffuse sky functions (#535)
* limit cos(aoi) in diffuse sky functions * no limit on cos_solar_zenith in hb calculation. change proj limit to -1 * reimplement without projection_minimum kwarg * fix np.minimum vs. np.maximum * update tutorial * add sky diffuse test for zenith close to 90 * fix botched whatsnew merge [skip ci]
1 parent 487cdb9 commit 4f3b7e4

File tree

4 files changed

+68
-45
lines changed

4 files changed

+68
-45
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ Bug fixes
111111
floats and NumPy arrays. (:issue:`508`)
112112
* Make GitHub recognize the license, add AUTHORS.md, clarify shared copyright.
113113
(:issue:`503`)
114+
* Fix issue with non-zero direct irradiance contribution to Reindl, Klucher,
115+
and Hay-Davies diffuse sky algorithms when the sun is behind the array.
116+
(:issue:`526`)
117+
* Fix issue with dividing by near-0 cos(solar_zenith) values in Reindl and
118+
Hay-Davies diffuse sky algorithms. (:issue:`432`)
114119
* Fix argument order of longitude and latitude when querying weather forecasts
115120
by lonlat bounding box (:issue:`521`)
116121

docs/tutorials/irradiance.ipynb

Lines changed: 39 additions & 39 deletions
Large diffs are not rendered by default.

pvlib/irradiance.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def poa_horizontal_ratio(surface_tilt, surface_azimuth,
256256

257257
cos_solar_zenith = tools.cosd(solar_zenith)
258258

259-
# ratio of titled and horizontal beam irradiance
259+
# ratio of tilted and horizontal beam irradiance
260260
ratio = cos_poa_zen / cos_solar_zenith
261261

262262
try:
@@ -746,6 +746,7 @@ def klucher(surface_tilt, surface_azimuth, dhi, ghi, solar_zenith,
746746
# zenith angle with respect to panel normal.
747747
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
748748
solar_zenith, solar_azimuth)
749+
cos_tt = np.maximum(cos_tt, 0) # GH 526
749750

750751
F = 1 - ((dhi / ghi) ** 2)
751752
try:
@@ -836,8 +837,9 @@ def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
836837
if projection_ratio is None:
837838
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
838839
solar_zenith, solar_azimuth)
840+
cos_tt = np.maximum(cos_tt, 0) # GH 526
839841
cos_solar_zenith = tools.cosd(solar_zenith)
840-
Rb = cos_tt / cos_solar_zenith
842+
Rb = cos_tt / np.maximum(cos_solar_zenith, 0.01745) # GH 432
841843
else:
842844
Rb = projection_ratio
843845

@@ -932,11 +934,13 @@ def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
932934

933935
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
934936
solar_zenith, solar_azimuth)
937+
cos_tt = np.maximum(cos_tt, 0) # GH 526
935938

939+
# do not apply cos(zen) limit here (needed for HB below)
936940
cos_solar_zenith = tools.cosd(solar_zenith)
937941

938942
# ratio of titled and horizontal beam irradiance
939-
Rb = cos_tt / cos_solar_zenith
943+
Rb = cos_tt / np.maximum(cos_solar_zenith, 0.01745) # GH 432
940944

941945
# Anisotropy Index
942946
AI = dni / dni_extra

pvlib/test/test_irradiance.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ def test_klucher_series(irrad_data, ephem_data):
181181
result = irradiance.klucher(40, 180, irrad_data['dhi'], irrad_data['ghi'],
182182
ephem_data['apparent_zenith'],
183183
ephem_data['azimuth'])
184-
assert_allclose(result, [0, 37.446276, 109.209347, 56.965916], atol=1e-4)
184+
# pvlib matlab 1.4 does not contain the max(cos_tt, 0) correction
185+
# so, these values are different
186+
assert_allclose(result, [0., 36.789794, 109.209347, 56.965916], atol=1e-4)
185187
# expect same result for np.array and pd.Series
186188
expected = irradiance.klucher(
187189
40, 180, irrad_data['dhi'].values, irrad_data['ghi'].values,
@@ -195,15 +197,17 @@ def test_haydavies(irrad_data, ephem_data, dni_et):
195197
dni_et,
196198
ephem_data['apparent_zenith'],
197199
ephem_data['azimuth'])
198-
assert_allclose(result, [0, 14.967008, 102.994862, 33.190865], atol=1e-4)
200+
# values from matlab 1.4 code
201+
assert_allclose(result, [0, 27.1775, 102.9949, 33.1909], atol=1e-4)
199202

200203

201204
def test_reindl(irrad_data, ephem_data, dni_et):
202205
result = irradiance.reindl(40, 180, irrad_data['dhi'], irrad_data['dni'],
203206
irrad_data['ghi'], dni_et,
204207
ephem_data['apparent_zenith'],
205208
ephem_data['azimuth'])
206-
assert_allclose(result, [np.nan, 15.730664, 104.131724, 34.166258], atol=1e-4)
209+
# values from matlab 1.4 code
210+
assert_allclose(result, [np.nan, 27.9412, 104.1317, 34.1663], atol=1e-4)
207211

208212

209213
def test_king(irrad_data, ephem_data):
@@ -265,6 +269,16 @@ def test_perez_arrays(irrad_data, ephem_data, dni_et, relative_airmass):
265269
assert_allclose(out, expected, atol=1e-2)
266270

267271

272+
@pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies',
273+
'reindl', 'king', 'perez'])
274+
def test_sky_diffuse_zenith_close_to_90(model):
275+
# GH 432
276+
sky_diffuse = irradiance.get_sky_diffuse(
277+
30, 180, 89.999, 230,
278+
dni=10, ghi=51, dhi=50, dni_extra=1360, airmass=12, model=model)
279+
assert sky_diffuse < 100
280+
281+
268282
def test_liujordan():
269283
expected = pd.DataFrame(np.
270284
array([[863.859736967, 653.123094076, 220.65905025]]),

0 commit comments

Comments
 (0)