Source code for cideMOD.models.PXD.degradation.SEI.electron_migration.preprocessing

#
# Copyright (c) 2023 CIDETEC Energy Storage.
#
# This file is part of cideMOD.
#
# cideMOD is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from collections import namedtuple

from cideMOD.numerics.time_scheme import TimeScheme
from cideMOD.numerics.fem_handler import BlockFunction
from cideMOD.cell.components import BatteryCell
from cideMOD.cell.variables import ProblemVariables
from cideMOD.models.PXD.base_model import BasePXDModelPreprocessing


[docs] class MigrationSEIModelPreprocessing(BasePXDModelPreprocessing): """ Base mixin class that contains the mandatory methods to be overrided related to the preprocessing of the model inputs. """ # ******************************************************************************************* # # *** Problem *** # # ******************************************************************************************* #
[docs] def set_state_variables(self, state_vars: list, mesher, V, V_vec, problem) -> None: """ This method sets the state variables of the compact SEI model. Parameters ---------- state_vars : List(Tuple(str, numpy.ndarray, dolfinx.fem.FunctionSpace)) List of tuples, each one containing the name, the subdomain and the function space of the state variable. mesher : BaseMesher Object that contains the mesh information. V : dolfinx.fem.FunctionSpace Common FunctionSpace to be used for each model. V_vec : dolfinx.fem.VectorFunctionSpace Common VectorFunctionSpace to be used for each model. """ res = mesher.get_restrictions() state_vars.extend([(f'j_sei_a{i}', V.clone(), res.anode) for i in range(problem.cell_parser.anode.n_mat)]) state_vars.extend([(f'delta_porous_sei_a{i}', V.clone(), res.anode) for i in range(problem.cell_parser.anode.n_mat)]) state_vars.extend([(f'delta_compact_sei_a{i}', V.clone(), res.anode) for i in range(problem.cell_parser.anode.n_mat)]) state_var_names = [var_name for var_name, _, _ in state_vars] self._state_vars = state_var_names[state_var_names.index('j_sei_a0'):]
[docs] def set_dependent_variables(self, var: ProblemVariables, cell: BatteryCell, DT: TimeScheme, problem): """ This method sets the dependent variables of the electron migration SEI model. Parameters ---------- var: ProblemVariables Object that store the preprocessed problem variables. cell: BatteryCell Object where cell parameters are preprocessed and stored. DT: TimeScheme Object that provide the temporal derivatives with the specified scheme. problem: Problem Object that handles the battery cell simulation. """ # build j_Li var._J_Li = namedtuple('J_Li', var._J_Li._fields + ('SEI',)) electrode = cell.anode var.j_Li_a = var._J_Li._make([var.j_Li_a.total, var.j_Li_a.int, var.j_Li_a.LLI, var.j_Li_a.C_dl, var.j_Li_a.total_0, list()]) for idx in range(len(electrode.active_materials)): # Compact Solid Electrolyte Interphase var.j_Li_a.SEI.append(var.f_1(f'j_sei_{electrode.label}{idx}')) # Lost of Lithium Inventory var.j_Li_a.LLI[idx] += var.j_Li_a.SEI[idx] # Total Li flux var.j_Li_a.total_0[idx] += var.j_Li_a.SEI[idx] var.j_Li_a.total[idx] += var.j_Li_a.SEI[idx] # build j_Li term = sum(j_Li * a_s) j_Li_term = [] for ff, field in enumerate(var.j_Li_a._fields): j_Li_term.append(0) for i, am in enumerate(electrode.active_materials): j_Li_term[ff] += var.j_Li_a._asdict()[field][i] * am.a_s setattr(var, f'j_Li_{electrode.label}_term', var._J_Li._make(j_Li_term)) # Overpotential var.overpotential_sei = [] var.delta_porous_sei_a, var.delta_compact_sei_a = [], [] for i in range(var.n_mat_a): delta_porous_sei = var.f_1(f'delta_porous_sei_a{i}') var.delta_porous_sei_a.append(delta_porous_sei) delta_compact_sei = var.f_1(f'delta_compact_sei_a{i}') var.delta_compact_sei_a.append(delta_compact_sei) G = (cell.anode.SEI.porous.R + var.delta_porous_sei_a[i] / cell.anode.SEI.porous.kappa) var.overpotential_a[i] -= var.j_Li_a.total[i] * G # SEI overpotential var.overpotential_sei.append(var.f_1.phi_s - var.f_1.phi_e - cell.anode.SEI.compact.U - var.j_Li_a.total[i] * G)
[docs] def initial_guess(self, f: BlockFunction, var: ProblemVariables, cell: BatteryCell, problem) -> None: """ This method initializes the state variables based on the initial conditions and assuming that the simulation begins after a stationary state. Parameters ---------- f: BlockFunction Block function that contain the state variables to be initialized. var: ProblemVariables Object that store the preprocessed problem variables. cell: BatteryCell Object where cell parameters are preprocessed and stored. problem: Problem Object that handles the battery cell simulation. """ if var.n_mat_a == 0: # if not cell.anode.is_active: return P1_map = problem.P1_map for material in range(var.n_mat_a): P1_map.interpolate({'anode': cell.anode.SEI.compact.delta0}, f(f'delta_compact_sei_a{material}'), clear=True) P1_map.interpolate({'anode': cell.anode.SEI.porous.delta0}, f(f'delta_porous_sei_a{material}'), clear=True)
[docs] def setup(self, problem): """ This method setup the compact SEI model. Parameters ---------- problem: Problem Object that handles the battery cell simulation. """ self.Q_sei = [0 for _ in range(problem.cell.anode.n_mat)]
# ******************************************************************************************* # # *** DimensionalAnalysis *** # # ******************************************************************************************* # # ******************************************************************************************* # # *** BatteryCell *** # # ******************************************************************************************* #
[docs] def set_compactSEI_parameters(self, compact, problem) -> None: """ This method preprocesses the electrode parameters of the compact SEI model. Parameters ---------- compactSEI: BaseCellComponent Object where electrode parameters are preprocessed and stored. problem: Problem Object that handles the battery cell simulation. """ compact.U = compact.parser.reference_voltage.get_value(problem) compact.beta = compact.parser.charge_transfer_coefficient.get_value(problem) compact.kappa = compact.parser.electron_conductivity.get_value(problem)