Skip to content

Commit

Permalink
Merge pull request pybamm-team#3919 from DrSOKane/composite-plating
Browse files Browse the repository at this point in the history
Lithium plating upgrades
  • Loading branch information
valentinsulzer authored May 2, 2024
2 parents 1df87ec + 4e6b16f commit 33371b0
Show file tree
Hide file tree
Showing 14 changed files with 433 additions and 137 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- Added `plot_thermal_components` to plot the contributions to the total heat generation in a battery ([#4021](https://github.com/pybamm-team/PyBaMM/pull/4021))
- Added functions for normal probability density function (`pybamm.normal_pdf`) and cumulative distribution function (`pybamm.normal_cdf`) ([#3999](https://github.com/pybamm-team/PyBaMM/pull/3999))
- Updates multiprocess `Pool` in `BaseSolver.solve()` to be constructed with context `fork`. Adds small example for multiprocess inputs. ([#3974](https://github.com/pybamm-team/PyBaMM/pull/3974))
- Lithium plating now works on composite electrodes ([#3919](https://github.com/pybamm-team/PyBaMM/pull/3919))
- Added lithium plating parameters to `Ecker2015` and `Ecker2015_graphite_halfcell` parameter sets ([#3919](https://github.com/pybamm-team/PyBaMM/pull/3919))
- Added custom experiment steps ([#3835](https://github.com/pybamm-team/PyBaMM/pull/3835))
- Added support for macOS arm64 (M-series) platforms. ([#3789](https://github.com/pybamm-team/PyBaMM/pull/3789))
- Added the ability to specify a custom solver tolerance in `get_initial_stoichiometries` and related functions ([#3714](https://github.com/pybamm-team/PyBaMM/pull/3714))
Expand All @@ -19,6 +21,7 @@
- Fixed a bug where independent variables were removed from models even if they appeared in events ([#4019](https://github.com/pybamm-team/PyBaMM/pull/4019))
- Fix bug with upwind and downwind schemes producing the wrong discretised system ([#3979](https://github.com/pybamm-team/PyBaMM/pull/3979))
- Allow evaluation of an `Interpolant` object with a number ([#3932](https://github.com/pybamm-team/PyBaMM/pull/3932))
- Added scale to dead lithium variable ([#3919](https://github.com/pybamm-team/PyBaMM/pull/3919))
- `plot_voltage_components` now works even if the time does not start at 0 ([#3915](https://github.com/pybamm-team/PyBaMM/pull/3915))
- Fixed bug where separator porosity was used in calculation instead of transport efficiency ([#3905](https://github.com/pybamm-team/PyBaMM/pull/3905))
- Initial voltage can now match upper or lower cut-offs exactly ([#3842](https://github.com/pybamm-team/PyBaMM/pull/3842))
Expand Down
104 changes: 104 additions & 0 deletions pybamm/input/parameters/lithium_ion/Ecker2015.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,97 @@ def nco_electrolyte_exchange_current_density_Ecker2015(c_e, c_s_surf, c_s_max, T
return m_ref * arrhenius * c_e**0.5 * c_s_surf**0.5 * (c_s_max - c_s_surf) ** 0.5


def plating_exchange_current_density_OKane2020(c_e, c_Li, T):
"""
Exchange-current density for Li plating reaction [A.m-2].
References
----------
.. [1] O’Kane, Simon EJ, Ian D. Campbell, Mohamed WJ Marzook, Gregory J. Offer, and
Monica Marinescu. "Physical origin of the differential voltage minimum associated
with lithium plating in Li-ion batteries." Journal of The Electrochemical Society
167, no. 9 (2020): 090540.
Parameters
----------
c_e : :class:`pybamm.Symbol`
Electrolyte concentration [mol.m-3]
c_Li : :class:`pybamm.Symbol`
Plated lithium concentration [mol.m-3]
T : :class:`pybamm.Symbol`
Temperature [K]
Returns
-------
:class:`pybamm.Symbol`
Exchange-current density [A.m-2]
"""

k_plating = pybamm.Parameter("Lithium plating kinetic rate constant [m.s-1]")

return pybamm.constants.F * k_plating * c_e


def stripping_exchange_current_density_OKane2020(c_e, c_Li, T):
"""
Exchange-current density for Li stripping reaction [A.m-2].
References
----------
.. [1] O’Kane, Simon EJ, Ian D. Campbell, Mohamed WJ Marzook, Gregory J. Offer, and
Monica Marinescu. "Physical origin of the differential voltage minimum associated
with lithium plating in Li-ion batteries." Journal of The Electrochemical Society
167, no. 9 (2020): 090540.
Parameters
----------
c_e : :class:`pybamm.Symbol`
Electrolyte concentration [mol.m-3]
c_Li : :class:`pybamm.Symbol`
Plated lithium concentration [mol.m-3]
T : :class:`pybamm.Symbol`
Temperature [K]
Returns
-------
:class:`pybamm.Symbol`
Exchange-current density [A.m-2]
"""

k_plating = pybamm.Parameter("Lithium plating kinetic rate constant [m.s-1]")

return pybamm.constants.F * k_plating * c_Li


def SEI_limited_dead_lithium_OKane2022(L_sei):
"""
Decay rate for dead lithium formation [s-1].
References
----------
.. [1] Simon E. J. O'Kane, Weilong Ai, Ganesh Madabattula, Diega Alonso-Alvarez,
Robert Timms, Valentin Sulzer, Jaqueline Sophie Edge, Billy Wu, Gregory J. Offer
and Monica Marinescu. "Lithium-ion battery degradation: how to model it."
Physical Chemistry: Chemical Physics 24, no. 13 (2022): 7909-7922.
Parameters
----------
L_sei : :class:`pybamm.Symbol`
Total SEI thickness [m]
Returns
-------
:class:`pybamm.Symbol`
Dead lithium decay rate [s-1]
"""

gamma_0 = pybamm.Parameter("Dead lithium decay constant [s-1]")
L_inner_0 = pybamm.Parameter("Initial inner SEI thickness [m]")
L_outer_0 = pybamm.Parameter("Initial outer SEI thickness [m]")
L_sei_0 = L_inner_0 + L_outer_0

gamma = gamma_0 * L_sei_0 / L_sei

return gamma


def electrolyte_diffusivity_Ecker2015(c_e, T):
"""
Diffusivity of LiPF6 in EC:DMC as a function of ion concentration [1, 2, 3].
Expand Down Expand Up @@ -409,6 +500,18 @@ def get_parameter_values():

return {
"chemistry": "lithium_ion",
# lithium plating
"Lithium metal partial molar volume [m3.mol-1]": 1.3e-05,
"Lithium plating kinetic rate constant [m.s-1]": 1e-10,
"Exchange-current density for plating [A.m-2]"
"": plating_exchange_current_density_OKane2020,
"Exchange-current density for stripping [A.m-2]"
"": stripping_exchange_current_density_OKane2020,
"Initial plated lithium concentration [mol.m-3]": 0.0,
"Typical plated lithium concentration [mol.m-3]": 1000.0,
"Lithium plating transfer coefficient": 0.5,
"Dead lithium decay constant [s-1]": 1e-06,
"Dead lithium decay rate [s-1]": SEI_limited_dead_lithium_OKane2022,
# sei
"Ratio of lithium moles to SEI moles": 2.0,
"Inner SEI reaction proportion": 0.5,
Expand Down Expand Up @@ -530,5 +633,6 @@ def get_parameter_values():
"Zhao2018",
"Hales2019",
"Richardson2020",
"OKane2020",
],
}
103 changes: 103 additions & 0 deletions pybamm/input/parameters/lithium_ion/Ecker2015_graphite_halfcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,97 @@ def graphite_electrolyte_exchange_current_density_Ecker2015(c_e, c_s_surf, c_s_m
return m_ref * arrhenius * c_e**0.5 * c_s_surf**0.5 * (c_s_max - c_s_surf) ** 0.5


def plating_exchange_current_density_OKane2020(c_e, c_Li, T):
"""
Exchange-current density for Li plating reaction [A.m-2].
References
----------
.. [1] O’Kane, Simon EJ, Ian D. Campbell, Mohamed WJ Marzook, Gregory J. Offer, and
Monica Marinescu. "Physical origin of the differential voltage minimum associated
with lithium plating in Li-ion batteries." Journal of The Electrochemical Society
167, no. 9 (2020): 090540.
Parameters
----------
c_e : :class:`pybamm.Symbol`
Electrolyte concentration [mol.m-3]
c_Li : :class:`pybamm.Symbol`
Plated lithium concentration [mol.m-3]
T : :class:`pybamm.Symbol`
Temperature [K]
Returns
-------
:class:`pybamm.Symbol`
Exchange-current density [A.m-2]
"""

k_plating = pybamm.Parameter("Lithium plating kinetic rate constant [m.s-1]")

return pybamm.constants.F * k_plating * c_e


def stripping_exchange_current_density_OKane2020(c_e, c_Li, T):
"""
Exchange-current density for Li stripping reaction [A.m-2].
References
----------
.. [1] O’Kane, Simon EJ, Ian D. Campbell, Mohamed WJ Marzook, Gregory J. Offer, and
Monica Marinescu. "Physical origin of the differential voltage minimum associated
with lithium plating in Li-ion batteries." Journal of The Electrochemical Society
167, no. 9 (2020): 090540.
Parameters
----------
c_e : :class:`pybamm.Symbol`
Electrolyte concentration [mol.m-3]
c_Li : :class:`pybamm.Symbol`
Plated lithium concentration [mol.m-3]
T : :class:`pybamm.Symbol`
Temperature [K]
Returns
-------
:class:`pybamm.Symbol`
Exchange-current density [A.m-2]
"""

k_plating = pybamm.Parameter("Lithium plating kinetic rate constant [m.s-1]")

return pybamm.constants.F * k_plating * c_Li


def SEI_limited_dead_lithium_OKane2022(L_sei):
"""
Decay rate for dead lithium formation [s-1].
References
----------
.. [1] Simon E. J. O'Kane, Weilong Ai, Ganesh Madabattula, Diega Alonso-Alvarez,
Robert Timms, Valentin Sulzer, Jaqueline Sophie Edge, Billy Wu, Gregory J. Offer
and Monica Marinescu. "Lithium-ion battery degradation: how to model it."
Physical Chemistry: Chemical Physics 24, no. 13 (2022): 7909-7922.
Parameters
----------
L_sei : :class:`pybamm.Symbol`
Total SEI thickness [m]
Returns
-------
:class:`pybamm.Symbol`
Dead lithium decay rate [s-1]
"""

gamma_0 = pybamm.Parameter("Dead lithium decay constant [s-1]")
L_inner_0 = pybamm.Parameter("Initial inner SEI thickness [m]")
L_outer_0 = pybamm.Parameter("Initial outer SEI thickness [m]")
L_sei_0 = L_inner_0 + L_outer_0

gamma = gamma_0 * L_sei_0 / L_sei

return gamma


def electrolyte_diffusivity_Ecker2015(c_e, T):
"""
Diffusivity of LiPF6 in EC:DMC as a function of ion concentration [1, 2, 3].
Expand Down Expand Up @@ -332,6 +423,17 @@ def get_parameter_values():

return {
"chemistry": "lithium_ion",
# lithium plating
"Lithium plating kinetic rate constant [m.s-1]": 1e-10,
"Exchange-current density for plating [A.m-2]"
"": plating_exchange_current_density_OKane2020,
"Exchange-current density for stripping [A.m-2]"
"": stripping_exchange_current_density_OKane2020,
"Initial plated lithium concentration [mol.m-3]": 0.0,
"Typical plated lithium concentration [mol.m-3]": 1000.0,
"Lithium plating transfer coefficient": 0.5,
"Dead lithium decay constant [s-1]": 1e-06,
"Dead lithium decay rate [s-1]": SEI_limited_dead_lithium_OKane2022,
# sei
"Ratio of lithium moles to SEI moles": 2.0,
"Inner SEI reaction proportion": 0.5,
Expand Down Expand Up @@ -435,5 +537,6 @@ def get_parameter_values():
"Hales2019",
"Xu2019",
"Richardson2020",
"OKane2020",
],
}
4 changes: 1 addition & 3 deletions pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,14 +609,12 @@ def __init__(self, extra_options):
and options["particle"] == "Fickian diffusion"
and options["particle mechanics"] == "none"
and options["loss of active material"] == "none"
and options["lithium plating"] == "none"
):
raise pybamm.OptionError(
"If there are multiple particle phases: 'surface form' cannot be "
"'false', 'particle size' must be 'single', 'particle' must be "
"'Fickian diffusion'. Also the following must "
"be 'none': 'particle mechanics', "
"'loss of active material', 'lithium plating'"
"be 'none': 'particle mechanics', 'loss of active material'"
)

# Check options are valid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,22 @@ def set_lithium_plating_submodel(self):
if domain != "separator":
domain = domain.split()[0].lower()
lithium_plating_opt = getattr(self.options, domain)["lithium plating"]
if lithium_plating_opt == "none":
self.submodels[f"{domain} lithium plating"] = (
pybamm.lithium_plating.NoPlating(
self.param, domain, self.options
phases = self.options.phases[domain]
for phase in phases:
if lithium_plating_opt == "none":
submodel = pybamm.lithium_plating.NoPlating(
self.param, domain, self.options, phase
)
)
else:
x_average = self.options["x-average side reactions"] == "true"
self.submodels[f"{domain} lithium plating"] = (
pybamm.lithium_plating.Plating(
self.param, domain, x_average, self.options
else:
x_average = self.options["x-average side reactions"] == "true"
submodel = pybamm.lithium_plating.Plating(
self.param, domain, x_average, self.options, phase
)
self.submodels[f"{domain} {phase} lithium plating"] = submodel
if len(phases) > 1:
self.submodels[f"{domain} total lithium plating"] = (
pybamm.lithium_plating.TotalLithiumPlating(
self.param, domain, self.options
)
)

Expand Down
1 change: 1 addition & 0 deletions pybamm/models/submodels/interface/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(self, param, domain, reaction, options, phase="primary"):
if reaction in [
"lithium-ion main",
"lithium metal plating",
"lithium plating",
"SEI",
"SEI on cracks",
]:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .base_plating import BasePlating
from .no_plating import NoPlating
from .plating import Plating
from .total_lithium_plating import TotalLithiumPlating
Loading

0 comments on commit 33371b0

Please sign in to comment.