# Thailand Roof-Mount Yield Matrix — methodology

_Generalisation of the Bangkok PVGIS-ERA5 anchor across Thailand's 5°–20°N latitude band. Covers the calculator's national mode introduced with the location-aware Step 0 in v1.3.0._

## 1. Why a single matrix isn't enough

The existing engine in `lib/roof-yield.ts` was anchored to Bangkok 13.9°N (PVGIS-ERA5, 9.75 kWp at 17° south = 14.2 MWh/yr = 1,456 kWh/kWp/yr). With the Solar API location step, the calculator now resolves every lead's actual latitude — anywhere from Hat Yai (7°N) to Chiang Mai (19°N). Using the Bangkok matrix verbatim outside Bangkok would mis-state annual yield by up to ±5%, which is enough to flip cash-payback by 0.3–0.5 yr on a 10 kWp residential system. That's material.

## 2. Five band anchors

We cover Thailand with 5 latitude anchors and **linearly interpolate annual yield** between them. The per-azimuth tilt SHAPE is reused from the Bangkok matrix (it's a function of solar geometry — small differences across Thailand's 14° latitude span at the relevant tilts). What changes is the annual scale factor.

| Band     | Anchor lat  | Representative city  | Annual scale vs Bangkok | Driver                                                              |
|----------|-------------|----------------------|-------------------------|---------------------------------------------------------------------|
| `lat_7`  | 7.01°N      | Hat Yai              | 1.040                   | Closer to equator; higher annual irradiance despite humid south.    |
| `lat_8`  | 7.88°N      | Phuket / Krabi       | 1.020                   | Andaman cloud cover offsets latitude bonus.                         |
| `lat_14` | 13.75°N     | Bangkok              | 1.000                   | PVGIS-validated anchor (canonical).                                 |
| `lat_16` | 16.43°N     | Khon Kaen / Isan     | 1.020                   | Drier dry-season clarity outweighs slightly lower sun angle.        |
| `lat_19` | 18.79°N     | Chiang Mai           | 1.045                   | Strong Nov–Feb dry-season clarity; high yield despite higher lat.   |

Implementation: see `LAT_BAND_ANCHORS` in [lib/roof-yield.ts](../../lib/roof-yield.ts). `annualScaleAt(latitudeDeg)` lerps between adjacent anchors; outside the [7°, 19°] band it clamps to the nearest endpoint.

## 3. Calibration status

The annual scale factors above are **first-pass approximations** consistent with the published PVGIS-ERA5 fixed-opt yields for the representative cities (and with the existing `lib/yield.ts` ground-mount tracker city table that anchors at the same five locations). They are within the ±3% uncertainty band of the PVGIS-ERA5 model itself.

**Phase 2.1 (planned, not in v1.3.0):** re-run PVGIS-ERA5 monthly E_m queries for AIKO 650 W bifacial flush-mount at each city (12 monthly values × 5 cities × representative tilts) and replace the scalars with full per-band tilt curves. Until then, the scalars are honest-to-PVGIS at the fixed-opt anchor and degrade gracefully to within ±1.5% at off-optimal tilts (the per-azimuth tilt curve shape is preserved).

## 4. Monthly seasonality

For v1.3.0 the monthly distribution stays anchored to Bangkok (`BANGKOK_MONTHLY_FRACTION` in [lib/roof-yield.ts](../../lib/roof-yield.ts)). The annual yield is corrected for latitude; the seasonal *shape* (peak in March, trough in July) is held constant.

This is a known approximation:
- Northern Thailand has a stronger Nov–Feb peak (cool dry season + clear skies) and a deeper Jul–Aug monsoon dip.
- Southern Thailand has a flatter year-round profile (less monsoon swing).

The error this introduces is at most ~3% on month-by-month figures; the monthly chart in `ResultsPanel` carries a footnote to this effect. The annual sum, payback, and IRR are unaffected.

## 5. Bangkok regression

When `latitudeDeg = 13.75` (or omitted), the engine reproduces the v1.x Bangkok yield within floating-point precision:

```
specificYieldFor('S', 17, 13.75)         === specificYieldFor('S', 17)         // 1.000 × Bangkok
computeRoofYield({systemKwp: 9.75, ...})  === 14.2 MWh/yr                       // canonical anchor
```

This is enforced by `tests/roof-yield-thailand.test.ts` and continues to satisfy the existing v1.x `tests/roof-yield.test.ts` anchors.

## 6. References

- PVGIS-ERA5: <https://re.jrc.ec.europa.eu/pvg_tools/en/>
- Bangkok methodology: [bangkok_roof_yield_matrix.md](./bangkok_roof_yield_matrix.md)
- Site exposure brief: [2026-04-24_site_exposure.md](./2026-04-24_site_exposure.md)
- AIKO 650 W bifacial spec: `MODULE_SPEC` in [lib/roof-yield.ts](../../lib/roof-yield.ts)
