From 64207ea225245da5ee70003a4ff730b6529e30c2 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 14 Jul 2026 23:30:51 +0000 Subject: [PATCH] =?UTF-8?q?Accrue=20Table=203=20primary-circuit=20loss=20f?= =?UTF-8?q?or=20water-only=20heat-network=20cylinders=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../rdsap/test_cert_to_inputs.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index f0a2e14ac..96227afaf 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -478,6 +478,57 @@ def test_heat_network_primary_loss_uses_p1_h3_all_months_per_table_3() -> None: assert abs(sum(wh_result.primary_loss_monthly_kwh) - expected_primary_kwh) <= 1e-6 +def test_water_only_heat_network_cylinder_accrues_primary_loss() -> None: + # Arrange — DHW from a water-ONLY community scheme (WHC 950) with a + # lodged 210 L cylinder, on a heat-network space main (Table 4a 301, + # cat 6) — fixture 507644414148's shape. 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)" — the network + # feeds the dwelling-side cylinder via primary pipework whichever WHC + # lodges it, so the loss applies to 950/951/952 exactly as to + # 901/902/914 (pre-fix these fell through to zero). Table 3 heat- + # network row: p = 1.0 and h = 3 for all months. + main = MainHeatingDetail( + has_fghrs=False, + main_fuel_type=51, # Table 12 community heat (from boilers) + heat_emitter_type=1, + emitter_temperature=1, + main_heating_control=2306, + main_heating_category=6, + sap_main_heating_code=301, + ) + part = make_building_part(construction_age_band="F") + epc = make_minimal_sap10_epc( + total_floor_area_m2=_TYPICAL_TFA_M2, + habitable_rooms_count=4, + country_code="ENG", + has_hot_water_cylinder=True, + sap_building_parts=[part], + sap_heating=make_sap_heating( + main_heating_details=[main], + water_heating_code=950, + water_heating_fuel=51, + cylinder_size=4, # Large (>170 litres) → 210 L + cylinder_insulation_type=1, + cylinder_insulation_thickness_mm=50, + ), + ) + + # Act + wh_result, _ = _water_heating_worksheet_and_gains( + epc=epc, + water_efficiency_pct=100.0, + is_instantaneous=False, + primary_age="F", + pcdb_record=None, + ) + + # Assert — p=1.0, h=3 all months → 365 × 14 × (0.0091×3 + 0.0263). + assert wh_result is not None + expected_primary_kwh = 365.0 * 14.0 * (0.0091 * 3.0 + 0.0263) + assert abs(sum(wh_result.primary_loss_monthly_kwh) - expected_primary_kwh) <= 1e-6 + + def test_dual_main_system_2_costed_at_its_own_fuel_price() -> None: # Arrange — SAP 10.2 §10a: main heating system 2's fuel cost (worksheet # line (213)) is billed at ITS OWN Table 32 fuel price, separately from