diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 50f02426de..82b144cbe9 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -595,7 +595,7 @@ def get_ground_diffuse(surface_tilt, ghi, albedo=.25, surface_type=None): return diffuse_irrad -def isotropic(surface_tilt, dhi): +def isotropic(surface_tilt, dhi, return_components=False): r''' Determine diffuse irradiance from the sky on a tilted surface using the isotropic sky model. @@ -619,11 +619,27 @@ def isotropic(surface_tilt, dhi): dhi : numeric Diffuse horizontal irradiance, must be >=0. See :term:`dhi`. + return_components : bool, default `False` + If `False`, ``sky_diffuse`` is returned. + If `True`, ``diffuse_components`` is returned. + For this model, return_components does not add more information, + but it is included for consistency with the other sky diffuse models. + Returns ------- - diffuse : numeric + numeric, Dict, or DataFrame + Return type controlled by ``return_components`` argument. + If `False`, ``sky_diffuse`` is returned. + If `True`, ``diffuse_components`` is returned. + + sky_diffuse : numeric The sky diffuse component of the solar radiation. [Wm⁻²] + diffuse_components : Dict (array input) or DataFrame (Series input) + Keys/columns are: + * poa_sky_diffuse: Total sky diffuse + * poa_isotropic + References ---------- .. [1] Loutzenhiser P.G. et al. "Empirical validation of models to @@ -638,7 +654,18 @@ def isotropic(surface_tilt, dhi): ''' sky_diffuse = dhi * (1 + tools.cosd(surface_tilt)) * 0.5 - return sky_diffuse + if return_components: + diffuse_components = { + 'poa_sky_diffuse': sky_diffuse, + 'poa_isotropic': sky_diffuse + } + + if isinstance(sky_diffuse, pd.Series): + diffuse_components = pd.DataFrame(diffuse_components) + + return diffuse_components + else: + return sky_diffuse def klucher(surface_tilt, surface_azimuth, dhi, ghi, solar_zenith, diff --git a/tests/test_irradiance.py b/tests/test_irradiance.py index a416636ae9..ce7878fdbc 100644 --- a/tests/test_irradiance.py +++ b/tests/test_irradiance.py @@ -168,6 +168,32 @@ def test_isotropic_series(irrad_data): assert_allclose(result, [0, 35.728402, 104.601328, 54.777191], atol=1e-4) +def test_isotropic_components(irrad_data): + keys = ['poa_sky_diffuse', 'poa_isotropic'] + expected = pd.DataFrame(np.array( + [[0, 35.728402, 104.601328, 54.777191], + [0, 35.728402, 104.601328, 54.777191]]).T, + columns=keys, + index=irrad_data.index + ) + # pandas + result = irradiance.isotropic( + 40, irrad_data['dhi'], return_components=True) + assert_frame_equal(result, expected, check_less_precise=4) + # numpy + result = irradiance.isotropic( + 40, irrad_data['dhi'].values, return_components=True) + for key in keys: + assert_allclose(result[key], expected[key], atol=1e-4) + assert isinstance(result, dict) + # scalar + result = irradiance.isotropic( + 40, irrad_data['dhi'].values[-1], return_components=True) + for key in keys: + assert_allclose(result[key], expected[key].iloc[-1], atol=1e-4) + assert isinstance(result, dict) + + def test_klucher_series_float(): # klucher inputs surface_tilt, surface_azimuth = 40.0, 180.0