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 value
  • surface_azimuth (int, required): The surface_azimuth value
  • solar_zenith (int, required): The solar_zenith value
  • solar_azimuth (int, required): The solar_azimuth value
  • dni (int, required): The dni value
  • ghi (int, required): The ghi value
  • dhi (int, required): The dhi value
  • dni_extra (float, optional, default: 1367): The dni_extra value
  • airmass (float, optional, default: null): The airmass value
  • albedo (float, optional, default: null): The albedo value
  • model (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}"

Online Calculator