diff --git a/pybamm/expression_tree/parameter.py b/pybamm/expression_tree/parameter.py index 805861e374..daab7ddf85 100644 --- a/pybamm/expression_tree/parameter.py +++ b/pybamm/expression_tree/parameter.py @@ -48,26 +48,21 @@ class FunctionParameter(pybamm.Symbol): name : str name of the node - child : :class:`Symbol` - child node + inputs : dict + A dictionary with string keys and :class:`pybamm.Symbol` values representing + the function inputs. diff_variable : :class:`pybamm.Symbol`, optional if diff_variable is specified, the FunctionParameter node will be replaced by a :class:`pybamm.Function` and then differentiated with respect to diff_variable. Default is None. - description: str - A description of the function. - inputs: list - A list of strings describing the inputs. - outputs: list - A list of string describing the outputs. """ def __init__( - self, name, *children, diff_variable=None, inputs=None, + self, name, inputs, diff_variable=None, ): # assign diff variable self.diff_variable = diff_variable - children_list = list(children) + children_list = list(inputs.values()) # Turn numbers into scalars for idx, child in enumerate(children_list): @@ -83,16 +78,16 @@ def __init__( auxiliary_domains=auxiliary_domains, ) - self.inputs = inputs + self.input_names = list(inputs.keys()) @property - def inputs(self): + def input_names(self): if self._inputs: - for inp in self._inputs: + for inp in self._input_names: print(inp) - @inputs.setter - def inputs(self, inp=None): + @input_names.setter + def inputs_names(self, inp=None): if inp: if inp.__class__ is list: for i in inp: @@ -103,7 +98,7 @@ def inputs(self, inp=None): else: raise TypeError("Inputs must be a provided as a list of strings") - self._inputs = inp + self._input_names = inp def set_id(self): """See :meth:`pybamm.Symbol.set_id` """ @@ -136,19 +131,24 @@ def diff(self, variable): """ See :meth:`pybamm.Symbol.diff()`. """ # return a new FunctionParameter, that knows it will need to be differentiated # when the parameters are set - return FunctionParameter( - self.name, *self.orphans, diff_variable=variable, inputs=self._inputs - ) + children_list = self.orphans + input_names = self._input_names + + input_dict = {input_names[i]: children_list[i] for i in range(len(input_names))} + + return FunctionParameter(self.name, input_dict, diff_variable=variable) def new_copy(self): """ See :meth:`pybamm.Symbol.new_copy()`. """ - return self._function_parameter_new_copy(self.orphans) + return self._function_parameter_new_copy(self.input_names, self.orphans) - def _function_parameter_new_copy(self, children): + def _function_parameter_new_copy(self, input_names, children): """Returns a new copy of the function parameter. Inputs ------ + input_names : : list + A list of str of the names of the children/function inputs children : : list A list of the children of the function @@ -157,8 +157,11 @@ def _function_parameter_new_copy(self, children): : :pybamm.FunctionParameter A new copy of the function parameter """ + + input_dict = {input_names[i]: children[i] for i in range(len(input_names))} + return FunctionParameter( - self.name, *children, diff_variable=self.diff_variable, inputs=self._inputs + self.name, input_dict, diff_variable=self.diff_variable ) def _evaluate_for_shape(self): diff --git a/pybamm/parameters/electrical_parameters.py b/pybamm/parameters/electrical_parameters.py index e2f0de71d9..b98c0d2e7f 100644 --- a/pybamm/parameters/electrical_parameters.py +++ b/pybamm/parameters/electrical_parameters.py @@ -26,7 +26,7 @@ # the user may provide the typical timescale as a parameter. timescale = pybamm.Parameter("Typical timescale [s]") dimensional_current_with_time = pybamm.FunctionParameter( - "Current function [A]", pybamm.t * timescale, inputs=["Time [s]"] + "Current function [A]", {"Time[s]": pybamm.t * timescale} ) dimensional_current_density_with_time = dimensional_current_with_time / ( n_electrodes_parallel * pybamm.geometric_parameters.A_cc diff --git a/pybamm/parameters/standard_parameters_lead_acid.py b/pybamm/parameters/standard_parameters_lead_acid.py index 55e7c933c2..0d290005f2 100644 --- a/pybamm/parameters/standard_parameters_lead_acid.py +++ b/pybamm/parameters/standard_parameters_lead_acid.py @@ -174,28 +174,19 @@ def D_e_dimensional(c_e, T): "Dimensional diffusivity in electrolyte" - return pybamm.FunctionParameter( - "Electrolyte diffusivity [m2.s-1]", - c_e, - inputs=["Electrolyte concentration [mol.m-3"], - ) + inputs = {"Electrolyte concentration [mol.m-3": c_e} + return pybamm.FunctionParameter("Electrolyte diffusivity [m2.s-1]", inputs) def kappa_e_dimensional(c_e, T): "Dimensional electrolyte conductivity" - return pybamm.FunctionParameter( - "Electrolyte conductivity [S.m-1]", - c_e, - inputs=["Electrolyte concentration [mol.m-3]"], - ) + inputs = {"Electrolyte concentration [mol.m-3]": c_e} + return pybamm.FunctionParameter("Electrolyte conductivity [S.m-1]", inputs) def chi_dimensional(c_e): - return pybamm.FunctionParameter( - "Darken thermodynamic factor", - c_e, - inputs=["Electrolyte concentration [mol.m-3]"], - ) + inputs = {"Electrolyte concentration [mol.m-3]": c_e} + return pybamm.FunctionParameter("Darken thermodynamic factor", inputs) def c_w_dimensional(c_e, c_ox=0, c_hy=0): @@ -236,43 +227,37 @@ def mu_dimensional(c_e): """ Dimensional viscosity of electrolyte [kg.m-1.s-1]. """ - return pybamm.FunctionParameter( - "Electrolyte viscosity [kg.m-1.s-1]", - c_e, - inputs=["Electrolyte concentration [mol.m-3]"], - ) + inputs = {"Electrolyte concentration [mol.m-3]": c_e} + return pybamm.FunctionParameter("Electrolyte viscosity [kg.m-1.s-1]", inputs) def U_n_dimensional(c_e, T): "Dimensional open-circuit voltage in the negative electrode [V]" + inputs = {"Electrolyte molar mass [mol.kg-1]": m_dimensional(c_e)} return pybamm.FunctionParameter( - "Negative electrode open-circuit potential [V]", - m_dimensional(c_e), - inputs=["Electrolyte concentration [mol.m-3]"], + "Negative electrode open-circuit potential [V]", inputs ) def U_p_dimensional(c_e, T): "Dimensional open-circuit voltage in the positive electrode [V]" + inputs = {"Electrolyte molar mass [mol.kg-1]": m_dimensional(c_e)} return pybamm.FunctionParameter( - "Positive electrode open-circuit potential [V]", - m_dimensional(c_e), - inputs=["Electrolyte concentration [mol.m-3]"], + "Positive electrode open-circuit potential [V]", inputs ) D_e_typ = D_e_dimensional(c_e_typ, T_ref) rho_typ = rho_dimensional(c_e_typ) mu_typ = mu_dimensional(c_e_typ) + +inputs = {"Electrolyte concentration [mol.m-3]": pybamm.Scalar(1)} U_n_ref = pybamm.FunctionParameter( - "Negative electrode open-circuit potential [V]", - pybamm.Scalar(1), - inputs=["Electrolyte concentration [mol.m-3]"], + "Negative electrode open-circuit potential [V]", inputs ) +inputs = {"Electrolyte concentration [mol.m-3]": pybamm.Scalar(1)} U_p_ref = pybamm.FunctionParameter( - "Positive electrode open-circuit potential [V]", - pybamm.Scalar(1), - inputs=["Electrolyte concentration [mol.m-3]"], + "Positive electrode open-circuit potential [V]", inputs ) @@ -516,7 +501,7 @@ def U_p(c_e_p, T): # 6. Input current and voltage dimensional_current_with_time = pybamm.FunctionParameter( - "Current function [A]", pybamm.t * timescale, inputs=["Time [s]"] + "Current function [A]", {"Time [s]": pybamm.t * timescale} ) dimensional_current_density_with_time = dimensional_current_with_time / ( n_electrodes_parallel * pybamm.geometric_parameters.A_cc diff --git a/pybamm/parameters/standard_parameters_lithium_ion.py b/pybamm/parameters/standard_parameters_lithium_ion.py index 08589da4a5..4e68ca6709 100644 --- a/pybamm/parameters/standard_parameters_lithium_ion.py +++ b/pybamm/parameters/standard_parameters_lithium_ion.py @@ -108,19 +108,17 @@ def c_n_init_dimensional(x): "Initial concentration as a function of dimensionless position x" + inputs = {"Dimensionless through-cell position (x_n)": x} return pybamm.FunctionParameter( - "Initial concentration in negative electrode [mol.m-3]", - x, - inputs=["Dimensionless through-cell position (x_n)"], + "Initial concentration in negative electrode [mol.m-3]", inputs ) def c_p_init_dimensional(x): "Initial concentration as a function of dimensionless position x" + inputs = {"Dimensionless through-cell position (x_p)": x} return pybamm.FunctionParameter( - "Initial concentration in positive electrode [mol.m-3]", - x, - inputs=["Dimensionless through-cell position (x_p)"], + "Initial concentration in positive electrode [mol.m-3]", inputs ) @@ -144,112 +142,88 @@ def c_p_init_dimensional(x): def D_e_dimensional(c_e, T): "Dimensional diffusivity in electrolyte" - inputs = [ - "Electrolyte concentration [mol.m-3]", - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] - return pybamm.FunctionParameter( - "Electrolyte diffusivity [m2.s-1]", c_e, T, T_ref, E_D_e, R, inputs=inputs - ) + inputs = { + "Electrolyte concentration [mol.m-3]": c_e, + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_D_e, + "Ideal gas constant [J.mol-1.K-1]": R, + } + return pybamm.FunctionParameter("Electrolyte diffusivity [m2.s-1]", inputs) def kappa_e_dimensional(c_e, T): "Dimensional electrolyte conductivity" - inputs = [ - "Electrolyte concentration [mol.m-3]", - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] - return pybamm.FunctionParameter( - "Electrolyte conductivity [S.m-1]", c_e, T, T_ref, E_k_e, R, inputs=inputs - ) + inputs = { + "Electrolyte concentration [mol.m-3]": c_e, + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_k_e, + "Ideal gas constant [J.mol-1.K-1]": R, + } + return pybamm.FunctionParameter("Electrolyte conductivity [S.m-1]", inputs) def D_n_dimensional(sto, T): """Dimensional diffusivity in negative particle. Note this is defined as a function of stochiometry""" - inputs = [ - "Negative particle stoichiometry", - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] + inputs = { + "Negative particle stoichiometry": sto, + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_D_s_n, + "Ideal gas constant [J.mol-1.K-1]": R, + } - return pybamm.FunctionParameter( - "Negative electrode diffusivity [m2.s-1]", - sto, - T, - T_ref, - E_D_s_n, - R, - inputs=inputs, - ) + return pybamm.FunctionParameter("Negative electrode diffusivity [m2.s-1]", inputs) def D_p_dimensional(sto, T): """Dimensional diffusivity in positive particle. Note this is defined as a function of stochiometry""" - inputs = [ - "Positive particle stoichiometry", - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] - return pybamm.FunctionParameter( - "Positive electrode diffusivity [m2.s-1]", - sto, - T, - T_ref, - E_D_s_p, - R, - inputs=inputs, - ) + inputs = { + "Positive particle stoichiometry": sto, + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_D_s_p, + "Ideal gas constant [J.mol-1.K-1]": R, + } + return pybamm.FunctionParameter("Positive electrode diffusivity [m2.s-1]", inputs) def m_n_dimensional(T): "Dimensional negative reaction rate" - inputs = [ - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] - return pybamm.FunctionParameter( - "Negative electrode reaction rate", T, T_ref, E_r_n, R, inputs=inputs - ) + inputs = { + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_r_n, + "Ideal gas constant [J.mol-1.K-1]": R, + } + return pybamm.FunctionParameter("Negative electrode reaction rate", inputs) def m_p_dimensional(T): "Dimensional negative reaction rate" - inputs = [ - "Temperature [K]", - "Reference temperature [K]", - "Activation energy [J.mol-1]", - "Ideal gas constant [J.mol-1.K-1]", - ] - return pybamm.FunctionParameter( - "Positive electrode reaction rate", T, T_ref, E_r_p, R, inputs=inputs - ) + inputs = { + "Temperature [K]": T, + "Reference temperature [K]": T_ref, + "Activation energy [J.mol-1]": E_r_p, + "Ideal gas constant [J.mol-1.K-1]": R, + } + return pybamm.FunctionParameter("Positive electrode reaction rate", inputs) def dUdT_n_dimensional(sto): """ Dimensional entropic change of the negative electrode open-circuit potential [V.K-1] """ - inputs = [ - "Negative particle stoichiometry", - "Max negative particle concentration [mol.m-3]", - ] + inputs = { + "Negative particle stoichiometry": sto, + "Max negative particle concentration [mol.m-3]": c_n_max, + } return pybamm.FunctionParameter( - "Negative electrode OCP entropic change [V.K-1]", sto, c_n_max, inputs=inputs + "Negative electrode OCP entropic change [V.K-1]", inputs ) @@ -257,30 +231,26 @@ def dUdT_p_dimensional(sto): """ Dimensional entropic change of the positive electrode open-circuit potential [V.K-1] """ - inputs = [ - "Positive particle stoichiometry", - "Max positive particle concentration [mol.m-3]", - ] + inputs = { + "Positive particle stoichiometry": sto, + "Max positive particle concentration [mol.m-3]": c_p_max, + } return pybamm.FunctionParameter( - "Positive electrode OCP entropic change [V.K-1]", sto, c_p_max, inputs=inputs + "Positive electrode OCP entropic change [V.K-1]", inputs ) def U_n_dimensional(sto, T): "Dimensional open-circuit potential in the negative electrode [V]" - inputs = [ - "Negative particle stoichiometry", - ] - u_ref = pybamm.FunctionParameter("Negative electrode OCP [V]", sto, inputs=inputs) + inputs = {"Negative particle stoichiometry": sto} + u_ref = pybamm.FunctionParameter("Negative electrode OCP [V]", inputs) return u_ref + (T - T_ref) * dUdT_n_dimensional(sto) def U_p_dimensional(sto, T): "Dimensional open-circuit potential in the positive electrode [V]" - inputs = [ - "Positive particle stoichiometry", - ] - u_ref = pybamm.FunctionParameter("Positive electrode OCP [V]", sto, inputs=inputs) + inputs = {"Positive particle stoichiometry": sto} + u_ref = pybamm.FunctionParameter("Positive electrode OCP [V]", inputs) return u_ref + (T - T_ref) * dUdT_p_dimensional(sto) @@ -364,22 +334,18 @@ def U_p_dimensional(sto, T): centre_z_tab_p = pybamm.geometric_parameters.centre_z_tab_p # Microscale geometry -epsilon_n = pybamm.FunctionParameter( - "Negative electrode porosity", - pybamm.standard_spatial_vars.x_n, - inputs=["Through-cell distance (x_n) [m]"], -) -epsilon_s = pybamm.FunctionParameter( - "Separator porosity", - pybamm.standard_spatial_vars.x_s, - inputs=["Through-cell distance (x_s) [m]"], -) -epsilon_p = pybamm.FunctionParameter( - "Positive electrode porosity", - pybamm.standard_spatial_vars.x_p, - inputs=["Through-cell distance (x_p) [m]"], -) + +inputs = {"Through-cell distance (x_n) [m]": pybamm.standard_spatial_vars.x_n} +epsilon_n = pybamm.FunctionParameter("Negative electrode porosity", inputs) + +inputs = {"Through-cell distance (x_s) [m]": pybamm.standard_spatial_vars.x_s} +epsilon_s = pybamm.FunctionParameter("Separator porosity", inputs) + +inputs = {"Through-cell distance (x_p) [m]": pybamm.standard_spatial_vars.x_p} +epsilon_p = pybamm.FunctionParameter("Positive electrode porosity", inputs) + epsilon = pybamm.Concatenation(epsilon_n, epsilon_s, epsilon_p) + epsilon_s_n = pybamm.Parameter("Negative electrode active material volume fraction") epsilon_s_p = pybamm.Parameter("Positive electrode active material volume fraction") epsilon_inactive_n = 1 - epsilon_n - epsilon_s_n @@ -552,7 +518,7 @@ def dUdT_p(c_s_p): # 6. Input current and voltage dimensional_current_with_time = pybamm.FunctionParameter( - "Current function [A]", pybamm.t * timescale, inputs=["Time [s]"] + "Current function [A]", {"Time [s]": pybamm.t * timescale} ) dimensional_current_density_with_time = dimensional_current_with_time / ( n_electrodes_parallel * pybamm.geometric_parameters.A_cc