Custom variables let you define new quantities that are computed from the model’s built-in state variables and parameters. They are evaluated lazily when you request them in simulation results, so they don’t slow down the simulation itself.
Custom variables are stored on the model and are available to all simulations and optimizations that use that model.
Variables vs custom variables
Battery models solve for dozens of built-in variables — quantities like voltage, current, and temperature that the solver computes at each time step. Custom variables are expressions you define that combine these built-in variables with parameters and math.
| Variable | Custom variable |
|---|
| Source | Solved by the PyBaMM model | Defined by you |
| Examples | Voltage [V], Current [A], Temperature [K] | Temperature [degC], Anode potential [V] |
| Referenced via | CoupledVariable("name") | Also CoupledVariable("name") once defined |
| Editable | No | Append-only — cannot edit or delete after creation |
Custom variables are append-only because their evaluated values are stored in simulation result files. Changing or removing a variable after simulations have run would invalidate those results.
All system models (SPM, SPMe, DFN, their composite variants, LumpedSPMR, LumpedSPMeR, and both full-cell and half-cell ECM) come with the following custom variables already defined:
| Variable | Description |
|---|
Anode potential [V] | Negative electrode potential, derived from the appropriate internal model variable for each model type |
Cathode potential [V] | Positive electrode potential, derived from the appropriate internal model variable for each model type |
Temperature [degC] | Cell temperature converted from Kelvin to Celsius |
These are available in simulation results immediately — you don’t need to add them yourself when using system models.
If you create a new custom model by cloning a system model, the custom variables carry over automatically. If you create a model from scratch, you need to add any custom variables you want manually.
Electrode potential expressions by model type
The expression used for electrode potentials depends on the model type:
| Model type | Anode potential expression | Cathode potential expression |
|---|
| Full-cell (SPM, SPMe, DFN) | CoupledVariable("Negative electrode surface potential difference at separator interface [V]") | CoupledVariable("Positive electrode surface potential difference at separator interface [V]") |
| Half-cell (SPM, SPMe, DFN) | Scalar(0) | CoupledVariable("Voltage [V]") |
| Full-cell ECM | CoupledVariable("Anode potential [V]") | CoupledVariable("Cathode potential [V]") |
| Half-cell ECM | Scalar(0) | CoupledVariable("Voltage [V]") |
| LumpedSPMR, LumpedSPMeR | CoupledVariable("X-averaged negative electrode surface potential difference [V]") | CoupledVariable("X-averaged positive electrode surface potential difference [V]") |
The full-cell ECM is circuit-based and does not solve for individual electrode potentials directly. Instead, it reconstructs them by splitting the total overpotential between the anode and cathode using the Anode overpotential fraction parameter. See ECM in Models for details and use cases such as reproducing BioLogic EWE/ECE control. The half-cell ECM treats the working electrode as the cathode (anode potential = 0 V), so the cell voltage equals the cathode potential.
Expression Syntax
Custom variable expressions use PyBaMM building blocks:
Types
| Type | Purpose | Example |
|---|
CoupledVariable("name") | Reference a model variable or another custom variable | CoupledVariable("Voltage [V]") |
Parameter("name") | Reference or create a model parameter | Parameter("C-rate") |
| Numbers | Constant values — use plain numbers in expressions | 273.15, 3600 |
Math Operations
Standard arithmetic: +, -, *, /, ** (power)
Functions
exp(), log(), sqrt(), tanh(), cosh(), sinh()
Examples
Temperature conversion (Kelvin to Celsius):
CoupledVariable("Volume-averaged cell temperature [K]") - 273.15
Electrode potential from internal model variable:
CoupledVariable("Negative electrode surface potential difference at separator interface [V]")
Scaled parameter for use in expressions:
Parameter("C-rate") * 3600
Power output (combining two model variables):
CoupledVariable("Voltage [V]") * CoupledVariable("Current [A]")
Using math functions:
exp(CoupledVariable("Overpotential [V]") / 0.026)
Evaluation
Custom variables are evaluated lazily — only when you view them in simulation results. When you select a custom variable for plotting or display, the system submits an evaluation job in the background. A loading indicator shows progress while the evaluation runs.
If an evaluation fails (for example, due to a transient error), the plot displays an error state instead of continuing to load. Click the Retry button that appears to resubmit the evaluation job.
Validation
When you add a custom variable, the system validates your expression:
- Valid syntax — the expression must parse as a valid PyBaMM expression
- References exist — all
CoupledVariable references must point to existing model variables or other custom variables you’ve already defined
- No circular references — custom variable A cannot reference B if B references A (directly or indirectly)
- Parameter awareness — if you use
Parameter("name"), the system tells you whether it matches an existing model parameter or creates a new one. If the name doesn’t match exactly, it suggests similar existing parameters
Limitations
- Append-only — custom variables cannot be edited or deleted after creation
- Not available on uploaded models — only built-in PyBaMM model types support custom variables
- Cannot modify system models — clone a system model first, then add custom variables to the clone