Skip to content

Commit 9a74404

Browse files
committed
limit cos(aoi) in diffuse sky functions
1 parent 10339ee commit 9a74404

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ API Changes
4949
enhancement factor can yield unphysical results, especially for latitudes
5050
closer to the poles and especially in the winter months. It may yield
5151
improved results under other conditions. (:issue:`435`)
52+
* Add projection_minimum keyword argument to irradiance.aoi_projection.
53+
Default behavior remains the same. (:issue:`526`)
5254

5355

5456
Enhancements
@@ -109,6 +111,11 @@ Bug fixes
109111
* Make GitHub recognize the license, add AUTHORS.md, clarify shared copyright.
110112
(:issue:`503`)
111113
* Fix argument order of longitude and latitude when querying weather forecasts by lonlat bounding box (:issue:`521`)
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`)
112119

113120

114121
Documentation

pvlib/irradiance.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ def _handle_extra_radiation_types(datetime_or_doy, epoch_year):
152152
return to_doy, to_datetimeindex, to_output
153153

154154

155-
def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
155+
def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
156+
projection_minimum=None):
156157
"""
157158
Calculates the dot product of the solar vector and the surface
158159
normal.
@@ -169,6 +170,11 @@ def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
169170
Solar zenith angle.
170171
solar_azimuth : numeric
171172
Solar azimuth angle.
173+
projection_minimum : None or numeric, default None
174+
Minimum allowable value for the projection for the solar angle
175+
into the plane of the array. For example, 0 is equivalent to a
176+
90 degree limit, 0.01745 is equivalent to a 89 degree limit.
177+
`None` applies no limit.
172178
173179
Returns
174180
-------
@@ -181,6 +187,9 @@ def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
181187
tools.sind(surface_tilt) * tools.sind(solar_zenith) *
182188
tools.cosd(solar_azimuth - surface_azimuth))
183189

190+
if projection_minimum is not None:
191+
projection = np.maximum(projection, projection_minimum)
192+
184193
try:
185194
projection.name = 'aoi_projection'
186195
except AttributeError:
@@ -226,7 +235,9 @@ def aoi(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
226235

227236

228237
def poa_horizontal_ratio(surface_tilt, surface_azimuth,
229-
solar_zenith, solar_azimuth):
238+
solar_zenith, solar_azimuth,
239+
poa_projection_minimum=None,
240+
solar_zenith_projection_minimum=None):
230241
"""
231242
Calculates the ratio of the beam components of the plane of array
232243
irradiance and the horizontal irradiance.
@@ -243,6 +254,12 @@ def poa_horizontal_ratio(surface_tilt, surface_azimuth,
243254
Solar zenith angle.
244255
solar_azimuth : numeric
245256
Solar azimuth angle.
257+
poa_projection_minimum : None or numeric, default None
258+
Minimum allowable value for the projection for the solar angle
259+
into the plane of the array. `None` applies no limit.
260+
solar_zenith_projection_minimum : numeric, default None
261+
Minimum allowable value for the projection of the solar angle
262+
on to a horizontal surface. `None` applies no limit.
246263
247264
Returns
248265
-------
@@ -252,10 +269,15 @@ def poa_horizontal_ratio(surface_tilt, surface_azimuth,
252269
"""
253270

254271
cos_poa_zen = aoi_projection(surface_tilt, surface_azimuth,
255-
solar_zenith, solar_azimuth)
272+
solar_zenith, solar_azimuth,
273+
projection_minimum=poa_projection_minimum)
256274

257275
cos_solar_zenith = tools.cosd(solar_zenith)
258276

277+
if solar_zenith_projection_minimum is not None:
278+
cos_solar_zenith = np.maximum(cos_solar_zenith,
279+
solar_zenith_projection_minimum)
280+
259281
# ratio of titled and horizontal beam irradiance
260282
ratio = cos_poa_zen / cos_solar_zenith
261283

@@ -745,7 +767,8 @@ def klucher(surface_tilt, surface_azimuth, dhi, ghi, solar_zenith,
745767

746768
# zenith angle with respect to panel normal.
747769
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
748-
solar_zenith, solar_azimuth)
770+
solar_zenith, solar_azimuth,
771+
projection_minimum=0)
749772

750773
F = 1 - ((dhi / ghi) ** 2)
751774
try:
@@ -835,8 +858,9 @@ def haydavies(surface_tilt, surface_azimuth, dhi, dni, dni_extra,
835858
# if necessary, calculate ratio of titled and horizontal beam irradiance
836859
if projection_ratio is None:
837860
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
838-
solar_zenith, solar_azimuth)
839-
cos_solar_zenith = tools.cosd(solar_zenith)
861+
solar_zenith, solar_azimuth,
862+
projection_minimum=0)
863+
cos_solar_zenith = np.maximum(tools.cosd(solar_zenith), 0.01745)
840864
Rb = cos_tt / cos_solar_zenith
841865
else:
842866
Rb = projection_ratio
@@ -931,9 +955,10 @@ def reindl(surface_tilt, surface_azimuth, dhi, dni, ghi, dni_extra,
931955
'''
932956

933957
cos_tt = aoi_projection(surface_tilt, surface_azimuth,
934-
solar_zenith, solar_azimuth)
958+
solar_zenith, solar_azimuth,
959+
projection_minimum=0)
935960

936-
cos_solar_zenith = tools.cosd(solar_zenith)
961+
cos_solar_zenith = np.maximum(tools.cosd(solar_zenith), 0.01745)
937962

938963
# ratio of titled and horizontal beam irradiance
939964
Rb = cos_tt / cos_solar_zenith

0 commit comments

Comments
 (0)