Skip to content

Commit

Permalink
Update infinite_sheds.py to add shaded fraction to returned variables…
Browse files Browse the repository at this point in the history
… in infinite_sheds.get_irradiance and infinite_sheds.get_irradiance_poa (#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 <kevin.anderso@gmail.com>

* Update infinite_sheds.py

* Update infinite_sheds.py

* Update infinite_sheds.py

fixed indentation issues

---------

Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com>
  • Loading branch information
williamhobbs and kandersolar authored Oct 4, 2023
1 parent e36e50a commit 46851d9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
5 changes: 4 additions & 1 deletion docs/sphinx/source/whatsnew/v0.10.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ v0.10.3 (Anticipated December, 2023)

Enhancements
~~~~~~~~~~~~

* :py:func:`pvlib.bifacial.infinite_sheds.get_irradiance` and
:py:func:`pvlib.bifacial.infinite_sheds.get_irradiance_poa` now include
shaded fraction in returned variables. (:pull:`1871`)

Bug fixes
~~~~~~~~~
Expand All @@ -26,3 +28,4 @@ Contributors
~~~~~~~~~~~~
* Arjan Keeman (:ghuser:`akeeman`)
* Miguel Sánchez de León Peque (:ghuser:`Peque`)
* Will Hobbs (:ghuser:`williamhobbs`)
12 changes: 11 additions & 1 deletion pvlib/bifacial/infinite_sheds.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
[W/m^2]
- ``poa_ground_diffuse`` : total ground-reflected diffuse irradiance on the
plane of array. [W/m^2]
- ``shaded_fraction`` : fraction of row slant height from the bottom that
is shaded from direct irradiance by adjacent rows. [unitless]
References
----------
Expand Down Expand Up @@ -369,7 +371,7 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
output = {
'poa_global': poa_global, 'poa_direct': poa_direct,
'poa_diffuse': poa_diffuse, 'poa_ground_diffuse': poa_gnd_pv,
'poa_sky_diffuse': poa_sky_pv}
'poa_sky_diffuse': poa_sky_pv, 'shaded_fraction': f_x}
if isinstance(poa_global, pd.Series):
output = pd.DataFrame(output)
return output
Expand Down Expand Up @@ -502,6 +504,9 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
cells from the front surface. [W/m^2]
- ``poa_front_ground_diffuse`` : ground-reflected diffuse irradiance
reaching the module cells from the front surface. [W/m^2]
- ``shaded_fraction_front`` : fraction of row slant height from the bottom
that is shaded from direct irradiance on the front surface by adjacent
rows. [unitless]
- ``poa_back_direct`` : direct irradiance reaching the module cells from
the back surface. [W/m^2]
- ``poa_back_diffuse`` : total diffuse irradiance reaching the module
Expand All @@ -510,6 +515,9 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
cells from the back surface. [W/m^2]
- ``poa_back_ground_diffuse`` : ground-reflected diffuse irradiance
reaching the module cells from the back surface. [W/m^2]
- ``shaded_fraction_back`` : fraction of row slant height from the bottom
that is shaded from direct irradiance on the back surface by adjacent
rows. [unitless]
References
----------
Expand Down Expand Up @@ -545,13 +553,15 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
'poa_diffuse': 'poa_front_diffuse',
'poa_sky_diffuse': 'poa_front_sky_diffuse',
'poa_ground_diffuse': 'poa_front_ground_diffuse',
'shaded_fraction': 'shaded_fraction_front',
}
colmap_back = {
'poa_global': 'poa_back',
'poa_direct': 'poa_back_direct',
'poa_diffuse': 'poa_back_diffuse',
'poa_sky_diffuse': 'poa_back_sky_diffuse',
'poa_ground_diffuse': 'poa_back_ground_diffuse',
'shaded_fraction': 'shaded_fraction_back',
}

