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.

Loss of active material submodels#

In this notebook we show how to use the loss of active materials (LAM) submodels in PyBaMM.

Stress-driven LAM#

The first model we consider is the stress-driven submodel, which follows equation (25) from Reniers et al (2019), and the stresses are calculated by equations (7)-(9) in Ai et al (2020). To see all of the models and submodels available in PyBaMM, please take a look at the documentation.

As usual, we start by defining the model. We choose a DFN model with stress-driven loss of active material, and we also include SEI growth. We then define the parameters and experiments, and solve the simulation.

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

model = pybamm.lithium_ion.DFN(
    options={
        "SEI": "solvent-diffusion limited",
        "SEI porosity change": "false",
        "particle mechanics": "swelling only",
        "loss of active material": "stress-driven",
    }
)
param = pybamm.ParameterValues("Ai2020")
param.update({"Negative electrode LAM constant proportional term [s-1]": 1e-4 / 3600})
param.update({"Positive electrode LAM constant proportional term [s-1]": 1e-4 / 3600})
experiment = pybamm.Experiment(
    [
        "Discharge at 1C until 3 V",
        "Rest for 600 seconds",
        "Charge at 1C until 4.2 V",
        "Hold at 4.199 V for 600 seconds",
    ]
)
sim = pybamm.Simulation(
    model,
    experiment=experiment,
    parameter_values=param,
    discretisation_kwargs={"remove_independent_variables_from_rhs": True},
)
solution = sim.solve(calc_esoh=False)
Note: you may need to restart the kernel to use updated packages.
At t = 57.3387, , mxstep steps taken before reaching tout.
At t = 57.3387 and h = 7.05477e-15, the corrector convergence failed repeatedly or with |h| = hmin.
At t = 57.3387, , mxstep steps taken before reaching tout.
At t = 57.3387, , mxstep steps taken before reaching tout.

We can now plot the results as usual.

[2]:
sim.plot(
    [
        "Voltage [V]",
        "Current [A]",
        "Sum of x-averaged positive electrode volumetric interfacial current densities [A.m-3]",
        "Sum of x-averaged negative electrode volumetric interfacial current densities [A.m-3]",
        "X-averaged positive electrode active material volume fraction",
        "X-averaged negative electrode active material volume fraction",
        "X-averaged positive particle surface tangential stress [Pa]",
        "X-averaged negative particle surface tangential stress [Pa]",
    ]
)
[2]:
<pybamm.plotting.quick_plot.QuickPlot at 0x152567510>

To understand the effect of the LAM constant proportional term, let’s perform a parameter sweep.

[3]:
ks = [1e-4, 1e-3, 1e-2]
solutions = []

for k in ks:
    param.update({"Positive electrode LAM constant proportional term [s-1]": k / 3600})
    param.update({"Negative electrode LAM constant proportional term [s-1]": k / 3600})

    sim = pybamm.Simulation(
        model,
        experiment=experiment,
        parameter_values=param,
        discretisation_kwargs={"remove_independent_variables_from_rhs": True},
    )
    solution = sim.solve(calc_esoh=False)
    solutions.append(solution)

pybamm.dynamic_plot(
    solutions,
    output_variables=[
        "Voltage [V]",
        "Current [A]",
        "Sum of x-averaged positive electrode volumetric interfacial current densities [A.m-3]",
        "Sum of x-averaged negative electrode volumetric interfacial current densities [A.m-3]",
        "X-averaged positive electrode active material volume fraction",
        "X-averaged negative electrode active material volume fraction",
        "X-averaged positive electrode surface area to volume ratio [m-1]",
        "X-averaged negative electrode surface area to volume ratio [m-1]",
    ],
    labels=[f"k={k:.0e}" for k in ks],
)
At t = 57.3387, , mxstep steps taken before reaching tout.
At t = 57.3387 and h = 7.05477e-15, the corrector convergence failed repeatedly or with |h| = hmin.
At t = 57.3387, , mxstep steps taken before reaching tout.
At t = 57.3387, , mxstep steps taken before reaching tout.
At t = 57.3307, , mxstep steps taken before reaching tout.
At t = 57.3307, , mxstep steps taken before reaching tout.
At t = 57.3307, , mxstep steps taken before reaching tout.
At t = 57.3307, , mxstep steps taken before reaching tout.
At t = 57.2504, , mxstep steps taken before reaching tout.
At t = 57.2504, , mxstep steps taken before reaching tout.
At t = 57.2504, , mxstep steps taken before reaching tout.
At t = 57.2504, , mxstep steps taken before reaching tout.
[3]:
<pybamm.plotting.quick_plot.QuickPlot at 0x163635410>

