From 269dd991b516f82c269608b6328469b5c1416980 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 20 May 2026 13:28:23 +0000 Subject: [PATCH] Elmhurst 000490 fixture: tag Ext1 floor as exposed timber MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the worksheet docstring on this fixture, Extension 1 hangs off the main from the first storey upward — its lowest dimension is an exposed timber floor (over outside air), not a ground floor on soil. Set is_exposed_floor=True so heat_transmission_from_cert routes Ext1 through the Table 20 lookup (U=1.20 W/m²K at age B unknown insulation) instead of BS EN ISO 13370. Combined with the Table 19 fn 1 default that routes Main to the suspended-timber branch (U≈0.71), §3 LINE_28A floor sum lands at ≈32.4 W/K — matching the worksheet's 0.71×14.85 + 1.20×18.18. A new floor-sum regression test pins the combined behaviour; the existing LINE_31/36 parametrised test still passes (the exposed-floor route contributes its area to LINE_31 the same way the ground-floor route did). Co-Authored-By: Claude Opus 4.7 --- .../tests/_elmhurst_worksheet_000490.py | 4 +++- .../worksheet/tests/test_heat_transmission.py | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py b/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py index 966958a0..72c9d7f2 100644 --- a/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py +++ b/packages/domain/src/domain/sap/worksheet/tests/_elmhurst_worksheet_000490.py @@ -68,12 +68,14 @@ def build_epc() -> EpcPropertyData: sap_floor_dimensions=[ # Cert records the extension at the dwelling's 1st/2nd-storey # level (no ground floor). Within our domain the lowest floor - # of the part is still floor=0. + # of the part is still floor=0, but it's an *exposed timber* + # floor (over passageway / outside air below) — Table 20 route. SapFloorDimension( room_height_m=2.88, # 1st-of-ext internal total_floor_area_m2=18.18, party_wall_length_m=3.53, heat_loss_perimeter_m=8.68, floor=0, + is_exposed_floor=True, ), SapFloorDimension( room_height_m=3.21, # = 2.96 internal + 0.25 floor structure diff --git a/packages/domain/src/domain/sap/worksheet/tests/test_heat_transmission.py b/packages/domain/src/domain/sap/worksheet/tests/test_heat_transmission.py index 3badb7d7..a1eafd61 100644 --- a/packages/domain/src/domain/sap/worksheet/tests/test_heat_transmission.py +++ b/packages/domain/src/domain/sap/worksheet/tests/test_heat_transmission.py @@ -1179,6 +1179,26 @@ def test_section_3_non_rr_line_31_and_36_match_elmhurst_worksheet( ) +def test_section_3_floor_w_per_k_for_000490_uses_suspended_and_exposed_routes() -> None: + """000490 exercises both new floor routes: Main is a suspended-timber + ground floor (Table 19 fn 1 default for age B → U=0.71) and Extension + 1 is an exposed-timber upper floor (Table 20 row A–G unknown → U=1.20). + Together the §3 LINE_28A floor sum is 0.71 × 14.85 + 1.20 × 18.18 ≈ + 32.4 W/K with the cascade keeping full precision. The Elmhurst + worksheet displays U-values to 2 d.p., so allow a small tolerance to + absorb whichever rounding policy lands first.""" + # Arrange + epc = _w000490.build_epc() + + # Act + result = heat_transmission_from_cert( + epc, window_total_area_m2=0.0, window_avg_u_value=None, door_count=0, + ) + + # Assert + assert result.floor_w_per_k == pytest.approx(32.4, abs=0.1) + + @pytest.mark.parametrize("fixture", _ELMHURST_FIXTURES, ids=_elmhurst_fixture_id) def test_section_3_partial_match_against_elmhurst_worksheet(fixture: ModuleType) -> None: """Real Elmhurst SAP10.2 worksheets — partial §3 conformance.