This example requires external dependencies and cannot be run in the browser.

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).

Python
Loading...
/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.

Python
Loading...
Python
Loading...
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)
Python
Loading...
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)
Python
Loading...
Output

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.

Python
Loading...
Python
Loading...
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)
Python
Loading...
Output

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 dt reduces ZOH error at the cost of more PyBaMM step() calls.
  • The external thermal loop extends naturally to multi-cell pack models.