From 8e8e52853fa7670879d615f020001658c2fda0f4 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 10:43:05 -0500 Subject: [PATCH 01/12] #1245 make submodel for active material --- pybamm/__init__.py | 1 + .../full_battery_models/base_battery_model.py | 8 ++ .../full_battery_models/lithium_ion/dfn.py | 18 ++++ .../full_battery_models/lithium_ion/spm.py | 22 +++++ .../full_battery_models/lithium_ion/spme.py | 22 +++++ .../submodels/active_material/__init__.py | 2 + .../active_material/base_active_material.py | 92 ++++++++++++++++++ .../constant_active_material.py | 42 +++++++++ pybamm/models/submodels/base_submodel.py | 5 +- .../submodels/interface/base_interface.py | 17 +--- .../submodels/interface/sei/base_sei.py | 2 +- .../submodels/interface/sei/constant_sei.py | 2 +- .../interface/sei/ec_reaction_limited.py | 2 +- .../sei/electron_migration_limited.py | 2 +- .../sei/interstitial_diffusion_limited.py | 2 +- .../models/submodels/interface/sei/no_sei.py | 2 +- .../interface/sei/reaction_limited.py | 2 +- .../sei/solvent_diffusion_limited.py | 2 +- .../submodels/particle/base_particle.py | 53 +++++------ .../particle/fickian_many_particles.py | 1 + .../particle/fickian_single_particle.py | 1 + .../particle/polynomial_many_particles.py | 1 + .../particle/polynomial_single_particle.py | 1 + .../particle_cracking/base_cracking.py | 16 ++-- .../particle_cracking/crack_propagation.py | 1 + .../particle_cracking/no_cracking.py | 1 + .../submodels/porosity/base_porosity.py | 19 ---- .../leading_reaction_driven_porosity.py | 8 +- .../tortuosity/bruggeman_tortuosity.py | 4 +- pybamm/parameters/lithium_ion_parameters.py | 94 +++++++++---------- .../test_bruggeman_tortuosity.py | 6 +- 31 files changed, 313 insertions(+), 138 deletions(-) create mode 100644 pybamm/models/submodels/active_material/__init__.py create mode 100644 pybamm/models/submodels/active_material/base_active_material.py create mode 100644 pybamm/models/submodels/active_material/constant_active_material.py diff --git a/pybamm/__init__.py b/pybamm/__init__.py index 295d0b83ff..741f6b4795 100644 --- a/pybamm/__init__.py +++ b/pybamm/__init__.py @@ -136,6 +136,7 @@ def version(formatted=False): from .models.submodels.base_submodel import BaseSubModel from .models.submodels import ( + active_material, convection, current_collector, electrolyte_conductivity, diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index cd6df85048..f9e18930a0 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -212,6 +212,7 @@ def options(self, extra_options): "external submodels": [], "sei": None, "sei porosity change": False, + "active material change": None, "working electrode": None, "particle cracking": None, } @@ -350,6 +351,13 @@ def options(self, extra_options): ) ) + if options["active material change"] not in [None, "example"]: + raise pybamm.OptionError( + "Unknown active material change '{}'".format( + options["active material change"] + ) + ) + if options["particle cracking"] not in [ None, "no cracking", diff --git a/pybamm/models/full_battery_models/lithium_ion/dfn.py b/pybamm/models/full_battery_models/lithium_ion/dfn.py index 568dbe6ab2..353dcb7cd3 100644 --- a/pybamm/models/full_battery_models/lithium_ion/dfn.py +++ b/pybamm/models/full_battery_models/lithium_ion/dfn.py @@ -35,6 +35,7 @@ def __init__(self, options=None, name="Doyle-Fuller-Newman model", build=True): self.set_external_circuit_submodel() self.set_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_convection_submodel() self.set_interfacial_submodel() @@ -59,6 +60,23 @@ def set_porosity_submodel(self): elif self.options["sei porosity change"] is True: self.submodels["porosity"] = pybamm.porosity.Full(self.param) + def set_active_material_submodel(self): + + if self.options["active material change"] is None: + self.submodels[ + "negative active material" + ] = pybamm.active_material.Constant(self.param, "Negative", self.options) + self.submodels[ + "positive active material" + ] = pybamm.active_material.Constant(self.param, "Positive", self.options) + elif self.options["active material change"] == "example": + self.submodels["negative active material"] = pybamm.active_material.Full( + self.param, "Negative", self.options + ) + self.submodels["positive active material"] = pybamm.active_material.Full( + self.param, "Positive", self.options + ) + def set_convection_submodel(self): self.submodels[ diff --git a/pybamm/models/full_battery_models/lithium_ion/spm.py b/pybamm/models/full_battery_models/lithium_ion/spm.py index f87f5d005f..b4d7d2b99b 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spm.py +++ b/pybamm/models/full_battery_models/lithium_ion/spm.py @@ -34,6 +34,7 @@ def __init__(self, options=None, name="Single Particle Model", build=True): self.set_external_circuit_submodel() self.set_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_convection_submodel() self.set_interfacial_submodel() @@ -59,6 +60,27 @@ def set_porosity_submodel(self): elif self.options["sei porosity change"] is True: self.submodels["porosity"] = pybamm.porosity.LeadingOrder(self.param) + def set_active_material_submodel(self): + + if self.options["active material change"] is None: + self.submodels[ + "negative active material" + ] = pybamm.active_material.Constant(self.param, "Negative", self.options) + self.submodels[ + "positive active material" + ] = pybamm.active_material.Constant(self.param, "Positive", self.options) + elif self.options["active material change"] == "example": + self.submodels[ + "negative active material" + ] = pybamm.active_material.LeadingOrder( + self.param, "Negative", self.options + ) + self.submodels[ + "positive active material" + ] = pybamm.active_material.LeadingOrder( + self.param, "Positive", self.options + ) + def set_convection_submodel(self): self.submodels[ diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index acfd940f12..d7bc935c46 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -37,6 +37,7 @@ def __init__( self.set_external_circuit_submodel() self.set_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_convection_submodel() self.set_interfacial_submodel() @@ -62,6 +63,27 @@ def set_porosity_submodel(self): elif self.options["sei porosity change"] is True: self.submodels["porosity"] = pybamm.porosity.LeadingOrder(self.param) + def set_active_material_submodel(self): + + if self.options["active material change"] is None: + self.submodels[ + "negative active material" + ] = pybamm.active_material.Constant(self.param, "Negative", self.options) + self.submodels[ + "positive active material" + ] = pybamm.active_material.Constant(self.param, "Positive", self.options) + elif self.options["active material change"] == "example": + self.submodels[ + "negative active material" + ] = pybamm.active_material.LeadingOrder( + self.param, "Negative", self.options + ) + self.submodels[ + "positive active material" + ] = pybamm.active_material.LeadingOrder( + self.param, "Positive", self.options + ) + def set_convection_submodel(self): self.submodels[ diff --git a/pybamm/models/submodels/active_material/__init__.py b/pybamm/models/submodels/active_material/__init__.py new file mode 100644 index 0000000000..dc299c953a --- /dev/null +++ b/pybamm/models/submodels/active_material/__init__.py @@ -0,0 +1,2 @@ +from .base_active_material import BaseModel +from .constant_active_material import Constant diff --git a/pybamm/models/submodels/active_material/base_active_material.py b/pybamm/models/submodels/active_material/base_active_material.py new file mode 100644 index 0000000000..9d4a23e1b0 --- /dev/null +++ b/pybamm/models/submodels/active_material/base_active_material.py @@ -0,0 +1,92 @@ +# +# Base class for active material volume fraction +# +import pybamm + + +class BaseModel(pybamm.BaseSubModel): + """Base class for active material volume fraction + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + domain : str + The domain of the model either 'Negative' or 'Positive' + options : dict + Additional options to pass to the model + + **Extends:** :class:`pybamm.BaseSubModel` + """ + + def __init__(self, param, domain, options): + super().__init__(param, domain, options=options) + + def _get_standard_active_material_variables(self, eps_solid): + + eps_solid_av = pybamm.x_average(eps_solid) + + variables = { + self.domain + " electrode active material volume fraction": eps_solid, + "X-averaged " + + self.domain.lower() + + " electrode active material volume fraction": eps_solid_av, + } + + # Update other microstructure variables + if self.domain == "Negative": + x = pybamm.standard_spatial_vars.x_n + R = self.param.R_n(x) + R_typ = self.param.R_n_typ + a_typ = self.param.a_n_typ + elif self.domain == "Positive": + x = pybamm.standard_spatial_vars.x_p + R = self.param.R_p(x) + R_typ = self.param.R_p_typ + a_typ = self.param.a_p_typ + + # Compute dimensional particle shape + if self.options["particle shape"] == "spherical": + R_dim = R * R_typ + a_dim = 3 * eps_solid / R_dim + elif self.options["particle shape"] == "user": + if self.domain == "Negative": + # give dimensional x as an input + inputs = {"Through-cell distance (x_n) [m]": x * param.L_x} + a_dim = pybamm.FunctionParameter( + "Negative electrode surface area to volume ratio [m-1]", inputs + ) + if self.domain == "Positive": + # give dimensional x as an input + inputs = {"Through-cell distance (x_p) [m]": x * param.L_x} + a_dim = pybamm.FunctionParameter( + "Positive electrode surface area to volume ratio [m-1]", inputs + ) + + # Surface area to volume ratio is scaled with a_typ, so that it is equal to 1 + # when eps_solid and R are uniform in space and time + a = a_dim / a_typ + variables.update( + { + self.domain + " particle radius": R, + self.domain + " particle radius [m]": R * R_typ, + self.domain + " electrode surface area per unit volume": a, + self.domain + " electrode surface area per unit volume [m-1]": a_dim, + } + ) + + return variables + + def _get_standard_active_material_change_variables(self, deps_solid_dt): + + deps_solid_dt_av = pybamm.x_average(deps_solid_dt) + + variables = { + self.domain + + " electrode active material volume fraction change": deps_solid_dt, + "X-averaged negative " + + self.domain + + " electrode active material volume fraction change": deps_solid_dt_av, + } + + return variables diff --git a/pybamm/models/submodels/active_material/constant_active_material.py b/pybamm/models/submodels/active_material/constant_active_material.py new file mode 100644 index 0000000000..bc24debecb --- /dev/null +++ b/pybamm/models/submodels/active_material/constant_active_material.py @@ -0,0 +1,42 @@ +# +# Class for constant porosity +# +import pybamm + +from .base_active_material import BaseModel + + +class Constant(BaseModel): + """Submodel for constant porosity + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + domain : str + The domain of the model either 'Negative' or 'Positive' + + + **Extends:** :class:`pybamm.porosity.BaseModel` + """ + + def get_fundamental_variables(self): + if self.domain == "Negative": + x_n = pybamm.standard_spatial_vars.x_n + eps_solid = self.param.epsilon_s_n(x_n) + deps_solid_dt = pybamm.FullBroadcast( + 0, "negative electrode", "current collector" + ) + elif self.domain == "Positive": + x_p = pybamm.standard_spatial_vars.x_p + eps_solid = self.param.epsilon_s_p(x_p) + deps_solid_dt = pybamm.FullBroadcast( + 0, "positive electrode", "current collector" + ) + + variables = self._get_standard_active_material_variables(eps_solid) + variables.update( + self._get_standard_active_material_change_variables(deps_solid_dt) + ) + + return variables diff --git a/pybamm/models/submodels/base_submodel.py b/pybamm/models/submodels/base_submodel.py index 283d842995..83462afb9d 100644 --- a/pybamm/models/submodels/base_submodel.py +++ b/pybamm/models/submodels/base_submodel.py @@ -46,7 +46,9 @@ class BaseSubModel(pybamm.BaseModel): existance of a discontinuity (e.g. discontinuity in the input current) """ - def __init__(self, param, domain=None, name="Unnamed submodel", external=False): + def __init__( + self, param, domain=None, name="Unnamed submodel", external=False, options=None + ): super().__init__(name) self.param = param @@ -55,6 +57,7 @@ def __init__(self, param, domain=None, name="Unnamed submodel", external=False): self.name = name self.external = external + self.options = options or {} @property def domain(self): diff --git a/pybamm/models/submodels/interface/base_interface.py b/pybamm/models/submodels/interface/base_interface.py index 4d891e8cdd..d31d51a687 100644 --- a/pybamm/models/submodels/interface/base_interface.py +++ b/pybamm/models/submodels/interface/base_interface.py @@ -173,14 +173,6 @@ def _get_number_of_electrons_in_reaction(self): else: return pybamm.Scalar(0) - def _get_surface_area_per_unit_volume(self): - "Returns the surface area per unit volume (which may depend on position)" - x_n = pybamm.standard_spatial_vars.x_n - x_p = pybamm.standard_spatial_vars.x_p - a_n = self.param.a_n(x_n) - a_p = self.param.a_p(x_p) - return a_n, a_p - def _get_electrolyte_reaction_signed_stoichiometry(self): "Returns the number of electrons in the reaction" if self.reaction in ["lithium-ion main", "sei"]: @@ -347,16 +339,11 @@ def _get_standard_whole_cell_interfacial_current_variables(self, variables): } ) - a_n, a_p = self._get_surface_area_per_unit_volume() + a_n = variables["Negative electrode surface area per unit volume"] + a_p = variables["Positive electrode surface area per unit volume"] a = pybamm.Concatenation( a_n, pybamm.FullBroadcast(0, "separator", "current collector"), a_p ) - variables.update( - { - "Negative electrode surface area per unit volume": a_n, - "Positive electrode surface area per unit volume": a_p, - } - ) s_n, s_p = self._get_electrolyte_reaction_signed_stoichiometry() s = pybamm.Concatenation( diff --git a/pybamm/models/submodels/interface/sei/base_sei.py b/pybamm/models/submodels/interface/sei/base_sei.py index 8c0ee8bc4d..b29513ff8f 100644 --- a/pybamm/models/submodels/interface/sei/base_sei.py +++ b/pybamm/models/submodels/interface/sei/base_sei.py @@ -95,7 +95,7 @@ def _get_standard_total_thickness_variables(self, L_sei): } return variables - def _get_standard_concentraion_variables(self, variables): + def _get_standard_concentration_variables(self, variables): "Update variables related to the SEI concentration" param = self.param domain = self.domain.lower() + " electrode" diff --git a/pybamm/models/submodels/interface/sei/constant_sei.py b/pybamm/models/submodels/interface/sei/constant_sei.py index 89cb986b2b..ba540373fa 100644 --- a/pybamm/models/submodels/interface/sei/constant_sei.py +++ b/pybamm/models/submodels/interface/sei/constant_sei.py @@ -33,7 +33,7 @@ def get_fundamental_variables(self): variables = self._get_standard_thickness_variables(L_inner, L_outer) # Concentrations (derived from thicknesses) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) # Reactions zero = pybamm.FullBroadcast( diff --git a/pybamm/models/submodels/interface/sei/ec_reaction_limited.py b/pybamm/models/submodels/interface/sei/ec_reaction_limited.py index 9c03cd9d54..78cad89c42 100644 --- a/pybamm/models/submodels/interface/sei/ec_reaction_limited.py +++ b/pybamm/models/submodels/interface/sei/ec_reaction_limited.py @@ -47,7 +47,7 @@ def get_fundamental_variables(self): def get_coupled_variables(self, variables): # Get variables related to the concentration - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) # Update whole cell variables, which also updates the "sum of" variables if ( diff --git a/pybamm/models/submodels/interface/sei/electron_migration_limited.py b/pybamm/models/submodels/interface/sei/electron_migration_limited.py index a4988ccdcd..bb473da158 100644 --- a/pybamm/models/submodels/interface/sei/electron_migration_limited.py +++ b/pybamm/models/submodels/interface/sei/electron_migration_limited.py @@ -27,7 +27,7 @@ def get_fundamental_variables(self): L_outer = pybamm.standard_variables.L_outer variables = self._get_standard_thickness_variables(L_inner, L_outer) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/interface/sei/interstitial_diffusion_limited.py b/pybamm/models/submodels/interface/sei/interstitial_diffusion_limited.py index 3865a7a1ca..50e1cf3c1c 100644 --- a/pybamm/models/submodels/interface/sei/interstitial_diffusion_limited.py +++ b/pybamm/models/submodels/interface/sei/interstitial_diffusion_limited.py @@ -27,7 +27,7 @@ def get_fundamental_variables(self): L_outer = pybamm.standard_variables.L_outer variables = self._get_standard_thickness_variables(L_inner, L_outer) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/interface/sei/no_sei.py b/pybamm/models/submodels/interface/sei/no_sei.py index 2a477e5ded..f188554b78 100644 --- a/pybamm/models/submodels/interface/sei/no_sei.py +++ b/pybamm/models/submodels/interface/sei/no_sei.py @@ -27,7 +27,7 @@ def get_fundamental_variables(self): pybamm.Scalar(0), self.domain.lower() + " electrode", "current collector" ) variables = self._get_standard_thickness_variables(zero, zero) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) variables.update(self._get_standard_reaction_variables(zero, zero)) return variables diff --git a/pybamm/models/submodels/interface/sei/reaction_limited.py b/pybamm/models/submodels/interface/sei/reaction_limited.py index a78c7a5a56..32758b2c2e 100644 --- a/pybamm/models/submodels/interface/sei/reaction_limited.py +++ b/pybamm/models/submodels/interface/sei/reaction_limited.py @@ -27,7 +27,7 @@ def get_fundamental_variables(self): L_outer = pybamm.standard_variables.L_outer variables = self._get_standard_thickness_variables(L_inner, L_outer) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/interface/sei/solvent_diffusion_limited.py b/pybamm/models/submodels/interface/sei/solvent_diffusion_limited.py index 521a581af6..67bfa5d6a6 100644 --- a/pybamm/models/submodels/interface/sei/solvent_diffusion_limited.py +++ b/pybamm/models/submodels/interface/sei/solvent_diffusion_limited.py @@ -27,7 +27,7 @@ def get_fundamental_variables(self): L_outer = pybamm.standard_variables.L_outer variables = self._get_standard_thickness_variables(L_inner, L_outer) - variables.update(self._get_standard_concentraion_variables(variables)) + variables.update(self._get_standard_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/particle/base_particle.py b/pybamm/models/submodels/particle/base_particle.py index e4336c06fe..9b87359c9c 100644 --- a/pybamm/models/submodels/particle/base_particle.py +++ b/pybamm/models/submodels/particle/base_particle.py @@ -41,11 +41,9 @@ def _get_standard_concentration_variables( if self.domain == "Negative": c_scale = self.param.c_n_max - eps_s = self.param.epsilon_s_n L = self.param.L_n elif self.domain == "Positive": c_scale = self.param.c_p_max - eps_s = self.param.epsilon_s_p L = self.param.L_p A = self.param.A_cc @@ -54,7 +52,6 @@ def _get_standard_concentration_variables( c_s_xav = c_s_xav or pybamm.x_average(c_s) c_s_rav = c_s_rav or pybamm.r_average(c_s) c_s_av = c_s_av or pybamm.r_average(c_s_xav) - c_s_vol_av = pybamm.x_average(eps_s * c_s_rav) variables = { self.domain + " particle concentration": c_s, @@ -81,18 +78,10 @@ def _get_standard_concentration_variables( "X-averaged " + self.domain.lower() + " particle surface concentration [mol.m-3]": c_scale * c_s_surf_av, - self.domain + " electrode active volume fraction": eps_s, - self.domain + " electrode volume-averaged concentration": c_s_vol_av, - self.domain - + " electrode " - + "volume-averaged concentration [mol.m-3]": c_s_vol_av * c_scale, self.domain + " electrode extent of lithiation": c_s_rav, "X-averaged " + self.domain.lower() + " electrode extent of lithiation": c_s_av, - "Total lithium in " - + self.domain.lower() - + " electrode [mol]": c_s_vol_av * c_scale * L * A, "Minimum " + self.domain.lower() + " particle concentration": pybamm.min(c_s), @@ -121,31 +110,33 @@ def _get_standard_concentration_variables( * c_scale, } - variables.update(self._get_microstrcuture_variables()) - return variables - def _get_microstrcuture_variables(self): + def _get_total_concentration_variables(self, variables): + c_s_rav = variables[ + "R-averaged " + self.domain.lower() + " particle concentration" + ] + eps_s = variables[self.domain + " electrode active material volume fraction"] + c_s_vol_av = pybamm.x_average(eps_s * c_s_rav) if self.domain == "Negative": - x = pybamm.standard_spatial_vars.x_n - R = self.param.R_n(x) - R_scale = self.param.R_n_typ - a = self.param.a_n(x) - a_scale = self.param.a_n_typ + c_scale = self.param.c_n_max + L = self.param.L_n elif self.domain == "Positive": - x = pybamm.standard_spatial_vars.x_p - R = self.param.R_p(x) - R_scale = self.param.R_p_typ - a = self.param.a_p(x) - a_scale = self.param.a_p_typ - - variables = { - self.domain + " particle radius": R, - self.domain + " particle radius [m]": R * R_scale, - self.domain + " electrode surface area per unit volume": a, - self.domain + " electrode surface area per unit volume [m-1]": a * a_scale, - } + c_scale = self.param.c_p_max + L = self.param.L_p + A = self.param.A_cc + variables.update( + { + self.domain + " electrode volume-averaged concentration": c_s_vol_av, + self.domain + + " electrode " + + "volume-averaged concentration [mol.m-3]": c_s_vol_av * c_scale, + "Total lithium in " + + self.domain.lower() + + " electrode [mol]": c_s_vol_av * c_scale * L * A, + } + ) return variables def _get_standard_flux_variables(self, N_s, N_s_xav): diff --git a/pybamm/models/submodels/particle/fickian_many_particles.py b/pybamm/models/submodels/particle/fickian_many_particles.py index d4b6d5f4cf..75a89f3e02 100644 --- a/pybamm/models/submodels/particle/fickian_many_particles.py +++ b/pybamm/models/submodels/particle/fickian_many_particles.py @@ -47,6 +47,7 @@ def get_coupled_variables(self, variables): N_s = -self.param.D_p(c_s, T) * pybamm.grad(c_s) variables.update(self._get_standard_flux_variables(N_s, N_s)) + variables.update(self._get_total_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/particle/fickian_single_particle.py b/pybamm/models/submodels/particle/fickian_single_particle.py index a05c7efca3..5fd2faa952 100644 --- a/pybamm/models/submodels/particle/fickian_single_particle.py +++ b/pybamm/models/submodels/particle/fickian_single_particle.py @@ -55,6 +55,7 @@ def get_coupled_variables(self, variables): N_s = pybamm.SecondaryBroadcast(N_s_xav, [self._domain.lower() + " electrode"]) variables.update(self._get_standard_flux_variables(N_s, N_s_xav)) + variables.update(self._get_total_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/particle/polynomial_many_particles.py b/pybamm/models/submodels/particle/polynomial_many_particles.py index a669204946..f92aa3d450 100644 --- a/pybamm/models/submodels/particle/polynomial_many_particles.py +++ b/pybamm/models/submodels/particle/polynomial_many_particles.py @@ -176,6 +176,7 @@ def get_coupled_variables(self, variables): N_s_xav = pybamm.x_average(N_s) variables.update(self._get_standard_flux_variables(N_s, N_s_xav)) + variables.update(self._get_total_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/particle/polynomial_single_particle.py b/pybamm/models/submodels/particle/polynomial_single_particle.py index 22a7d1b916..61f97790b0 100644 --- a/pybamm/models/submodels/particle/polynomial_single_particle.py +++ b/pybamm/models/submodels/particle/polynomial_single_particle.py @@ -271,6 +271,7 @@ def get_coupled_variables(self, variables): c_s, c_s_av=c_s_rxav, c_s_surf=c_s_surf ) variables.update(self._get_standard_flux_variables(N_s, N_s_xav)) + variables.update(self._get_total_concentration_variables(variables)) return variables diff --git a/pybamm/models/submodels/particle_cracking/base_cracking.py b/pybamm/models/submodels/particle_cracking/base_cracking.py index f4882556b5..1388a64358 100644 --- a/pybamm/models/submodels/particle_cracking/base_cracking.py +++ b/pybamm/models/submodels/particle_cracking/base_cracking.py @@ -48,7 +48,6 @@ def _get_standard_variables(self, l_cr): f"X-averaged {domain} crack length": l_cr_av, f"X-averaged {domain} crack length [m]": l_cr_av * l_cr0, } - variables.update(self._get_standard_surface_variables(l_cr)) return variables def _get_mechanical_results(self, variables): @@ -57,6 +56,7 @@ def _get_mechanical_results(self, variables): ] c_s_surf = variables[self.domain + " particle surface concentration"] T_xav = variables["X-averaged cell temperature"] + eps_s = variables[self.domain + " electrode active material volume fraction"] if "Cell thickness change [m]" not in variables: cell_thickness_change = ( @@ -73,7 +73,6 @@ def _get_mechanical_results(self, variables): c_0 = self.param.c_n_0 E0 = self.param.E_n nu = self.param.nu_n - eps_s = self.param.epsilon_s_n L0 = self.param.L_n c_init = self.param.c_n_init(1) v_change = pybamm.x_average( @@ -88,7 +87,6 @@ def _get_mechanical_results(self, variables): c_0 = self.param.c_p_0 E0 = self.param.E_p nu = self.param.nu_p - eps_s = self.param.epsilon_s_p L0 = self.param.L_p c_init = self.param.c_p_init(0) v_change = pybamm.x_average( @@ -132,27 +130,31 @@ def _get_mechanical_results(self, variables): "Cell thickness change [m]": cell_thickness_change, } - def _get_standard_surface_variables(self, l_cr): + def _get_standard_surface_variables(self, variables): """ A private function to obtain the standard variables which can be derived from the local particle crack surfaces. + Parameters ---------- l_cr : :class:`pybamm.Symbol` The crack length in electrode particles. + a0 : :class:`pybamm.Symbol` + Smooth surface area to volume ratio. + Returns ------- variables : dict - The variables which can be derived from the crack length. + The variables which can be derived from the crack length. """ + l_cr = variables[self.domain + " particle crack length"] + a0 = variables[self.domain + " electrode surface area to volume ratio"] if self.domain == "Negative": x = pybamm.standard_spatial_vars.x_n - a0 = self.param.a_n(x) R0 = self.param.R_n(x) rho_cr = self.param.rho_cr_n elif self.domain == "Positive": x = pybamm.standard_spatial_vars.x_p - a0 = self.param.a_p(x) R0 = self.param.R_p(x) rho_cr = self.param.rho_cr_p roughness = l_cr * 2 * rho_cr + 1 # the ratio of cracks to normal surface diff --git a/pybamm/models/submodels/particle_cracking/crack_propagation.py b/pybamm/models/submodels/particle_cracking/crack_propagation.py index fd96c7cfda..e54de72250 100644 --- a/pybamm/models/submodels/particle_cracking/crack_propagation.py +++ b/pybamm/models/submodels/particle_cracking/crack_propagation.py @@ -39,6 +39,7 @@ def get_fundamental_variables(self): return self._get_standard_variables(l_cr) def get_coupled_variables(self, variables): + variables.update(self._get_standard_surface_variables(variables)) variables.update(self._get_mechanical_results(variables)) T = variables[self.domain + " electrode temperature"] if self.domain == "Negative": diff --git a/pybamm/models/submodels/particle_cracking/no_cracking.py b/pybamm/models/submodels/particle_cracking/no_cracking.py index 8eecfd9cb1..05b7aca264 100644 --- a/pybamm/models/submodels/particle_cracking/no_cracking.py +++ b/pybamm/models/submodels/particle_cracking/no_cracking.py @@ -37,5 +37,6 @@ def get_fundamental_variables(self): return variables def get_coupled_variables(self, variables): + variables.update(self._get_standard_surface_variables(variables)) variables.update(self._get_mechanical_results(variables)) return variables diff --git a/pybamm/models/submodels/porosity/base_porosity.py b/pybamm/models/submodels/porosity/base_porosity.py index 7e710f733f..f05120b578 100644 --- a/pybamm/models/submodels/porosity/base_porosity.py +++ b/pybamm/models/submodels/porosity/base_porosity.py @@ -38,25 +38,6 @@ def _get_standard_porosity_variables( "X-averaged positive electrode porosity": eps_p_av, } - # activate material volume fractions - eps_solid_n = 1 - eps_n - self.param.epsilon_inactive_n - eps_solid_s = 1 - eps_s - self.param.epsilon_inactive_s - eps_solid_p = 1 - eps_p - self.param.epsilon_inactive_p - eps_solid = pybamm.Concatenation(eps_solid_n, eps_solid_s, eps_solid_p) - - am = "active material volume fraction" - variables.update( - { - am.capitalize(): eps_solid, - "Negative electrode " + am: eps_solid_n, - "Separator " + am: eps_solid, - "Positive electrode " + am: eps_solid_p, - "X-averaged negative electrode " + am: pybamm.x_average(eps_solid_n), - "X-averaged separator " + am: pybamm.x_average(eps_solid), - "X-averaged positive electrode " + am: pybamm.x_average(eps_solid_p), - } - ) - if set_leading_order is True: leading_order_variables = { "Leading-order " + name.lower(): var for name, var in variables.items() diff --git a/pybamm/models/submodels/porosity/leading_reaction_driven_porosity.py b/pybamm/models/submodels/porosity/leading_reaction_driven_porosity.py index 7337d8b793..a3715736f5 100644 --- a/pybamm/models/submodels/porosity/leading_reaction_driven_porosity.py +++ b/pybamm/models/submodels/porosity/leading_reaction_driven_porosity.py @@ -73,6 +73,8 @@ def set_initial_conditions(self, variables): eps_s_av = variables["X-averaged separator porosity"] eps_p_av = variables["X-averaged positive electrode porosity"] - self.initial_conditions = {eps_n_av: self.param.epsilon_n_init} - self.initial_conditions.update({eps_s_av: self.param.epsilon_s_init}) - self.initial_conditions.update({eps_p_av: self.param.epsilon_p_init}) + self.initial_conditions = { + eps_n_av: self.param.epsilon_n_init, + eps_s_av: self.param.epsilon_s_init, + eps_p_av: self.param.epsilon_p_init, + } diff --git a/pybamm/models/submodels/tortuosity/bruggeman_tortuosity.py b/pybamm/models/submodels/tortuosity/bruggeman_tortuosity.py index 0ccc5a8a4b..d600380ba0 100644 --- a/pybamm/models/submodels/tortuosity/bruggeman_tortuosity.py +++ b/pybamm/models/submodels/tortuosity/bruggeman_tortuosity.py @@ -25,7 +25,9 @@ def get_coupled_variables(self, variables): eps_n ** param.b_e_n, eps_s ** param.b_e_s, eps_p ** param.b_e_p ) elif self.phase == "Electrode": - eps_n, eps_s, eps_p = variables["Active material volume fraction"].orphans + eps_n = variables["Negative electrode active material volume fraction"] + eps_s = pybamm.FullBroadcast(0, "separator", "current collector") + eps_p = variables["Positive electrode active material volume fraction"] tor = pybamm.Concatenation( eps_n ** param.b_s_n, eps_s ** param.b_s_s, eps_p ** param.b_s_p ) diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 34986f09fa..527b48d1ef 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -113,27 +113,35 @@ def _set_dimensional_parameters(self): # Note: the particle radius in the electrodes can be set as a function # of through-cell position, so is defined later as a function, along with # the surface area per unit volume - inputs = {"Through-cell distance (x_n) [m]": pybamm.standard_spatial_vars.x_n} + inputs = { + "Through-cell distance (x_n) [m]": pybamm.standard_spatial_vars.x_n + * self.L_x + } self.epsilon_n = pybamm.FunctionParameter("Negative electrode porosity", inputs) - inputs = {"Through-cell distance (x_s) [m]": pybamm.standard_spatial_vars.x_s} + inputs = { + "Through-cell distance (x_s) [m]": pybamm.standard_spatial_vars.x_s + * self.L_x + } self.epsilon_s = pybamm.FunctionParameter("Separator porosity", inputs) - inputs = {"Through-cell distance (x_p) [m]": pybamm.standard_spatial_vars.x_p} + inputs = { + "Through-cell distance (x_p) [m]": pybamm.standard_spatial_vars.x_p + * self.L_x + } self.epsilon_p = pybamm.FunctionParameter("Positive electrode porosity", inputs) self.epsilon = pybamm.Concatenation( self.epsilon_n, self.epsilon_s, self.epsilon_p ) - self.epsilon_s_n = pybamm.Parameter( - "Negative electrode active material volume fraction" + self.epsilon_inactive_n = ( + 1 - self.epsilon_n - self.epsilon_s_n(pybamm.standard_spatial_vars.x_n) ) - self.epsilon_s_p = pybamm.Parameter( - "Positive electrode active material volume fraction" - ) - self.epsilon_inactive_n = 1 - self.epsilon_n - self.epsilon_s_n self.epsilon_inactive_s = 1 - self.epsilon_s - self.epsilon_inactive_p = 1 - self.epsilon_p - self.epsilon_s_p + self.epsilon_inactive_p = ( + 1 - self.epsilon_p - self.epsilon_s_p(pybamm.standard_spatial_vars.x_p) + ) + self.b_e_n = self.geo.b_e_n self.b_e_s = self.geo.b_e_s self.b_e_p = self.geo.b_e_p @@ -368,31 +376,19 @@ def R_p_dimensional(self, x): inputs = {"Through-cell distance (x_p) [m]": x} return pybamm.FunctionParameter("Positive particle radius [m]", inputs) - def a_n_dimensional(self, x): - """ - Negative electrode surface area per unit volume as a function of - through-cell distance - """ - inputs = {"Through-cell distance (x_n) [m]": x} - if self.options["particle shape"] == "spherical": - return 3 * self.epsilon_s_n / self.R_n_dimensional(x) - elif self.options["particle shape"] == "user": - return pybamm.FunctionParameter( - "Negative electrode surface area to volume ratio [m-1]", inputs - ) + def epsilon_s_n(self, x): + "Negative electrode active material volume fraction" + inputs = {"Through-cell distance (x_n) [m]": x * self.L_x} + return pybamm.FunctionParameter( + "Negative electrode active material volume fraction", inputs + ) - def a_p_dimensional(self, x): - """ - Positive electrode surface area per unit volume as a function of - through-cell distance - """ - inputs = {"Through-cell distance (x_p) [m]": x} - if self.options["particle shape"] == "spherical": - return 3 * self.epsilon_s_p / self.R_p_dimensional(x) - elif self.options["particle shape"] == "user": - return pybamm.FunctionParameter( - "Positive electrode surface area to volume ratio [m-1]", inputs - ) + def epsilon_s_p(self, x): + "Positive electrode active material volume fraction" + inputs = {"Through-cell distance (x_p) [m]": x * self.L_x} + return pybamm.FunctionParameter( + "Positive electrode active material volume fraction", inputs + ) def c_n_init_dimensional(self, x): "Initial concentration as a function of dimensionless position x" @@ -414,8 +410,18 @@ def _set_scales(self): # Microscale (typical values at electrode/current collector interface) self.R_n_typ = self.R_n_dimensional(0) self.R_p_typ = self.R_p_dimensional(self.L_x) - self.a_n_typ = self.a_n_dimensional(0) - self.a_p_typ = self.a_p_dimensional(self.L_x) + if self.options["particle shape"] == "spherical": + self.a_n_typ = 3 * self.epsilon_s_n(0) / self.R_n_typ + self.a_p_typ = 3 * self.epsilon_s_p(1) / self.R_n_typ + elif self.options["particle shape"] == "user": + inputs = {"Through-cell distance (x_n) [m]": 0} + self.a_n_typ = pybamm.FunctionParameter( + "Negative electrode surface area to volume ratio [m-1]", inputs + ) + inputs = {"Through-cell distance (x_p) [m]": self.L_x} + self.a_n_typ = pybamm.FunctionParameter( + "Positive electrode surface area to volume ratio [m-1]", inputs + ) # Concentration self.electrolyte_concentration_scale = self.c_e_typ @@ -836,22 +842,6 @@ def R_p(self, x): x_dim = x * self.L_x return self.R_p_dimensional(x_dim) / self.R_p_typ - def a_n(self, x): - """ - Dimensionless negative electrode surface area per unit volume as a - function of dimensionless position x. - """ - x_dim = x * self.L_x - return self.a_n_dimensional(x_dim) / self.a_n_typ - - def a_p(self, x): - """ - Dimensionless positive electrode surface area per unit volume as a - function of dimensionless position x. - """ - x_dim = x * self.L_x - return self.a_p_dimensional(x_dim) / self.a_p_typ - def c_n_init(self, x): "Dimensionless initial concentration as a function of dimensionless position x" return self.c_n_init_dimensional(x) / self.c_n_max diff --git a/tests/unit/test_models/test_submodels/test_tortuosity/test_bruggeman_tortuosity.py b/tests/unit/test_models/test_submodels/test_tortuosity/test_bruggeman_tortuosity.py index 1f2ca9030c..43800fa4cb 100644 --- a/tests/unit/test_models/test_submodels/test_tortuosity/test_bruggeman_tortuosity.py +++ b/tests/unit/test_models/test_submodels/test_tortuosity/test_bruggeman_tortuosity.py @@ -15,7 +15,11 @@ def test_public_functions(self): pybamm.FullBroadcast(0, ["separator"], "current collector"), pybamm.FullBroadcast(0, ["positive electrode"], "current collector"), ) - variables = {"Porosity": a, "Active material volume fraction": a} + variables = { + "Porosity": a, + "Negative electrode active material volume fraction": a.orphans[0], + "Positive electrode active material volume fraction": a.orphans[2], + } submodel = pybamm.tortuosity.Bruggeman(param, "Electrolyte") std_tests = tests.StandardSubModelTests(submodel, variables) std_tests.test_all() From 62cc9d81108fbb941eb84373620dcb97e111682d Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 11:41:16 -0500 Subject: [PATCH 02/12] #1245 fix lead-acid models --- .../full_battery_models/base_battery_model.py | 2 +- .../lead_acid/base_lead_acid_model.py | 11 ++ .../full_battery_models/lead_acid/full.py | 1 + .../lead_acid/higher_order.py | 1 + .../full_battery_models/lead_acid/loqs.py | 1 + .../active_material/base_active_material.py | 104 +++++++++++------- .../submodels/particle/base_particle.py | 3 - pybamm/parameters/lead_acid_parameters.py | 20 ++++ 8 files changed, 97 insertions(+), 46 deletions(-) diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index f9e18930a0..11e96ce2e0 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -393,7 +393,7 @@ def options(self, extra_options): "The 'fast diffusion' option has been renamed. " "Use 'uniform profile' instead." ) - if options["particle shape"] not in ["spherical", "user"]: + if options["particle shape"] not in ["spherical", "user", "no particles"]: raise pybamm.OptionError( "particle shape '{}' not recognised".format(options["particle shape"]) ) diff --git a/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py b/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py index 494cf368dc..20b7e3d6a8 100644 --- a/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py +++ b/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py @@ -16,6 +16,9 @@ class BaseModel(pybamm.BaseBatteryModel): """ def __init__(self, options=None, name="Unnamed lead-acid model", build=False): + options = options or {} + # Specify that there are no particles in lead-acid + options["particle shape"] = "no particles" super().__init__(options, name) self.param = pybamm.LeadAcidParameters() @@ -67,6 +70,14 @@ def set_soc_variables(self): self.rhs[fci] = -self.variables["Total current density"] * 100 self.initial_conditions[fci] = self.param.q_init * 100 + def set_active_material_submodel(self): + self.submodels["negative active material"] = pybamm.active_material.Constant( + self.param, "Negative", self.options + ) + self.submodels["positive active material"] = pybamm.active_material.Constant( + self.param, "Positive", self.options + ) + def set_sei_submodel(self): self.submodels["negative sei"] = pybamm.sei.NoSEI(self.param, "Negative") diff --git a/pybamm/models/full_battery_models/lead_acid/full.py b/pybamm/models/full_battery_models/lead_acid/full.py index 3e4716e9bc..4ac4a8b095 100644 --- a/pybamm/models/full_battery_models/lead_acid/full.py +++ b/pybamm/models/full_battery_models/lead_acid/full.py @@ -37,6 +37,7 @@ def __init__(self, options=None, name="Full model", build=True): self.set_external_circuit_submodel() self.set_interfacial_submodel() self.set_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_convection_submodel() self.set_electrolyte_submodel() diff --git a/pybamm/models/full_battery_models/lead_acid/higher_order.py b/pybamm/models/full_battery_models/lead_acid/higher_order.py index 1e95ca288e..673a348086 100644 --- a/pybamm/models/full_battery_models/lead_acid/higher_order.py +++ b/pybamm/models/full_battery_models/lead_acid/higher_order.py @@ -49,6 +49,7 @@ def __init__(self, options=None, name="Composite model", build=True): self.set_full_interface_submodel() self.set_full_convection_submodel() self.set_full_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_thermal_submodel() self.set_current_collector_submodel() diff --git a/pybamm/models/full_battery_models/lead_acid/loqs.py b/pybamm/models/full_battery_models/lead_acid/loqs.py index 0bf88228a3..1930b0aa07 100644 --- a/pybamm/models/full_battery_models/lead_acid/loqs.py +++ b/pybamm/models/full_battery_models/lead_acid/loqs.py @@ -37,6 +37,7 @@ def __init__(self, options=None, name="LOQS model", build=True): self.set_interfacial_submodel() self.set_convection_submodel() self.set_porosity_submodel() + self.set_active_material_submodel() self.set_tortuosity_submodels() self.set_negative_electrode_submodel() self.set_electrolyte_submodel() diff --git a/pybamm/models/submodels/active_material/base_active_material.py b/pybamm/models/submodels/active_material/base_active_material.py index 9d4a23e1b0..1730aaa297 100644 --- a/pybamm/models/submodels/active_material/base_active_material.py +++ b/pybamm/models/submodels/active_material/base_active_material.py @@ -23,7 +23,6 @@ def __init__(self, param, domain, options): super().__init__(param, domain, options=options) def _get_standard_active_material_variables(self, eps_solid): - eps_solid_av = pybamm.x_average(eps_solid) variables = { @@ -34,48 +33,69 @@ def _get_standard_active_material_variables(self, eps_solid): } # Update other microstructure variables - if self.domain == "Negative": - x = pybamm.standard_spatial_vars.x_n - R = self.param.R_n(x) - R_typ = self.param.R_n_typ - a_typ = self.param.a_n_typ - elif self.domain == "Positive": - x = pybamm.standard_spatial_vars.x_p - R = self.param.R_p(x) - R_typ = self.param.R_p_typ - a_typ = self.param.a_p_typ - - # Compute dimensional particle shape - if self.options["particle shape"] == "spherical": - R_dim = R * R_typ - a_dim = 3 * eps_solid / R_dim - elif self.options["particle shape"] == "user": + # some models (e.g. lead-acid) do not have particles + if self.options["particle shape"] == "no particles": if self.domain == "Negative": - # give dimensional x as an input - inputs = {"Through-cell distance (x_n) [m]": x * param.L_x} - a_dim = pybamm.FunctionParameter( - "Negative electrode surface area to volume ratio [m-1]", inputs - ) - if self.domain == "Positive": - # give dimensional x as an input - inputs = {"Through-cell distance (x_p) [m]": x * param.L_x} - a_dim = pybamm.FunctionParameter( - "Positive electrode surface area to volume ratio [m-1]", inputs - ) - - # Surface area to volume ratio is scaled with a_typ, so that it is equal to 1 - # when eps_solid and R are uniform in space and time - a = a_dim / a_typ - variables.update( - { - self.domain + " particle radius": R, - self.domain + " particle radius [m]": R * R_typ, - self.domain + " electrode surface area per unit volume": a, - self.domain + " electrode surface area per unit volume [m-1]": a_dim, - } - ) - - return variables + x = pybamm.standard_spatial_vars.x_n + a = self.param.a_n(x) + a_typ = self.param.a_n_typ + elif self.domain == "Positive": + x = pybamm.standard_spatial_vars.x_p + a = self.param.a_p(x) + a_typ = self.param.a_p_typ + variables.update( + { + self.domain + " electrode surface area per unit volume": a, + self.domain + + " electrode surface area per unit volume [m-1]": a * a_typ, + } + ) + return variables + + else: + if self.domain == "Negative": + x = pybamm.standard_spatial_vars.x_n + R = self.param.R_n(x) + R_typ = self.param.R_n_typ + a_typ = self.param.a_n_typ + elif self.domain == "Positive": + x = pybamm.standard_spatial_vars.x_p + R = self.param.R_p(x) + R_typ = self.param.R_p_typ + a_typ = self.param.a_p_typ + + # Compute dimensional particle shape + if self.options["particle shape"] == "spherical": + R_dim = R * R_typ + a_dim = 3 * eps_solid / R_dim + elif self.options["particle shape"] == "user": + if self.domain == "Negative": + # give dimensional x as an input + inputs = {"Through-cell distance (x_n) [m]": x * self.param.L_x} + a_dim = pybamm.FunctionParameter( + "Negative electrode surface area to volume ratio [m-1]", inputs + ) + if self.domain == "Positive": + # give dimensional x as an input + inputs = {"Through-cell distance (x_p) [m]": x * self.param.L_x} + a_dim = pybamm.FunctionParameter( + "Positive electrode surface area to volume ratio [m-1]", inputs + ) + + # Surface area to volume ratio is scaled with a_typ, so that it is equal to + # 1 when eps_solid and R are uniform in space and time + a = a_dim / a_typ + variables.update( + { + self.domain + " particle radius": R, + self.domain + " particle radius [m]": R * R_typ, + self.domain + " electrode surface area per unit volume": a, + self.domain + + " electrode surface area per unit volume [m-1]": a_dim, + } + ) + + return variables def _get_standard_active_material_change_variables(self, deps_solid_dt): diff --git a/pybamm/models/submodels/particle/base_particle.py b/pybamm/models/submodels/particle/base_particle.py index 9b87359c9c..20d27120cd 100644 --- a/pybamm/models/submodels/particle/base_particle.py +++ b/pybamm/models/submodels/particle/base_particle.py @@ -41,11 +41,8 @@ def _get_standard_concentration_variables( if self.domain == "Negative": c_scale = self.param.c_n_max - L = self.param.L_n elif self.domain == "Positive": c_scale = self.param.c_p_max - L = self.param.L_p - A = self.param.A_cc # Get average concentration(s) if not provided as fundamental variable to # solve for diff --git a/pybamm/parameters/lead_acid_parameters.py b/pybamm/parameters/lead_acid_parameters.py index e25e5faaba..d1cc5ff667 100644 --- a/pybamm/parameters/lead_acid_parameters.py +++ b/pybamm/parameters/lead_acid_parameters.py @@ -336,6 +336,26 @@ def a_p_dimensional(self, x): "Positive electrode surface area to volume ratio [m-1]", inputs ) + def epsilon_s_n(self, x): + """ + Negative electrode active material volume fraction, specified for compatibility + with lithium-ion submodels. Note that this does not change even though porosity + changes, since the material being created is inactive. + """ + return pybamm.FullBroadcast( + 1 - self.eps_n_max, "negative electrode", "current collector" + ) + + def epsilon_s_p(self, x): + """ + Positive electrode active material volume fraction, specified for compatibility + with lithium-ion submodels. Note that this does not change even though porosity + changes, since the material being created is inactive. + """ + return pybamm.FullBroadcast( + 1 - self.eps_p_max, "positive electrode", "current collector" + ) + def _set_scales(self): "Define the scales used in the non-dimensionalisation scheme" From e32b2802f267a4d8fb96dbcf918ae8f7682bd262 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 13:38:49 -0500 Subject: [PATCH 03/12] #1245 fix lithium-ion models --- CHANGELOG.md | 4 ++-- .../Tutorial 3 - Basic plotting.ipynb | 4 ++-- examples/notebooks/models/SPM.ipynb | 8 ++++---- examples/notebooks/models/thermal-models.ipynb | 2 +- .../solution-data-and-processed-variables.ipynb | 2 +- examples/scripts/compare_particle_shape.py | 4 ++-- .../models/full_battery_models/base_battery_model.py | 2 +- .../active_material/base_active_material.py | 8 ++++---- pybamm/models/submodels/electrode/ohm/full_ohm.py | 4 ++-- .../electrolyte_conductivity/full_conductivity.py | 6 +++--- .../full_surface_form_conductivity.py | 8 ++++---- pybamm/models/submodels/interface/base_interface.py | 4 ++-- .../submodels/particle/polynomial_single_particle.py | 6 ++++-- .../submodels/particle_cracking/base_cracking.py | 12 +++++------- pybamm/models/submodels/thermal/base_thermal.py | 4 ++-- pybamm/parameters/lead_acid_parameters.py | 10 +++++----- pybamm/parameters/lithium_ion_parameters.py | 6 +++--- pybamm/parameters/parameter_values.py | 4 ++-- .../integration/test_models/standard_output_tests.py | 4 ++-- .../test_full_conductivity.py | 2 +- .../test_full_surface_form_conductivity.py | 4 ++-- .../test_submodels/test_thermal/coupled_variables.py | 4 ++-- tests/unit/test_parameters/test_parameter_values.py | 4 ++-- 23 files changed, 58 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea3d2e92f..e29ac26d57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ This release introduces a new aging model for particle swelling and cracking, a ## Breaking changes -- The parameters "Positive/Negative particle distribution in x" and "Positive/Negative surface area per unit volume distribution in x" have been deprecated. Instead, users can provide "Positive/Negative particle radius [m]" and "Positive/Negative surface area per unit volume [m-1]" directly as functions of through-cell position (x [m]) ([#1237](https://github.com/pybamm-team/PyBaMM/pull/1237)) +- The parameters "Positive/Negative particle distribution in x" and "Positive/Negative surface area to volume ratio distribution in x" have been deprecated. Instead, users can provide "Positive/Negative particle radius [m]" and "Positive/Negative surface area to volume ratio [m-1]" directly as functions of through-cell position (x [m]) ([#1237](https://github.com/pybamm-team/PyBaMM/pull/1237)) # [v0.2.4](https://github.com/pybamm-team/PyBaMM/tree/v0.2.4) - 2020-09-07 @@ -48,7 +48,7 @@ This release adds new operators for more complex models, some basic sensitivity - Added particle submodel that use a polynomial approximation to the concentration within the electrode particles ([#1130](https://github.com/pybamm-team/PyBaMM/pull/1130)) - Added `Modulo`, `Floor` and `Ceiling` operators ([#1121](https://github.com/pybamm-team/PyBaMM/pull/1121)) - Added DFN model for a half cell ([#1121](https://github.com/pybamm-team/PyBaMM/pull/1121)) -- Automatically compute surface area per unit volume based on particle shape for li-ion models ([#1120](https://github.com/pybamm-team/PyBaMM/pull/1120)) +- Automatically compute surface area to volume ratio based on particle shape for li-ion models ([#1120](https://github.com/pybamm-team/PyBaMM/pull/1120)) - Added "R-averaged particle concentration" variables ([#1118](https://github.com/pybamm-team/PyBaMM/pull/1118)) - Added support for sensitivity calculations to the casadi solver ([#1109](https://github.com/pybamm-team/PyBaMM/pull/1109)) - Added support for index 1 semi-explicit dae equations and sensitivity calculations to JAX BDF solver ([#1107](https://github.com/pybamm-team/PyBaMM/pull/1107)) diff --git a/examples/notebooks/Getting Started/Tutorial 3 - Basic plotting.ipynb b/examples/notebooks/Getting Started/Tutorial 3 - Basic plotting.ipynb index 8154c22e0c..0c63bf8283 100644 --- a/examples/notebooks/Getting Started/Tutorial 3 - Basic plotting.ipynb +++ b/examples/notebooks/Getting Started/Tutorial 3 - Basic plotting.ipynb @@ -432,8 +432,8 @@ " 'Sei interfacial current density',\n", " 'Sei interfacial current density [A.m-2]',\n", " 'Sei interfacial current density per volume [A.m-3]',\n", - " 'Negative surface area per unit volume distribution in x',\n", - " 'Positive surface area per unit volume distribution in x',\n", + " 'Negative surface area to volume ratio distribution in x',\n", + " 'Positive surface area to volume ratio distribution in x',\n", " 'Negative electrode interfacial current density',\n", " 'X-averaged negative electrode interfacial current density',\n", " 'Negative electrode interfacial current density [A.m-2]',\n", diff --git a/examples/notebooks/models/SPM.ipynb b/examples/notebooks/models/SPM.ipynb index 90cee2c20e..5db6220b99 100644 --- a/examples/notebooks/models/SPM.ipynb +++ b/examples/notebooks/models/SPM.ipynb @@ -531,8 +531,8 @@ "\t- Maximum negative particle surface concentration [mol.m-3]\n", "\t- Negative particle radius\n", "\t- Negative particle radius [m]\n", - "\t- Negative surface area per unit volume\n", - "\t- Negative surface area per unit volume [m-1]\n", + "\t- Negative surface area to volume ratio\n", + "\t- Negative surface area to volume ratio [m-1]\n", "\t- Positive particle concentration\n", "\t- Positive particle concentration [mol.m-3]\n", "\t- X-averaged positive particle concentration\n", @@ -561,8 +561,8 @@ "\t- Maximum positive particle surface concentration [mol.m-3]\n", "\t- Positive particle radius\n", "\t- Positive particle radius [m]\n", - "\t- Positive surface area per unit volume\n", - "\t- Positive surface area per unit volume [m-1]\n", + "\t- Positive surface area to volume ratio\n", + "\t- Positive surface area to volume ratio [m-1]\n", "\t- Electrolyte concentration\n", "\t- Electrolyte concentration [mol.m-3]\n", "\t- Electrolyte concentration [Molar]\n", diff --git a/examples/notebooks/models/thermal-models.ipynb b/examples/notebooks/models/thermal-models.ipynb index dcbf58100d..ed49458520 100644 --- a/examples/notebooks/models/thermal-models.ipynb +++ b/examples/notebooks/models/thermal-models.ipynb @@ -60,7 +60,7 @@ "\n", "with \n", "$$ Q_{Ohm,k} = -i_k \\nabla \\phi_k, \\quad Q_{rxn,k} = a_k j_k \\eta_k, \\quad Q_{rev,k} = a_k j_k T_k \\frac{\\partial U}{\\partial T} \\bigg|_{T=T_{\\infty}}.$$\n", - "Here $i_k$ is the current, $\\phi_k$ the potential, $a_k$ the surface area per unit volume, $j_k$ the interfacial current density, $\\eta_k$ the overpotential, and $U$ the open circuit potential. The averaged heat source term $\\bar{Q}$ is computed by taking the volume-average of $Q$." + "Here $i_k$ is the current, $\\phi_k$ the potential, $a_k$ the surface area to volume ratio, $j_k$ the interfacial current density, $\\eta_k$ the overpotential, and $U$ the open circuit potential. The averaged heat source term $\\bar{Q}$ is computed by taking the volume-average of $Q$." ] }, { diff --git a/examples/notebooks/solution-data-and-processed-variables.ipynb b/examples/notebooks/solution-data-and-processed-variables.ipynb index a97ca8a187..5d717dc816 100644 --- a/examples/notebooks/solution-data-and-processed-variables.ipynb +++ b/examples/notebooks/solution-data-and-processed-variables.ipynb @@ -149,7 +149,7 @@ "output_type": "stream", "name": "stdout", "text": [ - " electrode temperature', 'Negative electrode temperature [K]', 'Negative electrode tortuosity', 'Negative electrode transverse volume-averaged acceleration', 'Negative electrode transverse volume-averaged acceleration [m.s-2]', 'Negative electrode transverse volume-averaged velocity', 'Negative electrode transverse volume-averaged velocity [m.s-2]', 'Negative electrode volume-averaged acceleration', 'Negative electrode volume-averaged acceleration [m.s-1]', 'Negative electrode volume-averaged concentration', 'Negative electrode volume-averaged concentration [mol.m-3]', 'Negative electrode volume-averaged velocity', 'Negative electrode volume-averaged velocity [m.s-1]', 'Negative electrolyte concentration', 'Negative electrolyte concentration [Molar]', 'Negative electrolyte concentration [mol.m-3]', 'Negative electrolyte current density', 'Negative electrolyte current density [A.m-2]', 'Negative electrolyte potential', 'Negative electrolyte potential [V]', 'Negative electrolyte tortuosity', 'Negative particle concentration', 'Negative particle concentration [mol.m-3]', 'Negative particle flux', 'Negative particle surface concentration', 'Negative particle surface concentration [mol.m-3]', 'Negative sei concentration [mol.m-3]', 'Negative surface area per unit volume distribution in x', 'Ohmic heating', 'Ohmic heating [W.m-3]', 'Outer negative electrode sei concentration [mol.m-3]', 'Outer negative electrode sei interfacial current density', 'Outer negative electrode sei interfacial current density [A.m-2]', 'Outer negative electrode sei thickness', 'Outer negative electrode sei thickness [m]', 'Outer positive electrode sei concentration [mol.m-3]', 'Outer positive electrode sei interfacial current density', 'Outer positive electrode sei interfacial current density [A.m-2]', 'Outer positive electrode sei thickness', 'Outer positive electrode sei thickness [m]', 'Oxygen exchange current density', 'Oxygen exchange current density [A.m-2]', 'Oxygen exchange current density per volume [A.m-3]', 'Oxygen interfacial current density', 'Oxygen interfacial current density [A.m-2]', 'Oxygen interfacial current density per volume [A.m-3]', 'Porosity', 'Porosity change', 'Positive current collector potential', 'Positive current collector potential [V]', 'Positive current collector temperature', 'Positive current collector temperature [K]', 'Positive electrode active material volume fraction', 'Positive electrode active volume fraction', 'Positive electrode current density', 'Positive electrode current density [A.m-2]', 'Positive electrode entropic change', 'Positive electrode exchange current density', 'Positive electrode exchange current density [A.m-2]', 'Positive electrode exchange current density per volume [A.m-3]', 'Positive electrode extent of lithiation', 'Positive electrode interfacial current density', 'Positive electrode interfacial current density [A.m-2]', 'Positive electrode interfacial current density per volume [A.m-3]', 'Positive electrode ohmic losses', 'Positive electrode ohmic losses [V]', 'Positive electrode open circuit potential', 'Positive electrode open circuit potential [V]', 'Positive electrode oxygen exchange current density', 'Positive electrode oxygen exchange current density [A.m-2]', 'Positive electrode oxygen exchange current density per volume [A.m-3]', 'Positive electrode oxygen interfacial current density', 'Positive electrode oxygen interfacial current density [A.m-2]', 'Positive electrode oxygen interfacial current density per volume [A.m-3]', 'Positive electrode oxygen open circuit potential', 'Positive electrode oxygen open circuit potential [V]', 'Positive electrode oxygen reaction overpotential', 'Positive electrode oxygen reaction overpotential [V]', 'Positive electrode porosity', 'Positive electrode porosity change', 'Positive electrode potential', 'Positive electrode potential [V]', 'Positive electrode pressure', 'Positive electrode reaction overpotential', 'Positive electrode reaction overpotential [V]', 'Positive electrode sei film overpotential', 'Positive electrode sei film overpotential [V]', 'Positive electrode sei interfacial current density', 'Positive electrode sei interfacial current density [A.m-2]', 'Positive electrode surface potential difference', 'Positive electrode surface potential difference [V]', 'Positive electrode temperature', 'Positive electrode temperature [K]', 'Positive electrode tortuosity', 'Positive electrode transverse volume-averaged acceleration', 'Positive electrode transverse volume-averaged acceleration [m.s-2]', 'Positive electrode transverse volume-averaged velocity', 'Positive electrode transverse volume-averaged velocity [m.s-2]', 'Positive electrode volume-averaged acceleration', 'Positive electrode volume-averaged acceleration [m.s-1]', 'Positive electrode volume-averaged concentration', 'Positive electrode volume-averaged concentration [mol.m-3]', 'Positive electrode volume-averaged velocity', 'Positive electrode volume-averaged velocity [m.s-1]', 'Positive electrolyte concentration', 'Positive electrolyte concentration [Molar]', 'Positive electrolyte concentration [mol.m-3]', 'Positive electrolyte current density', 'Positive electrolyte current density [A.m-2]', 'Positive electrolyte potential', 'Positive electrolyte potential [V]', 'Positive electrolyte tortuosity', 'Positive particle concentration', 'Positive particle concentration [mol.m-3]', 'Positive particle flux', 'Positive particle surface concentration', 'Positive particle surface concentration [mol.m-3]', 'Positive sei concentration [mol.m-3]', 'Positive surface area per unit volume distribution in x', 'Pressure', 'R-averaged negative particle concentration', 'R-averaged negative particle concentration [mol.m-3]', 'R-averaged positive particle concentration', 'R-averaged positive particle concentration [mol.m-3]', 'Reversible heating', 'Reversible heating [W.m-3]', 'Sei interfacial current density', 'Sei interfacial current density [A.m-2]', 'Sei interfacial current density per volume [A.m-3]', 'Separator active material volume fraction', 'Separator electrolyte concentration', 'Separator electrolyte concentration [Molar]', 'Separator electrolyte concentration [mol.m-3]', 'Separator electrolyte potential', 'Separator electrolyte potential [V]', 'Separator porosity', 'Separator porosity change', 'Separator pressure', 'Separator temperature', 'Separator temperature [K]', 'Separator tortuosity', 'Separator transverse volume-averaged acceleration', 'Separator transverse volume-averaged acceleration [m.s-2]', 'Separator transverse volume-averaged velocity', 'Separator transverse volume-averaged velocity [m.s-2]', 'Separator volume-averaged acceleration', 'Separator volume-averaged acceleration [m.s-1]', 'Separator volume-averaged velocity', 'Separator volume-averaged velocity [m.s-1]', 'Sum of electrolyte reaction source terms', 'Sum of interfacial current densities', 'Sum of negative electrode electrolyte reaction source terms', 'Sum of negative electrode interfacial current densities', 'Sum of positive electrode electrolyte reaction source terms', 'Sum of positive electrode interfacial current densities', 'Sum of x-averaged negative electrode electrolyte reaction source terms', 'Sum of x-averaged negative electrode interfacial current densities', 'Sum of x-averaged positive electrode electrolyte reaction source terms', 'Sum of x-averaged positive electrode interfacial current densities', 'Terminal power [W]', 'Terminal voltage', 'Terminal voltage [V]', 'Time', 'Time [h]', 'Time [min]', 'Time [s]', 'Total concentration in electrolyte [mol]', 'Total current density', 'Total current density [A.m-2]', 'Total heating', 'Total heating [W.m-3]', 'Total lithium in negative electrode [mol]', 'Total lithium in positive electrode [mol]', 'Total negative electrode sei thickness', 'Total negative electrode sei thickness [m]', 'Total positive electrode sei thickness', 'Total positive electrode sei thickness [m]', 'Transverse volume-averaged acceleration', 'Transverse volume-averaged acceleration [m.s-2]', 'Transverse volume-averaged velocity', 'Transverse volume-averaged velocity [m.s-2]', 'Volume-averaged Ohmic heating', 'Volume-averaged Ohmic heating [W.m-3]', 'Volume-averaged acceleration', 'Volume-averaged acceleration [m.s-1]', 'Volume-averaged cell temperature', 'Volume-averaged cell temperature [K]', 'Volume-averaged irreversible electrochemical heating', 'Volume-averaged irreversible electrochemical heating[W.m-3]', 'Volume-averaged reversible heating', 'Volume-averaged reversible heating [W.m-3]', 'Volume-averaged total heating', 'Volume-averaged total heating [W.m-3]', 'Volume-averaged velocity', 'Volume-averaged velocity [m.s-1]', 'X-averaged Ohmic heating', 'X-averaged Ohmic heating [W.m-3]', 'X-averaged battery concentration overpotential [V]', 'X-averaged battery electrolyte ohmic losses [V]', 'X-averaged battery open circuit voltage [V]', 'X-averaged battery reaction overpotential [V]', 'X-averaged battery solid phase ohmic losses [V]', 'X-averaged cell temperature', 'X-averaged cell temperature [K]', 'X-averaged concentration overpotential', 'X-averaged concentration overpotential [V]', 'X-averaged electrolyte concentration', 'X-averaged electrolyte concentration [Molar]', 'X-averaged electrolyte concentration [mol.m-3]', 'X-averaged electrolyte ohmic losses', 'X-averaged electrolyte ohmic losses [V]', 'X-averaged electrolyte overpotential', 'X-averaged electrolyte overpotential [V]', 'X-averaged electrolyte potential', 'X-averaged electrolyte potential [V]', 'X-averaged inner negative electrode sei concentration [mol.m-3]', 'X-averaged inner negative electrode sei interfacial current density', 'X-averaged inner negative electrode sei interfacial current density [A.m-2]', 'X-averaged inner negative electrode sei thickness', 'X-averaged inner negative electrode sei thickness [m]', 'X-averaged inner positive electrode sei concentration [mol.m-3]', 'X-averaged inner positive electrode sei interfacial current density', 'X-averaged inner positive electrode sei interfacial current density [A.m-2]', 'X-averaged inner positive electrode sei thickness', 'X-averaged inner positive electrode sei thickness [m]', 'X-averaged irreversible electrochemical heating', 'X-averaged irreversible electrochemical heating [W.m-3]', 'X-averaged negative electrode active material volume fraction', 'X-averaged negative electrode entropic change', 'X-averaged negative electrode exchange current density', 'X-averaged negative electrode exchange current density [A.m-2]', 'X-averaged negative electrode exchange current density per volume [A.m-3]', 'X-averaged negative electrode extent of lithiation', 'X-averaged negative electrode interfacial current density', 'X-averaged negative electrode interfacial current density [A.m-2]', 'X-averaged negative electrode interfacial current density per volume [A.m-3]', 'X-averaged negative electrode ohmic losses', 'X-averaged negative electrode ohmic losses [V]', 'X-averaged negative electrode open circuit potential', 'X-averaged negative electrode open circuit potential [V]', 'X-averaged negative electrode oxygen exchange current density', 'X-averaged negative electrode oxygen exchange current density [A.m-2]', 'X-averaged negative electrode oxygen exchange current density per volume [A.m-3]', 'X-averaged negative electrode oxygen interfacial current density', 'X-averaged negative electrode oxygen interfacial current density [A.m-2]', 'X-averaged negative electrode oxygen interfacial current density per volume [A.m-3]', 'X-averaged negative electrode oxygen open circuit potential', 'X-averaged negative electrode oxygen open circuit potential [V]', 'X-averaged negative electrode oxygen reaction overpotential', 'X-averaged negative electrode oxygen reaction overpotential [V]', 'X-averaged negative electrode porosity', 'X-averaged negative electrode porosity change', 'X-averaged negative electrode potential', 'X-averaged negative electrode potential [V]', 'X-averaged negative electrode pressure', 'X-averaged negative electrode reaction overpotential', 'X-averaged negative electrode reaction overpotential [V]', 'X-averaged negative electrode resistance [Ohm.m2]', 'X-averaged negative electrode sei concentration [mol.m-3]', 'X-averaged negative electrode sei film overpotential', 'X-averaged negative electrode sei film overpotential [V]', 'X-averaged negative electrode sei interfacial current density', 'X-averaged negative electrode sei interfacial current density [A.m-2]', 'X-averaged negative electrode surface potential difference', 'X-averaged negative electrode surface potential difference [V]', 'X-averaged negative electrode temperature', 'X-averaged negative electrode temperature [K]', 'X-averaged negative electrode tortuosity', 'X-averaged negative electrode total interfacial current density', 'X-averaged negative electrode total interfacial current density [A.m-2]', 'X-averaged negative electrode total interfacial current density per volume [A.m-3]', 'X-averaged negative electrode transverse volume-averaged acceleration', 'X-averaged negative electrode transverse volume-averaged acceleration [m.s-2]', 'X-averaged negative electrode transverse volume-averaged velocity', 'X-averaged negative electrode transverse volume-averaged velocity [m.s-2]', 'X-averaged negative electrode volume-averaged acceleration', 'X-averaged negative electrode volume-averaged acceleration [m.s-1]', 'X-averaged negative electrolyte concentration', 'X-averaged negative electrolyte concentration [mol.m-3]', 'X-averaged negative electrolyte potential', 'X-averaged negative electrolyte potential [V]', 'X-averaged negative electrolyte tortuosity', 'X-averaged negative particle concentration', 'X-averaged negative particle concentration [mol.m-3]', 'X-averaged negative particle flux', 'X-averaged negative particle surface concentration', 'X-averaged negative particle surface concentration [mol.m-3]', 'X-averaged open circuit voltage', 'X-averaged open circuit voltage [V]', 'X-averaged outer negative electrode sei concentration [mol.m-3]', 'X-averaged outer negative electrode sei interfacial current density', 'X-averaged outer negative electrode sei interfacial current density [A.m-2]', 'X-averaged outer negative electrode sei thickness', 'X-averaged outer negative electrode sei thickness [m]', 'X-averaged outer positive electrode sei concentration [mol.m-3]', 'X-averaged outer positive electrode sei interfacial current density', 'X-averaged outer positive electrode sei interfacial current density [A.m-2]', 'X-averaged outer positive electrode sei thickness', 'X-averaged outer positive electrode sei thickness [m]', 'X-averaged positive electrode active material volume fraction', 'X-averaged positive electrode entropic change', 'X-averaged positive electrode exchange current density', 'X-averaged positive electrode exchange current density [A.m-2]', 'X-averaged positive electrode exchange current density per volume [A.m-3]', 'X-averaged positive electrode extent of lithiation', 'X-averaged positive electrode interfacial current density', 'X-averaged positive electrode interfacial current density [A.m-2]', 'X-averaged positive electrode interfacial current density per volume [A.m-3]', 'X-averaged positive electrode ohmic losses', 'X-averaged positive electrode ohmic losses [V]', 'X-averaged positive electrode open circuit potential', 'X-averaged positive electrode open circuit potential [V]', 'X-averaged positive electrode oxygen exchange current density', 'X-averaged positive electrode oxygen exchange current density [A.m-2]', 'X-averaged positive electrode oxygen exchange current density per volume [A.m-3]', 'X-averaged positive electrode oxygen interfacial current density', 'X-averaged positive electrode oxygen interfacial current density [A.m-2]', 'X-averaged positive electrode oxygen interfacial current density per volume [A.m-3]', 'X-averaged positive electrode oxygen open circuit potential', 'X-averaged positive electrode oxygen open circuit potential [V]', 'X-averaged positive electrode oxygen reaction overpotential', 'X-averaged positive electrode oxygen reaction overpotential [V]', 'X-averaged positive electrode porosity', 'X-averaged positive electrode porosity change', 'X-averaged positive electrode potential', 'X-averaged positive electrode potential [V]', 'X-averaged positive electrode pressure', 'X-averaged positive electrode reaction overpotential', 'X-averaged positive electrode reaction overpotential [V]', 'X-averaged positive electrode resistance [Ohm.m2]', 'X-averaged positive electrode sei concentration [mol.m-3]', 'X-averaged positive electrode sei film overpotential', 'X-averaged positive electrode sei film overpotential [V]', 'X-averaged positive electrode sei interfacial current density', 'X-averaged positive electrode sei interfacial current density [A.m-2]', 'X-averaged positive electrode surface potential difference', 'X-averaged positive electrode surface potential difference [V]', 'X-averaged positive electrode temperature', 'X-averaged positive electrode temperature [K]', 'X-averaged positive electrode tortuosity', 'X-averaged positive electrode total interfacial current density', 'X-averaged positive electrode total interfacial current density [A.m-2]', 'X-averaged positive electrode total interfacial current density per volume [A.m-3]', 'X-averaged positive electrode transverse volume-averaged acceleration', 'X-averaged positive electrode transverse volume-averaged acceleration [m.s-2]', 'X-averaged positive electrode transverse volume-averaged velocity', 'X-averaged positive electrode transverse volume-averaged velocity [m.s-2]', 'X-averaged positive electrode volume-averaged acceleration', 'X-averaged positive electrode volume-averaged acceleration [m.s-1]', 'X-averaged positive electrolyte concentration', 'X-averaged positive electrolyte concentration [mol.m-3]', 'X-averaged positive electrolyte potential', 'X-averaged positive electrolyte potential [V]', 'X-averaged positive electrolyte tortuosity', 'X-averaged positive particle concentration', 'X-averaged positive particle concentration [mol.m-3]', 'X-averaged positive particle flux', 'X-averaged positive particle surface concentration', 'X-averaged positive particle surface concentration [mol.m-3]', 'X-averaged reaction overpotential', 'X-averaged reaction overpotential [V]', 'X-averaged reversible heating', 'X-averaged reversible heating [W.m-3]', 'X-averaged sei film overpotential', 'X-averaged sei film overpotential [V]', 'X-averaged separator active material volume fraction', 'X-averaged separator electrolyte concentration', 'X-averaged separator electrolyte concentration [mol.m-3]', 'X-averaged separator electrolyte potential', 'X-averaged separator electrolyte potential [V]', 'X-averaged separator porosity', 'X-averaged separator porosity change', 'X-averaged separator pressure', 'X-averaged separator temperature', 'X-averaged separator temperature [K]', 'X-averaged separator tortuosity', 'X-averaged separator transverse volume-averaged acceleration', 'X-averaged separator transverse volume-averaged acceleration [m.s-2]', 'X-averaged separator transverse volume-averaged velocity', 'X-averaged separator transverse volume-averaged velocity [m.s-2]', 'X-averaged separator volume-averaged acceleration', 'X-averaged separator volume-averaged acceleration [m.s-1]', 'X-averaged solid phase ohmic losses', 'X-averaged solid phase ohmic losses [V]', 'X-averaged total heating', 'X-averaged total heating [W.m-3]', 'X-averaged total negative electrode sei thickness', 'X-averaged total negative electrode sei thickness [m]', 'X-averaged total positive electrode sei thickness', 'X-averaged total positive electrode sei thickness [m]', 'X-averaged volume-averaged acceleration', 'X-averaged volume-averaged acceleration [m.s-1]', 'r_n', 'r_n [m]', 'r_p', 'r_p [m]', 'x', 'x [m]', 'x_n', 'x_n [m]', 'x_p', 'x_p [m]', 'x_s', 'x_s [m]']\n" + " electrode temperature', 'Negative electrode temperature [K]', 'Negative electrode tortuosity', 'Negative electrode transverse volume-averaged acceleration', 'Negative electrode transverse volume-averaged acceleration [m.s-2]', 'Negative electrode transverse volume-averaged velocity', 'Negative electrode transverse volume-averaged velocity [m.s-2]', 'Negative electrode volume-averaged acceleration', 'Negative electrode volume-averaged acceleration [m.s-1]', 'Negative electrode volume-averaged concentration', 'Negative electrode volume-averaged concentration [mol.m-3]', 'Negative electrode volume-averaged velocity', 'Negative electrode volume-averaged velocity [m.s-1]', 'Negative electrolyte concentration', 'Negative electrolyte concentration [Molar]', 'Negative electrolyte concentration [mol.m-3]', 'Negative electrolyte current density', 'Negative electrolyte current density [A.m-2]', 'Negative electrolyte potential', 'Negative electrolyte potential [V]', 'Negative electrolyte tortuosity', 'Negative particle concentration', 'Negative particle concentration [mol.m-3]', 'Negative particle flux', 'Negative particle surface concentration', 'Negative particle surface concentration [mol.m-3]', 'Negative sei concentration [mol.m-3]', 'Negative surface area to volume ratio distribution in x', 'Ohmic heating', 'Ohmic heating [W.m-3]', 'Outer negative electrode sei concentration [mol.m-3]', 'Outer negative electrode sei interfacial current density', 'Outer negative electrode sei interfacial current density [A.m-2]', 'Outer negative electrode sei thickness', 'Outer negative electrode sei thickness [m]', 'Outer positive electrode sei concentration [mol.m-3]', 'Outer positive electrode sei interfacial current density', 'Outer positive electrode sei interfacial current density [A.m-2]', 'Outer positive electrode sei thickness', 'Outer positive electrode sei thickness [m]', 'Oxygen exchange current density', 'Oxygen exchange current density [A.m-2]', 'Oxygen exchange current density per volume [A.m-3]', 'Oxygen interfacial current density', 'Oxygen interfacial current density [A.m-2]', 'Oxygen interfacial current density per volume [A.m-3]', 'Porosity', 'Porosity change', 'Positive current collector potential', 'Positive current collector potential [V]', 'Positive current collector temperature', 'Positive current collector temperature [K]', 'Positive electrode active material volume fraction', 'Positive electrode active volume fraction', 'Positive electrode current density', 'Positive electrode current density [A.m-2]', 'Positive electrode entropic change', 'Positive electrode exchange current density', 'Positive electrode exchange current density [A.m-2]', 'Positive electrode exchange current density per volume [A.m-3]', 'Positive electrode extent of lithiation', 'Positive electrode interfacial current density', 'Positive electrode interfacial current density [A.m-2]', 'Positive electrode interfacial current density per volume [A.m-3]', 'Positive electrode ohmic losses', 'Positive electrode ohmic losses [V]', 'Positive electrode open circuit potential', 'Positive electrode open circuit potential [V]', 'Positive electrode oxygen exchange current density', 'Positive electrode oxygen exchange current density [A.m-2]', 'Positive electrode oxygen exchange current density per volume [A.m-3]', 'Positive electrode oxygen interfacial current density', 'Positive electrode oxygen interfacial current density [A.m-2]', 'Positive electrode oxygen interfacial current density per volume [A.m-3]', 'Positive electrode oxygen open circuit potential', 'Positive electrode oxygen open circuit potential [V]', 'Positive electrode oxygen reaction overpotential', 'Positive electrode oxygen reaction overpotential [V]', 'Positive electrode porosity', 'Positive electrode porosity change', 'Positive electrode potential', 'Positive electrode potential [V]', 'Positive electrode pressure', 'Positive electrode reaction overpotential', 'Positive electrode reaction overpotential [V]', 'Positive electrode sei film overpotential', 'Positive electrode sei film overpotential [V]', 'Positive electrode sei interfacial current density', 'Positive electrode sei interfacial current density [A.m-2]', 'Positive electrode surface potential difference', 'Positive electrode surface potential difference [V]', 'Positive electrode temperature', 'Positive electrode temperature [K]', 'Positive electrode tortuosity', 'Positive electrode transverse volume-averaged acceleration', 'Positive electrode transverse volume-averaged acceleration [m.s-2]', 'Positive electrode transverse volume-averaged velocity', 'Positive electrode transverse volume-averaged velocity [m.s-2]', 'Positive electrode volume-averaged acceleration', 'Positive electrode volume-averaged acceleration [m.s-1]', 'Positive electrode volume-averaged concentration', 'Positive electrode volume-averaged concentration [mol.m-3]', 'Positive electrode volume-averaged velocity', 'Positive electrode volume-averaged velocity [m.s-1]', 'Positive electrolyte concentration', 'Positive electrolyte concentration [Molar]', 'Positive electrolyte concentration [mol.m-3]', 'Positive electrolyte current density', 'Positive electrolyte current density [A.m-2]', 'Positive electrolyte potential', 'Positive electrolyte potential [V]', 'Positive electrolyte tortuosity', 'Positive particle concentration', 'Positive particle concentration [mol.m-3]', 'Positive particle flux', 'Positive particle surface concentration', 'Positive particle surface concentration [mol.m-3]', 'Positive sei concentration [mol.m-3]', 'Positive surface area to volume ratio distribution in x', 'Pressure', 'R-averaged negative particle concentration', 'R-averaged negative particle concentration [mol.m-3]', 'R-averaged positive particle concentration', 'R-averaged positive particle concentration [mol.m-3]', 'Reversible heating', 'Reversible heating [W.m-3]', 'Sei interfacial current density', 'Sei interfacial current density [A.m-2]', 'Sei interfacial current density per volume [A.m-3]', 'Separator active material volume fraction', 'Separator electrolyte concentration', 'Separator electrolyte concentration [Molar]', 'Separator electrolyte concentration [mol.m-3]', 'Separator electrolyte potential', 'Separator electrolyte potential [V]', 'Separator porosity', 'Separator porosity change', 'Separator pressure', 'Separator temperature', 'Separator temperature [K]', 'Separator tortuosity', 'Separator transverse volume-averaged acceleration', 'Separator transverse volume-averaged acceleration [m.s-2]', 'Separator transverse volume-averaged velocity', 'Separator transverse volume-averaged velocity [m.s-2]', 'Separator volume-averaged acceleration', 'Separator volume-averaged acceleration [m.s-1]', 'Separator volume-averaged velocity', 'Separator volume-averaged velocity [m.s-1]', 'Sum of electrolyte reaction source terms', 'Sum of interfacial current densities', 'Sum of negative electrode electrolyte reaction source terms', 'Sum of negative electrode interfacial current densities', 'Sum of positive electrode electrolyte reaction source terms', 'Sum of positive electrode interfacial current densities', 'Sum of x-averaged negative electrode electrolyte reaction source terms', 'Sum of x-averaged negative electrode interfacial current densities', 'Sum of x-averaged positive electrode electrolyte reaction source terms', 'Sum of x-averaged positive electrode interfacial current densities', 'Terminal power [W]', 'Terminal voltage', 'Terminal voltage [V]', 'Time', 'Time [h]', 'Time [min]', 'Time [s]', 'Total concentration in electrolyte [mol]', 'Total current density', 'Total current density [A.m-2]', 'Total heating', 'Total heating [W.m-3]', 'Total lithium in negative electrode [mol]', 'Total lithium in positive electrode [mol]', 'Total negative electrode sei thickness', 'Total negative electrode sei thickness [m]', 'Total positive electrode sei thickness', 'Total positive electrode sei thickness [m]', 'Transverse volume-averaged acceleration', 'Transverse volume-averaged acceleration [m.s-2]', 'Transverse volume-averaged velocity', 'Transverse volume-averaged velocity [m.s-2]', 'Volume-averaged Ohmic heating', 'Volume-averaged Ohmic heating [W.m-3]', 'Volume-averaged acceleration', 'Volume-averaged acceleration [m.s-1]', 'Volume-averaged cell temperature', 'Volume-averaged cell temperature [K]', 'Volume-averaged irreversible electrochemical heating', 'Volume-averaged irreversible electrochemical heating[W.m-3]', 'Volume-averaged reversible heating', 'Volume-averaged reversible heating [W.m-3]', 'Volume-averaged total heating', 'Volume-averaged total heating [W.m-3]', 'Volume-averaged velocity', 'Volume-averaged velocity [m.s-1]', 'X-averaged Ohmic heating', 'X-averaged Ohmic heating [W.m-3]', 'X-averaged battery concentration overpotential [V]', 'X-averaged battery electrolyte ohmic losses [V]', 'X-averaged battery open circuit voltage [V]', 'X-averaged battery reaction overpotential [V]', 'X-averaged battery solid phase ohmic losses [V]', 'X-averaged cell temperature', 'X-averaged cell temperature [K]', 'X-averaged concentration overpotential', 'X-averaged concentration overpotential [V]', 'X-averaged electrolyte concentration', 'X-averaged electrolyte concentration [Molar]', 'X-averaged electrolyte concentration [mol.m-3]', 'X-averaged electrolyte ohmic losses', 'X-averaged electrolyte ohmic losses [V]', 'X-averaged electrolyte overpotential', 'X-averaged electrolyte overpotential [V]', 'X-averaged electrolyte potential', 'X-averaged electrolyte potential [V]', 'X-averaged inner negative electrode sei concentration [mol.m-3]', 'X-averaged inner negative electrode sei interfacial current density', 'X-averaged inner negative electrode sei interfacial current density [A.m-2]', 'X-averaged inner negative electrode sei thickness', 'X-averaged inner negative electrode sei thickness [m]', 'X-averaged inner positive electrode sei concentration [mol.m-3]', 'X-averaged inner positive electrode sei interfacial current density', 'X-averaged inner positive electrode sei interfacial current density [A.m-2]', 'X-averaged inner positive electrode sei thickness', 'X-averaged inner positive electrode sei thickness [m]', 'X-averaged irreversible electrochemical heating', 'X-averaged irreversible electrochemical heating [W.m-3]', 'X-averaged negative electrode active material volume fraction', 'X-averaged negative electrode entropic change', 'X-averaged negative electrode exchange current density', 'X-averaged negative electrode exchange current density [A.m-2]', 'X-averaged negative electrode exchange current density per volume [A.m-3]', 'X-averaged negative electrode extent of lithiation', 'X-averaged negative electrode interfacial current density', 'X-averaged negative electrode interfacial current density [A.m-2]', 'X-averaged negative electrode interfacial current density per volume [A.m-3]', 'X-averaged negative electrode ohmic losses', 'X-averaged negative electrode ohmic losses [V]', 'X-averaged negative electrode open circuit potential', 'X-averaged negative electrode open circuit potential [V]', 'X-averaged negative electrode oxygen exchange current density', 'X-averaged negative electrode oxygen exchange current density [A.m-2]', 'X-averaged negative electrode oxygen exchange current density per volume [A.m-3]', 'X-averaged negative electrode oxygen interfacial current density', 'X-averaged negative electrode oxygen interfacial current density [A.m-2]', 'X-averaged negative electrode oxygen interfacial current density per volume [A.m-3]', 'X-averaged negative electrode oxygen open circuit potential', 'X-averaged negative electrode oxygen open circuit potential [V]', 'X-averaged negative electrode oxygen reaction overpotential', 'X-averaged negative electrode oxygen reaction overpotential [V]', 'X-averaged negative electrode porosity', 'X-averaged negative electrode porosity change', 'X-averaged negative electrode potential', 'X-averaged negative electrode potential [V]', 'X-averaged negative electrode pressure', 'X-averaged negative electrode reaction overpotential', 'X-averaged negative electrode reaction overpotential [V]', 'X-averaged negative electrode resistance [Ohm.m2]', 'X-averaged negative electrode sei concentration [mol.m-3]', 'X-averaged negative electrode sei film overpotential', 'X-averaged negative electrode sei film overpotential [V]', 'X-averaged negative electrode sei interfacial current density', 'X-averaged negative electrode sei interfacial current density [A.m-2]', 'X-averaged negative electrode surface potential difference', 'X-averaged negative electrode surface potential difference [V]', 'X-averaged negative electrode temperature', 'X-averaged negative electrode temperature [K]', 'X-averaged negative electrode tortuosity', 'X-averaged negative electrode total interfacial current density', 'X-averaged negative electrode total interfacial current density [A.m-2]', 'X-averaged negative electrode total interfacial current density per volume [A.m-3]', 'X-averaged negative electrode transverse volume-averaged acceleration', 'X-averaged negative electrode transverse volume-averaged acceleration [m.s-2]', 'X-averaged negative electrode transverse volume-averaged velocity', 'X-averaged negative electrode transverse volume-averaged velocity [m.s-2]', 'X-averaged negative electrode volume-averaged acceleration', 'X-averaged negative electrode volume-averaged acceleration [m.s-1]', 'X-averaged negative electrolyte concentration', 'X-averaged negative electrolyte concentration [mol.m-3]', 'X-averaged negative electrolyte potential', 'X-averaged negative electrolyte potential [V]', 'X-averaged negative electrolyte tortuosity', 'X-averaged negative particle concentration', 'X-averaged negative particle concentration [mol.m-3]', 'X-averaged negative particle flux', 'X-averaged negative particle surface concentration', 'X-averaged negative particle surface concentration [mol.m-3]', 'X-averaged open circuit voltage', 'X-averaged open circuit voltage [V]', 'X-averaged outer negative electrode sei concentration [mol.m-3]', 'X-averaged outer negative electrode sei interfacial current density', 'X-averaged outer negative electrode sei interfacial current density [A.m-2]', 'X-averaged outer negative electrode sei thickness', 'X-averaged outer negative electrode sei thickness [m]', 'X-averaged outer positive electrode sei concentration [mol.m-3]', 'X-averaged outer positive electrode sei interfacial current density', 'X-averaged outer positive electrode sei interfacial current density [A.m-2]', 'X-averaged outer positive electrode sei thickness', 'X-averaged outer positive electrode sei thickness [m]', 'X-averaged positive electrode active material volume fraction', 'X-averaged positive electrode entropic change', 'X-averaged positive electrode exchange current density', 'X-averaged positive electrode exchange current density [A.m-2]', 'X-averaged positive electrode exchange current density per volume [A.m-3]', 'X-averaged positive electrode extent of lithiation', 'X-averaged positive electrode interfacial current density', 'X-averaged positive electrode interfacial current density [A.m-2]', 'X-averaged positive electrode interfacial current density per volume [A.m-3]', 'X-averaged positive electrode ohmic losses', 'X-averaged positive electrode ohmic losses [V]', 'X-averaged positive electrode open circuit potential', 'X-averaged positive electrode open circuit potential [V]', 'X-averaged positive electrode oxygen exchange current density', 'X-averaged positive electrode oxygen exchange current density [A.m-2]', 'X-averaged positive electrode oxygen exchange current density per volume [A.m-3]', 'X-averaged positive electrode oxygen interfacial current density', 'X-averaged positive electrode oxygen interfacial current density [A.m-2]', 'X-averaged positive electrode oxygen interfacial current density per volume [A.m-3]', 'X-averaged positive electrode oxygen open circuit potential', 'X-averaged positive electrode oxygen open circuit potential [V]', 'X-averaged positive electrode oxygen reaction overpotential', 'X-averaged positive electrode oxygen reaction overpotential [V]', 'X-averaged positive electrode porosity', 'X-averaged positive electrode porosity change', 'X-averaged positive electrode potential', 'X-averaged positive electrode potential [V]', 'X-averaged positive electrode pressure', 'X-averaged positive electrode reaction overpotential', 'X-averaged positive electrode reaction overpotential [V]', 'X-averaged positive electrode resistance [Ohm.m2]', 'X-averaged positive electrode sei concentration [mol.m-3]', 'X-averaged positive electrode sei film overpotential', 'X-averaged positive electrode sei film overpotential [V]', 'X-averaged positive electrode sei interfacial current density', 'X-averaged positive electrode sei interfacial current density [A.m-2]', 'X-averaged positive electrode surface potential difference', 'X-averaged positive electrode surface potential difference [V]', 'X-averaged positive electrode temperature', 'X-averaged positive electrode temperature [K]', 'X-averaged positive electrode tortuosity', 'X-averaged positive electrode total interfacial current density', 'X-averaged positive electrode total interfacial current density [A.m-2]', 'X-averaged positive electrode total interfacial current density per volume [A.m-3]', 'X-averaged positive electrode transverse volume-averaged acceleration', 'X-averaged positive electrode transverse volume-averaged acceleration [m.s-2]', 'X-averaged positive electrode transverse volume-averaged velocity', 'X-averaged positive electrode transverse volume-averaged velocity [m.s-2]', 'X-averaged positive electrode volume-averaged acceleration', 'X-averaged positive electrode volume-averaged acceleration [m.s-1]', 'X-averaged positive electrolyte concentration', 'X-averaged positive electrolyte concentration [mol.m-3]', 'X-averaged positive electrolyte potential', 'X-averaged positive electrolyte potential [V]', 'X-averaged positive electrolyte tortuosity', 'X-averaged positive particle concentration', 'X-averaged positive particle concentration [mol.m-3]', 'X-averaged positive particle flux', 'X-averaged positive particle surface concentration', 'X-averaged positive particle surface concentration [mol.m-3]', 'X-averaged reaction overpotential', 'X-averaged reaction overpotential [V]', 'X-averaged reversible heating', 'X-averaged reversible heating [W.m-3]', 'X-averaged sei film overpotential', 'X-averaged sei film overpotential [V]', 'X-averaged separator active material volume fraction', 'X-averaged separator electrolyte concentration', 'X-averaged separator electrolyte concentration [mol.m-3]', 'X-averaged separator electrolyte potential', 'X-averaged separator electrolyte potential [V]', 'X-averaged separator porosity', 'X-averaged separator porosity change', 'X-averaged separator pressure', 'X-averaged separator temperature', 'X-averaged separator temperature [K]', 'X-averaged separator tortuosity', 'X-averaged separator transverse volume-averaged acceleration', 'X-averaged separator transverse volume-averaged acceleration [m.s-2]', 'X-averaged separator transverse volume-averaged velocity', 'X-averaged separator transverse volume-averaged velocity [m.s-2]', 'X-averaged separator volume-averaged acceleration', 'X-averaged separator volume-averaged acceleration [m.s-1]', 'X-averaged solid phase ohmic losses', 'X-averaged solid phase ohmic losses [V]', 'X-averaged total heating', 'X-averaged total heating [W.m-3]', 'X-averaged total negative electrode sei thickness', 'X-averaged total negative electrode sei thickness [m]', 'X-averaged total positive electrode sei thickness', 'X-averaged total positive electrode sei thickness [m]', 'X-averaged volume-averaged acceleration', 'X-averaged volume-averaged acceleration [m.s-1]', 'r_n', 'r_n [m]', 'r_p', 'r_p [m]', 'x', 'x [m]', 'x_n', 'x_n [m]', 'x_p', 'x_p [m]', 'x_s', 'x_s [m]']\n" ] } ], diff --git a/examples/scripts/compare_particle_shape.py b/examples/scripts/compare_particle_shape.py index 393dd85211..a43c6cfbb6 100644 --- a/examples/scripts/compare_particle_shape.py +++ b/examples/scripts/compare_particle_shape.py @@ -1,8 +1,8 @@ # -# Example showing how to prescribe the surface area per unit volume independent of +# Example showing how to prescribe the surface area to volume ratio independent of # the assumed particle shape. Setting the "particle shape" option to "user" returns # a model which solves a spherical diffusion problem in the particles, but passes -# a user supplied surface area per unit volume +# a user supplied surface area to volume ratio # import pybamm diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 11e96ce2e0..5ac478ae15 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -48,7 +48,7 @@ class BaseBatteryModel(pybamm.BaseModel): "quadratic profile", or "quartic profile". * "particle shape" : str, optional Sets the model shape of the electrode particles. This is used to - calculate the surface area per unit volume. Can be "spherical" + calculate the surface area to volume ratio. Can be "spherical" (default) or "user". For the "user" option the surface area per unit volume can be passed as a parameter, and is therefore not necessarily consistent with the particle shape. diff --git a/pybamm/models/submodels/active_material/base_active_material.py b/pybamm/models/submodels/active_material/base_active_material.py index 1730aaa297..a930d18337 100644 --- a/pybamm/models/submodels/active_material/base_active_material.py +++ b/pybamm/models/submodels/active_material/base_active_material.py @@ -45,9 +45,9 @@ def _get_standard_active_material_variables(self, eps_solid): a_typ = self.param.a_p_typ variables.update( { - self.domain + " electrode surface area per unit volume": a, + self.domain + " electrode surface area to volume ratio": a, self.domain - + " electrode surface area per unit volume [m-1]": a * a_typ, + + " electrode surface area to volume ratio [m-1]": a * a_typ, } ) return variables @@ -89,9 +89,9 @@ def _get_standard_active_material_variables(self, eps_solid): { self.domain + " particle radius": R, self.domain + " particle radius [m]": R * R_typ, - self.domain + " electrode surface area per unit volume": a, + self.domain + " electrode surface area to volume ratio": a, self.domain - + " electrode surface area per unit volume [m-1]": a_dim, + + " electrode surface area to volume ratio [m-1]": a_dim, } ) diff --git a/pybamm/models/submodels/electrode/ohm/full_ohm.py b/pybamm/models/submodels/electrode/ohm/full_ohm.py index c649610cd4..a11fe5eefd 100644 --- a/pybamm/models/submodels/electrode/ohm/full_ohm.py +++ b/pybamm/models/submodels/electrode/ohm/full_ohm.py @@ -60,9 +60,9 @@ def set_algebraic(self, variables): phi_s = variables[self.domain + " electrode potential"] i_s = variables[self.domain + " electrode current density"] - # Get surface area per unit volume (could be a distribution in x to + # Get surface area to volume ratio (could be a distribution in x to # account for graded electrodes) - a = variables[self.domain + " electrode surface area per unit volume"] + a = variables[self.domain + " electrode surface area to volume ratio"] # Variable summing all of the interfacial current densities sum_j = variables[ diff --git a/pybamm/models/submodels/electrolyte_conductivity/full_conductivity.py b/pybamm/models/submodels/electrolyte_conductivity/full_conductivity.py index af6fca9b7a..0a6d80071b 100644 --- a/pybamm/models/submodels/electrolyte_conductivity/full_conductivity.py +++ b/pybamm/models/submodels/electrolyte_conductivity/full_conductivity.py @@ -52,10 +52,10 @@ def set_algebraic(self, variables): phi_e = variables["Electrolyte potential"] i_e = variables["Electrolyte current density"] - # Get surface area per unit volume (could be a distribution in x to + # Get surface area to volume ratio (could be a distribution in x to # account for graded electrodes) - a_n = variables["Negative electrode surface area per unit volume"] - a_p = variables["Positive electrode surface area per unit volume"] + a_n = variables["Negative electrode surface area to volume ratio"] + a_p = variables["Positive electrode surface area to volume ratio"] a = pybamm.Concatenation( a_n, pybamm.FullBroadcast(0, "separator", "current collector"), a_p ) diff --git a/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/full_surface_form_conductivity.py b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/full_surface_form_conductivity.py index b3fd388acd..33255648b0 100644 --- a/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/full_surface_form_conductivity.py +++ b/pybamm/models/submodels/electrolyte_conductivity/surface_potential_form/full_surface_form_conductivity.py @@ -217,9 +217,9 @@ def set_algebraic(self, variables): delta_phi = variables[self.domain + " electrode surface potential difference"] i_e = variables[self.domain + " electrolyte current density"] - # Get surface area per unit volume (could be a distribution in x to + # Get surface area to volume ratio (could be a distribution in x to # account for graded electrodes) - a = variables[self.domain + " electrode surface area per unit volume"] + a = variables[self.domain + " electrode surface area to volume ratio"] # Variable summing all of the interfacial current densities sum_j = variables[ @@ -259,9 +259,9 @@ def set_rhs(self, variables): delta_phi = variables[self.domain + " electrode surface potential difference"] i_e = variables[self.domain + " electrolyte current density"] - # Get surface area per unit volume (could be a distribution in x to + # Get surface area to volume ratio (could be a distribution in x to # account for graded electrodes) - a = variables[self.domain + " electrode surface area per unit volume"] + a = variables[self.domain + " electrode surface area to volume ratio"] # Variable summing all of the interfacial current densities sum_j = variables[ diff --git a/pybamm/models/submodels/interface/base_interface.py b/pybamm/models/submodels/interface/base_interface.py index d31d51a687..01d7dd5459 100644 --- a/pybamm/models/submodels/interface/base_interface.py +++ b/pybamm/models/submodels/interface/base_interface.py @@ -339,8 +339,8 @@ def _get_standard_whole_cell_interfacial_current_variables(self, variables): } ) - a_n = variables["Negative electrode surface area per unit volume"] - a_p = variables["Positive electrode surface area per unit volume"] + a_n = variables["Negative electrode surface area to volume ratio"] + a_p = variables["Positive electrode surface area to volume ratio"] a = pybamm.Concatenation( a_n, pybamm.FullBroadcast(0, "separator", "current collector"), a_p ) diff --git a/pybamm/models/submodels/particle/polynomial_single_particle.py b/pybamm/models/submodels/particle/polynomial_single_particle.py index 61f97790b0..6da67466ac 100644 --- a/pybamm/models/submodels/particle/polynomial_single_particle.py +++ b/pybamm/models/submodels/particle/polynomial_single_particle.py @@ -267,8 +267,10 @@ def get_coupled_variables(self, variables): N_s = pybamm.SecondaryBroadcast(N_s_xav, [self._domain.lower() + " electrode"]) - variables = self._get_standard_concentration_variables( - c_s, c_s_av=c_s_rxav, c_s_surf=c_s_surf + variables.update( + self._get_standard_concentration_variables( + c_s, c_s_av=c_s_rxav, c_s_surf=c_s_surf + ) ) variables.update(self._get_standard_flux_variables(N_s, N_s_xav)) variables.update(self._get_total_concentration_variables(variables)) diff --git a/pybamm/models/submodels/particle_cracking/base_cracking.py b/pybamm/models/submodels/particle_cracking/base_cracking.py index 1388a64358..0eb706011e 100644 --- a/pybamm/models/submodels/particle_cracking/base_cracking.py +++ b/pybamm/models/submodels/particle_cracking/base_cracking.py @@ -76,8 +76,8 @@ def _get_mechanical_results(self, variables): L0 = self.param.L_n c_init = self.param.c_n_init(1) v_change = pybamm.x_average( - self.param.t_n_change(c_s_rav) - ) - self.param.t_n_change(c_init) + eps_s * self.param.t_n_change(c_s_rav) + ) - pybamm.x_average(eps_s * self.param.t_n_change(c_init)) elif self.domain == "Positive": x = pybamm.standard_spatial_vars.x_p @@ -90,12 +90,10 @@ def _get_mechanical_results(self, variables): L0 = self.param.L_p c_init = self.param.c_p_init(0) v_change = pybamm.x_average( - self.param.t_p_change(c_s_rav) - ) - self.param.t_p_change(c_init) + eps_s * self.param.t_p_change(c_s_rav) + ) - pybamm.x_average(eps_s * self.param.t_p_change(c_init)) - cell_thickness_change += ( - self.param.n_electrodes_parallel * eps_s * v_change * L0 - ) + cell_thickness_change += self.param.n_electrodes_parallel * v_change * L0 disp_surf_dim = Omega * R0 / 3 * (c_s_rav - c_0) * c_scale # c0 reference concentration for no deformation stress_r_surf_dim = 0 * E0 diff --git a/pybamm/models/submodels/thermal/base_thermal.py b/pybamm/models/submodels/thermal/base_thermal.py index 832e9d5634..ca079ec56f 100644 --- a/pybamm/models/submodels/thermal/base_thermal.py +++ b/pybamm/models/submodels/thermal/base_thermal.py @@ -91,8 +91,8 @@ def _get_standard_coupled_variables(self, variables): T = variables["Cell temperature"] T_n, _, T_p = T.orphans - a_n = variables["Negative electrode surface area per unit volume"] - a_p = variables["Positive electrode surface area per unit volume"] + a_n = variables["Negative electrode surface area to volume ratio"] + a_p = variables["Positive electrode surface area to volume ratio"] j_n = variables["Negative electrode interfacial current density"] j_p = variables["Positive electrode interfacial current density"] diff --git a/pybamm/parameters/lead_acid_parameters.py b/pybamm/parameters/lead_acid_parameters.py index d1cc5ff667..5e097a95d5 100644 --- a/pybamm/parameters/lead_acid_parameters.py +++ b/pybamm/parameters/lead_acid_parameters.py @@ -86,7 +86,7 @@ def _set_dimensional_parameters(self): ) # pybamm.Parameter("Typical oxygen concentration [mol.m-3]") # Microstructure - # Note: the surface area per unit volume can be set as a function of + # Note: the surface area to volume ratio can be set as a function of # through-cell position, so is defined later as a function self.b_e_n = self.geo.b_e_n self.b_e_s = self.geo.b_e_s @@ -318,7 +318,7 @@ def j0_p_Ox_dimensional(self, c_e, T): def a_n_dimensional(self, x): """ - Negative electrode surface area per unit volume as a function of + Negative electrode surface area to volume ratio as a function of through-cell distance """ inputs = {"Through-cell distance (x_n) [m]": x} @@ -328,7 +328,7 @@ def a_n_dimensional(self, x): def a_p_dimensional(self, x): """ - Positive electrode surface area per unit volume as a function of + Positive electrode surface area to volume ratio as a function of through-cell distance """ inputs = {"Through-cell distance (x_p) [m]": x} @@ -757,7 +757,7 @@ def c_p_init(self, x): def a_n(self, x): """ - Dimensionless negative electrode surface area per unit volume as a + Dimensionless negative electrode surface area to volume ratio as a function of dimensionless position x """ x_dim = x * self.L_x @@ -765,7 +765,7 @@ def a_n(self, x): def a_p(self, x): """ - Dimensionless positive electrode surface area per unit volume as a + Dimensionless positive electrode surface area to volume ratio as a function of dimensionless position x """ x_dim = x * self.L_x diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 527b48d1ef..a62f016c20 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -26,7 +26,7 @@ class LithiumIonParameters: * "particle shape" : str, optional Sets the model shape of the electrode particles. This is used to - calculate the surface area per unit volume. Can be "spherical" + calculate the surface area to volume ratio. Can be "spherical" (default) or "user". For the "user" option the surface area per unit volume can be passed as a parameter, and is therefore not necessarily consistent with the particle shape. @@ -112,7 +112,7 @@ def _set_dimensional_parameters(self): # Microscale geometry # Note: the particle radius in the electrodes can be set as a function # of through-cell position, so is defined later as a function, along with - # the surface area per unit volume + # the surface area to volume ratio inputs = { "Through-cell distance (x_n) [m]": pybamm.standard_spatial_vars.x_n * self.L_x @@ -419,7 +419,7 @@ def _set_scales(self): "Negative electrode surface area to volume ratio [m-1]", inputs ) inputs = {"Through-cell distance (x_p) [m]": self.L_x} - self.a_n_typ = pybamm.FunctionParameter( + self.a_p_typ = pybamm.FunctionParameter( "Positive electrode surface area to volume ratio [m-1]", inputs ) diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py index b4c8bf1737..96fad1035b 100644 --- a/pybamm/parameters/parameter_values.py +++ b/pybamm/parameters/parameter_values.py @@ -321,10 +321,10 @@ def check_parameter_values(self, values): "instead of providing a reference value and a distribution." ) for param in values: - if "surface area per unit volume distribution in x" in param: + if "surface area to volume ratio distribution in x" in param: raise ValueError( "The parameter '{}' has been deprecated".format(param) - + "The surface area per unit volume is now set as a function " + + "The surface area to volume ratio is now set as a function " "of x directly instead of providing a reference value and a " "distribution." ) diff --git a/tests/integration/test_models/standard_output_tests.py b/tests/integration/test_models/standard_output_tests.py index 370c6cf4a0..b2d75dcccb 100644 --- a/tests/integration/test_models/standard_output_tests.py +++ b/tests/integration/test_models/standard_output_tests.py @@ -595,8 +595,8 @@ def __init__(self, model, param, disc, solution, operating_condition): self.i_s = solution["Electrode current density"] self.i_e = solution["Electrolyte current density"] - self.a_n = solution["Negative electrode surface area per unit volume"] - self.a_p = solution["Positive electrode surface area per unit volume"] + self.a_n = solution["Negative electrode surface area to volume ratio"] + self.a_p = solution["Positive electrode surface area to volume ratio"] def test_interfacial_current_average(self): """Test that average of the surface area density distribution (in x) diff --git a/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_full_conductivity.py b/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_full_conductivity.py index 5675654696..6e27db95a4 100644 --- a/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_full_conductivity.py +++ b/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_full_conductivity.py @@ -11,7 +11,7 @@ class TestFull(unittest.TestCase): def test_public_functions(self): param = pybamm.LithiumIonParameters() a = pybamm.Scalar(0) - surf = "electrode surface area per unit volume" + surf = "electrode surface area to volume ratio" variables = { "Electrolyte tortuosity": a, "Electrolyte concentration": pybamm.FullBroadcast( diff --git a/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_surface_form/test_full_surface_form_conductivity.py b/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_surface_form/test_full_surface_form_conductivity.py index 3dbe5e2bcf..66092ef862 100644 --- a/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_surface_form/test_full_surface_form_conductivity.py +++ b/tests/unit/test_models/test_submodels/test_electrolyte_conductivity/test_surface_form/test_full_surface_form_conductivity.py @@ -25,7 +25,7 @@ def test_public_functions(self): "Negative electrode porosity": a_n, "Negative electrolyte tortuosity": a_n, "Negative electrode tortuosity": a_n, - "Negative electrode surface area per unit volume": a_n, + "Negative electrode surface area to volume ratio": a_n, "Negative electrolyte concentration": a_n, "Sum of negative electrode interfacial current densities": a_n, "Electrolyte potential": pybamm.Concatenation(a_n, a_s, a_p), @@ -55,7 +55,7 @@ def test_public_functions(self): "Positive electrode porosity": a_p, "Positive electrolyte tortuosity": a_p, "Positive electrode tortuosity": a_p, - "Positive electrode surface area per unit volume": a_p, + "Positive electrode surface area to volume ratio": a_p, "Positive electrolyte concentration": a_p, "Sum of positive electrode interfacial current densities": a_p, "Positive electrode temperature": a_p, diff --git a/tests/unit/test_models/test_submodels/test_thermal/coupled_variables.py b/tests/unit/test_models/test_submodels/test_thermal/coupled_variables.py index 7fdc1fa565..5f150c795d 100644 --- a/tests/unit/test_models/test_submodels/test_thermal/coupled_variables.py +++ b/tests/unit/test_models/test_submodels/test_thermal/coupled_variables.py @@ -10,8 +10,8 @@ b = pybamm.PrimaryBroadcast(pybamm.Scalar(1), "current collector") coupled_variables = { - "Negative electrode surface area per unit volume": a_n, - "Positive electrode surface area per unit volume": a_p, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode surface area to volume ratio": a_p, "Negative electrode interfacial current density": a_n, "Positive electrode interfacial current density": a_p, "Negative electrode reaction overpotential": a_n, diff --git a/tests/unit/test_parameters/test_parameter_values.py b/tests/unit/test_parameters/test_parameter_values.py index f00006473b..47768f62c5 100644 --- a/tests/unit/test_parameters/test_parameter_values.py +++ b/tests/unit/test_parameters/test_parameter_values.py @@ -105,9 +105,9 @@ def test_check_parameter_values(self): pybamm.ParameterValues({"Negative reaction rate": 1}) with self.assertRaisesRegex(ValueError, "particle distribution"): pybamm.ParameterValues({"Negative particle distribution in x": 1}) - with self.assertRaisesRegex(ValueError, "surface area per unit volume"): + with self.assertRaisesRegex(ValueError, "surface area to volume ratio"): pybamm.ParameterValues( - {"Negative electrode surface area per unit volume distribution in x": 1} + {"Negative electrode surface area to volume ratio distribution in x": 1} ) def test_process_symbol(self): From 19d5e2341af871662a6cc94027d6e789c5219fb2 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 14:20:42 -0500 Subject: [PATCH 04/12] #1245 fix submodel tests --- .../submodels/active_material/base_active_material.py | 7 +++---- pybamm/parameters/lithium_ion_parameters.py | 2 +- .../test_submodels/test_interface/test_butler_volmer.py | 2 ++ .../test_interface/test_kinetics/test_butler_volmer.py | 3 +++ .../test_interface/test_kinetics/test_tafel.py | 3 +++ .../test_submodels/test_interface/test_lead_acid.py | 3 +++ .../test_submodels/test_interface/test_lithium_ion.py | 3 +++ .../test_mechanical/test_crack_propagation.py | 4 ++++ .../test_particle/test_fickian_many_particles.py | 6 ++++++ .../test_particle/test_fickian_single_particle.py | 4 ++++ .../test_particle/test_polynomial_many_particles.py | 6 ++++++ .../test_particle/test_polynomial_single_particle.py | 4 ++++ tests/unit/test_parameters/test_lithium_ion_parameters.py | 8 ++++---- 13 files changed, 46 insertions(+), 9 deletions(-) diff --git a/pybamm/models/submodels/active_material/base_active_material.py b/pybamm/models/submodels/active_material/base_active_material.py index a930d18337..4d82d8d793 100644 --- a/pybamm/models/submodels/active_material/base_active_material.py +++ b/pybamm/models/submodels/active_material/base_active_material.py @@ -56,17 +56,16 @@ def _get_standard_active_material_variables(self, eps_solid): if self.domain == "Negative": x = pybamm.standard_spatial_vars.x_n R = self.param.R_n(x) - R_typ = self.param.R_n_typ + R_dim = self.param.R_n_dimensional(x * self.param.L_x) a_typ = self.param.a_n_typ elif self.domain == "Positive": x = pybamm.standard_spatial_vars.x_p R = self.param.R_p(x) - R_typ = self.param.R_p_typ + R_dim = self.param.R_p_dimensional(x * self.param.L_x) a_typ = self.param.a_p_typ # Compute dimensional particle shape if self.options["particle shape"] == "spherical": - R_dim = R * R_typ a_dim = 3 * eps_solid / R_dim elif self.options["particle shape"] == "user": if self.domain == "Negative": @@ -88,7 +87,7 @@ def _get_standard_active_material_variables(self, eps_solid): variables.update( { self.domain + " particle radius": R, - self.domain + " particle radius [m]": R * R_typ, + self.domain + " particle radius [m]": R_dim, self.domain + " electrode surface area to volume ratio": a, self.domain + " electrode surface area to volume ratio [m-1]": a_dim, diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index a62f016c20..b588dd4125 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -412,7 +412,7 @@ def _set_scales(self): self.R_p_typ = self.R_p_dimensional(self.L_x) if self.options["particle shape"] == "spherical": self.a_n_typ = 3 * self.epsilon_s_n(0) / self.R_n_typ - self.a_p_typ = 3 * self.epsilon_s_p(1) / self.R_n_typ + self.a_p_typ = 3 * self.epsilon_s_p(1) / self.R_p_typ elif self.options["particle shape"] == "user": inputs = {"Through-cell distance (x_n) [m]": 0} self.a_n_typ = pybamm.FunctionParameter( diff --git a/tests/integration/test_models/test_submodels/test_interface/test_butler_volmer.py b/tests/integration/test_models/test_submodels/test_interface/test_butler_volmer.py index 5ce91fe70b..105a2360b2 100644 --- a/tests/integration/test_models/test_submodels/test_interface/test_butler_volmer.py +++ b/tests/integration/test_models/test_submodels/test_interface/test_butler_volmer.py @@ -50,6 +50,8 @@ def setUp(self): "Current collector current density": pybamm.Scalar(1), "Negative electrode temperature": 0, "Positive electrode temperature": 0, + "Negative electrode surface area to volume ratio": 1 + 0 * self.c_e_n, + "Positive electrode surface area to volume ratio": 1 + 0 * self.c_e_p, "Sum of electrolyte reaction source terms": pybamm.Scalar(1), "Sum of interfacial current densities": pybamm.Scalar(1), "Sum of negative electrode interfacial current densities": pybamm.Scalar(1), diff --git a/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_butler_volmer.py b/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_butler_volmer.py index d053e9feaf..698c22da2e 100644 --- a/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_butler_volmer.py +++ b/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_butler_volmer.py @@ -26,6 +26,7 @@ def test_public_functions(self): "Negative electrolyte concentration": a_n, "Negative particle surface concentration": a_n, "Negative electrode temperature": a_n, + "Negative electrode surface area to volume ratio": a_n, } submodel = pybamm.interface.ButlerVolmer(param, "Negative", "lithium-ion main") std_tests = tests.StandardSubModelTests(submodel, variables) @@ -42,6 +43,8 @@ def test_public_functions(self): "Negative electrode interfacial current density": a_n, "Negative electrode exchange current density": a_n, "Positive electrode temperature": a_p, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode surface area to volume ratio": a_p, "X-averaged negative electrode interfacial current density": a, "X-averaged positive electrode interfacial current density": a, "Sum of electrolyte reaction source terms": 0, diff --git a/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_tafel.py b/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_tafel.py index 565d98d709..0f13fa8940 100644 --- a/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_tafel.py +++ b/tests/unit/test_models/test_submodels/test_interface/test_kinetics/test_tafel.py @@ -26,6 +26,7 @@ def test_public_function(self): "Negative electrolyte concentration": a_n, "Negative particle surface concentration": a_n, "Negative electrode temperature": a_n, + "Negative electrode surface area to volume ratio": a_n, } submodel = pybamm.interface.ForwardTafel(param, "Negative", "lithium-ion main") std_tests = tests.StandardSubModelTests(submodel, variables) @@ -43,6 +44,8 @@ def test_public_function(self): "Negative electrode interfacial current density": a_n, "Negative electrode exchange current density": a_n, "Positive electrode temperature": a_p, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode surface area to volume ratio": a_p, "X-averaged negative electrode interfacial current density": a, "X-averaged positive electrode interfacial current density": a, "Sum of electrolyte reaction source terms": 0, diff --git a/tests/unit/test_models/test_submodels/test_interface/test_lead_acid.py b/tests/unit/test_models/test_submodels/test_interface/test_lead_acid.py index ba57b49ad3..bb95bcb2eb 100644 --- a/tests/unit/test_models/test_submodels/test_interface/test_lead_acid.py +++ b/tests/unit/test_models/test_submodels/test_interface/test_lead_acid.py @@ -26,6 +26,7 @@ def test_public_functions(self): "Negative electrolyte concentration": a_n, "Negative particle surface concentration": a_n, "Negative electrode temperature": a_n, + "Negative electrode surface area to volume ratio": a_n, } submodel = pybamm.interface.ButlerVolmer(param, "Negative", "lead-acid main") std_tests = tests.StandardSubModelTests(submodel, variables) @@ -42,6 +43,8 @@ def test_public_functions(self): "Negative electrode interfacial current density": a_n, "Negative electrode exchange current density": a_n, "Positive electrode temperature": a_p, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode surface area to volume ratio": a_p, "X-averaged negative electrode interfacial current density": a, "X-averaged positive electrode interfacial current density": a, "Sum of electrolyte reaction source terms": 0, diff --git a/tests/unit/test_models/test_submodels/test_interface/test_lithium_ion.py b/tests/unit/test_models/test_submodels/test_interface/test_lithium_ion.py index 7fb5ce7183..b76ed428d9 100644 --- a/tests/unit/test_models/test_submodels/test_interface/test_lithium_ion.py +++ b/tests/unit/test_models/test_submodels/test_interface/test_lithium_ion.py @@ -26,6 +26,7 @@ def test_public_functions(self): "Negative electrolyte concentration": a_n, "Negative particle surface concentration": a_n, "Negative electrode temperature": a_n, + "Negative electrode surface area to volume ratio": a_n, } submodel = pybamm.interface.ButlerVolmer(param, "Negative", "lithium-ion main") std_tests = tests.StandardSubModelTests(submodel, variables) @@ -42,6 +43,8 @@ def test_public_functions(self): "Negative electrode interfacial current density": a_n, "Negative electrode exchange current density": a_n, "Positive electrode temperature": a_p, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode surface area to volume ratio": a_p, "X-averaged negative electrode interfacial current density": a, "X-averaged positive electrode interfacial current density": a, "Sum of electrolyte reaction source terms": 0, diff --git a/tests/unit/test_models/test_submodels/test_mechanical/test_crack_propagation.py b/tests/unit/test_models/test_submodels/test_mechanical/test_crack_propagation.py index cd838cd9c1..8d9e22dc9c 100644 --- a/tests/unit/test_models/test_submodels/test_mechanical/test_crack_propagation.py +++ b/tests/unit/test_models/test_submodels/test_mechanical/test_crack_propagation.py @@ -28,6 +28,10 @@ def test_public_functions(self): "R-averaged positive particle concentration": a_p, "Average positive particle concentration": a, "Positive electrode temperature": a_p, + "Negative electrode active material volume fraction": a_n, + "Negative electrode surface area to volume ratio": a_n, + "Positive electrode active material volume fraction": a_p, + "Positive electrode surface area to volume ratio": a_p, } options = {"particle": "Fickian diffusion", "particle cracking": "both"} param = pybamm.LithiumIonParameters(options) diff --git a/tests/unit/test_models/test_submodels/test_particle/test_fickian_many_particles.py b/tests/unit/test_models/test_submodels/test_particle/test_fickian_many_particles.py index 3ba0c71d9e..2554c57211 100644 --- a/tests/unit/test_models/test_submodels/test_particle/test_fickian_many_particles.py +++ b/tests/unit/test_models/test_submodels/test_particle/test_fickian_many_particles.py @@ -21,6 +21,9 @@ def test_public_functions(self): variables = { "Negative electrode interfacial current density": a_n, "Negative electrode temperature": a_n, + "Negative electrode active material volume fraction": a_n, + "Negative electrode surface area to volume ratio": a_n, + "Negative particle radius": a_n, } submodel = pybamm.particle.FickianManyParticles(param, "Negative") @@ -30,6 +33,9 @@ def test_public_functions(self): variables = { "Positive electrode interfacial current density": a_p, "Positive electrode temperature": a_p, + "Positive electrode active material volume fraction": a_p, + "Positive electrode surface area to volume ratio": a_p, + "Positive particle radius": a_p, } submodel = pybamm.particle.FickianManyParticles(param, "Positive") std_tests = tests.StandardSubModelTests(submodel, variables) diff --git a/tests/unit/test_models/test_submodels/test_particle/test_fickian_single_particle.py b/tests/unit/test_models/test_submodels/test_particle/test_fickian_single_particle.py index 8d5292daa6..6b11753550 100644 --- a/tests/unit/test_models/test_submodels/test_particle/test_fickian_single_particle.py +++ b/tests/unit/test_models/test_submodels/test_particle/test_fickian_single_particle.py @@ -15,6 +15,8 @@ def test_public_functions(self): variables = { "X-averaged negative electrode interfacial current density": a, "X-averaged negative electrode temperature": a, + "Negative electrode active material volume fraction": a, + "Negative electrode surface area to volume ratio": a, } submodel = pybamm.particle.FickianSingleParticle(param, "Negative") @@ -24,6 +26,8 @@ def test_public_functions(self): variables = { "X-averaged positive electrode interfacial current density": a, "X-averaged positive electrode temperature": a, + "Positive electrode active material volume fraction": a, + "Positive electrode surface area to volume ratio": a, } submodel = pybamm.particle.FickianSingleParticle(param, "Positive") std_tests = tests.StandardSubModelTests(submodel, variables) diff --git a/tests/unit/test_models/test_submodels/test_particle/test_polynomial_many_particles.py b/tests/unit/test_models/test_submodels/test_particle/test_polynomial_many_particles.py index e4c939589d..718fa91c50 100644 --- a/tests/unit/test_models/test_submodels/test_particle/test_polynomial_many_particles.py +++ b/tests/unit/test_models/test_submodels/test_particle/test_polynomial_many_particles.py @@ -21,6 +21,9 @@ def test_public_functions(self): variables = { "Negative electrode interfacial current density": a_n, "Negative electrode temperature": a_n, + "Negative electrode active material volume fraction": a_n, + "Negative electrode surface area to volume ratio": a_n, + "Negative particle radius": a_n, } submodel = pybamm.particle.PolynomialManyParticles( @@ -44,6 +47,9 @@ def test_public_functions(self): variables = { "Positive electrode interfacial current density": a_p, "Positive electrode temperature": a_p, + "Positive electrode active material volume fraction": a_p, + "Positive electrode surface area to volume ratio": a_p, + "Positive particle radius": a_p, } submodel = pybamm.particle.PolynomialManyParticles( diff --git a/tests/unit/test_models/test_submodels/test_particle/test_polynomial_single_particle.py b/tests/unit/test_models/test_submodels/test_particle/test_polynomial_single_particle.py index fee9b29a15..d949027aa0 100644 --- a/tests/unit/test_models/test_submodels/test_particle/test_polynomial_single_particle.py +++ b/tests/unit/test_models/test_submodels/test_particle/test_polynomial_single_particle.py @@ -17,6 +17,8 @@ def test_public_functions(self): "Current collector current density": a, "X-averaged negative electrode interfacial current density": a, "X-averaged negative electrode temperature": a, + "Negative electrode active material volume fraction": a, + "Negative electrode surface area to volume ratio": a, } submodel = pybamm.particle.PolynomialSingleParticle( @@ -41,6 +43,8 @@ def test_public_functions(self): "Current collector current density": a, "X-averaged positive electrode interfacial current density": a, "X-averaged positive electrode temperature": a, + "Positive electrode active material volume fraction": a, + "Positive electrode surface area to volume ratio": a, } submodel = pybamm.particle.PolynomialSingleParticle( diff --git a/tests/unit/test_parameters/test_lithium_ion_parameters.py b/tests/unit/test_parameters/test_lithium_ion_parameters.py index 9288d9bfef..4eba7a046d 100644 --- a/tests/unit/test_parameters/test_lithium_ion_parameters.py +++ b/tests/unit/test_parameters/test_lithium_ion_parameters.py @@ -28,9 +28,9 @@ def test_lithium_ion(self): # Note: in general these can be functions, but are constant for this # set, so we just arbitrarily evaluate at 0 - # a_n dimensional + # a_n_typ np.testing.assert_almost_equal( - values.evaluate(param.a_n_dimensional(0)), 0.18 * 10 ** (6), 2 + values.evaluate(param.a_n_typ), 0.18 * 10 ** (6), 2 ) # R_n dimensional np.testing.assert_almost_equal( @@ -40,9 +40,9 @@ def test_lithium_ion(self): # a_R_n = a_n_typ * R_n_typ np.testing.assert_almost_equal(values.evaluate(param.a_R_n), 1.8, 2) - # a_p dimensional + # a_p_typ np.testing.assert_almost_equal( - values.evaluate(param.a_p_dimensional(0)), 0.15 * 10 ** (6), 2 + values.evaluate(param.a_p_typ), 0.15 * 10 ** (6), 2 ) # R_p dimensional From 0ff31e9411b4f1631da521e7681d95a9fe61729c Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 18:29:54 -0500 Subject: [PATCH 05/12] #1245 fix examples --- examples/notebooks/using-submodels.ipynb | 112 ++++++------------ examples/scripts/custom_model.py | 10 +- .../full_battery_models/lead_acid/full.py | 4 +- .../lead_acid/higher_order.py | 4 +- .../full_battery_models/lead_acid/loqs.py | 12 +- .../full_battery_models/lithium_ion/dfn.py | 4 +- .../full_battery_models/lithium_ion/spm.py | 12 +- .../full_battery_models/lithium_ion/spme.py | 4 +- 8 files changed, 62 insertions(+), 100 deletions(-) diff --git a/examples/notebooks/using-submodels.ipynb b/examples/notebooks/using-submodels.ipynb index c63e32f87e..552c80665e 100644 --- a/examples/notebooks/using-submodels.ipynb +++ b/examples/notebooks/using-submodels.ipynb @@ -24,8 +24,8 @@ "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", + "name": "stdout", "text": [ "Note: you may need to restart the kernel to use updated packages.\n" ] @@ -65,31 +65,10 @@ "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", + "name": "stdout", "text": [ - "external circuit \n", - "porosity \n", - "electrolyte tortuosity \n", - "electrode tortuosity \n", - "through-cell convection \n", - "transverse convection \n", - "negative interface \n", - "positive interface \n", - "negative interface current \n", - "positive interface current \n", - "negative oxygen interface \n", - "positive oxygen interface \n", - "negative particle \n", - "positive particle \n", - "negative electrode \n", - "leading-order electrolyte conductivity \n", - "electrolyte diffusion \n", - "positive electrode \n", - "thermal \n", - "current collector \n", - "negative sei \n", - "positive sei \n" + "external circuit \nporosity \nnegative active material \npositive active material \nelectrolyte tortuosity \nelectrode tortuosity \nthrough-cell convection \ntransverse convection \nnegative interface \npositive interface \nnegative interface current \npositive interface current \nnegative oxygen interface \npositive oxygen interface \nnegative particle \npositive particle \nnegative electrode potential \nleading-order electrolyte conductivity \nelectrolyte diffusion \npositive electrode potential \nthermal \ncurrent collector \nnegative sei \npositive sei \n" ] } ], @@ -150,31 +129,10 @@ "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", + "name": "stdout", "text": [ - "external circuit \n", - "porosity \n", - "electrolyte tortuosity \n", - "electrode tortuosity \n", - "through-cell convection \n", - "transverse convection \n", - "negative interface \n", - "positive interface \n", - "negative interface current \n", - "positive interface current \n", - "negative oxygen interface \n", - "positive oxygen interface \n", - "negative particle \n", - "positive particle \n", - "negative electrode \n", - "leading-order electrolyte conductivity \n", - "electrolyte diffusion \n", - "positive electrode \n", - "thermal \n", - "current collector \n", - "negative sei \n", - "positive sei \n" + "external circuit \nporosity \nnegative active material \npositive active material \nelectrolyte tortuosity \nelectrode tortuosity \nthrough-cell convection \ntransverse convection \nnegative interface \npositive interface \nnegative interface current \npositive interface current \nnegative oxygen interface \npositive oxygen interface \nnegative particle \npositive particle \nnegative electrode potential \nleading-order electrolyte conductivity \nelectrolyte diffusion \npositive electrode potential \nthermal \ncurrent collector \nnegative sei \npositive sei \n" ] } ], @@ -196,14 +154,14 @@ "metadata": {}, "outputs": [ { + "output_type": "execute_result", "data": { "text/plain": [ "{}" ] }, - "execution_count": 7, "metadata": {}, - "output_type": "execute_result" + "execution_count": 7 } ], "source": [ @@ -239,16 +197,16 @@ "metadata": {}, "outputs": [ { + "output_type": "execute_result", "data": { "text/plain": [ - "{Variable(-0x3a598270a8eb6e0d, Discharge capacity [A.h], children=[], domain=[], auxiliary_domains={}): Division(-0x67bf165961891da0, /, children=['Current function [A] * 96485.33212 * Maximum concentration in negative electrode [mol.m-3] * Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m] / function (absolute)', '3600.0'], domain=[], auxiliary_domains={}),\n", - " Variable(-0x26eb1beb51f287ce, R-X-averaged negative particle concentration, children=[], domain=['current collector'], auxiliary_domains={}): Division(-0x13cd5de5ba47373f, /, children=[\"-3.0 * integral dx_n ['negative electrode'](broadcast(broadcast(Current function [A] / Typical current [A] * function (sign)) / Negative electrode thickness [m] / Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]) - broadcast(0.0) + broadcast(0.0)) / Negative electrode thickness [m] / Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]\", '3.0 * Negative electrode active material volume fraction / Negative particle radius [m] * Negative particle radius [m]'], domain=['current collector'], auxiliary_domains={}),\n", - " Variable(0x174cc116f4516de8, X-averaged positive particle concentration, children=[], domain=['positive particle'], auxiliary_domains={'secondary': \"['current collector']\"}): Multiplication(-0x617f4041866fdbc6, *, children=['-1.0 / Positive particle radius [m] ** 2.0 / Positive electrode diffusivity [m2.s-1] / 96485.33212 * Maximum concentration in negative electrode [mol.m-3] * Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m] / function (absolute)', 'div(-Positive electrode diffusivity [m2.s-1] / Positive electrode diffusivity [m2.s-1] * grad(X-averaged positive particle concentration))'], domain=['positive particle'], auxiliary_domains={'secondary': \"['current collector']\"})}" + "{Variable(0x542b6e7f2fc158ff, Discharge capacity [A.h], children=[], domain=[], auxiliary_domains={}): Division(0x7ed4925718627720, /, children=['Current function [A] * 96485.33212 * Maximum concentration in negative electrode [mol.m-3] * (Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]) / absolute(Typical current [A] / (Number of electrodes connected in parallel to make a cell * Electrode width [m] * Electrode height [m]))', '3600.0'], domain=[], auxiliary_domains={}),\n", + " Variable(0x165d2402d241c851, R-X-averaged negative particle concentration, children=[], domain=['current collector'], auxiliary_domains={}): Division(0x677241cfb40b75e7, /, children=[\"-3.0 * integral dx_n ['negative electrode'](broadcast(broadcast((Current function [A] / Typical current [A]) * sign(Typical current [A])) / (Negative electrode thickness [m] / (Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]))) - (broadcast(0.0) + broadcast(0.0))) / (Negative electrode thickness [m] / (Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]))\", '(3.0 * Negative electrode active material volume fraction / Negative particle radius [m]) * Negative particle radius [m]'], domain=['current collector'], auxiliary_domains={}),\n", + " Variable(-0x7eb62f1bf7f5033a, X-averaged positive particle concentration, children=[], domain=['positive particle'], auxiliary_domains={'secondary': \"['current collector']\"}): Multiplication(0x4f0a988357e5b89a, *, children=['-1.0 / ((Positive particle radius [m] ** 2.0) / (Positive electrode diffusivity [m2.s-1] * 1.0) / (96485.33212 * Maximum concentration in negative electrode [mol.m-3] * (Negative electrode thickness [m] + Separator thickness [m] + Positive electrode thickness [m]) / absolute(Typical current [A] / (Number of electrodes connected in parallel to make a cell * Electrode width [m] * Electrode height [m]))))', 'div(-Positive electrode diffusivity [m2.s-1] * 1.0 / (Positive electrode diffusivity [m2.s-1] * 1.0) * grad(X-averaged positive particle concentration))'], domain=['positive particle'], auxiliary_domains={'secondary': \"['current collector']\"})}" ] }, - "execution_count": 9, "metadata": {}, - "output_type": "execute_result" + "execution_count": 9 } ], "source": [ @@ -268,18 +226,16 @@ "metadata": {}, "outputs": [ { + "output_type": "display_data", "data": { + "text/plain": "interactive(children=(FloatSlider(value=0.0, description='t', max=1.0, step=0.01), Output()), _dom_classes=('w…", "application/vnd.jupyter.widget-view+json": { - "model_id": "df45b8c8b48b415d83703b37df5d1099", "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=1.0, step=0.01), Output()), _dom_classes=('w…" - ] + "version_minor": 0, + "model_id": "1fd88972119643f79521c0711054584d" + } }, - "metadata": {}, - "output_type": "display_data" + "metadata": {} } ], "source": [ @@ -329,7 +285,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We want to build a 1D model, so select the `Uniform` current collector model (if the current collectors are behaving uniformly, then a 1D model is appropriate). We also want the model to be isothermal, so select the thermal model accordingly. Further, we assume that the porosity is constant in time." + "We want to build a 1D model, so select the `Uniform` current collector model (if the current collectors are behaving uniformly, then a 1D model is appropriate). We also want the model to be isothermal, so select the thermal model accordingly. Further, we assume that the porosity and active material are constant in space and time." ] }, { @@ -340,7 +296,13 @@ "source": [ "model.submodels[\"current collector\"] = pybamm.current_collector.Uniform(model.param)\n", "model.submodels[\"thermal\"] = pybamm.thermal.isothermal.Isothermal(model.param)\n", - "model.submodels[\"porosity\"] = pybamm.porosity.Constant(model.param)" + "model.submodels[\"porosity\"] = pybamm.porosity.Constant(model.param)\n", + "model.submodels[\"negative active material\"] = pybamm.active_material.Constant(\n", + " model.param, \"Negative\", model.options\n", + ")\n", + "model.submodels[\"positive active material\"] = pybamm.active_material.Constant(\n", + " model.param, \"Positive\", model.options\n", + ")" ] }, { @@ -356,10 +318,10 @@ "metadata": {}, "outputs": [], "source": [ - "model.submodels[\"negative electrode\"] = pybamm.electrode.ohm.LeadingOrder(\n", + "model.submodels[\"negative electrode potentials\"] = pybamm.electrode.ohm.LeadingOrder(\n", " model.param, \"Negative\"\n", ")\n", - "model.submodels[\"positive electrode\"] = pybamm.electrode.ohm.LeadingOrder(\n", + "model.submodels[\"positive electrode potentials\"] = pybamm.electrode.ohm.LeadingOrder(\n", " model.param, \"Positive\"\n", ")" ] @@ -483,18 +445,16 @@ "metadata": {}, "outputs": [ { + "output_type": "display_data", "data": { + "text/plain": "interactive(children=(FloatSlider(value=0.0, description='t', max=1.0, step=0.01), Output()), _dom_classes=('w…", "application/vnd.jupyter.widget-view+json": { - "model_id": "b72a4d3d547e416cac2871daf105072a", "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=1.0, step=0.01), Output()), _dom_classes=('w…" - ] + "version_minor": 0, + "model_id": "7a4b113af0ed4f62a55bdca44d06f03a" + } }, - "metadata": {}, - "output_type": "display_data" + "metadata": {} } ], "source": [ @@ -537,9 +497,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.8.6-final" } }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/examples/scripts/custom_model.py b/examples/scripts/custom_model.py index 70348ffb70..853230b49f 100644 --- a/examples/scripts/custom_model.py +++ b/examples/scripts/custom_model.py @@ -17,10 +17,16 @@ model.submodels["current collector"] = pybamm.current_collector.Uniform(model.param) model.submodels["thermal"] = pybamm.thermal.isothermal.Isothermal(model.param) model.submodels["porosity"] = pybamm.porosity.Constant(model.param) -model.submodels["negative electrode"] = pybamm.electrode.ohm.LeadingOrder( +model.submodels["negative active material"] = pybamm.active_material.Constant( + model.param, "Negative", model.options +) +model.submodels["positive active material"] = pybamm.active_material.Constant( + model.param, "Positive", model.options +) +model.submodels["negative electrode potential"] = pybamm.electrode.ohm.LeadingOrder( model.param, "Negative" ) -model.submodels["positive electrode"] = pybamm.electrode.ohm.LeadingOrder( +model.submodels["positive electrode potential"] = pybamm.electrode.ohm.LeadingOrder( model.param, "Positive" ) model.submodels["negative particle"] = pybamm.particle.PolynomialSingleParticle( diff --git a/pybamm/models/full_battery_models/lead_acid/full.py b/pybamm/models/full_battery_models/lead_acid/full.py index 4ac4a8b095..055e584f9a 100644 --- a/pybamm/models/full_battery_models/lead_acid/full.py +++ b/pybamm/models/full_battery_models/lead_acid/full.py @@ -92,8 +92,8 @@ def set_solid_submodel(self): submod_n = pybamm.electrode.ohm.SurfaceForm(self.param, "Negative") submod_p = pybamm.electrode.ohm.SurfaceForm(self.param, "Positive") - self.submodels["negative electrode"] = submod_n - self.submodels["positive electrode"] = submod_p + self.submodels["negative electrode potential"] = submod_n + self.submodels["positive electrode potential"] = submod_p def set_electrolyte_submodel(self): diff --git a/pybamm/models/full_battery_models/lead_acid/higher_order.py b/pybamm/models/full_battery_models/lead_acid/higher_order.py index 673a348086..74bafd3a3a 100644 --- a/pybamm/models/full_battery_models/lead_acid/higher_order.py +++ b/pybamm/models/full_battery_models/lead_acid/higher_order.py @@ -135,12 +135,12 @@ def set_electrolyte_conductivity_submodel(self): ) def set_negative_electrode_submodel(self): - self.submodels["negative electrode"] = pybamm.electrode.ohm.Composite( + self.submodels["negative electrode potential"] = pybamm.electrode.ohm.Composite( self.param, "Negative" ) def set_positive_electrode_submodel(self): - self.submodels["positive electrode"] = pybamm.electrode.ohm.Composite( + self.submodels["positive electrode potential"] = pybamm.electrode.ohm.Composite( self.param, "Positive" ) diff --git a/pybamm/models/full_battery_models/lead_acid/loqs.py b/pybamm/models/full_battery_models/lead_acid/loqs.py index 1930b0aa07..8127818d0e 100644 --- a/pybamm/models/full_battery_models/lead_acid/loqs.py +++ b/pybamm/models/full_battery_models/lead_acid/loqs.py @@ -39,9 +39,8 @@ def __init__(self, options=None, name="LOQS model", build=True): self.set_porosity_submodel() self.set_active_material_submodel() self.set_tortuosity_submodels() - self.set_negative_electrode_submodel() self.set_electrolyte_submodel() - self.set_positive_electrode_submodel() + self.set_electrode_submodels() self.set_thermal_submodel() self.set_side_reaction_submodels() self.set_current_collector_submodel() @@ -171,16 +170,13 @@ def set_interfacial_submodel(self): ], } - def set_negative_electrode_submodel(self): + def set_electrode_submodels(self): self.submodels[ - "leading-order negative electrode" + "leading-order negative electrode potential" ] = pybamm.electrode.ohm.LeadingOrder(self.param, "Negative") - - def set_positive_electrode_submodel(self): - self.submodels[ - "leading-order positive electrode" + "leading-order positive electrode potential" ] = pybamm.electrode.ohm.LeadingOrder(self.param, "Positive") def set_electrolyte_submodel(self): diff --git a/pybamm/models/full_battery_models/lithium_ion/dfn.py b/pybamm/models/full_battery_models/lithium_ion/dfn.py index 353dcb7cd3..5ecb6b211e 100644 --- a/pybamm/models/full_battery_models/lithium_ion/dfn.py +++ b/pybamm/models/full_battery_models/lithium_ion/dfn.py @@ -129,8 +129,8 @@ def set_solid_submodel(self): submod_n = pybamm.electrode.ohm.SurfaceForm(self.param, "Negative") submod_p = pybamm.electrode.ohm.SurfaceForm(self.param, "Positive") - self.submodels["negative electrode"] = submod_n - self.submodels["positive electrode"] = submod_p + self.submodels["negative electrode potential"] = submod_n + self.submodels["positive electrode potential"] = submod_p def set_electrolyte_submodel(self): diff --git a/pybamm/models/full_battery_models/lithium_ion/spm.py b/pybamm/models/full_battery_models/lithium_ion/spm.py index b4d7d2b99b..b6362f71ed 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spm.py +++ b/pybamm/models/full_battery_models/lithium_ion/spm.py @@ -145,15 +145,15 @@ def set_particle_submodel(self): def set_negative_electrode_submodel(self): - self.submodels["negative electrode"] = pybamm.electrode.ohm.LeadingOrder( - self.param, "Negative" - ) + self.submodels[ + "negative electrode potential" + ] = pybamm.electrode.ohm.LeadingOrder(self.param, "Negative") def set_positive_electrode_submodel(self): - self.submodels["positive electrode"] = pybamm.electrode.ohm.LeadingOrder( - self.param, "Positive" - ) + self.submodels[ + "positive electrode potential" + ] = pybamm.electrode.ohm.LeadingOrder(self.param, "Positive") def set_electrolyte_submodel(self): diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index d7bc935c46..c54af5605e 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -147,13 +147,13 @@ def set_particle_submodel(self): def set_negative_electrode_submodel(self): - self.submodels["negative electrode"] = pybamm.electrode.ohm.Composite( + self.submodels["negative electrode potential"] = pybamm.electrode.ohm.Composite( self.param, "Negative" ) def set_positive_electrode_submodel(self): - self.submodels["positive electrode"] = pybamm.electrode.ohm.Composite( + self.submodels["positive electrode potential"] = pybamm.electrode.ohm.Composite( self.param, "Positive" ) From 186b5219a5387ef2737878ee73f5bf454ea42238 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 23:04:55 -0500 Subject: [PATCH 06/12] #1245 add placeholder model for LAM --- examples/scripts/compare_lithium_ion.py | 6 +- .../full_battery_models/base_battery_model.py | 8 +-- .../full_battery_models/lithium_ion/dfn.py | 16 ++--- .../full_battery_models/lithium_ion/spm.py | 8 +-- .../full_battery_models/lithium_ion/spme.py | 8 +-- .../submodels/active_material/__init__.py | 2 + .../active_material/base_active_material.py | 4 +- .../constant_active_material.py | 9 +-- .../varying_active_material_full.py | 65 +++++++++++++++++ .../varying_active_material_uniform.py | 72 +++++++++++++++++++ .../test_models/standard_output_tests.py | 14 +--- .../test_lithium_ion/test_dfn.py | 6 ++ .../test_lithium_ion/test_spm.py | 6 ++ .../test_lithium_ion/test_spme.py | 28 +++++--- .../test_lithium_ion/test_dfn.py | 5 ++ .../test_lithium_ion/test_spm.py | 5 ++ .../test_lithium_ion/test_spme.py | 5 ++ 17 files changed, 217 insertions(+), 50 deletions(-) create mode 100644 pybamm/models/submodels/active_material/varying_active_material_full.py create mode 100644 pybamm/models/submodels/active_material/varying_active_material_uniform.py diff --git a/examples/scripts/compare_lithium_ion.py b/examples/scripts/compare_lithium_ion.py index d018988106..826230bcfa 100644 --- a/examples/scripts/compare_lithium_ion.py +++ b/examples/scripts/compare_lithium_ion.py @@ -6,7 +6,11 @@ pybamm.set_logging_level("INFO") # load models -models = [pybamm.lithium_ion.SPM(), pybamm.lithium_ion.SPMe(), pybamm.lithium_ion.DFN()] +models = [ + pybamm.lithium_ion.SPM({"loss of active material": "example"}), + pybamm.lithium_ion.SPMe({"loss of active material": "example"}), + pybamm.lithium_ion.DFN({"loss of active material": "example"}), +] # create and run simulations sims = [] diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 5ac478ae15..d490545f03 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -212,7 +212,7 @@ def options(self, extra_options): "external submodels": [], "sei": None, "sei porosity change": False, - "active material change": None, + "loss of active material": None, "working electrode": None, "particle cracking": None, } @@ -351,10 +351,10 @@ def options(self, extra_options): ) ) - if options["active material change"] not in [None, "example"]: + if options["loss of active material"] not in [None, "example"]: raise pybamm.OptionError( - "Unknown active material change '{}'".format( - options["active material change"] + "Unknown loss of active material '{}'".format( + options["loss of active material"] ) ) diff --git a/pybamm/models/full_battery_models/lithium_ion/dfn.py b/pybamm/models/full_battery_models/lithium_ion/dfn.py index 5ecb6b211e..4321063f36 100644 --- a/pybamm/models/full_battery_models/lithium_ion/dfn.py +++ b/pybamm/models/full_battery_models/lithium_ion/dfn.py @@ -62,20 +62,20 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["active material change"] is None: + if self.options["loss of active material"] is None: self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) self.submodels[ "positive active material" ] = pybamm.active_material.Constant(self.param, "Positive", self.options) - elif self.options["active material change"] == "example": - self.submodels["negative active material"] = pybamm.active_material.Full( - self.param, "Negative", self.options - ) - self.submodels["positive active material"] = pybamm.active_material.Full( - self.param, "Positive", self.options - ) + elif self.options["loss of active material"] == "example": + self.submodels[ + "negative active material" + ] = pybamm.active_material.VaryingFull(self.param, "Negative", self.options) + self.submodels[ + "positive active material" + ] = pybamm.active_material.VaryingFull(self.param, "Positive", self.options) def set_convection_submodel(self): diff --git a/pybamm/models/full_battery_models/lithium_ion/spm.py b/pybamm/models/full_battery_models/lithium_ion/spm.py index b6362f71ed..e9ae7d0aeb 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spm.py +++ b/pybamm/models/full_battery_models/lithium_ion/spm.py @@ -62,22 +62,22 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["active material change"] is None: + if self.options["loss of active material"] is None: self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) self.submodels[ "positive active material" ] = pybamm.active_material.Constant(self.param, "Positive", self.options) - elif self.options["active material change"] == "example": + elif self.options["loss of active material"] == "example": self.submodels[ "negative active material" - ] = pybamm.active_material.LeadingOrder( + ] = pybamm.active_material.VaryingUniform( self.param, "Negative", self.options ) self.submodels[ "positive active material" - ] = pybamm.active_material.LeadingOrder( + ] = pybamm.active_material.VaryingUniform( self.param, "Positive", self.options ) diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index 8268e1e4ff..9857076922 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -65,22 +65,22 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["active material change"] is None: + if self.options["loss of active material"] is None: self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) self.submodels[ "positive active material" ] = pybamm.active_material.Constant(self.param, "Positive", self.options) - elif self.options["active material change"] == "example": + elif self.options["loss of active material"] == "example": self.submodels[ "negative active material" - ] = pybamm.active_material.LeadingOrder( + ] = pybamm.active_material.VaryingUniform( self.param, "Negative", self.options ) self.submodels[ "positive active material" - ] = pybamm.active_material.LeadingOrder( + ] = pybamm.active_material.VaryingUniform( self.param, "Positive", self.options ) diff --git a/pybamm/models/submodels/active_material/__init__.py b/pybamm/models/submodels/active_material/__init__.py index dc299c953a..a559bbd510 100644 --- a/pybamm/models/submodels/active_material/__init__.py +++ b/pybamm/models/submodels/active_material/__init__.py @@ -1,2 +1,4 @@ from .base_active_material import BaseModel from .constant_active_material import Constant +from .varying_active_material_full import VaryingFull +from .varying_active_material_uniform import VaryingUniform \ No newline at end of file diff --git a/pybamm/models/submodels/active_material/base_active_material.py b/pybamm/models/submodels/active_material/base_active_material.py index 4d82d8d793..72b371e0e2 100644 --- a/pybamm/models/submodels/active_material/base_active_material.py +++ b/pybamm/models/submodels/active_material/base_active_material.py @@ -103,8 +103,8 @@ def _get_standard_active_material_change_variables(self, deps_solid_dt): variables = { self.domain + " electrode active material volume fraction change": deps_solid_dt, - "X-averaged negative " - + self.domain + "X-averaged " + + self.domain.lower() + " electrode active material volume fraction change": deps_solid_dt_av, } diff --git a/pybamm/models/submodels/active_material/constant_active_material.py b/pybamm/models/submodels/active_material/constant_active_material.py index bc24debecb..983442f55a 100644 --- a/pybamm/models/submodels/active_material/constant_active_material.py +++ b/pybamm/models/submodels/active_material/constant_active_material.py @@ -1,5 +1,5 @@ # -# Class for constant porosity +# Class for constant active material # import pybamm @@ -7,7 +7,7 @@ class Constant(BaseModel): - """Submodel for constant porosity + """Submodel for constant active material Parameters ---------- @@ -15,9 +15,10 @@ class Constant(BaseModel): The parameters to use for this submodel domain : str The domain of the model either 'Negative' or 'Positive' + options : dict + Additional options to pass to the model - - **Extends:** :class:`pybamm.porosity.BaseModel` + **Extends:** :class:`pybamm.active_material.BaseModel` """ def get_fundamental_variables(self): diff --git a/pybamm/models/submodels/active_material/varying_active_material_full.py b/pybamm/models/submodels/active_material/varying_active_material_full.py new file mode 100644 index 0000000000..05e633da68 --- /dev/null +++ b/pybamm/models/submodels/active_material/varying_active_material_full.py @@ -0,0 +1,65 @@ +# +# Class for varying active material volume fraction +# +import pybamm + +from .base_active_material import BaseModel + + +class VaryingFull(BaseModel): + """Submodel for varying active material volume fraction + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + domain : str + The domain of the model either 'Negative' or 'Positive' + options : dict + Additional options to pass to the model + + **Extends:** :class:`pybamm.active_material.BaseModel` + """ + + def get_fundamental_variables(self): + eps_solid = pybamm.Variable( + self.domain + " electrode active material volume fraction", + domain=self.domain.lower() + " electrode", + auxiliary_domains={"secondary": "current collector"}, + ) + variables = self._get_standard_active_material_variables(eps_solid) + return variables + + def get_coupled_variables(self, variables): + # This submodel only contains the structure to allow the active material volume + # fraction to vary, it does not implement an actual model for LAM. + # As a placeholder, we use deps_dt = 0 * j + j = variables[self.domain + " electrode interfacial current density"] + deps_solid_dt = 0 * j + variables.update( + self._get_standard_active_material_change_variables(deps_solid_dt) + ) + return variables + + def set_rhs(self, variables): + eps_solid = variables[ + self.domain + " electrode active material volume fraction" + ] + deps_solid_dt = variables[ + self.domain + " electrode active material volume fraction change" + ] + self.rhs = {eps_solid: deps_solid_dt} + + def set_initial_conditions(self, variables): + eps_solid = variables[ + self.domain + " electrode active material volume fraction" + ] + + if self.domain == "Negative": + x_n = pybamm.standard_spatial_vars.x_n + eps_solid_init = self.param.epsilon_s_n(x_n) + elif self.domain == "Positive": + x_p = pybamm.standard_spatial_vars.x_p + eps_solid_init = self.param.epsilon_s_p(x_p) + + self.initial_conditions = {eps_solid: eps_solid_init} \ No newline at end of file diff --git a/pybamm/models/submodels/active_material/varying_active_material_uniform.py b/pybamm/models/submodels/active_material/varying_active_material_uniform.py new file mode 100644 index 0000000000..4d723b18bc --- /dev/null +++ b/pybamm/models/submodels/active_material/varying_active_material_uniform.py @@ -0,0 +1,72 @@ +# +# Class for varying active material volume fraction +# +import pybamm + +from .base_active_material import BaseModel + + +class VaryingUniform(BaseModel): + """Submodel for varying active material volume fraction, with variations uniform + across each electrode + + Parameters + ---------- + param : parameter class + The parameters to use for this submodel + domain : str + The domain of the model either 'Negative' or 'Positive' + options : dict + Additional options to pass to the model + + **Extends:** :class:`pybamm.active_material.BaseModel` + """ + + def get_fundamental_variables(self): + domain = self.domain.lower() + " electrode" + eps_solid_xav = pybamm.Variable( + "X-averaged " + domain + " active material volume fraction", + domain="current collector", + ) + eps_solid = pybamm.PrimaryBroadcast(eps_solid_xav, domain) + variables = self._get_standard_active_material_variables(eps_solid) + return variables + + def get_coupled_variables(self, variables): + domain = self.domain.lower() + " electrode" + # This submodel only contains the structure to allow the active material volume + # fraction to vary, it does not implement an actual model for LAM. + # As a placeholder, we use deps_dt = 0 * j + j_xav = variables["X-averaged " + domain + " interfacial current density"] + deps_solid_dt_xav = 0 * j_xav + deps_solid_dt = pybamm.PrimaryBroadcast(deps_solid_dt_xav, domain) + variables.update( + self._get_standard_active_material_change_variables(deps_solid_dt) + ) + return variables + + def set_rhs(self, variables): + domain = self.domain.lower() + " electrode" + eps_solid_xav = variables[ + "X-averaged " + domain + " active material volume fraction" + ] + deps_solid_dt_xav = variables[ + "X-averaged " + domain + " active material volume fraction change" + ] + self.rhs = {eps_solid_xav: deps_solid_dt_xav} + + def set_initial_conditions(self, variables): + eps_solid_xav = variables[ + "X-averaged " + + self.domain.lower() + + " electrode active material volume fraction" + ] + + if self.domain == "Negative": + x_n = pybamm.standard_spatial_vars.x_n + eps_solid_init = self.param.epsilon_s_n(x_n) + elif self.domain == "Positive": + x_p = pybamm.standard_spatial_vars.x_p + eps_solid_init = self.param.epsilon_s_p(x_p) + + self.initial_conditions = {eps_solid_xav: pybamm.x_average(eps_solid_init)} \ No newline at end of file diff --git a/tests/integration/test_models/standard_output_tests.py b/tests/integration/test_models/standard_output_tests.py index b2d75dcccb..915499d2d9 100644 --- a/tests/integration/test_models/standard_output_tests.py +++ b/tests/integration/test_models/standard_output_tests.py @@ -605,7 +605,7 @@ def test_interfacial_current_average(self): np.testing.assert_array_almost_equal( np.mean( - self.a_n(x=self.x_n) + self.a_n(self.t, self.x_n) * (self.j_n(self.t, self.x_n) + self.j_n_sei(self.t, self.x_n)), axis=0, ), @@ -614,23 +614,13 @@ def test_interfacial_current_average(self): ) np.testing.assert_array_almost_equal( np.mean( - self.a_p(x=self.x_p) + self.a_p(self.t, self.x_p) * (self.j_p(self.t, self.x_p) + self.j_p_sei(self.t, self.x_p)), axis=0, ), -self.i_cell / self.l_p, decimal=4, ) - # np.testing.assert_array_almost_equal( - # (self.j_n_av(self.t) + self.j_n_sei_av(self.t)), - # self.i_cell / self.l_n, - # decimal=4, - # ) - # np.testing.assert_array_almost_equal( - # self.j_p_av(self.t) + self.j_p_sei_av(self.t), - # -self.i_cell / self.l_p, - # decimal=4, - # ) def test_conservation(self): """Test sum of electrode and electrolyte current densities give the applied diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index da70b056db..42c066648a 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -107,6 +107,12 @@ def test_particle_quartic(self): modeltest = tests.StandardModelTest(model) modeltest.test_all() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.DFN(options) + modeltest = tests.StandardModelTest(model) + modeltest.test_all() + def test_surface_form_differential(self): options = {"surface form": "differential"} model = pybamm.lithium_ion.DFN(options) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py index 78ead4bbab..be2e5cecb3 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py @@ -120,6 +120,12 @@ def test_particle_quartic(self): modeltest = tests.StandardModelTest(model) modeltest.test_all() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.SPM(options) + modeltest = tests.StandardModelTest(model) + modeltest.test_all() + def test_surface_form_differential(self): options = {"surface form": "differential"} model = pybamm.lithium_ion.SPM(options) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py index 4261851106..e56c184dd6 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py @@ -112,17 +112,23 @@ def test_particle_quartic(self): modeltest = tests.StandardModelTest(model) modeltest.test_all() - # def test_surface_form_differential(self): - # options = {"surface form": "differential"} - # model = pybamm.lithium_ion.SPMe(options) - # modeltest = tests.StandardModelTest(model) - # modeltest.test_all() - - # def test_surface_form_algebraic(self): - # options = {"surface form": "algebraic"} - # model = pybamm.lithium_ion.SPMe(options) - # modeltest = tests.StandardModelTest(model) - # modeltest.test_all() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.SPMe(options) + modeltest = tests.StandardModelTest(model) + modeltest.test_all() + + def test_surface_form_differential(self): + options = {"surface form": "differential"} + model = pybamm.lithium_ion.SPMe(options) + modeltest = tests.StandardModelTest(model) + modeltest.test_all() + + def test_surface_form_algebraic(self): + options = {"surface form": "algebraic"} + model = pybamm.lithium_ion.SPMe(options) + modeltest = tests.StandardModelTest(model) + modeltest.test_all() def test_integrated_conductivity(self): options = {"electrolyte conductivity": "integrated"} diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index de1776b229..da5b74f443 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -108,6 +108,11 @@ def test_particle_shape_user(self): model = pybamm.lithium_ion.DFN(options) model.check_well_posedness() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.DFN(options) + model.check_well_posedness() + def test_surface_form_differential(self): options = {"surface form": "differential"} model = pybamm.lithium_ion.DFN(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py index 84606408d3..cd8bad53fb 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py @@ -109,6 +109,11 @@ def test_particle_shape_user(self): model = pybamm.lithium_ion.SPM(options) model.check_well_posedness() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.SPM(options) + model.check_well_posedness() + def test_surface_form_differential(self): options = {"surface form": "differential"} model = pybamm.lithium_ion.SPM(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py index 748d3e644d..3575e4d0b5 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py @@ -108,6 +108,11 @@ def test_particle_shape_user(self): model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() + def test_loss_active_material(self): + options = {"loss of active material": "example"} + model = pybamm.lithium_ion.SPMe(options) + model.check_well_posedness() + def test_surface_form_differential(self): options = {"surface form": "differential"} model = pybamm.lithium_ion.SPMe(options) From 83a484bdbac6db6cf3313590d54ab1e18d8a4965 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 26 Nov 2020 23:54:34 -0500 Subject: [PATCH 07/12] #1245 flake8 --- .../submodels/active_material/varying_active_material_full.py | 2 +- .../active_material/varying_active_material_uniform.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pybamm/models/submodels/active_material/varying_active_material_full.py b/pybamm/models/submodels/active_material/varying_active_material_full.py index 05e633da68..8d81a3e5eb 100644 --- a/pybamm/models/submodels/active_material/varying_active_material_full.py +++ b/pybamm/models/submodels/active_material/varying_active_material_full.py @@ -62,4 +62,4 @@ def set_initial_conditions(self, variables): x_p = pybamm.standard_spatial_vars.x_p eps_solid_init = self.param.epsilon_s_p(x_p) - self.initial_conditions = {eps_solid: eps_solid_init} \ No newline at end of file + self.initial_conditions = {eps_solid: eps_solid_init} diff --git a/pybamm/models/submodels/active_material/varying_active_material_uniform.py b/pybamm/models/submodels/active_material/varying_active_material_uniform.py index 4d723b18bc..400f870cb3 100644 --- a/pybamm/models/submodels/active_material/varying_active_material_uniform.py +++ b/pybamm/models/submodels/active_material/varying_active_material_uniform.py @@ -69,4 +69,4 @@ def set_initial_conditions(self, variables): x_p = pybamm.standard_spatial_vars.x_p eps_solid_init = self.param.epsilon_s_p(x_p) - self.initial_conditions = {eps_solid_xav: pybamm.x_average(eps_solid_init)} \ No newline at end of file + self.initial_conditions = {eps_solid_xav: pybamm.x_average(eps_solid_init)} From 2c5e7392558d59f04af6fd343737a6b242537590 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Fri, 27 Nov 2020 17:31:34 -0500 Subject: [PATCH 08/12] #1245 changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fe71bbbbc..554039050a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Features +- Added submodels for active material ([#1262](https://github.com/pybamm-team/PyBaMM/pull/1262)) - Added composite surface form electrolyte models: `CompositeDifferential` and `CompositeAlgebraic` ([#1207](https://github.com/pybamm-team/PyBaMM/issues/1207)) ## Optimizations From ca6a9e55180772c7d2b32530d8ea5ec21c16a6c1 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Mon, 30 Nov 2020 14:10:48 -0500 Subject: [PATCH 09/12] #1245 add test for option failure --- .../full_battery_models/base_battery_model.py | 47 ++++++++++--------- .../lithium_ion/base_lithium_ion_model.py | 4 +- .../full_battery_models/lithium_ion/dfn.py | 2 +- .../full_battery_models/lithium_ion/spm.py | 2 +- .../full_battery_models/lithium_ion/spme.py | 2 +- .../inverse_kinetics/inverse_butler_volmer.py | 4 +- .../interface/kinetics/base_kinetics.py | 2 +- .../test_base_battery_model.py | 11 ++++- 8 files changed, 43 insertions(+), 31 deletions(-) diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index d490545f03..12bcb294eb 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -42,6 +42,9 @@ class BaseBatteryModel(pybamm.BaseModel): * "interfacial surface area" : str, optional Sets the model for the interfacial surface area. Can be "constant" (default) or "varying". Not currently implemented in any of the models. + * "loss of active material" : str, optional + Sets the model for loss of active material. Can be "none" (default) or + "example", which is a placeholder for LAM models. * "particle" : str, optional Sets the submodel to use to describe behaviour within the particle. Can be "Fickian diffusion" (default), "uniform profile", @@ -54,8 +57,8 @@ class BaseBatteryModel(pybamm.BaseModel): necessarily consistent with the particle shape. * "particle cracking" : str, optional Sets the model to account for mechanical effects and particle - cracking. Can be None, "no cracking", "anode", "cathode" or "both". - All options other than None account for the effects of swelling + cracking. Can be "none", "no cracking", "anode", "cathode" or "both". + All options other than "none" account for the effects of swelling of electrode particles, cell thickness change, and stress-assisted diffusion. The options "anode", "cathode" or "both" additionally account for crack propagation in the anode, cathode or both electrodes, @@ -63,7 +66,7 @@ class BaseBatteryModel(pybamm.BaseModel): * "sei" : str Set the sei submodel to be used. Options are: - - None: :class:`pybamm.sei.NoSEI` (no SEI growth) + - "none": :class:`pybamm.sei.NoSEI` (no SEI growth) - "constant": :class:`pybamm.sei.Constant` (constant SEI thickness) - "reaction limited": :class:`pybamm.sei.ReactionLimited` - "solvent-diffusion limited": \ @@ -76,12 +79,12 @@ class BaseBatteryModel(pybamm.BaseModel): :class:`pybamm.sei.EcReactionLimited` * "sei film resistance" : str Set the submodel for additional term in the overpotential due to SEI. - The default value is "None" if the "sei" option is "None", and + The default value is "none" if the "sei" option is "none", and "distributed" otherwise. This is because the "distributed" model is more complex than the model with no additional resistance, which adds unnecessary complexity if there is no SEI in the first place - - None: no additional resistance\ + - "none": no additional resistance\ .. math:: \\eta_r = \\frac{F}{RT} * (\\phi_s - \\phi_e - U) @@ -208,20 +211,20 @@ def options(self, extra_options): "particle shape": "spherical", "electrolyte conductivity": "default", "thermal": "isothermal", - "cell geometry": None, + "cell geometry": "none", "external submodels": [], - "sei": None, + "sei": "none", "sei porosity change": False, - "loss of active material": None, - "working electrode": None, - "particle cracking": None, + "loss of active material": "none", + "working electrode": "none", + "particle cracking": "none", } # Change the default for cell geometry based on which thermal option is provided extra_options = extra_options or {} thermal_option = extra_options.get( - "thermal", None - ) # return None if option not given - if thermal_option is None or thermal_option in ["isothermal", "lumped"]: + "thermal", "none" + ) # return "none" if option not given + if thermal_option in ["none", "isothermal", "lumped"]: default_options["cell geometry"] = "arbitrary" else: default_options["cell geometry"] = "pouch" @@ -231,9 +234,11 @@ def options(self, extra_options): # Change the default for SEI film resistance based on which sei option is # provided # extra_options = extra_options or {} - sei_option = extra_options.get("sei", None) # return None if option not given - if sei_option is None: - default_options["sei film resistance"] = None + sei_option = extra_options.get( + "sei", "none" + ) # return "none" if option not given + if sei_option == "none": + default_options["sei film resistance"] = "none" else: default_options["sei film resistance"] = "distributed" # The "sei film resistance" option will still be overridden by extra_options if @@ -270,7 +275,7 @@ def options(self, extra_options): "Lead-acid models can only have thermal " "effects if dimensionality is 0." ) - if options["sei"] is not None or options["sei film resistance"] is not None: + if options["sei"] != "none" or options["sei film resistance"] != "none": raise pybamm.OptionError("Lead-acid models cannot have SEI formation") # Some standard checks to make sure options are compatible @@ -329,7 +334,7 @@ def options(self, extra_options): "Unknown geometry '{}'".format(options["cell geometry"]) ) if options["sei"] not in [ - None, + "none", "constant", "reaction limited", "solvent-diffusion limited", @@ -338,7 +343,7 @@ def options(self, extra_options): "ec reaction limited", ]: raise pybamm.OptionError("Unknown sei model '{}'".format(options["sei"])) - if options["sei film resistance"] not in [None, "distributed", "average"]: + if options["sei film resistance"] not in ["none", "distributed", "average"]: raise pybamm.OptionError( "Unknown sei film resistance model '{}'".format( options["sei film resistance"] @@ -351,7 +356,7 @@ def options(self, extra_options): ) ) - if options["loss of active material"] not in [None, "example"]: + if options["loss of active material"] not in ["none", "example"]: raise pybamm.OptionError( "Unknown loss of active material '{}'".format( options["loss of active material"] @@ -359,7 +364,7 @@ def options(self, extra_options): ) if options["particle cracking"] not in [ - None, + "none", "no cracking", "anode", "cathode", diff --git a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py index a6696938b2..f73c408d93 100644 --- a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py +++ b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py @@ -49,7 +49,7 @@ def set_standard_output_variables(self): def set_sei_submodel(self): # negative electrode SEI - if self.options["sei"] is None: + if self.options["sei"] == "none": self.submodels["negative sei"] = pybamm.sei.NoSEI(self.param, "Negative") if self.options["sei"] == "constant": @@ -94,7 +94,7 @@ def set_other_reaction_submodels_to_zero(self): ) def set_crack_submodel(self): - if self.options["particle cracking"] is None: + if self.options["particle cracking"] == "none": return if self.options["particle cracking"] == "no cracking": diff --git a/pybamm/models/full_battery_models/lithium_ion/dfn.py b/pybamm/models/full_battery_models/lithium_ion/dfn.py index 4321063f36..405c86cc40 100644 --- a/pybamm/models/full_battery_models/lithium_ion/dfn.py +++ b/pybamm/models/full_battery_models/lithium_ion/dfn.py @@ -62,7 +62,7 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["loss of active material"] is None: + if self.options["loss of active material"] == "none": self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) diff --git a/pybamm/models/full_battery_models/lithium_ion/spm.py b/pybamm/models/full_battery_models/lithium_ion/spm.py index e9ae7d0aeb..c4a3ef847d 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spm.py +++ b/pybamm/models/full_battery_models/lithium_ion/spm.py @@ -62,7 +62,7 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["loss of active material"] is None: + if self.options["loss of active material"] == "none": self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index 9857076922..c74eb0fb5d 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -65,7 +65,7 @@ def set_porosity_submodel(self): def set_active_material_submodel(self): - if self.options["loss of active material"] is None: + if self.options["loss of active material"] == "none": self.submodels[ "negative active material" ] = pybamm.active_material.Constant(self.param, "Negative", self.options) diff --git a/pybamm/models/submodels/interface/inverse_kinetics/inverse_butler_volmer.py b/pybamm/models/submodels/interface/inverse_kinetics/inverse_butler_volmer.py index 0f807389e5..8a36b5502c 100644 --- a/pybamm/models/submodels/interface/inverse_kinetics/inverse_butler_volmer.py +++ b/pybamm/models/submodels/interface/inverse_kinetics/inverse_butler_volmer.py @@ -30,7 +30,7 @@ class InverseButlerVolmer(BaseInterface): def __init__(self, param, domain, reaction, options=None): super().__init__(param, domain, reaction) if options is None: - options = {"sei film resistance": None} + options = {"sei film resistance": "none"} self.options = options def get_coupled_variables(self, variables): @@ -62,7 +62,7 @@ def get_coupled_variables(self, variables): eta_r = self._get_overpotential(j_tot, j0, ne, T) # With SEI resistance (distributed and averaged have the same effect here) - if self.options["sei film resistance"] is not None: + if self.options["sei film resistance"] != "none": if self.domain == "Negative": R_sei = self.param.R_sei_n elif self.domain == "Positive": diff --git a/pybamm/models/submodels/interface/kinetics/base_kinetics.py b/pybamm/models/submodels/interface/kinetics/base_kinetics.py index 4e2589bbbc..a5ce2525d2 100644 --- a/pybamm/models/submodels/interface/kinetics/base_kinetics.py +++ b/pybamm/models/submodels/interface/kinetics/base_kinetics.py @@ -28,7 +28,7 @@ class BaseKinetics(BaseInterface): def __init__(self, param, domain, reaction, options=None): super().__init__(param, domain, reaction) if options is None: - options = {"sei film resistance": None} + options = {"sei film resistance": "none"} self.options = options def get_fundamental_variables(self): diff --git a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py index 48ad9ef44d..63d71b990b 100644 --- a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py +++ b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py @@ -161,11 +161,18 @@ def test_options(self): pybamm.BaseBatteryModel({"sei film resistance": "bad sei film resistance"}) with self.assertRaisesRegex(pybamm.OptionError, "sei porosity change"): pybamm.BaseBatteryModel({"sei porosity change": "bad sei porosity change"}) - # variable defaults + # changing defaults based on other options model = pybamm.BaseBatteryModel() - self.assertEqual(model.options["sei film resistance"], None) + self.assertEqual(model.options["sei film resistance"], "none") model = pybamm.BaseBatteryModel({"sei": "constant"}) self.assertEqual(model.options["sei film resistance"], "distributed") + + # loss of active material model + with self.assertRaisesRegex(pybamm.OptionError, "loss of active material"): + model = pybamm.BaseBatteryModel( + {"loss of active material": "bad LAM model"} + ) + # crack model with self.assertRaisesRegex(pybamm.OptionError, "particle cracking"): pybamm.BaseBatteryModel({"particle cracking": "bad particle cracking"}) From 35d598886e8d354fdc294ea5c26aafb79616436a Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Mon, 30 Nov 2020 16:18:25 -0500 Subject: [PATCH 10/12] #1245 fix options --- pybamm/parameters/lithium_ion_parameters.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index b588dd4125..453d9a7f4b 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -280,7 +280,7 @@ def D_n_dimensional(self, sto, T): """Dimensional diffusivity in negative particle. Note this is defined as a function of stochiometry""" inputs = {"Negative particle stoichiometry": sto, "Temperature [K]": T} - if self.options["particle cracking"] is not None: + if self.options["particle cracking"] != "none": mech_effects = ( 1 + self.theta_n_dim * (sto * self.c_n_max - self.c_n_0_dim) / T ) @@ -295,7 +295,7 @@ def D_p_dimensional(self, sto, T): """Dimensional diffusivity in positive particle. Note this is defined as a function of stochiometry""" inputs = {"Positive particle stoichiometry": sto, "Temperature [K]": T} - if self.options["particle cracking"] is not None: + if self.options["particle cracking"] != "none": mech_effects = ( 1 + self.theta_p_dim * (sto * self.c_p_max - self.c_p_0_dim) / T ) @@ -919,7 +919,7 @@ def options(self, extra_options): extra_options = extra_options or {} # Default options - options = {"particle shape": "spherical", "particle cracking": None} + options = {"particle shape": "spherical", "particle cracking": "none"} # All model options get passed to the parameter class, so we just need # to update the options in the default options and ignore the rest @@ -936,7 +936,7 @@ def options(self, extra_options): ) if options["particle cracking"] not in [ - None, + "none", "no cracking", "cathode", "anode", From 682d8f7a6b2a7fe665b86b89ee3cf0968e0d10d1 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Mon, 30 Nov 2020 16:56:57 -0500 Subject: [PATCH 11/12] #1245 fix tests --- .../test_full_battery_models/test_lithium_ion/test_dfn.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_spm.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_spme.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_dfn.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_spm.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_spme.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index 42c066648a..2d962646f0 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -190,7 +190,7 @@ def test_well_posed_ec_reaction_limited(self): class TestDFNWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.DFN(options) chemistry = pybamm.parameter_sets.Ai2020 parameter_values = pybamm.ParameterValues(chemistry=chemistry) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py index be2e5cecb3..b926c2cca0 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spm.py @@ -173,7 +173,7 @@ def test_well_posed_ec_reaction_limited(self): class TestSPMWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.SPM(options) chemistry = pybamm.parameter_sets.Ai2020 parameter_values = pybamm.ParameterValues(chemistry=chemistry) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py index e56c184dd6..7cbf01e615 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_spme.py @@ -171,7 +171,7 @@ def test_well_posed_ec_reaction_limited(self): class TestSPMeWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.SPMe(options) chemistry = pybamm.parameter_sets.Ai2020 parameter_values = pybamm.ParameterValues(chemistry=chemistry) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index da5b74f443..532c57b807 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -168,7 +168,7 @@ def test_well_posed_ec_reaction_limited(self): class TestDFNWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.DFN(options) model.check_well_posedness() diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py index cd8bad53fb..d97229090a 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spm.py @@ -200,7 +200,7 @@ def test_well_posed_ec_reaction_limited(self): class TestSPMWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.SPM(options) model.check_well_posedness() diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py index 3575e4d0b5..f19a9ae7dd 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_spme.py @@ -163,7 +163,7 @@ def test_well_posed_ec_reaction_limited(self): class TestSPMeWithCrack(unittest.TestCase): def test_well_posed_none_crack(self): - options = {"particle": "Fickian diffusion", "particle cracking": None} + options = {"particle": "Fickian diffusion", "particle cracking": "none"} model = pybamm.lithium_ion.SPMe(options) model.check_well_posedness() From 41284b71236e436aa1a77570d8c43b6b84d20b2a Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Mon, 30 Nov 2020 17:15:02 -0500 Subject: [PATCH 12/12] #1245 revert compare_lithium_ion.py --- examples/scripts/compare_lithium_ion.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/scripts/compare_lithium_ion.py b/examples/scripts/compare_lithium_ion.py index 826230bcfa..d018988106 100644 --- a/examples/scripts/compare_lithium_ion.py +++ b/examples/scripts/compare_lithium_ion.py @@ -6,11 +6,7 @@ pybamm.set_logging_level("INFO") # load models -models = [ - pybamm.lithium_ion.SPM({"loss of active material": "example"}), - pybamm.lithium_ion.SPMe({"loss of active material": "example"}), - pybamm.lithium_ion.DFN({"loss of active material": "example"}), -] +models = [pybamm.lithium_ion.SPM(), pybamm.lithium_ion.SPMe(), pybamm.lithium_ion.DFN()] # create and run simulations sims = []