Source code for pybamm.expression_tree.input_parameter

#
# Parameter classes
#
from __future__ import annotations
import numbers
import numpy as np
import scipy.sparse
import pybamm

from pybamm.type_definitions import DomainType


[docs] class InputParameter(pybamm.Symbol): """ A node in the expression tree representing an input parameter. This node's value can be set at the point of solving, allowing parameter estimation and control Parameters ---------- name : str name of the node domain : iterable of str, or str list of domains over which the node is valid (empty list indicates the symbol is valid over all domains) expected_size : int The size of the input parameter expected, defaults to 1 (scalar input) """ def __init__( self, name: str, domain: DomainType = None, expected_size: int | None = None, ) -> None: # Expected size defaults to 1 if no domain else None (gets set later) if expected_size is None: if domain is None: expected_size = 1 else: expected_size = None self._expected_size = expected_size super().__init__(name, domain=domain) @classmethod def _from_json(cls, snippet: dict): return cls( snippet["name"], domain=snippet["domain"], expected_size=snippet["expected_size"], )
[docs] def create_copy(self) -> pybamm.InputParameter: """See :meth:`pybamm.Symbol.new_copy()`.""" new_input_parameter = InputParameter( self.name, self.domain, expected_size=self._expected_size ) return new_input_parameter
def _evaluate_for_shape(self): """ Returns the scalar 'NaN' to represent the shape of a parameter. See :meth:`pybamm.Symbol.evaluate_for_shape()` """ if self._expected_size is None: return pybamm.evaluate_for_shape_using_domain(self.domains) elif self._expected_size == 1: return np.nan else: return np.nan * np.ones((self._expected_size, 1)) def _jac(self, variable: pybamm.StateVector) -> pybamm.Matrix: """See :meth:`pybamm.Symbol._jac()`.""" n_variable = variable.evaluation_array.count(True) nan_vector = self._evaluate_for_shape() if isinstance(nan_vector, numbers.Number): n_self = 1 else: n_self = nan_vector.shape[0] zero_matrix = scipy.sparse.csr_matrix((n_self, n_variable)) return pybamm.Matrix(zero_matrix) def _base_evaluate( self, t: float | None = None, y: np.ndarray | None = None, y_dot: np.ndarray | None = None, inputs: dict | str | None = None, ): # inputs should be a dictionary # convert 'None' to empty dictionary for more informative error if inputs is None: inputs = {} if not isinstance(inputs, dict): # if the special input "shape test" is passed, just return NaN if inputs == "shape test": return self.evaluate_for_shape() raise TypeError("inputs should be a dictionary") try: input_eval = inputs[self.name] # raise more informative error if can't find name in dict except KeyError as error: raise KeyError(f"Input parameter '{self.name}' not found") from error if isinstance(input_eval, numbers.Number): input_size = 1 input_ndim = 0 else: input_size = input_eval.shape[0] input_ndim = len(input_eval.shape) if input_size == self._expected_size: if input_ndim == 1: return input_eval[:, np.newaxis] else: return input_eval else: raise ValueError( f"Input parameter '{self.name}' was given an object of size '{input_size}'" + f" but was expecting an object of size '{self._expected_size}'." )
[docs] def to_json(self): """ Method to serialise an InputParameter object into JSON. """ json_dict = { "name": self.name, "id": self.id, "domain": self.domain, "expected_size": self._expected_size, } return json_dict