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.

A composite electrode particle model#

A composite electrode particle model is developed for (negative) electrodes with two phases, e.g. graphite/silicon in LG M50 battery cells. The current version is demonstrated for negative composite electrodes only but is easily extended to positive composite electrodes. The reference is at the end of this notebook.

How to use the model#

Let us set up PyBaMM

[1]:
# %pip install "pybamm[plot,cite]" -q    # install PyBaMM if it is not installed
import os
import matplotlib.pyplot as plt
import numpy as np
import pybamm
import timeit
from matplotlib import style

style.use("ggplot")
os.chdir(pybamm.__path__[0] + "/..")
pybamm.set_logging_level("INFO")

Choose the option {"particle phases": ("2", "1")} to load the composite electrode particle model by specifying that there are two particle phases (graphite and silicon) in the negative electrode. The parameter set “Chen2020_composite” includes parameters for silicon as a secondary particle

[2]:
start = timeit.default_timer()
model = pybamm.lithium_ion.DFN(
    {
        "particle phases": ("2", "1"),
        "open-circuit potential": (("single", "current sigmoid"), "single"),
    }
)
param = pybamm.ParameterValues("Chen2020_composite")

param.update({"Upper voltage cut-off [V]": 4.5})
param.update({"Lower voltage cut-off [V]": 2.5})

param.update(
    {
        "Primary: Maximum concentration in negative electrode [mol.m-3]": 28700,
        "Primary: Initial concentration in negative electrode [mol.m-3]": 23000,
        "Primary: Negative particle diffusivity [m2.s-1]": 5.5e-14,
        "Secondary: Negative particle diffusivity [m2.s-1]": 1.67e-14,
        "Secondary: Initial concentration in negative electrode [mol.m-3]": 277000,
        "Secondary: Maximum concentration in negative electrode [mol.m-3]": 278000,
    }
)
2023-02-21 09:08:46.318 - [INFO] base_model._build_model(550): Start building Doyle-Fuller-Newman model
2023-02-21 09:08:46.452 - [INFO] base_battery_model.build_model(970): Finish building Doyle-Fuller-Newman model

Single Cycle Simulations#

Define a current loading

[3]:
C_rate = 0.5
capacity = param["Nominal cell capacity [A.h]"]
I_load = C_rate * capacity

t_eval = np.linspace(0, 10000, 1000)

param["Current function [A]"] = I_load

It is very easy to vary the relative volume fraction of each phase. The following example shows how to compare the results of batteries with three relative volume fractions (0.001, 0.04, 0.1) of silicon.

[4]:
v_si = [0.001, 0.04, 0.1]
total_am_volume_fraction = 0.75
solution = []
for v in v_si:
    param.update(
        {
            "Primary: Negative electrode active material volume fraction": (1 - v)
            * total_am_volume_fraction,  # primary
            "Secondary: Negative electrode active material volume fraction": v
            * total_am_volume_fraction,
        }
    )
    print(v)
    sim = pybamm.Simulation(
        model,
        parameter_values=param,
        solver=pybamm.CasadiSolver(dt_max=5),
    )
    solution.append(sim.solve(t_eval=t_eval))
