Skip to content

Commit

Permalink
fixed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DrSOKane committed Jun 5, 2023
1 parent d90a56c commit cf53ff1
Show file tree
Hide file tree
Showing 23 changed files with 108 additions and 136 deletions.
6 changes: 3 additions & 3 deletions examples/scripts/compare_lithium_ion_half_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

# load models
models = [
pybamm.lithium_ion.SPM({"working electrode": "positive"}),
pybamm.lithium_ion.SPMe({"working electrode": "positive"}),
pybamm.lithium_ion.DFN({"working electrode": "positive"}),
pybamm.lithium_ion.SPM({"half-cell": "true"}),
pybamm.lithium_ion.SPMe({"half-cell": "true"}),
pybamm.lithium_ion.DFN({"half-cell": "true"}),
]

# create and run simulations
Expand Down
2 changes: 1 addition & 1 deletion pybamm/expression_tree/averages.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def r_average(symbol):
# "positive electrode", take the r-average of the child then broadcast back
elif isinstance(symbol, pybamm.SecondaryBroadcast) and symbol.domains[
"secondary"
] in [["positive electrode"], ["negative electrode"], ["working electrode"]]:
] in [["positive electrode"], ["negative electrode"]]:
child = symbol.orphans[0]
child_av = pybamm.r_average(child)
return pybamm.PrimaryBroadcast(child_av, symbol.domains["secondary"])
Expand Down
24 changes: 9 additions & 15 deletions pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class BatteryModelOptions(pybamm.FuzzyDict):
* "electrolyte conductivity" : str
Can be "default" (default), "full", "leading order", "composite" or
"integrated".
* "half-cell" : str
Can be "false" (default) for a standard battery or "true" for a
half-cell where the negative electrode is replaced with a lithium metal
counter electrode.
* "hydrolysis" : str
Whether to include hydrolysis in the model. Only implemented for
lead-acid models. Can be "false" (default) or "true". If "true", then
Expand Down Expand Up @@ -168,10 +172,6 @@ class BatteryModelOptions(pybamm.FuzzyDict):
solve an algebraic equation for it. Default is "false", unless "SEI film
resistance" is distributed in which case it is automatically set to
"true".
* "working electrode": str
Which electrode(s) intercalates and which is counter. If "both"
(default), the model is a standard battery. Otherwise can be "negative"
or "positive" to indicate a half-cell model.
* "x-average side reactions": str
Whether to average the side reactions (SEI growth, lithium plating and
the respective porosity change) over the x-axis in Single Particle
Expand Down Expand Up @@ -199,6 +199,7 @@ def __init__(self, extra_options):
"composite",
"integrated",
],
"half-cell": ["false", "true"],
"hydrolysis": ["false", "true"],
"intercalation kinetics": [
"symmetric Butler-Volmer",
Expand Down Expand Up @@ -262,7 +263,6 @@ def __init__(self, extra_options):
"surface form": ["false", "differential", "algebraic"],
"thermal": ["isothermal", "lumped", "x-lumped", "x-full"],
"total interfacial current density as a state": ["false", "true"],
"working electrode": ["both", "negative", "positive"],
"x-average side reactions": ["false", "true"],
}

Expand Down Expand Up @@ -495,7 +495,7 @@ def __init__(self, extra_options):
"mechanics model"
)

if options["working electrode"] != "both":
if options["half-cell"] == "true":
if options["thermal"] == "x-full":
raise pybamm.OptionError(
"X-full thermal submodel is not compatible with half-cell models"
Expand All @@ -506,10 +506,6 @@ def __init__(self, extra_options):
f"X-lumped thermal submodels do not yet support {n}D "
"current collectors in a half-cell configuration"
)
elif options["SEI on cracks"] == "true":
raise NotImplementedError(
"SEI on cracks not yet implemented for half-cell models"
)

