Skip to content

Commit

Permalink
adds numerical impedance predictions, figs, citation. updts nyquist g…
Browse files Browse the repository at this point in the history
…rids,
  • Loading branch information
BradyPlanden committed Nov 29, 2024
1 parent d60e763 commit 5f24ac5
Show file tree
Hide file tree
Showing 18 changed files with 126 additions and 9 deletions.
Binary file added joss/figures/impedance_contour.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added joss/figures/impedance_spectrum.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/contour_evolution.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/contour_gradient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/contour_heuristic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/contour_total.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/converge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/design.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added joss/figures/joss/impedance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/optimisers_parameters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/joss/sim-landscape.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified joss/figures/landscape.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions joss/image_combine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ convert +append figures/convergence_minimising.png figures/convergence_maximisin

convert +append figures/simulation.png figures/landscape.png figures/joss/sim-landscape.png

convert +append figures/impedance_spectrum.png figures/impedance_contour.png figures/joss/impedance.png

convert +append figures/contour_gradient_0.png figures/contour_gradient_1.png figures/contour_gradient_2.png figures/contour_gradient_3.png figures/joss/contour_gradient.png

convert +append figures/contour_evolution_0.png figures/contour_evolution_1.png figures/contour_evolution_2.png figures/contour_evolution_3.png figures/joss/contour_evolution.png
Expand Down
7 changes: 7 additions & 0 deletions joss/paper.bib
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,10 @@ @article{metropolis:1953
pages = {1087--1092},
file = {Submitted Version:/Users/engs2510/Zotero/storage/LKZVAGE4/Metropolis et al. - 1953 - Equation of State Calculations by Fast Computing M.pdf:application/pdf},
}

