Repository: pybamm-team/PyBaMM
Pull request #3919 (2024-03-22 11:47:40)

Lithium plating upgrades
# Description

- Lithium plating model now works on composite electrodes
- Added plating parameters to Ecker2015, Ecker2015_graphite_halfcell and Chen2020_composite parameter sets
- Fixed bug where the dead lithium concentration variable had no scale

## Type of change

Please add a line in the relevant section of [CHANGELOG.md](https://github.com/pybamm-team/PyBaMM/blob/develop/CHANGELOG.md) to document the change (include PR #) - note reverse order of PR #s. If necessary, also add to the list of breaking changes.

- [x] New feature (non-breaking change which adds functionality)
- [ ] Optimization (back-end change that speeds up the code)
- [x] Bug fix (non-breaking change which fixes an issue)

# Key checklist:

- [x] No style issues: `$ pre-commit run` (or `$ nox -s pre-commit`) (see [CONTRIBUTING.md](https://github.com/pybamm-team/PyBaMM/blob/develop/CONTRIBUTING.md#installing-and-using-pre-commit) for how to set this up to run automatically when committing locally, in just two lines of code)
- [x] All tests pass: `$ python run-tests.py --all` (or `$ nox -s tests`)
- [x] The documentation builds: `$ python run-tests.py --doctest` (or `$ nox -s doctests`)

You can run integration tests, unit tests, and doctests together at once, using `$ python run-tests.py --quick` (or `$ nox -s quick`).

## Further checks:

- [ ] Code is commented, particularly in hard-to-understand areas
- [ ] Tests added that prove fix is effective or that feature works



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a8d7d155d..1e439dcf9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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))
@@ -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))
diff --git a/pybamm/input/parameters/lithium_ion/Ecker2015.py b/pybamm/input/parameters/lithium_ion/Ecker2015.py
index fa9fd2dca..32cc63129 100644
--- a/pybamm/input/parameters/lithium_ion/Ecker2015.py
+++ b/pybamm/input/parameters/lithium_ion/Ecker2015.py
@@ -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].
@@ -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,
@@ -530,5 +633,6 @@ def get_parameter_values():
             "Zhao2018",
             "Hales2019",
             "Richardson2020",
+            "OKane2020",
         ],
     }
diff --git a/pybamm/input/parameters/lithium_ion/Ecker2015_graphite_halfcell.py b/pybamm/input/parameters/lithium_ion/Ecker2015_graphite_halfcell.py
index d878ff740..365bb6386 100644
--- a/pybamm/input/parameters/lithium_ion/Ecker2015_graphite_halfcell.py
+++ b/pybamm/input/parameters/lithium_ion/Ecker2015_graphite_halfcell.py
@@ -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].
@@ -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,
@@ -435,5 +537,6 @@ def get_parameter_values():
             "Hales2019",
             "Xu2019",
             "Richardson2020",
+            "OKane2020",
         ],
     }
diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py
index 7a29ad64c..335ac2665 100644
--- a/pybamm/models/full_battery_models/base_battery_model.py
+++ b/pybamm/models/full_battery_models/base_battery_model.py
@@ -609,14 +609,12 @@ class BatteryModelOptions(pybamm.FuzzyDict):
                 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
diff --git a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py
index d6f80b3cc..b7a8cfec7 100644
--- a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py
+++ b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py
@@ -331,17 +331,22 @@ class BaseModel(pybamm.BaseBatteryModel):
             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
                         )
                     )
 
diff --git a/pybamm/models/submodels/interface/base_interface.py b/pybamm/models/submodels/interface/base_interface.py
index b7e160ee2..ab9b80eae 100644
--- a/pybamm/models/submodels/interface/base_interface.py
+++ b/pybamm/models/submodels/interface/base_interface.py
@@ -38,6 +38,7 @@ class BaseInterface(pybamm.BaseSubModel):
         if reaction in [
             "lithium-ion main",
             "lithium metal plating",
+            "lithium plating",
             "SEI",
             "SEI on cracks",
         ]:
