mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
fix(uvalues): correct rafter-roof age-M default U 0.18->0.15 (RdSAP 10 Table 18 col 2, PDF p.46)
A full row-by-row audit of the roof U-value tables (16, 17, 18) and floor tables (19, 20) against the PDF found one numeric error: Table 18 column (2) "Pitched, insulation at rafters" band M is 0.15 W/m²K (footnote (1) only — no country variation; the whole M row converges to 0.15), but _ROOF_RAFTERS_BY_AGE carried 0.18. The rafters column diverges above the joist column at H-L (0.35/0.35/0.20/0.20/0.18) and rejoins it at M=0.15. Everything else in the roof/floor tables is exact: Table 16 joist + rafter thickness ladders, Table 17 room-in-roof (all 6 columns), Table 18 cols (1) joists / (3) flat / (4) room-in-roof, Table 19 (England & Wales) floor insulation defaults, and Table 20 (England) exposed-floor U-values. Known remaining gaps (NOT fixed — zero England-corpus reach, would need a new roof country-override mechanism): Scotland Table 18 footnote (2) K=0.20 (flat/ RR/thatch) and (3) joists-L=0.15; Scotland/NI Table 19 thicknesses; Scotland/ Wales Table 20 L/M overrides. Logged for a future country pass. Corpus unchanged (band-M rafter roofs essentially absent from the 1000-cert England corpus). pyright not installed in this container. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
104e3725b8
commit
b22b27c0ff
2 changed files with 30 additions and 10 deletions
|
|
@ -839,20 +839,21 @@ _ROOF_RAFTERS_BY_THICKNESS: Final[list[tuple[int, float]]] = [
|
|||
(400, 0.14),
|
||||
]
|
||||
|
||||
# Table 18 rafters column: pitched-roof "insulation at rafters" default U
|
||||
# by age band when the thickness cannot be determined. RdSAP 10 §5.11
|
||||
# Table 18 (PDF p.45). Identical to the joist column (1) for bands A-G
|
||||
# Table 18 column (2) "Pitched, insulation at rafters": pitched-roof default
|
||||
# U by age band when the thickness cannot be determined. RdSAP 10 §5.11
|
||||
# Table 18 (PDF p.46). Identical to the joist column (1) for bands A-G
|
||||
# (2.30 → 0.40), then diverges higher (H 0.35 vs 0.30, I 0.35 vs 0.26,
|
||||
# J/K 0.20 vs 0.16, L 0.18 vs 0.16). Unlike the loft-joist default this
|
||||
# does NOT collapse to the optimistic 0.40 "assume modern retrofit" floor
|
||||
# at old bands — a rafter cavity cannot be topped up from the loft, so an
|
||||
# unknown-thickness rafter roof keeps the as-built age-band U (band F
|
||||
# 0.68, band E 1.50, A-D 2.30). Worksheet-validated by simulated case 41
|
||||
# Ext3 (band F, R Rafters, As Built → P960 §3 (30) U=0.68).
|
||||
# J/K 0.20 vs 0.16, L 0.18 vs 0.16) before converging to 0.15 at band M.
|
||||
# Unlike the loft-joist default this does NOT collapse to the optimistic
|
||||
# 0.40 "assume modern retrofit" floor at old bands — a rafter cavity cannot
|
||||
# be topped up from the loft, so an unknown-thickness rafter roof keeps the
|
||||
# as-built age-band U (band F 0.68, band E 1.50, A-D 2.30). Worksheet-
|
||||
# validated by simulated case 41 Ext3 (band F, R Rafters, As Built → P960
|
||||
# §3 (30) U=0.68).
|
||||
_ROOF_RAFTERS_BY_AGE: Final[dict[str, float]] = {
|
||||
"A": 2.30, "B": 2.30, "C": 2.30, "D": 2.30, "E": 1.50,
|
||||
"F": 0.68, "G": 0.40, "H": 0.35, "I": 0.35, "J": 0.20,
|
||||
"K": 0.20, "L": 0.18, "M": 0.18,
|
||||
"K": 0.20, "L": 0.18, "M": 0.15,
|
||||
}
|
||||
|
||||
# Table 18 column (3): flat-roof default U by age band when thickness unknown.
|
||||
|
|
|
|||
|
|
@ -1265,6 +1265,25 @@ def test_u_roof_at_rafters_unknown_thickness_uses_table18_rafters_age_band() ->
|
|||
assert abs(band_c - 2.30) <= 0.001
|
||||
|
||||
|
||||
def test_u_roof_at_rafters_unknown_thickness_age_m_returns_0_15_per_table18() -> None:
|
||||
# Arrange — RdSAP 10 Table 18 column (2) "Pitched, insulation at
|
||||
# rafters" (PDF p.46): band M = 0.15 (footnote (1) only, no country
|
||||
# variation — the whole M row converges to 0.15). The rafters column
|
||||
# diverges above the joist column at H-L (0.35/0.35/0.20/0.20/0.18)
|
||||
# but rejoins it at M = 0.15; the table previously carried 0.18 here.
|
||||
|
||||
# Act
|
||||
band_m = u_roof(
|
||||
country=Country.ENG,
|
||||
age_band="M",
|
||||
insulation_thickness_mm=None,
|
||||
insulation_at_rafters=True,
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert abs(band_m - 0.15) <= 0.001
|
||||
|
||||
|
||||
def test_u_roof_unknown_age_band_falls_back_to_mid_range() -> None:
|
||||
# Arrange — nothing known.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue