Repository: pybamm-team/PyBaMM
Pull request #4693 (2024-12-18 23:07:13)

Sei composite multiparticle
# Description

make sei work with particle size distributions

Fixes # (issue)

## 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.

- [ ] New feature (non-breaking change which adds functionality)
- [ ] Optimization (back-end change that speeds up the code)
- [ ] Bug fix (non-breaking change which fixes an issue)

# Key checklist:

- [ ] 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)
- [ ] All tests pass: `$ python -m pytest` (or `$ nox -s tests`)
- [ ] The documentation builds: `$ python -m pytest --doctest-plus src` (or `$ nox -s doctests`)

You can run integration tests, unit tests, and doctests together at once, using `$ 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


review-notebook-app[bot]: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/pybamm-team/PyBaMM/pull/4693"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) Report
Attention: Patch coverage is `79.47020%` with `31 lines` in your changes missing coverage. Please review.
> Project coverage is 99.08%. Comparing base [(`864388f`)](https://app.codecov.io/gh/pybamm-team/PyBaMM/commit/864388f583734e96464bf803300c109f908fa55e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) to head [(`83264a1`)](https://app.codecov.io/gh/pybamm-team/PyBaMM/commit/83264a1bdfb74b301fcf5fe77910981c685d155e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team).
> Report is 8 commits behind head on develop.

| [Files with missing lines](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) | Patch % | Lines |
|---|---|---|
| [.../pybamm/parameters/size\_distribution\_parameters.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fparameters%2Fsize_distribution_parameters.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9wYXJhbWV0ZXJzL3NpemVfZGlzdHJpYnV0aW9uX3BhcmFtZXRlcnMucHk=) | 38.09% | [13 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [src/pybamm/expression\_tree/averages.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fexpression_tree%2Faverages.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9leHByZXNzaW9uX3RyZWUvYXZlcmFnZXMucHk=) | 63.15% | [7 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [.../submodels/active\_material/base\_active\_material.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fmodels%2Fsubmodels%2Factive_material%2Fbase_active_material.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9tb2RlbHMvc3VibW9kZWxzL2FjdGl2ZV9tYXRlcmlhbC9iYXNlX2FjdGl2ZV9tYXRlcmlhbC5weQ==) | 60.00% | [4 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [src/pybamm/geometry/battery\_geometry.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fgeometry%2Fbattery_geometry.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9nZW9tZXRyeS9iYXR0ZXJ5X2dlb21ldHJ5LnB5) | 66.66% | [2 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [src/pybamm/parameters/geometric\_parameters.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fparameters%2Fgeometric_parameters.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9wYXJhbWV0ZXJzL2dlb21ldHJpY19wYXJhbWV0ZXJzLnB5) | 71.42% | [2 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [...ybamm/models/submodels/interface/base\_interface.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fmodels%2Fsubmodels%2Finterface%2Fbase_interface.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9tb2RlbHMvc3VibW9kZWxzL2ludGVyZmFjZS9iYXNlX2ludGVyZmFjZS5weQ==) | 93.33% | [1 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [...s/submodels/interface/total\_interfacial\_current.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fmodels%2Fsubmodels%2Finterface%2Ftotal_interfacial_current.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9tb2RlbHMvc3VibW9kZWxzL2ludGVyZmFjZS90b3RhbF9pbnRlcmZhY2lhbF9jdXJyZW50LnB5) | 75.00% | [1 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |
| [.../pybamm/models/submodels/porosity/base\_porosity.py](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&filepath=src%2Fpybamm%2Fmodels%2Fsubmodels%2Fporosity%2Fbase_porosity.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team#diff-c3JjL3B5YmFtbS9tb2RlbHMvc3VibW9kZWxzL3Bvcm9zaXR5L2Jhc2VfcG9yb3NpdHkucHk=) | 50.00% | [1 Missing :warning: ](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team) |

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop    #4693      +/-   ##
===========================================
- Coverage    99.21%   99.08%   -0.14%     
===========================================
  Files          302      302              
  Lines        22880    22996     +116     
===========================================
+ Hits         22701    22786      +85     
- Misses         179      210      +31     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/pybamm-team/PyBaMM/pull/4693?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pybamm-team).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b96e684e0..388d66d89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## Features
 
+- Enabled using SEI models with particle size distributions. ([#4693](https://github.com/pybamm-team/PyBaMM/pull/4693))
 - Added symbolic mesh which allows for using InputParameters for geometric parameters ([#4665](https://github.com/pybamm-team/PyBaMM/pull/4665))
 - Enhanced the `search` method to accept multiple search terms in the form of a string or a list. ([#4650](https://github.com/pybamm-team/PyBaMM/pull/4650))
 - Made composite electrode model compatible with particle size distribution ([#4687](https://github.com/pybamm-team/PyBaMM/pull/4687))
diff --git a/src/pybamm/models/full_battery_models/base_battery_model.py b/src/pybamm/models/full_battery_models/base_battery_model.py
index 83d62df27..a556c3fe7 100644
--- a/src/pybamm/models/full_battery_models/base_battery_model.py
+++ b/src/pybamm/models/full_battery_models/base_battery_model.py
@@ -526,10 +526,15 @@ class BatteryModelOptions(pybamm.FuzzyDict):
         # Options not yet compatible with particle-size distributions
         if options["particle size"] == "distribution":
             if options["lithium plating porosity change"] != "false":
-                raise NotImplementedError(
+                raise pybamm.OptionError(
                     "Lithium plating porosity change not yet supported for particle-size"
                     " distributions."
                 )
+            if options["SEI porosity change"] == "true":
+                raise NotImplementedError(
+                    "SEI porosity change submodels do not yet support particle-size "
+                    "distributions."
+                )
             if options["heat of mixing"] != "false":
                 raise NotImplementedError(
                     "Heat of mixing submodels do not yet support particle-size "
@@ -550,10 +555,6 @@ class BatteryModelOptions(pybamm.FuzzyDict):
                     "Particle shape must be 'spherical' for particle-size distribution"
                     " submodels."
                 )
-            if options["SEI"] != "none":
-                raise NotImplementedError(
-                    "SEI submodels do not yet support particle-size distributions."
-                )
             if options["stress-induced diffusion"] == "true":
                 raise NotImplementedError(
                     "stress-induced diffusion cannot yet be included in "
diff --git a/src/pybamm/models/submodels/interface/kinetics/base_kinetics.py b/src/pybamm/models/submodels/interface/kinetics/base_kinetics.py
index c3b6ed532..1c8773f02 100644
--- a/src/pybamm/models/submodels/interface/kinetics/base_kinetics.py
+++ b/src/pybamm/models/submodels/interface/kinetics/base_kinetics.py
@@ -151,6 +151,10 @@ class BaseKinetics(BaseInterface):
             j_tot.print_name = "j_tot"
 
             eta_sei = -j_tot * L_sei * R_sei
+            if self.size_distribution and eta_r.domains["secondary"] != [
+                f"{domain} electrode"
+            ]:
+                eta_sei = pybamm.x_average(eta_sei)
         else:
             eta_sei = pybamm.Scalar(0)
         eta_r += eta_sei


Test patch:
diff --git a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
index 554b65d88..dc056523a 100644
--- a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
+++ b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
@@ -313,6 +313,13 @@ class TestBaseBatteryModel:
                     "plating porosity change"
                 }
             )
+        with pytest.raises(pybamm.OptionError, match="distributions"):
+            pybamm.BaseBatteryModel(
+                {
+                    "particle size": "distribution",
+                    "lithium plating porosity change": "true",
+                }
+            )
 
         # contact resistance
         with pytest.raises(pybamm.OptionError, match="contact resistance"):
diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
index 5f693264d..f69e96f7b 100644
--- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
+++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
@@ -98,7 +98,7 @@ class TestMPM:
             "lithium plating": "reversible",
             "lithium plating porosity change": "true",
         }
-        with pytest.raises(NotImplementedError):
+        with pytest.raises(pybamm.OptionError, match="distributions"):
             pybamm.lithium_ion.MPM(options)
 
     def test_stress_induced_diffusion_not_implemented(self):
@@ -159,25 +159,25 @@ class TestMPMExternalCircuits:
 
 
 class TestMPMWithSEI:
-    def test_reaction_limited_not_implemented(self):
+    def test_reaction_limited(self):
         options = {"SEI": "reaction limited"}
-        with pytest.raises(NotImplementedError):
-            pybamm.lithium_ion.MPM(options)
+        model = pybamm.lithium_ion.MPM(options)
+        model.check_well_posedness()
 
-    def test_solvent_diffusion_limited_not_implemented(self):
+    def test_solvent_diffusion_limited(self):
         options = {"SEI": "solvent-diffusion limited"}
-        with pytest.raises(NotImplementedError):
-            pybamm.lithium_ion.MPM(options)
+        model = pybamm.lithium_ion.MPM(options)
+        model.check_well_posedness()
 
-    def test_electron_migration_limited_not_implemented(self):
+    def test_electron_migration_limited(self):
         options = {"SEI": "electron-migration limited"}
-        with pytest.raises(NotImplementedError):
-            pybamm.lithium_ion.MPM(options)
+        model = pybamm.lithium_ion.MPM(options)
+        model.check_well_posedness()
 
-    def test_interstitial_diffusion_limited_not_implemented(self):
+    def test_interstitial_diffusion_limited(self):
         options = {"SEI": "interstitial-diffusion limited"}
-        with pytest.raises(NotImplementedError):
-            pybamm.lithium_ion.MPM(options)
+        model = pybamm.lithium_ion.MPM(options)
+        model.check_well_posedness()
 
     def test_ec_reaction_limited_not_implemented(self):
         options = {