Skip to content

Commit ad832cd

Browse files
Lakshyadevelopscwhansekandersolar
authored
Implement pvlib.irradiance.louche decomposition model (#1705)
* added pvl_louche * stickler * add tests * stickler * stickler * made suggested changes * updated what's new, doc API changes & added notes * correct comments * Update pvlib/irradiance.py Co-authored-by: Cliff Hansen <[email protected]> * complete PR with formatting changes * stickler * Update pvlib/irradiance.py Co-authored-by: Kevin Anderson <[email protected]> * done necessary changes * Update docs/sphinx/source/reference/irradiance/decomposition.rst Co-authored-by: Cliff Hansen <[email protected]> * removed SSC comment * Apply suggestions from code review --------- Co-authored-by: Cliff Hansen <[email protected]> Co-authored-by: Kevin Anderson <[email protected]>
1 parent 5596be3 commit ad832cd

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

docs/sphinx/source/reference/irradiance/decomposition.rst

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ DNI estimation models
1515
irradiance.boland
1616
irradiance.campbell_norman
1717
irradiance.gti_dirint
18+
irradiance.louche
19+

docs/sphinx/source/whatsnew/v0.9.6.rst

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Deprecations
2323

2424
Enhancements
2525
~~~~~~~~~~~~
26+
* Added a new irradiance decomposition model :py:func:`pvlib.irradiance.louche`. (:pull:`1705`)
2627
* Add optional encoding parameter to :py:func:`pvlib.iotools.read_tmy3`.
2728
(:issue:`1732`, :pull:`1737`)
2829
* Added function to retrieve horizon data from PVGIS
@@ -79,3 +80,4 @@ Contributors
7980
* Andy Lam (:ghuser:`@andylam598`)
8081
* :ghuser:`ooprathamm`
8182
* Kevin Anderson (:ghuser:`kandersolar`)
83+

pvlib/irradiance.py

+61
Original file line numberDiff line numberDiff line change
@@ -3117,3 +3117,64 @@ def complete_irradiance(solar_zenith,
31173117
'dhi': dhi,
31183118
'dni': dni})
31193119
return component_sum_df
3120+
3121+
3122+
def louche(ghi, solar_zenith, datetime_or_doy, max_zenith=90):
3123+
"""
3124+
Determine DNI and DHI from GHI using the Louche model.
3125+
3126+
Parameters
3127+
----------
3128+
ghi : numeric
3129+
Global horizontal irradiance. [W/m^2]
3130+
3131+
solar_zenith : numeric
3132+
True (not refraction-corrected) zenith angles in decimal
3133+
degrees. Angles must be >=0 and <=90.
3134+
3135+
datetime_or_doy : numeric, pandas.DatetimeIndex
3136+
Day of year or array of days of year e.g.
3137+
pd.DatetimeIndex.dayofyear, or pd.DatetimeIndex.
3138+
3139+
Returns
3140+
-------
3141+
data: OrderedDict or DataFrame
3142+
Contains the following keys/columns:
3143+
3144+
* ``dni``: the modeled direct normal irradiance in W/m^2.
3145+
* ``dhi``: the modeled diffuse horizontal irradiance in
3146+
W/m^2.
3147+
* ``kt``: Ratio of global to extraterrestrial irradiance
3148+
on a horizontal plane.
3149+
3150+
References
3151+
-------
3152+
.. [1] Louche A, Notton G, Poggi P, Simonnot G. Correlations for direct
3153+
normal and global horizontal irradiation on a French Mediterranean site.
3154+
Solar Energy 1991;46:261-6. :doi:`10.1016/0038-092X(91)90072-5`
3155+
3156+
"""
3157+
3158+
I0 = get_extra_radiation(datetime_or_doy)
3159+
3160+
Kt = clearness_index(ghi, solar_zenith, I0)
3161+
3162+
kb = -10.627*Kt**5 + 15.307*Kt**4 - 5.205 * \
3163+
Kt**3 + 0.994*Kt**2 - 0.059*Kt + 0.002
3164+
dni = kb*I0
3165+
dhi = ghi - dni*tools.cosd(solar_zenith)
3166+
3167+
bad_values = (solar_zenith > max_zenith) | (ghi < 0) | (dni < 0)
3168+
dni = np.where(bad_values, 0, dni)
3169+
# ensure that closure relationship remains valid
3170+
dhi = np.where(bad_values, ghi, dhi)
3171+
3172+
data = OrderedDict()
3173+
data['dni'] = dni
3174+
data['dhi'] = dhi
3175+
data['kt'] = Kt
3176+
3177+
if isinstance(datetime_or_doy, pd.DatetimeIndex):
3178+
data = pd.DataFrame(data, index=datetime_or_doy)
3179+
3180+
return data

pvlib/tests/test_irradiance.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def test_haydavies_components(irrad_data, ephem_data, dni_et):
246246
assert_allclose(result['horizon'], expected['horizon'][-1], atol=1e-4)
247247
assert isinstance(result, dict)
248248

249+
249250
def test_reindl(irrad_data, ephem_data, dni_et):
250251
result = irradiance.reindl(
251252
40, 180, irrad_data['dhi'], irrad_data['dni'], irrad_data['ghi'],
@@ -903,8 +904,12 @@ def test_dirindex(times):
903904
assert np.allclose(out, expected_out, rtol=tolerance, atol=0,
904905
equal_nan=True)
905906
tol_dirint = 0.2
906-
assert np.allclose(out.values, dirint_close_values, rtol=tol_dirint, atol=0,
907-
equal_nan=True)
907+
assert np.allclose(
908+
out.values,
909+
dirint_close_values,
910+
rtol=tol_dirint,
911+
atol=0,
912+
equal_nan=True)
908913

909914

910915
def test_dirindex_min_cos_zenith_max_zenith():
@@ -1203,3 +1208,20 @@ def test_complete_irradiance():
12031208
dhi=None,
12041209
dni=i.dni,
12051210
dni_clear=clearsky.dni)
1211+
1212+
1213+
def test_louche():
1214+
1215+
index = pd.DatetimeIndex(['20190101']*3 + ['20190620']*1)
1216+
ghi = pd.Series([0, 50, 1000, 1000], index=index)
1217+
zenith = pd.Series([91, 85, 10, 10], index=index)
1218+
expected = pd.DataFrame(np.array(
1219+
[[0, 0, 0],
1220+
[130.089669, 38.661938, 0.405724],
1221+
[828.498650, 184.088106, 0.718133],
1222+
[887.407348, 126.074364, 0.768214]]),
1223+
columns=['dni', 'dhi', 'kt'], index=index)
1224+
1225+
out = irradiance.louche(ghi, zenith, index)
1226+
1227+
assert_frame_equal(out, expected)

0 commit comments

Comments
 (0)