diff --git a/pybop/models/lithium_ion/utils.py b/pybop/models/lithium_ion/utils.py index be95bd80d..6448306b0 100644 --- a/pybop/models/lithium_ion/utils.py +++ b/pybop/models/lithium_ion/utils.py @@ -3,6 +3,7 @@ import numpy as np from pybamm import Interpolant as PybammInterpolant +from pybamm import Symbol from scipy import interpolate if TYPE_CHECKING: @@ -51,7 +52,7 @@ def __init__( ): self.x = np.asarray(x) self.y = np.asarray(y) - self.name = name + self.name = name if name is None else name.replace(" ", "_") self.kind = kind or "linear" self._interp_func = self._create_interpolant(bounds_error, fill_value, axis) @@ -82,14 +83,15 @@ def __call__(self, x: float | np.ndarray): float, array_like, or pybamm.Interpolant Interpolated values or PyBaMM interpolant object. """ - try: - # Try numeric evaluation first - return self._interp_func(x) - except Exception: - # Fall back to PyBaMM interpolant for symbolic evaluation + if isinstance(x, Symbol): # symbolic evaluation return PybammInterpolant( self.x, self.y, x, name=self.name, interpolator=self.kind ) + else: # numeric evaluation + return self._interp_func(x) + + def __repr__(self): + return f"{self.name}, {self.kind} interpolant" class InverseOCV: @@ -116,11 +118,13 @@ def __init__( self.optimiser = optimiser or SciPyMinimize self.optimiser_options = optimiser_options or self.optimiser.default_options() - parameters = Parameters({"Root": Parameter(initial_value=0.5, bounds=[0, 1])}) + self.parameters = Parameters( + {"Root": Parameter(initial_value=0.5, bounds=[0, 1])} + ) # Set up a root-finding cost function class OCVRoot(BaseSimulator): - def __init__(self, ocv_value: float): + def __init__(self, parameters: Parameters, ocv_value: float): super().__init__(parameters=parameters) self.ocv_value = ocv_value @@ -153,7 +157,7 @@ def __call__(self, ocv_value: float) -> float: float The stoichiometry corresponding to the open-circuit voltage value. """ - problem = Problem(self.ocv_root(ocv_value), self.cost) + problem = Problem(self.ocv_root(self.parameters, ocv_value), self.cost) optim = self.optimiser(problem, options=self.optimiser_options) result = optim.run() return result.best_inputs["Root"] diff --git a/pybop/parameters/distributions.py b/pybop/parameters/distributions.py index 0b8ae4c8e..2572555b2 100644 --- a/pybop/parameters/distributions.py +++ b/pybop/parameters/distributions.py @@ -431,7 +431,7 @@ def __init__( self.initial_value = ( None if initial_value is None - else float(np.minimum(np.maximum(initial_value, lower), upper)) + else float(np.clip(initial_value, lower, upper)) ) def support(self) -> tuple[float]: