Skip to content

Commit 46851d9

Browse files
Update infinite_sheds.py to add shaded fraction to returned variables in infinite_sheds.get_irradiance and infinite_sheds.get_irradiance_poa (pvlib#1871)
* Update infinite_sheds.py Added shaded fraction to returned variables. * Update v0.10.3.rst * Update test_infinite_sheds.py added tests for shaded fraction * Update test_infinite_sheds.py Corrected the shaded fraction tests in the haydavies portion. * Update pvlib/bifacial/infinite_sheds.py Co-authored-by: Kevin Anderson <[email protected]> * Update infinite_sheds.py * Update infinite_sheds.py * Update infinite_sheds.py fixed indentation issues --------- Co-authored-by: Kevin Anderson <[email protected]>
1 parent e36e50a commit 46851d9

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ v0.10.3 (Anticipated December, 2023)
77

88
Enhancements
99
~~~~~~~~~~~~
10-
10+
* :py:func:`pvlib.bifacial.infinite_sheds.get_irradiance` and
11+
:py:func:`pvlib.bifacial.infinite_sheds.get_irradiance_poa` now include
12+
shaded fraction in returned variables. (:pull:`1871`)
1113

1214
Bug fixes
1315
~~~~~~~~~
@@ -26,3 +28,4 @@ Contributors
2628
~~~~~~~~~~~~
2729
* Arjan Keeman (:ghuser:`akeeman`)
2830
* Miguel Sánchez de León Peque (:ghuser:`Peque`)
31+
* Will Hobbs (:ghuser:`williamhobbs`)

pvlib/bifacial/infinite_sheds.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
276276
[W/m^2]
277277
- ``poa_ground_diffuse`` : total ground-reflected diffuse irradiance on the
278278
plane of array. [W/m^2]
279+
- ``shaded_fraction`` : fraction of row slant height from the bottom that
280+
is shaded from direct irradiance by adjacent rows. [unitless]
279281
280282
References
281283
----------
@@ -369,7 +371,7 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
369371
output = {
370372
'poa_global': poa_global, 'poa_direct': poa_direct,
371373
'poa_diffuse': poa_diffuse, 'poa_ground_diffuse': poa_gnd_pv,
372-
'poa_sky_diffuse': poa_sky_pv}
374+
'poa_sky_diffuse': poa_sky_pv, 'shaded_fraction': f_x}
373375
if isinstance(poa_global, pd.Series):
374376
output = pd.DataFrame(output)
375377
return output
@@ -502,6 +504,9 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
502504
cells from the front surface. [W/m^2]
503505
- ``poa_front_ground_diffuse`` : ground-reflected diffuse irradiance
504506
reaching the module cells from the front surface. [W/m^2]
507+
- ``shaded_fraction_front`` : fraction of row slant height from the bottom
508+
that is shaded from direct irradiance on the front surface by adjacent
509+
rows. [unitless]
505510
- ``poa_back_direct`` : direct irradiance reaching the module cells from
506511
the back surface. [W/m^2]
507512
- ``poa_back_diffuse`` : total diffuse irradiance reaching the module
@@ -510,6 +515,9 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
510515
cells from the back surface. [W/m^2]
511516
- ``poa_back_ground_diffuse`` : ground-reflected diffuse irradiance
512517
reaching the module cells from the back surface. [W/m^2]
518+
- ``shaded_fraction_back`` : fraction of row slant height from the bottom
519+
that is shaded from direct irradiance on the back surface by adjacent
520+
rows. [unitless]
513521
514522
References
515523
----------
@@ -545,13 +553,15 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
545553
'poa_diffuse': 'poa_front_diffuse',
546554
'poa_sky_diffuse': 'poa_front_sky_diffuse',
547555
'poa_ground_diffuse': 'poa_front_ground_diffuse',
556+
'shaded_fraction': 'shaded_fraction_front',
548557
}
549558
colmap_back = {
550559
'poa_global': 'poa_back',
551560
'poa_direct': 'poa_back_direct',
552561
'poa_diffuse': 'poa_back_diffuse',
553562
'poa_sky_diffuse': 'poa_back_sky_diffuse',
554563
'poa_ground_diffuse': 'poa_back_ground_diffuse',
564+
'shaded_fraction': 'shaded_fraction_back',
555565
}
556566

557567
if isinstance(ghi, pd.Series):

pvlib/tests/bifacial/test_infinite_sheds.py