diff --git a/pybamm/models/submodels/interface/lithium_plating/__init__.py b/pybamm/models/submodels/interface/lithium_plating/__init__.py
index cea178158..1bb826294 100644
--- a/pybamm/models/submodels/interface/lithium_plating/__init__.py
+++ b/pybamm/models/submodels/interface/lithium_plating/__init__.py
@@ -1,3 +1,4 @@
 from .base_plating import BasePlating
 from .no_plating import NoPlating
 from .plating import Plating
+from .total_lithium_plating import TotalLithiumPlating
diff --git a/pybamm/models/submodels/interface/lithium_plating/base_plating.py b/pybamm/models/submodels/interface/lithium_plating/base_plating.py
index ebfbe4683..7d9a4bb2e 100644
--- a/pybamm/models/submodels/interface/lithium_plating/base_plating.py
+++ b/pybamm/models/submodels/interface/lithium_plating/base_plating.py
@@ -17,44 +17,30 @@ class BasePlating(BaseInterface):
         A dictionary of options to be passed to the model.
     """
 
-    def __init__(self, param, domain, options=None):
+    def __init__(self, param, domain, options=None, phase="primary"):
         reaction = "lithium plating"
-        super().__init__(param, domain, reaction, options=options)
+        super().__init__(param, domain, reaction, options=options, phase=phase)
 
     def get_coupled_variables(self, variables):
         # Update some common variables
         domain, Domain = self.domain_Domain
 
-        if self.options.electrode_types[domain] == "porous":
-            j_plating = variables[
-                f"{Domain} lithium plating interfacial current density [A.m-2]"
-            ]
-            j_plating_av = variables[
-                f"X-averaged {domain} lithium plating "
-                "interfacial current density [A.m-2]"
-            ]
-            particle_phases_option = getattr(self.options, domain)["particle phases"]
-            if particle_phases_option == "1":
-                a = variables[f"{Domain} electrode surface area to volume ratio [m-1]"]
-            else:
-                a = variables[
-                    f"{Domain} electrode primary surface area to volume ratio [m-1]"
-                ]
-            a_j_plating = a * j_plating
-            a_j_plating_av = pybamm.x_average(a_j_plating)
-
-            variables.update(
-                {
-                    f"{Domain} electrode lithium plating interfacial current "
-                    "density [A.m-2]": j_plating,
-                    f"X-averaged {domain} electrode lithium plating "
-                    "interfacial current density [A.m-2]": j_plating_av,
-                    f"{Domain} lithium plating volumetric "
-                    "interfacial current density [A.m-3]": a_j_plating,
-                    f"X-averaged {domain} lithium plating volumetric "
-                    "interfacial current density [A.m-3]": a_j_plating_av,
-                }
-            )
+        j_plating_av = variables[
+            f"X-averaged {domain} electrode {self.phase_name}lithium plating "
+            "interfacial current density [A.m-2]"
+        ]
+        j_plating = variables[
+            f"{Domain} electrode {self.phase_name}lithium plating "
+            "interfacial current density [A.m-2]"
+        ]
+        variables.update(
+            {
+                f"X-averaged {domain} electrode {self.phase_name}lithium plating "
+                "interfacial current density [A.m-2]": j_plating_av,
+                f"{Domain} electrode {self.phase_name}lithium plating "
+                "interfacial current density [A.m-2]": j_plating,
+            }
+        )
 
         variables.update(
             self._get_standard_volumetric_current_density_variables(variables)
@@ -75,7 +61,8 @@ class BasePlating(BaseInterface):
         variables : dict
             The variables which can be derived from the plated lithium thickness.
         """
-        param = self.param
+        phase_name = self.phase_name
+        phase_param = self.phase_param
         domain, Domain = self.domain_Domain
 
         # Set scales to one for the "no plating" model so that they are not required