Reaction-driven LAM#

Another option is to use reaction-driven (i.e. SEI) LAM. In this case we need to choose the "reaction-driven" option in the model, and proceed along the lines of the previous example.

[4]:
model = pybamm.lithium_ion.DFN(
    options={
        "SEI": "solvent-diffusion limited",
        "loss of active material": "reaction-driven",
    }
)
param = pybamm.ParameterValues("Chen2020")
param.update({"Negative electrode reaction-driven LAM factor [m3.mol-1]": 1e-3})
sim = pybamm.Simulation(
    model,
    experiment=experiment,
    parameter_values=param,
    solver=pybamm.CasadiSolver("fast with events"),
)
solution = sim.solve(calc_esoh=False)

sim.plot(
    [
        "Voltage [V]",
        "Current [A]",
        "Sum of x-averaged negative electrode volumetric interfacial current densities [A.m-3]",
        "X-averaged negative electrode active material volume fraction",
        "Negative total SEI thickness [m]",
        "X-averaged negative total SEI thickness [m]",
    ]
)
[4]:
<pybamm.plotting.quick_plot.QuickPlot at 0x164f1f810>

Both stress-driven and reaction-driven can be combined by calling the "stress and reaction-driven" option.

Current-driven LAM#

The final submodel is current-driven LAM, which follows equation (26) from Reniers et al (2019). In this case we need to define the RHS of the equation as a function of current density and temperature. The example here is illustrative and does not represent any real scenario.

[5]:
def current_LAM(i, T):
    return -1e-10 * (abs(i) + 1e3 * abs(i) ** 0.5)


model = pybamm.lithium_ion.DFN(
    options={
        "loss of active material": "current-driven",
    }
)
param = pybamm.ParameterValues("Chen2020")
param.update(
    {
        "Positive electrode current-driven LAM rate": current_LAM,
        "Negative electrode current-driven LAM rate": current_LAM,
    },
    check_already_exists=False,
)
sim = pybamm.Simulation(
    model,
    experiment=experiment,
    parameter_values=param,
    solver=pybamm.CasadiSolver("fast with events"),
)
solution = sim.solve(calc_esoh=False)

sim.plot(
    [
        "Voltage [V]",
        "Current [A]",
        "X-averaged positive electrode active material volume fraction",
        "X-averaged negative electrode active material volume fraction",
    ]
)
[5]:
<pybamm.plotting.quick_plot.QuickPlot at 0x29d0de550>

References#

The relevant papers for this notebook are:

[6]:
pybamm.print_citations()
[1] Weilong Ai, Ludwig Kraft, Johannes Sturm, Andreas Jossen, and Billy Wu. Electrochemical thermal-mechanical modelling of stress inhomogeneity in lithium-ion pouch cells. Journal of The Electrochemical Society, 167(1):013512, 2019. doi:10.1149/2.0122001JES.
[2] 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.
[3] Chang-Hui Chen, Ferran Brosa Planella, Kieran O'Regan, Dominika Gastol, W. Dhammika Widanage, and Emma Kendrick. Development of Experimental Techniques for Parameterization of Multi-scale Lithium-ion Battery Models. Journal of The Electrochemical Society, 167(8):080534, 2020. doi:10.1149/1945-7111/ab9050.
[4] Rutooj Deshpande, Mark Verbrugge, Yang-Tse Cheng, John Wang, and Ping Liu. Battery cycle life prediction with coupled chemical degradation and fatigue mechanics. Journal of the Electrochemical Society, 159(10):A1730, 2012. doi:10.1149/2.049210jes.
[5] Marc Doyle, Thomas F. Fuller, and John Newman. Modeling of galvanostatic charge and discharge of the lithium/polymer/insertion cell. Journal of the Electrochemical society, 140(6):1526–1533, 1993. doi:10.1149/1.2221597.
[6] 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.
[7] Scott G. Marquis. Long-term degradation of lithium-ion batteries. PhD thesis, University of Oxford, 2020.
[8] Jorn M. Reniers, Grietus Mulder, and David A. Howey. Review and performance comparison of mechanical-chemical degradation models for lithium-ion batteries. Journal of The Electrochemical Society, 166(14):A3189, 2019. doi:10.1149/2.0281914jes.
[9] 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.

[ ]: