Skip to content
33 changes: 23 additions & 10 deletions pvlib/bifacial/infinite_sheds.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def _shaded_fraction(solar_zenith, solar_azimuth, surface_tilt,
def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
solar_azimuth, gcr, height, pitch, ghi, dhi, dni,
albedo, model='isotropic', dni_extra=None, iam=1.0,
npoints=100, vectorize=False):
npoints=None, vectorize=None):
r"""
Calculate plane-of-array (POA) irradiance on one side of a row of modules.

Expand Down Expand Up @@ -250,12 +250,19 @@ def get_irradiance_poa(surface_tilt, surface_azimuth, solar_zenith,
on the surface that is not reflected away. [unitless]

npoints : int, default 100
Number of discretization points for calculating integrated view
factors.

.. deprecated:: v0.11.2

This parameter has no effect; integrated view factors are now
calculated exactly instead of with discretized approximations.

vectorize : bool, default False
If True, vectorize the view factor calculation across ``surface_tilt``.
This increases speed with the cost of increased memory usage.

.. deprecated:: v0.11.2

This parameter has no effect; calculations are now vectorized
with no memory usage penality.


Returns
-------
Expand Down Expand Up @@ -381,7 +388,7 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni,
albedo, model='isotropic', dni_extra=None, iam_front=1.0,
iam_back=1.0, bifaciality=0.8, shade_factor=-0.02,
transmission_factor=0, npoints=100, vectorize=False):
transmission_factor=0, npoints=None, vectorize=None):
"""
Get front and rear irradiance using the infinite sheds model.

Expand Down Expand Up @@ -472,12 +479,18 @@ def get_irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
etc. A negative value is a reduction in back irradiance. [unitless]

npoints : int, default 100
Number of discretization points for calculating integrated view
factors.

.. deprecated:: v0.11.2

This parameter has no effect; integrated view factors are now
calculated exactly instead of with discretized approximations.

vectorize : bool, default False
If True, vectorize the view factor calculation across ``surface_tilt``.
This increases speed with the cost of increased memory usage.

.. deprecated:: v0.11.2

This parameter has no effect; calculations are now vectorized
with no memory usage penality.

Returns
-------
Expand Down
6 changes: 4 additions & 2 deletions pvlib/bifacial/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import warnings
from pvlib._deprecation import pvlibDeprecationWarning


