EnerHabitat

Thermal simulation of opaque constructive systems (walls and roofs) from EPW data, in 1D and 2D

EnerHabitat is a Python package for the thermal simulation of opaque constructive systems (walls and roofs) driven by EPW weather data. It solves the time-dependent heat conduction equation across the system and produces indoor temperatures and air-conditioning energy demands for an average day of a chosen month (Barrios et al. 2016). Homogeneous layer stacks are solved in 1D (System); units that are heterogeneous across their width, such as concrete hollow-block walls and joist-and-block roofs, are solved in 2D over their cross-section (System2D).

The model considers a single opaque envelope component: no windows, no ventilation, no infiltration, no internal gains. Two solution modes are available: free-running (the indoor temperature evolves with the system’s dynamics) and air-conditioned (the indoor temperature is held at a comfort setpoint and the energy demands are reported). The full list of modelling assumptions and their consequences is in Assumptions and limits.

Installation

pip install enerhabitat        # or: uv add enerhabitat

Requires Python ≥ 3.10. The section inspector plots are an optional extra: pip install enerhabitat[viz].

Quickstart

EnerHabitat bundles no materials. Create a plain text file materials.ini in your working directory (or point eh.config.file to one) before running anything:

[Adobe]
k   = 0.58    # W/(m·K),  thermal conductivity
rho = 1500    # kg/m³,    density
c   = 1480    # J/(kg·K), specific heat
import enerhabitat as eh

# 1. Create or locate the materials file (required; no defaults are bundled)
eh.config.file = "./materials.ini"

# 2. Geolocate: read an EPW weather file
loc = eh.Location("./epw/example.epw")

# 3. Define the constructive system: orientation, solar absorptance, layers
wall = eh.System(location=loc)
wall.azimuth = 90                  # surface azimuth: 0 N, 90 E, 180 S, 270 W
wall.absortance = 0.3              # solar (short-wave) absorptance of the outdoor surface
wall.layers = [("Adobe", 0.20)]    # (material, thickness in m), outside → inside
                                   # tilt: 90 = vertical wall (default), 0 = roof

# 4. Choose the period: the average day of May
#    (the year only stamps the datetime index; in a TMY it selects nothing)
loc.meanDay(month=5, year=2025)
wall.Tsa()                         # sun–air temperature, the outdoor forcing

# 5. Solve: free-running indoor temperature (pandas Series named "Ti")
ti = wall.solve()
print(wall.energy_transfer)        # J/(m²·day)

# ...or air-conditioned: Ti held at the neutrality temperature Tn
# wall.solveAC()
# print(wall.cooling_energy, wall.heating_energy)

The same steps, with real results and plots, run in Usage — 1D; 2D units add their geometry in Usage — 2D.

Where to go next

  • Usage — setup: the materials file and the configuration (config, config2d).
  • Usage — 1D: the Quickstart steps on a homogeneous wall, free-running and air-conditioned, executed live.
  • Usage — 2D: hollow blocks and joist-and-block slabs, with geometry schemes, section inspection and temperature fields.
  • Theory: 1D model (physical problem, equations, boundary conditions), 2D model (cavities, hollow blocks, slabs), numerical method (discretisation, convergence, validation) and assumptions and limits.
  • API reference: every class and parameter.
  • About: how to cite, changelog, authors.

References

Barrios, G., J. M. Casas, G. Huelsz, and J. Rojas. 2016. “Ener-Habitat: An Online Numerical Tool to Evaluate the Thermal Performance of Homogeneous and Non-Homogeneous Envelope Walls/Roofs.” Solar Energy 131: 296–304. https://doi.org/10.1016/j.solener.2015.12.017.