fix(hp): floor heat-pump water-heating efficiency at 100% (App N3.7) 🟩

_heat_pump_apm_efficiencies applied the Table N8 in-use factor to the PCDB
water-heating efficiency but omitted the spec's "subject to a minimum
efficiency of 100%" clause (SAP 10.2 Appendix N3.7, PDF p.109). An oversized
heat pump whose PSR-extended water,3 x the 0.60 in-use factor fell below
100% therefore billed water heating at that sub-100% efficiency, over-
counting hot-water fuel.

Apply max(in_use x eta_water, 100%). Accredited Elmhurst worksheet for cert
100110101713 (golden fixture case 56, PCDB 100061): water (216) = 100.0000,
which we now match (was 77.13%). Combined with the space-heating PSR-
extension fix the cert lands 72.51 vs lodged 73 (|err| 18.32 -> 0.49).

Data-driven: only the single oversized-PSR cert moves (in-range heat pumps
keep their > 100% water COP, e.g. case 54 112.5%, case 55 179.6%). Corpus
(RdSAP-21.0.1 n=1000) MAE 0.726 -> 0.721, within-0.5 74.1% -> 74.2%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-29 15:38:31 +00:00
parent 672e6679c8
commit dbaf3c49e2

View file

@ -6234,6 +6234,10 @@ _SAP_DESIGN_HEAT_LOSS_DELTA_T_K: Final[float] = 24.2
_HP_SPACE_HEATING_IN_USE_FACTOR_N3_6: Final[float] = 0.95
_HP_IN_USE_FACTOR_CRITERIA_MET: Final[float] = 0.95
_HP_IN_USE_FACTOR_CRITERIA_FAIL: Final[float] = 0.60
# SAP 10.2 Appendix N3.7 (PDF p.109): the heat-pump water-heating efficiency
# (in-use factor × η_water) is "subject to a minimum efficiency of 100%" —
# below that the direct-electric backup governs.
_HP_WATER_HEATING_MIN_EFFICIENCY: Final[float] = 1.0
def _heat_pump_cylinder_meets_pcdb_criteria(
@ -6325,7 +6329,12 @@ def _heat_pump_apm_efficiencies(
main_heating_efficiency = (
_HP_SPACE_HEATING_IN_USE_FACTOR_N3_6 * eta_space_1_pct / 100.0
)
water_efficiency_pct = in_use_water * eta_water_3_pct / 100.0
# N3.7: in-use factor × η_water, subject to a minimum efficiency of 100%
# (the direct-electric backup floors the heat pump's water heating).
water_efficiency_pct = max(
in_use_water * eta_water_3_pct / 100.0,
_HP_WATER_HEATING_MIN_EFFICIENCY,
)
return (main_heating_efficiency, water_efficiency_pct)