mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Audit: pin u_floor §5.12 formula cascade for cert 0240 cohort geometry
Floor U is formula-driven (BS EN ISO 13370 + RdSAP10 §5.12), not a table lookup, so cohort pins assert per-geometry values derived by hand from the spec formula. Cert 0240's main + extension building parts cover both the dt < B and dt > B branches of the solid-floor cascade with age J → Table 19 default 75 mm insulation. Hand-derivation matches calculator output to 2 d.p.; the formula cascade is correct on this cohort case. Suspended-floor + Table 19 footnote (2) overrides remain unpinned until cohort coverage demands them. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
acc6331dc3
commit
8ac548ca2a
1 changed files with 54 additions and 0 deletions
|
|
@ -1283,3 +1283,57 @@ def test_u_roof_matches_table16_for_every_cohort_description_thickness_pair(
|
|||
|
||||
# Assert
|
||||
assert abs(u - expected_u) < 1e-4
|
||||
|
||||
|
||||
# ----- §5.12 formula cascade cohort pins (Floors) -----
|
||||
#
|
||||
# u_floor is formula-driven (BS EN ISO 13370 + RdSAP10 §5.12) rather
|
||||
# than table-lookup, so each pin asserts a per-geometry value derived
|
||||
# by hand from the spec formula. Two cases from cert 0240 (main +
|
||||
# extension) cover the dt < B and dt > B branches of the solid-floor
|
||||
# branch; suspended-floor + Table 19 footnote (2) overrides land in
|
||||
# follow-on slices when cohort coverage demands them.
|
||||
#
|
||||
# Hand-derivation for the first row (cert 0240 bp0):
|
||||
# age J → Table 19 default insulation = 75 mm
|
||||
# w = 0.3 m (default), g = 1.5, Rsi+Rse = 0.21, Rf = 0.001×75/0.035 = 2.143
|
||||
# dt = 0.3 + 1.5×(0.21 + 2.143) = 3.829
|
||||
# B = 2×97.72/36.45 = 5.362 → dt < B branch
|
||||
# U = 2g·ln(πB/dt + 1)/(πB + dt) = 0.2447 → rounds to 0.24
|
||||
_FLOOR_FORMULA_COHORT_PINS: tuple[tuple[str, str, Optional[int], float, float, Optional[int], float], ...] = (
|
||||
# (description, age, construction, area_m2, perimeter_m, wall_thickness_mm, expected_u)
|
||||
("Solid, insulated (assumed)", "J", 1, 97.72, 36.45, None, 0.24), # cert 0240 bp0 (dt < B)
|
||||
("Solid, insulated (assumed)", "J", 1, 20.61, 13.45, None, 0.29), # cert 0240 bp1 (dt > B)
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"description, age_band, construction, area_m2, perimeter_m, wall_thickness_mm, expected_u",
|
||||
_FLOOR_FORMULA_COHORT_PINS,
|
||||
)
|
||||
def test_u_floor_matches_section_5_12_formula_for_cohort_geometry(
|
||||
description: str,
|
||||
age_band: str,
|
||||
construction: Optional[int],
|
||||
area_m2: float,
|
||||
perimeter_m: float,
|
||||
wall_thickness_mm: Optional[int],
|
||||
expected_u: float,
|
||||
) -> None:
|
||||
# Arrange — inputs replicate what `heat_transmission_from_cert` feeds
|
||||
# `u_floor` for the corresponding building part in the cohort.
|
||||
|
||||
# Act
|
||||
u = u_floor(
|
||||
country=Country.ENG,
|
||||
age_band=age_band,
|
||||
construction=construction,
|
||||
insulation_thickness_mm=None,
|
||||
area_m2=area_m2,
|
||||
perimeter_m=perimeter_m,
|
||||
wall_thickness_mm=wall_thickness_mm,
|
||||
description=description,
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert abs(u - expected_u) < 1e-4
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue