Slice 73: 1:1 windows expansion in cohort 000477 (3 → 7 entries)

Closes the final `sap_windows: LEN 7 vs 3` divergence by replacing
the cohort 000477 hand-built's glazing-type-collapsed 3-window
encoding with 7 SapWindow entries mirroring the Summary §11 1:1 —
the same row breakdown the Elmhurst mapper extracts. Total area per
glazing-type group is preserved (cascade-equivalent):

  g=0.72/U=2.0: 8.04 m² total — was 2 rows (E 1.28 + W 6.76),
    now 6 rows (E 1.28 + W [1.8 + 1.7 + 1.36 + 1.36 + 0.54])
  g=0.76/U=2.8: 1.17 m² in 1 row (unchanged)

Cohort 000477 is a single-bp dwelling, so every window's
`window_location` is "Main" — no per-bp apportionment complexity.

Cascade output unchanged: all 11 `_FIXTURE_PINS["000477"]` SapResult
pins remain GREEN at 1e-4 against worksheet `SAP value 65.0057`.

**Cohort 000477 is now fully Layer-2 GREEN** —
`test_from_elmhurst_site_notes_matches_hand_built_000477` passes with
zero load-bearing divergences between the mapped EpcPropertyData
(from `Summary_000477.pdf`) and the hand-built fixture.

Full sweep: 103 passed (was 102 pre-Slice-71; +1 new diff test),
10 failed (same 10 001479-related as documented in the handover).
Pyright net-zero on the touched fixture.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-25 17:47:31 +00:00
parent 6d9cf47344
commit 3614c14bf5

View file

@ -347,18 +347,36 @@ LINE_73_M_TOTAL_INTERNAL_GAINS_W: tuple[float, ...] = (
# ============================================================================
# §6 Solar gains — cert-derived inputs + expected outputs
# ============================================================================
# 3 wall windows across 2 glazing types (Manufacturer-declared g⊥):
# "Double between 2002" g=0.72: E 1.28, W 6.76
# "Double with unknown" g=0.76: W 1.17
# All PVC frame. No roof windows, no rooflights.
# 7 wall windows mirroring the Summary §11 1:1, matching the Elmhurst
# mapper's per-row extraction (mapper-vs-hand-built field-parity test).
# Per-window curtain-transform U_eff sums to the same total as the prior
# 3-window collapsed encoding (same total area per glazing-type group:
# g=0.72/U=2.0 → 8.04 m² across 6 rows; g=0.76/U=2.8 → 1.17 m² in 1
# row). Cascade output is unchanged at 1e-4.
#
# Single-bp dwelling → every window's `window_location` is "Main".
SECTION_6_VERTICAL_WINDOWS: tuple[SapWindow, ...] = (
# Windows 1 (PDF (27) U_eff=1.8519, raw U=2.0 post-2002; g_⊥=0.72):
# area 1.28 + 6.76 = 8.04 m².
make_window(orientation=3, width=1.28, height=1.0, solar_transmittance=0.72, u_value=2.0),
make_window(orientation=7, width=6.76, height=1.0, solar_transmittance=0.72, u_value=2.0),
# Windows 2 (PDF (27) U_eff=2.5180, raw U=2.8 pre-2002; g_⊥=0.76):
# area 1.17 m². make_window default u_value=2.8 matches.
make_window(orientation=7, width=1.17, height=1.0, solar_transmittance=0.76),
# Windows 1 — W
make_window(orientation=7, width=1.8, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
# Windows 1 — W
make_window(orientation=7, width=1.7, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
# Windows 1 — E
make_window(orientation=3, width=1.28, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
# Windows 1 — W
make_window(orientation=7, width=1.36, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
# Windows 1 — W
make_window(orientation=7, width=1.36, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
# Windows 2 — W (raw U=2.8 pre-2002, g_⊥=0.76)
make_window(orientation=7, width=1.17, height=1.0, solar_transmittance=0.76,
u_value=2.8, window_location="Main"),
# Windows 1 — W
make_window(orientation=7, width=0.54, height=1.0, solar_transmittance=0.72,
u_value=2.0, window_location="Main"),
)
SECTION_6_ROOF_WINDOWS: tuple[RoofWindowInput, ...] = ()
SECTION_6_ROOFLIGHTS: tuple[RooflightInput, ...] = ()