if isinstance(ghi, pd.Series):
Expand Down
34 changes: 33 additions & 1 deletion pvlib/tests/bifacial/test_infinite_sheds.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ def test_get_irradiance_poa():
expected_diffuse = np.array([300.])
expected_direct = np.array([700.])
expected_global = expected_diffuse + expected_direct
expected_shaded_fraction = np.array([0.])
assert np.isclose(res['poa_global'], expected_global)
assert np.isclose(res['poa_diffuse'], expected_diffuse)
assert np.isclose(res['poa_direct'], expected_direct)
assert np.isclose(res['shaded_fraction'], expected_shaded_fraction)
# vector inputs
surface_tilt = np.array([0., 0., 0., 0.])
height = 1.
Expand All @@ -115,13 +117,16 @@ def test_get_irradiance_poa():
expected_direct = np.array(
[700., 350. * np.sqrt(2), 350. * np.sqrt(2), 0.])
expected_global = expected_diffuse + expected_direct
expected_shaded_fraction = np.array(
[0., 0., 0., 0.])
res = infinite_sheds.get_irradiance_poa(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni,
albedo, iam=iam, npoints=npoints)
assert np.allclose(res['poa_global'], expected_global)
assert np.allclose(res['poa_diffuse'], expected_diffuse)
assert np.allclose(res['poa_direct'], expected_direct)
assert np.allclose(res['shaded_fraction'], expected_shaded_fraction)
# series inputs
surface_tilt = pd.Series(surface_tilt)
surface_azimuth = pd.Series(data=surface_azimuth, index=surface_tilt.index)
Expand All @@ -133,15 +138,19 @@ def test_get_irradiance_poa():
data=expected_direct, index=surface_tilt.index)
expected_global = expected_diffuse + expected_direct
expected_global.name = 'poa_global' # to match output Series
expected_shaded_fraction = pd.Series(
data=expected_shaded_fraction, index=surface_tilt.index)
expected_shaded_fraction.name = 'shaded_fraction' # to match output Series
res = infinite_sheds.get_irradiance_poa(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni,
albedo, iam=iam, npoints=npoints)
assert isinstance(res, pd.DataFrame)
assert_series_equal(res['poa_global'], expected_global)
assert_series_equal(res['shaded_fraction'], expected_shaded_fraction)
assert all(k in res.columns for k in [
'poa_global', 'poa_diffuse', 'poa_direct', 'poa_ground_diffuse',
'poa_sky_diffuse'])
'poa_sky_diffuse', 'shaded_fraction'])


def test__backside_tilt():
Expand Down Expand Up @@ -177,10 +186,16 @@ def test_get_irradiance(vectorize):
expected_front_diffuse = np.array([300.])
expected_front_direct = np.array([700.])
expected_front_global = expected_front_diffuse + expected_front_direct
expected_shaded_fraction_front = np.array([0.])
expected_shaded_fraction_back = np.array([0.])
assert np.isclose(result['poa_front'], expected_front_global)
assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
assert np.isclose(result['poa_front_direct'], expected_front_direct)
assert np.isclose(result['poa_global'], result['poa_front'])
assert np.isclose(result['shaded_fraction_front'],
expected_shaded_fraction_front)
assert np.isclose(result['shaded_fraction_back'],
expected_shaded_fraction_back)
# series inputs
ghi = pd.Series([1000., 500., 500., np.nan])
dhi = pd.Series([300., 500., 500., 500.], index=ghi.index)
Expand All @@ -200,7 +215,12 @@ def test_get_irradiance(vectorize):
expected_poa_global = pd.Series(
[1000., 500., result_front['poa_global'][2] * (1 + 0.8 * 0.98),
np.nan], index=ghi.index, name='poa_global')
expected_shaded_fraction = pd.Series(
result_front['shaded_fraction'], index=ghi.index,
name='shaded_fraction_front')
assert_series_equal(result['poa_global'], expected_poa_global)
assert_series_equal(result['shaded_fraction_front'],
expected_shaded_fraction)


def test_get_irradiance_limiting_gcr():
Expand Down Expand Up @@ -230,6 +250,8 @@ def test_get_irradiance_limiting_gcr():
expected_direct = np.array([0.])
expected_diffuse = expected_ground_diffuse + expected_sky_diffuse
expected_poa = expected_diffuse + expected_direct
expected_shaded_fraction_front = np.array([0.])
expected_shaded_fraction_back = np.array([0.])
assert np.isclose(result['poa_front'], expected_poa, rtol=0.01)
assert np.isclose(result['poa_front_diffuse'], expected_diffuse, rtol=0.01)
assert np.isclose(result['poa_front_direct'], expected_direct)
Expand All @@ -244,6 +266,10 @@ def test_get_irradiance_limiting_gcr():
result['poa_back_sky_diffuse'])
assert np.isclose(result['poa_front_ground_diffuse'],
result['poa_back_ground_diffuse'])
assert np.isclose(result['shaded_fraction_front'],
expected_shaded_fraction_front)
assert np.isclose(result['shaded_fraction_back'],
expected_shaded_fraction_back)


def test_get_irradiance_with_haydavies():
Expand Down Expand Up @@ -272,10 +298,16 @@ def test_get_irradiance_with_haydavies():
expected_front_diffuse = np.array([151.38])
expected_front_direct = np.array([848.62])
expected_front_global = expected_front_diffuse + expected_front_direct
expected_shaded_fraction_front = np.array([0.])
expected_shaded_fraction_back = np.array([0.])
assert np.isclose(result['poa_front'], expected_front_global)
assert np.isclose(result['poa_front_diffuse'], expected_front_diffuse)
assert np.isclose(result['poa_front_direct'], expected_front_direct)
assert np.isclose(result['poa_global'], result['poa_front'])
assert np.isclose(result['shaded_fraction_front'],
expected_shaded_fraction_front)
assert np.isclose(result['shaded_fraction_back'],
expected_shaded_fraction_back)
# test for when dni_extra is not supplied
with pytest.raises(ValueError, match='supply dni_extra for haydavies'):
result = infinite_sheds.get_irradiance(
Expand Down

0 comments on commit 46851d9

Please sign in to comment.