stop = timeit.default_timer()
print("running time: " + str(stop - start) + "s")
2023-02-21 09:08:46.528 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
0.001
2023-02-21 09:08:46.741 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:08:46.743 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:08:46.750 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:08:47.292 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:08:47.293 - [INFO] base_solver.solve(703): Start solving Doyle-Fuller-Newman model with CasADi solver with 'safe' mode
2023-02-21 09:08:47.297 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:08:47.433 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:08:55.129 - [INFO] base_solver.solve(937): Finish solving Doyle-Fuller-Newman model (event: Minimum voltage)
2023-02-21 09:08:55.130 - [INFO] base_solver.solve(938): Set-up time: 136.675 ms, Solve time: 7.685 s (of which integration time: 6.012 s), Total time: 7.821 s
2023-02-21 09:08:55.137 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:08:55.250 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:08:55.252 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:08:55.260 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
0.04
2023-02-21 09:08:55.808 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:08:55.809 - [INFO] base_solver.solve(703): Start solving Doyle-Fuller-Newman model with CasADi solver with 'safe' mode
2023-02-21 09:08:55.814 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:08:55.947 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:06.233 - [INFO] base_solver.solve(937): Finish solving Doyle-Fuller-Newman model (event: Minimum voltage)
2023-02-21 09:09:06.234 - [INFO] base_solver.solve(938): Set-up time: 134.145 ms, Solve time: 10.272 s (of which integration time: 8.058 s), Total time: 10.407 s
2023-02-21 09:09:06.242 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:06.444 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
0.1
2023-02-21 09:09:06.447 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:06.453 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:07.047 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:07.048 - [INFO] base_solver.solve(703): Start solving Doyle-Fuller-Newman model with CasADi solver with 'safe' mode
2023-02-21 09:09:07.052 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:07.200 - [INFO] base_solver.set_up(236): Finish solver set-up
At t = 0.00076482 and h = 3.55373e-22, the corrector convergence failed repeatedly or with |h| = hmin.
At t = 0.000250492 and h = 1.20507e-16, the corrector convergence failed repeatedly or with |h| = hmin.
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:849: Calculating Jacobian failed
At t = 0.000250493 and h = 2.0588e-18, the corrector convergence failed repeatedly or with |h| = hmin.
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
At t = 0.000121913 and h = 6.48118e-25, the corrector convergence failed repeatedly or with |h| = hmin.
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
At t = 5.76225e-05 and h = 3.13053e-22, the corrector convergence failed repeatedly or with |h| = hmin.
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
At t = 2.54755e-05 and h = 4.28889e-31, the corrector convergence failed repeatedly or with |h| = hmin.
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
psetup failed: .../casadi/interfaces/sundials/idas_interface.cpp:852: Linear solve failed
At t = 9.40462e-06 and h = 4.82262e-22, the corrector convergence failed repeatedly or with |h| = hmin.
2023-02-21 09:09:21.630 - [INFO] base_solver.solve(937): Finish solving Doyle-Fuller-Newman model (event: Minimum voltage)
2023-02-21 09:09:21.631 - [INFO] base_solver.solve(938): Set-up time: 148.688 ms, Solve time: 14.417 s (of which integration time: 9.176 s), Total time: 14.566 s
running time: 35.389444837s

Results#

Compare the cell voltages of the three cells in this example, to see how silicon affects the output capacity

