Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/sphinx/source/whatsnew/v0.16.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Breaking Changes
* Removed the deprecated ``server`` keyword argument from
:py:func:`pvlib.iotools.sodapro.get_cams`. Use ``url`` instead.
(:issue:`2767`, :pull:`2766`)
* Changed the output type of :py:func:`pvlib.iam.marion_ruiz_diffuse`
and :py:func:`pvlib.iam.schlick_diffuse` from tuple to ``dict``, to be
consistent with :py:func:`pvlib.iam.marion_diffuse`. (:issue:`2837`,
:pull:`2842`)

Deprecations
~~~~~~~~~~~~
Expand Down
26 changes: 15 additions & 11 deletions pvlib/iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,11 @@ def martin_ruiz_diffuse(surface_tilt, a_r=0.16, c1=0.4244, c2=None):

Returns
-------
iam_sky : numeric
The incident angle modifier for sky diffuse
iam : dict
IAM values for each type of diffuse irradiance (assuming isotropy):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
IAM values for each type of diffuse irradiance (assuming isotropy):
IAM values for each type of diffuse irradiance:

This remark belongs in the docstring's summary section. It's about the model's assumption, rather than describing the values returned by the model. Placing it on the parameter description suggests that there's an option to consider non-isotropic irradiance.

    Determine the incidence angle modifiers (IAMs) for sky diffuse and
    ground-reflected irradiance using the Martin and Ruiz incident angle model.

    As described in [1]_, the IAMs result from integrals that assume the incoming
    sky diffuse and ground-reflected irradiance are isotropic.


iam_ground : numeric
The incident angle modifier for ground-reflected diffuse
* 'sky': radiation from the sky dome
* 'ground': radiation reflected from the ground

Notes
-----
Expand Down Expand Up @@ -419,7 +419,9 @@ def martin_ruiz_diffuse(surface_tilt, a_r=0.16, c1=0.4244, c2=None):
iam_sky = pd.Series(iam_sky, index=out_index, name='iam_sky')
iam_gnd = pd.Series(iam_gnd, index=out_index, name='iam_ground')

return iam_sky, iam_gnd
iam = {'sky': iam_sky, 'ground': iam_gnd}

return iam


def interp(aoi, theta_ref, iam_ref, method='linear', normalize=True):
Expand Down Expand Up @@ -603,7 +605,7 @@ def marion_diffuse(model, surface_tilt, **kwargs):
Returns
-------
iam : dict
IAM values for each type of diffuse irradiance:
IAM values for each type of diffuse irradiance (assuming isotropy):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
IAM values for each type of diffuse irradiance (assuming isotropy):
IAM values for each type of diffuse irradiance:


* 'sky': radiation from the sky dome (zenith <= 90)
* 'horizon': radiation from the region of the sky near the horizon
Expand Down Expand Up @@ -890,11 +892,11 @@ def schlick_diffuse(surface_tilt):

Returns
-------
iam_sky : numeric
The incident angle modifier for sky diffuse.
iam : dict
IAM values for each type of diffuse irradiance (assuming isotropy):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
IAM values for each type of diffuse irradiance (assuming isotropy):
IAM values for each type of diffuse irradiance:


iam_ground : numeric
The incident angle modifier for ground-reflected diffuse.
* 'sky': radiation from the sky dome
* 'ground': radiation reflected from the ground

See Also
--------
Expand Down Expand Up @@ -961,7 +963,9 @@ def schlick_diffuse(surface_tilt):
cuk = pd.Series(cuk, surface_tilt.index)
cug = pd.Series(cug, surface_tilt.index)

return cuk, cug
iam = {'sky': cuk, 'ground': cug}

return iam


def _get_model(model_name):
Expand Down
42 changes: 22 additions & 20 deletions tests/test_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,18 @@ def test_martin_ruiz_diffuse():

surface_tilt = 30.
a_r = 0.16
expected = (0.9549735, 0.7944426)
expected_sky = 0.9549735
expected_ground = 0.7944426

