Source code for pybamm.models.submodels.porosity.reaction_driven_porosity_ode
#
# Class for reaction driven porosity changes as an ODE
#
import pybamm
from .base_porosity import BaseModel
[docs]
class ReactionDrivenODE(BaseModel):
"""Reaction-driven porosity changes as an ODE
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_fundamental_variables(self):
eps_dict = {}
for domain in self.options.whole_cell_domains:
Domain = domain.capitalize()
if self.x_average is True:
eps_k_av = pybamm.Variable(
f"X-averaged {domain} porosity",
domain="current collector",
bounds=(0, 1),
)
eps_k = pybamm.PrimaryBroadcast(eps_k_av, domain)
else:
eps_k = pybamm.Variable(
f"{Domain} porosity",
domain=domain,
auxiliary_domains={"secondary": "current collector"},
bounds=(0, 1),
)
eps_dict[domain] = eps_k
variables = self._get_standard_porosity_variables(eps_dict)
return variables
[docs]
def get_coupled_variables(self, variables):
depsdt_dict = {}
for domain in self.options.whole_cell_domains:
domain_param = self.param.domain_params[domain.split()[0]]
if domain == "separator":
depsdt_k = pybamm.FullBroadcast(0, domain, "current collector")
else:
if self.x_average is True:
a_j_k_av = variables[
f"X-averaged {domain} volumetric "
"interfacial current density [A.m-3]"
]
depsdt_k_av = domain_param.DeltaVsurf * a_j_k_av / self.param.F
depsdt_k = pybamm.PrimaryBroadcast(depsdt_k_av, domain)
else:
Domain = domain.capitalize()
a_j_k = variables[
f"{Domain} volumetric interfacial current density [A.m-3]"
]
depsdt_k = domain_param.DeltaVsurf * a_j_k / self.param.F
depsdt_dict[domain] = depsdt_k
variables.update(self._get_standard_porosity_change_variables(depsdt_dict))
return variables
[docs]
def set_rhs(self, variables):
if self.x_average is True:
for domain in self.options.whole_cell_domains:
eps_av = variables[f"X-averaged {domain} porosity"]
deps_dt_av = variables[f"X-averaged {domain} porosity change [s-1]"]
self.rhs.update({eps_av: deps_dt_av})
else:
eps = variables["Porosity"]
deps_dt = variables["Porosity change"]
self.rhs = {eps: deps_dt}
[docs]
def set_initial_conditions(self, variables):
if self.x_average is True:
for domain in self.options.whole_cell_domains:
eps_k_av = variables[f"X-averaged {domain} porosity"]
domain_param = self.param.domain_params[domain.split()[0]]
self.initial_conditions[eps_k_av] = domain_param.epsilon_init
else:
eps = variables["Porosity"]
self.initial_conditions = {eps: self.param.epsilon_init}
[docs]
def add_events_from(self, variables):
for domain in self.options.whole_cell_domains:
if domain == "separator":
continue
Domain = domain.capitalize()
eps_k = variables[f"{Domain} porosity"]
self.events.append(
pybamm.Event(
f"Zero {domain} porosity cut-off",
pybamm.min(eps_k),
pybamm.EventType.TERMINATION,
)
)
self.events.append(
pybamm.Event(
f"Max {domain} porosity cut-off",
1 - pybamm.max(eps_k),
pybamm.EventType.TERMINATION,
)
)