Beispiel #1
0
    def test_process_input_parameter(self):
        parameter_values = pybamm.ParameterValues({
            "a":
            "[input]",
            "b":
            3,
            "c times 2":
            pybamm.InputParameter("c") * 2
        })
        # process input parameter
        a = pybamm.Parameter("a")
        processed_a = parameter_values.process_symbol(a)
        self.assertIsInstance(processed_a, pybamm.InputParameter)
        self.assertEqual(processed_a.evaluate(inputs={"a": 5}), 5)

        # process binary operation
        b = pybamm.Parameter("b")
        add = a + b
        processed_add = parameter_values.process_symbol(add)
        self.assertIsInstance(processed_add, pybamm.Addition)
        self.assertIsInstance(processed_add.children[0], pybamm.InputParameter)
        self.assertIsInstance(processed_add.children[1], pybamm.Scalar)
        self.assertEqual(processed_add.evaluate(inputs={"a": 4}), 7)

        # process complex input parameter
        c = pybamm.Parameter("c times 2")
        processed_c = parameter_values.process_symbol(c)
        self.assertEqual(processed_c.evaluate(inputs={"c": 5}), 10)
Beispiel #2
0
    def test_symbol_replacements(self):
        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        c = pybamm.Parameter("c")
        d = pybamm.Parameter("d")
        replacer = pybamm.SymbolReplacer({a: b, c: d})

        for symbol_in, symbol_out in [
            (a, b),  # just the symbol
            (a + a, b + b),  # binary operator
            (2 * pybamm.sin(a), 2 * pybamm.sin(b)),  # function
            (3 * b, 3 * b),  # no replacement
            (a + c, b + d),  # two replacements
        ]:
            replaced_symbol = replacer.process_symbol(symbol_in)
            self.assertEqual(replaced_symbol.id, symbol_out.id)

        var1 = pybamm.Variable("var 1", domain="dom 1")
        var2 = pybamm.Variable("var 2", domain="dom 2")
        var3 = pybamm.Variable("var 3", domain="dom 1")
        conc = pybamm.concatenation(var1, var2)

        replacer = pybamm.SymbolReplacer({var1: var3})
        replaced_symbol = replacer.process_symbol(conc)
        self.assertEqual(replaced_symbol.id,
                         pybamm.concatenation(var3, var2).id)
 def beta(T):
     T_inf = pybamm.FunctionParameter("T_inf", {"x": self.x})
     h = pybamm.Parameter("h")
     eps0 = pybamm.Parameter("eps0")
     return (1e-4 * (1.0 + 5.0 * pybamm.sin(3 * np.pi * T / 200.0) +
                     pybamm.exp(0.02 * T)) / eps0 + h * (T_inf - T) /
             (T_inf**4 - T**4) / eps0)
Beispiel #4
0
def lico2_volume_change_Ai2020(sto):
    omega = pybamm.Parameter(
        "Positive electrode partial molar volume [m3.mol-1]")
    c_p_max = pybamm.Parameter(
        "Maximum concentration in positive electrode [mol.m-3]")
    t_change = omega * c_p_max * sto
    return t_change
Beispiel #5
0
    def test_unpack_list_of_symbols(self):
        a = pybamm.Scalar(1)
        b = pybamm.Parameter("b")
        c = pybamm.Parameter("c")

        unpacker = pybamm.SymbolUnpacker(pybamm.Parameter)
        unpacked = unpacker.unpack_list_of_symbols([a + b, a - c, b + c])
        # Can't check dictionary directly so check ids
        self.assertEqual(unpacked.keys(), {b.id: b, c.id: c}.keys())
        self.assertEqual(unpacked[b.id].id, b.id)
        self.assertEqual(unpacked[c.id].id, c.id)
    def test_multi_var_function_with_parameters(self):
        def D(a, b):
            return a * np.exp(b)

        parameter_values = pybamm.ParameterValues({"a": 3, "b": 0})
        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        func = pybamm.Function(D, a, b)

        processed_func = parameter_values.process_symbol(func)
        self.assertIsInstance(processed_func, pybamm.Function)
        self.assertEqual(processed_func.evaluate(), 3)