+33-1
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@ def test_get_irradiance_poa():
100100
expected_diffuse = np.array([300.])
101101
expected_direct = np.array([700.])
102102
expected_global = expected_diffuse + expected_direct
103+
expected_shaded_fraction = np.array([0.])
103104
assert np.isclose(res['poa_global'], expected_global)
104105
assert np.isclose(res['poa_diffuse'], expected_diffuse)
105106
assert np.isclose(res['poa_direct'], expected_direct)
107+
assert np.isclose(res['shaded_fraction'], expected_shaded_fraction)
106108
# vector inputs
107109
surface_tilt = np.array([0., 0., 0., 0.])
108110
height = 1.
@@ -115,13 +117,16 @@ def test_get_irradiance_poa():
115117
expected_direct = np.array(
116118
[700., 350. * np.sqrt(2), 350. * np.sqrt(2), 0.])
117119
expected_global = expected_diffuse + expected_direct
120+
expected_shaded_fraction = np.array(
121+
[0., 0., 0., 0.])
118122
res = infinite_sheds.get_irradiance_poa(
119123
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
120124
gcr, height, pitch, ghi, dhi, dni,
121125
albedo, iam=iam, npoints=npoints)
122126
assert np.allclose(res['poa_global'], expected_global)
123127
assert np.allclose(res['poa_diffuse'], expected_diffuse)
124128
assert np.allclose(res['poa_direct'], expected_direct)
129+
assert np.allclose(res['shaded_fraction'], expected_shaded_fraction)
125130
# series inputs
126131
surface_tilt = pd.Series(surface_tilt)
127132
surface_azimuth = pd.Series(data=surface_azimuth, index=surface_tilt.index)
@@ -133,15 +138,19 @@ def test_get_irradiance_poa():
133138
data=expected_direct, index=surface_tilt.index)
134139
expected_global = expected_diffuse + expected_direct
135140
expected_global.name = 'poa_global' # to match output Series
141+
expected_shaded_fraction = pd.Series(
142+
data=expected_shaded_fraction, index=surface_tilt.index)
143+
expected_shaded_fraction.name = 'shaded_fraction' # to match output Series
136144
res = infinite_sheds.get_irradiance_poa(
137145
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
138146
gcr, height, pitch, ghi, dhi, dni,
139147
albedo, iam=iam, npoints=npoints)
140148
assert isinstance(res, pd.DataFrame)
141149
assert_series_equal(res['poa_global'], expected_global)
150+
assert_series_equal(res['shaded_fraction'], expected_shaded_fraction)
142151
assert all(k in res.columns for k in [
143152
'poa_global', 'poa_diffuse', 'poa_direct', 'poa_ground_diffuse',
144-
'poa_sky_diffuse'])
153+
'poa_sky_diffuse', 'shaded_fraction'])
145154

146155

147156
def test__backside_tilt():
@@ -177,10 +186,16 @@ def test_get_irradiance(vectorize):
177186
expected_front_diffuse = np.array([300.])
178187
expected_front_direct = np.array([700.])
179188
expected_front_global = expected_front_diffuse + expected_front_direct
189+
expected_shaded_fraction_front = np.array([0.])
190+
expected_shaded_fraction_back = np.array([0.])
180191
assert np.isclose(result['poa_front'], expected_front_global)
181192
assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
182193
assert np.isclose(result['poa_front_direct'], expected_front_direct)
183194
assert np.isclose(result['poa_global'], result['poa_front'])
195+
assert np.isclose(result['shaded_fraction_front'],
196+
expected_shaded_fraction_front)
197+
assert np.isclose(result['shaded_fraction_back'],
198+
expected_shaded_fraction_back)
184199
# series inputs
185200
ghi = pd.Series([1000., 500., 500., np.nan])
186201
dhi = pd.Series([300., 500., 500., 500.], index=ghi.index)
@@ -200,7 +215,12 @@ def test_get_irradiance(vectorize):
200215
expected_poa_global = pd.Series(
201216
[1000., 500., result_front['poa_global'][2] * (1 + 0.8 * 0.98),
202217
np.nan], index=ghi.index, name='poa_global')
218+
expected_shaded_fraction = pd.Series(
219+
result_front['shaded_fraction'], index=ghi.index,
220+
name='shaded_fraction_front')
203221
assert_series_equal(result['poa_global'], expected_poa_global)
222+
assert_series_equal(result['shaded_fraction_front'],
223+
expected_shaded_fraction)
204224

205225

206226
def test_get_irradiance_limiting_gcr():
@@ -230,6 +250,8 @@ def test_get_irradiance_limiting_gcr():
230250
expected_direct = np.array([0.])
231251
expected_diffuse = expected_ground_diffuse + expected_sky_diffuse
232252
expected_poa = expected_diffuse + expected_direct
253+
expected_shaded_fraction_front = np.array([0.])
254+
expected_shaded_fraction_back = np.array([0.])
233255
assert np.isclose(result['poa_front'], expected_poa, rtol=0.01)
234256
assert np.isclose(result['poa_front_diffuse'], expected_diffuse, rtol=0.01)
235257
assert np.isclose(result['poa_front_direct'], expected_direct)
@@ -244,6 +266,10 @@ def test_get_irradiance_limiting_gcr():
244266
result['poa_back_sky_diffuse'])
245267
assert np.isclose(result['poa_front_ground_diffuse'],
246268
result['poa_back_ground_diffuse'])
269+
assert np.isclose(result['shaded_fraction_front'],
270+
expected_shaded_fraction_front)
271+
assert np.isclose(result['shaded_fraction_back'],
272+
expected_shaded_fraction_back)
247273

248274

249275
def test_get_irradiance_with_haydavies():
@@ -272,10 +298,16 @@ def test_get_irradiance_with_haydavies():
272298
expected_front_diffuse = np.array([151.38])
273299
expected_front_direct = np.array([848.62])
274300
expected_front_global = expected_front_diffuse + expected_front_direct
301+
expected_shaded_fraction_front = np.array([0.])
302+
expected_shaded_fraction_back = np.array([0.])
275303
assert np.isclose(result['poa_front'], expected_front_global)
276304
assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
277305
assert np.isclose(result['poa_front_direct'], expected_front_direct)
278306
assert np.isclose(result['poa_global'], result['poa_front'])
307+
assert np.isclose(result['shaded_fraction_front'],
308+
expected_shaded_fraction_front)
309+
assert np.isclose(result['shaded_fraction_back'],
310+
expected_shaded_fraction_back)
279311
# test for when dni_extra is not supplied
280312
with pytest.raises(ValueError, match='supply dni_extra for haydavies'):
281313
result = infinite_sheds.get_irradiance(

0 commit comments

Comments
 (0)