Skip to content

Simulation performance

Envelope-only models generated by trano simulate a week in about a second; the same buildings with a hydronic heating system take ten to two hundred times longer. This page explains where the time goes, which simplifications trano applies by default to reduce it (and how to turn them off), what they cost in accuracy, and what remains inherent to the libraries. The numbers are measured by a reproducible benchmark:

TRANO_MODELICA_LIBRARIES=<installed libraries> python -m validation.performance \
    --profiles baseline fast hysteresis fast_hysteresis

Diagnosis method

Each model is translated with buildModel and its executable run on its own, so that the translation (OpenModelica front end, back end, code generation and C compilation) and the simulation are timed separately. The settings are fixed: DASSL, tolerance 1e-6, one week from 1 January (Uccle weather), one output point every 15 minutes, OpenModelica 1.26.9 with Buildings 13.0.0, IDEAS 3.0.0 and the Modelica Standard Library 4.1.0.

The statistics behind the diagnosis come from OpenModelica itself:

  • -d=backenddaeinfo at translation: number of states and size of the linear and nonlinear systems left after tearing;
  • -lv=LOG_STATS,LOG_STATS_V at simulation: steps, right-hand-side and Jacobian evaluations, error and convergence test failures, state and time events, time spent in each linear and nonlinear system;
  • -lv=LOG_EVENTS: which zero-crossing triggers each event;
  • -noEquidistantTimeGrid: every accepted step written to the result, to see where the steps are small.

Controlled experiments then change one aspect of the generated model at a time and measure the effect on speed and on the results.

Where the time goes

envelope only with hydronic heating
steps per simulated week about 1 900 22 000 to 42 000
median step about 300 s 1.9 s
state events per week 0 to 14 330 to 1 080
share of the simulation time spent in Jacobian evaluations small 74 % (single zone) to 88 % (house)

Buildings and IDEAS are equally slow for the same hydronic system: the cost comes from the hydronic components trano shares between the libraries, not from the envelope models. Four causes were found.

Actuator filters inside control loops (trano modelling default). Every valve and pump keeps the filter of its library approximating the actuator's stroke time (120 s) or the mover's rise time (30 s), and the temperature sensors keep a first-order lag of 1 s. The valves and pumps sit in proportional or PI loops on the zone temperature and on the loop pressure: with the filters, these loops force steps of about 2 s for the whole simulation and trigger many convergence test failures, each of which costs a new Jacobian.

Costly Jacobians. DASSL evaluates its Jacobian numerically, one model evaluation per colour of the sparsity pattern (about 20 to 45). Each evaluation solves the algebraic loop of the hydraulic network (the pump curve, the three-way valve and the radiator valves: a nonlinear system of 3 to 8 iteration variables and a linear system of up to 14) and, with Buildings, the long-wave radiation exchange of every room (linear systems of 10 to 24 unknowns per room). The number of Jacobians is set by the step failures and the events.

Events of the controls (trano modelling default). The boiler control compares the tank temperatures with fixed thresholds without hysteresis and waits on state-graph timers: in the three-zone model it causes 585 of the 913 events of a week, about 3.5 threshold crossings per burner cycle. The G36 zone controller of the radiator valves adds about 100 events per zone and week (enable hysteresis, PI reset, timers). After the filters are removed, a third of all steps are the small steps following an event.

Translation (library and tool). 35 s to 220 s, of which about 7 s load the libraries and 10 s to 25 s compile the C code. It does not depend on the options below.

Solver settings were measured as well and are not worth changing: a tolerance of 1e-4 saves about 20 % with DASSL, CVODE is 20 % faster on one model and 60 % slower on another (and fails on a pump efficiency assertion at zero speed with a tolerance of 1e-4), a symbolic Jacobian saves at most 10 %, the sparse linear solvers fail at initialization, and the output interval is negligible (writing the result takes less than 0.3 s).

Options

Ideal actuators and steady-state sensors (on by default)

Both options are on by default. To generate the detailed model, with the actuator and sensor dynamics of the libraries, turn them off in the YAML (an option left out of the block stays on):

