Selecting a model
As mentioned in the first tutorial, a model can be thought as a mathematical implementation of the electrochemical and transport phenomena occuring in a real battery cell. The implementation consist of a system of partial differential equations and their corresponding parameters, constants, boundary conditions and assumptions.
The default Lithium-Ion Battery Model corresponds to a basic P2D model, where neither current collectors, degradation nor thermal effects are considered. BattMo has implemented several variants of the Lithium-Ion Battery Model, which can be accessed by configuring the model object. In this tutorial, we’ll configure a P2D model with degradation driven by SEI (Solid Electrolyte Interphase) growth.
Load BattMo and Model Settings
using BattMo, GLMakie
Let’s begin by loading the default model settings for a P2D simulation. This will return a ModelSettings object:
model_settings = load_model_settings(; from_default_set = "P2D")
We can inspect all current settings with:
model_settings.all
Dict{String, Any} with 4 entries:
"RampUp" => "Sinusoidal"
"Metadata" => {…
"TransportInSolid" => "FullDiffusion"
"ModelFramework" => "P2D"
By default, the "SEIModel" parameter is set to false. Since we want to observe SEI-driven degradation effects, we’ll specify which SEI model we'd like to use, and with that enable the use of the SEI model during the simulation. Let's have a look at which models are available to include in the settings:
print_submodels_info()
================================================================================
ℹ️ Submodels Information
================================================================================
Parameter Options Documentation
--------------------------------------------------------------------------------
CurrentCollectors Generic -
SEIModel Bolay ]8;;https://battmoteam.github.io/BattMo.jl/dev/manuals/user_guide/sei_model\visit]8;;\
RampUp Sinusoidal ]8;;https://battmoteam.github.io/BattMo.jl/dev/manuals/user_guide/ramp_up\visit]8;;\
TransportInSolid FullDiffusion -
ModelFramework P2D, P4D Pouch, P4D Cylindrical]8;;https://battmoteam.github.io/BattMo.jl/dev/manuals/user_guide/pxd_model\visit]8;;\
For the SEI model, we can see there's one model to enable which is the "Bolay" model. We enable it in the model settings:
model_settings["SEIModel"] = "Bolay"
model_settings.all
Dict{String, Any} with 5 entries:
"SEIModel" => "Bolay"
"RampUp" => "Sinusoidal"
"Metadata" => {…
"TransportInSolid" => "FullDiffusion"
"ModelFramework" => "P2D"
Initialize the Model
Let’s now create the battery model using the modified settings:
model_setup = LithiumIonBattery(; model_settings);
✔️ Validation of ModelSettings passed: No issues found.
──────────────────────────────────────────────────
When setting up the model, the LithiumIonBattery constructor runs a validation on the model_settings. In this case, because we set the "SEIModel" parameter to true, the validator provides a warning that we should define which SEI model we would like to use. If we ignore any warnings and pass the model to the Simulation constructor then we get an error. Let's create such a situation:
model_settings["SEIModel"] = "Bola"
model_setup = LithiumIonBattery(; model_settings);
🔍 Validation of ModelSettings failed with 1 issue:
──────────────────────────────────────────────────
──────────────────────────────────────────────────
Issue 1:
📍 Where: [SEIModel]
🔢 Provided: Bola
🔑 Rule: enum = ["Bolay"]
🛠 Issue: Value must be one of: Bolay
──────────────────────────────────────────────────
We get a warning that a validation issue has been encountered. For now we ignore it:
cell_parameters_sei = load_cell_parameters(; from_default_set = "Chen2020")
cccv_protocol = load_cycling_protocol(; from_default_set = "CCCV")
sim = Simulation(model_setup, cell_parameters_sei, cccv_protocol)
Oops! Your Model object is not valid. 🛑
TIP: Validation happens when instantiating the Model object.
Check the warnings to see exactly where things went wrong. 🔍
As expected, this results in an error because we didn't specify the SEI model correctly.
Specify SEI Model and Rebuild
Let's resolve the issue again and run the simulation:
model_settings["SEIModel"] = "Bolay"
Now rebuild the model:
model_setup = LithiumIonBattery(; model_settings);
✔️ Validation of ModelSettings passed: No issues found.
──────────────────────────────────────────────────
Now we can setup the simulation and run it.
sim = Simulation(model_setup, cell_parameters_sei, cccv_protocol)
output = solve(sim)
✔️ Validation of CellParameters passed: No issues found.
──────────────────────────────────────────────────
✔️ Validation of CyclingProtocol passed: No issues found.
──────────────────────────────────────────────────
✔️ Validation of SimulationSettings passed: No issues found.
──────────────────────────────────────────────────
Jutul: Simulating 15 hours as 1080 report steps
╭────────────────┬───────────┬───────────────┬────────────╮
│ Iteration type │ Avg/step │ Avg/ministep │ Total │
│ │ 794 steps │ 841 ministeps │ (wasted) │
├────────────────┼───────────┼───────────────┼────────────┤
│ Newton │ 2.85642 │ 2.69679 │ 2268 (525) │
│ Linearization │ 3.91436 │ 3.6956 │ 3108 (551) │
│ Linear solver │ 2.85642 │ 2.69679 │ 2268 (525) │
│ Precond apply │ 0.0 │ 0.0 │ 0 (0) │
╰────────────────┴───────────┴───────────────┴────────────╯
╭───────────────┬────────┬────────────┬────────╮
│ Timing type │ Each │ Relative │ Total │
│ │ ms │ Percentage │ s │
├───────────────┼────────┼────────────┼────────┤
│ Properties │ 0.0420 │ 2.13 % │ 0.0953 │
│ Equations │ 0.6336 │ 44.03 % │ 1.9693 │
│ Assembly │ 0.0740 │ 5.14 % │ 0.2300 │
│ Linear solve │ 0.5844 │ 29.63 % │ 1.3254 │
│ Linear setup │ 0.0000 │ 0.00 % │ 0.0000 │
│ Precond apply │ 0.0000 │ 0.00 % │ 0.0000 │
│ Update │ 0.0569 │ 2.89 % │ 0.1291 │
│ Convergence │ 0.0746 │ 5.18 % │ 0.2318 │
│ Input/Output │ 0.0231 │ 0.43 % │ 0.0194 │
│ Other │ 0.2085 │ 10.57 % │ 0.4728 │
├───────────────┼────────┼────────────┼────────┤
│ Total │ 1.9723 │ 100.00 % │ 4.4731 │
╰───────────────┴────────┴────────────┴────────╯
Plot of voltage and current
states = output[:states]
t = [state[:Control][:Controller].time for state in states]
E = [state[:Control][:Phi][1] for state in states]
I = [state[:Control][:Current][1] for state in states]
f = Figure(size = (1000, 400))
ax = Axis(f[1, 1],
title = "Voltage",
xlabel = "Time / s",
ylabel = "Voltage / V",
xlabelsize = 25,
ylabelsize = 25,
xticklabelsize = 25,
yticklabelsize = 25,
)
scatterlines!(ax,
t,
E;
linewidth = 4,
markersize = 10,
marker = :cross,
markercolor = :black,
label = "Julia",
)
ax = Axis(f[1, 2],
title = "Current",
xlabel = "Time / s",
ylabel = "Current / A",
xlabelsize = 25,
ylabelsize = 25,
xticklabelsize = 25,
yticklabelsize = 25,
)
scatterlines!(ax,
t,
I;
linewidth = 4,
markersize = 10,
marker = :cross,
markercolor = :black,
label = "Julia",
)
Plot of SEI length
We recover the SEI length from the state
output
seilength = [state[:NeAm][:SEIlength][end] for state in states]
f = Figure(size = (1000, 400))
ax = Axis(f[1, 1],
title = "Length",
xlabel = "Time / s",
ylabel = "Length / m",
xlabelsize = 25,
ylabelsize = 25,
xticklabelsize = 25,
yticklabelsize = 25,
)
scatterlines!(ax,
t,
seilength;
linewidth = 4,
markersize = 10,
marker = :cross,
markercolor = :black)
ax = Axis(f[2, 1],
title = "Length",
xlabel = "Time / s",
ylabel = "Voltage / V",
xlabelsize = 25,
ylabelsize = 25,
xticklabelsize = 25,
yticklabelsize = 25,
)
scatterlines!(ax,
t,
E;
linewidth = 4,
markersize = 10,
marker = :cross,
markercolor = :black)
Example on GitHub
If you would like to run this example yourself, it can be downloaded from the BattMo.jl GitHub repository as a script.
This page was generated using Literate.jl.