Skip to main content

Solver Comparison

SolverBackendODEDAESensitivityNotes
CasadiSolverCasADi / SUNDIALSYesYesYesGeneral-purpose; safe mode handles events
IDAKLUSolverSUNDIALS IDA + KLUYesYesYesFastest for most problems; recommended default
ScipySolverSciPy solve_ivpYesNoNoSimple; no DAE support
JaxSolverJAXYesBDF onlyNoGPU/TPU capable; requires Python ≥ 3.11
AlgebraicSolverSciPy root-findingNoAlgebraic onlyNoFor purely algebraic (steady-state) problems
CompositeSolverMultiple backendsYesYesVariesTries multiple solvers until one succeeds
CasadiAlgebraicSolverCasADiNoAlgebraic onlyNoCasADi-based algebraic solver

Choosing a Solver

  • Most lithium-ion models (SPM, SPMe, DFN) include algebraic equations (DAEs). Use IDAKLUSolver (default in pybamm.Simulation) for best performance.
  • Drive-cycle simulations with no voltage events: use CasadiSolver(mode="fast") or IDAKLUSolver.
  • Simple ODE-only models (equivalent circuit, 0D): ScipySolver works well and has minimal dependencies.
  • Batch parameter sweeps on GPU/TPU: JaxSolver with method="RK45" enables JIT compilation.

BaseSolver Common Interface

All solvers inherit from pybamm.BaseSolver and share the following constructor parameters and methods.

Constructor Parameters

method
str
default:"None"
Integration method name. Meaning is solver-specific.
rtol
float
default:"1e-6"
Relative tolerance.
atol
float
default:"1e-6"
Absolute tolerance.
root_method
str | algebraic solver
default:"None"
Method used to compute consistent initial conditions for DAE problems. Options include "casadi", "lm", "hybr", or a PyBaMM algebraic solver class.
root_tol
float
default:"1e-6"
Tolerance for the initial-condition root-finding step.
extrap_tol
float
default:"-1e-10"
Tolerance for detecting extrapolation beyond the solved time span.
on_extrapolation
str
default:"\"warn\""
Behaviour when extrapolation is detected. One of "warn", "error", or "ignore".
output_variables
list[str]
default:"[]"
If specified, only these variables are computed and returned (reduces memory usage).

solve

solver.solve(model, t_eval, inputs=None, initial_conditions=None, ...)
Solve the model over the time span t_eval and return a pybamm.Solution object.

step

solver.step(old_solution, model, dt, npts=2, inputs=None, ...)
Advance the solution by a single time step dt. Useful for online / real-time simulation.

Setting Tolerances

import pybamm

# Tighter tolerances for high-accuracy simulations
solver = pybamm.IDAKLUSolver(rtol=1e-8, atol=1e-8)

# Looser tolerances for fast exploratory runs
solver = pybamm.CasadiSolver(rtol=1e-3, atol=1e-6)

sim = pybamm.Simulation(
    pybamm.lithium_ion.DFN(),
    solver=solver,
    parameter_values=pybamm.ParameterValues("Chen2020"),
)
sol = sim.solve([0, 3600])
For production simulations with lithium-ion physics models, IDAKLUSolver is the recommended starting point. It handles both ODE and DAE systems, supports sparse KLU factorisation, and exposes a rich options dict for fine-tuning.

Build docs developers (and LLMs) love