@@ -2267,6 +2267,136 @@ def erbs(ghi, zenith, datetime_or_doy, min_cos_zenith=0.065, max_zenith=87):
22672267 return data
22682268
22692269
2270+ def erbs_driesse (ghi , zenith , datetime_or_doy = None , dni_extra = None ,
2271+ min_cos_zenith = 0.065 , max_zenith = 87 ):
2272+ r"""
2273+ Estimate DNI and DHI from GHI using the continuous Erbs-Driesse model.
2274+
2275+ The Erbs-Driesse model [1]_ is a reformulation of the original Erbs
2276+ model [2]_ that provides continuity of the function and its first
2277+ derivative at the two transition points.
2278+
2279+ .. math::
2280+
2281+ DHI = DF \times GHI
2282+
2283+ DNI is then estimated as
2284+
2285+ .. math::
2286+
2287+ DNI = (GHI - DHI)/\cos(Z)
2288+
2289+ where Z is the zenith angle.
2290+
2291+ Parameters
2292+ ----------
2293+ ghi: numeric
2294+ Global horizontal irradiance in W/m^2.
2295+ zenith: numeric
2296+ True (not refraction-corrected) zenith angles in decimal degrees.
2297+ datetime_or_doy : int, float, array, pd.DatetimeIndex, default None
2298+ Day of year or array of days of year e.g.
2299+ pd.DatetimeIndex.dayofyear, or pd.DatetimeIndex.
2300+ Either datetime_or_doy or dni_extra must be provided.
2301+ dni_extra : numeric, default None
2302+ Extraterrestrial normal irradiance.
2303+ dni_extra can be provided if available to avoid recalculating it
2304+ inside this function. In this case datetime_or_doy is not required.
2305+ min_cos_zenith : numeric, default 0.065
2306+ Minimum value of cos(zenith) to allow when calculating global
2307+ clearness index `kt`. Equivalent to zenith = 86.273 degrees.
2308+ max_zenith : numeric, default 87
2309+ Maximum value of zenith to allow in DNI calculation. DNI will be
2310+ set to 0 for times with zenith values greater than `max_zenith`.
2311+
2312+ Returns
2313+ -------
2314+ data : OrderedDict or DataFrame
2315+ Contains the following keys/columns:
2316+
2317+ * ``dni``: the modeled direct normal irradiance in W/m^2.
2318+ * ``dhi``: the modeled diffuse horizontal irradiance in
2319+ W/m^2.
2320+ * ``kt``: Ratio of global to extraterrestrial irradiance
2321+ on a horizontal plane.
2322+
2323+ Raises
2324+ ------
2325+ ValueError
2326+ If neither datetime_or_doy nor dni_extra is provided.
2327+
2328+ Notes
2329+ -----
2330+ The diffuse fraction DHI/GHI of the Erbs-Driesse model deviates from the
2331+ original Erbs model by less than 0.0005.
2332+
2333+ References
2334+ ----------
2335+ .. [1] A. Driesse, A. Jensen, R. Perez, A Continuous Form of the Perez
2336+ Diffuse Sky Model for Forward and Reverse Transposition, forthcoming.
2337+
2338+ .. [2] D. G. Erbs, S. A. Klein and J. A. Duffie, Estimation of the
2339+ diffuse radiation fraction for hourly, daily and monthly-average
2340+ global radiation, Solar Energy 28(4), pp 293-302, 1982. Eq. 1
2341+
2342+ See also
2343+ --------
2344+ erbs
2345+ dirint
2346+ disc
2347+ orgill_hollands
2348+ boland
2349+ """
2350+ # central polynomial coefficients with float64 precision
2351+ p = [+ 12.26911439571261000 ,
2352+ - 16.47050842469730700 ,
2353+ + 04.24692671521831700 ,
2354+ - 00.11390583806313881 ,
2355+ + 00.94629663357100100 ]
2356+
2357+ if datetime_or_doy is None and dni_extra is None :
2358+ raise ValueError ('Either datetime_or_doy or dni_extra '
2359+ 'must be provided.' )
2360+
2361+ if dni_extra is None :
2362+ dni_extra = get_extra_radiation (datetime_or_doy )
2363+
2364+ # negative ghi should not reach this point, but just in case
2365+ ghi = np .maximum (0 , ghi )
2366+
2367+ kt = clearness_index (ghi , zenith , dni_extra , min_cos_zenith = min_cos_zenith ,
2368+ max_clearness_index = 1 )
2369+
2370+ # For all Kt, set the default diffuse fraction
2371+ df = 1 - 0.09 * kt
2372+
2373+ # For Kt > 0.216, update the diffuse fraction
2374+ df = np .where (kt > 0.216 , np .polyval (p , kt ), df )
2375+
2376+ # For Kt > 0.792, update the diffuse fraction again
2377+ df = np .where (kt > 0.792 , 0.165 , df )
2378+
2379+ dhi = df * ghi
2380+
2381+ dni = (ghi - dhi ) / tools .cosd (zenith )
2382+ bad_values = (zenith > max_zenith ) | (ghi < 0 ) | (dni < 0 )
2383+ dni = np .where (bad_values , 0 , dni )
2384+ # ensure that closure relationship remains valid
2385+ dhi = np .where (bad_values , ghi , dhi )
2386+
2387+ data = OrderedDict ()
2388+ data ['dni' ] = dni
2389+ data ['dhi' ] = dhi
2390+ data ['kt' ] = kt
2391+
2392+ if isinstance (datetime_or_doy , pd .DatetimeIndex ):
2393+ data = pd .DataFrame (data , index = datetime_or_doy )
2394+ elif isinstance (ghi , pd .Series ):
2395+ data = pd .DataFrame (data , index = ghi .index )
2396+
2397+ return data
2398+
2399+
22702400def orgill_hollands (ghi , zenith , datetime_or_doy , dni_extra = None ,
22712401 min_cos_zenith = 0.065 , max_zenith = 87 ):
22722402 """Estimate DNI and DHI from GHI using the Orgill and Hollands model.
0 commit comments