diff --git a/examples/scripts/calendar_ageing.py b/examples/scripts/calendar_ageing.py index 3d37f296d5..1eb35d429a 100644 --- a/examples/scripts/calendar_ageing.py +++ b/examples/scripts/calendar_ageing.py @@ -5,9 +5,13 @@ models = [ pb.lithium_ion.SPM({"sei": "reaction limited"}), + pb.lithium_ion.SPMe({"sei": "reaction limited"}), pb.lithium_ion.SPM( {"sei": "reaction limited", "surface form": "algebraic"}, name="Algebraic SPM" ), + pb.lithium_ion.SPMe( + {"sei": "reaction limited", "surface form": "algebraic"}, name="Algebraic SPMe" + ), pb.lithium_ion.DFN({"sei": "reaction limited"}), ] diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index acfd940f12..cf59e1fdc8 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -81,22 +81,31 @@ def set_tortuosity_submodels(self): def set_interfacial_submodel(self): - self.submodels["negative interface"] = pybamm.interface.InverseButlerVolmer( - self.param, "Negative", "lithium-ion main", self.options - ) - self.submodels["positive interface"] = pybamm.interface.InverseButlerVolmer( - self.param, "Positive", "lithium-ion main", self.options - ) - self.submodels[ - "negative interface current" - ] = pybamm.interface.CurrentForInverseButlerVolmer( - self.param, "Negative", "lithium-ion main" - ) - self.submodels[ - "positive interface current" - ] = pybamm.interface.CurrentForInverseButlerVolmer( - self.param, "Positive", "lithium-ion main" - ) + if self.options["surface form"] is False: + self.submodels["negative interface"] = pybamm.interface.InverseButlerVolmer( + self.param, "Negative", "lithium-ion main", self.options + ) + self.submodels["positive interface"] = pybamm.interface.InverseButlerVolmer( + self.param, "Positive", "lithium-ion main", self.options + ) + self.submodels[ + "negative interface current" + ] = pybamm.interface.CurrentForInverseButlerVolmer( + self.param, "Negative", "lithium-ion main" + ) + self.submodels[ + "positive interface current" + ] = pybamm.interface.CurrentForInverseButlerVolmer( + self.param, "Positive", "lithium-ion main" + ) + else: + self.submodels["negative interface"] = pybamm.interface.ButlerVolmer( + self.param, "Negative", "lithium-ion main", self.options + ) + + self.submodels["positive interface"] = pybamm.interface.ButlerVolmer( + self.param, "Positive", "lithium-ion main", self.options + ) def set_particle_submodel(self): @@ -137,6 +146,8 @@ def set_positive_electrode_submodel(self): def set_electrolyte_submodel(self): + surf_form = pybamm.electrolyte_conductivity.surface_potential_form + if self.options["electrolyte conductivity"] not in [ "default", "composite", @@ -158,17 +169,15 @@ def set_electrolyte_submodel(self): "electrolyte conductivity" ] = pybamm.electrolyte_conductivity.Integrated(self.param) elif self.options["surface form"] == "differential": - raise NotImplementedError( - "surface form '{}' has not been implemented for SPMe yet".format( - self.options["surface form"] - ) - ) + for domain in ["Negative", "Separator", "Positive"]: + self.submodels[ + domain.lower() + " electrolyte conductivity" + ] = surf_form.CompositeDifferential(self.param, domain) elif self.options["surface form"] == "algebraic": - raise NotImplementedError( - "surface form '{}' has not been implemented for SPMe yet".format( - self.options["surface form"] - ) - ) + for domain in ["Negative", "Separator", "Positive"]: + self.submodels[ + domain.lower() + " electrolyte conductivity" + ] = surf_form.CompositeAlgebraic(self.param, domain) self.submodels["electrolyte diffusion"] = pybamm.electrolyte_diffusion.Full( self.param diff --git a/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/__init__.py b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/__init__.py index 985cb52531..ecec3243ec 100644 --- a/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/__init__.py +++ b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/__init__.py @@ -1,6 +1,12 @@ # Full order models from .full_surface_form_conductivity import FullAlgebraic, FullDifferential +# Composite models +from .composite_surface_form_conductivity import ( + CompositeDifferential, + CompositeAlgebraic, +) + # Leading-order models from .leading_surface_form_conductivity import ( LeadingOrderDifferential, diff --git a/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/composite_surface_form_conductivity.py b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/composite_surface_form_conductivity.py new file mode 100644 index 0000000000..0cd28f6757 --- /dev/null +++ b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/composite_surface_form_conductivity.py @@ -0,0 +1,158 @@ +# +# Class for composite surface form electrolyte conductivity employing stefan-maxwell +# +import pybamm + +from ..composite_conductivity import Composite + + +class BaseModel(Composite): + """ + Base class for composite conservation of charge in the electrolyte employing + the Stefan-Maxwell constitutive equations employing the surface potential difference + formulation. + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + domain : str + The domain in which the model holds + reactions : dict + Dictionary of reaction terms + + **Extends:** :class:`pybamm.electrolyte_conductivity.Composite` + """ + + def __init__(self, param, domain): + super().__init__(param, domain) + + def get_fundamental_variables(self): + + if self.domain == "Negative": + delta_phi = pybamm.standard_variables.delta_phi_n_av + elif self.domain == "Separator": + return {} + elif self.domain == "Positive": + delta_phi = pybamm.standard_variables.delta_phi_p_av + + variables = self._get_standard_surface_potential_difference_variables(delta_phi) + return variables + + def set_initial_conditions(self, variables): + + if self.domain == "Separator": + return + + delta_phi = variables[ + "X-averaged " + + self.domain.lower() + + " electrode surface potential difference" + ] + if self.domain == "Negative": + delta_phi_init = self.param.U_n(self.param.c_n_init(0), self.param.T_init) + elif self.domain == "Positive": + delta_phi_init = self.param.U_p(self.param.c_p_init(1), self.param.T_init) + + self.initial_conditions = {delta_phi: delta_phi_init} + + def set_boundary_conditions(self, variables): + if self.domain == "Negative": + phi_e = variables["Electrolyte potential"] + self.boundary_conditions = { + phi_e: { + "left": (pybamm.Scalar(0), "Neumann"), + "right": (pybamm.Scalar(0), "Neumann"), + } + } + + +class CompositeDifferential(BaseModel): + """ + Composite model for conservation of charge in the electrolyte employing the + Stefan-Maxwell constitutive equations employing the surface potential difference + formulation and where capacitance is present. + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + + + **Extends:** :class:`BaseModel` + """ + + def __init__(self, param, domain): + super().__init__(param, domain) + + def set_rhs(self, variables): + if self.domain == "Separator": + return + + param = self.param + + sum_j = variables[ + "Sum of x-averaged " + + self.domain.lower() + + " electrode interfacial current densities" + ] + + sum_j_av = variables[ + "X-averaged " + + self.domain.lower() + + " electrode total interfacial current density" + ] + delta_phi = variables[ + "X-averaged " + + self.domain.lower() + + " electrode surface potential difference" + ] + + if self.domain == "Negative": + C_dl = param.C_dl_n + elif self.domain == "Positive": + C_dl = param.C_dl_p + + self.rhs[delta_phi] = 1 / C_dl * (sum_j_av - sum_j) + + +class CompositeAlgebraic(BaseModel): + """ + Composite model for conservation of charge in the electrolyte employing the + Stefan-Maxwell constitutive equations employing the surface potential difference + formulation. + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + + + **Extends:** :class:`BaseModel` + """ + + def __init__(self, param, domain): + super().__init__(param, domain) + + def set_algebraic(self, variables): + if self.domain == "Separator": + return + + sum_j = variables[ + "Sum of x-averaged " + + self.domain.lower() + + " electrode interfacial current densities" + ] + + sum_j_av = variables[ + "X-averaged " + + self.domain.lower() + + " electrode total interfacial current density" + ] + delta_phi = variables[ + "X-averaged " + + self.domain.lower() + + " electrode surface potential difference" + ] + + self.algebraic[delta_phi] = sum_j_av - sum_j