mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Cert 1536 lodged window dimensions including (0.65 × 0.70) × 3
windows. In float arithmetic 0.65 × 0.70 = 0.45499999999999996,
which the `_round_half_up(float, dp)` helper snaps to 0.45 vs the
spec answer 0.46 (Decimal: 0.65 × 0.70 = 0.4550 exact, HALF_UP at
2 d.p. = 0.46). The shortfall of 0.01 m² × 3 windows = 0.03 m²
under-counted as ~0.073 W/K of conduction loss vs the worksheet's
windows_w_per_k = 25.6354 — closing the cert 1536 residual at
+0.00152 to <2e-6.
Same class of bug as the S0380.34/35 living-area / gross-wall /
party-wall closures (Decimal HALF_UP at the 0.005 boundary that
float drops). RdSAP10 §15 (p.66) lists "all element areas (gross)
including window areas: 2 d.p." — Decimal is the only arithmetic
that matches that boundary deterministically.
Three cascade sites now use Decimal HALF_UP for per-window areas:
- heat_transmission.py: `_decimal_round_half_up_product(W, H, 2)`
replaces `_round_half_up(W × H, 2)` at the windows_w_per_k cascade
AND at the per-bp window-area accumulation (the wall-net deduction
branch must agree with the conduction branch for cascade-internal
consistency, per the existing comment at line 575-583).
- internal_gains.py: `_decimal_window_area_2dp(W, H)` replaces the
inline `_round_area_2dp(W × H)` in the daylight factor `g_l`
sum so §5 (66)..(67) sees the same per-window areas as §3 (27).
- solar_gains.py: same Decimal helper replaces `_round_area_2dp` in
`_wall_window_solar_gain_monthly_w` so §6 (74)..(81) area = (27).
The `_round_area_2dp` helpers were inlined per-module in pre-S0380.42
work; this slice deletes them since the Decimal-aware product
replaces all call sites. `_round_half_up` stays in heat_transmission
for non-product per-element area calls (single-value rounds).
Test impact:
- Cohort-2 cert 1536 API path: +0.00152 → -1e-6 (<1e-4 ✓).
Moves from _COHORT_2_API_OPEN to _COHORT_2_API_CLOSED. Cohort
distribution: 37/38 exact (was 34/38 at start of session);
only cert 2102 (-6.30 secondary-heating routing) remains open.
- Cohort-2 cert 0300/9380 unchanged (already <1e-4 after S0380.41).
- Cohort-1 ASHP 9/9 unchanged: <1e-4 on both paths.
- Elmhurst 6-cert worksheet sweep: unchanged (lodges
`window_width=area, window_height=1.0` per the Elmhurst lodging
convention — Decimal(area) × Decimal(1.0) = Decimal(area), no
rounding shift).
Test suite: 750 pass + 0 fail. Pyright net-zero per touched file
(heat_transmission 13/13; internal_gains 4/4 pre-existing; solar_gains
0/0; chain test 0/0).
Spec citation: RdSAP 10 Specification §15 "Rounding of data" p.66 —
"All element areas (gross) including window areas and conservatory
wall area: 2 d.p." Decimal is the float-precision-stable arithmetic
that matches this rule at the .005 boundary.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| handler | ||
| tests | ||
| __init__.py | ||
| db_writer.py | ||
| elmhurst_extractor.py | ||
| extractor.py | ||
| local_runner.py | ||
| parser.py | ||
| pdf.py | ||