Model/domain/building_geometry.py
Khalim Conn-Kowlessar 0ba0575877 feat(modelling): shared gross heat-loss wall area geometry helper
domain/building_geometry.gross_heat_loss_wall_area(epc, identifier) sums
heat_loss_perimeter x room_height across a building part's storeys — the
heat-loss wall area (party walls excluded by construction), not total
wall area. Lives outside the calculator so Modelling cost quantities can
reuse it; the calculator computes the same quantity inline today and
should be DRY'd onto this later (coordinated with the calculator branch).

Pinned at 45.93 m^2 against the 000490 MAIN part. Toward #1155 cost
(behaviour 4). pyright strict clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 22:53:12 +00:00

33 lines
1.2 KiB
Python

"""Building geometry derived purely from an EpcPropertyData.
Reusable outside the SAP calculator (e.g. for Modelling cost quantities).
Today this re-derives the heat-loss wall area; the calculator computes the
same quantity inline (`heat_transmission._part_geometry`). A later, calculator-
branch-coordinated refactor should DRY the two onto this module so there is a
single source of truth. See the project memory on calculator geometry.
"""
from datatypes.epc.domain.epc_property_data import (
BuildingPartIdentifier,
EpcPropertyData,
)
def gross_heat_loss_wall_area(
epc: EpcPropertyData, identifier: BuildingPartIdentifier
) -> float:
"""Gross external wall area of one building part, in m^2: the sum over its
storeys of heat-loss perimeter x room height. This is the heat-loss area
(party walls are excluded — they are not on the heat-loss perimeter); it is
not netted of window/door openings.
"""
part = next(
candidate
for candidate in epc.sap_building_parts
if candidate.identifier is identifier
)
area = sum(
fd.heat_loss_perimeter_m * fd.room_height_m
for fd in part.sap_floor_dimensions
)
return round(area, 2)