## 1 Overview

### Introduction

With the battery modelling research community growing rapidly in the UK in the last few years [], it is essential to develop tools that facilitate cross-institutional collaboration. One such tool is battery modelling software that allows new research (e.g. new physics, numerical methods) to be employed with minimal effort by the rest of the community. Modelling software should also facilitate quantitative comparison of different models and numerical methods. To be reusable and extendable, the software should be both modular, so that new models and numerical methods can easily be added, and rigorously tested, in order to be robust to changes.

### Existing software

Currently, COMSOL [] is the modelling software most commonly utilised by the the battery modelling community, providing a simple graphical user interface (GUI) to implement and solve standard battery models. However, there are several drawbacks to COMSOL. Firstly, its prohibitively expensive licence fee is a barrier to collaboration and sharing of software. Secondly, it has limited flexibility for adaptation of existing battery models, or investigation of new numerical methods. Thirdly, as the implementation is performed through a GUI, programs cannot be directly scripted without additional software, which inhibits version control, unit testing and combination with other software (for example, for parameter estimation).

Several existing open-source battery modelling software packages provide an alternative option to COMSOL. Examples include DUALFOIL [], fastDFN [], LIONSIMBA [], and M-PET []. However, each of these packages is focused on the implementation of one specific battery model under a specific choice of operating conditions. As a result, these software packages lack the flexibility required to allow for easy implementation of reduced-order versions of a model or to include model extensions. This lack of flexibility considerably limits the reuse of such packages across different research projects.

### Overview of PyBaMM

PyBaMM (Python Battery Mathematical Modelling) is a tool for fast and flexible simulations of battery models. Our mission is to accelerate battery modelling research by providing an open-source framework for multi-institutional, interdisciplinary collaboration. PyBaMM offers improved collaboration and research impact in battery modelling by creating a modular framework through which either existing or new tools can be combined in order to solve continuum models for batteries. To achieve this, PyBaMM separates the models, discretisation and solver, giving ultimate flexibility to the end user, and provides a unified interface through which to incorporate new models, alternative spatial discretisations, or new time-stepping algorithms. Any such additions can then immediately be used with the existing suite of models already implemented, and comparisons can be made between different models, discretisations, or algorithms with variables such as hardware, software and implementation details held fixed. Similarly, additional physics can be incorporated into the existing models, enabled by the extensible “plug-and-play” submodel structure around which models are constructed. As a result, the need to start from scratch to study each new effect is removed, and the simultaneous study of a range of extensions to the standard battery models, for example by coupling together several degradation mechanisms, is readily achieved. A comprehensive suite of tests provides the robustness necessary to allow the continual addition of new models and solvers in an open-source framework.

PyBaMM is one of the major components of the Faraday Institution’s ‘Common Modelling Framework’, part of the Multi-Scale Modelling Fast Start project, which will act as a central repository for UK battery modelling research. PyBaMM has already been used to develop and compare reduced-order models for lithium-ion [] and lead-acid [**, **] batteries, parameterize lithium-ion cells [], model spirally-wound batteries [], model two-dimensional distributions in the current collectors [**, **], and model SEI growth []. Further research outcomes are anticipated from continued collaborations with other members of the modelling community, both within and beyond the Faraday Institution. An up-to-date list of papers that use PyBaMM can be found at *pybamm.org/publications*.

PyBaMM is an Affiliated Project with NumFOCUS, and builds on other tools in the NumFOCUS ecosystem including NumPy [], SciPy [], pandas [], Matplotlib [], and Project Jupyter [].

### Implementation and architecture

PyBaMM’s architecture is based around two core components. The first is the expression tree, which encodes mathematical equations symbolically (see ** Figure 1**). Each expression tree consists of a set of symbols, each of which represents either a variable, parameter, mathematical operation, matrix, or vector. Every battery model in PyBaMM is then defined as a collection of symbolic expression trees. The expression trees in each model are organised within python dictionaries representing the governing equations, boundary equations, and initial conditions of the model.

An example of implementing a simple diffusion model using expression trees is provided in Appendix A. Further examples of creating ODE and PDE models can be found in the *“Creating Models”* notebooks hosted online. To clearly demonstrate how to set up multi-domain and multi-physics models PyBaMM includes “basic” versions of the SPM (basic_spm.py) and DFN (basic_dfn.py) which are defined in a single script, separate from the submodel structure. These are intended to act as a learning tool, and can be found in the lithium-ion models sub-directory of the PyBaMM GitHub repository.

The second core component of PyBaMM’s architecture is the pipeline process (see ** Figure 2**). In the pipeline process different modular components operate on the model in turn. The pipeline is constructed in Python using PyBaMM classes, so that users have full control over the entire process, and can customise the pipeline or insert their own components at any stage.

**depicts a typical pipeline with the following stages:**

