From 02ae5686a18aed5e14e7a9b3cf9d09a11dd07c1f Mon Sep 17 00:00:00 2001 From: Nicolau Date: Mon, 26 Aug 2024 14:34:14 +0200 Subject: [PATCH 01/50] muneer transposition model still not tested --- pvlib/irradiance.py | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 435c318562..f49137533b 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -994,6 +994,56 @@ def king(surface_tilt, dhi, ghi, solar_zenith): return sky_diffuse +def muneer(surface_tilt, dhi, b): + ''' + Determine diffuse irradiance from the sky on a tilted surface using + the Muneer [1]_ model. + + Parameters + ---------- + surface_tilt : numeric + Surface tilt angle in decimal degrees. Tilt must be >=0 and + <=180. The tilt angle is defined as degrees from horizontal + (e.g. surface facing up = 0, surface facing horizon = 90) + + dhi : numeric + Diffuse horizontal irradiance in W/m^2. DHI must be >=0. + + b : numeric + Radiance distribution index, introduced by Moon and Spencer [2]_ to model + luminance distribution of overcast sky. + + 'best' values of b as found for Easthampstead data: + isotropic: b = 0 + shaded surface: b = 5.73 + sunlit surface under overcast sky: b = 1.68 + sunlit surface under non-overcast sky: b = -0.62 + + + Returns + ------- + diffuse : numeric + The sky diffuse component of the solar radiation. + + References + ---------- + .. [1] Muneer, T., 1990, Solar radiation model for Europe. + Building services engineering research and technology, 11: 153-163. + + .. [2] Moon P and Spencer D E Illumination from a non-uniform sky + Trans. Illum. Eng. Soc. (London) 37 707-725 (1942) + ''' + + term1 = 2 * b / (np.pi * (3 + 2 * b)) + term2 = (tools.sind(surface_tilt) + - surface_tilt * tools.cosd(surface_tilt) + - np.pi * (1 - tools.cosd(surface_tilt)) * 0.5 + ) + sky_diffuse = dhi * ((1 + tools.cosd(surface_tilt)) * 0.5 + term1 * term2) + + return sky_diffuse + + def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra, solar_zenith, solar_azimuth, airmass, model='allsitescomposite1990', return_components=False): From ea15728d9d53c07aacfaf287f1869cd064ba79b0 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:15:01 +0200 Subject: [PATCH 02/50] Update pvlib/irradiance.py Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index f49137533b..87440cd54d 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -996,8 +996,8 @@ def king(surface_tilt, dhi, ghi, solar_zenith): def muneer(surface_tilt, dhi, b): ''' - Determine diffuse irradiance from the sky on a tilted surface using - the Muneer [1]_ model. + Determine sky diffuse irradiance on a tilted surface using the + Muneer [1]_ model. Parameters ---------- From feafceafffbe7354113b72cf27e42fcaa72ae550 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:16:18 +0200 Subject: [PATCH 03/50] Update pvlib/irradiance.py Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 87440cd54d..c11bd79895 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1007,7 +1007,7 @@ def muneer(surface_tilt, dhi, b): (e.g. surface facing up = 0, surface facing horizon = 90) dhi : numeric - Diffuse horizontal irradiance in W/m^2. DHI must be >=0. + Diffuse horizontal irradiance. [W/m^2] b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model From e4646d47ac7cec84815ac22caf628f10c100a5a0 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:19:21 +0200 Subject: [PATCH 04/50] Update pvlib/irradiance.py Adam initial review Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index c11bd79895..10275f9f81 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1012,13 +1012,12 @@ def muneer(surface_tilt, dhi, b): b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model luminance distribution of overcast sky. - - 'best' values of b as found for Easthampstead data: - isotropic: b = 0 - shaded surface: b = 5.73 - sunlit surface under overcast sky: b = 1.68 - sunlit surface under non-overcast sky: b = -0.62 - + Recommend values from [X]_: + + - isotropic: b = 0 + - shaded surface: b = 5.73 + - sunlit surface, overcast sky: b = 1.68 + - sunlit surface, non-overcast sky: b = -0.62 Returns ------- From 80664586324cb0ef9a3382a54e0fc65f7428ca99 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:19:36 +0200 Subject: [PATCH 05/50] Update pvlib/irradiance.py Adam initial review Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 10275f9f81..bc04068388 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1011,7 +1011,7 @@ def muneer(surface_tilt, dhi, b): b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model - luminance distribution of overcast sky. + luminance distribution of overcast sky. [unitless] Recommend values from [X]_: - isotropic: b = 0 From 1798da83887a59f16830b28ef7e5e02111f70218 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:19:41 +0200 Subject: [PATCH 06/50] Update pvlib/irradiance.py Adam initial review Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index bc04068388..e5148d8a21 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1021,7 +1021,7 @@ def muneer(surface_tilt, dhi, b): Returns ------- - diffuse : numeric + poa_sky_diffuse : numeric The sky diffuse component of the solar radiation. References From 4281d6135c340937166dbe6e60485f160932fb24 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:20:51 +0200 Subject: [PATCH 07/50] Update pvlib/irradiance.py Adam initial review Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index e5148d8a21..b9a8228b7e 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1022,7 +1022,7 @@ def muneer(surface_tilt, dhi, b): Returns ------- poa_sky_diffuse : numeric - The sky diffuse component of the solar radiation. + In-plane diffuse irradiance from the sky. [W/m^2] References ---------- From 8b1359588f190fa001e691eca9ba676043942a77 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Mon, 26 Aug 2024 16:32:04 +0200 Subject: [PATCH 08/50] references modified and doi added Co-Authored-By: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- .../irradiance-transposition/test_muneer.py | 6 ++++++ pvlib/irradiance.py | 14 ++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 docs/examples/irradiance-transposition/test_muneer.py diff --git a/docs/examples/irradiance-transposition/test_muneer.py b/docs/examples/irradiance-transposition/test_muneer.py new file mode 100644 index 0000000000..49215ca436 --- /dev/null +++ b/docs/examples/irradiance-transposition/test_muneer.py @@ -0,0 +1,6 @@ +import pvlib + +lat = 41.54 +lon = 2.40 +df = pvlib.iotools.get_pvgis_hourly(lat, lon, surface_tilt = 30, ) +test \ No newline at end of file diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index b9a8228b7e..85a3de4b2b 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1012,7 +1012,7 @@ def muneer(surface_tilt, dhi, b): b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model luminance distribution of overcast sky. [unitless] - Recommend values from [X]_: + Recommend values from [1]_: - isotropic: b = 0 - shaded surface: b = 5.73 @@ -1026,11 +1026,13 @@ def muneer(surface_tilt, dhi, b): References ---------- - .. [1] Muneer, T., 1990, Solar radiation model for Europe. - Building services engineering research and technology, 11: 153-163. - - .. [2] Moon P and Spencer D E Illumination from a non-uniform sky - Trans. Illum. Eng. Soc. (London) 37 707-725 (1942) + .. [1] Muneer, T., 1990. Solar radiation model for Europe. Building + Services Engineering Research and Technology 11, 153-163. + :doi:`10.1177/014362449001100405` + + .. [2] Moon, P., Spencer, D.E., 1942. Illumination from a non-uniform sky. + Trans. Illum. Eng. Soc. (London) 37, 707-725. + :doi:`10.1177/096032719302500301` ''' term1 = 2 * b / (np.pi * (3 + 2 * b)) From 6cd63a81b9f50a1e15213de0275c4d8e41a5d6ac Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Mon, 26 Aug 2024 16:33:16 +0200 Subject: [PATCH 09/50] removed unwanted file --- docs/examples/irradiance-transposition/test_muneer.py | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 docs/examples/irradiance-transposition/test_muneer.py diff --git a/docs/examples/irradiance-transposition/test_muneer.py b/docs/examples/irradiance-transposition/test_muneer.py deleted file mode 100644 index 49215ca436..0000000000 --- a/docs/examples/irradiance-transposition/test_muneer.py +++ /dev/null @@ -1,6 +0,0 @@ -import pvlib - -lat = 41.54 -lon = 2.40 -df = pvlib.iotools.get_pvgis_hourly(lat, lon, surface_tilt = 30, ) -test \ No newline at end of file From fa4d8e6aade2f7efb4e17b5cf560796858ac9403 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Mon, 26 Aug 2024 17:06:28 +0200 Subject: [PATCH 10/50] formating autopep8 --- pvlib/irradiance.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 85a3de4b2b..388eba1104 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -998,7 +998,7 @@ def muneer(surface_tilt, dhi, b): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer [1]_ model. - + Parameters ---------- surface_tilt : numeric @@ -1008,7 +1008,7 @@ def muneer(surface_tilt, dhi, b): dhi : numeric Diffuse horizontal irradiance. [W/m^2] - + b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model luminance distribution of overcast sky. [unitless] @@ -1036,7 +1036,8 @@ def muneer(surface_tilt, dhi, b): ''' term1 = 2 * b / (np.pi * (3 + 2 * b)) - term2 = (tools.sind(surface_tilt) + term2 = ( + tools.sind(surface_tilt) - surface_tilt * tools.cosd(surface_tilt) - np.pi * (1 - tools.cosd(surface_tilt)) * 0.5 ) From 8318d5b8c70e08bddd6926742134aaa77981c292 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Mon, 26 Aug 2024 17:20:33 +0200 Subject: [PATCH 11/50] formatting --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 388eba1104..0828a67a7f 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1010,8 +1010,8 @@ def muneer(surface_tilt, dhi, b): Diffuse horizontal irradiance. [W/m^2] b : numeric - Radiance distribution index, introduced by Moon and Spencer [2]_ to model - luminance distribution of overcast sky. [unitless] + Radiance distribution index, introduced by Moon and Spencer [2]_ + to model luminance distribution of overcast sky. [unitless] Recommend values from [1]_: - isotropic: b = 0 From d5c8bc326a1d5f4d8d56474c4e72bc96f977a9b5 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:51:24 +0200 Subject: [PATCH 12/50] avoid references first paragraph Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> --- pvlib/irradiance.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 0828a67a7f..bc952a8ddb 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -997,7 +997,9 @@ def king(surface_tilt, dhi, ghi, solar_zenith): def muneer(surface_tilt, dhi, b): ''' Determine sky diffuse irradiance on a tilted surface using the - Muneer [1]_ model. + Muneer model. + + This model is described in [1]_. Parameters ---------- From 8cbee571c1050b8b7870797be5912bf73be19e1c Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:56:49 +0200 Subject: [PATCH 13/50] updated wording Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index bc952a8ddb..adfe03c4d3 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1014,7 +1014,7 @@ def muneer(surface_tilt, dhi, b): b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ to model luminance distribution of overcast sky. [unitless] - Recommend values from [1]_: + Recommended values from [1]_: - isotropic: b = 0 - shaded surface: b = 5.73 From 20c8fae31f46c7fc7256b20b46e5a94f3185d93b Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 27 Aug 2024 17:59:22 +0200 Subject: [PATCH 14/50] function finished still needs testing --- pvlib/irradiance.py | 57 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 0828a67a7f..09ce48bdd3 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -994,7 +994,8 @@ def king(surface_tilt, dhi, ghi, solar_zenith): return sky_diffuse -def muneer(surface_tilt, dhi, b): +def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b, solar_zenith=None, + solar_azimuth=None, projection_ratio=None): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer [1]_ model. @@ -1002,12 +1003,23 @@ def muneer(surface_tilt, dhi, b): Parameters ---------- surface_tilt : numeric - Surface tilt angle in decimal degrees. Tilt must be >=0 and - <=180. The tilt angle is defined as degrees from horizontal + Surface tilt angles in decimal degrees. surface_tilt must be >=0 + and <=180. The tilt angle is defined as degrees from horizontal (e.g. surface facing up = 0, surface facing horizon = 90) + surface_azimuth : numeric + Surface azimuth angles in decimal degrees. surface_azimuth must + be >=0 and <=360. The azimuth convention is defined as degrees + east of north (e.g. North = 0, South=180 East = 90, West = 270). + dhi : numeric Diffuse horizontal irradiance. [W/m^2] + + ghi : numeric + Global horizontal irradiance in W/m^2. + + dni_extra : numeric + Extraterrestrial normal irradiance in W/m^2. b : numeric Radiance distribution index, introduced by Moon and Spencer [2]_ @@ -1018,6 +1030,21 @@ def muneer(surface_tilt, dhi, b): - shaded surface: b = 5.73 - sunlit surface, overcast sky: b = 1.68 - sunlit surface, non-overcast sky: b = -0.62 + + solar_zenith : numeric, optional + Solar apparent (refraction-corrected) zenith angles in decimal + degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or + supply ``projection_ratio``. + + solar_azimuth : numeric, optional + Solar azimuth angles in decimal degrees. Must supply + ``solar_zenith`` and ``solar_azimuth`` or supply + ``projection_ratio``. + + projection_ratio : numeric, optional + Ratio of angle of incidence projection to solar zenith angle + projection. Must supply ``solar_zenith`` and ``solar_azimuth`` + or supply ``projection_ratio``. Returns ------- @@ -1034,14 +1061,30 @@ def muneer(surface_tilt, dhi, b): Trans. Illum. Eng. Soc. (London) 37, 707-725. :doi:`10.1177/096032719302500301` ''' + + # if necessary, calculate ratio of titled and horizontal beam irradiance + if projection_ratio is None: + cos_tt = aoi_projection(surface_tilt, surface_azimuth, + solar_zenith, solar_azimuth) + cos_tt = np.maximum(cos_tt, 0) # GH 526 + cos_solar_zenith = tools.cosd(solar_zenith) + Rb = cos_tt / np.maximum(cos_solar_zenith, 0.01745) # GH 432 + else: + Rb = projection_ratio - term1 = 2 * b / (np.pi * (3 + 2 * b)) - term2 = ( + T_term1 = (1 + tools.cosd(surface_tilt)) * 0.5 + T_term2 = 2 * b / (np.pi * (3 + 2 * b)) + T_term3 = ( tools.sind(surface_tilt) - - surface_tilt * tools.cosd(surface_tilt) + - np.radians(surface_tilt) * tools.cosd(surface_tilt) - np.pi * (1 - tools.cosd(surface_tilt)) * 0.5 ) - sky_diffuse = dhi * ((1 + tools.cosd(surface_tilt)) * 0.5 + term1 * term2) + T = T_term1 + T_term2 * T_term3 + + horizontal_extra = dni_extra * np.maximum(cos_solar_zenith, 0.01745) + F = (ghi - dhi) / horizontal_extra + + sky_diffuse = dhi*(T*(1-F) + F*Rb) return sky_diffuse From e0d85c03320f4f46fd2fdbce55f41e71f7cc1f56 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 10:21:15 +0200 Subject: [PATCH 15/50] pvlib.irradiance update (muneer) muneer included in get_sky_diffuse code and documentation muneer included in get_total_irradiance documentation muneer function updated TODO: tests, create documentation --- pvlib/irradiance.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index aadf3b97bd..966c81b7f4 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -280,6 +280,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, * king * perez * perez-driesse + * muneer Parameters ---------- @@ -309,7 +310,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, model : str, default 'isotropic' Irradiance model. Can be one of ``'isotropic'``, ``'klucher'``, ``'haydavies'``, ``'reindl'``, ``'king'``, ``'perez'``, - ``'perez-driesse'``. + ``'perez-driesse'`` and ``'muneer '``. model_perez : str, default 'allsitescomposite1990' Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`. @@ -346,7 +347,7 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi, dni_extra=None, airmass=None, model='isotropic', - model_perez='allsitescomposite1990'): + model_perez='allsitescomposite1990', b = 5.73): r""" Determine in-plane sky diffuse irradiance component using the specified sky diffuse irradiance model. @@ -359,6 +360,7 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, * king * perez * perez-driesse + * muneer Parameters ---------- @@ -383,9 +385,11 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, model : str, default 'isotropic' Irradiance model. Can be one of ``'isotropic'``, ``'klucher'``, ``'haydavies'``, ``'reindl'``, ``'king'``, ``'perez'``, - ``'perez-driesse'``. + ``'perez-driesse'``, ``'muneer'``. model_perez : str, default 'allsitescomposite1990' Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`. + b : numeric, default 5.73 + Used only if ``model='muneer'``. See :py:func:`~pvlib.irradiance.muneer`. Returns ------- @@ -395,14 +399,14 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, Raises ------ ValueError - If model is one of ``'haydavies'``, ``'reindl'``, or ``'perez'`` and - ``dni_extra`` is not specified. + If model is one of ``'haydavies'``, ``'reindl'``, ``'perez'`` or + ``'muneer'``and ``dni_extra`` is not specified. Notes ----- - Models ``'haydavies'``, ``'reindl'``, ``'perez'`` and ``'perez-driesse'`` - require ``'dni_extra'``. Values can be calculated using - :py:func:`~pvlib.irradiance.get_extra_radiation`. + Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'`` + and ``'muneer'`` require ``'dni_extra'``. Values can be calculated + using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'Perez'`` transposition model features discontinuities in the predicted tilted diffuse irradiance due to relying on discrete input @@ -443,6 +447,9 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, # perez_driesse will calculate its own airmass if needed sky = perez_driesse(surface_tilt, surface_azimuth, dhi, dni, dni_extra, solar_zenith, solar_azimuth, airmass) + elif model == 'muneer': + sky = muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, + b, solar_zenith, solar_azimuth) else: raise ValueError(f'invalid model selection {model}') @@ -994,15 +1001,15 @@ def king(surface_tilt, dhi, ghi, solar_zenith): return sky_diffuse -def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b, solar_zenith=None, - solar_azimuth=None, projection_ratio=None): +def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, + solar_zenith=None, solar_azimuth=None, projection_ratio=None): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer model. This model is described in [1]_. - Parameters + Parameters ---------- surface_tilt : numeric Surface tilt angles in decimal degrees. surface_tilt must be >=0 @@ -1023,17 +1030,17 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b, solar_zenith=N dni_extra : numeric Extraterrestrial normal irradiance in W/m^2. - b : numeric + b : numeric, default 5.73 Radiance distribution index, introduced by Moon and Spencer [2]_ to model luminance distribution of overcast sky. [unitless] Recommended values from [1]_: - isotropic: b = 0 - - shaded surface: b = 5.73 + - shaded surface: b = 5.73 (default) - sunlit surface, overcast sky: b = 1.68 - sunlit surface, non-overcast sky: b = -0.62 - solar_zenith : numeric, optional + solar_zenith : numeric Solar apparent (refraction-corrected) zenith angles in decimal degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or supply ``projection_ratio``. @@ -1064,12 +1071,12 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b, solar_zenith=N :doi:`10.1177/096032719302500301` ''' + cos_solar_zenith = tools.cosd(solar_zenith) # if necessary, calculate ratio of titled and horizontal beam irradiance if projection_ratio is None: cos_tt = aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth) cos_tt = np.maximum(cos_tt, 0) # GH 526 - cos_solar_zenith = tools.cosd(solar_zenith) Rb = cos_tt / np.maximum(cos_solar_zenith, 0.01745) # GH 432 else: Rb = projection_ratio From 30fb33a834cc29f4569fd476ffa50ca9d456deb8 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 10:40:47 +0200 Subject: [PATCH 16/50] documentation, tests and flake8 added documentation, tests and modifications according to flake8 --- .../reference/irradiance/transposition.rst | 1 + pvlib/irradiance.py | 25 ++++++++++--------- pvlib/tests/test_irradiance.py | 21 +++++++++++++--- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/docs/sphinx/source/reference/irradiance/transposition.rst b/docs/sphinx/source/reference/irradiance/transposition.rst index 22136f0c58..d77e0d2801 100644 --- a/docs/sphinx/source/reference/irradiance/transposition.rst +++ b/docs/sphinx/source/reference/irradiance/transposition.rst @@ -15,4 +15,5 @@ Transposition models irradiance.klucher irradiance.reindl irradiance.king + irradiance.muneer irradiance.ghi_from_poa_driesse_2023 diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 966c81b7f4..5fade0b168 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -310,7 +310,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, model : str, default 'isotropic' Irradiance model. Can be one of ``'isotropic'``, ``'klucher'``, ``'haydavies'``, ``'reindl'``, ``'king'``, ``'perez'``, - ``'perez-driesse'`` and ``'muneer '``. + ``'perez-driesse'`` and ``'muneer model_perez : str, default 'allsitescomposite1990' Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`. @@ -347,7 +347,7 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi, dni_extra=None, airmass=None, model='isotropic', - model_perez='allsitescomposite1990', b = 5.73): + model_perez='allsitescomposite1990', b=5.73): r""" Determine in-plane sky diffuse irradiance component using the specified sky diffuse irradiance model. @@ -389,7 +389,8 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, model_perez : str, default 'allsitescomposite1990' Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`. b : numeric, default 5.73 - Used only if ``model='muneer'``. See :py:func:`~pvlib.irradiance.muneer`. + Used only if ``model='muneer'``. + See :py:func:`~pvlib.irradiance.muneer`. Returns ------- @@ -405,7 +406,7 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, Notes ----- Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'`` - and ``'muneer'`` require ``'dni_extra'``. Values can be calculated + and ``'muneer'`` require ``'dni_extra'``. Values can be calculated using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'Perez'`` transposition model features discontinuities in the @@ -1001,12 +1002,12 @@ def king(surface_tilt, dhi, ghi, solar_zenith): return sky_diffuse -def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, +def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, solar_zenith=None, solar_azimuth=None, projection_ratio=None): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer model. - + This model is described in [1]_. Parameters @@ -1023,10 +1024,10 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, dhi : numeric Diffuse horizontal irradiance. [W/m^2] - + ghi : numeric Global horizontal irradiance in W/m^2. - + dni_extra : numeric Extraterrestrial normal irradiance in W/m^2. @@ -1039,7 +1040,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, - shaded surface: b = 5.73 (default) - sunlit surface, overcast sky: b = 1.68 - sunlit surface, non-overcast sky: b = -0.62 - + solar_zenith : numeric Solar apparent (refraction-corrected) zenith angles in decimal degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or @@ -1070,7 +1071,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, Trans. Illum. Eng. Soc. (London) 37, 707-725. :doi:`10.1177/096032719302500301` ''' - + cos_solar_zenith = tools.cosd(solar_zenith) # if necessary, calculate ratio of titled and horizontal beam irradiance if projection_ratio is None: @@ -1089,10 +1090,10 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b = 5.73, - np.pi * (1 - tools.cosd(surface_tilt)) * 0.5 ) T = T_term1 + T_term2 * T_term3 - + horizontal_extra = dni_extra * np.maximum(cos_solar_zenith, 0.01745) F = (ghi - dhi) / horizontal_extra - + sky_diffuse = dhi*(T*(1-F) + F*Rb) return sky_diffuse diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 0eb951f9a1..11f29c21ac 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -284,6 +284,15 @@ def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass): [0., 29.991, np.nan, 47.397]), index=irrad_data.index) assert_series_equal(out, expected, check_less_precise=2) + +def test_muneer(irrad_data, ephem_data, dni_et): + out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], + dni_et, solar_zenith=ephem_data['apparent_zenith'], + solar_azimuth=ephem_data['azimuth']) + expected = pd.Series(np.array( + [0., 25.173, 100.757, 31.121]), + index=irrad_data.index) + assert_series_equal(out, expected, check_less_precise=2) def test_perez_driesse_airmass(irrad_data, ephem_data, dni_et): @@ -443,7 +452,8 @@ def test_perez_driesse_scalar(): @pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies', - 'reindl', 'king', 'perez', 'perez-driesse']) + 'reindl', 'king', 'perez', 'perez-driesse', + 'muneer']) def test_sky_diffuse_zenith_close_to_90(model): # GH 432 sky_diffuse = irradiance.get_sky_diffuse( @@ -495,7 +505,8 @@ def test_campbell_norman(): def test_get_total_irradiance(irrad_data, ephem_data, dni_et, relative_airmass): models = ['isotropic', 'klucher', - 'haydavies', 'reindl', 'king', 'perez', 'perez-driesse'] + 'haydavies', 'reindl', 'king', 'perez', 'perez-driesse', + 'muneer'] for model in models: total = irradiance.get_total_irradiance( @@ -514,7 +525,8 @@ def test_get_total_irradiance(irrad_data, ephem_data, dni_et, @pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies', 'reindl', 'king', - 'perez', 'perez-driesse']) + 'perez', 'perez-driesse', + 'muneer']) def test_get_total_irradiance_albedo( irrad_data, ephem_data, dni_et, relative_airmass, model): albedo = pd.Series(0.2, index=ephem_data.index) @@ -534,7 +546,8 @@ def test_get_total_irradiance_albedo( @pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies', 'reindl', 'king', - 'perez', 'perez-driesse']) + 'perez', 'perez-driesse', + 'muneer']) def test_get_total_irradiance_scalars(model): total = irradiance.get_total_irradiance( 32, 180, From e1a7f74c3e0cbbeade221f70c430888a5c9b9ffb Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 10:43:43 +0200 Subject: [PATCH 17/50] flake8 update still quite new to the flake8. May not pass the test --- pvlib/tests/test_irradiance.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 11f29c21ac..ed33697aeb 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -284,11 +284,12 @@ def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass): [0., 29.991, np.nan, 47.397]), index=irrad_data.index) assert_series_equal(out, expected, check_less_precise=2) - + + def test_muneer(irrad_data, ephem_data, dni_et): out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], - dni_et, solar_zenith=ephem_data['apparent_zenith'], - solar_azimuth=ephem_data['azimuth']) + dni_et, solar_zenith=ephem_data['apparent_zenith'], + solar_azimuth=ephem_data['azimuth']) expected = pd.Series(np.array( [0., 25.173, 100.757, 31.121]), index=irrad_data.index) From 618ca9154790f031d9ea4c06701d940ad40aaaa2 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 11:02:43 +0200 Subject: [PATCH 18/50] test_added --- pvlib/irradiance.py | 6 +++--- pvlib/tests/test_irradiance.py | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 5fade0b168..6be867eb93 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -322,9 +322,9 @@ def get_total_irradiance(surface_tilt, surface_azimuth, Notes ----- - Models ``'haydavies'``, ``'reindl'``, ``'perez'`` and ``'perez-driesse'`` - require ``'dni_extra'``. Values can be calculated using - :py:func:`~pvlib.irradiance.get_extra_radiation`. + Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'`` + and ``'muneer'`` require ``'dni_extra'``. Values can be calculated + using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'perez'`` and ``'perez-driesse'`` models require relative airmass (``airmass``) as input. If ``airmass`` is not provided, it is calculated diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index ed33697aeb..1116e85c7d 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -287,13 +287,19 @@ def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass): def test_muneer(irrad_data, ephem_data, dni_et): + projection_ratio = np.array( + [0, 0, 0.8639607552973, 0.1716097049224]) out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], dni_et, solar_zenith=ephem_data['apparent_zenith'], solar_azimuth=ephem_data['azimuth']) + out_Rb = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], + dni_et, solar_zenith=ephem_data['apparent_zenith'], + projection_ratio=projection_ratio) expected = pd.Series(np.array( [0., 25.173, 100.757, 31.121]), index=irrad_data.index) assert_series_equal(out, expected, check_less_precise=2) + assert_series_equal(out_Rb, expected, check_less_precise=2) def test_perez_driesse_airmass(irrad_data, ephem_data, dni_et): From 373d3e089c711c60522e07fa8d830b042770af08 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 11:09:49 +0200 Subject: [PATCH 19/50] flake8 --- pvlib/irradiance.py | 2 +- pvlib/tests/test_irradiance.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 6be867eb93..212c07f6d5 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -323,7 +323,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, Notes ----- Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'`` - and ``'muneer'`` require ``'dni_extra'``. Values can be calculated + and ``'muneer'`` require ``'dni_extra'``. Values can be calculated using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'perez'`` and ``'perez-driesse'`` models require relative airmass diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 1116e85c7d..a070fe190f 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -293,8 +293,8 @@ def test_muneer(irrad_data, ephem_data, dni_et): dni_et, solar_zenith=ephem_data['apparent_zenith'], solar_azimuth=ephem_data['azimuth']) out_Rb = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], - dni_et, solar_zenith=ephem_data['apparent_zenith'], - projection_ratio=projection_ratio) + dni_et, solar_zenith=ephem_data['apparent_zenith'], + projection_ratio=projection_ratio) expected = pd.Series(np.array( [0., 25.173, 100.757, 31.121]), index=irrad_data.index) From e517a84cfd6a3ce704804049af8c7ff12066c998 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 11:11:33 +0200 Subject: [PATCH 20/50] E501 --- pvlib/tests/test_irradiance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index a070fe190f..e159b58d6c 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -293,7 +293,8 @@ def test_muneer(irrad_data, ephem_data, dni_et): dni_et, solar_zenith=ephem_data['apparent_zenith'], solar_azimuth=ephem_data['azimuth']) out_Rb = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], - dni_et, solar_zenith=ephem_data['apparent_zenith'], + dni_et, + solar_zenith=ephem_data['apparent_zenith'], projection_ratio=projection_ratio) expected = pd.Series(np.array( [0., 25.173, 100.757, 31.121]), From 94522480489513e701a04df5ec086738dcfcf3d7 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 28 Aug 2024 11:18:12 +0200 Subject: [PATCH 21/50] update whatsnew --- docs/sphinx/source/whatsnew/v0.11.1.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/sphinx/source/whatsnew/v0.11.1.rst b/docs/sphinx/source/whatsnew/v0.11.1.rst index 229cca63ba..4ff95b0085 100644 --- a/docs/sphinx/source/whatsnew/v0.11.1.rst +++ b/docs/sphinx/source/whatsnew/v0.11.1.rst @@ -30,6 +30,10 @@ Enhancements * Added function for calculating wind speed at different heights, :py:func:`pvlib.atmosphere.windspeed_powerlaw`. (:issue:`2118`, :pull:`2124`) +* Added function for determine sky diffuse irradiance on a tilted surface + using the Muneer model. + :py:func:`pvlib.irradiance.muneer`. + (:issue:`2117`, :pull:`2184`) Bug fixes ~~~~~~~~~ @@ -70,3 +74,4 @@ Contributors * Ben Pierce (:ghuser:`bgpierc`) * Jose Meza (:ghuser:`JoseMezaMendieta`) * Eduardo Sarquis (:ghuser:`EduardoSarquis`) +* Bernat Nicolau (:ghuser:`BernatNicolau`) From 36f633e317253edc0b2048958c8572d3bdc3baab Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:49:53 +0200 Subject: [PATCH 22/50] Update docs/sphinx/source/whatsnew/v0.11.1.rst replace . by , Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- docs/sphinx/source/whatsnew/v0.11.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx/source/whatsnew/v0.11.1.rst b/docs/sphinx/source/whatsnew/v0.11.1.rst index 4b1d2a97ed..f77bd081e8 100644 --- a/docs/sphinx/source/whatsnew/v0.11.1.rst +++ b/docs/sphinx/source/whatsnew/v0.11.1.rst @@ -31,7 +31,7 @@ Enhancements :py:func:`pvlib.atmosphere.windspeed_powerlaw`. (:issue:`2118`, :pull:`2124`) * Added function for determine sky diffuse irradiance on a tilted surface - using the Muneer model. + using the Muneer model, :py:func:`pvlib.irradiance.muneer`. (:issue:`2117`, :pull:`2184`) From 982d2f97e21581e72befd25d3f81f68705470a94 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:02:05 +0200 Subject: [PATCH 23/50] documentation improvement Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 212c07f6d5..0f6bb87984 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -322,7 +322,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, Notes ----- - Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'`` + Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'``, and ``'muneer'`` require ``'dni_extra'``. Values can be calculated using :py:func:`~pvlib.irradiance.get_extra_radiation`. From eecc05e3db2e52d661c6ea90b5e94b20fd20e895 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:02:14 +0200 Subject: [PATCH 24/50] documentation improvement Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 0f6bb87984..fcdcdb48c9 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -400,7 +400,7 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, Raises ------ ValueError - If model is one of ``'haydavies'``, ``'reindl'``, ``'perez'`` or + If model is one of ``'haydavies'``, ``'reindl'``, ``'perez'``, or ``'muneer'``and ``dni_extra`` is not specified. Notes From 83b5036b51bd825ae4e1bf1bdd07935f2f6e92d0 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:02:22 +0200 Subject: [PATCH 25/50] documentation improvement Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com> --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index fcdcdb48c9..327805a6b9 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1008,7 +1008,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, Determine sky diffuse irradiance on a tilted surface using the Muneer model. - This model is described in [1]_. + This Muneer transposition model is described in [1]_. Parameters ---------- From 4fb4baecee4b613fb756ad190baede0b0da1dc43 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Thu, 29 Aug 2024 09:20:24 +0200 Subject: [PATCH 26/50] b added to `get_total_irradiance` --- pvlib/irradiance.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 7552d4f5a5..e2e2c8fff8 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -263,7 +263,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, dni, ghi, dhi, dni_extra=None, airmass=None, albedo=0.25, surface_type=None, model='isotropic', - model_perez='allsitescomposite1990'): + model_perez='allsitescomposite1990', b=5.73): r""" Determine total in-plane irradiance and its beam, sky diffuse and ground reflected components, using the specified sky diffuse irradiance model. @@ -313,6 +313,9 @@ def get_total_irradiance(surface_tilt, surface_azimuth, ``'perez-driesse'`` and ``'muneer model_perez : str, default 'allsitescomposite1990' Used only if ``model='perez'``. See :py:func:`~pvlib.irradiance.perez`. + b : numeric, default 5.73 + Used only if ``model='muneer'``. + See :py:func:`~pvlib.irradiance.muneer`. Returns ------- @@ -334,7 +337,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth, poa_sky_diffuse = get_sky_diffuse( surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi, dni_extra=dni_extra, airmass=airmass, model=model, - model_perez=model_perez) + model_perez=model_perez, b=b) poa_ground_diffuse = get_ground_diffuse(surface_tilt, ghi, albedo, surface_type) From 4c69d6f7e34163d8ccb70096b1fdd447aece61e6 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Mon, 2 Sep 2024 10:45:49 +0200 Subject: [PATCH 27/50] Apply suggestions from code review (documentation) Co-authored-by: Echedey Luis <80125792+echedey-ls@users.noreply.github.com> Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- docs/sphinx/source/whatsnew/v0.11.1.rst | 2 +- pvlib/irradiance.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.11.1.rst b/docs/sphinx/source/whatsnew/v0.11.1.rst index f77bd081e8..d6b414d018 100644 --- a/docs/sphinx/source/whatsnew/v0.11.1.rst +++ b/docs/sphinx/source/whatsnew/v0.11.1.rst @@ -30,7 +30,7 @@ Enhancements * Added function for calculating wind speed at different heights, :py:func:`pvlib.atmosphere.windspeed_powerlaw`. (:issue:`2118`, :pull:`2124`) -* Added function for determine sky diffuse irradiance on a tilted surface +* Added function to determine sky diffuse irradiance on a tilted surface using the Muneer model, :py:func:`pvlib.irradiance.muneer`. (:issue:`2117`, :pull:`2184`) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index e2e2c8fff8..72296b700c 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -326,11 +326,11 @@ def get_total_irradiance(surface_tilt, surface_azimuth, Notes ----- Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'``, - and ``'muneer'`` require ``'dni_extra'``. Values can be calculated + and ``'muneer'`` require ``'dni_extra'``. Values of ``'dni_extra'`` can be calculated using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'perez'`` and ``'perez-driesse'`` models require relative airmass - (``airmass``) as input. If ``airmass`` is not provided, it is calculated + (``airmass``) as an input. If ``airmass`` is not provided, it is calculated using the defaults in :py:func:`~pvlib.atmosphere.get_relative_airmass`. """ @@ -1017,13 +1017,14 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, Parameters ---------- surface_tilt : numeric - Surface tilt angles in decimal degrees. surface_tilt must be >=0 + Surface tilt angles in decimal degrees. ``surface_tilt`` must + be >=0 and <=180. The tilt angle is defined as degrees from horizontal (e.g. surface facing up = 0, surface facing horizon = 90) surface_azimuth : numeric - Surface azimuth angles in decimal degrees. surface_azimuth must - be >=0 and <=360. The azimuth convention is defined as degrees + Surface azimuth angles in decimal degrees. ``surface_azimuth`` + must be >=0 and <=360. The azimuth convention is defined as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270). dhi : numeric From b93aa058a77f7edf582ef0ebdd1ba8173cf03dcd Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Mon, 2 Sep 2024 10:57:55 +0200 Subject: [PATCH 28/50] flake8-linter --- pvlib/irradiance.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 72296b700c..44fdf471b8 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -326,8 +326,8 @@ def get_total_irradiance(surface_tilt, surface_azimuth, Notes ----- Models ``'haydavies'``, ``'reindl'``, ``'perez'``, ``'perez-driesse'``, - and ``'muneer'`` require ``'dni_extra'``. Values of ``'dni_extra'`` can be calculated - using :py:func:`~pvlib.irradiance.get_extra_radiation`. + and ``'muneer'`` require ``'dni_extra'``. Values of ``'dni_extra'`` + can be calculated using :py:func:`~pvlib.irradiance.get_extra_radiation`. The ``'perez'`` and ``'perez-driesse'`` models require relative airmass (``airmass``) as an input. If ``airmass`` is not provided, it is calculated @@ -1018,8 +1018,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ---------- surface_tilt : numeric Surface tilt angles in decimal degrees. ``surface_tilt`` must - be >=0 - and <=180. The tilt angle is defined as degrees from horizontal + be >=0 and <=180. The tilt angle is defined as degrees from horizontal (e.g. surface facing up = 0, surface facing horizon = 90) surface_azimuth : numeric From c2248f15e17d1166f74d3ae1ba9fe9a98e8e4268 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:50:51 +0200 Subject: [PATCH 29/50] Update DOI Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- pvlib/irradiance.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 44fdf471b8..b2ebdccab7 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1073,7 +1073,6 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, .. [2] Moon, P., Spencer, D.E., 1942. Illumination from a non-uniform sky. Trans. Illum. Eng. Soc. (London) 37, 707-725. - :doi:`10.1177/096032719302500301` ''' cos_solar_zenith = tools.cosd(solar_zenith) From 91fd1172e295193cd0633e31db15ddd037822541 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 19:36:55 +0200 Subject: [PATCH 30/50] create scenario with low solar altitude (<0.1rad) --- pvlib/irradiance.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index b2ebdccab7..24dd23ff89 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1094,10 +1094,21 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ) T = T_term1 + T_term2 * T_term3 - horizontal_extra = dni_extra * np.maximum(cos_solar_zenith, 0.01745) + horizontal_extra = dni_extra * cos_solar_zenith F = (ghi - dhi) / horizontal_extra - sky_diffuse = dhi*(T*(1-F) + F*Rb) + solar_elevation = np.pi/2 - np.radians(solar_zenith) + + numer_low = tools.sind(surface_tilt) * \ + tools.cosd(surface_azimuth - solar_azimuth) + denom_low = 0.1 - 0.008 * solar_elevation + + sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) + sky_diffuse_high = dhi*(T*(1-F) + F*Rb) + + low_elevation_condition = solar_elevation < 0.1 + sky_diffuse = np.where(low_elevation_condition, + sky_diffuse_low, sky_diffuse_high) return sky_diffuse From b8910dea5f8d6c27f2daa72fa354308e3ec53ef7 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 19:48:18 +0200 Subject: [PATCH 31/50] avoid zero in denominator --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 24dd23ff89..34a790abdf 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1101,7 +1101,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, numer_low = tools.sind(surface_tilt) * \ tools.cosd(surface_azimuth - solar_azimuth) - denom_low = 0.1 - 0.008 * solar_elevation + denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 0) sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) sky_diffuse_high = dhi*(T*(1-F) + F*Rb) From 0591323e4fabf58d6f32dcf47aa3ae80190b3217 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 19:58:36 +0200 Subject: [PATCH 32/50] division by zero fix --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 34a790abdf..6cf68ebabf 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1101,7 +1101,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, numer_low = tools.sind(surface_tilt) * \ tools.cosd(surface_azimuth - solar_azimuth) - denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 0) + denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 1e-10) sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) sky_diffuse_high = dhi*(T*(1-F) + F*Rb) From aed0e6d6e1f1d0e65ef0ce12ca5e0f826824734a Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:09:54 +0200 Subject: [PATCH 33/50] solar_azimuth is not optional anymore + test updated --- pvlib/irradiance.py | 5 ++--- pvlib/tests/test_irradiance.py | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 6cf68ebabf..15c0b38611 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1050,15 +1050,14 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or supply ``projection_ratio``. - solar_azimuth : numeric, optional + solar_azimuth : numeric Solar azimuth angles in decimal degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or supply ``projection_ratio``. projection_ratio : numeric, optional Ratio of angle of incidence projection to solar zenith angle - projection. Must supply ``solar_zenith`` and ``solar_azimuth`` - or supply ``projection_ratio``. + projection. Returns ------- diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index e159b58d6c..41380c25ca 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -290,14 +290,15 @@ def test_muneer(irrad_data, ephem_data, dni_et): projection_ratio = np.array( [0, 0, 0.8639607552973, 0.1716097049224]) out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], - dni_et, solar_zenith=ephem_data['apparent_zenith'], + dni_et, solar_zenith=ephem_data['zenith'], solar_azimuth=ephem_data['azimuth']) out_Rb = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], dni_et, - solar_zenith=ephem_data['apparent_zenith'], + solar_zenith=ephem_data['zenith'], + solar_azimuth=ephem_data['azimuth'], projection_ratio=projection_ratio) expected = pd.Series(np.array( - [0., 25.173, 100.757, 31.121]), + [0., 25.036, 100.757, 31.121]), index=irrad_data.index) assert_series_equal(out, expected, check_less_precise=2) assert_series_equal(out_Rb, expected, check_less_precise=2) From 2d4b10f4319922c69a0f4c1d178ad0453a72bdbd Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:30:08 +0200 Subject: [PATCH 34/50] # GH 432 --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 15c0b38611..b7206e6aec 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1100,7 +1100,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, numer_low = tools.sind(surface_tilt) * \ tools.cosd(surface_azimuth - solar_azimuth) - denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 1e-10) + denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 0.35025) # GH 432 sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) sky_diffuse_high = dhi*(T*(1-F) + F*Rb) From bec741250a636af13da18867444d79d53bfdc83d Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:39:24 +0200 Subject: [PATCH 35/50] test_update --- pvlib/tests/test_irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 41380c25ca..19fc354e63 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -288,7 +288,7 @@ def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass): def test_muneer(irrad_data, ephem_data, dni_et): projection_ratio = np.array( - [0, 0, 0.8639607552973, 0.1716097049224]) + [0, 0, 0.86399, 0.169725]) out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], dni_et, solar_zenith=ephem_data['zenith'], solar_azimuth=ephem_data['azimuth']) @@ -298,7 +298,7 @@ def test_muneer(irrad_data, ephem_data, dni_et): solar_azimuth=ephem_data['azimuth'], projection_ratio=projection_ratio) expected = pd.Series(np.array( - [0., 25.036, 100.757, 31.121]), + [0., 25.036, 100.759, 31.007]), index=irrad_data.index) assert_series_equal(out, expected, check_less_precise=2) assert_series_equal(out_Rb, expected, check_less_precise=2) From a3e3e3c20c31776afdade0aef811c2472ff6650b Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:46:10 +0200 Subject: [PATCH 36/50] replace np.where by .where to keep the pd.Series type --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index b7206e6aec..e9ae1c6418 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1106,8 +1106,8 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, sky_diffuse_high = dhi*(T*(1-F) + F*Rb) low_elevation_condition = solar_elevation < 0.1 - sky_diffuse = np.where(low_elevation_condition, - sky_diffuse_low, sky_diffuse_high) + sky_diffuse = sky_diffuse_low.where(low_elevation_condition, + sky_diffuse_high) return sky_diffuse From 927c8a89ed268863282315675431430f5e623a22 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:51:33 +0200 Subject: [PATCH 37/50] revert np.where and modify type if needed --- pvlib/irradiance.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index e9ae1c6418..92a76fc441 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1106,8 +1106,11 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, sky_diffuse_high = dhi*(T*(1-F) + F*Rb) low_elevation_condition = solar_elevation < 0.1 - sky_diffuse = sky_diffuse_low.where(low_elevation_condition, - sky_diffuse_high) + sky_diffuse = np.where(low_elevation_condition, + sky_diffuse_low, sky_diffuse_high) + if isinstance(sky_diffuse_low, pd.Series): + sky_diffuse = pd.Series(sky_diffuse_low, + index=sky_diffuse_low.index) return sky_diffuse From 7cfd6052e8a6101a9c3d0fd1e54b908b93a714fb Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 20:56:09 +0200 Subject: [PATCH 38/50] typo when converting sky_diffuse --- pvlib/irradiance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 92a76fc441..c102b41808 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1109,7 +1109,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, sky_diffuse = np.where(low_elevation_condition, sky_diffuse_low, sky_diffuse_high) if isinstance(sky_diffuse_low, pd.Series): - sky_diffuse = pd.Series(sky_diffuse_low, + sky_diffuse = pd.Series(sky_diffuse, index=sky_diffuse_low.index) return sky_diffuse From 5298cb2e861cb27807be559315020364f4dae6e3 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Tue, 3 Sep 2024 21:11:00 +0200 Subject: [PATCH 39/50] improvement # GH 432 --- pvlib/irradiance.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index c102b41808..b834ec664f 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1093,14 +1093,15 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ) T = T_term1 + T_term2 * T_term3 - horizontal_extra = dni_extra * cos_solar_zenith + horizontal_extra = dni_extra * \ + np.maximum(cos_solar_zenith, 0.01745) # GH 432 F = (ghi - dhi) / horizontal_extra solar_elevation = np.pi/2 - np.radians(solar_zenith) numer_low = tools.sind(surface_tilt) * \ tools.cosd(surface_azimuth - solar_azimuth) - denom_low = np.maximum(0.1 - 0.008 * solar_elevation, 0.35025) # GH 432 + denom_low = 0.1 - 0.008 * solar_elevation sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) sky_diffuse_high = dhi*(T*(1-F) + F*Rb) From ce6f5c088a41cd32dd3d003410347c73d18d49c8 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 09:45:43 +0200 Subject: [PATCH 40/50] np.array and float tests added --- pvlib/tests/test_irradiance.py | 36 ++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 19fc354e63..0b267f5850 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -287,8 +287,10 @@ def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass): def test_muneer(irrad_data, ephem_data, dni_et): - projection_ratio = np.array( - [0, 0, 0.86399, 0.169725]) + projection_ratio = pd.Series(np.array( + [0, 0, 0.86399, 0.169725]), index=irrad_data.index) + dni_et = pd.Series(dni_et, index=irrad_data.index) + # pd.Series out = irradiance.muneer(40, 180, irrad_data['dhi'], irrad_data['ghi'], dni_et, solar_zenith=ephem_data['zenith'], solar_azimuth=ephem_data['azimuth']) @@ -297,11 +299,41 @@ def test_muneer(irrad_data, ephem_data, dni_et): solar_zenith=ephem_data['zenith'], solar_azimuth=ephem_data['azimuth'], projection_ratio=projection_ratio) + # np.array + out_np = irradiance.muneer(40, 180, irrad_data['dhi'].values, + irrad_data['ghi'].values, dni_et.values, + solar_zenith=ephem_data['zenith'].values, + solar_azimuth=ephem_data['azimuth'].values) + out_np_Rb = irradiance.muneer(40, 180, irrad_data['dhi'].values, + irrad_data['ghi'].values, dni_et.values, + solar_zenith=ephem_data['zenith'].values, + solar_azimuth=ephem_data['azimuth'].values, + projection_ratio=projection_ratio.values) + # float + dhi_f = irrad_data['dhi'].values[2] + ghi_f = irrad_data['ghi'].values[2] + dni_et_f = dni_et.values[2] + solar_zenith_f = ephem_data['zenith'].values[2] + solar_azimuth_f = ephem_data['azimuth'].values[2] + projection_ratio_f = projection_ratio.values[2] + out_f = irradiance.muneer(40, 180, dhi_f, ghi_f, dni_et_f, + solar_zenith=solar_zenith_f, + solar_azimuth=solar_azimuth_f) + out_f_Rb = irradiance.muneer(40, 180, dhi_f, ghi_f, dni_et_f, + solar_zenith=solar_zenith_f, + solar_azimuth=solar_azimuth_f, + projection_ratio=projection_ratio_f) + expected = pd.Series(np.array( [0., 25.036, 100.759, 31.007]), index=irrad_data.index) + expected_f = 100.759 assert_series_equal(out, expected, check_less_precise=2) assert_series_equal(out_Rb, expected, check_less_precise=2) + assert_series_equal(out_np, expected, check_less_precise=2) + assert_series_equal(out_np_Rb, expected, check_less_precise=2) + assert_series_equal(out_f, expected_f, check_less_precise=2) + assert_series_equal(out_f_Rb, expected_f, check_less_precise=2) def test_perez_driesse_airmass(irrad_data, ephem_data, dni_et): From ce422410f9d1c535da5bba58dace6539e6e597e5 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 09:51:52 +0200 Subject: [PATCH 41/50] updated expected to np.array as it should be --- pvlib/tests/test_irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 0b267f5850..98f2c201c3 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -330,8 +330,8 @@ def test_muneer(irrad_data, ephem_data, dni_et): expected_f = 100.759 assert_series_equal(out, expected, check_less_precise=2) assert_series_equal(out_Rb, expected, check_less_precise=2) - assert_series_equal(out_np, expected, check_less_precise=2) - assert_series_equal(out_np_Rb, expected, check_less_precise=2) + assert_series_equal(out_np, expected.values, check_less_precise=2) + assert_series_equal(out_np_Rb, expected.values, check_less_precise=2) assert_series_equal(out_f, expected_f, check_less_precise=2) assert_series_equal(out_f_Rb, expected_f, check_less_precise=2) From 5632bda1e10ce987f50d006296d9652579526af2 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 10:41:58 +0200 Subject: [PATCH 42/50] assert_series_equal to assert_almost_equal --- pvlib/tests/test_irradiance.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pvlib/tests/test_irradiance.py b/pvlib/tests/test_irradiance.py index 98f2c201c3..aa62f7b21e 100644 --- a/pvlib/tests/test_irradiance.py +++ b/pvlib/tests/test_irradiance.py @@ -330,10 +330,10 @@ def test_muneer(irrad_data, ephem_data, dni_et): expected_f = 100.759 assert_series_equal(out, expected, check_less_precise=2) assert_series_equal(out_Rb, expected, check_less_precise=2) - assert_series_equal(out_np, expected.values, check_less_precise=2) - assert_series_equal(out_np_Rb, expected.values, check_less_precise=2) - assert_series_equal(out_f, expected_f, check_less_precise=2) - assert_series_equal(out_f_Rb, expected_f, check_less_precise=2) + assert_almost_equal(out_np, expected.values, decimal=2) + assert_almost_equal(out_np_Rb, expected.values, decimal=2) + assert_almost_equal(out_f, expected_f, decimal=2) + assert_almost_equal(out_f_Rb, expected_f, decimal=2) def test_perez_driesse_airmass(irrad_data, ephem_data, dni_et): From b2128cf7e05e50fd2b0f05ada5b8b141b4c6d0f4 Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 4 Sep 2024 12:25:18 +0200 Subject: [PATCH 43/50] documentation improvement Co-authored-by: Cliff Hansen --- pvlib/irradiance.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index b834ec664f..77b313b26b 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1056,8 +1056,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ``projection_ratio``. projection_ratio : numeric, optional - Ratio of angle of incidence projection to solar zenith angle - projection. + Ratio of cosing of angle of incidence to cosine of solar zenith angle. [unitless] Returns ------- From f9fb65c01bad7261d73655ebcab84594b68a4bb7 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 12:34:27 +0200 Subject: [PATCH 44/50] linter --- pvlib/irradiance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 77b313b26b..625046dff7 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1056,7 +1056,8 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ``projection_ratio``. projection_ratio : numeric, optional - Ratio of cosing of angle of incidence to cosine of solar zenith angle. [unitless] + Ratio of cosing of angle of incidence to cosine of solar zenith + angle. [unitless] Returns ------- From c0caf047f257aa7b7cdeb8b0c8f813ca226321ae Mon Sep 17 00:00:00 2001 From: Bernat Nicolau <55044322+BernatNicolau@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:56:17 +0200 Subject: [PATCH 45/50] Apply suggestions from code review Co-authored-by: RDaxini <143435106+RDaxini@users.noreply.github.com> --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 625046dff7..f94034a19c 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1056,7 +1056,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ``projection_ratio``. projection_ratio : numeric, optional - Ratio of cosing of angle of incidence to cosine of solar zenith + Ratio of cosine of angle of incidence to cosine of solar zenith angle. [unitless] Returns @@ -1070,7 +1070,7 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, Services Engineering Research and Technology 11, 153-163. :doi:`10.1177/014362449001100405` - .. [2] Moon, P., Spencer, D.E., 1942. Illumination from a non-uniform sky. + .. [2] Moon, P., and Spencer, D. E., 1942. Illumination from a non-uniform sky. Trans. Illum. Eng. Soc. (London) 37, 707-725. ''' From 21425593db6c73f1f563ff123bd52ecfa90e77da Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 14:59:01 +0200 Subject: [PATCH 46/50] unify irradiation unit format --- pvlib/irradiance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 625046dff7..00fc9af405 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1030,10 +1030,10 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, Diffuse horizontal irradiance. [W/m^2] ghi : numeric - Global horizontal irradiance in W/m^2. + Global horizontal irradiance. [W/m^2] dni_extra : numeric - Extraterrestrial normal irradiance in W/m^2. + Extraterrestrial normal irradiance. [W/m^2] b : numeric, default 5.73 Radiance distribution index, introduced by Moon and Spencer [2]_ From bedd18bbda3e398b9e730fe8928d32b7cc40d998 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Wed, 4 Sep 2024 14:59:58 +0200 Subject: [PATCH 47/50] linter --- pvlib/irradiance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 5ae0a01e36..71fc1695cd 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1070,7 +1070,8 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, Services Engineering Research and Technology 11, 153-163. :doi:`10.1177/014362449001100405` - .. [2] Moon, P., and Spencer, D. E., 1942. Illumination from a non-uniform sky. + .. [2] Moon, P., and Spencer, D. E., 1942. Illumination from a + non-uniform sky. Trans. Illum. Eng. Soc. (London) 37, 707-725. ''' From b5e4aeca16ad90c996cb962de609265c0dd451af Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Thu, 5 Sep 2024 12:29:17 +0200 Subject: [PATCH 48/50] muneer2004 --- pvlib/irradiance.py | 143 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 4 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 71fc1695cd..55d41ab271 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -453,8 +453,8 @@ def get_sky_diffuse(surface_tilt, surface_azimuth, sky = perez_driesse(surface_tilt, surface_azimuth, dhi, dni, dni_extra, solar_zenith, solar_azimuth, airmass) elif model == 'muneer': - sky = muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, - b, solar_zenith, solar_azimuth) + sky = muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, + solar_zenith, solar_azimuth) else: raise ValueError(f'invalid model selection {model}') @@ -1006,8 +1006,8 @@ def king(surface_tilt, dhi, ghi, solar_zenith): return sky_diffuse -def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, - solar_zenith=None, solar_azimuth=None, projection_ratio=None): +def muneer1990(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, + solar_zenith=None, solar_azimuth=None, projection_ratio=None): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer model. @@ -1117,6 +1117,141 @@ def muneer(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, return sky_diffuse +def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, + solar_zenith=None, solar_azimuth=None, projection_ratio=None, + location="northern_europe"): + ''' + Determine sky diffuse irradiance on a tilted surface using the + Muneer model. + + This Muneer transposition model is originally described in [1]_, and + improved for low solar elevations in [2]_. + + Parameters + ---------- + surface_tilt : numeric + Surface tilt angles in decimal degrees. ``surface_tilt`` must + be >=0 and <=180. The tilt angle is defined as degrees from horizontal + (e.g. surface facing up = 0, surface facing horizon = 90) + + surface_azimuth : numeric + Surface azimuth angles in decimal degrees. ``surface_azimuth`` + must be >=0 and <=360. The azimuth convention is defined as degrees + east of north (e.g. North = 0, South=180 East = 90, West = 270). + + dhi : numeric + Diffuse horizontal irradiance. [W/m^2] + + ghi : numeric + Global horizontal irradiance. [W/m^2] + + dni_extra : numeric + Extraterrestrial normal irradiance. [W/m^2] + + location : string, default 'northern_europe' + A string which selects the desired equation for calculating the second + term of T of Muneer model based on location. If location is not + provided as an input, the default, 'northern_europe' will be used. + All possible location selections are: + + * 'northern_europe' + * 'southern_europe' + * 'japan' + * 'globe' + + solar_zenith : numeric + Solar apparent (refraction-corrected) zenith angles in decimal + degrees. Must supply ``solar_zenith`` and ``solar_azimuth`` or + supply ``projection_ratio``. + + solar_azimuth : numeric + Solar azimuth angles in decimal degrees. Must supply + ``solar_zenith`` and ``solar_azimuth`` or supply + ``projection_ratio``. + + projection_ratio : numeric, optional + Ratio of cosine of angle of incidence to cosine of solar zenith + angle. [unitless] + + Returns + ------- + poa_sky_diffuse : numeric + In-plane diffuse irradiance from the sky. [W/m^2] + + References + ---------- + .. [1] Muneer, T., Gueymard, C., & Kambezidis, H., 2004. Hourly horizontal + irradiation and illuminance. 157-158 + :doi:`10.1016/B978-075065974-1/50011-5` + + .. [2] Gracia, A., & Huld, T., 2013. Performance comparison of different + models for the estimation of global irradiance on inclined surfaces: + validation of the model implemented in PVGIS. Centro Común de + Investigación, Instituto de Energía y Transporte. + :doi:`10.2790/91554` + + ''' + available_locations = ["northern_europe", "southern_europe", "japan", + "globe"] + if location not in available_locations: + raise ValueError + desired_index = available_locations.index(location) + + cos_solar_zenith = tools.cosd(solar_zenith) + # if necessary, calculate ratio of titled and horizontal beam irradiance + if projection_ratio is None: + cos_tt = aoi_projection(surface_tilt, surface_azimuth, + solar_zenith, solar_azimuth) + cos_tt = np.maximum(cos_tt, 0) # GH 526 + Rb = cos_tt / np.maximum(cos_solar_zenith, 0.01745) # GH 432 + else: + Rb = projection_ratio + + horizontal_extra = dni_extra * \ + np.maximum(cos_solar_zenith, 0.01745) # GH 432 + F = (ghi - dhi) / horizontal_extra + + aoi_ = aoi(surface_tilt, surface_azimuth, + solar_zenith, solar_azimuth) + low_elevation_condition = aoi_ >= 90 + F = np.where(low_elevation_condition, 0, F) + + T_term1 = (1 + tools.cosd(surface_tilt)) * 0.5 + + # term 2 depending on the selected location + T_term2_model0 = 0.00333 - 0.415 * F - 0.6987 * F ** 2 + T_term2_model1 = 0.00263 - 0.712 * F - 0.6883 * F ** 2 + T_term2_model2 = 0.08000 - 1.050 * F - 2.8400 * F ** 2 + T_term2_model3 = 0.04000 - 0.820 * F - 2.0260 * F ** 2 + T_term2 = np.array([T_term2_model0, T_term2_model1, + T_term2_model2, T_term2_model3]) + T_term2 = T_term2[desired_index] + + T_term3 = ( + tools.sind(surface_tilt) + - np.radians(surface_tilt) * tools.cosd(surface_tilt) + - np.pi * (1 - tools.cosd(surface_tilt)) * 0.5 + ) + + T = T_term1 + T_term2 * T_term3 + + solar_elevation = np.pi/2 - np.radians(solar_zenith) + numer_low = tools.sind(surface_tilt) * \ + tools.cosd(surface_azimuth - solar_azimuth) + denom_low = 0.1 - 0.008 * solar_elevation + + sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) + sky_diffuse_high = dhi*(T*(1-F) + F*Rb) + + low_elevation_condition = solar_elevation < 0.1 + sky_diffuse = np.where(low_elevation_condition, + sky_diffuse_low, sky_diffuse_high) + if isinstance(ghi, pd.Series): + sky_diffuse = pd.Series(sky_diffuse, + index=ghi.index) + return sky_diffuse + + def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra, solar_zenith, solar_azimuth, airmass, model='allsitescomposite1990', return_components=False): From 1bcf20def58184a5644d1cbd5376f192b8c67928 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Thu, 5 Sep 2024 14:06:31 +0200 Subject: [PATCH 49/50] overcast condition --- pvlib/irradiance.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 55d41ab271..535359f050 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1119,7 +1119,7 @@ def muneer1990(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, solar_zenith=None, solar_azimuth=None, projection_ratio=None, - location="northern_europe"): + location="southern_europe"): ''' Determine sky diffuse irradiance on a tilted surface using the Muneer model. @@ -1211,10 +1211,13 @@ def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, np.maximum(cos_solar_zenith, 0.01745) # GH 432 F = (ghi - dhi) / horizontal_extra + solar_elevation = np.pi/2 - np.radians(solar_zenith) + low_elevation_condition = solar_elevation < 0.1 + aoi_ = aoi(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth) - low_elevation_condition = aoi_ >= 90 - F = np.where(low_elevation_condition, 0, F) + overcast_condition = aoi_ >= 90 + F = np.where(overcast_condition, 0, F) T_term1 = (1 + tools.cosd(surface_tilt)) * 0.5 @@ -1226,6 +1229,7 @@ def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, T_term2 = np.array([T_term2_model0, T_term2_model1, T_term2_model2, T_term2_model3]) T_term2 = T_term2[desired_index] + T_term2 = np.where(overcast_condition, 0.25227, T_term2) T_term3 = ( tools.sind(surface_tilt) @@ -1235,7 +1239,6 @@ def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, T = T_term1 + T_term2 * T_term3 - solar_elevation = np.pi/2 - np.radians(solar_zenith) numer_low = tools.sind(surface_tilt) * \ tools.cosd(surface_azimuth - solar_azimuth) denom_low = 0.1 - 0.008 * solar_elevation @@ -1243,7 +1246,6 @@ def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, sky_diffuse_low = dhi*(T*(1-F) + F*(numer_low/denom_low)) sky_diffuse_high = dhi*(T*(1-F) + F*Rb) - low_elevation_condition = solar_elevation < 0.1 sky_diffuse = np.where(low_elevation_condition, sky_diffuse_low, sky_diffuse_high) if isinstance(ghi, pd.Series): From c9b92149617334e1b8e40ff728d793bd5f92c176 Mon Sep 17 00:00:00 2001 From: BernatNicolau Date: Fri, 6 Sep 2024 09:31:32 +0200 Subject: [PATCH 50/50] update clearness index --- pvlib/irradiance.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 535359f050..369cb260f2 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1094,9 +1094,8 @@ def muneer1990(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, b=5.73, ) T = T_term1 + T_term2 * T_term3 - horizontal_extra = dni_extra * \ - np.maximum(cos_solar_zenith, 0.01745) # GH 432 - F = (ghi - dhi) / horizontal_extra + F = pvlib.irradiance.clearness_index( + ghi - dhi, solar_zenith, dni_extra) solar_elevation = np.pi/2 - np.radians(solar_zenith) @@ -1207,9 +1206,8 @@ def muneer2004(surface_tilt, surface_azimuth, dhi, ghi, dni_extra, else: Rb = projection_ratio - horizontal_extra = dni_extra * \ - np.maximum(cos_solar_zenith, 0.01745) # GH 432 - F = (ghi - dhi) / horizontal_extra + F = pvlib.irradiance.clearness_index( + ghi - dhi, solar_zenith, dni_extra) solar_elevation = np.pi/2 - np.radians(solar_zenith) low_elevation_condition = solar_elevation < 0.1