ERBS
This function decomposes Global Horizontal Irradiance (GHI) into Direct Normal Irradiance (DNI) and Diffuse Horizontal Irradiance (DHI) using the Erbs empirical model.
The model estimates the diffuse fraction from GHI and computing the ratio of GHI to extraterrestrial irradiance. The result is returned as a 2D array where each row contains the computed DNI, DHI, and the clearness index (Kt).
Excel Usage
=ERBS(ghi, solar_zenith, times, min_cos_zenith, max_zenith)
ghi(list[list], required): Global horizontal irradiance (W/m^2).solar_zenith(list[list], required): True (not refraction-corrected) solar zenith angles (degrees).times(list[list], required): Timestamps in ISO8601 format.min_cos_zenith(float, optional, default: 0.065): Minimum value of cos(zenith) when calculating clearness index.max_zenith(float, optional, default: 87): Maximum value of zenith to allow in DNI calculation (degrees).
Returns (list[list]): 2D list containing [[dni, dhi, kt]], or an error string.
Example 1: Perform Erbs decomposition
Inputs:
| ghi | solar_zenith | times |
|---|---|---|
| 800 | 40 | 2024-06-21T12:00:00Z |
| 500 | 60 | 2024-06-21T16:00:00Z |
Excel formula:
=ERBS({800;500}, {40;60}, {"2024-06-21T12:00:00Z";"2024-06-21T16:00:00Z"})
Expected output:
| Result | ||
|---|---|---|
| 872.408 | 131.696 | 0.790283 |
| 822.17 | 88.9148 | 0.75674 |
Example 2: Erbs decomposition for a morning ramp
Inputs:
| ghi | solar_zenith | times |
|---|---|---|
| 250 | 75 | 2024-04-10T07:00:00Z |
| 500 | 55 | 2024-04-10T09:00:00Z |
| 720 | 35 | 2024-04-10T11:00:00Z |
Excel formula:
=ERBS({250;500;720}, {75;55;35}, {"2024-04-10T07:00:00Z";"2024-04-10T09:00:00Z";"2024-04-10T11:00:00Z"})
Expected output:
| Result | ||
|---|---|---|
| 744.997 | 57.1806 | 0.710242 |
| 565.004 | 175.927 | 0.640975 |
| 579.196 | 245.55 | 0.646295 |
Example 3: Erbs decomposition with custom minimum cosine
Inputs:
| ghi | solar_zenith | times | min_cos_zenith |
|---|---|---|---|
| 300 | 70 | 2024-08-01T08:00:00Z | 0.08 |
| 620 | 45 | 2024-08-01T10:00:00Z | |
| 450 | 62 | 2024-08-01T14:00:00Z |
Excel formula:
=ERBS({300;620;450}, {70;45;62}, {"2024-08-01T08:00:00Z";"2024-08-01T10:00:00Z";"2024-08-01T14:00:00Z"}, 0.08)
Expected output:
| Result | ||
|---|---|---|
| 604.64 | 93.2011 | 0.661743 |
| 603.997 | 192.91 | 0.661495 |
| 755.897 | 95.128 | 0.723141 |
Example 4: Erbs decomposition with stricter zenith cutoff
Inputs:
| ghi | solar_zenith | times | max_zenith |
|---|---|---|---|
| 180 | 82 | 2024-02-20T07:30:00Z | 80 |
| 340 | 74 | 2024-02-20T08:30:00Z | |
| 520 | 68 | 2024-02-20T09:30:00Z |
Excel formula:
=ERBS({180;340;520}, {82;74;68}, {"2024-02-20T07:30:00Z";"2024-02-20T08:30:00Z";"2024-02-20T09:30:00Z"}, 80)
Expected output:
| Result | ||
|---|---|---|
| 0 | 180 | 0.92514 |
| 1029.98 | 56.1 | 0.88233 |
| 1159.08 | 85.8 | 0.992929 |
Python Code
Show Code
import pandas as pd
import numpy as np
from pvlib.irradiance import erbs as result_func
def erbs(ghi, solar_zenith, times, min_cos_zenith=0.065, max_zenith=87):
"""
Estimate DNI and DHI from GHI and solar zenith using the Erbs model.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.erbs.html
This example function is provided as-is without any representation of accuracy.
Args:
ghi (list[list]): Global horizontal irradiance (W/m^2).
solar_zenith (list[list]): True (not refraction-corrected) solar zenith angles (degrees).
times (list[list]): Timestamps in ISO8601 format.
min_cos_zenith (float, optional): Minimum value of cos(zenith) when calculating clearness index. Default is 0.065.
max_zenith (float, optional): Maximum value of zenith to allow in DNI calculation (degrees). Default is 87.
Returns:
list[list]: 2D list containing [[dni, dhi, kt]], or an error string.
"""
try:
def flatten_num(data):
if not isinstance(data, list): return [float(data)]
flat = []
for row in data:
row = row if isinstance(row, list) else [row]
for val in row:
if val == "": flat.append(float('nan'))
else: flat.append(float(val))
return flat
def flatten_str(data):
if not isinstance(data, list): return [str(data)]
return [str(val) for row in data for val in (row if isinstance(row, list) else [row]) if val != ""]
ghi_list = flatten_num(ghi)
zen_list = flatten_num(solar_zenith)
time_list = flatten_str(times)
n = len(ghi_list)
if n == 0 or len(zen_list) != n or len(time_list) != n:
return "Error: All input arrays must have the same non-zero length"
idx = pd.DatetimeIndex(time_list)
min_cz = float(min_cos_zenith) if min_cos_zenith is not None else 0.065
max_z = float(max_zenith) if max_zenith is not None else 87.0
res = result_func(np.array(ghi_list), np.array(zen_list), idx, min_cos_zenith=min_cz, max_zenith=max_z)
output = []
# Res returns an OrderedDict with 'dni', 'dhi', 'kt'
dnia = res['dni']
dhia = res['dhi']
kta = res['kt']
for i in range(n):
d = float(dnia[i])
dh = float(dhia[i])
k = float(kta[i])
output.append([d if not pd.isna(d) else "", dh if not pd.isna(dh) else "", k if not pd.isna(k) else ""])
return output
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Global horizontal irradiance (W/m^2).
True (not refraction-corrected) solar zenith angles (degrees).
Timestamps in ISO8601 format.
Minimum value of cos(zenith) when calculating clearness index.
Maximum value of zenith to allow in DNI calculation (degrees).