*Figure 2*- Define a battery model and geometry using PyBaMM’s syntax. This generates a collection of expression trees representing the model.
- Parse the expression trees for the battery model and geometry, replacing any parameters with their provided numerical values. For convenience, parameter values may be provided in a csv file.
- Mesh the geometry and discretise the model on this mesh with user-defined spatial methods. This process parses each expression tree converting variables into state vectors, and spatial operators (e.g. gradient and divergence) into matrices (accounting for the boundary conditions of the model).
- Solve the model using a time-stepping algorithm. PyBaMM offers a consistent interface to a number of ordinary differential equation (ODE), differential algebraic equation (DAE), and algebraic (root-finding) solvers, including via SciPy [], SUNDIALS [
**,****,**], CasADi [], and JAX []. One of the main benefits of PyBaMM’s expression tree structure is that it provides the capability to automatically compute the Jacobian for any model, using symbolic differentiation, which significantly improves the performance of the numerical solvers. - Post-processes the solution. Built-in post processing utilities provided access to any user-defined output variables at any solution time or state. Additionally, PyBaMM includes a number of visualisation utilities which allow for easy plotting and comparison of any of the model variables (for example output, see
).*Figure 3*

The various stages of the pipeline process are handled automatically by PyBaMM’s Simulation class, providing a user friendly way to solve battery models. The simplest example to use PyBaMM is to run a 1C constant-current discharge with a given model with all the default settings, as shown in ** Listing 1**. For greater customisation users can pass different parameters, adjust the mesh and discretisation, change the solver, and tailor the output of the plots, all via the Simulation class. For example, experimental protocols can be simulated using a simple text-based syntax, as shown in

**, or simulate non-constant current (dis)charge by passing time-current data. For more information please consult the latest documentation.**

*Listing 2*1 | import pybamm |

2 | # Doyle-Fuller-Newman model |

3 | model = pybamm.lithium_ion.DFN() |

4 | sim = pybamm.Simulation(model) |

5 | sim.solve([0, 3600]) # solve for 1 hour |

6 | sim.plot() |

1 | import pybamm |

2 | experiment = pybamm.Experiment( |

3 | [ |

4 | ″Discharge at C/10 for 10 hours or until 3.3 V″, |

5 | ″Rest for 1 hour″, |

6 | ″Charge at 1 A until 4.1 V″, |

7 | ″Hold at 4.1 V until 50 mA″, |

8 | ″Rest for 1 hour”, |

9 | ] |

10 | * 3, |

11 | ) |

12 | model = pybamm.lithium_ion.DFN() |

13 | sim = pybamm.Simulation( |

14 | model, |

15 | experiment=experiment, |

16 | solver=pybamm.CasadiSolver(), |

17 | ) |

18 | sim.solve() |

19 | sim.plot() |

### Quality control

Tests in PyBaMM are performed within the unittest framework. We follow a test-driven development process, and unit tests are implemented for every class with unit test code coverage consistently above 98%. In addition, a smaller set of integration tests are implemented to ensure the end-to-end reliability of the code. The integration tests consist of tests that check every model in PyBaMM can be processed and solved for a set of default inputs, convergence tests between reduced-order and full-order models, convergence tests for each spatial method, and tests for each solver type.

PyBaMM is developed using git version control, with all unit and integration tests being run cross-platform via GitHub Actions every time a pull request is made. At the time of writing, the PyBaMM tests run on Ubuntu, macOS and Windows systems with Python 3.7-3.9.

The main PyBaMM repository contains a selection of *Jupyter Notebooks* that provide a useful set of examples on how to use PyBaMM for different tasks such as creating a new battery model, running the existing models, or changing the default parameters. These are tested along with the main PyBaMM code to ensure they are up to date. All of the examples, as well as a “Getting Started” guide can be accessed from the *PyBaMM website* and can be run interactively in a web browser via Google Colab with no installation necessary. Further examples can be found on the accompanying case studies repository, which, among other things, shows how PyBaMM can be used for parameter estimation and simulation of drive-cycle experiments.

Please consult the CONTRIBUTING.md file in the PyBaMM repository for more detailed and up-to-date information on our development workflow, testing and CI infrastructure, and coding style guidelines.

## (2) Availability

### Operating system

PyBaMM can run on any Linux, MacOS or Windows sytem that has Python 3.6-3.8 installed, along with the dependencies listed below. The optional dependency, scikits-odes, currently only supports Linux and MacOS. For Windows users, we therefore recommend using Windows Subsystems for Linux (WSL); detailed instructions are available on GitHub. On Linux and MacOS, Google’s JAX library can be used to provide additional autograd and solver capabilities.

### Programming language

Python 3.6-3.8

### Additional system requirements

PyBaMM has no special requirements and can be run on a standard laptop or desktop machine.

### Dependencies

Required:

- numpy≥1.16
- scipy≥1.3
- pandas≥0.24
- anytree≥2.4.3
- autograd≥1.2
- scikit-fem≥0.2.0
- casasi≥3.5.0,
- jupyter (for example notebooks)
- matplotlib≥2.0
- jax=0.1.75, (not supported on Windows)
- jaxlib==0.1.52, (not supported on Windows)

