| name | energy-simulation |
| description | Building energy simulation and analysis for construction. Calculate heating/cooling loads, evaluate envelope performance, optimize HVAC sizing, and ensure energy code compliance. |
| homepage | https://datadrivenconstruction.io |
| metadata | {"openclaw":{"emoji":"🚀","os":["darwin","linux","win32"],"homepage":"https://datadrivenconstruction.io","requires":{"bins":"[Truncated]"}}} |
Energy Simulation
Overview
This skill implements building energy simulation and analysis. Calculate thermal loads, evaluate building envelope performance, and optimize systems for energy efficiency and code compliance.
Capabilities:
- Heating/cooling load calculations
- Envelope thermal analysis
- HVAC system sizing
- Energy code compliance
- Renewable energy integration
- Life cycle cost analysis
Quick Start
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
from enum import Enum
import numpy as np
class WallType(Enum):
CONCRETE = "concrete"
BRICK = "brick"
WOOD_FRAME = "wood_frame"
STEEL_FRAME = "steel_frame"
CURTAIN_WALL = "curtain_wall"
@dataclass
class BuildingEnvelope:
wall_area_m2: float
wall_u_value: float
roof_area_m2: float
roof_u_value: float
floor_area_m2: float
floor_u_value: float
window_area_m2: float
window_u_value: float
window_shgc: float
@dataclass
class ClimateData:
location: str
heating_degree_days: float
cooling_degree_days: float
design_temp_winter: float
design_temp_summer: float
def calculate_heat_loss(envelope: BuildingEnvelope, climate: ClimateData,
indoor_temp: float = 21) -> float:
"""Calculate design heat loss (W)"""
delta_t = indoor_temp - climate.design_temp_winter
wall_loss = envelope.wall_area_m2 * envelope.wall_u_value * delta_t
roof_loss = envelope.roof_area_m2 * envelope.roof_u_value * delta_t
floor_loss = envelope.floor_area_m2 * envelope.floor_u_value * delta_t * 0.5
window_loss = envelope.window_area_m2 * envelope.window_u_value * delta_t
total_loss = wall_loss + roof_loss + floor_loss + window_loss
volume = envelope.floor_area_m2 * 3
infiltration = volume * 0.5 * 0.33 * delta_t
return total_loss + infiltration
envelope = BuildingEnvelope(
wall_area_m2=500, wall_u_value=0.35,
roof_area_m2=200, roof_u_value=0.25,
floor_area_m2=200, floor_u_value=0.30,
window_area_m2=100, window_u_value=1.4, window_shgc=0.4
)
climate = ClimateData(
location="Moscow",
heating_degree_days=5000,
cooling_degree_days=300,
design_temp_winter=-25,
design_temp_summer=30
)
heat_loss = calculate_heat_loss(envelope, climate)
print(f"Design heat loss: {heat_loss/1000:.1f} kW")
Comprehensive Energy Analysis
Building Thermal Model
from dataclasses import dataclass, field
from typing import List, Dict, Optional, Tuple
from enum import Enum
import numpy as np
from datetime import datetime
@dataclass
class MaterialLayer:
name: str
thickness_m: float
conductivity: float
density: float
specific_heat: float
@property
def resistance(self) -> float:
"""Thermal resistance R (m²K/W)"""
return self.thickness_m / self.conductivity if self.conductivity > 0 else 0
@dataclass
class WallAssembly:
name: str
layers: List[MaterialLayer]
inside_surface_resistance: float = 0.13
outside_surface_resistance: float = 0.04
@property
def () -> :
(.inside_surface_resistance +
(layer.resistance layer .layers) +
.outside_surface_resistance)
() -> :
/ .total_resistance .total_resistance >
:
name:
u_value:
shgc:
visible_transmittance: =
frame_fraction: =
:
zone_id:
name:
floor_area_m2:
volume_m3:
occupancy:
lighting_power_density:
equipment_power_density:
ventilation_rate:
setpoint_heating: =
setpoint_cooling: =
:
zones: [Zone]
walls: []
windows: []
roofs: []
floors: []
:
CLIMATE_DB = {
: {
: , : ,
: -, : ,
:
},
: {
: , : ,
: -, : ,
:
},
: {
: , : ,
: , : ,
:
}
}
():
.building = building
.location = location.lower()
.climate = .CLIMATE_DB.get(.location, .CLIMATE_DB[])
() -> :
delta_t = - .climate[]
results = {}
zone .building.zones:
wall_loss =
window_loss =
roof_loss =
floor_loss =
wall .building.walls:
wall[] == zone.zone_id:
u_value = wall[].u_value
wall_loss += wall[] * u_value * delta_t
window .building.windows:
window[] == zone.zone_id:
window_loss += window[] * window[].u_value * delta_t
roof .building.roofs:
roof[] == zone.zone_id:
u_value = roof[].u_value
roof_loss += roof[] * u_value * delta_t
floor .building.floors:
floor[] == zone.zone_id:
u_value = floor[].u_value
factor = floor.get(, )
floor_loss += floor[] * u_value * delta_t * factor
infiltration_loss = zone.volume_m3 * * * delta_t
ventilation_loss = zone.occupancy * zone.ventilation_rate * * delta_t
total = wall_loss + window_loss + roof_loss + floor_loss + infiltration_loss + ventilation_loss
results[zone.zone_id] = {
: zone.name,
: wall_loss,
: window_loss,
: roof_loss,
: floor_loss,
: infiltration_loss,
: ventilation_loss,
: total,
: total / ,
: total / zone.floor_area_m2
}
results
() -> :
delta_t = .climate[] -
results = {}
zone .building.zones:
transmission_gain =
wall .building.walls:
wall[] == zone.zone_id:
u_value = wall[].u_value
sol_air_delta = delta_t + ._get_sol_air_correction(wall[])
transmission_gain += wall[] * u_value * sol_air_delta
solar_gain =
window .building.windows:
window[] == zone.zone_id:
shgc = window[].shgc
irradiance = ._get_solar_irradiance(window[])
solar_gain += window[] * shgc * irradiance
window_conduction =
window .building.windows:
window[] == zone.zone_id:
window_conduction += window[] * window[].u_value * delta_t
lighting_gain = zone.floor_area_m2 * zone.lighting_power_density
equipment_gain = zone.floor_area_m2 * zone.equipment_power_density
people_gain = zone.occupancy *
ventilation_gain = zone.occupancy * zone.ventilation_rate * * delta_t
total = (transmission_gain + solar_gain + window_conduction +
lighting_gain + equipment_gain + people_gain + ventilation_gain)
results[zone.zone_id] = {
: zone.name,
: transmission_gain,
: solar_gain,
: window_conduction,
: lighting_gain,
: equipment_gain,
: people_gain,
: ventilation_gain,
: total,
: total / ,
: total / zone.floor_area_m2
}
results
() -> :
corrections = {
: , : , : , : ,
: , : , : , :
}
corrections.get(orientation.lower(), )
() -> :
irradiance = {
: , : , : , : ,
: , : , : , :
}
irradiance.get(orientation.lower(), )
HVAC System Sizing
class HVACSizer:
"""Size HVAC systems based on loads"""
def __init__(self, calculator: ThermalCalculator):
self.calculator = calculator
def size_heating_system(self, safety_factor: float = 1.15) -> Dict:
"""Size heating system"""
heating_loads = self.calculator.calculate_design_heating_load()
total_load = sum(z['total_kw'] for z in heating_loads.values())
sized_capacity = total_load * safety_factor
if sized_capacity < 15:
system_type = "Split system heat pump"
elif sized_capacity < 50:
system_type = "Packaged rooftop unit"
elif sized_capacity < 200:
system_type = "Central boiler with radiators"
else:
system_type = "Central plant with multiple boilers"
return {
'total_load_kw': total_load,
'sized_capacity_kw': sized_capacity,
'safety_factor': safety_factor,
'recommended_system': system_type,
'zone_loads': heating_loads
}
def size_cooling_system(self, safety_factor: float = 1.1) -> :
cooling_loads = .calculator.calculate_design_cooling_load()
total_load = (z[] z cooling_loads.values())
sized_capacity = total_load * safety_factor
capacity_tons = sized_capacity /
capacity_tons < :
system_type =
capacity_tons < :
system_type =
capacity_tons < :
system_type =
:
system_type =
{
: total_load,
: capacity_tons,
: sized_capacity,
: capacity_tons * safety_factor,
: safety_factor,
: system_type,
: cooling_loads
}
() -> :
climate = .calculator.climate
heating_loads = .calculator.calculate_design_heating_load()
cooling_loads = .calculator.calculate_design_cooling_load()
total_heating_load = (z[] z heating_loads.values())
total_cooling_load = (z[] z cooling_loads.values())
delta_t_heating = - climate[]
heating_kwh = total_heating_load * climate[] * / delta_t_heating /
delta_t_cooling = climate[] -
cooling_kwh = total_cooling_load * climate[] * / delta_t_cooling / delta_t_cooling >
heating_fuel_efficiency =
cooling_cop =
heating_consumption = heating_kwh / heating_fuel_efficiency
cooling_consumption = cooling_kwh / cooling_cop
{
: total_heating_load,
: total_cooling_load,
: heating_kwh,
: cooling_kwh,
: heating_consumption,
: cooling_consumption,
: heating_consumption + cooling_consumption
}
Energy Code Compliance
@dataclass
class EnergyCodeRequirements:
code_name: str
climate_zone: str
wall_u_max: float
roof_u_max: float
floor_u_max: float
window_u_max: float
window_shgc_max: float
lighting_lpd_max: float
class ComplianceChecker:
"""Check energy code compliance"""
CODES = {
'ASHRAE_90.1_2019_4A': EnergyCodeRequirements(
code_name="ASHRAE 90.1-2019",
climate_zone="4A",
wall_u_max=0.45,
roof_u_max=0.27,
floor_u_max=0.32,
window_u_max=2.0,
window_shgc_max=0.40,
lighting_lpd_max=9.0
),
'IECC_2021_5A': EnergyCodeRequirements(
code_name="IECC 2021",
climate_zone="5A",
wall_u_max=0.35,
roof_u_max=0.20,
floor_u_max=0.30,
window_u_max=1.7,
window_shgc_max=0.40,
lighting_lpd_max=8.5
)
}
def __init__(self, code_key: str):
self.requirements = self.CODES.get(code_key)
if not self.requirements:
raise ValueError()
() -> :
results = {
: .requirements.code_name,
: .requirements.climate_zone,
: ,
: []
}
wall building.walls:
u_value = wall[].u_value
u_value > .requirements.wall_u_max:
results[] =
results[].append({
: ,
: u_value,
: .requirements.wall_u_max,
:
})
window building.windows:
u_value = window[].u_value
shgc = window[].shgc
u_value > .requirements.window_u_max:
results[] =
results[].append({
: ,
: u_value,
: .requirements.window_u_max,
:
})
shgc > .requirements.window_shgc_max:
results[] =
results[].append({
: ,
: shgc,
: .requirements.window_shgc_max,
:
})
roof building.roofs:
u_value = roof[].u_value
u_value > .requirements.roof_u_max:
results[] =
results[].append({
: ,
: u_value,
: .requirements.roof_u_max,
:
})
results
() -> :
results = {
: ,
: []
}
zone zones:
zone.lighting_power_density > .requirements.lighting_lpd_max:
results[] =
results[].append({
: zone.name,
: zone.lighting_power_density,
: .requirements.lighting_lpd_max
})
results
Quick Reference
| Component | Good U-Value | Code Maximum |
|---|
| Wall | < 0.25 W/m²K | 0.35-0.45 |
| Roof | < 0.15 W/m²K | 0.20-0.27 |
| Floor | < 0.20 W/m²K | 0.25-0.32 |
| Window | < 1.2 W/m²K | 1.7-2.0 |
Resources
- ASHRAE 90.1: Energy standard for buildings
- IECC: International Energy Conservation Code
- EnergyPlus: DOE building simulation
- DDC Website: https://datadrivenconstruction.io
Next Steps
- See
co2-estimation for carbon analysis
- See
cost-prediction for energy cost modeling
- See
bim-validation-pipeline for model integration