§5 slice 3: (69) cooking_monthly_w — 35 + 7N const-tuple

SAP10.2 Table 5 Column A row "Cooking": G_C = 35 + 7 × N watts,
year-round. Fuel-agnostic (gas/electric same gain — fuel matters only
for §12 cost). Verified against Elmhurst U985-0001-000490 worksheet
(69)m row.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-05-20 18:02:15 +00:00
parent 021f43ba67
commit 984a5b18d6
2 changed files with 38 additions and 0 deletions

View file

@ -34,6 +34,8 @@ from typing import Final, Optional
_MONTHS_IN_YEAR: Final[int] = 12
_METABOLIC_GAIN_W_PER_OCCUPANT_COL_A: Final[float] = 60.0
_LOSSES_W_PER_OCCUPANT_COL_A: Final[float] = -40.0
_COOKING_W_BASE_COL_A: Final[float] = 35.0
_COOKING_W_PER_OCCUPANT_COL_A: Final[float] = 7.0
def metabolic_monthly_w(*, n_occupants: float) -> tuple[float, ...]:
@ -57,6 +59,17 @@ def losses_monthly_w(*, n_occupants: float) -> tuple[float, ...]:
for _ in range(_MONTHS_IN_YEAR))
def cooking_monthly_w(*, n_occupants: float) -> tuple[float, ...]:
"""SAP 10.2 §5 line (69) — cooking gains in watts per month.
Table 5 Column A: G_C = 35 + 7 × N watts, constant year-round.
Fuel-agnostic (gas vs electric cooker has same heat gain; only the
§12 cost calc differentiates).
"""
gain = _COOKING_W_BASE_COL_A + _COOKING_W_PER_OCCUPANT_COL_A * n_occupants
return tuple(gain for _ in range(_MONTHS_IN_YEAR))
_METABOLIC_W_PER_OCCUPANT: Final[float] = 60.0

View file

@ -13,6 +13,7 @@ Table 5a + Appendix L (lighting/appliances/cooking) + Appendix J Table 1b
import pytest
from domain.sap.worksheet.internal_gains import (
cooking_monthly_w,
losses_monthly_w,
metabolic_monthly_w,
)
@ -62,3 +63,27 @@ def test_losses_are_negative_40n_constant_across_months() -> None:
for m, value in enumerate(monthly):
assert value == pytest.approx(-40.0 * n, abs=1e-9), f"month {m+1}"
assert value < 0, "Losses must be negative (heat-loss convention)"
def test_cooking_gains_match_table_5_col_a_formula() -> None:
"""SAP 10.2 Table 5 Column A row "Cooking": G_C = 35 + 7 × N watts,
constant year-round.
Cooking gains are fuel-agnostic the formula applies whether the
cooker is gas or electric (fuel matters only for the §12 cost calc,
not the internal-gain heat contribution).
Verified against Elmhurst U985-0001-000490 worksheet (69)m row,
which shows 50.0277 W flat. For 000490's N=2.1468:
35 + 7 × 2.1468 = 50.0276 W agrees to 4 d.p.
"""
# Arrange
n = 2.1468
# Act
monthly = cooking_monthly_w(n_occupants=n)
# Assert
assert len(monthly) == 12
for m, value in enumerate(monthly):
assert value == pytest.approx(35.0 + 7.0 * n, abs=1e-9), f"month {m+1}"