Accrue Table 3 primary-circuit loss for water-only heat-network cylinders 🟩

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 23:36:20 +00:00
parent 64207ea225
commit d3c0b9e499

View file

@ -6585,6 +6585,16 @@ def _primary_loss_applies(
# kWh/yr — zero before this branch.
if water_heating_code in _WATER_HEATING_BOILER_CIRCULATOR_CODES:
return True
# 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)." A water-ONLY community scheme (WHC 950/951/952) feeds the
# dwelling-side cylinder via primary pipework from the network
# connection whatever the space main is, so the loss applies exactly
# as for heat-network mains with WHC 901/902/914 (below). Checked off
# `water_heating_code` before the main-keyed branches so a non-network
# space main (HP, direct-acting electric) can't zero it out.
if water_heating_code in _WATER_HEAT_NETWORK_ONLY_CODES:
return True
# SAP 10.2 Table 3 (PDF p.160) zero-loss list names "Direct-acting
# electric boiler" verbatim. RdSAP 10 §12 (p.62) classifies SAP code
# 191 as the direct-acting electric boiler: its cylinder is immersion-
@ -7089,13 +7099,20 @@ def _primary_loss_override(
water_heating_code=epc.sap_heating.water_heating_code,
):
return None
# Heat-network DHW: either the space main is a network (WHC 901/902/914
# inherit its DHW) or the DHW is its own water-only community scheme
# (WHC 950/951/952) — the Table 3 heat-network row keys on the DHW
# source, not on the space main.
heat_network_dhw = is_heat_network_main(main) or (
epc.sap_heating.water_heating_code in _WATER_HEAT_NETWORK_ONLY_CODES
)
# SAP 10.2 §4 "Heat networks" (PDF p.17 line 1482) pins community-
# heating primary pipework to "insulated" (p=1.0), overriding the
# RdSAP §3 age-band default which would otherwise return 0 for
# pre-2007 stock. See `_HEAT_NETWORK_PIPEWORK_INSULATION_FRACTION`.
pipework_p = (
_HEAT_NETWORK_PIPEWORK_INSULATION_FRACTION
if is_heat_network_main(main)
if heat_network_dhw
else _pipework_insulation_fraction_table_3(primary_age)
)
base = primary_loss_monthly_kwh(
@ -7107,7 +7124,7 @@ def _primary_loss_override(
# row applies regardless of the thermostat / separate-timing
# lodgement (and so is robust to the community-fuel-as-electric
# collision that would otherwise route DHW to the h=5 row).
heat_network=is_heat_network_main(main),
heat_network=heat_network_dhw,
)
# SAP 10.2 §12.4.4 (PDF p.36-37): for back-boiler combos summer DHW
# comes from an electric immersion, not from the boiler — the boiler