mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
SAP 10.2 §4 "Heat networks" (PDF p.17 line 1482):
"Primary circuit loss for insulated pipework and cylinderstat
should be included (see Table 3)."
SAP 10.2 Table 2b note b (PDF p.159) verbatim:
"Multiply Temperature Factor by 0.9 if there is separate time
control of domestic hot water (boiler systems, warm air systems
and heat pump systems)."
The Table 2b note b ×0.9 multiplier is restricted to "boiler / warm
air / heat pump systems" — community heating is omitted from that
verbatim list. Pre-slice the cascade applied the ×0.9 reduction
unconditionally when DHW was separately timed, AND omitted the Table
3 primary-loss path for heat-network mains entirely. Combined the
two gaps under-counted (62)m HW total demand by ~320 kWh/yr for
heating-systems corpus 001431 community heating 1 (8164 + 0 vs
448.74 + 273.90 spec losses).
Three changes:
1. New `_HEAT_NETWORK_PIPEWORK_INSULATION_FRACTION = 1.0` constant.
`_primary_loss_override` selects this for heat-network mains
instead of the RdSAP §3 age-band default, per the spec's literal
"insulated pipework" + back-solve from worksheet (59) Jan = 23.26
= 31 × 14 × (0.0091×3 + 0.0263).
2. Extended `_primary_loss_applies` with a new branch: heat-network
main + WHC ∈ {901, 902, 914} + cylinder present → primary loss
applies.
3. New `_table_2b_note_b_multiplier_applies(epc, main)` predicate
that gates the ×0.9 storage-loss reduction on the spec's verbatim
system-type list, returning False for heat-network mains. The
primary-loss `_separately_timed_dhw` continues to return True for
community heating (Table 3's "separately timed" row is system-
type-agnostic and gives h=3 all year).
Closures (heating-systems corpus 001431):
CH1 HW kWh 3391.90 → 3854.12 (= ws 3854.1175, abs Δ < 1e-3)
CH1 HW cost £143.82 → £163.41 (= ws £163.41, EXACT)
CH1 (65)m heat gains 793.51 → 1221.62 (= ws 1221.62, EXACT)
CH2/CH3/CH4/CH6 same shape — HW path closes against ws (310).
§4 fix is spec-correct on all 5 CH variants. The closure surfaces a
separate §7 MIT (92)m over-count of +0.46 K (cascade Jan = 17.22 vs
ws 16.76) that the pre-slice (65)m gain under-count was masking. Per
[[feedback-software-no-special-handling]] apply the spec-correct
fix uniformly; new pinned residuals reflect the exposed MIT gap.
New residuals (vs pre-slice):
CH1 ΔSAP -0.5273 → -1.0572 ΔPE -9.15 → +408.67
CH2 ΔSAP -0.0076 → -0.4187 ΔPE +1506 → +1779
CH3 ΔSAP -0.5273 → -1.0572 ΔPE -387.03 → -239.03
CH4 ΔSAP -0.0076 → -0.4187 ΔPE +494.61 → +767.13
CH6 ΔSAP -8.0295 → -8.4406 ΔPE +7864.60 → +8137.11
927 pass + 0 fail (+1 new test). No regressions on the other 36
corpus variants — the gate is narrow on `_is_heat_network_main`.
Pyright net-zero (43 → 43) on cert_to_inputs.py + tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| handler | ||
| tests | ||
| __init__.py | ||
| db_writer.py | ||
| elmhurst_extractor.py | ||
| extractor.py | ||
| local_runner.py | ||
| parser.py | ||
| pdf.py | ||