Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marcus Hush chidsey kinetics #1858

Merged
merged 8 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features

- Added new kinetics models for asymmetric Butler-Volmer, linear kinetics, and Marcus-Hush-Chidsey ([#1858](https://github.com/pybamm-team/PyBaMM/pull/1858))
- Experiments can be set to terminate when a voltage is reached (across all steps) ([#1832](https://github.com/pybamm-team/PyBaMM/pull/1832))
- Added cylindrical geometry and finite volume method ([#1824](https://github.com/pybamm-team/PyBaMM/pull/1824))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Diffusion-limited
=================

.. autoclass:: pybamm.interface.DiffusionLimited
.. autoclass:: pybamm.kinetics.DiffusionLimited
:members:
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
First-order Kinetics
====================

.. autoclass:: pybamm.interface.FirstOrderKinetics
.. autoclass:: pybamm.kinetics.FirstOrderKinetics
:members:

.. autoclass:: pybamm.interface.InverseFirstOrderKinetics
.. autoclass:: pybamm.kinetics.InverseFirstOrderKinetics
:members:
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Inverse Butler-Volmer
=====================

.. autoclass:: pybamm.interface.inverse_kinetics.InverseButlerVolmer
.. autoclass:: pybamm.kinetics.InverseButlerVolmer
:members:
20 changes: 16 additions & 4 deletions docs/source/models/submodels/interface/kinetics.rst
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
Kinetics
========

.. autoclass:: pybamm.interface.BaseKinetics
.. autoclass:: pybamm.kinetics.BaseKinetics
:members:

.. autoclass:: pybamm.interface.ButlerVolmer
.. autoclass:: pybamm.kinetics.SymmetricButlerVolmer
:members:

.. autoclass:: pybamm.interface.NoReaction
.. autoclass:: pybamm.kinetics.AsymmetricButlerVolmer
:members:

.. autoclass:: pybamm.interface.ForwardTafel
.. autoclass:: pybamm.kinetics.Linear
:members:

.. autoclass:: pybamm.kinetics.Marcus
:members:

.. autoclass:: pybamm.kinetics.MarcusHushChidsey
:members:

.. autoclass:: pybamm.kinetics.NoReaction
:members:

.. autoclass:: pybamm.kinetics.ForwardTafel
:members:

.. .. autoclass:: pybamm.interface.BackwardTafel
Expand Down
8 changes: 4 additions & 4 deletions examples/notebooks/models/using-submodels.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -428,22 +428,22 @@
"source": [
"model.submodels[\n",
" \"negative interface\"\n",
"] = pybamm.interface.InverseButlerVolmer(\n",
"] = pybamm.kinetics.InverseButlerVolmer(\n",
" model.param, \"Negative\", \"lithium-ion main\", options=model.options\n",
")\n",
"model.submodels[\n",
" \"positive interface\"\n",
"] = pybamm.interface.InverseButlerVolmer(\n",
"] = pybamm.kinetics.InverseButlerVolmer(\n",
" model.param, \"Positive\", \"lithium-ion main\", options=model.options\n",
")\n",
"model.submodels[\n",
" \"negative interface current\"\n",
"] = pybamm.interface.CurrentForInverseButlerVolmer(\n",
"] = pybamm.kinetics.CurrentForInverseButlerVolmer(\n",
" model.param, \"Negative\", \"lithium-ion main\"\n",
")\n",
"model.submodels[\n",
" \"positive interface current\"\n",
"] = pybamm.interface.CurrentForInverseButlerVolmer(\n",
"] = pybamm.kinetics.CurrentForInverseButlerVolmer(\n",
" model.param, \"Positive\", \"lithium-ion main\"\n",
")\n",
"model.submodels[\"negative interface utilisation\"] = pybamm.interface_utilisation.Full(\n",
Expand Down
40 changes: 40 additions & 0 deletions examples/scripts/compare_intercalation_kinetics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#
# Compare different models for intercalation kinetics.
#
import pybamm

pybamm.set_logging_level("INFO")

# load models
kinetics = [
"symmetric Butler-Volmer",
"asymmetric Butler-Volmer",
"linear",
"Marcus-Hush-Chidsey",
]

extra_parameters = [
{},
{
"Negative electrode Butler-Volmer transfer coefficient": 0.6,
"Positive electrode Butler-Volmer transfer coefficient": 0.6,
},
{},
{
"Negative electrode reorganization energy [eV]": 0.35,
"Positive electrode reorganization energy [eV]": 0.35,
"Positive electrode exchange-current density [A.m-2]": 5,
},
]
# create and run simulations
sims = []
for k, p in zip(kinetics, extra_parameters):
model = pybamm.lithium_ion.DFN({"intercalation kinetics": k}, name=k)
param = model.default_parameter_values
param.update(p, check_already_exists=False)
sim = pybamm.Simulation(model, parameter_values=param)
sim.solve([0, 3600])
sims.append(sim)

# plot
pybamm.dynamic_plot(sims)
8 changes: 4 additions & 4 deletions examples/scripts/custom_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
model.param, "Positive", "uniform profile", options=model.options
)
model.submodels["positive particle"] = particle_p
model.submodels["negative interface"] = pybamm.interface.InverseButlerVolmer(
model.submodels["negative interface"] = pybamm.kinetics.InverseButlerVolmer(
model.param, "Negative", "lithium-ion main", options=model.options
)
model.submodels["positive interface"] = pybamm.interface.InverseButlerVolmer(
model.submodels["positive interface"] = pybamm.kinetics.InverseButlerVolmer(
model.param, "Positive", "lithium-ion main", options=model.options
)
model.submodels["negative interface utilisation"] = pybamm.interface_utilisation.Full(
Expand All @@ -51,12 +51,12 @@
)
model.submodels[
"negative interface current"
] = pybamm.interface.CurrentForInverseButlerVolmer(
] = pybamm.kinetics.CurrentForInverseButlerVolmer(
model.param, "Negative", "lithium-ion main"
)
model.submodels[
"positive interface current"
] = pybamm.interface.CurrentForInverseButlerVolmer(
] = pybamm.kinetics.CurrentForInverseButlerVolmer(
model.param, "Positive", "lithium-ion main"
)
model.submodels[
Expand Down
11 changes: 11 additions & 0 deletions pybamm/CITATIONS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,17 @@
doi = {10.1016/j.electacta.2020.135862},
}

@article{Sripad2020,
title={Kinetics of lithium electrodeposition and stripping},
author={Sripad, Shashank and Korff, Daniel and DeCaluwe, Steven C and Viswanathan, Venkatasubramanian},
journal={The Journal of Chemical Physics},
volume={153},
number={19},
pages={194701},
year={2020},
publisher={AIP Publishing LLC}
}

@article{Subramanian2005,
title = {Efficient macro-micro scale coupled modeling of batteries},
author = {Subramanian, Venkat R. and Diwakar, Vinten D. and Tapriyal, Deepak},
Expand Down
1 change: 1 addition & 0 deletions pybamm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def version(formatted=False):
tortuosity,
particle_mechanics,
)
from .models.submodels.interface import kinetics
from .models.submodels.interface import sei
from .models.submodels.interface import lithium_plating
from .models.submodels.interface import interface_utilisation
Expand Down
35 changes: 35 additions & 0 deletions pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class BatteryModelOptions(pybamm.FuzzyDict):
Whether to include hydrolysis in the model. Only implemented for
lead-acid models. Can be "false" (default) or "true". If "true", then
"surface form" cannot be 'false'.
* "intercalation kinetics" : str
Model for intercalation kinetics. Can be "symmetric Butler-Volmer"
(default), "asymmetric Butler-Volmer", "linear", "Marcus", or
"Marcus-Hush-Chidsey" (which uses the asymptotic form from Zeng 2014).
* "interface utilisation": str
Can be "full" (default), "constant", or "current-driven".
* "lithium plating" : str
Expand Down Expand Up @@ -160,6 +164,13 @@ def __init__(self, extra_options):
"integrated",
],
"hydrolysis": ["false", "true"],
"intercalation kinetics": [
"symmetric Butler-Volmer",
"asymmetric Butler-Volmer",
"linear",
"Marcus",
"Marcus-Hush-Chidsey",
],
"interface utilisation": ["full", "constant", "current-driven"],
"lithium plating": ["none", "reversible", "irreversible"],
"lithium plating porosity change": ["false", "true"],
Expand Down Expand Up @@ -776,6 +787,30 @@ def summary_variables(self, value):
def set_summary_variables(self):
self._summary_variables = []

@property
def intercalation_kinetics(self):
if self.options["intercalation kinetics"] == "symmetric Butler-Volmer":
return pybamm.kinetics.SymmetricButlerVolmer
elif self.options["intercalation kinetics"] == "asymmetric Butler-Volmer":
return pybamm.kinetics.AsymmetricButlerVolmer
elif self.options["intercalation kinetics"] == "linear":
return pybamm.kinetics.Linear
elif self.options["intercalation kinetics"] == "Marcus":
return pybamm.kinetics.Marcus
elif self.options["intercalation kinetics"] == "Marcus-Hush-Chidsey":
return pybamm.kinetics.MarcusHushChidsey

@property
def inverse_intercalation_kinetics(self):
if self.options["intercalation kinetics"] == "symmetric Butler-Volmer":
return pybamm.kinetics.InverseButlerVolmer
else:
raise pybamm.OptionError(
"Inverse kinetics are only implemented for symmetric Butler-Volmer. "
"Use option {'surface form': 'algebraic'} to use forward kinetics "
"instead."
)

def set_external_circuit_submodel(self):
"""
Define how the external circuit defines the boundary conditions for the model,
Expand Down
16 changes: 8 additions & 8 deletions pybamm/models/full_battery_models/lead_acid/full.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, options=None, name="Full model", build=True):
super().__init__(options, name)

self.set_external_circuit_submodel()
self.set_interfacial_submodel()
self.set_intercalation_kinetics_submodel()
self.set_interface_utilisation_submodel()
self.set_porosity_submodel()
self.set_active_material_submodel()
Expand Down Expand Up @@ -80,11 +80,11 @@ def set_convection_submodel(self):
"through-cell convection"
] = pybamm.convection.through_cell.Full(self.param)

def set_interfacial_submodel(self):
self.submodels["negative interface"] = pybamm.interface.ButlerVolmer(
def set_intercalation_kinetics_submodel(self):
self.submodels["negative interface"] = self.intercalation_kinetics(
self.param, "Negative", "lead-acid main", self.options
)
self.submodels["positive interface"] = pybamm.interface.ButlerVolmer(
self.submodels["positive interface"] = self.intercalation_kinetics(
self.param, "Positive", "lead-acid main", self.options
)

Expand Down Expand Up @@ -127,21 +127,21 @@ def set_side_reaction_submodels(self):
self.submodels["oxygen diffusion"] = pybamm.oxygen_diffusion.Full(
self.param
)
self.submodels["positive oxygen interface"] = pybamm.interface.ForwardTafel(
self.submodels["positive oxygen interface"] = pybamm.kinetics.ForwardTafel(
self.param, "Positive", "lead-acid oxygen", self.options
)
self.submodels[
"negative oxygen interface"
] = pybamm.interface.DiffusionLimited(
] = pybamm.kinetics.DiffusionLimited(
self.param, "Negative", "lead-acid oxygen", order="full"
)
else:
self.submodels["oxygen diffusion"] = pybamm.oxygen_diffusion.NoOxygen(
self.param
)
self.submodels["positive oxygen interface"] = pybamm.interface.NoReaction(
self.submodels["positive oxygen interface"] = pybamm.kinetics.NoReaction(
self.param, "Positive", "lead-acid oxygen"
)
self.submodels["negative oxygen interface"] = pybamm.interface.NoReaction(
self.submodels["negative oxygen interface"] = pybamm.kinetics.NoReaction(
self.param, "Negative", "lead-acid oxygen"
)
18 changes: 9 additions & 9 deletions pybamm/models/full_battery_models/lead_acid/higher_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ def set_leading_order_model(self):
def set_average_interfacial_submodel(self):
self.submodels[
"x-averaged negative interface"
] = pybamm.interface.InverseFirstOrderKinetics(
] = pybamm.kinetics.InverseFirstOrderKinetics(
self.param, "Negative", self.leading_order_reaction_submodels["Negative"]
)
self.submodels[
"x-averaged positive interface"
] = pybamm.interface.InverseFirstOrderKinetics(
] = pybamm.kinetics.InverseFirstOrderKinetics(
self.param, "Positive", self.leading_order_reaction_submodels["Positive"]
)

Expand All @@ -152,17 +152,17 @@ def set_full_interface_submodel(self):
densities
"""
# Main reaction
self.submodels["negative interface"] = pybamm.interface.FirstOrderKinetics(
self.submodels["negative interface"] = pybamm.kinetics.FirstOrderKinetics(
self.param,
"Negative",
pybamm.interface.ButlerVolmer(
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "Negative", "lead-acid main", self.options
),
)
self.submodels["positive interface"] = pybamm.interface.FirstOrderKinetics(
self.submodels["positive interface"] = pybamm.kinetics.FirstOrderKinetics(
self.param,
"Positive",
pybamm.interface.ButlerVolmer(
pybamm.kinetics.SymmetricButlerVolmer(
self.param, "Positive", "lead-acid main", self.options
),
)
Expand All @@ -171,16 +171,16 @@ def set_full_interface_submodel(self):
if self.options["hydrolysis"] == "true":
self.submodels[
"positive oxygen interface"
] = pybamm.interface.FirstOrderKinetics(
] = pybamm.kinetics.FirstOrderKinetics(
self.param,
"Positive",
pybamm.interface.ForwardTafel(
pybamm.kinetics.ForwardTafel(
self.param, "Positive", "lead-acid oxygen", self.options
),
)
self.submodels[
"negative oxygen interface"
] = pybamm.interface.DiffusionLimited(
] = pybamm.kinetics.DiffusionLimited(
self.param, "Negative", "lead-acid oxygen", order="composite"
)

Expand Down
Loading