@@ -84,40 +71,43 @@ class BasePlating(BaseInterface):
             c_to_L = 1
             L_k = 1
         elif domain == "negative":
-            c_to_L = param.V_bar_Li / param.n.prim.a_typ
-            L_k = param.n.L
+            c_to_L = self.param.V_bar_Li / phase_param.a_typ
+            L_k = self.param.n.L
         elif domain == "positive":
-            c_to_L = param.V_bar_Li / param.p.prim.a_typ
-            L_k = param.p.L
+            c_to_L = self.param.V_bar_Li / phase_param.a_typ
+            L_k = self.param.p.L
 
         c_plated_Li_av = pybamm.x_average(c_plated_Li)
         L_plated_Li = c_plated_Li * c_to_L  # plated Li thickness
         L_plated_Li_av = pybamm.x_average(L_plated_Li)
-        Q_plated_Li = c_plated_Li_av * L_k * param.L_y * param.L_z
+        Q_plated_Li = c_plated_Li_av * L_k * self.param.L_y * self.param.L_z
 
         c_dead_Li_av = pybamm.x_average(c_dead_Li)
         # dead Li "thickness", required by porosity submodel
         L_dead_Li = c_dead_Li * c_to_L
         L_dead_Li_av = pybamm.x_average(L_dead_Li)
-        Q_dead_Li = c_dead_Li_av * L_k * param.L_y * param.L_z
+        Q_dead_Li = c_dead_Li_av * L_k * self.param.L_y * self.param.L_z
 
         variables = {
-            f"{Domain} lithium plating concentration [mol.m-3]": c_plated_Li,
-            f"X-averaged {domain} lithium plating "
-            "concentration [mol.m-3]": c_plated_Li_av,
-            f"{Domain} dead lithium concentration [mol.m-3]": c_dead_Li,
-            f"X-averaged {domain} dead lithium concentration [mol.m-3]": c_dead_Li_av,
-            f"{Domain} lithium plating thickness [m]": L_plated_Li,
-            f"X-averaged {domain} lithium plating thickness [m]": L_plated_Li_av,
-            f"{Domain} dead lithium thickness [m]": L_dead_Li,
-            f"X-averaged {domain} dead lithium thickness [m]": L_dead_Li_av,
-            f"Loss of lithium to {domain} lithium plating " "[mol]": (
+            f"{Domain} {phase_name}lithium plating concentration "
+            "[mol.m-3]": c_plated_Li,
+            f"X-averaged {domain} {phase_name}lithium plating concentration "
+            "[mol.m-3]": c_plated_Li_av,
+            f"{Domain} {phase_name}dead lithium concentration [mol.m-3]": c_dead_Li,
+            f"X-averaged {domain} {phase_name}dead lithium concentration "
+            "[mol.m-3]": c_dead_Li_av,
+            f"{Domain} {phase_name}lithium plating thickness [m]": L_plated_Li,
+            f"X-averaged {domain} {phase_name} lithium plating thickness "
+            "[m]": L_plated_Li_av,
+            f"{Domain} {phase_name}dead lithium thickness [m]": L_dead_Li,
+            f"X-averaged {domain} {phase_name}dead lithium thickness [m]": L_dead_Li_av,
+            f"Loss of lithium to {domain} {phase_name}lithium plating " "[mol]": (
                 Q_plated_Li + Q_dead_Li
             ),
-            f"Loss of capacity to {domain} lithium plating " "[A.h]": (
+            f"Loss of capacity to {domain} {phase_name}lithium plating " "[A.h]": (
                 Q_plated_Li + Q_dead_Li
             )
-            * param.F
+            * self.param.F
             / 3600,
         }
 
@@ -140,9 +130,9 @@ class BasePlating(BaseInterface):
         j_stripping_av = pybamm.x_average(j_stripping)
 
         variables = {
-            f"{Domain} lithium plating interfacial current density "
-            "[A.m-2]": j_stripping,
-            f"X-averaged {domain} lithium plating "
+            f"{Domain} electrode {self.phase_name}lithium plating "
+            "interfacial current density [A.m-2]": j_stripping,
+            f"X-averaged {domain} electrode {self.phase_name}lithium plating "
             "interfacial current density [A.m-2]": j_stripping_av,
         }
 
diff --git a/pybamm/models/submodels/interface/lithium_plating/no_plating.py b/pybamm/models/submodels/interface/lithium_plating/no_plating.py
index 94697fdd8..ddc13cfb9 100644
--- a/pybamm/models/submodels/interface/lithium_plating/no_plating.py
+++ b/pybamm/models/submodels/interface/lithium_plating/no_plating.py
@@ -16,8 +16,8 @@ class NoPlating(BasePlating):
         A dictionary of options to be passed to the model.
     """
 
-    def __init__(self, param, domain, options=None):
-        super().__init__(param, domain, options=options)
+    def __init__(self, param, domain, options=None, phase="primary"):
+        super().__init__(param, domain, options=options, phase=phase)
 
     def get_fundamental_variables(self):
         zero = pybamm.FullBroadcast(
diff --git a/pybamm/models/submodels/interface/lithium_plating/plating.py b/pybamm/models/submodels/interface/lithium_plating/plating.py
index 9f4de08d2..cd130ab48 100644
--- a/pybamm/models/submodels/interface/lithium_plating/plating.py
+++ b/pybamm/models/submodels/interface/lithium_plating/plating.py
@@ -19,37 +19,42 @@ class Plating(BasePlating):
         A dictionary of options to be passed to the model.
     """
 
-    def __init__(self, param, domain, x_average, options):
-        super().__init__(param, domain, options=options)
+    def __init__(self, param, domain, x_average, options, phase="primary"):
+        super().__init__(param, domain, options=options, phase=phase)
         self.x_average = x_average
         pybamm.citations.register("OKane2020")
         pybamm.citations.register("OKane2022")
 
     def get_fundamental_variables(self):
         domain, Domain = self.domain_Domain
+        scale = self.phase_param.c_Li_typ
         if self.x_average is True:
             c_plated_Li_av = pybamm.Variable(
-                f"X-averaged {domain} lithium plating concentration [mol.m-3]",
+                f"X-averaged {domain} {self.phase_name}lithium plating concentration "
+                "[mol.m-3]",
                 domain="current collector",
-                scale=self.param.c_Li_typ,
+                scale=scale,
             )
             c_plated_Li = pybamm.PrimaryBroadcast(c_plated_Li_av, f"{domain} electrode")
             c_dead_Li_av = pybamm.Variable(
-                f"X-averaged {domain} dead lithium concentration [mol.m-3]",
+                f"X-averaged {domain} {self.phase_name}dead lithium concentration "
+                "[mol.m-3]",
                 domain="current collector",
+                scale=scale,
             )
             c_dead_Li = pybamm.PrimaryBroadcast(c_dead_Li_av, f"{domain} electrode")
         else:
             c_plated_Li = pybamm.Variable(
-                f"{Domain} lithium plating concentration [mol.m-3]",
+                f"{Domain} {self.phase_name}lithium plating concentration [mol.m-3]",
                 domain=f"{domain} electrode",
                 auxiliary_domains={"secondary": "current collector"},
-                scale=self.param.c_Li_typ,
+                scale=scale,
             )
             c_dead_Li = pybamm.Variable(
-                f"{Domain} dead lithium concentration [mol.m-3]",
+                f"{Domain} {self.phase_name}dead lithium concentration [mol.m-3]",
                 domain=f"{domain} electrode",
                 auxiliary_domains={"secondary": "current collector"},
+                scale=scale,
             )
 
         variables = self._get_standard_concentration_variables(c_plated_Li, c_dead_Li)
@@ -57,22 +62,26 @@ class Plating(BasePlating):
         return variables
 
     def get_coupled_variables(self, variables):
-        param = self.param
+        phase_param = self.phase_param
         domain, Domain = self.domain_Domain
         delta_phi = variables[f"{Domain} electrode surface potential difference [V]"]
         c_e_n = variables[f"{Domain} electrolyte concentration [mol.m-3]"]
         T = variables[f"{Domain} electrode temperature [K]"]
-        eta_sei = variables[f"{Domain} electrode SEI film overpotential [V]"]
-        c_plated_Li = variables[f"{Domain} lithium plating concentration [mol.m-3]"]
-        j0_stripping = param.j0_stripping(c_e_n, c_plated_Li, T)
-        j0_plating = param.j0_plating(c_e_n, c_plated_Li, T)
+        eta_sei = variables[
+            f"{Domain} electrode {self.phase_name}SEI film overpotential [V]"
+        ]
+        c_plated_Li = variables[
+            f"{Domain} {self.phase_name}lithium plating concentration [mol.m-3]"
+        ]
+        j0_stripping = phase_param.j0_stripping(c_e_n, c_plated_Li, T)
+        j0_plating = phase_param.j0_plating(c_e_n, c_plated_Li, T)
 
         eta_stripping = delta_phi + eta_sei
         eta_plating = -eta_stripping
-        F_RT = param.F / (param.R * T)
+        F_RT = self.param.F / (self.param.R * T)
         # NEW: transfer coefficients can be set by the user
-        alpha_stripping = self.param.alpha_stripping
-        alpha_plating = self.param.alpha_plating
+        alpha_stripping = phase_param.alpha_stripping
+        alpha_plating = phase_param.alpha_plating
 
         lithium_plating_option = getattr(self.options, domain)["lithium plating"]
         if lithium_plating_option in ["reversible", "partially reversible"]:
@@ -87,33 +96,41 @@ class Plating(BasePlating):
         variables.update(self._get_standard_overpotential_variables(eta_stripping))
         variables.update(self._get_standard_reaction_variables(j_stripping))
 
-        # Update whole cell variables, which also updates the "sum of" variables
+        # Add other standard coupled variables
         variables.update(super().get_coupled_variables(variables))
 
         return variables
 
     def set_rhs(self, variables):
         domain, Domain = self.domain_Domain
+        phase_name = self.phase_name
         if self.x_average is True:
             c_plated_Li = variables[
-                f"X-averaged {domain} lithium plating concentration [mol.m-3]"
+                f"X-averaged {domain} {phase_name}lithium plating concentration "
+                "[mol.m-3]"
             ]
             c_dead_Li = variables[
-                f"X-averaged {domain} dead lithium concentration [mol.m-3]"
+                f"X-averaged {domain} {phase_name}dead lithium concentration [mol.m-3]"
             ]
             a_j_stripping = variables[
-                f"X-averaged {domain} lithium plating volumetric "
+                f"X-averaged {domain} electrode {phase_name}lithium plating volumetric "
                 "interfacial current density [A.m-3]"
             ]
-            L_sei = variables[f"X-averaged {domain} total SEI thickness [m]"]
+            L_sei = variables[
+                f"X-averaged {domain} total {phase_name}SEI thickness [m]"
+            ]
         else:
-            c_plated_Li = variables[f"{Domain} lithium plating concentration [mol.m-3]"]
-            c_dead_Li = variables[f"{Domain} dead lithium concentration [mol.m-3]"]
+            c_plated_Li = variables[
+                f"{Domain} {phase_name}lithium plating concentration [mol.m-3]"
+            ]
+            c_dead_Li = variables[
+                f"{Domain} {phase_name}dead lithium concentration [mol.m-3]"
+            ]
             a_j_stripping = variables[
-                f"{Domain} lithium plating volumetric "
+                f"{Domain} electrode {phase_name}lithium plating volumetric "
                 "interfacial current density [A.m-3]"
             ]
-            L_sei = variables[f"{Domain} total SEI thickness [m]"]
+            L_sei = variables[f"{Domain} total {phase_name}SEI thickness [m]"]
 
         lithium_plating_option = getattr(self.options, domain)["lithium plating"]
         if lithium_plating_option == "reversible":
@@ -127,7 +144,7 @@ class Plating(BasePlating):
         elif lithium_plating_option == "partially reversible":
             # In the partially reversible plating model, the coupling term turns
             # reversible lithium into dead lithium over time.
-            dead_lithium_decay_rate = self.param.dead_lithium_decay_rate(L_sei)
+            dead_lithium_decay_rate = self.phase_param.dead_lithium_decay_rate(L_sei)
             coupling_term = dead_lithium_decay_rate * c_plated_Li
             dc_plated_Li = -a_j_stripping / self.param.F - coupling_term
             dc_dead_Li = coupling_term
@@ -139,17 +156,23 @@ class Plating(BasePlating):
 
     def set_initial_conditions(self, variables):
         domain, Domain = self.domain_Domain
+        phase_name = self.phase_name
         if self.x_average is True:
             c_plated_Li = variables[
-                f"X-averaged {domain} lithium plating concentration [mol.m-3]"
+                f"X-averaged {domain} {phase_name}lithium plating concentration "
+                "[mol.m-3]"
             ]
             c_dead_Li = variables[
-                f"X-averaged {domain} dead lithium concentration [mol.m-3]"
+                f"X-averaged {domain} {phase_name}dead lithium concentration [mol.m-3]"
             ]
         else:
-            c_plated_Li = variables[f"{Domain} lithium plating concentration [mol.m-3]"]
-            c_dead_Li = variables[f"{Domain} dead lithium concentration [mol.m-3]"]
-        c_plated_Li_0 = self.param.c_plated_Li_0
-        zero = pybamm.Scalar(0)
+            c_plated_Li = variables[
+                f"{Domain} {phase_name}lithium plating concentration [mol.m-3]"
+            ]
+            c_dead_Li = variables[
+                f"{Domain} {phase_name}dead lithium concentration [mol.m-3]"
+            ]
+        c_plated_Li_0 = self.phase_param.c_plated_Li_0
+        zero = 0 * c_plated_Li_0
 
         self.initial_conditions = {c_plated_Li: c_plated_Li_0, c_dead_Li: zero}
diff --git a/pybamm/models/submodels/interface/lithium_plating/total_lithium_plating.py b/pybamm/models/submodels/interface/lithium_plating/total_lithium_plating.py
new file mode 100644
index 000000000..105a9a938
--- /dev/null
+++ b/pybamm/models/submodels/interface/lithium_plating/total_lithium_plating.py
@@ -0,0 +1,43 @@
+#
+# Class summing up contributions to the lithium plating reaction
+# for cases with primary, secondary, ... reactions e.g. silicon-graphite
+#
+import pybamm
+
+
+class TotalLithiumPlating(pybamm.BaseSubModel):
+    """
+    Class summing up contributions to the lithium plating reaction
+    for cases with primary, secondary, ... reactions e.g. silicon-graphite
+
+    Parameters
+    ----------
+    param :
+        model parameters
+    options: dict
+        A dictionary of options to be passed to the model.
+        See :class:`pybamm.BaseBatteryModel`
+    """
+
+    def __init__(self, param, domain, options):
+        super().__init__(param, domain, options=options)
+
+    def get_coupled_variables(self, variables):
+        domain, Domain = self.domain_Domain
+        phases = self.options.phases[domain]
+        # For each of the variables, the variable name without the phase name
+        # is constructed by summing all of the variable names with the phases
+        for variable_template in [
+            f"{Domain} electrode {{}}lithium plating volumetric "
+            "interfacial current density [A.m-3]",
+            f"X-averaged {domain} electrode {{}}lithium plating volumetric "
+            "interfacial current density [A.m-3]",
+            f"Loss of lithium to {domain} {{}}lithium plating [mol]",
+            f"Loss of capacity to {domain} {{}}lithium plating [A.h]",
+        ]:
+            sumvar = sum(
+                variables[variable_template.format(phase + " ")] for phase in phases
+            )
+            variables[variable_template.format("")] = sumvar
+
+        return variables
diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py
index e4e18579b..7ef032f7f 100644
--- a/pybamm/parameters/lithium_ion_parameters.py
+++ b/pybamm/parameters/lithium_ion_parameters.py
@@ -91,18 +91,10 @@ class LithiumIonParameters(BaseParameters):
             ]
         )
 