Beispiel #7
0
    def test_symbol_new_copy(self):
        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        v_n = pybamm.Variable("v", "negative electrode")
        x_n = pybamm.standard_spatial_vars.x_n
        v_s = pybamm.Variable("v", "separator")
        vec = pybamm.Vector([1, 2, 3, 4, 5])
        mat = pybamm.Matrix([[1, 2], [3, 4]])
        mesh = get_mesh_for_testing()

        for symbol in [
                a + b,
                a - b,
                a * b,
                a / b,
                a**b,
                -a,
                abs(a),
                pybamm.Function(np.sin, a),
                pybamm.FunctionParameter("function", {"a": a}),
                pybamm.grad(v_n),
                pybamm.div(pybamm.grad(v_n)),
                pybamm.upwind(v_n),
                pybamm.IndefiniteIntegral(v_n, x_n),
                pybamm.BackwardIndefiniteIntegral(v_n, x_n),
                pybamm.BoundaryValue(v_n, "right"),
                pybamm.BoundaryGradient(v_n, "right"),
                pybamm.PrimaryBroadcast(a, "domain"),
                pybamm.SecondaryBroadcast(v_n, "current collector"),
                pybamm.FullBroadcast(a, "domain",
                                     {"secondary": "other domain"}),
                pybamm.concatenation(v_n, v_s),
                pybamm.NumpyConcatenation(a, b, v_s),
                pybamm.DomainConcatenation([v_n, v_s], mesh),
                pybamm.Parameter("param"),
                pybamm.InputParameter("param"),
                pybamm.StateVector(slice(0, 56)),
                pybamm.Matrix(np.ones((50, 40))),
                pybamm.SpatialVariable("x", ["negative electrode"]),
                pybamm.t,
                pybamm.Index(vec, 1),
                pybamm.NotConstant(a),
                pybamm.ExternalVariable(
                    "external variable",
                    20,
                    domain="test",
                    auxiliary_domains={"secondary": "test2"},
                ),
                pybamm.minimum(a, b),
                pybamm.maximum(a, b),
                pybamm.SparseStack(mat, mat),
        ]:
            self.assertEqual(symbol.id, symbol.new_copy().id)
    def test_multi_var_function_parameter(self):
        def D(a, b):
            return a * pybamm.exp(b)

        parameter_values = pybamm.ParameterValues({"a": 3, "b": 0, "Diffusivity": D})

        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        func = pybamm.FunctionParameter("Diffusivity", {"a": a, "b": b})

        processed_func = parameter_values.process_symbol(func)
        self.assertEqual(processed_func.evaluate(), 3)
    def test_evaluate(self):
        parameter_values = pybamm.ParameterValues({"a": 1, "b": 2, "c": 3})
        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        c = pybamm.Parameter("c")
        self.assertEqual(parameter_values.evaluate(a), 1)
        self.assertEqual(parameter_values.evaluate(a + (b * c)), 7)

        y = pybamm.StateVector(slice(0, 1))
        with self.assertRaises(ValueError):
            parameter_values.evaluate(y)
        array = pybamm.Array(np.array([1, 2, 3]))
        with self.assertRaises(ValueError):
            parameter_values.evaluate(array)
