Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 14 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,47 +57,36 @@ Two decisions determine the right block: **thermal ownership** and **integration

| Block | Thermal | Strategy | Use when |
|---|---|---|---|
| `CellElectrothermal` | PyBaMM (internal) | Monolithic ODE | Single cell, coupled electro-thermal, ODE model |
| `CellElectrical` + `LumpedThermal` | PathSim (external) | Monolithic ODE | Pack-level, custom cooling, ODE model |
| `CellCoSimElectrothermal` | PyBaMM (internal) | Co-simulation | DAE models (DFN, lead_acid.Full), mixed solvers |
| `CellCoSimElectrical` + `LumpedThermal` | PathSim (external) | Co-simulation | DAE models with external thermal network |
| `CellElectrothermal` | PyBaMM (internal) | Monolithic | Single cell, coupled electro-thermal |
| `CellElectrical` + `LumpedThermal` | PathSim (external) | Monolithic | Pack-level, custom cooling |
| `CellCoSimElectrothermal` | PyBaMM (internal) | Co-simulation | PyBaMM's own solvers, mixed solvers |
| `CellCoSimElectrical` + `LumpedThermal` | PathSim (external) | Co-simulation | PyBaMM's own solvers with external thermal network |

`LumpedThermal` is a single-node thermal block (`mass`, `Cp`, `UA`, `T0`) that receives `Q_dot` from a `CellElectrical` block and feeds back cell temperature.

## PyBaMM model compatibility
## PyBaMM models

Thermal sub-model and heat-source options are injected automatically — pass the bare model class with no `options=`.
All blocks work with the standard PyBaMM battery models, e.g. `lithium_ion.SPM`, `SPMe`, `DFN`, `lead_acid.LOQS`, `lead_acid.Full` or `equivalent_circuit.Thevenin`. The model must provide the variables the block outputs (terminal voltage, heat generation and, for the electrothermal blocks, cell temperature); some minimal models such as `sodium_ion.BasicDFN` do not. Thermal sub-model and heat-source options are injected automatically — pass the bare model class with no `options=`.

| PyBaMM model | Default parameter set | `CellElectrical` | `CellElectrothermal` | `CellCoSimElectrical` | `CellCoSimElectrothermal` |
|---|---|:---:|:---:|:---:|:---:|
| `lithium_ion.SPM` | `Chen2020` | ✅ | ✅ | ✅ | ✅ |
| `lithium_ion.SPMe` | `Chen2020` | ✅ | ✅ | ✅ | ✅ |
| `lithium_ion.DFN` | `Chen2020` | ❌ DAE | ❌ DAE | ✅ | ✅ |
| `lead_acid.LOQS` | `Sulzer2019` | ✅ ¹ | ✅ ¹ | ✅ ² | ✅ ² |
| `lead_acid.Full` | `Sulzer2019` | ❌ DAE | ❌ DAE | ✅ | ✅ |
| `equivalent_circuit.Thevenin` | `ECM_Example` | ✅ | ✅ | ✅ ³ | ✅ ³ |
Known limitations of the co-simulation blocks:

¹ Not on PyBaMM 26.7 — there `LOQS` is a DAE, use a `CellCoSim*` block instead. It is an ODE again from 26.8 on.

² PyBaMM < 26.7 only — pass `pybamm_solver=pybamm.CasadiSolver(mode="safe")`; the default `IDAKLUSolver` errors on `LOQS`. Fixed in 26.7.

³ `initial_soc=1.0` fails because PyBaMM requires event values to be strictly positive at `t=0`; the "Maximum SoC" event is zero exactly at full charge. Any value below 1.0 (e.g. `initial_soc=0.99`) works.
- `lead_acid.LOQS` on PyBaMM < 26.7: pass `pybamm_solver=pybamm.CasadiSolver(mode="safe")`; the default `IDAKLUSolver` errors on `LOQS`.
- `equivalent_circuit.Thevenin`: `initial_soc=1.0` fails because PyBaMM requires event values to be strictly positive at `t=0`; use e.g. `initial_soc=0.99`.

