Repository: pybamm-team/PyBaMM

Issue:
Raise warning when converting pchip interpolants to casadi 
When a `pybamm.Interpolant` object is created you can set the `interpolator` to "linear", "pchip" or "cubic spline" (default). When this node gets converted to casadi, the converted interpolator is *always* a spline. We should raise a warning if an `Interpolant` using "linear" or "pchip" gets converted to casadi's interpolant so that users know it is switching to a spline. 

Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ef861062d..3d75b89be 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
 
 ## Breaking changes
 
+-   Raise error when trying to convert an `Interpolant` with the "pchip" interpolator to CasADI ([#1791](https://github.com/pybamm-team/PyBaMM/pull/1791))
 -   Raise error if `Concatenation` is used directly with `Variable` objects (`concatenation` should be used instead) ([#1789](https://github.com/pybamm-team/PyBaMM/pull/1789))
 -   Made jax and the PyBaMM JaxSolver optional ([#1767](https://github.com/pybamm-team/PyBaMM/pull/1767))
 
diff --git a/pybamm/expression_tree/operations/convert_to_casadi.py b/pybamm/expression_tree/operations/convert_to_casadi.py
index 1799b2aab..9c9a47601 100644
--- a/pybamm/expression_tree/operations/convert_to_casadi.py
+++ b/pybamm/expression_tree/operations/convert_to_casadi.py
@@ -47,7 +47,7 @@ class CasadiConverter(object):
             return casadi_symbol
 
     def _convert(self, symbol, t, y, y_dot, inputs):
-        """ See :meth:`CasadiConverter.convert()`. """
+        """See :meth:`CasadiConverter.convert()`."""
         if isinstance(
             symbol,
             (
@@ -132,9 +132,20 @@ class CasadiConverter(object):
             elif symbol.function == special.erf:
                 return casadi.erf(*converted_children)
             elif isinstance(symbol, pybamm.Interpolant):
-                return casadi.interpolant(
-                    "LUT", "bspline", symbol.x, symbol.y.flatten()
-                )(*converted_children)
+                if symbol.interpolator == "linear":
+                    solver = "linear"
+                elif symbol.interpolator == "cubic spline":
+                    solver = "bspline"
+                elif symbol.interpolator == "pchip":
+                    raise NotImplementedError(
+                        "The interpolator 'pchip' is not supported by CasAdi. "
+                        "Use 'linear' or 'cubic spline' instead. "
+                        "Alternatively, set 'model.convert_to_format = 'python'' "
+                        "and use a non-CasADi solver. "
+                    )
+                return casadi.interpolant("LUT", solver, symbol.x, symbol.y.flatten())(
+                    *converted_children
+                )
             elif symbol.function.__name__.startswith("elementwise_grad_of_"):
                 differentiating_child_idx = int(symbol.function.__name__[-1])
                 # Create dummy symbolic variables in order to differentiate using CasADi


Test patch:
diff --git a/tests/unit/test_expression_tree/test_operations/test_convert_to_casadi.py b/tests/unit/test_expression_tree/test_operations/test_convert_to_casadi.py
index 4e901bfef..dae333586 100644
--- a/tests/unit/test_expression_tree/test_operations/test_convert_to_casadi.py
+++ b/tests/unit/test_expression_tree/test_operations/test_convert_to_casadi.py
@@ -148,30 +148,34 @@ class TestCasadiConverter(unittest.TestCase):
         casadi_y = casadi.MX.sym("y", 2)
         # linear
         y_test = np.array([0.4, 0.6])
-        for interpolator in ["linear", "pchip", "cubic spline"]:
+        for interpolator in ["linear", "cubic spline"]:
             interp = pybamm.Interpolant(x, 2 * x, y, interpolator=interpolator)
             interp_casadi = interp.to_casadi(y=casadi_y)
             f = casadi.Function("f", [casadi_y], [interp_casadi])
             np.testing.assert_array_almost_equal(interp.evaluate(y=y_test), f(y_test))
         # square
         y = pybamm.StateVector(slice(0, 1))
-        for interpolator in ["pchip", "cubic spline"]:
-            interp = pybamm.Interpolant(x, x ** 2, y, interpolator=interpolator)
-            interp_casadi = interp.to_casadi(y=casadi_y)
-            f = casadi.Function("f", [casadi_y], [interp_casadi])
-            np.testing.assert_array_almost_equal(interp.evaluate(y=y_test), f(y_test))
+        interp = pybamm.Interpolant(x, x ** 2, y, interpolator="cubic spline")
+        interp_casadi = interp.to_casadi(y=casadi_y)
+        f = casadi.Function("f", [casadi_y], [interp_casadi])
+        np.testing.assert_array_almost_equal(interp.evaluate(y=y_test), f(y_test))
 
         # len(x)=1 but y is 2d
         y = pybamm.StateVector(slice(0, 1))
         casadi_y = casadi.MX.sym("y", 1)
         data = np.tile(2 * x, (10, 1)).T
         y_test = np.array([0.4])
-        for interpolator in ["linear", "pchip", "cubic spline"]:
+        for interpolator in ["linear", "cubic spline"]:
             interp = pybamm.Interpolant(x, data, y, interpolator=interpolator)
             interp_casadi = interp.to_casadi(y=casadi_y)
             f = casadi.Function("f", [casadi_y], [interp_casadi])
             np.testing.assert_array_almost_equal(interp.evaluate(y=y_test), f(y_test))
 
+        # error for pchip interpolator
+        interp = pybamm.Interpolant(x, data, y, interpolator="pchip")
+        with self.assertRaisesRegex(NotImplementedError, "The interpolator"):
+            interp_casadi = interp.to_casadi(y=casadi_y)
+
     def test_concatenations(self):
         y = np.linspace(0, 1, 10)[:, np.newaxis]
         a = pybamm.Vector(y)