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..20333b032 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -1449,6 +1449,62 @@ def test_hot_water_only_heat_network_whc_950_applies_table12c_dlf() -> None: assert abs(hw_network / baseline - 1.41) <= 0.02 +def test_water_only_heat_network_dhw_prices_heat_without_plant_efficiency() -> None: + # Arrange — SAP 10.2 §4.3 (PDF p.24): "The efficiency for water heating + # is incorporated in the price of heat from a heat network in Table 12." + # The dwelling buys DELIVERED heat at the Table 12 fuel-51 rate, so the + # RdSAP Table 4a plant efficiency (950 → 0.80) must NOT also divide on + # the dwelling side — worksheet (310) is "(64) × (305a) × (306)", with + # no efficiency term. C4 (p.53) scopes plant efficiency explicitly: "For + # heat networks not listed in the PCDB, FOR THE CALCULATION OF CO2 + # EMISSIONS AND PRIMARY ENERGY, the efficiency to be used is that of the + # heat generator" — i.e. never for delivered energy. + # + # (305a) is the Table 4c(3) "DHW-only system, flat rate charging" row = + # 1.05 (p.169); RdSAP 10 (spec p.59) defaults a non-PCDB water-only + # network to flat-rate charging. (306) is the age-E Table 12c DLF = 1.41. + # + # So HW fuel = q_useful × 1.41 × 1.05, i.e. water_eff = 1/(DLF × 1.05). + # Asserted as fuel ÷ q_useful (the §4 output at 100% efficiency) to pin + # the efficiency absolutely, mirroring the WHC-901 heat-network test + # above. The main is an ordinary gas boiler — NOT a heat network — since + # §4.3 keys on the DHW source ("Where hot water is provided by a heat + # network"), not on the space main. + part = make_building_part(construction_age_band="E") + gas_main = MainHeatingDetail( + has_fghrs=False, + main_fuel_type=26, + heat_emitter_type=1, + emitter_temperature=1, + main_heating_control=2106, + main_heating_category=2, + ) + hw_network_epc = make_minimal_sap10_epc( + total_floor_area_m2=_TYPICAL_TFA_M2, + habitable_rooms_count=4, + country_code="ENG", + sap_building_parts=[part], + sap_heating=make_sap_heating( + main_heating_details=[gas_main], + water_heating_code=950, # hot-water-only heat network (boilers) + ), + ) + + # Act + hw_fuel: float = cert_to_inputs(hw_network_epc).hot_water_kwh_per_yr + wh_result, _ = _water_heating_worksheet_and_gains( + epc=hw_network_epc, + water_efficiency_pct=100.0, + is_instantaneous=False, + primary_age="E", + pcdb_record=None, + ) + + # Assert — delivered HW fuel = q_useful × (305a) × (306); no 1/0.80. + assert wh_result is not None + assert abs(hw_fuel / wh_result.output_kwh_per_yr - 1.41 * 1.05) <= 1e-6 + + def test_gas_boiler_main_efficiency_unchanged_by_dlf_override() -> None: # Arrange — regression check: the DLF override only fires for heat- # network main heating. A standard gas boiler (cat=2, code=102) must