Beispiel #10
0
    def _set_dimensional_parameters(self):
        """Defines the dimensional parameters"""

        # Reference temperature
        self.T_ref = pybamm.Parameter("Reference temperature [K]")

        # Cooling coefficient
        self.h_cn_dim = pybamm.Parameter(
            "Negative current collector surface heat transfer coefficient [W.m-2.K-1]"
        )
        self.h_cp_dim = pybamm.Parameter(
            "Positive current collector surface heat transfer coefficient [W.m-2.K-1]"
        )
        self.h_tab_n_dim = pybamm.Parameter(
            "Negative tab heat transfer coefficient [W.m-2.K-1]")
        self.h_tab_p_dim = pybamm.Parameter(
            "Positive tab heat transfer coefficient [W.m-2.K-1]")
        self.h_edge_dim = pybamm.Parameter(
            "Edge heat transfer coefficient [W.m-2.K-1]")
        self.h_total_dim = pybamm.Parameter(
            "Total heat transfer coefficient [W.m-2.K-1]")

        # Typical temperature rise
        self.Delta_T = pybamm.Scalar(1)

        # Initial temperature
        self.T_init_dim = pybamm.Parameter("Initial temperature [K]")

        # Planar (y,z) thermal diffusion timescale
        self.tau_th_yz = (self.rho_eff_dim(self.T_ref) * (self.geo.L_z**2) /
                          self.lambda_eff_dim(self.T_ref))
    def test_process_parameter_in_parameter(self):
        parameter_values = pybamm.ParameterValues(
            {"a": 2, "2a": pybamm.Parameter("a") * 2, "b": np.array([1, 2, 3])}
        )

        # process 2a parameter
        a = pybamm.Parameter("2a")
        processed_a = parameter_values.process_symbol(a)
        self.assertEqual(processed_a.evaluate(), 4)

        # case where parameter can't be processed
        b = pybamm.Parameter("b")
        with self.assertRaisesRegex(TypeError, "Cannot process parameter"):
            parameter_values.process_symbol(b)
    def test_evaluate(self):
        parameter_values = pybamm.ParameterValues({"a": 1, "b": 2, "c": 3})
        a = pybamm.Parameter("a")
        b = pybamm.Parameter("b")
        c = pybamm.Parameter("c")
        self.assertEqual(parameter_values.evaluate(a), 1)
        self.assertEqual(parameter_values.evaluate(a + (b * c)), 7)
        d = pybamm.Parameter("a") + pybamm.Parameter("b") * pybamm.Array([4, 5])
        np.testing.assert_array_equal(
            parameter_values.evaluate(d), np.array([9, 11])[:, np.newaxis]
        )

        y = pybamm.StateVector(slice(0, 1))
        with self.assertRaises(ValueError):
            parameter_values.evaluate(y)
Beispiel #13
0
    def test_symbol_evaluates_to_number(self):
        a = pybamm.Scalar(3)
        self.assertTrue(a.evaluates_to_number())

        a = pybamm.Parameter("a")
        self.assertFalse(a.evaluates_to_number())

        a = pybamm.Scalar(3) * pybamm.Time()
        self.assertTrue(a.evaluates_to_number())
        # highlight difference between this function and isinstance(a, Scalar)
        self.assertNotIsInstance(a, pybamm.Scalar)

        a = pybamm.Variable("a")
        self.assertFalse(a.evaluates_to_number())

        a = pybamm.Scalar(3) - 2
        self.assertTrue(a.evaluates_to_number())

        a = pybamm.Vector(np.ones(5))
        self.assertFalse(a.evaluates_to_number())

        a = pybamm.Matrix(np.ones((4, 6)))
        self.assertFalse(a.evaluates_to_number())

        a = pybamm.StateVector(slice(0, 10))
        self.assertFalse(a.evaluates_to_number())

        # Time variable returns true
        a = 3 * pybamm.t + 2
        self.assertTrue(a.evaluates_to_number())
    def test_interpolant_against_function(self):
        parameter_values = pybamm.ParameterValues({"a": 0.6})
        parameter_values.update(
            {
                "function": "[function]lico2_ocp_Dualfoil1998",
                "interpolation": "[data]lico2_data_example",
            },
            path=os.path.join(
                pybamm.root_dir(),
                "input",
                "parameters",
                "lithium-ion",
                "cathodes",
                "lico2_Marquis2019",
            ),
        )

        a = pybamm.Parameter("a")
        func = pybamm.FunctionParameter("function", a)
        interp = pybamm.FunctionParameter("interpolation", a)

        processed_func = parameter_values.process_symbol(func)
        processed_interp = parameter_values.process_symbol(interp)
        np.testing.assert_array_almost_equal(processed_func.evaluate(),
                                             processed_interp.evaluate(),
                                             decimal=4)

        # process differentiated function parameter
        diff_func = func.diff(a)
        diff_interp = interp.diff(a)
        processed_diff_func = parameter_values.process_symbol(diff_func)
        processed_diff_interp = parameter_values.process_symbol(diff_interp)
        np.testing.assert_array_almost_equal(processed_diff_func.evaluate(),
                                             processed_diff_interp.evaluate(),
                                             decimal=2)
