#
# Lead-acid LOQS model
#
import pybamm
from .base_lead_acid_model import BaseModel
[docs]
class LOQS(BaseModel):
"""
Leading-Order Quasi-Static model for lead-acid, from
:footcite:t:`Sulzer2019asymptotic`.
See :class:`pybamm.lead_acid.BaseModel` for more details.
"""
def __init__(self, options=None, name="LOQS model", build=True):
super().__init__(options, name)
self.set_external_circuit_submodel()
self.set_open_circuit_potential_submodel()
self.set_intercalation_kinetics_submodel()
self.set_interface_utilisation_submodel()
self.set_convection_submodel()
self.set_porosity_submodel()
self.set_active_material_submodel()
self.set_transport_efficiency_submodels()
self.set_electrolyte_submodel()
self.set_electrode_submodels()
self.set_thermal_submodel()
self.set_surface_temperature_submodel()
self.set_side_reaction_submodels()
self.set_current_collector_submodel()
self.set_sei_submodel()
self.set_lithium_plating_submodel()
self.set_total_interface_submodel()
if build:
self.build_model()
if self.options["dimensionality"] == 0:
self.use_jacobian = False
pybamm.citations.register("Sulzer2019asymptotic")
[docs]
def set_external_circuit_submodel(self):
"""
Define how the external circuit defines the boundary conditions for the model,
e.g. (not necessarily constant-) current, voltage, etc
"""
if self.options["operating mode"] == "current":
self.submodels["external circuit"] = (
pybamm.external_circuit.ExplicitCurrentControl(self.param, self.options)
)
elif self.options["operating mode"] == "voltage":
self.submodels["external circuit"] = (
pybamm.external_circuit.VoltageFunctionControl(self.param, self.options)
)
elif self.options["operating mode"] == "power":
self.submodels["external circuit"] = (
pybamm.external_circuit.PowerFunctionControl(self.param, self.options)
)
elif callable(self.options["operating mode"]):
self.submodels["external circuit"] = (
pybamm.external_circuit.FunctionControl(
self.param, self.options["operating mode"], self.options
)
)
@property
def default_solver(self):
return pybamm.CasadiSolver()
def set_current_collector_submodel(self):
if self.options["current collector"] in [
"uniform",
"potential pair quite conductive",
]:
submodel = pybamm.current_collector.Uniform(self.param)
elif self.options["current collector"] == "potential pair":
if self.options["dimensionality"] == 1:
submodel = pybamm.current_collector.PotentialPair1plus1D(self.param)
elif self.options["dimensionality"] == 2:
submodel = pybamm.current_collector.PotentialPair2plus1D(self.param)
self.submodels["leading-order current collector"] = submodel
def set_porosity_submodel(self):
self.submodels["leading-order porosity"] = pybamm.porosity.ReactionDrivenODE(
self.param, self.options, True
)
def set_convection_submodel(self):
if self.options["convection"] == "none":
self.submodels["leading-order transverse convection"] = (
pybamm.convection.transverse.NoConvection(self.param)
)
self.submodels["leading-order through-cell convection"] = (
pybamm.convection.through_cell.NoConvection(self.param)
)
else:
if self.options["convection"] == "uniform transverse":
self.submodels["leading-order transverse convection"] = (
pybamm.convection.transverse.Uniform(self.param)
)
elif self.options["convection"] == "full transverse":
self.submodels["leading-order transverse convection"] = (
pybamm.convection.transverse.Full(self.param)
)
self.submodels["leading-order through-cell convection"] = (
pybamm.convection.through_cell.Explicit(self.param)
)
def set_intercalation_kinetics_submodel(self):
if self.options["surface form"] == "false":
self.submodels["leading-order negative interface"] = (
pybamm.kinetics.InverseButlerVolmer(
self.param, "negative", "lead-acid main", self.options
)
)
self.submodels["leading-order positive interface"] = (
pybamm.kinetics.InverseButlerVolmer(
self.param, "positive", "lead-acid main", self.options
)
)
self.submodels["negative interface current"] = (
pybamm.kinetics.CurrentForInverseKinetics(
self.param, "negative", "lead-acid main"
)
)
self.submodels["positive interface current"] = (
pybamm.kinetics.CurrentForInverseKinetics(
self.param, "positive", "lead-acid main"
)
)
else:
self.submodels["leading-order negative interface"] = (
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "negative", "lead-acid main", self.options, "primary"
)
)
self.submodels["leading-order positive interface"] = (
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "positive", "lead-acid main", self.options, "primary"
)
)
# always use forward Butler-Volmer for the reaction submodel to be passed to the
# higher order model
self.reaction_submodels = {
"negative": [
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "negative", "lead-acid main", self.options, "primary"
)
],
"positive": [
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "positive", "lead-acid main", self.options, "primary"
)
],
}
def set_electrode_submodels(self):
self.submodels["leading-order negative electrode potential"] = (
pybamm.electrode.ohm.LeadingOrder(self.param, "negative")
)
self.submodels["leading-order positive electrode potential"] = (
pybamm.electrode.ohm.LeadingOrder(self.param, "positive")
)
def set_electrolyte_submodel(self):
surf_form = pybamm.electrolyte_conductivity.surface_potential_form
if self.options["surface form"] == "false":
self.submodels["leading-order electrolyte conductivity"] = (
pybamm.electrolyte_conductivity.LeadingOrder(self.param)
)
surf_model = surf_form.Explicit
elif self.options["surface form"] == "differential":
surf_model = surf_form.LeadingOrderDifferential
elif self.options["surface form"] == "algebraic":
surf_model = surf_form.LeadingOrderAlgebraic
for domain in ["negative", "positive"]:
self.submodels[f"{domain} surface potential difference"] = surf_model(
self.param, domain, self.options
)
self.submodels["electrolyte diffusion"] = (
pybamm.electrolyte_diffusion.LeadingOrder(self.param)
)
def set_side_reaction_submodels(self):
if self.options["hydrolysis"] == "true":
self.submodels["leading-order oxygen diffusion"] = (
pybamm.oxygen_diffusion.LeadingOrder(self.param)
)
self.submodels["leading-order positive oxygen interface"] = (
pybamm.kinetics.ForwardTafel(
self.param, "positive", "lead-acid oxygen", self.options, "primary"
)
)
self.submodels["leading-order negative oxygen interface"] = (
pybamm.kinetics.DiffusionLimited(
self.param,
"negative",
"lead-acid oxygen",
self.options,
order="leading",
)
)
else:
self.submodels["leading-order oxygen diffusion"] = (
pybamm.oxygen_diffusion.NoOxygen(self.param)
)
self.submodels["leading-order negative oxygen interface"] = (
pybamm.kinetics.NoReaction(
self.param, "negative", "lead-acid oxygen", "primary"
)
)
self.submodels["leading-order positive oxygen interface"] = (
pybamm.kinetics.NoReaction(
self.param, "positive", "lead-acid oxygen", "primary"
)
)
self.reaction_submodels["negative"].append(
self.submodels["leading-order negative oxygen interface"]
)
self.reaction_submodels["positive"].append(
self.submodels["leading-order positive oxygen interface"]
)