Why the loss model deserves its own post


An irradiance model and a temperature model only get you to potential energy. What actually determines whether a yield number is trustworthy is the loss cascade sitting between potential and delivered energy — and that's usually the part vendors are least transparent about. This post documents exactly how our engine applies, combines, and — in a few specific cases — dynamically corrects every loss between the sun and the grid connection point.

The four-stage cascade:

GlobHor (horizontal irradiation)

   ↓  Perez (1990) transposition

GlobInc (in-plane / transposed irradiation)

   ↓  Stage 1 — irradiance/optical losses

GlobEff (effective irradiation, corrected for IAM, shading, spectral)

   ↓  Stage 2 — array/DC losses

E_Array (array nominal DC energy)

   ↓  Stage 3 — inverter/AC losses

E_Grid (before grid delivery chain)

   ↓  Stage 4 — grid delivery chain

E_Grid (energy actually injected into the grid)


Each anchor is a real, independently reportable energy value (kWh/m²/yr or MWh/yr) — not an internal-only intermediate — so a researcher rebuilding the calculation can check their own GlobEff or E_Array against ours before trusting the final number.

Stage 1 — Irradiance / optical losses

 Important distinction for reproducibility: IAM, spectral, electrical shading, and bifacial gain are physically computed at every time step from the actual sun position, irradiance components, and array geometry — the "default" percentages above are only what shows up in the annual loss-diagram summary for a typical case, not fixed multipliers applied blindly. Far-horizon shading and soiling, by contrast, are flat calibrated percentages in the current model. 

IAM Loss (Incidence Angle): Martin-Ruiz model, aᵣ = 0.08 (AR-coated) or 0.16 (uncoated), applied separately to beam vs. an effective constant (~0.93) for diffuse/ground.

Bifacial Gain (rear irrad): Infinite-sheds rear-irradiance model (Mikofski et al. 2019), computed per time step from GCR, row geometry, and albedo — only active for bifacial modules. 

Stage 2 — Array / DC losses

Array Thermal Loss (Uc+Uv): Physically computed per time step from the Faiman model — not a flat percentage.

Module Aging/Degradation: Applied via a separate degradation factor multiplier, driven by the multi-year lifetime module — not part of this flat-loss table, specifically to avoid double-counting when previewing later project years. 

Stage 3 — Inverter / AC losses

Clipping: two different calculation paths depending on engine and data quality

This is the most methodologically nuanced loss line in the model, so it's worth documenting in full:

In the hourly/sub-hourly engine (default, physical): at every time step, AC power is a genuine clamp. This is a real physical limit against the plant's total nameplate AC capacity, evaluated at sub-hourly resolution when sub-hourly weather is supplied.

Reconciliation floor for synthetic/non-measured weather: hourly or sub-hourly profiles built from smoothed or synthetic weather (i.e., not an explicitly measured NASA POWER hourly or PVGIS TMY source) systematically under-represent clipping, because real short-duration irradiance peaks get smoothed away. To correct for this, the engine additionally computes an empirical clipping-loss floor.

How it calculating hourly irradiance?

Step 1 — Split each month into days, each day into 24 hours  weather hourly engine. For every day of every month, Builds a "clear-sky shape" for that day, Normalizes that shape so it sums to 1 across the 24 hours, then multiplies each hour's fraction by the month's total daily GHI energy (kWh/m²/day → Wh/m²). So each hour gets a physically realistic share of that day's sunlight — mid-day hours get much more than early-morning/late-evening hours, and the daily total exactly matches your imported monthly average.

Step 2 — Split GHI into diffuse (DHI) and beam

If your imported monthly data already has a DHI figure, it uses that month's real DHI/GHI ratio, applied evenly across all daylight hours that day. If not, it estimates each day's own clearness index to get a diffuse fraction — a clear day gets a low diffuse fraction, an overcast day gets a high one, rather than one flat 30% assumption for the whole month. DNI (beam) is then back-calculated for every hour. 

Step 3 — Temperature & wind: Temperature follows a sine-wave diurnal cycle around that month's mean (±5 °C swing, peaking around 15:00 to reflect thermal lag behind solar noon). Wind speed is just held flat at the monthly average (no diurnal model for that). 

Step 4 — Optional 15-minute sub-hourly expansion: If you choose Sub-hourly in simulation, it linearly interpolates GHI/DHI/temp/wind between each pair of hourly points and recomputes DNI at the true sun position for each 15-min sub-step — so sunrise/sunset and shading-edge transitions aren't smeared across a whole hour. Choose Hourly or Sub-hourly, and click Run Simulation — it'll use the real imported dataset, not the synthetic one. Green confirmation if it matches, naming the active resource and coordinates.

A researcher reproducing our clipping number needs to know which of these three paths applies to their comparison case: physical-only (measured hourly/sub-hourly weather), physical-plus-empirical-floor (synthetic hourly weather), or empirical-only (monthly engine).

Uncertainty is tracked separately from the loss table itself


The loss table above describes the best-estimate energy cascade. Uncertainty around that estimate is tracked as three independent components, not folded into the loss percentages themselves:

  • Resource/data uncertainty: 2.5% (measured/ground TMY sources) or 5.0% (satellite/synthetic climatology) — per IEC 61724-3 convention.
  • Model uncertainty: 1.5% — transposition + PV conversion model error, reflecting that both engines use pvlib-cross-checked Perez transposition, De Soto diode model, and infinite-sheds bifacial geometry.
  • Component uncertainty: 2% — module power tolerance and soiling/degradation estimation error.

Keeping these separate (rather than one blended "±X%" figure) lets a researcher see which uncertainty term to challenge if their own field data disagrees with a specific part of our prediction.

Reproducing our loss cascade

To rebuild our energy cascade from GlobInc down to E_Grid, a researcher needs, in order:

  1. The physically-computed terms first (per time step, not as flat percentages): IAM via Martin-Ruiz, spectral via First Solar/Lee-Panchula, thermal via Faiman Uc+Uv feeding the De Soto diode model, electrical shading via the bypass-diode substring model, bifacial gain via infinite-sheds, inverter efficiency via EN 50530 curve interpolation, and clipping via the physical AC clamp (plus the empirical floor if using synthetic weather).
  2. The flat calibrated percentages — far-horizon shading, soiling, LID, mismatch, DC/AC ohmic, auxiliary/grid-unavailability — combined multiplicatively, not additively, using the retention-factor formula above.
  3. The grid delivery chain, if configured — transformer no-load + copper-loss model, flat cable loss, and hard export-limit clipping, applied in that order after inverter-side clipping.

Every default value in this post is exactly what our engine falls back to when a project hasn't overridden it with a site-specific measurement — nothing here is simplified for publication. Where our numbers and a researcher's independent reproduction disagree, the discrepancy should be traceable to one specific stage in this cascade, not buried in an opaque overall percentage — and we'd genuinely like to hear about it when that happens.

We'll keep this page updated as the model set evolves, and welcome outside researchers who want to run their own comparison against measured plant data — that's the kind of scrutiny that makes a simulation tool worth trusting.