Model/backend/documents_parser
Khalim Conn-Kowlessar efb203f7ad Slice S0380.109: Solid brick + insulation via §5.7 Table 13 + §5.8 Table 14 (RdSAP 10)
Closes the remaining cert 000565 BP[0] Main wall residual (-1.54 W/K
under ws) by routing solid-brick walls with documentary wall
thickness + lodged insulation through the RdSAP 10 §5.7 + §5.8
formula chain. Adds a Table-6 footnote (a) cap on the §5.6 stone
formula to handle thin uninsulated stone walls (Ext1 BP[1] Granite
W=50 mm).

RdSAP 10 §5.7 Table 13 (PDF p.41) verbatim:

  "Default U-values of brick walls
   Wall thickness, mm   U-value, W/m²K
   Up to 200 mm         2.5
   200 to 280 mm        1.7
   280 to 420 mm        1.4    ← cert 000565 Main W = 300 mm
   More than 420 mm     1.1"

RdSAP 10 §5.8 step 2 (PDF p.41-42) verbatim:

  "The U-value of the insulated wall is U = 1 / (1/U₀ + R_insulation)
   ...
   Where R_insulation comes from Table 14: Insulation thickness and
   corresponding resistance.
   ...
   R = 0.025 × T + 0.25 when λ = 0.04 W/m·K
   R = 0.0333 × T + 0.248 when λ = 0.03 W/m·K
   R = 0.040 × T + 0.25 when λ = 0.025 W/m·K
   Where T is thickness of insulation in mm"

Cert 000565 Main lodgement (Summary §7.0):
  Type SO Solid Brick (wall_construction = 3)
  Insulation E External (wall_insulation_type = 1)
  Insulation Thickness 75 mm
  Wall Thickness 300 mm (measured)
  Conductivity Known No  → λ defaults to 0.04 (§5.8 final note)
  Age band A

Formula chain:
  U₀ = 1.4 (§5.7 Table 13 row "280 to 420 mm")
  R  = 0.025 × 75 + 0.25 = 2.125 m²K/W
  U  = 1 / (1/1.4 + 2.125) = 1 / 2.8393 = 0.3522 → 0.35 (2 d.p.)

Pre-slice the cascade bucketed 75 mm into the Table-6 "100 mm
external/internal insulation" row → 0.32 for age A. The -0.03 U
delta on Main's 51.72 m² external wall is the entire -1.54 W/K
under-count driving the cohort's remaining fabric residual.

RdSAP 10 Table 6 footnote (a) (PDF p.34) verbatim:

  "Or from equations in 5.6 if the calculated U-value is less than
   1.7."

Applies only to the AS-BUILT (no insulation, no dry-line) Table 6
row. For thin walls where §5.6 gives U ≥ 1.7 the Table 6 row
default of 1.7 caps the result. Verified empirically against cert
000565 Main alt_wall_1 (granite W=120 mm dry-lined): raw §5.6 →
3.879 + dry-line → 2.34 matches worksheet, NOT capped 1.7 + dry-
line → 1.32. The cap therefore only fires when neither dry-lining
nor insulation is present (cert 000565 BP[1] Ext1: granite W=50 mm
"Insulation Unknown" → §5.6 = 6.09 → capped to 1.7, matches ws).

3-layer fix:
1. `domain/sap10_ml/rdsap_uvalues.py`:
   - Add `_u_brick_thin_wall_age_a_to_e(W_mm)` per §5.7 Table 13
   - Add `_r_insulation_table_14(T_mm, λ)` per §5.8 Table 14
     interpolation rule (handles all 3 λ columns)
   - Wire §5.7+§5.8 chain into `u_wall` for WALL_SOLID_BRICK + age
     A-E + lodged thickness + (External | Internal) insulation +
     thickness > 0
   - Add Table 6 footnote (a) cap to `_u_stone_thin_wall_age_a_to_e`
     (cap at 1.7 only when not dry-lined)
   - Round dry-lined §5.6 result to 2 d.p. (worksheet A×U precision)
