Source code for pybamm.models.submodels.porosity.reaction_driven_porosity
#
# Class for reaction driven porosity changes as a multiple of SEI/plating thicknesses
#
import pybamm
from .base_porosity import BaseModel
[docs]
class ReactionDriven(BaseModel):
"""Reaction-driven porosity changes as a multiple of SEI/plating thicknesses
Parameters
----------
param : parameter class
The parameters to use for this submodel
options : dict
Options dictionary passed from the full model
x_average : bool
Whether to use x-averaged variables (SPM, SPMe, etc) or full variables (DFN)
"""
def __init__(self, param, options, x_average):
super().__init__(param, options)
self.x_average = x_average
[docs]
def get_coupled_variables(self, variables):
eps_dict = {}
for domain in self.options.whole_cell_domains:
delta_eps_k = 0
if domain != "separator": # separator porosity does not change
dom = domain.split()[0]
Domain = dom.capitalize()
SEI_option = getattr(self.options, dom)["SEI"]
phases_option = getattr(self.options, dom)["particle phases"]
phases = self.options.phases[dom]
for phase in phases:
if phases_option == "1" and phase == "primary":
# `domain` has one phase
phase_name = ""
pref = ""
else:
# `domain` has more than one phase
phase_name = phase + " "
pref = phase.capitalize() + ": "
a_k = variables[
f"{Domain} electrode {phase_name}"
"surface area to volume ratio [m-1]"
]
if SEI_option == "none":
L_sei_0 = pybamm.Scalar(0)
else:
L_sei_0 = pybamm.Parameter(f"{pref}Initial SEI thickness [m]")
L_sei_k = variables[f"{Domain} {phase_name}SEI thickness [m]"]
L_pl_k = variables[
f"{Domain} {phase_name}lithium plating thickness [m]"
]
L_dead_k = variables[
f"{Domain} {phase_name}dead lithium thickness [m]"
]
L_sei_cr_k = variables[
f"{Domain} {phase_name}SEI on cracks thickness [m]"
]
roughness_k = variables[
f"{Domain} {phase_name}electrode roughness ratio"
]
L_tot = (
(L_sei_k - L_sei_0)
+ L_pl_k
+ L_dead_k
+ L_sei_cr_k * (roughness_k - 1)
)
# This assumes a thin film so curvature effects are neglected.
# They could be included (e.g. for a sphere it is
# a_n * (L_tot + L_tot ** 2 / R_n + L_tot ** # 3 / (3 * R_n ** 2)))
# but it is not clear if it is relevant or not.
delta_eps_k += -a_k * L_tot
domain_param = self.param.domain_params[domain.split()[0]]
eps_k = domain_param.epsilon_init + delta_eps_k
eps_dict[domain] = eps_k
variables = self._get_standard_porosity_variables(eps_dict)
return variables
[docs]
def add_events_from(self, variables):
eps_p = variables["Positive electrode porosity"]
self.events.append(
pybamm.Event(
"Zero positive electrode porosity cut-off",
pybamm.min(eps_p),
pybamm.EventType.TERMINATION,
)
)
self.events.append(
pybamm.Event(
"Max positive electrode porosity cut-off",
1 - pybamm.max(eps_p),
pybamm.EventType.TERMINATION,
)
)
if "negative electrode" in self.options.whole_cell_domains:
eps_n = variables["Negative electrode porosity"]
self.events.append(
pybamm.Event(
"Zero negative electrode porosity cut-off",
pybamm.min(eps_n),
pybamm.EventType.TERMINATION,
)
)
self.events.append(
pybamm.Event(
"Max negative electrode porosity cut-off",
1 - pybamm.max(eps_n),
pybamm.EventType.TERMINATION,
)
)