P5.2: SapResult.intermediate exposes heat transmission group

Seven fabric W/K components from `inputs.heat_transmission` populated on
`intermediate`: walls, roof, floor, party_walls, windows, doors,
thermal_bridging. Handover §11 / §5 (sap-spec sweep).

132 SAP tests pass.
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-19 10:19:21 +00:00
parent aa07265606
commit d5b1d0d483
2 changed files with 28 additions and 0 deletions

View file

@ -332,10 +332,18 @@ def calculate_sap_from_inputs(inputs: CalculatorInputs) -> SapResult:
)
primary_energy_per_m2 = primary_energy_kwh / tfa if tfa > 0 else 0.0
ht = inputs.heat_transmission
intermediate: dict[str, float] = {
"tfa_m2": inputs.dimensions.total_floor_area_m2,
"volume_m3": inputs.dimensions.volume_m3,
"storey_count": float(inputs.dimensions.storey_count),
"walls_w_per_k": ht.walls_w_per_k,
"roof_w_per_k": ht.roof_w_per_k,
"floor_w_per_k": ht.floor_w_per_k,
"party_walls_w_per_k": ht.party_walls_w_per_k,
"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,
}
return SapResult(

View file

@ -139,6 +139,26 @@ def test_calculate_exposes_dimensions_intermediates() -> None:
assert result.intermediate["storey_count"] == float(inputs.dimensions.storey_count)
def test_calculate_exposes_heat_transmission_intermediates() -> None:
# Arrange — P5 trace mode: the 7 fabric W/K components must surface on
# `intermediate` so section-§5 sweep slices can diff per-component
# against BRE worked examples.
inputs = _baseline_inputs()
# Act
result = calculate_sap_from_inputs(inputs)
# Assert
ht = inputs.heat_transmission
assert result.intermediate["walls_w_per_k"] == ht.walls_w_per_k
assert result.intermediate["roof_w_per_k"] == ht.roof_w_per_k
assert result.intermediate["floor_w_per_k"] == ht.floor_w_per_k
assert result.intermediate["party_walls_w_per_k"] == ht.party_walls_w_per_k
assert result.intermediate["windows_w_per_k"] == ht.windows_w_per_k
assert result.intermediate["doors_w_per_k"] == ht.doors_w_per_k
assert result.intermediate["thermal_bridging_w_per_k"] == ht.thermal_bridging_w_per_k
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.