Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fix: added SEI on cracks to total_kinetics.py #2262

Merged
merged 12 commits into from
Sep 12, 2022
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@

- For experiments, the simulation now automatically checks and skips steps that cannot be performed (e.g. "Charge at 1C until 4.2V" from 100% SOC) ([#2212](https://github.com/pybamm-team/PyBaMM/pull/2212))

## Bug fixes

- Added `SEI on cracks` to loop over all interfacial reactions ([#2262](https://github.com/pybamm-team/PyBaMM/pull/2262))
- Fixed `X-averaged SEI on cracks concentration` so it's an average over x only, not y and z ([#2262](https://github.com/pybamm-team/PyBaMM/pull/2262))
- Corrected initial state for SEI on cracks ([#2262](https://github.com/pybamm-team/PyBaMM/pull/2262))

## Optimizations

- Default options for `particle mechanics` now dealt with differently in each electrode ([#2262](https://github.com/pybamm-team/PyBaMM/pull/2262))
- Sped up calculations of Electrode SOH variables for summary variables ([#2210](https://github.com/pybamm-team/PyBaMM/pull/2210))

## Breaking changes
Expand Down
76 changes: 45 additions & 31 deletions examples/notebooks/models/SEI-on-cracks.ipynb

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,21 @@ def __init__(self, extra_options):
# The "SEI film resistance" option will still be overridden by extra_options if
# provided

# Change the default for particle mechanics based on which SEI on cracks option
# is provided
# return "false" if option not given
# Change the default for particle mechanics based on which SEI on cracks and LAM
# options are provided
# return "false" and "none" respectively if options not given
SEI_cracks_option = extra_options.get("SEI on cracks", "false")
LAM_opt = extra_options.get("loss of active material", "none")
if SEI_cracks_option == "true":
default_options["particle mechanics"] = "swelling and cracking"
if "stress-driven" in LAM_opt or "stress and reaction-driven" in LAM_opt:
default_options["particle mechanics"] = (
"swelling and cracking", "swelling only"
)
else:
default_options["particle mechanics"] = (
"swelling and cracking", "none"
)
else:
# Change the default for particle mechanics based on which LAM option is
# provided
# return "none" if option not given
LAM_opt = extra_options.get("loss of active material", "none")
if "stress-driven" in LAM_opt or "stress and reaction-driven" in LAM_opt:
default_options["particle mechanics"] = "swelling only"
else:
Expand Down
19 changes: 14 additions & 5 deletions pybamm/models/submodels/interface/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,16 +301,25 @@ def _get_standard_volumetric_current_density_variables(self, variables):
a_j_av = pybamm.x_average(a_j)
a_j_scale = self.param.i_typ / self.param.L_x

if reaction_name == "SEI on cracks ":
roughness = variables["Negative electrode roughness ratio"] - 1
roughness_av = variables[
"X-averaged negative electrode roughness ratio"
] - 1
else:
roughness = 1
roughness_av = 1

variables.update(
{
f"{Domain} electrode {reaction_name}volumetric "
"interfacial current density": a_j,
"interfacial current density": a_j * roughness,
f"X-averaged {domain} electrode {reaction_name}volumetric "
"interfacial current density": a_j_av,
"interfacial current density": a_j_av * roughness_av,
f"{Domain} electrode {reaction_name}volumetric "
"interfacial current density [A.m-3]": a_j_scale * a_j,
f"X-averaged {domain} electrode {reaction_name}volumetric "
"interfacial current density [A.m-3]": a_j_scale * a_j_av,
"interfacial current density [A.m-3]": a_j_scale * a_j * roughness,
f"X-averaged {domain} electrode {reaction_name}volumetric interfacial "
"current density [A.m-3]": a_j_scale * a_j_av * roughness_av,
}
)
return variables
Expand Down
17 changes: 10 additions & 7 deletions pybamm/models/submodels/interface/sei/base_sei.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ def _get_standard_concentration_variables(self, variables):
n_outer_av = pybamm.x_average(n_outer)

n_SEI = n_inner + n_outer / v_bar # SEI concentration
n_SEI_av = pybamm.yz_average(pybamm.x_average(n_SEI))
n_SEI_xav = pybamm.x_average(n_SEI)
n_SEI_av = pybamm.yz_average(n_SEI_xav)

# Calculate change in SEI concentration with respect to initial state
delta_n_SEI = n_SEI_av - (L_inner_0 + L_outer_0 / v_bar)
Expand All @@ -230,7 +231,7 @@ def _get_standard_concentration_variables(self, variables):
"X-averaged outer SEI concentration [mol.m-3]": n_outer_av
* n_outer_scale,
"SEI concentration [mol.m-3]": n_SEI * n_scale,
"X-averaged SEI concentration [mol.m-3]": n_SEI_av * n_scale,
"X-averaged SEI concentration [mol.m-3]": n_SEI_xav * n_scale,
"Loss of lithium to SEI [mol]": Q_sei,
"Loss of capacity to SEI [A.h]": Q_sei * self.param.F / 3600,
}
Expand All @@ -248,11 +249,13 @@ def _get_standard_concentration_variables(self, variables):
n_outer_cr_av = pybamm.x_average(n_outer_cr)

n_SEI_cr = n_inner_cr + n_outer_cr / v_bar # SEI on cracks concentration
n_SEI_cr_av = pybamm.yz_average(pybamm.x_average(n_SEI_cr))
n_SEI_cr_xav = pybamm.x_average(n_SEI_cr)
n_SEI_cr_av = pybamm.yz_average(n_SEI_cr_xav)

# Calculate change in SEI cracks concentration with respect to initial state
rho_cr = param.n.rho_cr
n_SEI_cr_init = 2 * rho_cr * (L_inner_0 + L_outer_0 / v_bar) / 10000
# Calculate change in SEI cracks concentration
# Initial state depends on roughness (to avoid division by zero)
roughness_av = pybamm.x_average(roughness)
n_SEI_cr_init = (L_inner_0 + L_outer_0 / v_bar) * (roughness_av - 1) / 10000
delta_n_SEI_cr = n_SEI_cr_av - n_SEI_cr_init

# Q_sei_cr in mol
Expand All @@ -275,7 +278,7 @@ def _get_standard_concentration_variables(self, variables):
"X-averaged outer SEI on cracks "
"concentration [mol.m-3]": n_outer_cr_av * n_outer_scale,
"SEI on cracks concentration [mol.m-3]": n_SEI_cr * n_scale,
"X-averaged SEI on cracks concentration [mol.m-3]": n_SEI_cr_av
"X-averaged SEI on cracks concentration [mol.m-3]": n_SEI_cr_xav
* n_scale,
"Loss of lithium to SEI on cracks [mol]": Q_sei_cr,
"Loss of capacity to SEI on cracks [A.h]": Q_sei_cr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,15 @@ def test_options(self):
)
}
)

# check default options change
model = pybamm.BaseBatteryModel({"loss of active material": "stress-driven"})
self.assertEqual(model.options["particle mechanics"], "swelling only")
self.assertEqual(model.options["stress-induced diffusion"], "true")
model = pybamm.BaseBatteryModel({"SEI on cracks": "true"})
self.assertEqual(model.options["particle mechanics"], "swelling and cracking")
model = pybamm.BaseBatteryModel({
"loss of active material": "stress-driven",
"SEI on cracks": "true"
})
self.assertEqual(model.options["particle mechanics"], (
"swelling and cracking", "swelling only"
))
self.assertEqual(model.options["stress-induced diffusion"], "true")

# crack model
Expand Down