Source code for pybamm.models.full_battery_models.lithium_ion.dfn

#
# Doyle-Fuller-Newman (DFN) Model
#
import pybamm

from .base_lithium_ion_model import BaseModel


[docs] class DFN(BaseModel): """ Doyle-Fuller-Newman (DFN) model of a lithium-ion battery, from :footcite:t:`Marquis2019`. See :class:`pybamm.lithium_ion.BaseModel` for more details. Examples -------- >>> model = pybamm.lithium_ion.DFN() >>> model.name 'Doyle-Fuller-Newman model' """ def __init__(self, options=None, name="Doyle-Fuller-Newman model", build=True): # For degradation models we use the full form since this is a full-order model self.x_average = False super().__init__(options, name) self.set_submodels(build) pybamm.citations.register("Doyle1993") def set_intercalation_kinetics_submodel(self): for domain in ["negative", "positive"]: electrode_type = self.options.electrode_types[domain] if electrode_type == "porous": intercalation_kinetics = self.get_intercalation_kinetics(domain) phases = self.options.phases[domain] for phase in phases: submod = intercalation_kinetics( self.param, domain, "lithium-ion main", self.options, phase ) self.submodels[f"{domain} {phase} interface"] = submod if len(phases) > 1: self.submodels[f"total {domain} interface"] = ( pybamm.kinetics.TotalMainKinetics( self.param, domain, "lithium-ion main", self.options ) ) def set_particle_submodel(self): for domain in ["negative", "positive"]: if self.options.electrode_types[domain] == "planar": continue particle = getattr(self.options, domain)["particle"] for phase in self.options.phases[domain]: if particle == "Fickian diffusion": submod = pybamm.particle.FickianDiffusion( self.param, domain, self.options, phase=phase, x_average=False ) elif particle in [ "uniform profile", "quadratic profile", "quartic profile", ]: submod = pybamm.particle.PolynomialProfile( self.param, domain, self.options, phase=phase ) elif particle == "MSMR": submod = pybamm.particle.MSMRDiffusion( self.param, domain, self.options, phase=phase, x_average=False ) # also set the submodel for calculating stoichiometry from # potential self.submodels[f"{domain} {phase} stoichiometry"] = ( pybamm.particle.MSMRStoichiometryVariables( self.param, domain, self.options, phase=phase, x_average=False, ) ) self.submodels[f"{domain} {phase} particle"] = submod self.submodels[f"{domain} {phase} total particle concentration"] = ( pybamm.particle.TotalConcentration( self.param, domain, self.options, phase ) ) def set_solid_submodel(self): for domain in ["negative", "positive"]: if self.options.electrode_types[domain] == "planar": continue if self.options["surface form"] == "false": submodel = pybamm.electrode.ohm.Full else: submodel = pybamm.electrode.ohm.SurfaceForm self.submodels[f"{domain} electrode potential"] = submodel( self.param, domain, self.options ) def set_electrolyte_concentration_submodel(self): self.submodels["electrolyte diffusion"] = pybamm.electrolyte_diffusion.Full( self.param, self.options ) def set_electrolyte_potential_submodel(self): surf_form = pybamm.electrolyte_conductivity.surface_potential_form if self.options["electrolyte conductivity"] not in ["default", "full"]: raise pybamm.OptionError( "electrolyte conductivity '{}' not suitable for DFN".format( self.options["electrolyte conductivity"] ) ) if self.options["surface form"] == "false": self.submodels["electrolyte conductivity"] = ( pybamm.electrolyte_conductivity.Full(self.param, self.options) ) if self.options["surface form"] == "false": surf_model = surf_form.Explicit elif self.options["surface form"] == "differential": surf_model = surf_form.FullDifferential elif self.options["surface form"] == "algebraic": surf_model = surf_form.FullAlgebraic for domain in ["negative", "separator", "positive"]: if self.options.electrode_types.get(domain) == "planar": continue self.submodels[f"{domain} surface potential difference"] = surf_model( self.param, domain, self.options ) def set_summary_variables(self): self.set_default_summary_variables()