Tip

An interactive online version of this notebook is available, which can be accessed via Open this notebook in Google Colab


Alternatively, you may download this notebook and run it offline.

Attention

You are viewing this notebook on the latest version of the documentation, where these notebooks may not be compatible with the stable release of PyBaMM since they can contain features that are not yet released. We recommend viewing these notebooks from the stable version of the documentation. To install the latest version of PyBaMM that is compatible with the latest notebooks, build PyBaMM from source.

Degradation experiments with reference performance tests#

When running degradation experiments in the lab, it is important to use reference performance tests (RPTs) to measure capacity and other key metrics, otherwise the experimental contitions will interfere with the measurement! In PyBaMM, you can run simulations with RPTs using the Experiment class.

[1]:
%pip install pybamm[plot,cite] -q  # install PyBaMM if it is not installed

import pybamm
import matplotlib.pyplot as plt
import os

os.chdir(pybamm.__path__[0] + "/..")
Note: you may need to restart the kernel to use updated packages.

Load a simple degradation model

[2]:
model = pybamm.lithium_ion.SPM({"SEI": "ec reaction limited"})
parameter_values = pybamm.ParameterValues("Mohtat2020")
parameter_values.update({"SEI kinetic rate constant [m.s-1]": 1e-14})

Define three different experiments using the Experiment class: * cccv_experiment is a cycle ageing experiment * charge_experiment charges to full after N ageing cycles * rpt_experiment is a C/3 discharge in this case, but can also contain a charge, GITT, EIS and other procedures

[3]:
N = 10
cccv_experiment = pybamm.Experiment(
    [
        (
            "Charge at 1C until 4.2V",
            "Hold at 4.2V until C/50",
            "Discharge at 1C until 3V",
            "Rest for 1 hour",
        )
    ]
    * N
)
charge_experiment = pybamm.Experiment(
    [
        (
            "Charge at 1C until 4.2V",
            "Hold at 4.2V until C/50",
        )
    ]
)
rpt_experiment = pybamm.Experiment([("Discharge at C/3 until 3V",)])

Run the ageing, charge and RPT experiments in order by feeding the previous solution into the solve command:

[4]:
sim = pybamm.Simulation(
    model, experiment=cccv_experiment, parameter_values=parameter_values
)
cccv_sol = sim.solve()
sim = pybamm.Simulation(
    model, experiment=charge_experiment, parameter_values=parameter_values
)
charge_sol = sim.solve(starting_solution=cccv_sol)
sim = pybamm.Simulation(
    model, experiment=rpt_experiment, parameter_values=parameter_values
)
rpt_sol = sim.solve(starting_solution=charge_sol)

Plot detailed current/voltage data for the RPT cycle only:

[5]:
pybamm.dynamic_plot(rpt_sol.cycles[-1], ["Current [A]", "Voltage [V]"])
[5]:
<pybamm.plotting.quick_plot.QuickPlot at 0x7ff13da91760>

PyBaMM’s summary variables track important cell-level degradation veriables at the end of each cycle. The charge and RPT cycles are also counted, making a total of 12 cycles:

[6]:
pybamm.plot_summary_variables(rpt_sol);
../../../../_images/source_examples_notebooks_simulations_and_experiments_rpt-experiment_12_0.png

Repeat the procedure four times:

[7]:
cccv_sols = []
charge_sols = []
rpt_sols = []
M = 5
for i in range(M):
    if i != 0:  # skip the first set of ageing cycles because it's already been done
        sim = pybamm.Simulation(
            model, experiment=cccv_experiment, parameter_values=parameter_values
        )
        cccv_sol = sim.solve(starting_solution=rpt_sol)
        sim = pybamm.Simulation(
            model, experiment=charge_experiment, parameter_values=parameter_values
        )
        charge_sol = sim.solve(starting_solution=cccv_sol)
        sim = pybamm.Simulation(
            model, experiment=rpt_experiment, parameter_values=parameter_values
        )
        rpt_sol = sim.solve(starting_solution=charge_sol)
    cccv_sols.append(cccv_sol)
    charge_sols.append(charge_sol)
    rpt_sols.append(rpt_sol)

You can plot any RPT cycle. The last one is chosen here.

[8]:
pybamm.dynamic_plot(rpt_sols[-1].cycles[-1], ["Current [A]", "Voltage [V]"])
[8]:
<pybamm.plotting.quick_plot.QuickPlot at 0x7ff12d79b610>

One way of demonstrating how useful RPTs are is to plot the discharge capacity for each cycle. It is convenient to use the final rpt_sol because it also contains all previous simulations.