Beispiel #15
0
    def test_process_parameters_and_discretise(self):
        model = pybamm.lithium_ion.SPM()
        # Set up geometry and parameters
        geometry = model.default_geometry
        parameter_values = model.default_parameter_values
        parameter_values.process_geometry(geometry)
        # Set up discretisation
        mesh = pybamm.Mesh(geometry, model.default_submesh_types, model.default_var_pts)
        disc = pybamm.Discretisation(mesh, model.default_spatial_methods)
        # Process expression
        c = pybamm.Parameter("Negative electrode thickness [m]") * pybamm.Variable(
            "X-averaged negative particle concentration",
            domain="negative particle",
            auxiliary_domains={"secondary": "current collector"},
        )
        processed_c = model.process_parameters_and_discretise(c, parameter_values, disc)
        self.assertIsInstance(processed_c, pybamm.Multiplication)
        self.assertIsInstance(processed_c.left, pybamm.Scalar)
        self.assertIsInstance(processed_c.right, pybamm.StateVector)
        # Process flux manually and check result against flux computed in particle
        # submodel
        c_n = model.variables["X-averaged negative particle concentration"]
        T = pybamm.PrimaryBroadcast(
            model.variables["X-averaged negative electrode temperature"],
            ["negative particle"],
        )
        D = model.param.D_n(c_n, T)
        N = -D * pybamm.grad(c_n)

        flux_1 = model.process_parameters_and_discretise(N, parameter_values, disc)
        flux_2 = model.variables["X-averaged negative particle flux"]
        param_flux_2 = parameter_values.process_symbol(flux_2)
        disc_flux_2 = disc.process_symbol(param_flux_2)
        self.assertEqual(flux_1.id, disc_flux_2.id)
    def test_process_function_parameter(self):
        parameter_values = pybamm.ParameterValues({
            "a":
            3,
            "func":
            pybamm.load_function("process_symbol_test_function.py"),
            "const":
            pybamm.load_function("process_symbol_test_constant_function.py"),
        })
        a = pybamm.Parameter("a")

        # process function
        func = pybamm.FunctionParameter("func", a)
        processed_func = parameter_values.process_symbol(func)
        self.assertIsInstance(processed_func, pybamm.Function)
        self.assertEqual(processed_func.evaluate(), 369)

        # process constant function
        const = pybamm.FunctionParameter("const", a)
        processed_const = parameter_values.process_symbol(const)
        self.assertIsInstance(processed_const, pybamm.Function)
        self.assertEqual(processed_const.evaluate(), 254)

        # process differentiated function parameter
        diff_func = func.diff(a)
        processed_diff_func = parameter_values.process_symbol(diff_func)
        self.assertEqual(processed_diff_func.evaluate(), 123)
    def test_process_interpolant(self):
        x = np.linspace(0, 10)[:, np.newaxis]
        data = np.hstack([x, 2 * x])
        parameter_values = pybamm.ParameterValues(
            {"a": 3.01, "Times two": ("times two", data)}
        )

        a = pybamm.Parameter("a")
        func = pybamm.FunctionParameter("Times two", {"a": a})

        processed_func = parameter_values.process_symbol(func)
        self.assertIsInstance(processed_func, pybamm.Interpolant)
        self.assertEqual(processed_func.evaluate(), 6.02)

        # process differentiated function parameter
        diff_func = func.diff(a)
        processed_diff_func = parameter_values.process_symbol(diff_func)
        self.assertEqual(processed_diff_func.evaluate(), 2)

        # interpolant defined up front
        interp2 = pybamm.Interpolant(data[:, 0], data[:, 1], a)
        processed_interp2 = parameter_values.process_symbol(interp2)
        self.assertEqual(processed_interp2.evaluate(), 6.02)

        data3 = np.hstack([x, 3 * x])
        interp3 = pybamm.Interpolant(data3[:, 0], data3[:, 1], a)
        processed_interp3 = parameter_values.process_symbol(interp3)
        self.assertEqual(processed_interp3.evaluate(), 9.03)
