Repository: pybamm-team/PyBaMM (python)

Issue:
[Bug]: `Particle electrode diffusivity` rename breaks ParameterSet.update()
### PyBaMM Version

[Develop]

### Python Version

3.12

### Describe the bug

The parameter rename of `Positive electrode diffusivity` -> `Positive particle diffusivity` currently breaks the `ParameterSet.update()` method.

Linking https://github.com/pybamm-team/PyBaMM/pull/3624

### Steps to Reproduce

```python
import pybamm
parameter_values = pybamm.ParameterValues("Chen2020")
parameter_values.update({"Positive electrode diffusivity [m2.s-1]": 1e-14})
```

### Relevant log output

```shell
{
	"name": "KeyError",
	"message": "\"Cannot update parameter 'Positive electrode diffusivity [m2.s-1]' as it does not have a default value. ('Positive electrode diffusivity [m2.s-1]' not found. Best matches are ['Positive particle diffusivity [m2.s-1]', 'Positive electrode conductivity [S.m-1]', 'Electrolyte diffusivity [m2.s-1]']). If you are sure you want to update this parameter, use param.update({{name: value}}, check_already_exists=False)\"",
	"stack": "---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~/Documents/Git/PyBaMM/pybamm/util.py:59, in FuzzyDict.__getitem__(self, key)
     58 try:
---> 59     return super().__getitem__(key)
     60 except KeyError as error:

KeyError: 'Positive electrode diffusivity [m2.s-1]'

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
File ~/Documents/Git/PyBaMM/pybamm/parameters/parameter_values.py:247, in ParameterValues.update(self, values, check_conflict, check_already_exists, path)
    246 try:
--> 247     self._dict_items[name]
    248 except KeyError as err:

File ~/Documents/Git/PyBaMM/pybamm/util.py:103, in FuzzyDict.__getitem__(self, key)
    100         raise KeyError(
    101             f\"'{key}' not found. Use the dimensional version '{k}' instead.\"
    102         ) from error
--> 103 raise KeyError(
    104     f\"'{key}' not found. Best matches are {best_matches}\"
    105 ) from error

KeyError: \"'Positive electrode diffusivity [m2.s-1]' not found. Best matches are ['Positive particle diffusivity [m2.s-1]', 'Positive electrode conductivity [S.m-1]', 'Electrolyte diffusivity [m2.s-1]']\"

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
Cell In[4], line 2
      1 parameter_values = pybamm.ParameterValues(\"Chen2020\")
----> 2 parameter_values.update({\"Positive electrode diffusivity [m2.s-1]\": 1e-14})

File ~/Documents/Git/PyBaMM/pybamm/parameters/parameter_values.py:249, in ParameterValues.update(self, values, check_conflict, check_already_exists, path)
    247         self._dict_items[name]
    248     except KeyError as err:
--> 249         raise KeyError(
    250             f\"Cannot update parameter '{name}' as it does not \"
    251             + f\"have a default value. ({err.args[0]}). If you are \"
    252             + \"sure you want to update this parameter, use \"
    253             + \"param.update({{name: value}}, check_already_exists=False)\"
    254         ) from err
    255 # if no conflicts, update
    256 if isinstance(value, str):

KeyError: \"Cannot update parameter 'Positive electrode diffusivity [m2.s-1]' as it does not have a default value. ('Positive electrode diffusivity [m2.s-1]' not found. Best matches are ['Positive particle diffusivity [m2.s-1]', 'Positive electrode conductivity [S.m-1]', 'Electrolyte diffusivity [m2.s-1]']). If you are sure you want to update this parameter, use param.update({{name: value}}, check_already_exists=False)\""
}
```


Pull request:
Fixes breaking changes from #3624
# Description

This PR updates `ParameterSet.update()` and `Solver.solve()` so that #3624 is non-breaking.

Fixes #4071 

## 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:

- [ ] 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 eb02ebedb..b72151f36 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,7 @@
 
 ## Bug Fixes
 
