AOI

This function computes the angle between the solar vector and the surface normal.

It is a fundamental calculation for determining the amount of direct irradiance reaching a PV module or thermal collector.

Excel Usage

=AOI(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth)
  • surface_tilt (list[list], required): Panel tilt from horizontal (degrees).
  • surface_azimuth (list[list], required): Panel azimuth direction (degrees).
  • solar_zenith (list[list], required): Solar zenith angle (degrees).
  • solar_azimuth (list[list], required): Solar azimuth angle (degrees).

Returns (list[list]): 2D list of AOI values (degrees), or an error string.

Example 1: Sun directly normal to surface

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
30 180 30 180

Excel formula:

=AOI({30}, {180}, {30}, {180})

Expected output:

0

Example 2: East-facing surface in morning sun

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
25 90 40 100

Excel formula:

=AOI({25}, {90}, {40}, {100})

Expected output:

15.888

Example 3: Vectorized AOI for two timesteps

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
20 20 180 180 20 60 180 210

Excel formula:

=AOI({20,20}, {180,180}, {20,60}, {180,210})

Expected output:

Result
0
43.4178
Example 4: Scalar inputs are accepted

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
35 180 50 170

Excel formula:

=AOI(35, 180, 50, 170)

Expected output:

16.4129

Python Code

Show Code
import pandas as pd
import numpy as np
from pvlib.irradiance import aoi as result_func

def aoi(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
    """
    Calculate the angle of incidence (AOI) for a surface.

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.aoi.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        surface_tilt (list[list]): Panel tilt from horizontal (degrees).
        surface_azimuth (list[list]): Panel azimuth direction (degrees).
        solar_zenith (list[list]): Solar zenith angle (degrees).
        solar_azimuth (list[list]): Solar azimuth angle (degrees).

    Returns:
        list[list]: 2D list of AOI values (degrees), 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

        t_list = flatten_num(surface_tilt)
        a_list = flatten_num(surface_azimuth)
        z_list = flatten_num(solar_zenith)
        az_list = flatten_num(solar_azimuth)

        n = len(t_list)
        if n == 0 or len(a_list) != n or len(z_list) != n or len(az_list) != n:
            return "Error: All input arrays must have the same non-zero length"

        res = result_func(
            surface_tilt=np.array(t_list),
            surface_azimuth=np.array(a_list),
            solar_zenith=np.array(z_list),
            solar_azimuth=np.array(az_list)
        )

        return [[float(v) if not pd.isna(v) else ""] for v in res]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Panel tilt from horizontal (degrees).
Panel azimuth direction (degrees).
Solar zenith angle (degrees).
Solar azimuth angle (degrees).