-        # Lithium plating parameters
+        # Required by lithium plating and lithium metal plating reactions
         self.V_bar_Li = pybamm.Parameter(
             "Lithium metal partial molar volume [m3.mol-1]"
         )
-        self.c_Li_typ = pybamm.Parameter(
-            "Typical plated lithium concentration [mol.m-3]"
-        )
-        self.c_plated_Li_0 = pybamm.Parameter(
-            "Initial plated lithium concentration [mol.m-3]"
-        )
-        self.alpha_plating = pybamm.Parameter("Lithium plating transfer coefficient")
-        self.alpha_stripping = 1 - self.alpha_plating
 
         # Initial conditions
         # Note: the initial concentration in the electrodes can be set as a function
@@ -188,33 +180,6 @@ class LithiumIonParameters(BaseParameters):
             "Exchange-current density for lithium metal electrode [A.m-2]", inputs
         )
 
-    def j0_stripping(self, c_e, c_Li, T):
-        """Dimensional exchange-current density for stripping [A.m-2]"""
-        inputs = {
-            "Electrolyte concentration [mol.m-3]": c_e,
-            "Plated lithium concentration [mol.m-3]": c_Li,
-            "Temperature [K]": T,
-        }
-        return pybamm.FunctionParameter(
-            "Exchange-current density for stripping [A.m-2]", inputs
-        )
-
-    def j0_plating(self, c_e, c_Li, T):
-        """Dimensional exchange-current density for plating [A.m-2]"""
-        inputs = {
-            "Electrolyte concentration [mol.m-3]": c_e,
-            "Plated lithium concentration [mol.m-3]": c_Li,
-            "Temperature [K]": T,
-        }
-        return pybamm.FunctionParameter(
-            "Exchange-current density for plating [A.m-2]", inputs
-        )
-
-    def dead_lithium_decay_rate(self, L_sei):
-        """Dimensional dead lithium decay rate [s-1]"""
-        inputs = {"Total SEI thickness [m]": L_sei}
-        return pybamm.FunctionParameter("Dead lithium decay rate [s-1]", inputs)
-
 
 class DomainLithiumIonParameters(BaseParameters):
     def __init__(self, domain, main_param):