+- Fixes the breaking changes caused by [#3624](https://github.com/pybamm-team/PyBaMM/pull/3624), specifically enables the deprecated parameter `electrode diffusivity` to be used by `ParameterValues.update({name:value})` and `Solver.solve(inputs={name:value})`. Fixes parameter translation from old name to new name, with corrected tests. ([#4072](https://github.com/pybamm-team/PyBaMM/pull/4072)
 - Set the `remove_independent_variables_from_rhs` to `False` by default, and moved the option from `Discretisation.process_model` to `Discretisation.__init__`. This fixes a bug related to the discharge capacity, but may make the simulation slower in some cases. To set the option to `True`, use `Simulation(..., discretisation_kwargs={"remove_independent_variables_from_rhs": True})`. ([#4020](https://github.com/pybamm-team/PyBaMM/pull/4020))
 - 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))
diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py
index 402000b5a..830177104 100644
--- a/pybamm/parameters/parameter_values.py
+++ b/pybamm/parameters/parameter_values.py
@@ -5,6 +5,7 @@ import numpy as np
 import pybamm
 import numbers
 from pprint import pformat
+from warnings import warn
 from collections import defaultdict
 
 
@@ -229,7 +230,7 @@ class ParameterValues:
         if not isinstance(values, dict):
             values = values._dict_items
         # check parameter values
-        self.check_parameter_values(values)
+        values = self.check_parameter_values(values)
         # update
         for name, value in values.items():
             # check for conflicts
@@ -389,7 +390,8 @@ class ParameterValues:
         )
         return parameter_values
 
-    def check_parameter_values(self, values):
+    @staticmethod
+    def check_parameter_values(values):
         for param in values:
             if "propotional term" in param:
                 raise ValueError(
@@ -402,6 +404,15 @@ class ParameterValues:
                 raise ValueError(
                     f"parameter '{param}' has been renamed to " "'Thermodynamic factor'"
                 )
+            if "electrode diffusivity" in param:
+                warn(
+                    f"The parameter '{param}' has been renamed to '{param.replace('electrode', 'particle')}'",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+                param = param.replace("electrode", "particle")
+
+        return values
 
     def process_model(self, unprocessed_model, inplace=True):
         """Assign parameter values to a model.
diff --git a/pybamm/solvers/base_solver.py b/pybamm/solvers/base_solver.py
index 625de7a3a..798ff9f19 100644
--- a/pybamm/solvers/base_solver.py
+++ b/pybamm/solvers/base_solver.py
@@ -12,6 +12,7 @@ import numpy as np
 
 import pybamm
 from pybamm.expression_tree.binary_operators import _Heaviside
+from pybamm import ParameterValues
 
 
 class BaseSolver:
@@ -1401,7 +1402,10 @@ class BaseSolver:
     @staticmethod
     def _set_up_model_inputs(model, inputs):
         """Set up input parameters"""
-        inputs = inputs or {}
+        if inputs is None:
+            inputs = {}
+        else:
+            inputs = ParameterValues.check_parameter_values(inputs)
 
         # Go through all input parameters that can be found in the model
         # Only keep the ones that are actually used in the model
diff --git a/pybamm/util.py b/pybamm/util.py
index ac7e5f647..e5ec0d812 100644
--- a/pybamm/util.py
+++ b/pybamm/util.py
@@ -57,14 +57,14 @@ class FuzzyDict(dict):
         try:
             return super().__getitem__(key)
         except KeyError as error:
-            if "particle diffusivity" in key:
+            if "electrode diffusivity" in key:
                 warn(
-                    f"The parameter '{key.replace('particle', 'electrode')}' "
+                    f"The parameter '{key.replace('electrode', 'particle')}' "
                     f"has been renamed to '{key}'",
                     DeprecationWarning,
                     stacklevel=2,
                 )
-                return super().__getitem__(key.replace("particle", "electrode"))
+                return super().__getitem__(key.replace("electrode", "particle"))
             if key in ["Negative electrode SOC", "Positive electrode SOC"]:
                 domain = key.split(" ")[0]
                 raise KeyError(


Test patch:
diff --git a/tests/unit/test_util.py b/tests/unit/test_util.py
index 603af5056..2daad1f6a 100644
--- a/tests/unit/test_util.py
+++ b/tests/unit/test_util.py
@@ -36,7 +36,7 @@ class TestUtil(TestCase):
                 "SEI current": 3,
                 "Lithium plating current": 4,
                 "A dimensional variable [m]": 5,
-                "Positive electrode diffusivity [m2.s-1]": 6,
+                "Positive particle diffusivity [m2.s-1]": 6,
             }
         )
         self.assertEqual(d["test"], 1)
@@ -59,10 +59,7 @@ class TestUtil(TestCase):
             d.__getitem__("Open-circuit voltage at 100% SOC [V]")
 
         with self.assertWarns(DeprecationWarning):
-            self.assertEqual(
-                d["Positive electrode diffusivity [m2.s-1]"],
-                d["Positive particle diffusivity [m2.s-1]"],
-            )
+            self.assertEqual(d["Positive electrode diffusivity [m2.s-1]"], 6)
 
     def test_get_parameters_filepath(self):
         tempfile_obj = tempfile.NamedTemporaryFile("w", dir=".")