performance:
  ideal_actuators: false       # keep the stroke-time and rise-time filters of valves, dampers, pumps, fans
  steady_state_sensors: false  # keep the first-order lag of the two-port sensors

ideal_actuators sets use_strokeTime=false (Buildings, AixLib) or use_inputFilter=false (IDEAS) on every valve and damper, and use_riseTime=false or use_inputFilter=false on every pump and fan; steady_state_sensors sets tau=0 on the two-port sensors of temperature, humidity, mass fraction, trace substances, enthalpy, entropy and density. They apply to every declaration of these library classes in the generated model, including the ones of the embedded Trano package; a value set by a template or in the YAML always wins. The same options can be given in Python, where they replace those of the YAML:

from trano.data_models.conversion import convert_network
from trano.performance import PerformanceOptions

detailed = convert_network("house", path, performance=PerformanceOptions.disabled())

Why it works: without the filters the actuators are algebraic, so the loops no longer have fast closed-loop dynamics and the steps are set by the building and the events; the convergence test failures drop from hundreds to tens. The price is a larger nonlinear system of the hydraulic network (the pump speed becomes an iteration variable), which is cheaper than the steps it saves.

The two options are meant to be used together: on their own, steady-state sensors do not speed the models up (their states are cheap), but they remove the last fast states once the actuators are ideal.

Accuracy: the filters are part of the closed-loop dynamics, so removing them shifts the burner and pump cycles in time. With the boiler models the zone air temperatures deviate by up to a few tenths of a kelvin in RMSE and up to a few kelvin at the worst instant, while the delivered heating energy changes by about one percent; with the heat pump of the residential house the zone temperatures stay within 0.05 K in RMSE and 0.35 K at the worst instant. With steady-state sensors, a sensor in a pipe without flow reports the water flowing in rather than the last temperature it measured: the supply and return temperatures read at zero flow differ, the heat delivered does not. The defaults suit long simulations (annual energy, parameter studies, optimization); turn the options off to study the transients of a control loop.

Hysteresis of the boiler control

systems:
  - boiler:
      id: BOILER:001
      control:
        boiler_control:
          id: BOILER_CONTROL:001
          parameters:
            temperature_hysteresis: 1.0  # [K], 0 by default

The tank temperature checks that start and stop the boiler stay true until their temperature falls temperature_hysteresis below the threshold, instead of switching at every crossing (default and complex boiler controls; the simple control of heat pumps has its own band). It removes the chattering of the checks around their threshold.

It does not change the results (zone temperatures within 0.11 K) but it does not speed the models up measurably either: it removes up to 110 of 900 events a week in the three-zone model, which is within the run-to-run noise of the timings. Use it for a cleaner burner operation, not for speed.

Results

Simulation of one week, translation measured once per model (the options do not change it). The timings vary by about 7 % from run to run on the same machine. Accuracy is measured against the baseline, the detailed model generated with both options off, from the second day on; tolerances: zone air temperature RMSE 0.1 K and maximum 0.5 K, heating energy 2 %. Bold deviations are beyond tolerance.

