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).