[5]:
ltype = ["k-", "r--", "b-.", "g:", "m-", "c--", "y-."]
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    V_i = solution[i]["Voltage [V]"].entries
    plt.plot(t_i, V_i, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Voltage [V]")
plt.legend()
[5]:
<matplotlib.legend.Legend at 0x12b1849a0>
../../../../_images/source_examples_notebooks_models_composite_particle_12_1.png

Results of interfacial current density in silicon

[6]:
plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    j_n_p1_av = solution[i][
        "X-averaged negative electrode primary interfacial current density [A.m-2]"
    ].entries
    plt.plot(t_i, j_n_p1_av, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Averaged interfacial current density [A/m$^{2}$]")
plt.legend()
plt.title("Graphite")

plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    j_n_p2_av = solution[i][
        "X-averaged negative electrode secondary interfacial current density [A.m-2]"
    ].entries
    plt.plot(t_i, j_n_p2_av, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Averaged interfacial current density [A/m$^{2}$]")
plt.legend()
plt.title("Silicon")
[6]:
Text(0.5, 1.0, 'Silicon')
../../../../_images/source_examples_notebooks_models_composite_particle_14_1.png
../../../../_images/source_examples_notebooks_models_composite_particle_14_2.png

Results of interfacial current density in graphite

[7]:
plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    j_n_p1_Vav = solution[i][
        "X-averaged negative electrode primary volumetric interfacial current density [A.m-3]"
    ].entries
    plt.plot(t_i, j_n_p1_Vav, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Averaged volumetric interfacial current density [A/m$^{3}$]")
plt.legend()
plt.title("Graphite")

plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    j_n_p2_Vav = solution[i][
        "X-averaged negative electrode secondary volumetric interfacial current density [A.m-3]"
    ].entries
    plt.plot(t_i, j_n_p2_Vav, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Averaged volumetric interfacial current density [A/m$^{3}$]")
plt.legend()
plt.title("Silicon")
[7]:
Text(0.5, 1.0, 'Silicon')
../../../../_images/source_examples_notebooks_models_composite_particle_16_1.png
../../../../_images/source_examples_notebooks_models_composite_particle_16_2.png

Results of average lithium concentration

[8]:
plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    c_s_xrav_n_p1 = solution[i][
        "Average negative primary particle concentration"
    ].entries
    plt.plot(t_i, c_s_xrav_n_p1, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("$c_\mathrm{g}/c_\mathrm{g,max}$")
plt.legend()
plt.title("Graphite")

plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    c_s_xrav_n_p2 = solution[i][
        "Average negative secondary particle concentration"
    ].entries
    plt.plot(t_i, c_s_xrav_n_p2, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("$c_\mathrm{si}/c_\mathrm{si,max}$")
plt.legend()
plt.title("Silicon")
[8]:
Text(0.5, 1.0, 'Silicon')
../../../../_images/source_examples_notebooks_models_composite_particle_18_1.png
../../../../_images/source_examples_notebooks_models_composite_particle_18_2.png

Results of equilibrium potential

[9]:
plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    ocp_p1 = solution[i][
        "X-averaged negative electrode primary open-circuit potential [V]"
    ].entries
    plt.plot(t_i, ocp_p1, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Equilibruim potential [V]")
plt.legend()
plt.title("Graphite")

plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    ocp_p2 = solution[i][
        "X-averaged negative electrode secondary open-circuit potential [V]"
    ].entries
    plt.plot(t_i, ocp_p2, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Equilibruim potential [V]")
plt.legend()
plt.title("Silicon")

plt.figure()
for i in range(0, len(v_si)):
    t_i = solution[len(v_si) - 1 - i]["Time [s]"].entries / 3600
    ocp_p = solution[len(v_si) - 1 - i][
        "X-averaged positive electrode open-circuit potential [V]"
    ].entries
    plt.plot(
        t_i,
        ocp_p,
        ltype[len(v_si) - 1 - i],
        label="$V_\mathrm{si}=$" + str(v_si[len(v_si) - 1 - i]),
    )
plt.xlabel("Time [h]")
plt.ylabel("Equilibrium potential [V]")
plt.legend()
plt.title("NMC811")
[9]:
Text(0.5, 1.0, 'NMC811')
../../../../_images/source_examples_notebooks_models_composite_particle_20_1.png
../../../../_images/source_examples_notebooks_models_composite_particle_20_2.png
../../../../_images/source_examples_notebooks_models_composite_particle_20_3.png

Multi-Cycle Simulations#

For multi-cycling, an experiment definition for static C/2 discharge and charge cycling is presented.

[10]:
experiment = pybamm.Experiment(
    [
        (
            "Discharge at C/2 until 3.0 V",
            "Rest for 1 hour",
            "Charge at C/2 until 4.2 V",
            "Rest for 1 hour",
        ),
    ]
    * 2
)
2023-02-21 09:09:26.957 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:26.959 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:26.961 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:26.963 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:26.964 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:26.965 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:26.966 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:26.967 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.

The solution is reintroduced, with calc_esoh=False passed into the solve function. Currently, composite electrode state of health predictions are not included in this model.

[11]:
solution = []
for v in v_si:
    param.update(
        {
            "Primary: Negative electrode active material volume fraction": (1 - v)
            * total_am_volume_fraction,  # primary
            "Secondary: Negative electrode active material volume fraction": v
            * total_am_volume_fraction,
        }
    )
    print(v)
    sim = pybamm.Simulation(
        model,
        experiment=experiment,
        parameter_values=param,
        solver=pybamm.CasadiSolver(dt_max=5),
    )
    solution.append(sim.solve(calc_esoh=False))
stop = timeit.default_timer()
print("running time: " + str(stop - start) + "s")
2023-02-21 09:09:27.094 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:27.096 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:27.097 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:27.098 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:27.099 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:27.099 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:27.100 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:27.101 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:27.115 - [INFO] callbacks.on_experiment_start(166): Start running experiment
2023-02-21 09:09:27.118 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:27.244 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:27.246 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:27.362 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
0.001
2023-02-21 09:09:27.364 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:27.482 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:27.486 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:27.492 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:28.059 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:28.060 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:28.066 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:28.601 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:28.602 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:28.610 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:29.139 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:29.140 - [NOTICE] callbacks.on_cycle_start(174): Cycle 1/2 (20.167 us elapsed) --------------------
2023-02-21 09:09:29.141 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:29.145 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:29.290 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:30.657 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:30.661 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:30.800 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:31.643 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:09:31.647 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:31.796 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:33.027 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 4/4: Rest for 1 hour
2023-02-21 09:09:33.910 - [NOTICE] callbacks.on_cycle_start(174): Cycle 2/2 (4.771 s elapsed) --------------------
2023-02-21 09:09:33.911 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:35.119 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:35.867 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:09:37.032 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 4/4: Rest for 1 hour
2023-02-21 09:09:37.783 - [NOTICE] callbacks.on_experiment_end(222): Finish experiment simulation, took 8.643 s
2023-02-21 09:09:37.784 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:37.785 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:37.785 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:37.786 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:37.788 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:37.789 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:37.790 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:37.791 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:37.792 - [INFO] callbacks.on_experiment_start(166): Start running experiment
2023-02-21 09:09:37.794 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:37.912 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:37.914 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:38.035 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
0.04
2023-02-21 09:09:38.037 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:38.341 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:38.344 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:38.349 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:38.914 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:38.915 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:38.922 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:39.441 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:39.442 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:39.448 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:39.986 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:39.987 - [NOTICE] callbacks.on_cycle_start(174): Cycle 1/2 (16.366 us elapsed) --------------------
2023-02-21 09:09:39.988 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:39.993 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:40.141 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:41.853 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:41.858 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:41.990 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:42.685 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:09:42.690 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:42.834 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:44.378 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 4/4: Rest for 1 hour
2023-02-21 09:09:45.649 - [NOTICE] callbacks.on_cycle_start(174): Cycle 2/2 (5.662 s elapsed) --------------------
2023-02-21 09:09:45.650 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:47.096 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:47.757 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:09:49.184 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 4/4: Rest for 1 hour
2023-02-21 09:09:49.955 - [NOTICE] callbacks.on_experiment_end(222): Finish experiment simulation, took 9.968 s
2023-02-21 09:09:49.956 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:49.957 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:49.958 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:49.959 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:49.960 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Discharge at C/2 until 3.0 V', using temperature from parameter values.
2023-02-21 09:09:49.961 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:49.962 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Charge at C/2 until 4.2 V', using temperature from parameter values.
2023-02-21 09:09:49.963 - [WARNING] experiment._read_and_drop_temperature(431): Temperature not found on step: 'Rest for 1 hour', using temperature from parameter values.
2023-02-21 09:09:49.964 - [INFO] callbacks.on_experiment_start(166): Start running experiment
2023-02-21 09:09:49.966 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:50.085 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:50.088 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:50.206 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
0.1
2023-02-21 09:09:50.209 - [INFO] parameter_values.process_model(425): Start setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:50.322 - [INFO] parameter_values.process_model(527): Finish setting parameters for Doyle-Fuller-Newman model
2023-02-21 09:09:50.326 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:50.332 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:50.868 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:50.869 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:50.877 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:51.557 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:51.557 - [INFO] discretisation.process_model(147): Start discretising Doyle-Fuller-Newman model
2023-02-21 09:09:51.563 - [INFO] discretisation.remove_independent_variables_from_rhs(1120): removing variable Discharge capacity [A.h] from rhs
2023-02-21 09:09:52.101 - [INFO] discretisation.process_model(259): Finish discretising Doyle-Fuller-Newman model
2023-02-21 09:09:52.101 - [NOTICE] callbacks.on_cycle_start(174): Cycle 1/2 (16.504 us elapsed) --------------------
2023-02-21 09:09:52.102 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:52.108 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:52.250 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:54.101 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:54.107 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:54.236 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:54.910 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:09:54.914 - [INFO] base_solver.set_up(111): Start solver set-up
2023-02-21 09:09:55.056 - [INFO] base_solver.set_up(236): Finish solver set-up
2023-02-21 09:09:56.719 - [NOTICE] callbacks.on_step_start(182): Cycle 1/2, step 4/4: Rest for 1 hour
2023-02-21 09:09:57.598 - [NOTICE] callbacks.on_cycle_start(174): Cycle 2/2 (5.496 s elapsed) --------------------
2023-02-21 09:09:57.598 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 1/4: Discharge at C/2 until 3.0 V
2023-02-21 09:09:59.232 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 2/4: Rest for 1 hour
2023-02-21 09:09:59.886 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 3/4: Charge at C/2 until 4.2 V
2023-02-21 09:10:01.516 - [NOTICE] callbacks.on_step_start(182): Cycle 2/2, step 4/4: Rest for 1 hour
2023-02-21 09:10:02.299 - [NOTICE] callbacks.on_experiment_end(222): Finish experiment simulation, took 10.198 s
running time: 76.058786603s

Cycling Results#

The previously displayed single discharge results can be extended to the cycling solution. As an example, voltage is displayed below.

[12]:
ltype = ["k-", "r--", "b-.", "g:", "m-", "c--", "y-."]
for i in range(0, len(v_si)):
    t_i = solution[i]["Time [s]"].entries / 3600
    V_i = solution[i]["Voltage [V]"].entries
    plt.plot(t_i, V_i, ltype[i], label="$V_\mathrm{si}=$" + str(v_si[i]))
plt.xlabel("Time [h]")
plt.ylabel("Voltage [V]")
plt.legend()
[12]:
<matplotlib.legend.Legend at 0x12c290850>
../../../../_images/source_examples_notebooks_models_composite_particle_26_1.png

References#

The relevant papers for this notebook are:

[13]:
pybamm.print_citations()
[1] Weilong Ai, Niall Kirkaldy, Yang Jiang, Gregory Offer, Huizhi Wang, and Billy Wu. A composite electrode model for lithium-ion batteries with silicon/graphite negative electrodes. Journal of Power Sources, 527:231142, 2022. URL: https://www.sciencedirect.com/science/article/pii/S0378775322001604, doi:https://doi.org/10.1016/j.jpowsour.2022.231142.
[2] 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.
[3] 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.
[4] 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.
[5] 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.
[6] 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.
[7] 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.
[8] 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.