Beispiel #18
0
 def test_simplify(self):
     a = pybamm.Parameter("A")
     # test error
     with self.assertRaisesRegex(
             pybamm.ModelError,
             "simplify is deprecated as it now has no effect"):
         (a + a).simplify()
Beispiel #19
0
    def test_symbol_evaluates_to_constant_number(self):
        a = pybamm.Scalar(3)
        self.assertTrue(a.evaluates_to_constant_number())

        a = pybamm.Parameter("a")
        self.assertFalse(a.evaluates_to_constant_number())

        a = pybamm.Variable("a")
        self.assertFalse(a.evaluates_to_constant_number())

        a = pybamm.Scalar(3) - 2
        self.assertTrue(a.evaluates_to_constant_number())

        a = pybamm.Vector(np.ones(5))
        self.assertFalse(a.evaluates_to_constant_number())

        a = pybamm.Matrix(np.ones((4, 6)))
        self.assertFalse(a.evaluates_to_constant_number())

        a = pybamm.StateVector(slice(0, 10))
        self.assertFalse(a.evaluates_to_constant_number())

        # Time variable returns true
        a = 3 * pybamm.t + 2
        self.assertFalse(a.evaluates_to_constant_number())
Beispiel #20
0
    def test_shape_and_size_for_testing(self):
        scal = pybamm.Scalar(1)
        self.assertEqual(scal.shape_for_testing, scal.shape)
        self.assertEqual(scal.size_for_testing, scal.size)

        state = pybamm.StateVector(slice(10, 25), domain="test")
        state2 = pybamm.StateVector(slice(10, 25), domain="test 2")
        self.assertEqual(state.shape_for_testing, state.shape)

        param = pybamm.Parameter("a")
        self.assertEqual(param.shape_for_testing, ())

        func = pybamm.FunctionParameter("func", {"state": state})
        self.assertEqual(func.shape_for_testing, state.shape_for_testing)

        concat = pybamm.concatenation(state, state2)
        self.assertEqual(concat.shape_for_testing, (30, 1))
        self.assertEqual(concat.size_for_testing, 30)

        var = pybamm.Variable("var", domain="negative electrode")
        broadcast = pybamm.PrimaryBroadcast(0, "negative electrode")
        self.assertEqual(var.shape_for_testing, broadcast.shape_for_testing)
        self.assertEqual((var + broadcast).shape_for_testing,
                         broadcast.shape_for_testing)

        var = pybamm.Variable("var", domain=["random domain", "other domain"])
        broadcast = pybamm.PrimaryBroadcast(0,
                                            ["random domain", "other domain"])
        self.assertEqual(var.shape_for_testing, broadcast.shape_for_testing)
        self.assertEqual((var + broadcast).shape_for_testing,
                         broadcast.shape_for_testing)

        sym = pybamm.Symbol("sym")
        with self.assertRaises(NotImplementedError):
            sym.shape_for_testing
Beispiel #21
0
 def test_evaluate_ignoring_errors(self):
     self.assertIsNone(pybamm.t.evaluate_ignoring_errors(t=None))
     self.assertEqual(pybamm.t.evaluate_ignoring_errors(t=0), 0)
     self.assertIsNone(pybamm.Parameter("a").evaluate_ignoring_errors())
     self.assertIsNone(
         pybamm.StateVector(slice(0, 1)).evaluate_ignoring_errors())
     self.assertEqual(
         pybamm.InputParameter("a").evaluate_ignoring_errors(), 1)