@@ -471,6 +436,18 @@ class ParticleLithiumIonParameters(BaseParameters):
         self.k_sei = pybamm.Parameter(f"{pref}SEI kinetic rate constant [m.s-1]")
         self.U_sei = pybamm.Parameter(f"{pref}SEI open-circuit potential [V]")
 
+        # Lithium plating parameters
+        self.c_Li_typ = pybamm.Parameter(
+            f"{pref}Typical plated lithium concentration [mol.m-3]"
+        )
+        self.c_plated_Li_0 = pybamm.Parameter(
+            f"{pref}Initial plated lithium concentration [mol.m-3]"
+        )
+        self.alpha_plating = pybamm.Parameter(
+            f"{pref}Lithium plating transfer coefficient"
+        )
+        self.alpha_stripping = 1 - self.alpha_plating
+
         if main.options.electrode_types[domain] == "planar":
             self.n_Li_init = pybamm.Scalar(0)
             self.Q_Li_init = pybamm.Scalar(0)
@@ -601,6 +578,40 @@ class ParticleLithiumIonParameters(BaseParameters):
             inputs,
         )
 
+    def j0_stripping(self, c_e, c_Li, T):
+        """Dimensional exchange-current density for stripping [A.m-2]"""
+        Domain = self.domain.capitalize()
+        inputs = {
+            f"{Domain} electrolyte concentration [mol.m-3]": c_e,
+            f"{Domain} plated lithium concentration [mol.m-3]": c_Li,
+            f"{Domain} temperature [K]": T,
+        }
+        return pybamm.FunctionParameter(
+            f"{self.phase_prefactor}Exchange-current density for stripping [A.m-2]",
+            inputs,
+        )
+
+    def j0_plating(self, c_e, c_Li, T):
+        """Dimensional exchange-current density for plating [A.m-2]"""
+        Domain = self.domain.capitalize()
+        inputs = {
+            f"{Domain} electrolyte concentration [mol.m-3]": c_e,
+            f"{Domain} plated lithium concentration [mol.m-3]": c_Li,
+            f"{Domain} temperature [K]": T,
+        }
+        return pybamm.FunctionParameter(
+            f"{self.phase_prefactor}Exchange-current density for plating [A.m-2]",
+            inputs,
+        )
+
+    def dead_lithium_decay_rate(self, L_sei):
+        """Dimensional dead lithium decay rate [s-1]"""
+        Domain = self.domain.capitalize()
+        inputs = {f"{Domain} total {self.phase_name}SEI thickness [m]": L_sei}
+        return pybamm.FunctionParameter(
+            f"{self.phase_prefactor}Dead lithium decay rate [s-1]", inputs
+        )
+
     def U(self, sto, T, lithiation=None):
         """Dimensional open-circuit potential [V]"""
         # bound stoichiometry between tol and 1-tol. Adding 1/sto + 1/(sto-1) later


