NandradSolver: the Engine Behind VICUS Buildings
How does a dynamic building simulation actually solve its equations? From the energy balance via ydot, dependency graph and CVODE to the Newton iteration and linear system — explained interactively.
What you will learn in this article:
- Why the solver balances energy rather than temperature directly
- How a balance equation becomes the rate of change `ydot` — and how a whole building emerges from it
- What the three nested loops (time → Newton → LSE) mean
- Why building simulations compute implicitly (stiffness) and what that costs
Table of Contents
Every dynamic building simulation stands or falls with its computational core — the piece of software that turns geometry, building components, weather and use into a physically reliable temperature and load profile. In VICUS Buildings this core is NANDRAD, a simulation solver matured over more than 20 years of research at TU Dresden. This article lifts the hood: step by step it shows what the NandradSolver computes and how it does it — from the physical balance equation via time integration to the linear system of equations at its heart.
You do not need a numerics degree for this. The central idea fits in a single sentence and can be „cranked through” yourself with the interactive demos below.
The core idea in one sentence
The solver describes the building (and possibly a pipe network) as one large system of coupled ordinary differential equations and integrates this system step by step through time. The heart of it is always the same question:
„How fast is the stored energy changing in every room and in every wall layer?”
Once you know this rate of change, you can take a small step into the future, compute the new temperatures and start over. In vector notation — exactly how the time integrator „sees” it — this reads:
Here is the state vector (a long list of all conserved quantities), their rate of change and the time.
The schema and three live demos
The interactive visualisation below summarises the whole process — and makes it tangible. At the top the functional schema with the three nested loops (hover the boxes to see the relevant source files; toggle between implicit and explicit). Beneath it three live demos in which you can turn the time step, grid fineness and heat-exchanger parameters yourself and find the stability limit.
How the NandradSolver computes
How to read this visualisation — from the overview to ever more strongly coupled systems of equations: How to read this visualisation — from a single equation to many that are connected:
📖 Each term in one sentence (look up any time)
State → temperature
„unpack“ energy y
- rooms
- constructions
- networks
Compute fluxes
physics at known T
- conduction, solar
- ventilation, int. gains
- HVAC, network
Σ fluxes → ẏ
close the balance
- rooms
- constructions
- networks
Step by step: a room cools down
The smallest conceivable NANDRAD model: one zone, one equation. A warm room (22 °C) loses heat to the cold outdoor air (5 °C): $\dfrac{dT}{dt} = -\dfrac{T - T_\text{out}}{\tau}$. Press Step and watch the integrator work its way through time — and turn dt to find the stability limit.
dt the solution overshoots T_out and explodes. Implicit stays stable — at the cost of Newton + LSE. For this linear example the implicit step even resolves directly (without Newton). If the solver takes time steps that are too large, the simple method „overshoots" and computes nonsense. The stable method stays calm — but costs more effort per step. Tip: drag dt past 6 h, then toggle between explicit/implicit. Try it: push dt past 6 h (= 2τ) and step with Explicit Euler — the solution starts to oscillate and explodes, even though physically the room only cools gently. Switch to Implicit Euler: the same large step size stays stable. That is exactly why NANDRAD computes stiff building models implicitly (CVODE).
Second example: heat conduction through a wall
Now a partial differential equation — the heat equation $\dfrac{\partial T}{\partial t} = \alpha\,\dfrac{\partial^2 T}{\partial x^2}$. A wall (warm inside, cold outside) is split into N cells; each cell balances only with its neighbours. This turns one PDE into a system of N coupled ODEs — exactly NANDRAD’s finite-volume wall, each layer one entry in y. Turn N and see why fine grids bring the explicit method to its knees.
$\dfrac{dT_i}{dt} = \dfrac{\alpha}{\Delta x^2}\,\bigl(T_{i-1} - 2T_i + T_{i+1}\bigr)$
// only the direct neighbours → tridiagonal
The stiffness effect: push N up (finer grid, more accurate!) — for explicit, r = α·dt/Δx² grows quadratically, quickly bursts the limit ½, and the profile jitters and explodes. To stay stable you would have to shrink dt drastically. Implicit solves a tridiagonal system (the LSE!) every step and stays stable for any N and dt. That is exactly why NANDRAD discretises walls into many cells and computes implicitly.
Third example: counter-flow heat exchanger
Two fluid streams exchange heat across a wall — hot and cold flow against each other. Split along the length into N segments, each segment has a hot and a cold fluid temperature → 2N coupled ODEs (flow + heat transfer). This is exactly how NANDRAD discretises pipes and heat exchangers in thermal networks. Compare counter-flow ↔ parallel-flow and see the effectiveness ε.
$M_h\dfrac{dT_{h,j}}{dt} = \dot C_h\,(T_{h,\text{in}}-T_{h,j}) \;-\; UA_\text{seg}\,(T_{h,j}-T_{c,j})$
$M_c\dfrac{dT_{c,j}}{dt} = \dot C_c\,(T_{c,\text{in}}-T_{c,j}) \;+\; UA_\text{seg}\,(T_{h,j}-T_{c,j})$
// cold: inflow from the other side; $\dot C_h \ne \dot C_c$ allowed
Why counter-flow? In parallel-flow both temperatures converge and end at a common mixing temperature — ε is capped. In counter-flow a nearly constant temperature gap is maintained along the length, and the cold outlet temperature can approach the hot inlet temperature → with large NTU, ε approaches 1.
Unequal capacity rates: the stream with the smaller $\dot C$ changes its temperature more (steeper curve) and sets $\dot C_\text{min}$. For $C_r\to 0$ counter- and parallel-flow give the same $\varepsilon = 1-e^{-\text{NTU}}$. The simulated effectiveness matches the analytic $\varepsilon$-NTU relation:$$\varepsilon_\text{counter} = \frac{1-e^{-\text{NTU}(1-C_r)}}{1-C_r\,e^{-\text{NTU}(1-C_r)}}, \qquad \varepsilon_\text{parallel} = \frac{1-e^{-\text{NTU}(1+C_r)}}{1+C_r}.$$
The rest of the article explains the individual building blocks in detail. You can scroll back up at any time and try out what you have learned.
Energy instead of temperature: the conserved quantity
A central design decision in NANDRAD: the solver balances energy (more precisely the stored internal energy), not temperature directly. The reason is physically clean — energy is a conserved quantity. All energy fluxes flowing into and out of a room can be summed unambiguously. Temperature is then a derived quantity, recovered from the energy and the heat capacity.
The general form of every balance equation is:
What is in the state vector y?
y is simply everything concatenated that changes over time and stores energy:
Part of the y vector | Meaning |
|---|---|
| Rooms / zones | internal energy of the room air (+ humidity if applicable) |
| Constructions (walls) | internal energy in each individual finite-volume element of a wall |
| Thermal networks | energy (mass × specific enthalpy) in pipes and components |
A single wall is therefore split internally into many thin layers — each layer is a separate entry in y. For a larger building this quickly amounts to several thousand unknowns. You can generate this „one wall into many coupled equations” decomposition yourself in the second demo (heat conduction through a wall) with the N slider.
Where does ydot come from? The balance, not a guess
A fair question: is stated — but where does the right-hand side come from? The answer: ydot is not guessed, it is derived from a conservation law. The recipe is always the same:
- Choose the conserved quantity
y(energy, mass, …) — not the temperature. - Write the balance: d(stored)/dt = Σ inflows − Σ outflows.
- Express each flux through the state (physical laws).
- Solve for
dy/dt— that isydot.
Example: a room cools down
The stored quantity is the internal energy with heat capacity . It only changes through the heat flow across the envelope, which is proportional to the temperature difference:
With , solving for the rate gives:
So ydot is derived, not invented — energy conservation plus one flux law. Exactly this single equation runs in the first demo („a room cools down”): you see the integrator work its way along the tangent through time, compared against the analytic solution.
And for a real building?
The crucial insight: in NANDRAD there is no single closed ydot formula sheet. With thousands of states a hand-written formula would be impossible. Instead the balance is the same for every state, but the sum of fluxes is assembled at runtime — every sub-model throws its contribution into the pot: conduction between layers, solar gains through windows, ventilation and infiltration, internal gains, heating and cooling power, pipe flow. ydot is therefore a function you do not write down but evaluate.
The three evaluation stages: Head → Middle → Tail
The integrator hands the model a y and asks for the corresponding ydot. Internally this happens in three stages — exactly the balance recipe, cast into code:
| Stage | Recipe step | in the room example |
|---|---|---|
| Head | state y → intensive quantity | T = U/C (energy → temperature) |
| Middle | compute fluxes from the state | Q = −(T − T_out)/R |
| Tail | close the balance → ydot | ydot = Q/C |
In the schema above this data flow is shown as a three-stage pipeline inside the Newton loop.
Order of the models: the dependency graph
There are many small sub-models, and they depend on one another: the window model needs the outdoor temperature from the climate model, the room balance needs the heating power from the HVAC model. In what order must one compute?
NANDRAD solves this with a dependency graph. Each model declares which quantities it needs as input and which it produces as a result. From this a correct evaluation order is computed automatically (topological sort). Two special cases are noteworthy:
- Parallelisation: models that are independent of one another sit in the same „level” of the graph and are evaluated in parallel (e.g. many walls at once).
- Cycles: if models depend on each other mutually (such as a controller reacting to a quantity it influences itself), they are grouped together and solved iteratively as a group.
Time integration: taking a step into the future
Now we have a function that yields ydot for any y. The job of time integration is to reconstruct the time history from it — the path from the slope. In an outer loop the solver advances step by step from t to t+dt, commits each accepted step and writes out any due results.
Importantly, the step size dt is not constant. The integrator chooses it itself — large steps at night when little changes, very small ones when the heating kicks in. The output (hourly values, say) is decoupled from this: between the actual computation steps, values are cleanly interpolated onto the requested output times.
Which integrator? CVODE as the default
NANDRAD ships several integrators; in practice CVODE from the SUNDIALS package is used almost always — an implicit, adaptive method based on BDF (Backward Differentiation Formulas) of order 1 to 5. Explicit methods (Explicit Euler, Runge-Kutta 45) are also available as reference and debugging integrators.
After each attempt CVODE estimates the local error and compares it with a prescribed relative and absolute error tolerance. If the error is too large, the step is rejected and retried with a smaller dt (or lower order); if it is comfortably small, step size and order may grow. This is how the solver automatically finds the compromise between accuracy and speed.
Explicit vs. implicit — and why buildings are computed implicitly
Whether a time step needs a Newton iteration and a linear system of equations depends solely on where the unknown y_{n+1} appears in the formula.
Explicit — only old, known values on the right. You substitute and compute, a single ydot evaluation per step, nothing to solve:
Implicit — the unknown also appears on the right and must be solved for:
If explicit is cheaper per step — why implicit? Because of stiffness. Building models combine very fast (air, thin layers) and very slow (massive walls, screed) time constants. Explicit methods then have to take tiny steps for stability reasons — the step size is governed not by the desired accuracy but by the fastest time constant. Thousands of cheap mini-steps end up far more expensive than the few large, accuracy-driven steps of an implicit method.
| Explicit | Implicit (NANDRAD default) | |
|---|---|---|
| Newton iteration needed? | no | yes |
LSE J·Δy = −F needed? | no | yes (per Newton iteration) |
| Cost per step | very low | high |
| Step size limited by | stability (very small for stiff systems) | accuracy (can be large) |
| Suitable for buildings? | no (too slow) | yes |
You can see the effect immediately in the first two demos: push dt past the stability limit and the explicit solution starts to oscillate and explodes — the implicit one stays calm. In the wall demo a finer grid (large N) makes the problem even stiffer, and the explicit Fourier number quickly bursts the limit .
Three nested loops
This is the most important mental map. The implicit solver consists of three levels nested inside each other — exactly the three loops from the interactive schema above:
- Outer — time loop (CVODE): picks the step size
dtand goes fromttot+dt. - Middle — Newton iteration: solves the nonlinear implicit equation for
y_{n+1}(usually 1–3 iterations). - Inner — linear system of equations (LSE): in every Newton iteration, is solved once.
The Newton iteration
The implicit equation is written as „= 0”:
Newton improves a guess step by step by linearising locally:
Here is the Jacobian — the derivative of with respect to , i.e. „how does each balance react to a small change of each state quantity”. This matrix equation is exactly the linear system of equations — and is its coefficient matrix (the in ), not a tool for error estimation. Adaptive step-size control estimates the time-step error separately via the tolerances and does not need for that. With states, is an matrix while and are vectors of length — a square system of equations.
Where ydot enters. Both parts of this system are built from ydot — it is not a side branch. The right-hand side is directly the negative residual, , i.e. one ydot evaluation at the current guess. The matrix is
and the sensitivity is itself obtained from ydot evaluations: NANDRAD perturbs each state quantity slightly, re-runs the Head→Middle→Tail pipeline with the perturbed state and forms the finite difference — that yields one column of . So each Newton iteration calls ydot several times: once for the right-hand side and additionally for the columns of the Jacobian (accelerated by sparsity and graph colouring, see below).
The linear system of equations (LSE)
In every Newton iteration must be solved. is an matrix; with thousands of unknowns this is the most compute-intensive part of the whole simulation.
Where does the Jacobian come from?
Usually is formed numerically via finite differences: each state quantity is perturbed slightly, the change in is observed, and the matrix is obtained column by column. With thousands of columns this would naively be very expensive — the trick is sparsity: a wall layer couples only with its direct neighbours, a room only with its adjacent components. The vast majority of entries in are therefore zero. NANDRAD knows the sparsity pattern in advance and, via graph colouring, perturbs many independent columns simultaneously — instead of thousands it often needs only a handful of evaluations.
The tridiagonal structure of a one-dimensional wall discretisation is the simplest case of this sparsity. The wall demo shows exactly this tridiagonal system and breaks it down cell by cell — the matrix shown there, with on the diagonal and next to it, is the Jacobian, i.e. the coefficient matrix of the LSE.
Direct vs. iterative solvers
There are two fundamentally different ways to solve :
- Direct solvers compute the exact solution via a factorisation (LU) — good for small, full as well as large, sparse systems.
- Iterative solvers approximate the solution step by step (Krylov methods); they need a preconditioner that „smooths” the system beforehand.
If you leave these fields empty in the project, NANDRAD picks sensible defaults (usually a direct sparse solver, or an iterative solver with a preconditioner for large networks). For most applications this is the right choice — you only touch these parameters when a simulation is too slow or fails to converge.
From state to solution in five sentences
- The solver balances energy per room and per wall layer; this yields a large system of ordinary differential equations .
- The function
ydotis evaluated in three stages (energy → temperature, fluxes, sum →ydot); the order is determined by an automatic dependency graph. - Integration uses CVODE (implicit BDF method) with adaptive step size plus error control — necessary because building models are stiff.
- Each implicit time step requires a Newton iteration, and each Newton iteration a linear system of equations (the three nested loops).
- Depending on size and sparsity, the LSE is solved directly (Dense/KLU) or iteratively (GMRES/BiCGStab + ILU); the Jacobian is formed numerically and exploits the sparsity via graph colouring.
What this means in practice
For day-to-day work in an engineering office you do not need to operate this machinery in detail — but it helps to understand why a validated dynamic simulation delivers reliable results and which screws to turn in case of doubt. The NandradSolver is the computational core that VICUS Buildings builds on; the underlying methodology is documented as open source through the SIM-VICUS research project and was developed over more than 20 years at TU Dresden. To dig deeper, see our articles on dynamic building simulation, on the difference between steady-state and dynamic, and on validation standards.
Frequently Asked Questions
What does the NandradSolver compute?
Why does building simulation compute implicitly rather than explicitly?
What is ydot in building simulation?
What are the Newton iteration and the linear system of equations (LSE)?
How large do these systems of equations get?
Related Articles
What is dynamic building simulation? Differences from steady-state calculation, fields of application and advantages for design
Summer thermal protection by simulation: solar heat gain coefficient vs. dynamic thermal building simulation per DIN 4108-2 – methods, overheating degree hours and limits.
From BIM model to simulation: how IFC files improve the workflow between CAD and building simulation
Comparison of steady-state energy demand calculation and dynamic simulation: methods, accuracy and fields of application
Disclaimer: The content of this page is for general information purposes only and does not constitute legal, planning or engineering advice. All information is provided without guarantee. Despite careful research, VICUS Software GmbH assumes no liability for the accuracy, completeness or timeliness of the information provided. Third-party product names and trademarks are mentioned for informational purposes only and are the property of their respective owners.