Repository: pybamm-team/PyBaMM (python)

Issue:
Raise OptionError if "SEI on cracks" is "true" but cracking isn't enabled.
If you do e.g. 
```python3
model = pybamm.lithium_ion.SPMe(
    {
        "SEI": "solvent-diffusion limited",
        "SEI porosity change": "true",
        "lithium plating": "partially reversible",
        "lithium plating porosity change": "true",  # alias for "SEI porosity change"
        "particle mechanics": ("swelling only", "swelling only"),
        "SEI on cracks": "true",
        "loss of active material": "stress-driven",
    }
)
```
you get a `ZeroDivisionError`. It doesn't make sense to have SEI n cracks if there are no cracks, so we should catch this and raise an `OptionError`

Pull request:
Bug fix for cracking options
# Description

Adds an OptionError if the option `SEI on cracks` is True but `particle mechanics` does not contain cracks. This issue only occurs if both options are set explicitly in the model's additional options - the user's `particle mechanics` option overrides the defaults which automatically set the mechanics to "swelling and cracking" if `SEI on cracks` is true.

Fixes #4119

## 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)
- [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:

- [x] Code is commented, particularly in hard-to-understand areas
- [x] Tests added that prove fix is effective or that feature works


Patch:
diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py
index fb8d001f9..8a2e44333 100644
--- a/pybamm/models/full_battery_models/base_battery_model.py
+++ b/pybamm/models/full_battery_models/base_battery_model.py
@@ -633,6 +633,20 @@ class BatteryModelOptions(pybamm.FuzzyDict):
                     "be 'none': 'particle mechanics', 'loss of active material'"
                 )
 
+        if "true" in options["SEI on cracks"]:
+            sei_on_cr = options["SEI on cracks"]
+            p_mechanics = options["particle mechanics"]
+            if isinstance(p_mechanics, str) and isinstance(sei_on_cr, tuple):
+                p_mechanics = (p_mechanics, p_mechanics)
+            if any(
+                sei == "true" and mech != "swelling and cracking"
+                for mech, sei in zip(p_mechanics, sei_on_cr)
+            ):
+                raise pybamm.OptionError(
+                    "If 'SEI on cracks' is 'true' then 'particle mechanics' must be "
+                    "'swelling and cracking'."
+                )
+
         # Check options are valid
         for option, value in options.items():
             if isinstance(value, str) or option in [


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 caff0cda5..057d6d2ad 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
@@ -310,6 +310,10 @@ class TestBaseBatteryModel(TestCase):
         # SEI on cracks
         with self.assertRaisesRegex(pybamm.OptionError, "SEI on cracks"):
             pybamm.BaseBatteryModel({"SEI on cracks": "bad SEI on cracks"})
+        with self.assertRaisesRegex(pybamm.OptionError, "'SEI on cracks' is 'true'"):
+            pybamm.BaseBatteryModel(
+                {"SEI on cracks": "true", "particle mechanics": "swelling only"}
+            )
 
         # plating model
         with self.assertRaisesRegex(pybamm.OptionError, "lithium plating"):