@software{pybamm-eis,
author = {Dhoot, Rishit and Timms, Robert and Please, Colin},
title = {PyBaMM EIS: Efficient Linear Algebra Methods to Determine Li-ion Battery Behaviour},
url = {https://www.github.com/pybamm-team/pybamm-eis},
version = {0.1.4}
}
15 changes: 12 additions & 3 deletions joss/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ authors:
- name: Martin Robinson
orcid: 0000-0002-1572-6782
affiliation: 3
- name: Agriya Khetarpal
orcid: 0000-0002-1112-1786
affiliation: 5
- name: Ferran Brosa Planella
affiliation: "2, 4"
orcid: 0000-0001-6363-2812
Expand All @@ -33,6 +36,8 @@ affiliations:
index: 3
- name: Mathematics Institute, University of Warwick, Coventry, UK
index: 4
- name: New delhi?
index: 5
date: 28 November 2024
bibliography: paper.bib
repository: https://github.com/pybop-team/PyBOP
Expand All @@ -46,7 +51,7 @@ Similarly, `PyBOP` can be used for parameter design optimisation under user-defi

# Statement of need

`PyBOP` is a Python package designed to provide a user-friendly, object-oriented interface for optimising battery models. `PyBOP` leverages the open-source `PyBaMM` package [@Sulzer:2021] to formulate and solve of these battery models. `PyBOP` is intended to serve a broad audience of students, engineers, and researchers in both academia and the battery industry by enabling the use of predictive battery models where previously this was not possible. `PyBOP` emphasises clear and informative diagnostics and workflows for users of varying expertise, by providing advanced optimisation and sampling algorithms. These methods are provided through interfaces to `PINTS` [@Clerx:2019], `SciPy` [@SciPy:2020], in addition to the PyBOP's own algorithms such as Adaptive Moment Estimation with Weight Decay (AdamW), and Cuckoo search.
`PyBOP` is a Python package designed to provide a user-friendly, object-oriented interface for optimising battery models. `PyBOP` leverages the open-source `PyBaMM` package [@Sulzer:2021] to formulate and solve of these battery models. `PyBOP` is intended to serve a broad audience of students, engineers, and researchers in both academia and the battery industry by enabling the use of predictive battery models where previously this was not possible. `PyBOP` emphasises clear and informative diagnostics and workflows for users of varying expertise, by providing advanced optimisation and sampling algorithms. These methods are provided through interfaces to `PINTS` [@Clerx:2019], `SciPy` [@SciPy:2020], in addition to the PyBOP's own algorithms such as Adaptive Moment Estimation with Weight Decay (AdamW), Gradient descent, and Cuckoo search.

`PyBOP` supports the Battery Parameter eXchange (BPX) standard [@BPX:2023] for sharing battery parameter sets. As these parameter sets are costly to obtain due to: the equipment and time required for characterisation experiments, the need for battery domain knowledge, and the computational cost of parameter estimation. `PyBOP` reduces these costs by providing fast computational estimation with parameter set interoperability.

Expand Down Expand Up @@ -144,9 +149,13 @@ where $\mathcal{L} : \mathbf{\theta} \mapsto [0,\infty)$ is a cost (or likelihoo

Next, we demonstrate the fitting of synthetic data where the system parameters are known. In this example problem, we use `PyBaMM`'s implementation of the single particle model (SPM) with an added contact resistance submodel. We assume that the battery model is already parameterised except for two dynamic parameters, namely the lithium diffusivity of the negative electrode active material particle (denoted "negative particle diffusivity") and the contact resistance. We generate synthetic data from a one-hour discharge from 100% state of charge, to 0% (denoted as 1C rate), followed by 30 minutes of relaxation. This data is then corrupted with zero mean Gaussian noise of amplitude 2mV, shown by the dots in \autoref{fig:inference-time-landscape} (left). The initial states are assumed known, although such an assumption is not generally necessary. The underlying cost landscape explored by the optimiser is shown in \autoref{fig:inference-time-landscape} (right).

![The cost landscape for the parameterisation problem with a root mean squared error cost function. \label{fig:inference-time-landscape}](figures/joss/sim-landscape.png){ width=100% }
![The cost landscape for the time-series parameterisation problem with a root mean squared error cost function. \label{fig:inference-time-landscape}](figures/joss/sim-landscape.png){ width=100% }

As gradient information is available for this problem, the choice of distance-based cost function and optimiser is not constrained. Due to the different magnitudes of the two parameters, we apply the logarithmic parameter transformation offered by `PyBOP`. This transforms the optimisers search space of the optimiser to allow for a common step size between the parameters, which is generally is not required, but improves convergence in this problem. As a demonstration of the parameterisation capabilities of `PyBOP`, \autoref{fig:convergence-min-max} (left) shows the rate of convergence for each of the distance-minimising cost functions, while \autoref{fig:convergence-min-max} (right) shows analogous results for maximising a likelihood. The optimisation is performed with SciPy Minimize using the gradient-based L-BFGS-B method.
As mentioned above, `PyBOP` also provides inference and optimisation capabilities through numerical impedance spectroscopy. This is based on the methods presented in the `pybamm-eis` package and allows fast impedance computation by inversion of the sparse PyBaMM mass matrix after scaling and subtraction of the auto-differentiated Jacobian matrix. More information about this procedure is available in [@pybamm-eis]. The \autoref{fig:impedance-landscape} below shows the numerical impedance prediction available in `PyBOP` alongside the cost landscape constructed for the inference task. At the time of publication, gradient-based optimisation and sampling methods are not available when using an impedance workflow.

![The cost landscape for the frequency domain impedance parameterisation problem with a root mean squared error cost function at 5% SOC. \label{fig:impedance-landscape}](figures/joss/impedance.png){ width=100% }

Moving forward, we will continue with identification in the time-domain. As gradient information is available for this problem, the choice of distance-based cost function and optimiser is not constrained. Due to the different magnitudes of the two parameters, we apply the logarithmic parameter transformation offered by `PyBOP`. This transforms the optimisers search space of the optimiser to allow for a common step size between the parameters, which is generally is not required, but improves convergence in this problem. As a demonstration of the parameterisation capabilities of `PyBOP`, \autoref{fig:convergence-min-max} (left) shows the rate of convergence for each of the distance-minimising cost functions, while \autoref{fig:convergence-min-max} (right) shows analogous results for maximising a likelihood. The optimisation is performed with SciPy Minimize using the gradient-based L-BFGS-B method.

![Convergence in the likelihood functions obtained using various likelihood functions and the L-BFGS-B algorithm. \label{fig:convergence-min-max}](figures/joss/converge.png){ width=100% }

Expand Down
Binary file modified joss/paper.pdf
Binary file not shown.
107 changes: 103 additions & 4 deletions joss/param_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
# Choose which plots to show and save
create_plot = {}
create_plot["simulation"] = False
create_plot["landscape"] = False
create_plot["landscape"] = True
create_plot["minimising"] = False
create_plot["maximising"] = False
create_plot["gradient"] = False
create_plot["evolution"] = False
create_plot["heuristic"] = True
create_plot["heuristic"] = False
create_plot["posteriors"] = False
create_plot["eis"] = True


# Parameter set and model definition
Expand Down Expand Up @@ -127,7 +128,7 @@
color="white",
line_color="black",
line_width=1,
size=14,
size=16,
showscale=False,
),
name="Initial values",
Expand All @@ -143,7 +144,7 @@
color="black",
line_color="white",
line_width=1,
size=14,
size=16,
showscale=False,
),
name="True values",
Expand Down Expand Up @@ -607,3 +608,101 @@ def format_axis(ax):
plt.tight_layout()
plt.savefig("joss/figures/joss/posteriors.png")
plt.show()


