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)... 10:55:19 - INFO - LOGGING (log: True) 10:55:19 - INFO - BLOCKS (total: 4, dynamic: 1, static: 3, eventful: 0) 10:55:19 - INFO - GRAPH (nodes: 4, edges: 5, alg. depth: 2, loop depth: 0, runtime: 0.048ms) 10:55:19 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 10:55:31 - INFO - -------------------- 1% | 11.8s<18:49 | 0.16 it/s 10:55:44 - INFO - -------------------- 2% | 25.0s<14:09 | 0.16 it/s 10:55:49 - INFO - -------------------- 4% | 30.0s<09:44 | 0.17 it/s 10:55:53 - INFO - #------------------- 6% | 33.7s<05:36 | 0.20 it/s 10:55:59 - INFO - #------------------- 9% | 39.8s<04:25 | 0.19 it/s 10:56:06 - INFO - ##------------------ 13% | 46.8s<03:19 | 0.18 it/s 10:56:10 - INFO - ####---------------- 20% | 50.4s<01:31 | 0.21 it/s 10:56:15 - INFO - ######-------------- 32% | 56.0s<53.3s | 0.20 it/s 10:56:21 - INFO - ###########--------- 56% | 01:01<19.1s | 0.20 it/s 10:56:27 - INFO - #################--- 88% | 01:07<3.9s | 0.18 it/s 10:56:34 - INFO - #################### 100% | 01:14<--:-- | 0.17 it/s 10:56:34 - INFO - FINISHED -> TRANSIENT (total steps: 13, successful: 13, runtime: 74543.22 ms)
Running DFN (co-simulation)... 10:56:35 - INFO - LOGGING (log: True) 10:56:35 - INFO - BLOCKS (total: 4, dynamic: 0, static: 4, eventful: 1) 10:56:35 - INFO - GRAPH (nodes: 4, edges: 5, alg. depth: 2, loop depth: 0, runtime: 0.049ms) 10:56:35 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 10:56:37 - INFO - -------------------- 1% | 1.8s<01:24 | 2.1 it/s 10:56:38 - INFO - #------------------- 5% | 2.8s<22.4s | 7.6 it/s 10:56:39 - INFO - ##------------------ 11% | 4.0s<22.7s | 7.0 it/s 10:56:40 - INFO - ##------------------ 14% | 5.1s<18.8s | 8.2 it/s 10:56:41 - INFO - ###----------------- 17% | 6.2s<29.9s | 5.0 it/s 10:56:42 - INFO - ###----------------- 19% | 7.3s<35.8s | 4.1 it/s 10:56:43 - INFO - ####---------------- 20% | 7.5s<35.3s | 4.1 it/s 10:56:44 - INFO - ####---------------- 23% | 8.6s<23.7s | 5.8 it/s 10:56:45 - INFO - #####--------------- 27% | 9.7s<22.8s | 5.7 it/s 10:56:46 - INFO - ######-------------- 31% | 10.9s<20.7s | 6.0 it/s 10:56:47 - INFO - ######-------------- 33% | 12.0s<24.2s | 4.9 it/s 10:56:48 - INFO - #######------------- 37% | 13.1s<20.3s | 5.6 it/s 10:56:49 - INFO - ########------------ 40% | 13.9s<19.2s | 5.6 it/s 10:56:50 - INFO - ########------------ 43% | 15.0s<18.0s | 5.7 it/s 10:56:51 - INFO - #########----------- 46% | 16.1s<17.4s | 5.5 it/s 10:56:52 - INFO - #########----------- 48% | 17.1s<21.9s | 4.2 it/s 10:56:53 - INFO - ##########---------- 51% | 18.3s<19.8s | 4.4 it/s 10:56:55 - INFO - ###########--------- 55% | 19.5s<15.8s | 5.1 it/s 10:56:56 - INFO - ###########--------- 57% | 20.6s<16.7s | 4.5 it/s 10:56:57 - INFO - ############-------- 60% | 21.7s<16.0s | 4.4 it/s 10:56:58 - INFO - ############-------- 63% | 22.9s<15.4s | 4.3 it/s 10:56:59 - INFO - #############------- 66% | 24.1s<14.4s | 4.2 it/s 10:57:00 - INFO - #############------- 68% | 25.3s<12.5s | 4.5 it/s 10:57:01 - INFO - ##############------ 71% | 26.4s<11.6s | 4.4 it/s 10:57:03 - INFO - ##############------ 74% | 27.5s<10.2s | 4.5 it/s 10:57:04 - INFO - ###############----- 77% | 28.7s<10.0s | 4.1 it/s 10:57:05 - INFO - ################---- 80% | 29.8s<8.0s | 4.5 it/s 10:57:06 - INFO - ################---- 82% | 30.9s<6.8s | 4.5 it/s 10:57:07 - INFO - #################--- 85% | 31.9s<6.7s | 4.1 it/s 10:57:08 - INFO - #################--- 88% | 33.1s<4.1s | 5.1 it/s 10:57:09 - INFO - ##################-- 91% | 34.2s<2.6s | 5.8 it/s 10:57:10 - INFO - ###################- 95% | 35.3s<1.6s | 5.6 it/s 10:57:11 - INFO - ###################- 98% | 36.4s<0.6s | 5.4 it/s 10:57:12 - INFO - #################### 100% | 37.0s<--:-- | 5.4 it/s 10:57:12 - INFO - FINISHED -> TRANSIENT (total steps: 180, successful: 180, runtime: 36961.13 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)... 10:57:14 - INFO - LOGGING (log: True) 10:57:14 - INFO - BLOCKS (total: 5, dynamic: 1, static: 4, eventful: 1) 10:57:14 - INFO - GRAPH (nodes: 5, edges: 7, alg. depth: 2, loop depth: 0, runtime: 0.133ms) 10:57:14 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 10:57:14 - INFO - -------------------- 1% | 0.5s<28.5s | 2.1 it/s 10:57:15 - INFO - ####---------------- 20% | 1.3s<2.9s | 16.6 it/s 10:57:16 - INFO - ########------------ 40% | 2.0s<1.7s | 21.8 it/s 10:57:16 - INFO - ############-------- 61% | 2.8s<1.6s | 14.2 it/s 10:57:17 - INFO - ################---- 80% | 3.8s<0.8s | 15.1 it/s 10:57:19 - INFO - ###################- 98% | 4.9s<0.1s | 9.2 it/s 10:57:19 - INFO - #################### 100% | 5.0s<--:-- | 8.9 it/s 10:57:19 - INFO - FINISHED -> TRANSIENT (total steps: 60, successful: 60, runtime: 5020.01 ms) Running DFN co-sim with external thermal (dt = 5 s)... 10:57:20 - INFO - LOGGING (log: True) 10:57:20 - INFO - BLOCKS (total: 5, dynamic: 1, static: 4, eventful: 1) 10:57:20 - INFO - GRAPH (nodes: 5, edges: 7, alg. depth: 2, loop depth: 0, runtime: 0.135ms) 10:57:20 - INFO - STARTING -> TRANSIENT (Duration: 1800.00s) 10:57:21 - INFO - -------------------- 1% | 0.8s<40.2s | 8.8 it/s 10:57:22 - INFO - -------------------- 3% | 1.8s<40.6s | 8.6 it/s 10:57:23 - INFO - #------------------- 7% | 2.8s<26.3s | 12.7 it/s 10:57:24 - INFO - ##------------------ 10% | 3.9s<28.1s | 11.4 it/s 10:57:25 - INFO - ##------------------ 13% | 5.0s<29.9s | 10.4 it/s 10:57:26 - INFO - ###----------------- 16% | 6.0s<26.3s | 11.4 it/s 10:57:27 - INFO - ####---------------- 20% | 7.0s<26.5s | 10.8 it/s 10:57:28 - INFO - ####---------------- 23% | 8.1s<25.8s | 10.7 it/s 10:57:30 - INFO - #####--------------- 26% | 9.2s<26.2s | 10.2 it/s 10:57:31 - INFO - #####--------------- 28% | 10.2s<30.1s | 8.5 it/s 10:57:32 - INFO - ######-------------- 31% | 11.3s<26.5s | 9.4 it/s 10:57:33 - INFO - ######-------------- 34% | 12.3s<17.4s | 13.5 it/s 10:57:34 - INFO - #######------------- 39% | 13.3s<16.2s | 13.4 it/s 10:57:34 - INFO - ########------------ 40% | 13.4s<12.9s | 16.7 it/s 10:57:35 - INFO - ########------------ 44% | 14.4s<9.2s | 21.7 it/s 10:57:36 - INFO - #########----------- 49% | 15.5s<13.4s | 13.6 it/s 10:57:37 - INFO - ##########---------- 53% | 16.5s<12.9s | 13.0 it/s 10:57:38 - INFO - ###########--------- 57% | 17.5s<11.7s | 13.1 it/s 10:57:39 - INFO - ############-------- 60% | 18.4s<10.9s | 13.1 it/s 10:57:40 - INFO - ############-------- 64% | 19.4s<9.8s | 13.2 it/s 10:57:41 - INFO - #############------- 68% | 20.5s<7.1s | 16.1 it/s 10:57:42 - INFO - ##############------ 71% | 21.6s<10.2s | 10.0 it/s 10:57:43 - INFO - ##############------ 74% | 22.7s<9.1s | 10.1 it/s 10:57:44 - INFO - ###############----- 77% | 23.7s<8.2s | 10.0 it/s 10:57:45 - INFO - ################---- 80% | 24.7s<7.2s | 10.0 it/s 10:57:46 - INFO - ################---- 83% | 25.8s<6.1s | 10.1 it/s 10:57:47 - INFO - #################--- 85% | 26.8s<5.0s | 10.3 it/s 10:57:48 - INFO - #################--- 89% | 27.9s<3.3s | 11.8 it/s 10:57:49 - INFO - ##################-- 92% | 29.0s<2.7s | 10.3 it/s 10:57:50 - INFO - ###################- 96% | 30.1s<1.2s | 11.9 it/s 10:57:51 - INFO - ###################- 98% | 31.1s<0.5s | 9.1 it/s 10:57:52 - INFO - #################### 100% | 31.6s<--:-- | 9.6 it/s 10:57:52 - INFO - FINISHED -> TRANSIENT (total steps: 360, successful: 360, runtime: 31567.46 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.