if options["particle phases"] != "1":
if not (
Expand All @@ -530,7 +526,7 @@ def __init__(self, extra_options):

# Check options are valid
for option, value in options.items():
if option in ["working electrode"]:
if option in ["half-cell"]: # is this exception still necessary?
pass
else:
if isinstance(value, str) or option in [
Expand Down Expand Up @@ -597,11 +593,9 @@ def phases(self):

@cached_property
def whole_cell_domains(self):
if self["working electrode"] == "positive":
if self["half-cell"] == "true":
return ["separator", "positive electrode"]
elif self["working electrode"] == "negative":
return ["negative electrode", "separator"]
elif self["working electrode"] == "both":
else:
return ["negative electrode", "separator", "positive electrode"]

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ class BasicDFNHalfCell(BaseModel):

def __init__(self, options=None, name="Doyle-Fuller-Newman half cell model"):
super().__init__(options, name)
if self.options["working electrode"] not in ["negative", "positive"]:
raise ValueError(
"The option 'working electrode' should be either 'positive'"
" or 'negative'"
)
pybamm.citations.register("Marquis2019")
# `param` is a class containing all the relevant parameters and functions for
# this model. These are purely symbolic at this stage, and will be set by the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,17 @@ class ElectrodeSOHHalfCell(pybamm.BaseModel):
expansion. Journal of Power Sources, 427, 101-111.
"""

def __init__(self, working_electrode, name="Electrode-specific SOH model"):
self.working_electrode = working_electrode
def __init__(self, name="Electrode-specific SOH model"):
pybamm.citations.register("Mohtat2019")
super().__init__(name)
param = pybamm.LithiumIonParameters({"working electrode": working_electrode})
param = pybamm.LithiumIonParameters({"half-cell": "true"})

x_100 = pybamm.Variable("x_100", bounds=(0, 1))
x_0 = pybamm.Variable("x_0", bounds=(0, 1))
Q_w = pybamm.InputParameter("Q_w")
T_ref = param.T_ref
if working_electrode == "negative": # pragma: no cover
raise NotImplementedError
elif working_electrode == "positive":
U_w = param.p.prim.U
Q = Q_w * (x_100 - x_0)
U_w = param.p.prim.U
Q = Q_w * (x_100 - x_0)

V_max = param.voltage_high_cut
V_min = param.voltage_low_cut
Expand Down
2 changes: 1 addition & 1 deletion pybamm/models/full_battery_models/lithium_ion/mpm.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ def __init__(self, options=None, name="Many-Particle Model", build=True):
def default_parameter_values(self):
default_params = super().default_parameter_values
default_params = pybamm.get_size_distribution_parameters(
default_params, electrode=self.options["working electrode"]
default_params, halfcell=self.options["half-cell"]
)
return default_params
2 changes: 1 addition & 1 deletion pybamm/models/full_battery_models/lithium_metal/dfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __init__(
self, options=None, name="Doyle-Fuller-Newman lithium metal model", build=True
):
options = options or {}
options["working electrode"] = "positive"
options["half-cell"] = "positive"
super().__init__(options, name, build=False)

if build:
Expand Down
39 changes: 22 additions & 17 deletions pybamm/models/submodels/interface/sei/base_sei.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,45 @@ def __init__(self, param, options, phase="primary", cracks=False):

def get_coupled_variables(self, variables):
# Update some common variables
zero_av = pybamm.PrimaryBroadcast(0, "current collector")
zero = pybamm.FullBroadcast(0, "positive electrode", "current collector")

if self.reaction_loc != "interface":
j_sei_av = variables[
f"X-averaged {self.reaction_name}interfacial current density [A.m-2]"
]
j_sei = variables[
f"{self.reaction_name}interfacial current density [A.m-2]"
]
variables.update(
{
f"X-averaged negative electrode {self.reaction_name}interfacial "
"current density [A.m-2]": j_sei_av,
"current density": variables[
f"X-averaged {self.reaction_name}interfacial current density"
],
f"Negative electrode {self.reaction_name}interfacial current "
"density": variables[
f"{self.reaction_name}interfacial current density"
],
f"Negative electrode {self.reaction_name}interfacial current "
"density [A.m-2]": j_sei,
"density [A.m-2]": variables[
f"{self.reaction_name}interfacial current density [A.m-2]"
],
}
)
variables.update(
self._get_standard_volumetric_current_density_variables(variables)
)

zero_av = pybamm.PrimaryBroadcast(0, "current collector")
zero = pybamm.FullBroadcast(0, "positive electrode", "current collector")
variables.update(
{
f"X-averaged positive electrode {self.reaction} "
"interfacial current density": zero_av,
f"Positive electrode {self.reaction} "
"interfacial current density": zero,
f"Positive electrode {self.reaction} "
"interfacial current density [A.m-2]": zero,
f"X-averaged positive electrode {self.reaction} "
"volumetric interfacial current density [A.m-2]": zero_av,
"volumetric interfacial current density": zero_av,
f"Positive electrode {self.reaction} "
"volumetric interfacial current density [A.m-3]": zero,
"volumetric interfacial current density": zero,
}
)

variables.update(
self._get_standard_volumetric_current_density_variables(variables)
)

return variables

def _get_standard_thickness_variables(self, L_inner, L_outer):
Expand Down Expand Up @@ -157,7 +162,7 @@ def _get_standard_concentration_variables(self, variables):
else:
# m * (mol/m4) = mol/m3 (n is a bulk quantity)
a = variables[
f"Negative electrode {self.phase_name}"
f"{Domain} electrode {self.phase_name}"
"surface area to volume ratio [m-1]"
]
L_to_n_inner = a / phase_param.V_bar_inner
Expand Down
8 changes: 4 additions & 4 deletions pybamm/parameters/lithium_ion_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ class LithiumIonParameters(BaseParameters):
A dictionary of options to be passed to the parameters. The options that
can be set are listed below.
* "half-cell": str
Can be "false" (default) for a standard battery or "true" for a
half-cell where the negative electrode is replaced with a lithium metal
counter electrode.
* "particle shape" : str, optional
Sets the model shape of the electrode particles. This is used to
calculate the surface area to volume ratio. Can be "spherical"
(default). TODO: implement "cylindrical" and "platelet".
* "working electrode": str
Which electrode(s) intercalates and which is counter. If "both"
(default), the model is a standard battery. Otherwise can be "negative"
or "positive" to indicate a half-cell model.
"""

Expand Down
60 changes: 29 additions & 31 deletions pybamm/parameters/size_distribution_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def get_size_distribution_parameters(
R_min_p=None,
R_max_n=None,
R_max_p=None,
electrode="both",
halfcell="false",
):
"""
A convenience method to add standard area-weighted particle-size distribution
Expand Down Expand Up @@ -60,7 +60,7 @@ def get_size_distribution_parameters(
"positive" to indicate a half-cell model, in which case size distribution
parameters are only added for a single electrode.
"""
if electrode in ["both", "negative"]:
if halfcell == "false":
# Radii from given parameter set
R_n_typ = param["Negative particle radius [m]"]

Expand Down Expand Up @@ -89,35 +89,33 @@ def f_a_dist_n(R):
},
check_already_exists=False,
)
if electrode in ["both", "positive"]:
# Radii from given parameter set
R_p_typ = param["Positive particle radius [m]"]

