Skip to content

Commit

Permalink
Merge pull request #1865 from pybamm-team/issue-1749-lam
Browse files Browse the repository at this point in the history
Issue 1749 lam
  • Loading branch information
valentinsulzer authored Dec 21, 2021
2 parents 93d6ddc + 73fc84d commit ccf5be7
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 290 deletions.
3 changes: 1 addition & 2 deletions docs/source/models/submodels/active_material/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ Submodels for (loss of) active material

base_active_material
constant_active_material
reaction_driven_active_material
stress_driven_active_material
loss_active_material

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Loss of Active Material
=======================

.. autoclass:: pybamm.active_material.LossActiveMaterial
:members:



This file was deleted.

This file was deleted.

52 changes: 38 additions & 14 deletions pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class BatteryModelOptions(pybamm.FuzzyDict):
"reversible" or "irreversible".
* "loss of active material" : str
Sets the model for loss of active material. Can be "none" (default),
"stress-driven", or "reaction-driven".
"stress-driven", "reaction-driven", or "stress and reaction-driven".
A 2-tuple can be provided for different behaviour in negative and
positive electrodes.
* "operating mode" : str
Expand Down Expand Up @@ -174,7 +174,12 @@ def __init__(self, extra_options):
"interface utilisation": ["full", "constant", "current-driven"],
"lithium plating": ["none", "reversible", "irreversible"],
"lithium plating porosity change": ["false", "true"],
"loss of active material": ["none", "stress-driven", "reaction-driven"],
"loss of active material": [
"none",
"stress-driven",
"reaction-driven",
"stress and reaction-driven",
],
"operating mode": ["current", "voltage", "power", "CCCV"],
"particle": [
"Fickian diffusion",
Expand Down Expand Up @@ -235,7 +240,7 @@ def __init__(self, extra_options):
# provided
# return "none" if option not given
lam_option = extra_options.get("loss of active material", "none")
if "stress-driven" in lam_option:
if "stress-driven" in lam_option or "stress and reaction-driven" in lam_option:
default_options["particle mechanics"] = "swelling only"
else:
default_options["particle mechanics"] = "none"
Expand Down Expand Up @@ -423,6 +428,32 @@ def print_detailed_options(self):
"""
print(self.__doc__)

@property
def negative(self):
"Returns the options for the negative electrode"
# index 0 in a 2-tuple for the negative electrode
return BatteryModelDomainOptions(self.items(), 0)

@property
def positive(self):
"Returns the options for the positive electrode"
# index 1 in a 2-tuple for the positive electrode
return BatteryModelDomainOptions(self.items(), 1)


class BatteryModelDomainOptions(dict):
def __init__(self, dict_items, index):
super().__init__(dict_items)
self.index = index

def __getitem__(self, key):
options = super().__getitem__(key)
if isinstance(options, str):
return options
else:
# 2-tuple, first is negative domain, second is positive domain
return options[self.index]


class BaseBatteryModel(pybamm.BaseModel):
"""
Expand Down Expand Up @@ -897,22 +928,15 @@ def set_current_collector_submodel(self):
self.submodels["current collector"] = submodel

def set_interface_utilisation_submodel(self):
# this option can either be a string (both sides the same) or a 2-tuple
# to indicate different options in negative and positive electrodes
if isinstance(self.options["interface utilisation"], str):
util_left = self.options["interface utilisation"]
util_right = self.options["interface utilisation"]
else:
util_left, util_right = self.options["interface utilisation"]

if self.half_cell:
domains = [[util_left, "Counter"], [util_right, "Positive"]]
domains = ["Counter", "Positive"]
else:
domains = [[util_left, "Negative"], [util_right, "Positive"]]
for util, domain in domains:
domains = ["Negative", "Positive"]
for domain in domains:
name = domain.lower() + " interface utilisation"
if domain == "Counter":
domain = "Negative"
util = getattr(self.options, domain.lower())["interface utilisation"]
if util == "full":
self.submodels[name] = pybamm.interface_utilisation.Full(
self.param, domain, self.options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,50 +225,32 @@ def set_other_reaction_submodels_to_zero(self):
)

def set_crack_submodel(self):
# this option can either be a string (both sides the same) or a 2-tuple
# to indicate different options in negative and positive electrodes
if isinstance(self.options["particle mechanics"], str):
crack_left = self.options["particle mechanics"]
crack_right = self.options["particle mechanics"]
else:
crack_left, crack_right = self.options["particle mechanics"]
for crack_side, domain in [[crack_left, "Negative"], [crack_right, "Positive"]]:
if crack_side == "none":
for domain in ["Negative", "Positive"]:
crack = getattr(self.options, domain.lower())["particle mechanics"]
if crack == "none":
pass
elif crack_side == "swelling only":
elif crack == "swelling only":
self.submodels[
domain.lower() + " particle mechanics"
] = pybamm.particle_mechanics.SwellingOnly(self.param, domain)
elif crack_side == "swelling and cracking":
elif crack == "swelling and cracking":
self.submodels[
domain.lower() + " particle mechanics"
] = pybamm.particle_mechanics.CrackPropagation(
self.param, domain, self.x_average
)

def set_active_material_submodel(self):
# this option can either be a string (both sides the same) or a 2-tuple
# to indicate different options in negative and positive electrodes
if isinstance(self.options["loss of active material"], str):
lam_left = self.options["loss of active material"]
lam_right = self.options["loss of active material"]
else:
lam_left, lam_right = self.options["loss of active material"]
for lam_side, domain in [[lam_left, "Negative"], [lam_right, "Positive"]]:
if lam_side == "none":
for domain in ["Negative", "Positive"]:
lam = getattr(self.options, domain.lower())["loss of active material"]
if lam == "none":
self.submodels[
domain.lower() + " active material"
] = pybamm.active_material.Constant(self.param, domain, self.options)
elif lam_side == "stress-driven":
self.submodels[
domain.lower() + " active material"
] = pybamm.active_material.StressDriven(
self.param, domain, self.options, self.x_average
)
elif lam_side == "reaction-driven":
else:
self.submodels[
domain.lower() + " active material"
] = pybamm.active_material.ReactionDriven(
] = pybamm.active_material.LossActiveMaterial(
self.param, domain, self.options, self.x_average
)

Expand Down
25 changes: 7 additions & 18 deletions pybamm/models/full_battery_models/lithium_ion/dfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,46 +80,35 @@ def set_intercalation_kinetics_submodel(self):
)

