Model/domain
Khalim Conn-Kowlessar 081bb8fd7e Slice S0380.28: SAP 10.2 Appendix N footnote 43 reciprocal η interpolation — closes the +0.03..+0.06 ASHP precision-floor cluster
Per SAP 10.2 Appendix N, PDF p.101 footnote 43 (line 7053):

  "For the efficiency values, the interpolated efficiency is the
  reciprocal of linear interpolation between the reciprocals of the
  efficiencies."

i.e. 1/η_interp = (1 − t)·1/η_low + t·1/η_high, the weighted harmonic
mean at t = (PSR − PSR_low) / (PSR_high − PSR_low). Cascade was using
**linear** interpolation directly on η — a +0.15..+0.25% over-estimate
in the typical PSR range (1.2..1.5) for ASHPs in the cohort.

Cohort fixture: cert 3336-2825-9400-0512-8292 (Mitsubishi PUZ-WM50VHA,
PCDB 104568). MIT/η-zone cascade matches worksheet EXACTLY (every line
86..92, every month), but η_main_heating cascade 225.443 vs worksheet
224.923 → main_heating_fuel +5.24 kWh/yr too high → ECF 1.5474 vs ws
1.5503 → SAP +0.04 vs worksheet 78.3739. Back-solving the worksheet's
η_main implies η_space_1 = 224.923 / 0.95 ≈ 236.76.

Closed form at PSR=1.40151, bracketing PCDB rows PSR 1.2
(η_space_1=253.9) and PSR 1.5 (η_space_1=229.2):
  Linear (pre-slice):     253.9 + (229.2 − 253.9) × 0.6717  = 237.31  ✗
  Reciprocal (footnote 43): 1 / ((1 − 0.6717)/253.9 + 0.6717/229.2)
                          = 1 / 0.004224                    = 236.74  ✓

The harmonic mean is curvature-aware: linear interpolation under-
penalises efficiency drops at higher PSR (η typically falls off as
PSR increases past the system's design point) by averaging on η
rather than 1/η. SAP 10.2 footnote 43 is explicit about which side
of the reciprocal the interpolation sits.

Outcome:

Cohort-2 Summary path (38 certs):
  exact (<1e-4): 23 → **33** (+10)
  ≤±0.07:        15 → **5**  (-10: HP certs close to exact)
  ±0.07..0.5:     0 → 0
  ±0.5..1:        0 → 0
  ±1+:            0 → 0
  RAISES:         0 → 0

Cohort-2 HP cluster post-slice:
  0100  +0.00003   ←  was +0.00283
  0320  -0.00001   ←  was +0.01801
  0330  -0.00004   ←  was +0.01772
  2336  +0.00003   ←  was +0.01778
  3336  +0.00001   ←  was +0.04005  (worst residual closes exact)
  4536  -0.00002   ←  was +0.01312
  9036  -0.00003   ←  was +0.02159
  9796  +0.00000   ←  was +0.00174  (post-S0380.27)
  2536  +0.00072   ←  was +0.00163
  2800  +0.00068   ←  was +0.00436
  4800  +0.00068   ←  was +0.02939
  9370  +0.00002   ←  was +0.00174
  9421  +0.00001   ←  was +0.00117

Cohort-1 ASHP cohort (7-cert cohort + new chain test certs):
  cert 0380:  +1e-6   ←  was +0.034 (Mitsubishi PUZ-WM50VHA, the
                                     canonical first-HP cohort cert)
  cert 3800:  -2e-5   ←  was +0.021
  cert 9418:  -3e-7   ←  was +0.00004
  cert 9285:  -3e-5   ←  was +0.021
  cert 2636:  -0.015  ←  was +0.003 (cantilever fixture; remaining
                                     residual is non-η in nature)

5 of 7 cohort-1 ASHP certs now hit delta < 1e-4 vs worksheet — the
+0.04 spec-precision-floor cluster diagnosed in
HANDOVER_CERT_0380_MIT_CASCADE.md is the linear-vs-reciprocal η
interpolation bug, not a spec-floor at all. The handover doc's "no
public spec or BRE data field would distinguish these" claim was
incorrect — SAP 10.2 footnote 43 is the resolution.

API path (golden fixtures): 6 ASHP cohort residuals updated to reflect
the cascade closure:
  cert 0380 PE: -14.7865 → -14.6848 kWh/m²; CO2: +0.2774 → +0.2780 t/yr
  cert 0350 PE: -7.9281  → -7.8741;        CO2: +0.1697 → +0.1701
  cert 2225 PE: -11.9175 → -11.8557;       CO2: +0.2617 → +0.2621
  cert 2636 PE: -9.7153  → -9.6692;        CO2: +0.2189 → +0.2193
  cert 3800 PE: -9.7551  → -9.6838;        CO2: +0.2598 → +0.2603
  cert 9285 PE: -8.1110  → -8.0466;        CO2: +0.1559 → +0.1564

All SAP integer residuals unchanged (cascade tracks the EPC integer
SAP at residual 0 across the cohort).

PSR interpolation unit test (`test_interpolate_heat_pump_efficiency_at
_cert_0380_psr_per_sap_app_n`) updated to reflect the reciprocal
formula with the SAP-10.2-footnote-43 spec citation and closed-form
asserts (η_space_1 ≈ 234.5235; η_water_3 ≈ 285.0861 at PSR=1.43).

Pyright net-zero (1 → 1 across touched files: pcdb/parser.py,
tests/test_pcdb_table_362_lookup.py, rdsap/tests/test_golden_fixtures.py).

Tests: 710 pass (was 710 pre-slice with linear interp + un-updated
pins; net-zero because the 6 golden pin updates + 1 interp test update
exactly offset the 6 + 1 failures the formula change introduced), 10
expected fails unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 11:44:11 +00:00
..
addresses get rid of comments 2026-05-20 13:21:11 +00:00
sap10_calculator Slice S0380.28: SAP 10.2 Appendix N footnote 43 reciprocal η interpolation — closes the +0.03..+0.06 ASHP precision-floor cluster 2026-05-28 11:44:11 +00:00
sap10_ml Slice S0380.26: RdSAP10 §5.8 dry-lining adjustment on alt walls — closes cert 7700 -0.44 → +5e-5 2026-05-28 10:56:11 +00:00
tasks added postcode splitter rewrite to ddd 2026-05-19 16:35:09 +00:00
postcode.py get rid of comments 2026-05-20 13:21:11 +00:00