# Set the mean particle radii
R_p_av = R_p_av or R_p_typ

# Minimum radii
R_min_p = R_min_p or np.max([0, 1 - sd_p * 5])

# Max radii
R_max_p = R_max_p or (1 + sd_p * 5)

# Area-weighted particle-size distribution
def f_a_dist_p(R):
return lognormal(R, R_p_av, sd_p * R_p_av)

param.update(
{
"Positive area-weighted mean particle radius [m]": R_p_av,
"Positive area-weighted particle-size "
+ "standard deviation [m]": sd_p * R_p_av,
"Positive minimum particle radius [m]": R_min_p * R_p_av,
"Positive maximum particle radius [m]": R_max_p * R_p_av,
"Positive area-weighted "
+ "particle-size distribution [m-1]": f_a_dist_p,
},
check_already_exists=False,
)
# Radii from given parameter set
R_p_typ = param["Positive particle radius [m]"]

# Set the mean particle radii
R_p_av = R_p_av or R_p_typ

# Minimum radii
R_min_p = R_min_p or np.max([0, 1 - sd_p * 5])

# Max radii
R_max_p = R_max_p or (1 + sd_p * 5)

# Area-weighted particle-size distribution
def f_a_dist_p(R):
return lognormal(R, R_p_av, sd_p * R_p_av)

param.update(
{
"Positive area-weighted mean particle radius [m]": R_p_av,
"Positive area-weighted particle-size "
+ "standard deviation [m]": sd_p * R_p_av,
"Positive minimum particle radius [m]": R_min_p * R_p_av,
"Positive maximum particle radius [m]": R_max_p * R_p_av,
"Positive area-weighted " + "particle-size distribution [m-1]": f_a_dist_p,
},
check_already_exists=False,
)
return param


Expand Down
2 changes: 1 addition & 1 deletion pybamm/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ def _get_esoh_solver(self, calc_esoh):
calc_esoh is False
or isinstance(self.model, pybamm.lead_acid.BaseModel)
or isinstance(self.model, pybamm.equivalent_circuit.Thevenin)
or self.model.options["working electrode"] != "both"
or self.model.options["half-cell"] == "true"
):
return None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class BaseIntegrationTestLithiumIonHalfCell:
def run_basic_processing_test(self, options, **kwargs):
options["working electrode"] = "positive"
options["half-cell"] = "true"
model = self.model(options)
modeltest = tests.StandardModelTest(model, **kwargs)
modeltest.test_all(skip_output_tests=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class TestBasicHalfCellModels(TestCase):
def test_runs_Xu2019(self):
options = {"working electrode": "positive"}
options = {"half-cell": "true"}
model = pybamm.lithium_ion.BasicDFNHalfCell(options=options)

# create geometry
Expand Down Expand Up @@ -40,7 +40,7 @@ def test_runs_Xu2019(self):

def test_runs_OKane2022(self):
# load model
options = {"working electrode": "positive"}
options = {"half-cell": "true"}
model = pybamm.lithium_ion.BasicDFNHalfCell(options=options)

# create geometry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ def test_run_experiment_half_cell(self):
experiment = pybamm.Experiment(
[("Discharge at C/20 until 3.5V", "Charge at 1C until 3.8 V")]
)
model = pybamm.lithium_ion.SPM({"working electrode": "positive"})
model = pybamm.lithium_ion.SPM({"half-cell": "true"})
sim = pybamm.Simulation(
model,
experiment=experiment,
Expand Down
Loading

0 comments on commit cf53ff1

Please sign in to comment.