```python
import pybamm
from pathsim_batt import CellElectrothermal, CellCoSimElectrical
from pathsim_batt import CellElectrical, CellElectrothermal

# Custom chemistry / parameter set
cell = CellElectrothermal(
model=pybamm.lithium_ion.SPMe(),
parameter_values=pybamm.ParameterValues("Mohtat2020"),
)

# Lead-acid via co-simulation (DAE model)
cell = CellCoSimElectrical(
model=pybamm.lead_acid.Full(),
parameter_values=pybamm.ParameterValues("Sulzer2019"),
dt=1.0,
# High-fidelity model
cell = CellElectrical(
model=pybamm.lithium_ion.DFN(),
parameter_values=pybamm.ParameterValues("Chen2020"),
)

# Equivalent circuit model
Expand Down
38 changes: 19 additions & 19 deletions docs/source/examples/03_dfn_cosimulation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"source": [
"# High-Fidelity DFN Simulation via Co-Simulation\n",
"\n",
"The **Doyle–Fuller–Newman (DFN)** model produces a DAE system after discretisation\n",
"and cannot be used with the monolithic ODE blocks. The co-simulation blocks\n",
"(`CellCoSimElectrothermal`, `CellCoSimElectrical`) let PyBaMM step the DAE internally\n",
"while PathSim receives zero-order-held outputs between macro-steps.\n"
"The **Doyle–Fuller–Newman (DFN)** model can run in every cell block. This notebook\n",
"uses the co-simulation blocks (`CellCoSimElectrothermal`, `CellCoSimElectrical`), which\n",
"let PyBaMM's own solver advance the model while PathSim receives zero-order-held outputs\n",
"between macro-steps.\n"
]
},
{
Expand All @@ -20,12 +20,12 @@
"source": [
"## Why Co-Simulation?\n",
"\n",
"The DFN model resolves spatial gradients in both the solid and electrolyte phases.\n",
"The phase-potential equations are **algebraic**, so after spatial discretisation the\n",
"DFN becomes a DAE — incompatible with `CellElectrical` / `CellElectrothermal`.\n",
"\n",
"The co-simulation blocks call `pybamm.Simulation.step()` internally on a fixed macro-step\n",
"`dt` and expose zero-order-held outputs to PathSim. This supports any PyBaMM model.\n",
"The DFN model resolves spatial gradients in both the solid and electrolyte phases, which\n",
"makes it much larger and slower to integrate than SPMe. `CellElectrical` /\n",
"`CellElectrothermal` integrate it with PathSim's own solvers; the co-simulation blocks\n",
"instead call `pybamm.Simulation.step()` internally on a fixed macro-step `dt` and expose\n",
"zero-order-held outputs to PathSim. This hands the work to PyBaMM's specialised solver at\n",
"the cost of a coarser coupling.\n",
"\n",
"> Brosa Planella et al., [arXiv:2203.16091](https://arxiv.org/abs/2203.16091) (2022).\n"
]
Expand Down Expand Up @@ -59,7 +59,7 @@
"source": [
"## Part 1: SPMe vs DFN with Built-in Thermal\n",
"\n",
"Both models use PyBaMM's lumped thermal sub-model. SPMe runs as a monolithic ODE in PathSim;\n",
"Both models use PyBaMM's lumped thermal sub-model. SPMe is integrated by PathSim;\n",
"DFN runs via co-simulation with a 10 s macro-step.\n"
]
},
Expand Down Expand Up @@ -245,14 +245,14 @@
"source": [
"## Summary\n",
"\n",
"| Block | Model | Thermal |\n",
"|-------|-------|---------|\n",
"| `CellElectrothermal` | SPMe / SPM (ODE) | Built-in |\n",
"| `CellCoSimElectrothermal` | Any incl. DFN (DAE) | Built-in |\n",
"| `CellElectrical` | SPMe / SPM (ODE) | External (`LumpedThermal`) |\n",
"| `CellCoSimElectrical` | Any incl. DFN (DAE) | External (`LumpedThermal`) |\n",
"| Block | Integrated by | Thermal |\n",
"|-------|---------------|---------|\n",
"| `CellElectrothermal` | PathSim | Built-in |\n",
"| `CellCoSimElectrothermal` | PyBaMM | Built-in |\n",
"| `CellElectrical` | PathSim | External (`LumpedThermal`) |\n",
"| `CellCoSimElectrical` | PyBaMM | External (`LumpedThermal`) |\n",
"\n",
"- DFN resolves spatial gradients in both phases but produces a DAE — use the co-simulation blocks.\n",
"- All four blocks accept DFN; the co-simulation blocks let PyBaMM's own solver do the integration.\n",
"- A smaller macro-step `dt` reduces ZOH error at the cost of more PyBaMM `step()` calls.\n",
"- The external thermal loop extends naturally to multi-cell pack models.\n"
]
Expand All @@ -279,4 +279,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ classifiers = [
"Topic :: Scientific/Engineering",
]
dependencies = [
"pathsim>=0.22",
"pathsim>=0.27.1",
# PyBaMM ships native code that can't be installed in Pyodide. The
# marker resolves to a normal eager install on every real platform and
# is skipped on Emscripten so the pure-Python parts of the toolbox
Expand Down
Loading
Loading