Skip to content

Commit

Permalink
Merge pull request #1731 from pybamm-team/li-metal-spm
Browse files Browse the repository at this point in the history
Li metal spm
  • Loading branch information
valentinsulzer authored Nov 5, 2021
2 parents 93ead88 + bfd4df3 commit 7b748f8
Show file tree
Hide file tree
Showing 20 changed files with 564 additions and 310 deletions.
58 changes: 0 additions & 58 deletions examples/scripts/DFN_half_cell.py

This file was deleted.

26 changes: 26 additions & 0 deletions examples/scripts/compare_lithium_ion_half_cell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#
# Compare half-cell lithium-ion battery models
#
import pybamm

pybamm.set_logging_level("INFO")

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

chemistry = pybamm.parameter_sets.Xu2019
param = pybamm.ParameterValues(chemistry=chemistry)

# create and run simulations
sims = []
for model in models:
sim = pybamm.Simulation(model, parameter_values=param)
sim.solve([0, 3600])
sims.append(sim)

# plot
pybamm.dynamic_plot(sims)
2 changes: 1 addition & 1 deletion pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ def build_model(self):

# Massive hack for consistent delta_phi = phi_s - phi_e with SPMe
# This needs to be corrected
if isinstance(self, pybamm.lithium_ion.SPMe):
if isinstance(self, pybamm.lithium_ion.SPMe) and not self.half_cell:
for domain in ["Negative", "Positive"]:
phi_s = self.variables[domain + " electrode potential"]
phi_e = self.variables[domain + " electrolyte potential"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,42 @@ def set_porosity_submodel(self):
self.submodels["porosity"] = pybamm.porosity.ReactionDriven(
self.param, self.options, self.x_average
)

def set_li_metal_counter_electrode_submodels(self):
if self.options["SEI"] in ["none", "constant"]:
self.submodels[
"counter electrode potential"
] = pybamm.electrode.ohm.LithiumMetalExplicit(self.param, self.options)
self.submodels[
"counter electrode interface"
] = pybamm.interface.InverseButlerVolmer(
self.param, "Negative", "lithium metal plating", self.options
) # assuming symmetric reaction for now so we can take the inverse
self.submodels[
"counter electrode interface current"
] = pybamm.interface.CurrentForInverseButlerVolmerLithiumMetal(
self.param, "Negative", "lithium metal plating", self.options
)
else:
self.submodels[
"counter electrode potential"
] = pybamm.electrode.ohm.LithiumMetalSurfaceForm(self.param, self.options)
self.submodels[
"counter electrode interface"
] = pybamm.interface.ButlerVolmer(
self.param, "Negative", "lithium metal plating", self.options
)

# For half-cell models, remove negative electrode submodels
# that are not needed before building
# We do this whether the working electrode is 'positive' or 'negative' since
# the half-cell models are always defined assuming the positive electrode is
# the working electrode

# This should be done before `self.build_model`, which is the expensive part

# Models added specifically for the counter electrode have been labelled with
# "counter electrode" so as not to be caught by this check
self.submodels = {
k: v for k, v in self.submodels.items() if not k.startswith("negative")
}
50 changes: 3 additions & 47 deletions pybamm/models/full_battery_models/lithium_ion/dfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,9 @@ def __init__(self, options=None, name="Doyle-Fuller-Newman model", build=True):
self.set_sei_submodel()
self.set_lithium_plating_submodel()

# For half-cell models, remove negative electrode submodels
# that are not needed before building
# We do this whether the working electrode is 'positive' or 'negative' since
# the half-cell models are always defined assuming the positive electrode is
# the working electrode
# It's ok to only do this now since `build_model` is the expensive part
if self.options["working electrode"] != "both":
self.submodels = {
k: v for k, v in self.submodels.items() if not k.startswith("negative")
}
# Models added specifically for the counter electrode should be labelled with
# "counter electrode" so as not to be caught by this check
if self.half_cell:
# This also removes "negative electrode" submodels, so should be done last
self.set_li_metal_counter_electrode_submodels()

if build:
self.build_model()
Expand All @@ -87,27 +78,6 @@ def set_interfacial_submodel(self):
self.param, "Positive", "lithium-ion main", self.options
)

# Set the counter-electrode model for the half-cell model
# The negative electrode model will be ignored
if self.half_cell:
if self.options["SEI"] in ["none", "constant"]:
self.submodels[
"counter electrode interface"
] = pybamm.interface.InverseButlerVolmer(
self.param, "Negative", "lithium metal plating", self.options
) # assuming symmetric reaction for now so we can take the inverse
self.submodels[
"counter electrode interface current"
] = pybamm.interface.CurrentForInverseButlerVolmerLithiumMetal(
self.param, "Negative", "lithium metal plating", self.options
)
else:
self.submodels[
"counter electrode interface"
] = pybamm.interface.ButlerVolmer(
self.param, "Negative", "lithium metal plating", self.options
)