Test patch:
diff --git a/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015.py b/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015.py
index f23976474..2dc73d448 100644
--- a/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015.py
+++ b/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015.py
@@ -13,6 +13,13 @@ class TestEcker2015(TestCase):
         T = pybamm.Scalar(298.15)
 
         fun_test = {
+            # Lithium plating
+            "Exchange-current density for plating [A.m-2]": ([1e3, 1e4, T], 9.6485e-3),
+            "Exchange-current density for stripping [A.m-2]": (
+                [1e3, 1e4, T],
+                9.6485e-2,
+            ),
+            "Dead lithium decay rate [s-1]": ([1e-8], 5e-7),
             # Negative electrode
             "Negative particle diffusivity [m2.s-1]": ([sto, T], 1.219e-14),
             "Negative electrode exchange-current density [A.m-2]": (
diff --git a/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015_graphite_halfcell.py b/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015_graphite_halfcell.py
index 862ac8295..f435ef6d3 100644
--- a/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015_graphite_halfcell.py
+++ b/tests/unit/test_parameters/test_parameter_sets/test_Ecker2015_graphite_halfcell.py
@@ -13,6 +13,13 @@ class TestEcker2015_graphite_halfcell(TestCase):
         T = pybamm.Scalar(298.15)
 
         fun_test = {
+            # Lithium plating
+            "Exchange-current density for plating [A.m-2]": ([1e3, 1e4, T], 9.6485e-3),
+            "Exchange-current density for stripping [A.m-2]": (
+                [1e3, 1e4, T],
+                9.6485e-2,
+            ),
+            "Dead lithium decay rate [s-1]": ([1e-8], 5e-7),
             # Positive electrode
             "Positive particle diffusivity [m2.s-1]": ([sto, T], 1.219e-14),
             "Positive electrode exchange-current density [A.m-2]": (