A lumped-parameter (1D) model of a single pumped cooling loop — pump, cold plate, and heat exchanger — that solves for the operating flow rate and the steady and transient temperatures around the loop. Every result is checked against a closed-form reference, so the model verifies itself.
heat in (chip load) heat out (to secondary)
| ^
v |
[pump] -> [cold plate] -> [heat exchanger] --+
^ |
+-------------------------------------------+
one mass flow (series)
The loop splits into two solves. The hydraulic problem finds the mass flow
where the pump head balances the sum of component pressure losses (Newton via
scipy.optimize.fsolve). The thermal problem is a set of lumped-capacitance
energy balances on a cold-plate solid-wall node and two fluid control volumes,
with advection between nodes carrying enthalpy around the loop; it is solved
both transiently (stiff BDF integration) and at steady state. The heat
exchanger uses a counterflow effectiveness-NTU model.
The model is verified three independent ways against analytical references — the check a reviewer should look at first.
1. Hydraulic operating point matches the closed-form intersection of the pump and system curves (residual ~1e-11 Pa).
2. Transient solution settles onto the analytical steady state. The stiff integrator converges to the same temperatures the algebraic steady solve and the closed form predict (dotted lines).
3. Cold-plate thermal resistance matches the closed form across the full
flow range. The model output lands on R_th = 1/hA + 1/(ṁ·cp) to within
machine precision (max relative error ~1e-15). Note that R_th depends only on
flow, not on heat load — a convective resistance plus a caloric (flow-rate)
resistance.
A steady-state energy balance also confirms that the heat rejected by the exchanger equals the imposed chip load to 0%.
git clone https://github.com/sgoudarzi/cooling-loop-1d.git
cd [repo]
pip install -r requirements.txt
python loop1d.py # solve a nominal case + run the validation self-test
python make_figures.py # regenerate the figures aboveloop1d.py prints the operating flow, steady and transient temperatures, the
closed-form cross-checks, and the energy balance, then runs a parameter sweep.
The same engine sweeps heat load, pump speed, and coolant inlet temperature and
records the steady-state metrics to rom_dataset.csv:
from loop1d import Loop, sweep
import numpy as np
sweep(
Loop(),
Q_chip_grid=np.linspace(250, 1000, 6),
speed_grid=np.linspace(0.6, 1.0, 5),
T_cold_grid=np.linspace(20, 40, 3),
out_csv="rom_dataset.csv",
)Each row pairs inputs (Q_chip, pump_speed, mdot, T_cold_in) with targets
(R_th, T_wall as a junction proxy, T_cp, eps) — ready to train a
surrogate / reduced-order model that predicts loop performance in microseconds.
The model is intentionally a clean core to build on:
- Add pipe control volumes for transport lag (currently adiabatic links)
- Replace the scalar hydraulic solve with a nodal Newton-Raphson solve for parallel branches — multiple cold plates / rack manifolds
- Outer Picard loop for temperature-dependent ρ, μ, cp
- Distributed multi-node heat exchanger for fast-transient fidelity
- Port the verified components to OpenModelica (acausal / equation-based)
This 1D loop is the middle rung of a 0D/1D/3D + data-driven workflow:
- 3D — conjugate-heat-transfer cold-plate simulation (high fidelity) → [link]
- 1D — this loop model (system level, fast) → here
- ROM — surrogate trained on
rom_dataset.csv(real-time) → https://github.com/sgoudarzi/cooling-loop-surrogate git add README.md
The 3D model informs component coefficients; this loop generates the training data; the surrogate makes it real-time. One physics problem, three fidelities.
Built by Sahar Goudarzi · LinkedIn