def set_particle_submodel(self):

if isinstance(self.options["particle"], str):
Expand Down Expand Up @@ -166,20 +136,6 @@ def set_solid_submodel(self):
self.submodels["negative electrode potential"] = submod_n
self.submodels["positive electrode potential"] = submod_p

# Set the counter-electrode model for the half-cell model
# The negative electrode model will be ignored
if self.half_cell:
if self.options["SEI"] in ["none", "constant"]:
self.submodels[
"counter electrode potential"
] = pybamm.electrode.ohm.LithiumMetalExplicit(self.param, self.options)
else:
self.submodels[
"counter electrode potential"
] = pybamm.electrode.ohm.LithiumMetalSurfaceForm(
self.param, self.options
)

def set_electrolyte_submodel(self):

surf_form = pybamm.electrolyte_conductivity.surface_potential_form
Expand Down
34 changes: 20 additions & 14 deletions pybamm/models/full_battery_models/lithium_ion/spm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,18 @@ def __init__(self, options=None, name="Single Particle Model", build=True):
self.set_interfacial_submodel()
self.set_other_reaction_submodels_to_zero()
self.set_particle_submodel()
self.set_negative_electrode_submodel()
self.set_solid_submodel()
self.set_electrolyte_submodel()
self.set_positive_electrode_submodel()
self.set_thermal_submodel()
self.set_current_collector_submodel()

self.set_sei_submodel()
self.set_lithium_plating_submodel()

if self.half_cell:
# This also removes "negative electrode" submodels, so should be done last
self.set_li_metal_counter_electrode_submodels()

if build:
self.build_model()

Expand All @@ -63,10 +66,10 @@ def set_convection_submodel(self):

self.submodels[
"through-cell convection"
] = pybamm.convection.through_cell.NoConvection(self.param)
] = pybamm.convection.through_cell.NoConvection(self.param, self.options)
self.submodels[
"transverse convection"
] = pybamm.convection.transverse.NoConvection(self.param)
] = pybamm.convection.transverse.NoConvection(self.param, self.options)

def set_interfacial_submodel(self):

Expand All @@ -80,12 +83,12 @@ def set_interfacial_submodel(self):
self.submodels[
"negative interface current"
] = pybamm.interface.CurrentForInverseButlerVolmer(
self.param, "Negative", "lithium-ion main"
self.param, "Negative", "lithium-ion main", self.options
)
self.submodels[
"positive interface current"
] = pybamm.interface.CurrentForInverseButlerVolmer(
self.param, "Positive", "lithium-ion main"
self.param, "Positive", "lithium-ion main", self.options
)
else:
self.submodels["negative interface"] = pybamm.interface.ButlerVolmer(
Expand Down Expand Up @@ -123,17 +126,18 @@ def set_particle_submodel(self):
self.param, domain, particle_side
)

def set_negative_electrode_submodel(self):
def set_solid_submodel(self):

self.submodels[
"negative electrode potential"
] = pybamm.electrode.ohm.LeadingOrder(self.param, "Negative")

def set_positive_electrode_submodel(self):

] = pybamm.electrode.ohm.LeadingOrder(
self.param, "Negative", options=self.options
)
self.submodels[
"positive electrode potential"
] = pybamm.electrode.ohm.LeadingOrder(self.param, "Positive")
] = pybamm.electrode.ohm.LeadingOrder(
self.param, "Positive", options=self.options
)

def set_electrolyte_submodel(self):

Expand All @@ -149,7 +153,9 @@ def set_electrolyte_submodel(self):
if self.options["surface form"] == "false":
self.submodels[
"leading-order electrolyte conductivity"
] = pybamm.electrolyte_conductivity.LeadingOrder(self.param)
] = pybamm.electrolyte_conductivity.LeadingOrder(
self.param, options=self.options
)

elif self.options["surface form"] == "differential":
for domain in ["Negative", "Separator", "Positive"]:
Expand All @@ -165,4 +171,4 @@ def set_electrolyte_submodel(self):

self.submodels[
"electrolyte diffusion"
] = pybamm.electrolyte_diffusion.ConstantConcentration(self.param)
] = pybamm.electrolyte_diffusion.ConstantConcentration(self.param, self.options)
Loading

0 comments on commit 7b748f8

Please sign in to comment.