Beispiel #22
0
    def _set_dimensional_parameters(self):
        "Defines the dimensional parameters"

        self.I_typ = pybamm.Parameter("Typical current [A]")
        self.Q = pybamm.Parameter("Cell capacity [A.h]")
        self.C_rate = pybamm.AbsoluteValue(self.I_typ / self.Q)
        self.n_electrodes_parallel = pybamm.Parameter(
            "Number of electrodes connected in parallel to make a cell")
        self.n_cells = pybamm.Parameter(
            "Number of cells connected in series to make a battery")
        self.i_typ = pybamm.Function(
            np.abs, self.I_typ / (self.n_electrodes_parallel * self.geo.A_cc))
        self.voltage_low_cut_dimensional = pybamm.Parameter(
            "Lower voltage cut-off [V]")
        self.voltage_high_cut_dimensional = pybamm.Parameter(
            "Upper voltage cut-off [V]")

        # Current as a function of *dimensional* time. The below is overwritten in
        # lithium_ion_parameters.py and lead_acid_parameters.py to use the correct
        # timescale used for non-dimensionalisation. For a base model, the user may
        # provide the typical timescale as a parameter.
        self.timescale = pybamm.Parameter("Typical timescale [s]")
        self.dimensional_current_with_time = pybamm.FunctionParameter(
            "Current function [A]", {"Time[s]": pybamm.t * self.timescale})
        self.dimensional_current_density_with_time = (
            self.dimensional_current_with_time /
            (self.n_electrodes_parallel * self.geo.A_cc))
Beispiel #23
0
    def test_symbol_is_constant(self):
        a = pybamm.Variable("a")
        self.assertFalse(a.is_constant())

        a = pybamm.Parameter("a")
        self.assertTrue(a.is_constant())

        a = pybamm.Scalar(1) * pybamm.Variable("a")
        self.assertFalse(a.is_constant())

        a = pybamm.Scalar(1) * pybamm.Parameter("a")
        self.assertTrue(a.is_constant())

        a = pybamm.Scalar(1) * pybamm.StateVector(slice(10))
        self.assertFalse(a.is_constant())

        a = pybamm.Scalar(1) * pybamm.Vector(np.zeros(10))
        self.assertTrue(a.is_constant())
Beispiel #24
0
def electrolyte_diffusivity_Ecker2015(c_e, T, T_inf, E_D_e, R_g):
    """
    Diffusivity of LiPF6 in EC:DMC as a function of ion concentration [1, 2, 3].

    References
    ----------
    .. [1] Ecker, Madeleine, et al. "Parameterization of a physico-chemical model of
    a lithium-ion battery i. determination of parameters." Journal of the
    Electrochemical Society 162.9 (2015): A1836-A1848.
    .. [2] Ecker, Madeleine, et al. "Parameterization of a physico-chemical model of
    a lithium-ion battery ii. model validation." Journal of The Electrochemical
    Society 162.9 (2015): A1849-A1857.
    .. [3] Richardson, Giles, et. al. "Generalised single particle models for
    high-rate operation of graded lithium-ion electrodes: Systematic derivation
    and validation." Electrochemica Acta 339 (2020): 135862

    Parameters
    ----------
    c_e: :class: `numpy.Array`
        Dimensional electrolyte concentration
    T: :class: `numpy.Array`
        Dimensional temperature
    T_inf: double
        Reference temperature
    E_D_e: double
        Electrolyte diffusion activation energy
    R_g: double
        The ideal gas constant

    Returns
    -------
    :`numpy.Array`
        Solid diffusivity
    """

    # The diffusivity epends on the electrolyte conductivity
    E_k_e = pybamm.Parameter(
        "Electrolyte conductivity activation energy [J.mol-1]")
    inputs = {
        "Electrolyte concentration [mol.m-3]": c_e,
        "Temperature [K]": T,
        "Reference temperature [K]": T_inf,
        "Activation energy [J.mol-1]": E_k_e,
        "Ideal gas constant [J.mol-1.K-1]": R_g,
    }
    sigma_e = pybamm.FunctionParameter("Electrolyte conductivity [S.m-1]",
                                       inputs)

    # constants
    k_b = constants.physical_constants["Boltzmann constant"][0]
    F = constants.physical_constants["Faraday constant"][0]
    q_e = constants.physical_constants["electron volt"][0]

    D_c_e = (k_b / (F * q_e)) * sigma_e * T / c_e

    return D_c_e
 def test_simple_model(self):
     model = pybamm.BaseModel()
     v = pybamm.Variable("v")
     a = pybamm.Parameter("a")
     model.rhs = {v: -a * v}
     model.initial_conditions = {v: 1}
     param = pybamm.ParameterValues({"a": 1})
     sim = pybamm.Simulation(model, parameter_values=param)
     sol = sim.solve([0, 1])
     np.testing.assert_array_almost_equal(sol.y.full()[0], np.exp(-sol.t), decimal=5)