def set_particle_submodel(self):

if isinstance(self.options["particle"], str):
particle_left = self.options["particle"]
particle_right = self.options["particle"]
else:
particle_left, particle_right = self.options["particle"]
for particle_side, domain in [
[particle_left, "Negative"],
[particle_right, "Positive"],
]:
for domain in ["Negative", "Positive"]:
particle = getattr(self.options, domain.lower())["particle"]
if self.options["particle size"] == "single":
if particle_side == "Fickian diffusion":
if particle == "Fickian diffusion":
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.FickianDiffusion(
self.param,
domain,
self.options,
)
elif particle_side in [
elif particle in [
"uniform profile",
"quadratic profile",
"quartic profile",
]:
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.PolynomialProfile(
self.param,
domain,
particle_side,
self.options,
self.param, domain, particle, self.options
)
elif self.options["particle size"] == "distribution":
if particle_side == "Fickian diffusion":
if particle == "Fickian diffusion":
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.size_distribution.FickianDiffusion(
self.param, domain
)
elif particle_side == "uniform profile":
elif particle == "uniform profile":
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.size_distribution.UniformProfile(
Expand Down
17 changes: 5 additions & 12 deletions pybamm/models/full_battery_models/lithium_ion/newman_tobias.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,23 @@ def __init__(self, options=None, name="Newman-Tobias model", build=True):
pybamm.citations.register("Chu2020")

def set_particle_submodel(self):
if isinstance(self.options["particle"], str):
particle_left = self.options["particle"]
particle_right = self.options["particle"]
else:
particle_left, particle_right = self.options["particle"]
for particle_side, domain in [
[particle_left, "Negative"],
[particle_right, "Positive"],
]:
if particle_side == "Fickian diffusion":
for domain in ["Negative", "Positive"]:
particle = getattr(self.options, domain.lower())["particle"]
if particle == "Fickian diffusion":
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.XAveragedFickianDiffusion(
self.param, domain, self.options
)
elif particle_side in [
elif particle in [
"uniform profile",
"quadratic profile",
"quartic profile",
]:
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.XAveragedPolynomialProfile(
self.param, domain, particle_side, self.options
self.param, domain, particle, self.options
)

def set_electrolyte_submodel(self):
Expand Down
17 changes: 5 additions & 12 deletions pybamm/models/full_battery_models/lithium_ion/spm.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,30 +107,23 @@ def set_intercalation_kinetics_submodel(self):
)

def set_particle_submodel(self):
if isinstance(self.options["particle"], str):
particle_left = self.options["particle"]
particle_right = self.options["particle"]
else:
particle_left, particle_right = self.options["particle"]
for particle_side, domain in [
[particle_left, "Negative"],
[particle_right, "Positive"],
]:
if particle_side == "Fickian diffusion":
for domain in ["Negative", "Positive"]:
particle = getattr(self.options, domain.lower())["particle"]
if particle == "Fickian diffusion":
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.XAveragedFickianDiffusion(
self.param, domain, self.options
)
elif particle_side in [
elif particle in [
"uniform profile",
"quadratic profile",
"quartic profile",
]:
self.submodels[
domain.lower() + " particle"
] = pybamm.particle.no_distribution.XAveragedPolynomialProfile(
self.param, domain, particle_side, self.options
self.param, domain, particle, self.options
)

def set_solid_submodel(self):
Expand Down
3 changes: 1 addition & 2 deletions pybamm/models/submodels/active_material/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from .base_active_material import BaseModel
from .constant_active_material import Constant
from .stress_driven_active_material import StressDriven
from .reaction_driven_active_material import ReactionDriven
from .loss_active_material import LossActiveMaterial
Loading

0 comments on commit ccf5be7

Please sign in to comment.