if create_plot["eis"]:

def noise(sigma, values):
# Generate real part noise
real_noise = np.random.normal(0, sigma, values)

# Generate imaginary part noise
imag_noise = np.random.normal(0, sigma, values)

# Combine them into a complex noise
return real_noise + 1j * imag_noise

var = pybamm.standard_spatial_vars
var_pts = {var.x_n: 10, var.x_s: 10, var.x_p: 10, var.r_n: 30, var.r_p: 30}

# Construct model
model = pybop.lithium_ion.SPMe(
parameter_set=parameter_set,
eis=True,
options={"surface form": "differential", "contact resistance": "true"},
var_pts=var_pts,
)

initial_state = {"Initial SoC": 0.05}
n_frequency = 35
sigma0 = 5e-4
f_eval = np.logspace(-3.75, 4, n_frequency)

# Create synthetic data for parameter inference
sim = model.simulateEIS(
inputs={
"Negative particle diffusivity [m2.s-1]": parameter_set[
"Negative particle diffusivity [m2.s-1]"
],
"Contact resistance [Ohm]": 0.01,
},
f_eval=f_eval,
initial_state=initial_state,
)

# Form dataset
dataset = pybop.Dataset(
{
"Frequency [Hz]": f_eval,
"Current function [A]": np.zeros(len(f_eval)),
"Impedance": sim["Impedance"] + noise(sigma0, len(sim["Impedance"])),
}
)

signal = ["Impedance"]
problem = pybop.FittingProblem(model, parameters, dataset, signal=signal)
cost = pybop.RootMeanSquaredError(problem)

optim = pybop.CMAES(cost, max_iterations=75, min_iterations=75, sigma0=0.25)
results = optim.run()

parameter_fig = pybop.plot.nyquist(problem, results.x, title="")
parameter_fig[0].write_image("joss/figures/impedance_spectrum.png")

landscape_fig = pybop.plot.contour(cost, steps=30, title="")
initial_value = parameters.initial_value()
true_value = parameters.true_value()
landscape_fig.add_trace(
go.Scatter(
x=[initial_value[0]],
y=[initial_value[1]],
mode="markers",
marker_symbol="x",
marker=dict(
color="white",
line_color="black",
line_width=1,
size=16,
showscale=False,
),
name="Initial values",
)
)
landscape_fig.add_trace(
go.Scatter(
x=[true_value[0]],
y=[true_value[1]],
mode="markers",
marker_symbol="cross",
marker=dict(
color="black",
line_color="white",
line_width=1,
size=16,
showscale=False,
),
name="True values",
)
)
landscape_fig.show()
landscape_fig.write_image("joss/figures/impedance_contour.png")
4 changes: 2 additions & 2 deletions pybop/plot/nyquist.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ def nyquist(problem, problem_inputs: Inputs = None, show=True, **layout_kwargs):
showgrid=True,
gridwidth=1,
gridcolor="lightgray",
minor=dict(showgrid=True, gridwidth=0.5, gridcolor="lightgray"),
zerolinecolor="lightgray",
)
fig.update_yaxes(
showgrid=True,
gridwidth=1,
gridcolor="lightgray",
minor=dict(showgrid=True, gridwidth=0.5, gridcolor="lightgray"),
zerolinecolor="lightgray",
)

# Overwrite with user-kwargs
Expand Down

0 comments on commit 5f24ac5

Please sign in to comment.