# will fail if default values change
iam = _iam.martin_ruiz_diffuse(surface_tilt)
assert_allclose(iam, expected)
actual_iam = _iam.martin_ruiz_diffuse(surface_tilt)
assert_allclose(actual_iam['sky'], expected_sky)
assert_allclose(actual_iam['ground'], expected_ground)

# will fail if parameter names change
iam = _iam.martin_ruiz_diffuse(surface_tilt=surface_tilt, a_r=a_r)
assert_allclose(iam, expected)
assert_allclose(iam['sky'], expected_sky)
assert_allclose(iam['ground'], expected_ground)

a_r = 0.18
surface_tilt = [0, 30, 90, 120, 180, np.nan, np.inf]
Expand All @@ -153,21 +156,21 @@ def test_martin_ruiz_diffuse():

# check various inputs as list
iam = _iam.martin_ruiz_diffuse(surface_tilt, a_r)
assert_allclose(iam[0], expected_sky, atol=1e-7, equal_nan=True)
assert_allclose(iam[1], expected_gnd, atol=1e-7, equal_nan=True)
assert_allclose(iam['sky'], expected_sky, atol=1e-7, equal_nan=True)
assert_allclose(iam['ground'], expected_gnd, atol=1e-7, equal_nan=True)

# check various inputs as array
iam = _iam.martin_ruiz_diffuse(np.array(surface_tilt), a_r)
assert_allclose(iam[0], expected_sky, atol=1e-7, equal_nan=True)
assert_allclose(iam[1], expected_gnd, atol=1e-7, equal_nan=True)
assert_allclose(iam['sky'], expected_sky, atol=1e-7, equal_nan=True)
assert_allclose(iam['ground'], expected_gnd, atol=1e-7, equal_nan=True)

# check various inputs as Series
surface_tilt = pd.Series(surface_tilt)
expected_sky = pd.Series(expected_sky, name='iam_sky')
expected_gnd = pd.Series(expected_gnd, name='iam_ground')
iam = _iam.martin_ruiz_diffuse(surface_tilt, a_r)
assert_series_equal(iam[0], expected_sky)
assert_series_equal(iam[1], expected_gnd)
assert_series_equal(iam['sky'], expected_sky)
assert_series_equal(iam['ground'], expected_gnd)


def test_iam_interp():
Expand Down Expand Up @@ -441,22 +444,21 @@ def test_schlick_diffuse():
expected_ground = np.array([0, 0.62693858, 0.93218737, 0.95238094])

# numpy arrays
actual_sky, actual_ground = _iam.schlick_diffuse(surface_tilt)
assert_allclose(expected_sky, actual_sky)
assert_allclose(expected_ground, actual_ground, rtol=1e-6)
actual_iam = _iam.schlick_diffuse(surface_tilt)
assert_allclose(expected_sky, actual_iam['sky'])
assert_allclose(expected_ground, actual_iam['ground'], rtol=1e-6)

# scalars
for i in range(len(surface_tilt)):
actual_sky, actual_ground = _iam.schlick_diffuse(surface_tilt[i])
assert_allclose(expected_sky[i], actual_sky)
assert_allclose(expected_ground[i], actual_ground, rtol=1e-6)
actual_iam = _iam.schlick_diffuse(surface_tilt[i])
assert_allclose(expected_sky[i], actual_iam['sky'], rtol=1e-6)
assert_allclose(expected_ground[i], actual_iam['ground'], rtol=1e-6)

# pandas Series
idx = pd.date_range('2019-01-01', freq='h', periods=len(surface_tilt))
actual_sky, actual_ground = _iam.schlick_diffuse(pd.Series(surface_tilt,
idx))
assert_series_equal(pd.Series(expected_sky, idx), actual_sky)
assert_series_equal(pd.Series(expected_ground, idx), actual_ground,
actual_iam = _iam.schlick_diffuse(pd.Series(surface_tilt, idx))
assert_series_equal(pd.Series(expected_sky, idx), actual_iam['sky'])
assert_series_equal(pd.Series(expected_ground, idx), actual_iam['ground'],
rtol=1e-6)


Expand Down
Loading