HeartPumpNode#
Module: maddening.nodes.heart_pump
Stability: experimental
Algorithm ID: MADD-NODE-008
Version: 1.0.0
Summary#
A 2-element Windkessel model of the systemic arterial tree [@Westerhof2009]: a compliant reservoir emptying through a peripheral resistance, filled by a pulsatile cardiac inflow. It produces a physiologically plausible arterial pressure waveform for driving a downstream vascular domain.
Governing Equations#
with the cardiac inflow sinusoidal during systole and zero during diastole,
\(Q_{\max}\) is fixed by the stroke volume: integrating the half-sine over systole gives \(Q_{\max} = \text{SV} \cdot \pi f / (2 f_s)\) with \(f = \text{HR}/60\).
Discretization#
Explicit, 1st order in time. Per step:
The phase advance is exact — the phase is linear in \(t\) — so the only discretisation error is in the pressure.
Declared order of accuracy: DiscretizationOrder(spatial=None, temporal=1.0).
There is no spatial order: the arterial compartment is lumped, with no spatial extent.
Warning
NodeMeta.discretization names forward Euler, which would place every
right-hand-side term at \(t^n\). As written above, the inflow is evaluated
at \(\phi^{n+1}\) — the end of the step — while the outflow uses \(P^n\).
The node’s own derivatives() evaluates the same waveform at \(\phi^n\), so
the explicit path and the derivatives()-based paths
(integrate_node, implicit_residual) integrate inflow waveforms offset
by one timestep. Both samplings are 1st order, so the declared order is
unaffected. Recorded as MADD-ANO-012.
backpressure is also cast to float32 unconditionally, which pins the
coupling variable to single precision under any caller precision
(MADD-ANO-013).
Implementation Mapping#
Equation Term |
Implementation |
Notes |
|---|---|---|
\(\dot\phi = \text{HR}/60\) (cycle phase) |
|
|
\(Q_{\text{heart}}(\phi)\) (cardiac inflow) |
|
Half-sine during systole, zero otherwise, branch-free via |
\(Q_{\max}\) from stroke volume |
|
\(\text{SV}\,\pi f / (2 f_s)\) |
\((P_{\text{art}} - P_{\text{down}})/R\) (outflow) |
|
|
\(P_{\text{down}}\) (downstream pressure) |
|
|
Time integration of \(P\) |
|
|
Continuous right-hand side |
|
Samples the inflow at \(\phi^n\), not \(\phi^{n+1}\) (MADD-ANO-012) |
Backward-Euler residual |
|
\(x^{n+1} - x^n - \Delta t f(x^{n+1})\) |
\(P_{\text{art}}\) published downstream |
|
|
Assumptions and Simplifications#
Lumped parameters: the arterial compartment is spatially uniform
Rigid arterial walls — compliance is constant
Sinusoidal systolic flow waveform
Instantaneous valve opening and closing; no valve dynamics
No inertial effects (2-element model, no inductance)
No wave propagation, no coronary circulation, no venous return dynamics
Validated Physical Regimes#
Parameter |
Verified Range |
Notes |
|---|---|---|
|
40 – 180 bpm |
|
|
0.2 – 0.5 |
Divides the phase; must stay strictly inside \((0, 1)\) |
|
0.01 – 100 |
|
|
0.001 – 100 |
|
|
not bounded |
No validated range is recorded; see the limitations below |
Known Limitations and Failure Modes#
1st-order integration: the pressure error is \(O(\Delta t)\)
No stability check on \(\Delta t\) relative to the \(RC\) time constant; forward Euler on this ODE is stable only for \(\Delta t < 2RC\), and nothing enforces it
Negative pressures are reachable with a large \(\Delta t\) or a low compliance
Source sampled at the end of the step: MADD-ANO-012, above
backpressuretruncated to float32: MADD-ANO-013, above. A float64 convergence study is floored at about \(10^{-6}\) relative error, and a weakly typed float64 pressure state is demoted to float32 by the same cast, which makeslax.scanreject the carryderivatives()leavesflow_ratewhere it started. It andimplicit_residual()take the injectedparamsby the same{**self.params, **params}rule asupdate()(MADD-ANO-018, resolved in 0.4.0), butderivatives()returns a zero rate forflow_rate, whichupdate()recomputes from the phase every step: after 20 steps of 0.01 s from rest,update()reports 314.6 andintegrate_nodestill 0.0The inflow waveform is continuous but has a corner at the systole/diastole transition, so it is not \(C^1\); higher-order integrators would not recover their order across it
Stability Conditions#
The homogeneous part of the pressure ODE decays with time constant \(RC\). Forward Euler is stable for
and non-oscillatory for \(\Delta t < RC\). With the defaults (\(R = C = 1\)) that is a 2-second bound, so stability is rarely the binding constraint; accuracy relative to the systolic pulse is (see the workaround recorded with MADD-ANO-012).
State Variables#
Field |
Shape |
Units |
Description |
|---|---|---|---|
|
scalar |
Pa |
Arterial pressure \(P_{\text{art}}\) |
|
scalar |
— |
Position in the cardiac cycle, \([0, 1)\) |
|
scalar |
volume/s |
Cardiac inflow at the end of the step |
Parameters#
Parameter |
Type |
Default |
Units |
Description |
|---|---|---|---|---|
|
float |
1.0 |
— |
Peripheral vascular resistance \(R\) |
|
float |
1.0 |
— |
Arterial compliance \(C\) |
|
float |
72.0 |
bpm |
Heart rate |
|
float |
70.0 |
— |
Volume ejected per beat |
|
float |
0.0 |
Pa |
Downstream pressure when |
|
float |
0.35 |
— |
Fraction of the cycle that is systole, \(f_s\) |
|
float |
80.0 |
Pa |
Starting arterial pressure |
Boundary Inputs#
Field |
Shape |
Default |
Description |
|---|---|---|---|
|
scalar |
|
Downstream pressure feedback, e.g. from an LBM outlet |
Boundary Fluxes#
Field |
Shape |
Units |
Description |
|---|---|---|---|
|
scalar |
Pa |
Arterial pressure, for a downstream vascular domain |
References#
[@Westerhof2009] Westerhof, N., Lankhaar, J.-W. and Westerhof, B.E. (2009). The arterial Windkessel. Med. Biol. Eng. Comput. 47(2), 131–141. — The 2-element model implemented here, and the limits of a lumped description of the arterial tree.
[@LeVeque2007] LeVeque, R.J. (2007). Finite Difference Methods for Ordinary and Partial Differential Equations. SIAM. — Convergence and stability of forward Euler on a linear decay ODE.
[@Roache2002] Roache, P.J. (2002). Code verification by the Method of Manufactured Solutions. J. Fluids Eng. — The method the order claim above is measured with.
Verification Evidence#
Benchmark:
MADD-VER-012— observed temporal order of accuracy by the Method of Manufactured Solutions. A manufactured arterial pressure history is injected throughbackpressure, which enters the outflow linearly, so the downstream pressure that makes the trajectory exact is available in closed form. Over a 200/400/800/1600 step ladder across one second of cardiac cycles, in float64, the observed order over the finest pair is 1.000 against the declared 1.0. The ladder stops at 1600 steps because MADD-ANO-013 turns it over below about \(6 \times 10^{-6}\) relative error, two orders of magnitude finer than the \(1.9 \times 10^{-3}\) this ladder reaches.Test file:
tests/verification/test_mms_order_ode_nodes.pyAnomalies:
MADD-ANO-012andMADD-ANO-013, both pinned as strict xfails in the same file.
Changelog#
Version |
Date |
Change |
|---|---|---|
1.0.0 |
2025-03-01 |
Initial implementation |
1.0.0 |
2026-09-20 |
Declared order of accuracy added and measured (MADD-VER-012); MADD-ANO-012 and MADD-ANO-013 recorded |