Optional:

- scikits.odes≥2.4.0 (optional DAE solver, requires SUNDIALS 5.0.0)

### List of contributors

The following people have contributed in some form to the development of PyBaMM at time of writing. An up-to-date list of contributors can be found in our README. Core developers are indicated in bold.

**Valentin Sulzer, Scott Marquis, Robert Timms, Martin Robinson, Ferran Brosa-Planella, Tom Tranter, Thibault Lestang**, Diego Alonso Álvarez, Jacqueline Edge, Colin Please, Jon Chapman, Fergus Cooper, Felipe Salinas, Peter Cho, Suhak Lee, Vivian Tran, Yannick Kuhn, Alexander Bessman, Daniel Albamonte, Anand Mohan Yadav, Weilong Ai.

### Software location

GitHub (release v0.2.4)Name:

Persistent identifier:https://github.com/pybamm-team/PyBaMM/releases/tag/v0.2.4

BSD 3-clauseLicence:

The PyBaMM teamPublisher:

v0.2.4Version published:

07/09/20Date published:

#### Code repository

GitHubName:

Persistent identifier:https://github.com/pybamm-team/PyBaMM

BSD-3-ClauseLicence:

04/11/2018Date published:

### Language

English

## (3) Reuse potential

We anticipate that the main use case will be the implementation, extension, and comparison of new models and parameter sets. For example, this will allow researchers to implement models that couple several degradation mechanisms together. Further, although PyBaMM has been written with battery models in mind, the expression tree and pipeline architecture could be potentially be used to solve different sets of continuum models numerically.

In addition to new models and parameter sets, the modular framework described in Section 1 allows researchers to add new numerical algorithms in the form of spatial discretisations or new ODE/DAE solvers. Any such extensions can then be immediately tested with the existing set of models and parameters. This allows researchers to quickly assess the accuracy and speed of their numerical algorithms for a range of models and relevant parameter values.

Information on how to extend the software in these ways is available both through tutorials in the API docs and example notebooks. All of the development is done through GitHub issues and pull requests, using the workflow explained in the CONTRIBUTING.md file. Users can request support by raising an issue on GitHub.

## A Creating a model

In this section, we present an example of how to enter a simple diffusion model in PyBaMM. This model serves as a good representation of the types of models that arise in battery modelling because it contains most of the key components: spatial operators, parameters, Dirichlet and Neumann boundary conditions, and initial conditions.

We consider the concentration of some species *c*, on a spatial domain *x* ∈ [0,1], and at some time *t* ∈ [0,∞). The concentration of the species is taken to evolve according to a nonlinear diffusion process with the concentration being fixed at *x =* 0 and a constant inward flux of species imposed at *x =* 1. Mathematically, the model is stated as

where *D*(*c*) *= k*(1*+c*) is the diffusion coefficient and *k* is a parameter, which we will refer to as the diffusion parameter.

In ** Listing 3**, we provide the PyBaMM code implementing (1). Note that operator overloading of

***and

*+*allows symbols to be intuitively combined to produce expression trees. A more detailed and up-to-date introduction to the syntax is provided in the online examples available on GitHub.

The model is now represented by a collection of expression trees and can therefore be solved by passing it through the pipeline just like any other model in PyBaMM. Additionally, extending the model to include additional physics is simple and intuitive due to the simple symbolic representation of the underlying mathematical equations. For example, we can add a source term to the governing equation (1a) by only modifying one line of code (line 10 of ** Listing 3**) and still obtain useful properties of the model such as the analytical Jacobian.

1 | # 1. Initialise model |

2 | model = pybamm.BaseModel() |

3 | |

4 | # 2. Define parameters and variables |

5 | c = pybamm.Variable(″c″, domain=″unit line″) |

6 | k = pybamm.Parameter(″Diffusion parameter″) |

7 | |

8 | # 3. State governing equations |

9 | D = k * (1 + c) |

10 | dcdt = pybamm.div(D * pybamm.grad(c)) |

11 | model.rhs = {c: dcdt} |

12 | |

13 | # 4. State boundary conditions |

14 | D_right = pybamm.BoundaryValue(D, ″right″) |

15 | model.boundary_conditions = { |

16 | c: { |

17 | ″left″: (1, ″Dirichlet″), |

18 | ″right″: (1/D_right, ″Neumann″) |

19 | } |

20 | } |

21 | |

22 | # 5. State initial conditions |

23 | x = pybamm.SpatialVariable(″x″, domain=″unit line″) |

24 | model.initial_conditions = {c: x + 1} |

The common interface of all PyBaMM models makes it easy to perform the pipeline process as illustrated here upon multiple models or the same model with different options activated. Therefore, comparing the results of different models, mesh types, discretisations, and solvers then becomes straightforward within the PyBaMM framework.