"""
Base Newman isothermal model
"""
import dolfin as fem
import ufl # type: ignore
import mtnlion.formulas.approximation
import mtnlion.formulas.dfn
from mtnlion.formula import Formula
from mtnlion.formulas.approximation import LagrangeMultiplier
from mtnlion.model import Model
from mtnlion.variable import Variable
# pylint: disable=invalid-name
[docs]class Isothermal(Model):
"""
The basic DFN lithium-ion model with no thermal considerations and a 1D approximation of the solid concentration.
"""
def __init__(self, num_functions):
"""
Defines the basic Newman Isothermal model.
:param num_functions: Number of functions to approximate `self.SolidConcentration`
"""
super(Isothermal, self).__init__(minimum_rothes_order=1)
self.Ns = num_functions
self.legendre = mtnlion.formulas.approximation.Legendre(self.Ns)
self.variables = [
Variable("j", ["anode", "cathode"]),
Variable("phi_s", ["anode", "cathode"]),
Variable("phi_e", ["anode", "separator", "cathode"]),
Variable("c_s", ["anode", "cathode"], self.Ns),
Variable("c_e", ["anode", "separator", "cathode"]),
Variable("lm_phis_gnd", ["anode_cc"]),
Variable("lm_phie", ["anode-separator", "separator-cathode"]),
Variable("lm_ce", ["anode-separator", "separator-cathode"]),
]
self.formulas = [
self.IntercalationFlux(),
self.SolidPotential(),
self.ElectrolytePotential(),
self.SolidConcentration(self.legendre),
self.ElectrolyteConcentration(),
self.SolidConcentrationBoundary(),
self.SolidPotentialNeumann(),
self.SolidConcentrationNeumann(),
self.ExchangeCurrentDensity(),
self.Overpotential(),
LagrangeMultiplier(["anode_cc"], "lm_phis_gnd", "phi_s"),
LagrangeMultiplier(["anode-separator", "separator-cathode"], "lm_phie", "phi_e"),
LagrangeMultiplier(["anode-separator", "separator-cathode"], "lm_ce", "c_e"),
self.StateOfCharge(),
self.OpenCircuitPotential(),
self.KappaRef(),
self.KappaEff(),
self.KappaDEff(),
]
[docs] class IntercalationFlux(Formula):
"""
Describes how the electrical current on an electrode depends on the electrode potential.
"""
def __init__(self):
super(Isothermal.IntercalationFlux, self).__init__(domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "j")
self.Parameters = self.typedef("Parameters", "alpha, F, R, T, i0, eta")
[docs] class SolidPotential(Formula):
"""
Charge conservation in the solid.
"""
def __init__(self):
super(Isothermal.SolidPotential, self).__init__(domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "phi_s, j")
self.Parameters = self.typedef("Parameters", "a_s, F, sigma_eff, L")
[docs] class ElectrolytePotential(Formula):
"""
Charge conservation in the electrolyte.
"""
def __init__(self):
super(Isothermal.ElectrolytePotential, self).__init__(domains=["anode", "separator", "cathode"])
self.Variables = self.typedef("Variables", "phi_e, c_e, j")
self.Parameters = self.typedef("Parameters", "L, a_s, F, kappa_eff, kappa_Deff")
self.Formulas = self.typedef("Formulas", "")
[docs] class SolidConcentration(Formula):
"""
Concentration of lithium in the solid, 1D approximation using Legendre polynomials.
"""
def __init__(self, legendre):
super(Isothermal.SolidConcentration, self).__init__(domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "c_s")
self.TimeDiscretization = self.typedef("TimeDiscretization", "dt_cs")
self.Parameters = self.typedef("Parameters", "Rs, Ds_ref")
self.legendre = legendre
[docs] class ElectrolyteConcentration(Formula):
"""
Concentration of lithium in the electrolyte.
"""
def __init__(self):
super(Isothermal.ElectrolyteConcentration, self).__init__(domains=["anode", "separator", "cathode"])
self.Variables = self.typedef("Variables", "c_e, j")
self.Parameters = self.typedef("Parameters", "a_s, De_eff, t_plus, L, eps_e")
self.TimeDiscretization = self.typedef("TimeDiscretization", "dt_ce")
[docs] class SolidConcentrationBoundary(Formula):
"""
This `Formula` defines the value of the lithium concentration at the surface of the solid particle.
"""
def __init__(self):
super(Isothermal.SolidConcentrationBoundary, self).__init__(name="cse", domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "c_s")
[docs] class SolidPotentialNeumann(Formula):
"""
Neumann boundary for the solid potential at the anode/cathode current collector boundaries.
"""
def __init__(self):
super(Isothermal.SolidPotentialNeumann, self).__init__(domains=["anode_cc", "cathode_cc"])
self.Variables = self.typedef("Variables", "phi_s")
self.Parameters = self.typedef("Parameters", "Iapp, Acell")
[docs] class SolidConcentrationNeumann(Formula):
"""
Nuemann boundary for the solid concentration. This `Formula` doesn't use a boundary domain due to the 1D
1D approximation.
"""
def __init__(self):
super(Isothermal.SolidConcentrationNeumann, self).__init__(domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "c_s, j")
[docs] class ExchangeCurrentDensity(Formula):
"""
The exchange current density is the current in the absence of net electrolysis and at zero overpotential.
"""
def __init__(self):
super(Isothermal.ExchangeCurrentDensity, self).__init__(name="i0", domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "c_e")
self.Parameters = self.typedef("Parameters", "csmax, ce0, alpha, k_norm_ref, cse")
[docs] class Overpotential(Formula):
"""
Voltage difference between a reduction potential and the potential of the redox event.
"""
def __init__(self):
super(Isothermal.Overpotential, self).__init__(name="eta", domains=["anode", "cathode"])
self.Variables = self.typedef("Variables", "phi_s, phi_e")
self.Parameters = self.typedef("Parameters", "Uocp")
[docs] class StateOfCharge(Formula):
"""
State of Charge (SOC) formula.
"""
def __init__(self):
super(Isothermal.StateOfCharge, self).__init__(name="soc", domains=["anode", "cathode"])
self.Parameters = self.typedef("Parameters", "csmax, cse")
[docs] class OpenCircuitPotential(Formula):
"""
Open-circuit potential formula.
"""
def __init__(self):
super(Isothermal.OpenCircuitPotential, self).__init__(name="Uocp", domains=["anode", "cathode"])
self.Parameters = self.typedef("Parameters", "soc")
[docs] class KappaRef(Formula):
"""
Bulk conductivity of the homogeneous materials.
"""
def __init__(self):
super(Isothermal.KappaRef, self).__init__(name="kappa_ref", domains=["anode", "separator", "cathode"])
self.Variables = self.typedef("Variables", "c_e")
[docs] class KappaEff(Formula):
"""
Effective conductivity of the electrolyte.
"""
def __init__(self):
super(Isothermal.KappaEff, self).__init__(name="kappa_eff", domains=["anode", "separator", "cathode"])
self.Parameters = self.typedef("Parameters", "eps_e, brug_kappa, kappa_ref")
[docs] class KappaDEff(Formula):
"""
kappa_d effective
"""
def __init__(self):
super(Isothermal.KappaDEff, self).__init__(name="kappa_Deff", domains=["anode", "separator", "cathode"])
self.Parameters = self.typedef("Parameters", "eps_e, kappa_D, kappa_ref")