2. `domain/sap10_calculator/worksheet/heat_transmission.py` passes
   `wall_thickness_mm=part.wall_thickness_mm` through to `u_wall`
   for the per-BP main wall U (previously passed only for alt walls).
3. AAA test pins cert 000565 walls_w_per_k = 604.07 within 1e-4.

Movement at HEAD `9159e91f` → post-slice (cert 000565):

Fabric (cascade vs ws):
  walls         602.53 → 604.08 (Δ -1.54 → +0.01 W/K — sub-spec
                                  alt-wall float rounding artifact)
  total W/K     935.54 → 937.09 (Δ -1.52 → +0.03 W/K — essentially
                                  zero net fabric HTC residual)

End-result pins:
  sap_score (int)    29 ✓ EXACT  (unchanged)
  sap_score_continuous 28.5380 → 28.5028  (Δ +0.0293 → -0.0059;
                                          80% magnitude reduction)
  ecf              5.3838 →  5.3874 (Δ -0.0028 → +0.0008)
  total_fuel_cost_gbp 4677.64 → 4680.78 (Δ -2.62 → +0.52)
  co2_kg_per_yr   6444.27  → 6448.34 (Δ -3.35 → +0.72)
  space_heating  58974.84  → 59020.02 (Δ -33.5 → +11.7)
  main_heating_fuel 34691.09 → 34717.66 (Δ -19.7 → +6.87)
  lighting_kwh    1382.67 (unchanged)
  pumps_fans_kwh ✓ EXACT (unchanged)

Continuous SAP magnitude improved 80% (0.0293 → 0.0059). All
SH-driven downstream residuals (cost, co2, SH kwh, main_heating
fuel) magnitude-reduced 65-80%. Integer SAP stays exact at 29.

Cohort safety verified: 6 cohort certs (000474-000516) lodge wc=4
(cavity) + wit=4 (as-built) — neither precondition for the new
§5.7+§5.8 path. §5.6 cap only fires when not dry-lined (cohort
certs don't trigger). All 11 cert→inputs and 6 sap_result_pin
cohort tests pass unchanged.

Golden cert 6035-7729-2309-0879-2296 (mid-terrace age A solid
brick) sees the §5.7+§5.8 chain fire on its Main wall:
  PE  +46.7562 → +46.0936 kWh/m² (cascade closer to actual EPC)
  CO2 +1.0652  → +1.0495 tonnes/yr (cascade closer to actual EPC)
Per [[feedback-golden-residuals-near-zero]] the expected pin is
updated to track the improvement (target → ~0 as mapper closes).

Test count: 608 pass + 7 expected 000565 fails → **608 pass + 7
expected 000565 fails** (new §5.7+§5.8 formula test green; golden
cert 6035 pin re-pinned; integer SAP stays at 29). Pyright net-zero
per touched file (27 baseline → 27 post-change).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 18:10:33 +00:00
..
handler address JTK review comments 2026-04-20 15:11:17 +00:00
tests Slice S0380.109: Solid brick + insulation via §5.7 Table 13 + §5.8 Table 14 (RdSAP 10) 2026-05-30 18:10:33 +00:00
__init__.py Map to RdSapSiteNotes from site notes JSON 🟥 2026-04-16 13:54:03 +00:00
db_writer.py include updating epc_property_data to pashub to ara workflow 2026-04-29 09:55:14 +00:00
elmhurst_extractor.py Slice S0380.102: Wire MEV decentralised cascade into pumps_fans (SAP 10.2 §2.6.4 + Table 4f line 230a) 2026-05-30 15:45:55 +00:00
extractor.py Handle wall thickness "Unmeasurable" 🟩 2026-04-30 16:41:16 +00:00
local_runner.py update local runner to work for elmhurst 2026-04-24 14:01:36 +00:00
parser.py load ecmk site notes to db 2026-04-29 11:20:47 +00:00
pdf.py update local runner to work for elmhurst 2026-04-24 14:01:36 +00:00