def _solar_projection_tangent(solar_zenith, solar_azimuth, surface_azimuth):
"""
Tangent of the angle between the zenith vector and the sun vector
Expand Down Expand Up @@ -243,8 +244,9 @@ def vf_ground_sky_2d_integ(surface_tilt, gcr, height, pitch, max_rows=10,
collector_width = pitch * gcr
surface_tilt = np.atleast_2d(np.abs(surface_tilt))

# TODO figure out if this range is correct, or if the original code has a bug
k = np.arange(-max_rows+1, max_rows+1)[:, np.newaxis]
# TODO seems like this should be np.arange(-max_rows, max_rows+1)?
# see GH #1867
k = np.arange(-max_rows, max_rows)[:, np.newaxis]

# primary crossed string points:
# a, b: boundaries of ground segment
Expand Down
54 changes: 36 additions & 18 deletions pvlib/tests/bifacial/test_infinite_sheds.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from pvlib.bifacial import infinite_sheds
from ..conftest import assert_series_equal

from pvlib._deprecation import pvlibDeprecationWarning

import pytest


Expand Down Expand Up @@ -92,11 +94,10 @@ def test_get_irradiance_poa():
dni = 700
albedo = 0
iam = 1.0
npoints = 100
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)
albedo, iam=iam)
expected_diffuse = np.array([300.])
expected_direct = np.array([700.])
expected_global = expected_diffuse + expected_direct
Expand All @@ -122,7 +123,7 @@ def test_get_irradiance_poa():
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)
albedo, iam=iam)
assert np.allclose(res['poa_global'], expected_global)
assert np.allclose(res['poa_diffuse'], expected_diffuse)
assert np.allclose(res['poa_direct'], expected_direct)
Expand All @@ -144,7 +145,7 @@ def test_get_irradiance_poa():
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)
albedo, iam=iam)
assert isinstance(res, pd.DataFrame)
assert_series_equal(res['poa_global'], expected_global)
assert_series_equal(res['shaded_fraction'], expected_shaded_fraction)
Expand All @@ -161,8 +162,7 @@ def test__backside_tilt():
assert np.allclose(back_az, np.array([0., 330., 90., 180.]))


@pytest.mark.parametrize("vectorize", [True, False])
def test_get_irradiance(vectorize):
def test_get_irradiance():
# singleton inputs
solar_zenith = 0.
solar_azimuth = 180.
Expand All @@ -177,12 +177,10 @@ def test_get_irradiance(vectorize):
albedo = 0.
iam_front = 1.0
iam_back = 1.0
npoints = 100
result = infinite_sheds.get_irradiance(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
bifaciality=0.8, shade_factor=-0.02, transmission_factor=0,
npoints=npoints, vectorize=vectorize)
bifaciality=0.8, shade_factor=-0.02, transmission_factor=0)
expected_front_diffuse = np.array([300.])
expected_front_direct = np.array([700.])
expected_front_global = expected_front_diffuse + expected_front_direct
Expand All @@ -205,12 +203,11 @@ def test_get_irradiance(vectorize):
result = infinite_sheds.get_irradiance(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
bifaciality=0.8, shade_factor=-0.02, transmission_factor=0,
npoints=npoints, vectorize=vectorize)
bifaciality=0.8, shade_factor=-0.02, transmission_factor=0)
result_front = infinite_sheds.get_irradiance_poa(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni,
albedo, iam=iam_front, vectorize=vectorize)
albedo, iam=iam_front)
assert isinstance(result, pd.DataFrame)
expected_poa_global = pd.Series(
[1000., 500., result_front['poa_global'][2] * (1 + 0.8 * 0.98),
Expand All @@ -223,6 +220,30 @@ def test_get_irradiance(vectorize):
expected_shaded_fraction)


def test_get_irradiance_deprecated():
kwargs = {"surface_tilt": 0, "surface_azimuth": 0, "solar_zenith": 0,
"solar_azimuth": 0, "gcr": 0.5, "height": 1, "pitch": 1,
"ghi": 1000, "dhi": 200, "dni": 800, "albedo": 0.2}

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = infinite_sheds.get_irradiance(**kwargs, npoints=10)

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = infinite_sheds.get_irradiance(**kwargs, vectorize=True)


def test_get_irradiance_poa_deprecated():
kwargs = {"surface_tilt": 0, "surface_azimuth": 0, "solar_zenith": 0,
"solar_azimuth": 0, "gcr": 0.5, "height": 1, "pitch": 1,
"ghi": 1000, "dhi": 200, "dni": 800, "albedo": 0.2}

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = infinite_sheds.get_irradiance_poa(**kwargs, npoints=10)

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = infinite_sheds.get_irradiance_poa(**kwargs, vectorize=True)


def test_get_irradiance_limiting_gcr():
# test confirms that irradiance on widely spaced rows is approximately
# the same as for a single row array
Expand All @@ -239,12 +260,10 @@ def test_get_irradiance_limiting_gcr():
albedo = 1.
iam_front = 1.0
iam_back = 1.0
npoints = 100
result = infinite_sheds.get_irradiance(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni, albedo, iam_front, iam_back,
bifaciality=1., shade_factor=-0.00, transmission_factor=0.,
npoints=npoints)
bifaciality=1., shade_factor=-0.00, transmission_factor=0.)
expected_ground_diffuse = np.array([500.])
expected_sky_diffuse = np.array([150.])
expected_direct = np.array([0.])
Expand Down Expand Up @@ -289,12 +308,11 @@ def test_get_irradiance_with_haydavies():
model = 'haydavies'
iam_front = 1.0
iam_back = 1.0
npoints = 100
result = infinite_sheds.get_irradiance(
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni, albedo, model, dni_extra,
iam_front, iam_back, bifaciality=0.8, shade_factor=-0.02,
transmission_factor=0, npoints=npoints)
transmission_factor=0)
expected_front_diffuse = np.array([151.38])
expected_front_direct = np.array([848.62])
expected_front_global = expected_front_diffuse + expected_front_direct
Expand All @@ -314,4 +332,4 @@ def test_get_irradiance_with_haydavies():
surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
gcr, height, pitch, ghi, dhi, dni, albedo, model, None,
iam_front, iam_back, bifaciality=0.8, shade_factor=-0.02,
transmission_factor=0, npoints=npoints)
transmission_factor=0)
30 changes: 19 additions & 11 deletions pvlib/tests/bifacial/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from pvlib.tools import cosd
from scipy.integrate import trapezoid

from pvlib._deprecation import pvlibDeprecationWarning


@pytest.fixture
def test_system_fixed_tilt():
Expand Down Expand Up @@ -91,17 +93,23 @@ def test__vf_ground_sky_2d(test_system_fixed_tilt):
assert np.isclose(vf, vfs_gnd_sky[0])


@pytest.mark.parametrize("vectorize", [True, False])
def test_vf_ground_sky_2d_integ(test_system_fixed_tilt, vectorize):
ts, pts, vfs_gnd_sky = test_system_fixed_tilt
# pass rotation here since max_rows=1 for the hand-solved case in
# the fixture test_system, which means the ground-to-sky view factor
# isn't summed over enough rows for symmetry to hold.
vf_integ = utils.vf_ground_sky_2d_integ(
ts['rotation'], ts['gcr'], ts['height'], ts['pitch'],
max_rows=1, npoints=3, vectorize=vectorize)
expected_vf_integ = trapezoid(vfs_gnd_sky, pts, axis=0)
assert np.isclose(vf_integ, expected_vf_integ, rtol=0.1)
def test_vf_ground_sky_2d_integ():
# test against numerical integration with vf_ground_sky_2d
x = np.linspace(0, 1, num=1000)
kwargs = dict(gcr=0.4, pitch=5.0, height=1.5)
vf_x = utils.vf_ground_sky_2d(rotation=-60, x=x, **kwargs)
vf_expected = trapezoid(vf_x, x, axis=0)

vf_actual = utils.vf_ground_sky_2d_integ(surface_tilt=60, **kwargs)
assert np.isclose(vf_expected, vf_actual)


def test_vf_ground_sky_2d_integ_deprecated():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def test_vf_ground_sky_2d_integ_deprecated():
@fail_on_pvlib_version(...)
def test_vf_ground_sky_2d_integ_deprecated():

Let's make sure docs and code gets cleaned in the future? v0.12 or v0.13, whatever feels right. I would also add the future version to deprecate in the docs admonition.

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = utils.vf_ground_sky_2d_integ(0, 0.5, 1, 1, npoints=10)

with pytest.warns(pvlibDeprecationWarning, match="have no effect"):
_ = utils.vf_ground_sky_2d_integ(0, 0.5, 1, 1, vectorize=True)


def test_vf_row_sky_2d(test_system_fixed_tilt):
Expand Down