Ideal actuators and steady-state sensors (fast, trano's default)

model library translation [s] simulation baseline [s] simulation fast [s] speed-up steps conv. failures zone T RMSE / max [K] heating energy
two_zones (envelope only) Buildings 41 1.2 - - 1,934 0 - -
two_zones (envelope only) IDEAS 40 1.5 - - 1,783 0 - -
single_zone_hydronic Buildings 35 16.6 8.6 1.92x 22,176 → 10,795 666 → 37 0.129 / 1.94 +0.0%
single_zone_hydronic IDEAS 32 14.7 10.6 1.38x 22,196 → 10,528 491 → 31 0.217 / 1.78 +0.1%
three_zones_hydronic Buildings 63 93.6 75.8 1.23x 41,370 → 22,516 856 → 91 0.342 / 3.08 +0.3%
three_zones_hydronic IDEAS 64 106.1 86.9 1.22x 33,395 → 17,297 423 → 228 0.464 / 1.66 -0.4%
house_infiltration_boiler Buildings 78 58.6 26.0 2.26x 24,755 → 13,239 911 → 9 0.035 / 0.27 -0.9%
house_infiltration_boiler IDEAS 68 39.1 16.1 2.42x 42,498 → 12,994 247 → 5 0.032 / 0.22 -0.3%
residential_after_renovation Buildings 147 247.7 179.8 1.38x 32,828 → 22,881 930 → 0 0.042 / 0.35 -0.0%
residential_after_renovation IDEAS 123 90.9 80.1 1.13x 35,605 → 23,601 73 → 1 0.009 / 0.06 -0.0%

The simulation is 1.1 to 2.4 times faster: the steps are halved and the convergence failures almost disappear. The heating energy is unchanged to within 1 %. The zone temperatures stay within tolerance for the house with infiltration and for the residential house (heat pump), but not for the single and three-zone boiler models, whose burner cycles are shifted in time: up to 0.46 K RMSE and 3.1 K at the worst instant. The supply and return temperatures differ by 3 K to 60 K at the worst instant, mostly while a loop has no flow, where the steady-state sensors read the incoming water instead of holding their last value. Turn the options off when the transients of a control loop matter. The gain on the whole run is smaller where translation dominates (three-zone model with Buildings: 157 s to 143 s, translation included).

Models outside the benchmark set were checked over one day with both libraries: the ventilation models (single_zone_air_handling_unit_complex_vav, multizone_air_handling_unit_space_connected) are unchanged (zone temperatures identical to 0.01 K); the house with an air-water heat pump simulates 1.7 to 1.9 times faster (zone temperature RMSE 0.03 K, heating energy within 1.4 %). The VAV model with IDEAS did not finish one simulated day in 30 minutes with the options off; with them it takes 27 s.

Hysteresis of the boiler control (hysteresis, 1 K)

model library simulation baseline [s] simulation hysteresis [s] state events zone T RMSE / max [K]
single_zone_hydronic Buildings 16.6 15.6 336 → 330 0.007 / 0.11
single_zone_hydronic IDEAS 14.7 15.4 332 → 332 0.002 / 0.04
three_zones_hydronic Buildings 93.6 94.0 900 → 790 0.004 / 0.10
three_zones_hydronic IDEAS 106.1 108.9 671 → 665 0.002 / 0.04

The house with infiltration and the residential house are not affected (their generator controls have no tank checks). Combined with fast, the hysteresis gives the same times as fast alone. The full report, with the solver statistics of every run, is written by the benchmark to .cache/performance/report.md.

Reproducing

# all models but house_complex, profiles baseline and fast, one week
TRANO_MODELICA_LIBRARIES=<installed libraries> python -m validation.performance
# one model and library, all profiles
python -m validation.performance --models three_zones_hydronic --libraries Buildings \
    --profiles baseline fast hysteresis fast_hysteresis

The runs are kept in .cache/performance/<case>/ (model, logs, results, run.json) and reused while the generated model does not change; --force runs them again, --reuse renders the report again from the stored runs. The executable resolves modelica:// URIs (the weather file) against its working directory, where the benchmark links the installed libraries.

Remaining limits

  • Room radiation exchange of Buildings. Each room of Buildings.ThermalZones.Detailed solves a dense linear system for the long-wave radiation between its surfaces at every model evaluation; with 6 to 11 surfaces per room it dominates the Jacobian cost of the residential house (Buildings is 2.8 times slower than IDEAS on it). Merging surfaces would shrink it, but in the houses benchmarked no two surfaces of a room share construction, orientation and neighbour, so no merge is exact; trano does not merge them.
  • Translation time is spent in OpenModelica and in the C compiler.
  • Events of the remaining controls. The heat pump's own minimum run and lock times, the buffer charging band and the G36 zone controllers still cause hundreds of events per week; they are part of the modelled behaviour.
  • Hydraulic operating point. The radiator loops run at 1 % to 10 % of the nominal flow of their pump, which is controlled by a proportional controller on the loop pressure. This is a sizing question for the model rather than a numerical setting and is left as it is.