From 443a7697ff63997b316d04558decaee03bb9f4c5 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 19 May 2026 10:20:27 +0000 Subject: [PATCH] P5.3: SapResult.intermediate exposes ventilation group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit infiltration_ach (the cert-derived input) and infiltration_w_per_k (the derived HLC_V = ACH × volume × 0.33 from SAP 10.2 §4.1) populated on `intermediate`. Diagnostic surface for the §4 / Table 4g sweep. 133 SAP tests pass. --- packages/domain/src/domain/sap/calculator.py | 2 ++ .../src/domain/sap/tests/test_calculator.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/domain/src/domain/sap/calculator.py b/packages/domain/src/domain/sap/calculator.py index 6e45ef53..88aaa360 100644 --- a/packages/domain/src/domain/sap/calculator.py +++ b/packages/domain/src/domain/sap/calculator.py @@ -344,6 +344,8 @@ def calculate_sap_from_inputs(inputs: CalculatorInputs) -> SapResult: "windows_w_per_k": ht.windows_w_per_k, "doors_w_per_k": ht.doors_w_per_k, "thermal_bridging_w_per_k": ht.thermal_bridging_w_per_k, + "infiltration_ach": inputs.infiltration_ach, + "infiltration_w_per_k": hlc_v, } return SapResult( diff --git a/packages/domain/src/domain/sap/tests/test_calculator.py b/packages/domain/src/domain/sap/tests/test_calculator.py index ae892772..a6dff041 100644 --- a/packages/domain/src/domain/sap/tests/test_calculator.py +++ b/packages/domain/src/domain/sap/tests/test_calculator.py @@ -159,6 +159,24 @@ def test_calculate_exposes_heat_transmission_intermediates() -> None: assert result.intermediate["thermal_bridging_w_per_k"] == ht.thermal_bridging_w_per_k +def test_calculate_exposes_ventilation_intermediates() -> None: + # Arrange — P5 trace mode: infiltration ach (the cert-derived input) and + # the derived ventilation heat-loss W/K must surface so §4 / Table 4g + # sweep slices can diff per-cert against the spec formula + # HLC_V = ACH × volume × 0.33 (SAP 10.2 §4.1). + inputs = _baseline_inputs() + + # Act + result = calculate_sap_from_inputs(inputs) + + # Assert + assert result.intermediate["infiltration_ach"] == inputs.infiltration_ach + expected_hlc_v = inputs.infiltration_ach * inputs.dimensions.volume_m3 * 0.33 + assert result.intermediate["infiltration_w_per_k"] == pytest.approx( + expected_hlc_v, rel=1e-9 + ) + + def test_higher_main_heating_efficiency_reduces_fuel_use() -> None: # Arrange — Direction check: doubling the boiler efficiency must halve # the main-heating fuel kWh, holding everything else constant.