IRRADIANCE
Overview
The IRRADIANCE function calculates plane of array (POA) irradiance components on a tilted photovoltaic surface using the pvlib library. POA irradiance represents the total solar radiation incident on a PV module, which is essential for accurately predicting solar energy system performance.
Solar irradiance at a tilted surface comprises three components: direct beam radiation from the sun, diffuse radiation scattered by the atmosphere, and ground-reflected radiation. The function performs irradiance transposition, converting horizontal irradiance measurements (GHI, DNI, DHI) into the plane of the solar array. The total POA irradiance is computed as:
I_{total} = I_{beam} + I_{sky\ diffuse} + I_{ground\ diffuse}
where I_{beam} is the direct component, I_{sky\ diffuse} is the portion of diffuse horizontal irradiance (DHI) that reaches the tilted surface from the sky dome, and I_{ground\ diffuse} is reflected radiation from the ground surface based on the albedo coefficient.
This implementation uses pvlib’s PVSystem.get_irradiance() method, which internally calls get_total_irradiance(). The function supports multiple sky diffuse transposition models including:
- Isotropic: Assumes uniform sky radiance distribution
- Hay-Davies (default): Accounts for circumsolar and isotropic diffuse components using an anisotropy index
- Perez: A more sophisticated model using empirical coefficients for circumsolar brightening and horizon brightness
- Klucher and Reindl: Additional anisotropic models with varying complexity
The function returns five irradiance components: poa_global (total), poa_direct, poa_diffuse, poa_sky_diffuse, and poa_ground_diffuse, all measured in W/m². For the Hay-Davies and Perez models, extraterrestrial DNI (dni_extra) is required; if not provided, the default solar constant of 1367 W/m² is used.
For more information on solar irradiance concepts and measurement, see the Wikipedia article on solar irradiance. The pvlib library source code is available on GitHub.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=IRRADIANCE(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi, dni_extra, airmass, albedo, model)
surface_tilt(int, required): The surface_tilt valuesurface_azimuth(int, required): The surface_azimuth valuesolar_zenith(int, required): The solar_zenith valuesolar_azimuth(int, required): The solar_azimuth valuedni(int, required): The dni valueghi(int, required): The ghi valuedhi(int, required): The dhi valuedni_extra(float, optional, default: 1367): The dni_extra valueairmass(float, optional, default: null): The airmass valuealbedo(float, optional, default: null): The albedo valuemodel(str, optional, default: “haydavies”): The model value
Returns (list[list]): 2D list [[poa_global, poa_direct, poa_diffuse, …]], or error string.
Examples
Example 1: Demo case 1
Inputs:
| surface_tilt | surface_azimuth | solar_zenith | solar_azimuth | dni | ghi | dhi | dni_extra | model |
|---|---|---|---|---|---|---|---|---|
| 30 | 180 | 40 | 180 | 800 | 1000 | 100 | 1367 | haydavies |
Excel formula:
=IRRADIANCE(30, 180, 40, 180, 800, 1000, 100, 1367, "haydavies")
Expected output:
| Result | ||||
|---|---|---|---|---|
| 918.5 | 787.8 | 130.7 | 113.9 | 16.75 |
Example 2: Demo case 2
Inputs:
| surface_tilt | surface_azimuth | solar_zenith | solar_azimuth | dni | ghi | dhi | dni_extra | albedo | model |
|---|---|---|---|---|---|---|---|---|---|
| 30 | 180 | 40 | 180 | 800 | 1000 | 100 | 1367 | 0.2 | haydavies |
Excel formula:
=IRRADIANCE(30, 180, 40, 180, 800, 1000, 100, 1367, 0.2, "haydavies")
Expected output:
| Result | ||||
|---|---|---|---|---|
| 915.2 | 787.8 | 127.3 | 113.9 | 13.4 |
Example 3: Demo case 3
Inputs:
| surface_tilt | surface_azimuth | solar_zenith | solar_azimuth | dni | ghi | dhi | dni_extra | model |
|---|---|---|---|---|---|---|---|---|
| 30 | 180 | 40 | 180 | 800 | 1000 | 100 | 1367 | isotropic |
Excel formula:
=IRRADIANCE(30, 180, 40, 180, 800, 1000, 100, 1367, "isotropic")
Expected output:
| Result | ||||
|---|---|---|---|---|
| 897.9 | 787.8 | 110 | 93.3 | 16.75 |
Example 4: Demo case 4
Inputs:
| surface_tilt | surface_azimuth | solar_zenith | solar_azimuth | dni | ghi | dhi | dni_extra | airmass | model |
|---|---|---|---|---|---|---|---|---|---|
| 30 | 180 | 40 | 180 | 800 | 1000 | 100 | 1367 | 1.5 | haydavies |
Excel formula:
=IRRADIANCE(30, 180, 40, 180, 800, 1000, 100, 1367, 1.5, "haydavies")
Expected output:
| Result | ||||
|---|---|---|---|---|
| 918.5 | 787.8 | 130.7 | 113.9 | 16.75 |
Python Code
import micropip
await micropip.install(["pvlib"])
from pvlib.pvsystem import PVSystem as pv_system
def irradiance(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi, dni_extra=1367, airmass=None, albedo=None, model='haydavies'):
"""
Calculate the plane of array irradiance components on a tilted surface using PVLib.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.PVSystem.get_irradiance.html
This example function is provided as-is without any representation of accuracy.
Args:
surface_tilt (int): The surface_tilt value
surface_azimuth (int): The surface_azimuth value
solar_zenith (int): The solar_zenith value
solar_azimuth (int): The solar_azimuth value
dni (int): The dni value
ghi (int): The ghi value
dhi (int): The dhi value
dni_extra (float, optional): The dni_extra value Default is 1367.
airmass (float, optional): The airmass value Default is None.
albedo (float, optional): The albedo value Default is None.
model (str, optional): The model value Default is 'haydavies'.
Returns:
list[list]: 2D list [[poa_global, poa_direct, poa_diffuse, ...]], or error string.
"""
try:
# Validate required arguments
args = [surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, dni, ghi, dhi]
for v in args:
if v is None:
return "Error: All required arguments must be provided."
# Convert all to float
surface_tilt = float(surface_tilt)
surface_azimuth = float(surface_azimuth)
solar_zenith = float(solar_zenith)
solar_azimuth = float(solar_azimuth)
dni = float(dni)
ghi = float(ghi)
dhi = float(dhi)
if dni_extra is not None:
dni_extra = float(dni_extra)
if airmass is not None:
airmass = float(airmass)
if albedo is not None:
albedo = float(albedo)
if model is None:
model = 'haydavies'
# Create PVSystem
system = pv_system(surface_tilt=surface_tilt, surface_azimuth=surface_azimuth)
# Call get_irradiance
poa = system.get_irradiance(
solar_zenith=solar_zenith,
solar_azimuth=solar_azimuth,
dni=dni,
ghi=ghi,
dhi=dhi,
dni_extra=dni_extra,
airmass=airmass,
albedo=albedo,
model=model
)
# Extract results
keys = ['poa_global', 'poa_direct', 'poa_diffuse', 'poa_sky_diffuse', 'poa_ground_diffuse']
row = []
for k in keys:
v = poa[k] if k in poa else None
if v is None:
row.append(None)
else:
try:
row.append(float(v))
except Exception:
row.append(None)
return [row]
except Exception as e:
return f"Error: {e}"