Skip to main content

Summary

Horizon shading accounts for beam irradiance losses when the sun is blocked by distant terrain features, trees, buildings, or other obstructions beyond the solar array field. Users define a horizon profile as a series of - pairs describing the apparent horizon line around the site. At each timestep, the algorithm compares the solar position to the interpolated horizon elevation at that azimuth and determines whether the sun is visible. When sunrise or sunset occurs within a timestep and the sun passes behind the horizon, fractional shading is calculated based on the duration of obstruction.

Inputs

NameSymbolUnitsDescription
Horizon Profile{(γi,ei)}\{(\gamma_i, e_i)\}degreesList of azimuth-elevation pairs defining horizon
Solar Zenith Angleθz\theta_zdegreesAngle between sun and vertical
Solar Azimuth Angleγs\gamma_sdegreesSun’s compass direction (0° = north)
Solar Elevation Angleese_sdegreesSun altitude above horizon (90°θz90° - \theta_z)
TimestampttCurrent time step
Previous/Next Timestampstprev,tnextt_{prev}, t_{next}Adjacent time steps for interpolation
Previous/Next Solar PositionsdegreesSolar positions at adjacent time steps
Sunrise/Sunset TimeTimes when sun crosses horizon (if in interval)

Outputs

NameSymbolUnitsDescription
Horizon Shading FactorUhorizonU_{horizon}Unshaded fraction of beam irradiance (0-1)
Traverse Timettraverset_{traverse}Time when sun clears horizon obstruction
Shading DurationΔt\Delta tminutesDuration sun is behind horizon within timestep

Detailed Description

Horizon Profile Definition

The horizon profile is a user-defined list of obstruction elevations at specified azimuths around the site: Horizon={(γ1,e1),(γ2,e2),,(γn,en)}\text{Horizon} = \{(\gamma_1, e_1), (\gamma_2, e_2), \ldots, (\gamma_n, e_n)\} where:
  • γi\gamma_i is the azimuth direction (0° to 360°, 0° = north, 90° = east)
  • eie_i is the elevation angle of the obstruction at that azimuth (degrees above horizon)
The profile typically includes 8 to 36 points covering the full 360° horizon. Points should be ordered by increasing azimuth.

Horizon Elevation Interpolation

For each timestep, the algorithm determines the horizon elevation at the current solar azimuth by linear interpolation: Find Bounding Azimuths: Locate indices ii and i+1i+1 such that: γiγs<γi+1\gamma_i \leq \gamma_s < \gamma_{i+1} Interpolate Elevation: ehorizon(γs)=ei+(γsγi)(γi+1γi)(ei+1ei)e_{horizon}(\gamma_s) = e_i + \frac{(\gamma_s - \gamma_i)}{(\gamma_{i+1} - \gamma_i)} (e_{i+1} - e_i) Special handling for azimuth wraparound at 0°/360°.

Sun Visibility Determination

The algorithm checks if the sun is blocked by comparing solar elevation to horizon elevation: Fully Visible: If esehorizon(γs)e_s \geq e_{horizon}(\gamma_s), the sun is above the horizon obstruction: Uhorizon=1.0U_{horizon} = 1.0 Fully Blocked: If es<ehorizon(γs)e_s < e_{horizon}(\gamma_s) and the sun remains blocked for the entire timestep: Uhorizon=0.0U_{horizon} = 0.0 Partial Blocking: If sunrise/sunset occurs within the timestep and the sun crosses behind or emerges from the horizon obstruction, fractional shading is calculated.

Fractional Shading Calculation

When the sun transitions across the horizon during a timestep, the algorithm calculates the traverse time and shading duration. Sun Direction Determination: Determine if the sun is rising (direction=1\text{direction} = 1) or setting (direction=1\text{direction} = -1) by comparing solar elevations at adjacent timesteps. Azimuth at Lowest Elevation Time: If sunrise/sunset occurs in the current timestep, the lowest solar elevation time is the sunrise or sunset time. The solar azimuth at this time is interpolated: For sunrise: γLET=γprev+(tLETtprev)(tcurrenttprev)(γcurrentγprev)\gamma_{LET} = \gamma_{prev} + \frac{(t_{LET} - t_{prev})}{(t_{current} - t_{prev})} (\gamma_{current} - \gamma_{prev}) For sunset: γLET=γnext+(tLETtnext)(tcurrenttnext)(γcurrentγnext)\gamma_{LET} = \gamma_{next} + \frac{(t_{LET} - t_{next})}{(t_{current} - t_{next})} (\gamma_{current} - \gamma_{next}) where tLETt_{LET} is the lowest elevation time (sunrise or sunset). Traverse Time Calculation: Starting from the lowest elevation time, iterate forward (sunrise) or backward (sunset) in 1-minute increments:
  1. Interpolate solar elevation and azimuth at each minute
  2. Interpolate horizon elevation at that solar azimuth
  3. Stop when solar elevation exceeds horizon elevation
The traverse time ttraverset_{traverse} is the time when the sun clears the horizon obstruction. Shading Duration: For sunrise: Δt=ttraversetsunrise\Delta t = t_{traverse} - t_{sunrise} For sunset: Δt=tsunsetttraverse\Delta t = t_{sunset} - t_{traverse} Horizon Shading Factor: For sunrise: Uhorizon=1ΔtΔtintervalU_{horizon} = 1 - \frac{\Delta t}{\Delta t_{interval}} where Δtinterval=tendtsunrise\Delta t_{interval} = t_{end} - t_{sunrise} is the time from sunrise to the end of the current interval. For sunset: Uhorizon=1ΔtΔtintervalU_{horizon} = 1 - \frac{\Delta t}{\Delta t_{interval}} where Δtinterval=tsunsettstart\Delta t_{interval} = t_{sunset} - t_{start} is the time from the start of the interval to sunset.

Application to Beam Irradiance

The horizon shading factor is applied to beam irradiance after near-field (row-to-row) shading: Ibeam,total=Ibeam,POA×Ushd,B×UhorizonI_{beam,total} = I_{beam,POA} \times U_{shd,B} \times U_{horizon} where:
  • Ibeam,POAI_{beam,POA} is the plane-of-array beam irradiance
  • Ushd,BU_{shd,B} is the near-field shading factor
  • UhorizonU_{horizon} is the horizon shading factor
Horizon shading only affects beam (direct) irradiance. Diffuse and ground-reflected irradiance components are not subject to horizon shading in this calculation (though the horizon profile does reduce the visible sky dome, which is accounted for in diffuse shading calculations).

Edge Cases

High Peak Elevation: If the highest peak elevation in the horizon profile is less than or equal to the lowest solar elevation during the day, no horizon shading occurs for that day. Continuous Blocking: If the sun remains below the horizon obstruction for multiple consecutive timesteps, Uhorizon=0U_{horizon} = 0 for all affected timesteps. No Sunrise/Sunset in Interval: If the timestep does not include sunrise or sunset, the algorithm interpolates solar elevation at the lowest elevation time within or near the interval and performs the same traverse time calculation.

References

  • Marion, B. (2021). Numerical verification of pvlib single-axis tracking shading algorithms. IEEE Journal of Photovoltaics, 11(1), 184–190.
  • Stein, J. S., Hansen, C. W., & Reno, M. J. (2012). The Sandia Array Performance Model (SAPM). SAND2012-2389, Sandia National Laboratories.