[9]:
cccv_cycles = []
cccv_capacities = []
rpt_cycles = []
rpt_capacities = []
for i in range(M):
    for j in range(N):
        cccv_cycles.append(i * (N + 2) + j + 1)
        start_capacity = (
            rpt_sol.cycles[i * (N + 2) + j]
            .steps[2]["Discharge capacity [A.h]"]
            .entries[0]
        )
        end_capacity = (
            rpt_sol.cycles[i * (N + 2) + j]
            .steps[2]["Discharge capacity [A.h]"]
            .entries[-1]
        )
        cccv_capacities.append(end_capacity - start_capacity)
    rpt_cycles.append((i + 1) * (N + 2))
    start_capacity = rpt_sol.cycles[(i + 1) * (N + 2) - 1][
        "Discharge capacity [A.h]"
    ].entries[0]
    end_capacity = rpt_sol.cycles[(i + 1) * (N + 2) - 1][
        "Discharge capacity [A.h]"
    ].entries[-1]
    rpt_capacities.append(end_capacity - start_capacity)
plt.scatter(cccv_cycles, cccv_capacities, label="Ageing cycles")
plt.scatter(rpt_cycles, rpt_capacities, label="RPT cycles")
plt.xlabel("Cycle number")
plt.ylabel("Discharge capacity [A.h]")
plt.legend()
[9]:
<matplotlib.legend.Legend at 0x7ff12d616bb0>
../../../../_images/source_examples_notebooks_simulations_and_experiments_rpt-experiment_18_1.png

The ageing cycles have a higher discharge rate than the RPT cycles and therefore have a slightly lower discharge capacity. (The charge cycles are not included because they have no discharge capacity.)

Finally, plot the summary variables for the entire experiment run.

[10]:
pybamm.plot_summary_variables(rpt_sol);
../../../../_images/source_examples_notebooks_simulations_and_experiments_rpt-experiment_21_0.png

References#

The relevant papers for this notebook are:

[11]:
pybamm.print_citations()
[1] Joel A. E. Andersson, Joris Gillis, Greg Horn, James B. Rawlings, and Moritz Diehl. CasADi – A software framework for nonlinear optimization and optimal control. Mathematical Programming Computation, 11(1):1–36, 2019. doi:10.1007/s12532-018-0139-4.
[2] Ferran Brosa Planella and W. Dhammika Widanage. Systematic derivation of a Single Particle Model with Electrolyte and Side Reactions (SPMe+SR) for degradation of lithium-ion batteries. Submitted for publication, ():, 2022. doi:.
[3] Charles R. Harris, K. Jarrod Millman, Stéfan J. van der Walt, Ralf Gommers, Pauli Virtanen, David Cournapeau, Eric Wieser, Julian Taylor, Sebastian Berg, Nathaniel J. Smith, and others. Array programming with NumPy. Nature, 585(7825):357–362, 2020. doi:10.1038/s41586-020-2649-2.
[4] Scott G. Marquis, Valentin Sulzer, Robert Timms, Colin P. Please, and S. Jon Chapman. An asymptotic derivation of a single particle model with electrolyte. Journal of The Electrochemical Society, 166(15):A3693–A3706, 2019. doi:10.1149/2.0341915jes.
[5] Peyman Mohtat, Suhak Lee, Jason B Siegel, and Anna G Stefanopoulou. Towards better estimability of electrode-specific state of health: decoding the cell expansion. Journal of Power Sources, 427:101–111, 2019.
[6] Peyman Mohtat, Suhak Lee, Valentin Sulzer, Jason B. Siegel, and Anna G. Stefanopoulou. Differential Expansion and Voltage Model for Li-ion Batteries at Practical Charging Rates. Journal of The Electrochemical Society, 167(11):110561, 2020. doi:10.1149/1945-7111/aba5d1.
[7] Valentin Sulzer, Scott G. Marquis, Robert Timms, Martin Robinson, and S. Jon Chapman. Python Battery Mathematical Modelling (PyBaMM). Journal of Open Research Software, 9(1):14, 2021. doi:10.5334/jors.309.
[8] Pauli Virtanen, Ralf Gommers, Travis E. Oliphant, Matt Haberland, Tyler Reddy, David Cournapeau, Evgeni Burovski, Pearu Peterson, Warren Weckesser, Jonathan Bright, and others. SciPy 1.0: fundamental algorithms for scientific computing in Python. Nature Methods, 17(3):261–272, 2020. doi:10.1038/s41592-019-0686-2.
[9] Andrew Weng, Jason B Siegel, and Anna Stefanopoulou. Differential voltage analysis for battery manufacturing process control. arXiv preprint arXiv:2303.07088, 2023.
[10] Xiao Guang Yang, Yongjun Leng, Guangsheng Zhang, Shanhai Ge, and Chao Yang Wang. Modeling of lithium plating induced aging of lithium-ion batteries: transition from linear to nonlinear aging. Journal of Power Sources, 360:28–40, 2017. doi:10.1016/j.jpowsour.2017.05.110.