Metadata-Version: 2.4
Name: thermobuilpy
Version: 1.0.4
Summary: Model and simulate lumped thermal RC systems with several time-discretization methods.
Author-email: Hannes Hanse <hannes.hanse@tu-clausthal.de>
License-Expression: MIT
Project-URL: Homepage, https://github.com/hanneshanse/ThermoBuilPy
Project-URL: Issues, https://github.com/hanneshanse/ThermoBuilPy/issues
Project-URL: Repository, https://github.com/hanneshanse/ThermoBuilPy
Keywords: building simulation,energy system,RC model,stratified storage,thermal model
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Provides-Extra: plot
Requires-Dist: matplotlib>=3.7; extra == "plot"
Provides-Extra: excel
Requires-Dist: openpyxl>=3.1; extra == "excel"
Requires-Dist: pandas>=2.0; extra == "excel"
Provides-Extra: optimization
Requires-Dist: milpython>=0.6.2; extra == "optimization"
Provides-Extra: examples
Requires-Dist: ipykernel>=6.29; extra == "examples"
Requires-Dist: matplotlib>=3.7; extra == "examples"
Requires-Dist: openpyxl>=3.1; extra == "examples"
Requires-Dist: pandas>=2.0; extra == "examples"
Provides-Extra: test
Requires-Dist: build>=1.2; extra == "test"
Requires-Dist: nbclient>=0.10; extra == "test"
Requires-Dist: nbformat>=5.10; extra == "test"
Requires-Dist: pytest>=8.0; extra == "test"
Requires-Dist: pytest-cov>=5.0; extra == "test"
Requires-Dist: PyYAML>=6.0; extra == "test"
Requires-Dist: ruff>=0.12; extra == "test"
Requires-Dist: tomli>=2.0; python_version < "3.11" and extra == "test"
Requires-Dist: twine>=6.0; extra == "test"
Dynamic: license-file

# ThermoBuilPy

[![Tests](https://github.com/hanneshanse/ThermoBuilPy/actions/workflows/tests.yml/badge.svg)](https://github.com/hanneshanse/ThermoBuilPy/actions/workflows/tests.yml)
[![PyPI](https://img.shields.io/pypi/v/thermobuilpy.svg)](https://pypi.org/project/thermobuilpy/)
[![Python](https://img.shields.io/pypi/pyversions/thermobuilpy.svg)](https://pypi.org/project/thermobuilpy/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/hanneshanse/ThermoBuilPy/blob/main/LICENSE)

ThermoBuilPy models lumped thermal resistance-capacitance (RC) systems and
simulates them with explicit Euler, implicit Euler, or Crank–Nicolson time
discretization. It supports thermal capacities, fixed or controlled boundary
temperatures, conductive heat transfer, forced convection, buoyancy-driven
mixing, stratified storages, and user-defined linear heat flows.

The project is under active development. Please report problems through the
[GitHub issue tracker](https://github.com/hanneshanse/ThermoBuilPy/issues).

## Installation

Install the numerical core from PyPI:

```console
python -m pip install thermobuilpy
```

Optional functionality is grouped into extras:

```console
python -m pip install "thermobuilpy[plot]"          # Matplotlib plots
python -m pip install "thermobuilpy[excel]"         # Excel import/export
python -m pip install "thermobuilpy[optimization]"  # MilPython integration
python -m pip install "thermobuilpy[examples]"      # tutorial requirements
```

Python 3.10 or newer is required.

## Quick start

```python
import numpy as np

from ThermoBuilPy import Conduction, ThermalStorage, ThermalSystem

capacity_1 = ThermalStorage.newStorage(cap=1_000.0, temp=30.0, name="Capacity 1")
capacity_2 = ThermalStorage.newStorage(cap=4_182.0, temp=50.0, name="Capacity 2")
conduction = Conduction(capacity_1, capacity_2, coeff=100.0)

system = ThermalSystem.newThermalSystem(
    storages=[capacity_1, capacity_2],
    conductions=[conduction],
)
initial_energy = capacity_1.get_Q() + capacity_2.get_Q()
system.simulate(num_steps=100, stepsize=1.0)

np.testing.assert_allclose(
    capacity_1.get_Q() + capacity_2.get_Q(),
    initial_energy,
)
```

Install the `plot` extra to visualize the result:

```python
system.plot_temps([capacity_1, capacity_2])
system.plot_heatflow([conduction])
```

The executable notebooks in [`Basic_examples`](https://github.com/hanneshanse/ThermoBuilPy/tree/main/Basic_examples) cover boundary
storages, stepwise simulation, convection, controls, and discretization.

## Units and physical boundary

ThermoBuilPy deliberately does not impose a unit system. All quantities must
use one consistent energy and time basis. For example:

| Quantity | SI example | Hour-based example |
| --- | --- | --- |
| Stored energy | J | Wh |
| Time | s | h |
| Heat flow | W = J/s | W = Wh/h |
| Heat capacity | J/K | Wh/K |
| Specific heat capacity | J/(kg K) | Wh/(kg K) |
| Mass flow | kg/s | kg/h |

`ThermalStorage` objects are states inside the modeled boundary. `ExtStorage`
objects prescribe temperatures outside that state boundary and record signed
boundary heat flow: positive values enter the external storage, negative values
are supplied to the modeled system. Forced-convection paths must keep the mass
of every internal storage constant; use a closed path or external source and
sink nodes.

## Time integration

`SimulationMethod.CRANK_NICOLSON` is the default. Explicit Euler is inexpensive
but requires a sufficiently small step for stability. Implicit Euler is more
damping and robust for stiff networks. `EXPLICIT_EULER_STRICT` retains the
previous coefficient and source vector for one full step and is mainly provided
for compatibility with earlier control semantics.

Use `simulate()` for a fixed result length or `prepare_simulation()` followed by
`do_simstep()` for online control. `do_simstep(commit_step=False)` calculates a
preview that can be inspected through `get_temp_temp()` and accepted later with
`commit_simstep()`. Calling it again before committing recalculates the preview
from the same committed state, allowing an iterative controller to adjust its
inputs.

## Excel and optimization integrations

`ThermalSystem.to_Excel()` and `ThermalSystem.from_Excel()` exchange the flat
system topology without evaluating workbook content as Python code. Install the
`excel` extra first. Storage names only need to be unique when exporting to
Excel because workbook connections refer to their endpoints by name; numerical
simulation uses object identity.

`ThermalSystem.makeLPSystem()` translates supported storages, conductances,
forced-convection paths, and general heat transfers into a MilPython model. The
resulting chain is ThermoBuilPy thermal topology → MilPython LP/MILP matrices →
the solver selected through MilPython. Free-convection switching is currently
available in numerical simulation but is not automatically translated to an
LP/MILP model.

## Development

```console
python -m venv .venv
.venv\Scripts\python -m pip install -e ".[examples,optimization,test]"
.venv\Scripts\python -m ruff check src tests tools
.venv\Scripts\python -m pytest
```

On Linux or macOS, use `.venv/bin/python` instead. See [CONTRIBUTING.md](https://github.com/hanneshanse/ThermoBuilPy/blob/main/CONTRIBUTING.md)
for test scope and [RELEASING.md](https://github.com/hanneshanse/ThermoBuilPy/blob/main/RELEASING.md) for the GitHub/PyPI release
process.

## License

ThermoBuilPy is distributed under the [MIT License](https://github.com/hanneshanse/ThermoBuilPy/blob/main/LICENSE).