Beispiel #26
0
    def test_orphans(self):
        a = pybamm.Scalar(1)
        b = pybamm.Parameter("b")
        summ = a + b

        a_orp, b_orp = summ.orphans
        self.assertIsNone(a_orp.parent)
        self.assertIsNone(b_orp.parent)
        self.assertEqual(a.id, a_orp.id)
        self.assertEqual(b.id, b_orp.id)
Beispiel #27
0
def constant_current_constant_voltage_constant_power(variables):
    I = variables["Current [A]"]
    V = variables["Terminal voltage [V]"]
    s_I = pybamm.InputParameter("Current switch")
    s_V = pybamm.InputParameter("Voltage switch")
    s_P = pybamm.InputParameter("Power switch")
    n_cells = pybamm.Parameter(
        "Number of cells connected in series to make a battery")
    return (s_I * (I - pybamm.InputParameter("Current input [A]")) + s_V *
            (V - pybamm.InputParameter("Voltage input [V]") / n_cells) + s_P *
            (V * I - pybamm.InputParameter("Power input [W]") / n_cells))
    def test_set_and_update_parameters(self):
        a = pybamm.Scalar(1)
        b = pybamm.Parameter(name="test parameter")
        c = pybamm.Scalar(3)
        eqn = a + b * c

        parameter_values = pybamm.ParameterValues({"test parameter": 2})
        eqn_processed = parameter_values.process_symbol(eqn)
        self.assertEqual(eqn_processed.evaluate(), 7)

        parameter_values = pybamm.ParameterValues({"test parameter": 3})
        eqn_updated = parameter_values.update_scalars(eqn_processed)
        self.assertEqual(eqn_updated.evaluate(), 10)
    def test_process_complex_expression(self):
        var1 = pybamm.Variable("var1")
        var2 = pybamm.Variable("var2")
        par1 = pybamm.Parameter("par1")
        par2 = pybamm.Parameter("par2")
        scal1 = pybamm.Scalar(3)
        scal2 = pybamm.Scalar(4)
        expression = (scal1 * (par1 + var2)) / ((var1 - par2) + scal2)

        param = pybamm.ParameterValues(values={"par1": 1, "par2": 2})
        exp_param = param.process_symbol(expression)
        self.assertIsInstance(exp_param, pybamm.Division)
        # left side
        self.assertIsInstance(exp_param.children[0], pybamm.Multiplication)
        self.assertIsInstance(exp_param.children[0].children[0], pybamm.Scalar)
        self.assertIsInstance(exp_param.children[0].children[1],
                              pybamm.Addition)
        self.assertTrue(
            isinstance(exp_param.children[0].children[1].children[0],
                       pybamm.Scalar))
        self.assertEqual(exp_param.children[0].children[1].children[0].value,
                         1)
        self.assertTrue(
            isinstance(exp_param.children[0].children[1].children[1],
                       pybamm.Variable))
        # right side
        self.assertIsInstance(exp_param.children[1], pybamm.Addition)
        self.assertTrue(
            isinstance(exp_param.children[1].children[0], pybamm.Subtraction))
        self.assertTrue(
            isinstance(exp_param.children[1].children[0].children[0],
                       pybamm.Variable))
        self.assertTrue(
            isinstance(exp_param.children[1].children[0].children[1],
                       pybamm.Scalar))
        self.assertEqual(exp_param.children[1].children[0].children[1].value,
                         2)
        self.assertIsInstance(exp_param.children[1].children[1], pybamm.Scalar)
Beispiel #30
0
    def test_smooth_absolute_value(self):
        # Test that smooth absolute value is used when the setting is changed
        a = pybamm.Symbol("a")
        pybamm.settings.abs_smoothing = 10
        self.assertEqual(str(abs(a)), str(pybamm.smooth_absolute_value(a, 10)))

        # But exact absolute value should still be used for constants
        a = pybamm.Parameter("a")
        self.assertEqual(str(abs(a)), str(pybamm.AbsoluteValue(a)))
        a = -1
        self.assertEqual(str(abs(a)), "1")

        # Change setting back for other tests
        pybamm.settings.abs_smoothing = "exact"