High-Fidelity DFN Simulation via Co-Simulation
The Doyle–Fuller–Newman (DFN) model produces a DAE system after discretisation
and cannot be used with the monolithic ODE blocks. The co-simulation blocks
(CellCoSimElectrothermal, CellCoSimElectrical) let PyBaMM step the DAE internally
while PathSim receives zero-order-held outputs between macro-steps.
Why Co-Simulation?
The DFN model resolves spatial gradients in both the solid and electrolyte phases.
The phase-potential equations are algebraic, so after spatial discretisation the
DFN becomes a DAE — incompatible with CellElectrical / CellElectrothermal.
The co-simulation blocks call pybamm.Simulation.step() internally on a fixed macro-step
dt and expose zero-order-held outputs to PathSim. This supports any PyBaMM model.
Brosa Planella et al., arXiv:2203.16091 (2022).
/opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html from .autonotebook import tqdm as notebook_tqdm
Part 1: SPMe vs DFN with Built-in Thermal
Both models use PyBaMM's lumped thermal sub-model. SPMe runs as a monolithic ODE in PathSim; DFN runs via co-simulation with a 10 s macro-step.
Running SPMe (monolithic)... 18:22:06 - INFO - LOGGING (log: True) 18:22:06 - INFO - BLOCKS (total: 4, dynamic: 1, static: 3, eventful: 0) 18:22:06 - INFO - GRAPH (nodes: 4, edges: 5, alg. depth: 2, loop depth: 0, runtime: 0.050ms) 18:22:06 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 18:22:22 - INFO - -------------------- 1% | 15.9s<25:34 | 0.12 it/s 18:22:35 - INFO - -------------------- 2% | 29.1s<15:48 | 0.14 it/s 18:22:40 - INFO - -------------------- 4% | 34.3s<10:25 | 0.15 it/s 18:22:47 - INFO - #------------------- 6% | 41.6s<08:12 | 0.15 it/s 18:22:55 - INFO - #------------------- 9% | 48.8s<05:52 | 0.15 it/s 18:23:02 - INFO - ##------------------ 13% | 55.8s<03:52 | 0.15 it/s 18:23:08 - INFO - ####---------------- 20% | 01:02<02:20 | 0.15 it/s 18:23:11 - INFO - ######-------------- 32% | 01:05<37.5s | 0.22 it/s 18:23:18 - INFO - ###########--------- 56% | 01:11<18.4s | 0.20 it/s 18:23:26 - INFO - #################--- 88% | 01:20<4.2s | 0.17 it/s 18:23:32 - INFO - #################### 100% | 01:26<--:-- | 0.17 it/s 18:23:32 - INFO - FINISHED -> TRANSIENT (total steps: 13, successful: 13, runtime: 86365.31 ms)
Running DFN (co-simulation)... 18:23:34 - INFO - LOGGING (log: True) 18:23:34 - INFO - BLOCKS (total: 4, dynamic: 0, static: 4, eventful: 1) 18:23:34 - INFO - GRAPH (nodes: 4, edges: 5, alg. depth: 2, loop depth: 0, runtime: 0.047ms) 18:23:34 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 18:23:36 - INFO - -------------------- 1% | 2.0s<01:58 | 1.5 it/s 18:23:37 - INFO - -------------------- 3% | 3.1s<40.9s | 4.2 it/s 18:23:38 - INFO - #------------------- 7% | 4.2s<30.2s | 5.5 it/s 18:23:39 - INFO - ##------------------ 10% | 5.2s<28.1s | 5.7 it/s 18:23:40 - INFO - ##------------------ 13% | 6.4s<32.1s | 4.8 it/s 18:23:41 - INFO - ###----------------- 16% | 7.5s<37.7s | 4.0 it/s 18:23:42 - INFO - ###----------------- 18% | 8.6s<31.5s | 4.6 it/s 18:23:43 - INFO - ####---------------- 20% | 9.1s<31.2s | 4.6 it/s 18:23:44 - INFO - ####---------------- 22% | 10.1s<29.6s | 4.7 it/s 18:23:45 - INFO - #####--------------- 25% | 11.3s<32.8s | 4.1 it/s 18:23:46 - INFO - #####--------------- 28% | 12.5s<24.1s | 5.3 it/s 18:23:47 - INFO - ######-------------- 32% | 13.5s<12.3s | 9.9 it/s 18:23:49 - INFO - #######------------- 38% | 14.7s<15.2s | 7.3 it/s 18:23:49 - INFO - ########------------ 40% | 15.2s<17.5s | 6.2 it/s 18:23:50 - INFO - ########------------ 43% | 16.3s<17.8s | 5.7 it/s 18:23:51 - INFO - #########----------- 46% | 17.4s<17.0s | 5.6 it/s 18:23:52 - INFO - ##########---------- 50% | 18.5s<16.3s | 5.5 it/s 18:23:53 - INFO - ##########---------- 53% | 19.6s<16.1s | 5.2 it/s 18:23:55 - INFO - ###########--------- 56% | 20.8s<17.6s | 4.5 it/s 18:23:56 - INFO - ###########--------- 58% | 21.9s<16.4s | 4.5 it/s 18:23:56 - INFO - ############-------- 60% | 22.6s<16.3s | 4.3 it/s 18:23:58 - INFO - ############-------- 63% | 23.8s<15.8s | 4.2 it/s 18:23:59 - INFO - #############------- 66% | 24.9s<13.3s | 4.6 it/s 18:24:00 - INFO - #############------- 68% | 26.1s<13.7s | 4.1 it/s 18:24:01 - INFO - ##############------ 71% | 27.3s<12.6s | 4.0 it/s 18:24:02 - INFO - ##############------ 74% | 28.3s<9.7s | 4.7 it/s 18:24:03 - INFO - ###############----- 77% | 29.4s<7.6s | 5.3 it/s 18:24:04 - INFO - ################---- 80% | 30.4s<8.1s | 4.5 it/s 18:24:05 - INFO - ################---- 83% | 31.5s<5.5s | 5.4 it/s 18:24:06 - INFO - #################--- 86% | 32.6s<4.4s | 5.5 it/s 18:24:08 - INFO - ##################-- 90% | 33.7s<3.3s | 5.5 it/s 18:24:09 - INFO - ##################-- 93% | 34.9s<1.6s | 6.8 it/s 18:24:10 - INFO - ###################- 97% | 35.9s<0.9s | 5.5 it/s 18:24:11 - INFO - #################### 100% | 36.9s<--:-- | 5.2 it/s 18:24:11 - INFO - FINISHED -> TRANSIENT (total steps: 180, successful: 180, runtime: 36890.82 ms)
Part 2: DFN with External Thermal Model
Same feedback topology as notebook 02, but with CellCoSimElectrical instead of
CellElectrical. We compare two macro-step sizes to illustrate ZOH approximation error.
Running DFN co-sim with external thermal (dt = 30 s)... 18:24:13 - INFO - LOGGING (log: True) 18:24:13 - INFO - BLOCKS (total: 5, dynamic: 1, static: 4, eventful: 1) 18:24:13 - INFO - GRAPH (nodes: 5, edges: 7, alg. depth: 2, loop depth: 0, runtime: 0.137ms) 18:24:13 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 18:24:13 - INFO - -------------------- 1% | 0.7s<42.7s | 1.4 it/s 18:24:14 - INFO - ####---------------- 20% | 1.7s<4.1s | 11.6 it/s 18:24:15 - INFO - #######------------- 38% | 2.7s<3.5s | 10.5 it/s 18:24:15 - INFO - ########------------ 40% | 2.9s<3.6s | 9.9 it/s 18:24:17 - INFO - ###########--------- 58% | 3.9s<2.3s | 10.6 it/s 18:24:17 - INFO - ############-------- 61% | 4.1s<2.2s | 10.3 it/s 18:24:18 - INFO - ###############----- 76% | 5.2s<1.6s | 8.9 it/s 18:24:18 - INFO - ################---- 80% | 5.4s<1.3s | 9.1 it/s 18:24:19 - INFO - ###################- 98% | 6.4s<0.1s | 12.9 it/s 18:24:19 - INFO - #################### 100% | 6.5s<--:-- | 13.2 it/s 18:24:19 - INFO - FINISHED -> TRANSIENT (total steps: 60, successful: 60, runtime: 6493.98 ms) Running DFN co-sim with external thermal (dt = 5 s)... 18:24:20 - INFO - LOGGING (log: True) 18:24:20 - INFO - BLOCKS (total: 5, dynamic: 1, static: 4, eventful: 1) 18:24:20 - INFO - GRAPH (nodes: 5, edges: 7, alg. depth: 2, loop depth: 0, runtime: 0.125ms) 18:24:20 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 18:24:21 - INFO - -------------------- 1% | 0.9s<47.1s | 7.6 it/s 18:24:22 - INFO - -------------------- 4% | 2.0s<34.3s | 10.1 it/s 18:24:23 - INFO - #------------------- 7% | 3.0s<31.6s | 10.6 it/s 18:24:24 - INFO - ##------------------ 10% | 4.0s<24.8s | 13.0 it/s 18:24:25 - INFO - ##------------------ 13% | 5.0s<27.7s | 11.2 it/s 18:24:26 - INFO - ###----------------- 16% | 6.0s<23.2s | 12.9 it/s 18:24:27 - INFO - ####---------------- 20% | 6.9s<21.8s | 13.2 it/s 18:24:28 - INFO - ####---------------- 23% | 7.9s<20.9s | 13.1 it/s 18:24:29 - INFO - #####--------------- 27% | 9.0s<19.6s | 13.2 it/s 18:24:30 - INFO - ######-------------- 31% | 10.1s<18.4s | 13.4 it/s 18:24:31 - INFO - ######-------------- 34% | 11.1s<24.7s | 9.5 it/s 18:24:32 - INFO - #######------------- 37% | 12.1s<25.9s | 8.7 it/s 18:24:33 - INFO - #######------------- 39% | 13.1s<24.9s | 8.7 it/s 18:24:33 - INFO - ########------------ 40% | 13.2s<24.8s | 8.7 it/s 18:24:34 - INFO - ########------------ 43% | 14.3s<13.1s | 15.6 it/s 18:24:36 - INFO - #########----------- 46% | 15.4s<17.0s | 11.4 it/s 18:24:37 - INFO - #########----------- 49% | 16.4s<16.5s | 11.0 it/s 18:24:38 - INFO - ##########---------- 52% | 17.4s<14.3s | 11.9 it/s 18:24:39 - INFO - ###########--------- 56% | 18.5s<12.0s | 13.1 it/s 18:24:40 - INFO - ############-------- 60% | 19.5s<10.9s | 13.1 it/s 18:24:41 - INFO - ############-------- 64% | 20.6s<9.8s | 13.1 it/s 18:24:42 - INFO - #############------- 69% | 21.6s<4.6s | 23.8 it/s 18:24:43 - INFO - ##############------ 73% | 22.6s<7.4s | 12.9 it/s 18:24:44 - INFO - ###############----- 77% | 23.6s<6.3s | 13.0 it/s 18:24:45 - INFO - ################---- 80% | 24.4s<5.6s | 12.9 it/s 18:24:46 - INFO - ################---- 84% | 25.4s<2.6s | 22.2 it/s 18:24:47 - INFO - #################--- 88% | 26.5s<2.4s | 17.4 it/s 18:24:48 - INFO - ##################-- 92% | 27.5s<2.2s | 12.9 it/s 18:24:49 - INFO - ###################- 95% | 28.5s<1.1s | 13.1 it/s 18:24:50 - INFO - ###################- 99% | 29.5s<0.1s | 13.8 it/s 18:24:50 - INFO - #################### 100% | 29.6s<--:-- | 13.6 it/s 18:24:50 - INFO - FINISHED -> TRANSIENT (total steps: 360, successful: 360, runtime: 29575.02 ms)
Summary
| Block | Model | Thermal |
|---|---|---|
CellElectrothermal |
SPMe / SPM (ODE) | Built-in |
CellCoSimElectrothermal |
Any incl. DFN (DAE) | Built-in |
CellElectrical |
SPMe / SPM (ODE) | External (LumpedThermal) |
CellCoSimElectrical |
Any incl. DFN (DAE) | External (LumpedThermal) |
- DFN resolves spatial gradients in both phases but produces a DAE — use the co-simulation blocks.
- A smaller macro-step
dtreduces ZOH error at the cost of more PyBaMMstep()calls. - The external thermal loop extends naturally to multi-cell pack models.