示例#1
0
    def test_advanced_functions(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))
        y = np.array([5, 3])

        #
        func = a * pybamm.exp(b)
        self.assertAlmostEqual(func.diff(a).evaluate(y=y)[0], np.exp(3))
        func = pybamm.exp(a + 2 * b + a * b) + a * pybamm.exp(b)
        self.assertEqual(
            func.diff(a).evaluate(y=y), (4 * np.exp(3 * 5 + 5 + 2 * 3) + np.exp(3))
        )
        self.assertEqual(
            func.diff(b).evaluate(y=y), np.exp(3) * (7 * np.exp(3 * 5 + 5 + 3) + 5)
        )
        #
        func = pybamm.sin(pybamm.cos(a * 4) / 2) * pybamm.cos(4 * pybamm.exp(b / 3))
        self.assertEqual(
            func.diff(a).evaluate(y=y),
            -2 * np.sin(20) * np.cos(np.cos(20) / 2) * np.cos(4 * np.exp(1)),
        )
        self.assertEqual(
            func.diff(b).evaluate(y=y),
            -4 / 3 * np.exp(1) * np.sin(4 * np.exp(1)) * np.sin(np.cos(20) / 2),
        )
        #
        func = pybamm.sin(a * b)
        self.assertEqual(func.diff(a).evaluate(y=y), 3 * np.cos(15))
示例#2
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
    def test_known_eval(self):
        # Scalars
        a = pybamm.Scalar(4)
        b = pybamm.StateVector(slice(0, 1))
        expr = (a + b) - (a + b) * (a + b)
        value = expr.evaluate(y=np.array([2]))
        self.assertEqual(expr.evaluate(y=np.array([2]), known_evals={})[0], value)
        self.assertIn((a + b).id, expr.evaluate(y=np.array([2]), known_evals={})[1])
        self.assertEqual(
            expr.evaluate(y=np.array([2]), known_evals={})[1][(a + b).id], 6
        )

        # Matrices
        a = pybamm.Matrix(np.random.rand(5, 5))
        b = pybamm.StateVector(slice(0, 5))
        expr2 = (a @ b) - (a @ b) * (a @ b) + (a @ b)
        y_test = np.linspace(0, 1, 5)
        value = expr2.evaluate(y=y_test)
        np.testing.assert_array_equal(
            expr2.evaluate(y=y_test, known_evals={})[0], value
        )
        self.assertIn((a @ b).id, expr2.evaluate(y=y_test, known_evals={})[1])
        np.testing.assert_array_equal(
            expr2.evaluate(y=y_test, known_evals={})[1][(a @ b).id],
            (a @ b).evaluate(y=y_test),
        )
    def test_interpolation(self):
        x = np.linspace(0, 1)
        y = pybamm.StateVector(slice(0, 2))
        casadi_y = casadi.MX.sym("y", 2)
        # linear
        y_test = np.array([0.4, 0.6])
        for interpolator in ["linear", "pchip", "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))

        # 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"]:
            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))
示例#5
0
    def test_diff(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))
        y = np.array([5])
        func = pybamm.Function(test_function, a)
        self.assertEqual(func.diff(a).evaluate(y=y), 2)
        self.assertEqual(func.diff(func).evaluate(), 1)
        func = pybamm.sin(a)
        self.assertEqual(func.evaluate(y=y), np.sin(a.evaluate(y=y)))
        self.assertEqual(func.diff(a).evaluate(y=y), np.cos(a.evaluate(y=y)))
        func = pybamm.exp(a)
        self.assertEqual(func.evaluate(y=y), np.exp(a.evaluate(y=y)))
        self.assertEqual(func.diff(a).evaluate(y=y), np.exp(a.evaluate(y=y)))

        # multiple variables
        func = pybamm.Function(test_multi_var_function, 4 * a, 3 * a)
        self.assertEqual(func.diff(a).evaluate(y=y), 7)
        func = pybamm.Function(test_multi_var_function, 4 * a, 3 * b)
        self.assertEqual(func.diff(a).evaluate(y=np.array([5, 6])), 4)
        self.assertEqual(func.diff(b).evaluate(y=np.array([5, 6])), 3)
        func = pybamm.Function(test_multi_var_function_cube, 4 * a, 3 * b)
        self.assertEqual(func.diff(a).evaluate(y=np.array([5, 6])), 4)
        self.assertEqual(
            func.diff(b).evaluate(y=np.array([5, 6])), 3 * 3 * (3 * 6) ** 2
        )

        # exceptions
        func = pybamm.Function(
            test_multi_var_function_cube, 4 * a, 3 * b, derivative="derivative"
        )
        with self.assertRaises(ValueError):
            func.diff(a)
示例#6
0
    def test_interpolation(self):
        x = np.linspace(0, 1)[:, np.newaxis]
        y = pybamm.StateVector(slice(0, 2))
        # linear
        linear = np.hstack([x, 2 * x])
        for interpolator in ["pchip", "cubic spline"]:
            interp = pybamm.Interpolant(linear, y, interpolator=interpolator)
            np.testing.assert_array_almost_equal(
                interp.evaluate(y=np.array([0.397, 1.5]))[:, 0],
                np.array([0.794, 3]))
        # square
        square = np.hstack([x, x**2])
        y = pybamm.StateVector(slice(0, 1))
        for interpolator in ["pchip", "cubic spline"]:
            interp = pybamm.Interpolant(square, y, interpolator=interpolator)
            np.testing.assert_array_almost_equal(
                interp.evaluate(y=np.array([0.397]))[:, 0],
                np.array([0.397**2]))

        # with extrapolation set to False
        for interpolator in ["pchip", "cubic spline"]:
            interp = pybamm.Interpolant(square,
                                        y,
                                        interpolator=interpolator,
                                        extrapolate=False)
            np.testing.assert_array_equal(
                interp.evaluate(y=np.array([2]))[:, 0], np.array([np.nan]))
示例#7
0
 def test_test_shape(self):
     # right shape, passes
     y1 = pybamm.StateVector(slice(0, 10))
     y1.test_shape()
     # bad shape, fails
     y2 = pybamm.StateVector(slice(0, 5))
     with self.assertRaises(pybamm.ShapeError):
         (y1 + y2).test_shape()
示例#8
0
 def test_name(self):
     sv = pybamm.StateVector(slice(0, 10))
     self.assertEqual(sv.name, "y[0:10]")
     sv = pybamm.StateVector(slice(0, 10), slice(20, 30))
     self.assertEqual(sv.name, "y[0:10,20:30]")
     sv = pybamm.StateVector(slice(0, 10), slice(20, 30), slice(40, 50),
                             slice(60, 70))
     self.assertEqual(sv.name, "y[0:10,20:30,...,60:70]")
示例#9
0
    def test_functions(self):
        y = pybamm.StateVector(slice(0, 4))
        u = pybamm.StateVector(slice(0, 2))
        v = pybamm.StateVector(slice(2, 4))
        const = pybamm.Scalar(1)

        y0 = np.array([1.0, 2.0, 3.0, 4.0])

        func = pybamm.sin(u)
        jacobian = np.array([[np.cos(1), 0, 0, 0], [0, np.cos(2), 0, 0]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.cos(v)
        jacobian = np.array([[0, 0, -np.sin(3), 0], [0, 0, 0, -np.sin(4)]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.sin(3 * u * v)
        jacobian = np.array(
            [
                [9 * np.cos(9), 0, 3 * np.cos(9), 0],
                [0, 12 * np.cos(24), 0, 6 * np.cos(24)],
            ]
        )
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.cos(5 * pybamm.exp(u + v))
        jacobian = np.array(
            [
                [
                    -5 * np.exp(4) * np.sin(5 * np.exp(4)),
                    0,
                    -5 * np.exp(4) * np.sin(5 * np.exp(4)),
                    0,
                ],
                [
                    0,
                    -5 * np.exp(6) * np.sin(5 * np.exp(6)),
                    0,
                    -5 * np.exp(6) * np.sin(5 * np.exp(6)),
                ],
            ]
        )
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        # when child evaluates to number
        func = pybamm.Sin(const)
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(0, dfunc_dy)

        # several children
        func = pybamm.Function(test_multi_var_function, 2 * y, 3 * y)
        jacobian = np.diag(5 * np.ones(4))
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())
示例#10
0
    def test_nonlinear(self):
        y = pybamm.StateVector(slice(0, 8))
        u = pybamm.StateVector(slice(0, 2), slice(4, 6))
        v = pybamm.StateVector(slice(2, 4), slice(6, 8))

        y0 = np.arange(1, 9)

        func = v**2
        jacobian = np.array([
            [0, 0, 6, 0, 0, 0, 0, 0],
            [0, 0, 0, 8, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 14, 0],
            [0, 0, 0, 0, 0, 0, 0, 16],
        ])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = 2**v
        jacobian = np.array([
            [0, 0, 2**3 * np.log(2), 0, 0, 0, 0, 0],
            [0, 0, 0, 2**4 * np.log(2), 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 2**7 * np.log(2), 0],
            [0, 0, 0, 0, 0, 0, 0, 2**8 * np.log(2)],
        ])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = v**v
        jacobian = [
            [0, 0, 27 * (1 + np.log(3)), 0, 0, 0, 0, 0],
            [0, 0, 0, 256 * (1 + np.log(4)), 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 823543 * (1 + np.log(7)), 0],
            [0, 0, 0, 0, 0, 0, 0, 16777216 * (1 + np.log(8))],
        ]
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_almost_equal(jacobian, dfunc_dy.toarray())

        func = u * v
        jacobian = np.array([
            [3, 0, 1, 0, 0, 0, 0, 0],
            [0, 4, 0, 2, 0, 0, 0, 0],
            [0, 0, 0, 0, 7, 0, 5, 0],
            [0, 0, 0, 0, 0, 8, 0, 6],
        ])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = u * (u + v)
        jacobian = np.array([
            [5, 0, 1, 0, 0, 0, 0, 0],
            [0, 8, 0, 2, 0, 0, 0, 0],
            [0, 0, 0, 0, 17, 0, 5, 0],
            [0, 0, 0, 0, 0, 20, 0, 6],
        ])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())
示例#11
0
 def test_interpolation_2_x_2d_y(self):
     x = (np.arange(-5.01, 5.01, 0.05), np.arange(-5.01, 5.01, 0.05))
     xx, yy = np.meshgrid(x[0], x[1])
     z = np.sin(xx**2 + yy**2)
     var1 = pybamm.StateVector(slice(0, 1))
     var2 = pybamm.StateVector(slice(1, 2))
     # linear
     interp = pybamm.Interpolant(x, z, (var1, var2), interpolator="linear")
     np.testing.assert_array_almost_equal(
         interp.evaluate(y=np.array([0, 0])), 0, decimal=3)
示例#12
0
 def test_jac_of_inner(self):
     a = pybamm.Scalar(1)
     b = pybamm.Scalar(2)
     y = pybamm.StateVector(slice(0, 1))
     self.assertEqual(pybamm.inner(a, b).jac(y).evaluate(), 0)
     self.assertEqual(pybamm.inner(a, y).jac(y).evaluate(), 1)
     self.assertEqual(pybamm.inner(y, b).jac(y).evaluate(), 2)
     vec = pybamm.StateVector(slice(0, 2))
     jac = pybamm.inner(a * vec, b * vec).jac(vec).evaluate(y=np.ones(2)).toarray()
     np.testing.assert_array_equal(jac, 4 * np.eye(2))
示例#13
0
 def test_multislice_raises(self):
     y1 = pybamm.StateVector(slice(0, 4), slice(7, 8))
     y_dot1 = pybamm.StateVectorDot(slice(0, 4), slice(7, 8))
     y2 = pybamm.StateVector(slice(4, 7))
     with self.assertRaises(NotImplementedError):
         y1.jac(y1)
     with self.assertRaises(NotImplementedError):
         y2.jac(y1)
     with self.assertRaises(NotImplementedError):
         y_dot1.jac(y1)
示例#14
0
    def test_functions(self):
        y = pybamm.StateVector(slice(0, 8))
        u = pybamm.StateVector(slice(0, 2), slice(4, 6))
        v = pybamm.StateVector(slice(2, 4), slice(6, 8))

        y0 = np.arange(1, 9)
        const = pybamm.Scalar(1)

        func = pybamm.sin(u)
        jacobian = np.array(
            [
                [np.cos(1), 0, 0, 0, 0, 0, 0, 0],
                [0, np.cos(2), 0, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, np.cos(5), 0, 0, 0],
                [0, 0, 0, 0, 0, np.cos(6), 0, 0],
            ]
        )
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.cos(v)
        jacobian = np.array(
            [
                [0, 0, -np.sin(3), 0, 0, 0, 0, 0],
                [0, 0, 0, -np.sin(4), 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 0, -np.sin(7), 0],
                [0, 0, 0, 0, 0, 0, 0, -np.sin(8)],
            ]
        )
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.sin(3 * u * v)
        jacobian = np.array(
            [
                [9 * np.cos(9), 0, 3 * np.cos(9), 0, 0, 0, 0, 0],
                [0, 12 * np.cos(24), 0, 6 * np.cos(24), 0, 0, 0, 0],
                [0, 0, 0, 0, 21 * np.cos(105), 0, 15 * np.cos(105), 0],
                [0, 0, 0, 0, 0, 24 * np.cos(144), 0, 18 * np.cos(144)],
            ]
        )
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        # when child evaluates to number
        func = pybamm.sin(const)
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(0, dfunc_dy)

        # several children
        func = pybamm.Function(test_multi_var_function, 2 * y, 3 * y)
        jacobian = np.diag(5 * np.ones(8))
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())
示例#15
0
 def test_evaluate_list(self):
     sv = pybamm.StateVector(slice(0, 11), slice(20, 31))
     y = np.linspace(0, 3, 31)
     np.testing.assert_array_almost_equal(
         sv.evaluate(y=y),
         np.concatenate([np.linspace(0, 1, 11), np.linspace(2, 3, 11)])[
             :, np.newaxis
         ],
     )
     sv = pybamm.StateVector(slice(0, 11), slice(11, 20), slice(20, 31))
     y = np.linspace(0, 3, 31)
     np.testing.assert_array_almost_equal(sv.evaluate(y=y), y[:, np.newaxis])
示例#16
0
    def test_diff(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))
        y = np.array([5, 3])

        # power
        self.assertEqual((a ** b).diff(b).evaluate(y=y), 5 ** 3 * np.log(5))
        self.assertEqual((a ** b).diff(a).evaluate(y=y), 3 * 5 ** 2)
        self.assertEqual((a ** b).diff(a ** b).evaluate(), 1)
        self.assertEqual(
            (a ** a).diff(a).evaluate(y=y), 5 ** 5 * np.log(5) + 5 * 5 ** 4
        )
        self.assertEqual((a ** a).diff(b).evaluate(y=y), 0)

        # addition
        self.assertEqual((a + b).diff(a).evaluate(), 1)
        self.assertEqual((a + b).diff(b).evaluate(), 1)
        self.assertEqual((a + b).diff(a + b).evaluate(), 1)
        self.assertEqual((a + a).diff(a).evaluate(), 2)
        self.assertEqual((a + a).diff(b).evaluate(), 0)

        # subtraction
        self.assertEqual((a - b).diff(a).evaluate(), 1)
        self.assertEqual((a - b).diff(b).evaluate(), -1)
        self.assertEqual((a - b).diff(a - b).evaluate(), 1)
        self.assertEqual((a - a).diff(a).evaluate(), 0)
        self.assertEqual((a + a).diff(b).evaluate(), 0)

        # multiplication
        self.assertEqual((a * b).diff(a).evaluate(y=y), 3)
        self.assertEqual((a * b).diff(b).evaluate(y=y), 5)
        self.assertEqual((a * b).diff(a * b).evaluate(y=y), 1)
        self.assertEqual((a * a).diff(a).evaluate(y=y), 10)
        self.assertEqual((a * a).diff(b).evaluate(y=y), 0)

        # matrix multiplication (not implemented)
        matmul = a @ b
        with self.assertRaises(NotImplementedError):
            matmul.diff(a)

        # inner
        self.assertEqual(pybamm.inner(a, b).diff(a).evaluate(y=y), 3)
        self.assertEqual(pybamm.inner(a, b).diff(b).evaluate(y=y), 5)
        self.assertEqual(pybamm.inner(a, b).diff(pybamm.inner(a, b)).evaluate(y=y), 1)
        self.assertEqual(pybamm.inner(a, a).diff(a).evaluate(y=y), 10)
        self.assertEqual(pybamm.inner(a, a).diff(b).evaluate(y=y), 0)

        # division
        self.assertEqual((a / b).diff(a).evaluate(y=y), 1 / 3)
        self.assertEqual((a / b).diff(b).evaluate(y=y), -5 / 9)
        self.assertEqual((a / b).diff(a / b).evaluate(y=y), 1)
        self.assertEqual((a / a).diff(a).evaluate(y=y), 0)
        self.assertEqual((a / a).diff(b).evaluate(y=y), 0)
示例#17
0
    def test_to_python(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))

        # test a * b
        expr = a + b
        constant_str, variable_str = pybamm.to_python(expr)
        expected_str = ("var_[0-9m]+ = y\[0:1\].*\\n"
                        "var_[0-9m]+ = y\[1:2\].*\\n"
                        "var_[0-9m]+ = var_[0-9m]+ \+ var_[0-9m]+")

        self.assertRegex(variable_str, expected_str)
示例#18
0
    def test_nonlinear(self):
        y = pybamm.StateVector(slice(0, 4))
        u = pybamm.StateVector(slice(0, 2))
        v = pybamm.StateVector(slice(2, 4))

        y0 = np.array([1, 2, 3, 4])

        func = v**2
        jacobian = np.array([[0, 0, 6, 0], [0, 0, 0, 8]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = 2**v
        jacobian = np.array([[0, 0, 2**3 * np.log(2), 0],
                             [0, 0, 0, 2**4 * np.log(2)]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = v**v
        jacobian = [[0, 0, 27 * (1 + np.log(3)), 0],
                    [0, 0, 0, 256 * (1 + np.log(4))]]
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_almost_equal(jacobian, dfunc_dy.toarray())

        func = u * v
        jacobian = np.array([[3, 0, 1, 0], [0, 4, 0, 2]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = u * (u + v)
        jacobian = np.array([[5, 0, 1, 0], [0, 8, 0, 2]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = 1 / u + v / 3
        jacobian = np.array([[-1, 0, 1 / 3, 0], [0, -1 / 4, 0, 1 / 3]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = u / v
        jacobian = np.array([[1 / 3, 0, -1 / 9, 0], [0, 1 / 4, 0, -1 / 8]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = v / (1 + v)
        jacobian = np.array([[0, 0, 1 / 16, 0], [0, 0, 0, 1 / 25]])
        dfunc_dy = func.jac(y).evaluate(y=y0)
        np.testing.assert_array_equal(jacobian, dfunc_dy.toarray())

        func = pybamm.AbsoluteValue(v)
        with self.assertRaises(pybamm.UndefinedOperationError):
            func.jac(y)
示例#19
0
    def test_to_python(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))

        # test a * b
        expr = a + b
        constant_str, variable_str = pybamm.to_python(expr)
        expected_str = (
            "self\.var_[0-9m]+ = y\[:1\]\[\[True\]\].*\\n"
            "self\.var_[0-9m]+ = y\[:2\]\[\[False, True\]\].*\\n"
            "self\.var_[0-9m]+ = self\.var_[0-9m]+ \+ self\.var_[0-9m]+")

        self.assertRegex(variable_str, expected_str)
示例#20
0
    def test_shape(self):
        scal = pybamm.Scalar(1)
        self.assertEqual(scal.shape, ())
        self.assertEqual(scal.size, 1)

        state = pybamm.StateVector(slice(10))
        self.assertEqual(state.shape, (10, 1))
        self.assertEqual(state.size, 10)
        state = pybamm.StateVector(slice(10, 25))
        self.assertEqual(state.shape, (15, 1))

        # test with big object
        state = 2 * pybamm.StateVector(slice(100000))
        self.assertEqual(state.shape, (100000, 1))
示例#21
0
    def test_advanced(self):
        a = pybamm.StateVector(slice(0, 1))
        b = pybamm.StateVector(slice(1, 2))
        y = np.array([5, 3])

        #
        func = (a * 2 + 5 * (-b)) / (a * b)
        self.assertEqual(func.diff(a).evaluate(y=y), 1 / 5)
        self.assertEqual(func.diff(b).evaluate(y=y), -2 / 9)
        #
        func = a * b**a
        testing.assert_array_almost_equal(
            func.diff(a).evaluate(y=y)[0], 3**5 * (5 * np.log(3) + 1))
        self.assertEqual(func.diff(b).evaluate(y=y), 5**2 * 3**4)
 def test_numpy_concatenation_vectors(self):
     # with entries
     y = np.linspace(0, 1, 15)[:, np.newaxis]
     a = pybamm.Vector(y[:5])
     b = pybamm.Vector(y[5:9])
     c = pybamm.Vector(y[9:])
     conc = pybamm.NumpyConcatenation(a, b, c)
     np.testing.assert_array_equal(conc.evaluate(None, y), y)
     # with y_slice
     a = pybamm.StateVector(slice(0, 10))
     b = pybamm.StateVector(slice(10, 15))
     c = pybamm.StateVector(slice(15, 23))
     conc = pybamm.NumpyConcatenation(a, b, c)
     y = np.linspace(0, 1, 23)[:, np.newaxis]
     np.testing.assert_array_equal(conc.evaluate(None, y), y)
示例#23
0
 def test_jac_of_heaviside(self):
     a = pybamm.Scalar(1)
     y = pybamm.StateVector(slice(0, 5))
     np.testing.assert_array_equal(
         ((a < y) * y**2).jac(y).evaluate(y=5 * np.ones(5)), 10 * np.eye(5))
     np.testing.assert_array_equal(
         ((a < y) * y**2).jac(y).evaluate(y=-5 * np.ones(5)), 0)
示例#24
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())
示例#25
0
    def test_convert_input_parameter(self):
        casadi_t = casadi.MX.sym("t")
        casadi_y = casadi.MX.sym("y", 10)
        casadi_ydot = casadi.MX.sym("ydot", 10)
        casadi_inputs = {
            "Input 1": casadi.MX.sym("Input 1"),
            "Input 2": casadi.MX.sym("Input 2"),
        }

        pybamm_y = pybamm.StateVector(slice(0, 10))
        pybamm_u1 = pybamm.InputParameter("Input 1")
        pybamm_u2 = pybamm.InputParameter("Input 2")

        # Input only
        self.assert_casadi_equal(
            pybamm_u1.to_casadi(casadi_t, casadi_y, casadi_ydot,
                                casadi_inputs),
            casadi_inputs["Input 1"],
        )

        # More complex
        expr = pybamm_u1 + pybamm_y
        self.assert_casadi_equal(
            expr.to_casadi(casadi_t, casadi_y, casadi_ydot, casadi_inputs),
            casadi_inputs["Input 1"] + casadi_y,
        )
        expr = pybamm_u2 * pybamm_y
        self.assert_casadi_equal(
            expr.to_casadi(casadi_t, casadi_y, casadi_ydot, casadi_inputs),
            casadi_inputs["Input 2"] * casadi_y,
        )
    def test_numpy_concatenation_vector_scalar(self):
        # with entries
        y = np.linspace(0, 1, 10)[:, np.newaxis]
        a = pybamm.Vector(y)
        b = pybamm.Scalar(16)
        c = pybamm.Scalar(3)
        conc = pybamm.NumpyConcatenation(a, b, c)
        np.testing.assert_array_equal(
            conc.evaluate(y=y),
            np.concatenate([y, np.array([[16]]),
                            np.array([[3]])]))

        # with y_slice
        a = pybamm.StateVector(slice(0, 10))
        conc = pybamm.NumpyConcatenation(a, b, c)
        np.testing.assert_array_equal(
            conc.evaluate(y=y),
            np.concatenate([y, np.array([[16]]),
                            np.array([[3]])]))

        # with time
        b = pybamm.t
        conc = pybamm.NumpyConcatenation(a, b, c)
        np.testing.assert_array_equal(
            conc.evaluate(16, y),
            np.concatenate([y, np.array([[16]]),
                            np.array([[3]])]))
示例#27
0
 def test_jac_of_sign(self):
     y = pybamm.StateVector(slice(0, 10))
     func = pybamm.sign(y) * y
     jac = func.jac(y)
     y_test = np.linspace(-2, 2, 10)
     np.testing.assert_array_equal(np.diag(jac.evaluate(y=y_test)),
                                   np.sign(y_test))
示例#28
0
 def test_jac_of_abs(self):
     y = pybamm.StateVector(slice(0, 10))
     absy = abs(y)
     jac = absy.jac(y)
     y_test = np.linspace(-2, 2, 10)
     np.testing.assert_array_equal(
         np.diag(jac.evaluate(y=y_test).toarray()), np.sign(y_test))
示例#29
0
    def test_convert_array_symbols(self):
        # Arrays
        a = np.array([1, 2, 3, 4, 5])
        pybamm_a = pybamm.Array(a)
        self.assert_casadi_equal(pybamm_a.to_casadi(), casadi.MX(a))

        casadi_t = casadi.MX.sym("t")
        casadi_y = casadi.MX.sym("y", 10)
        casadi_y_dot = casadi.MX.sym("y_dot", 10)

        pybamm_t = pybamm.Time()
        pybamm_y = pybamm.StateVector(slice(0, 10))
        pybamm_y_dot = pybamm.StateVectorDot(slice(0, 10))

        # Time
        self.assertEqual(pybamm_t.to_casadi(casadi_t, casadi_y), casadi_t)

        # State Vector
        self.assert_casadi_equal(pybamm_y.to_casadi(casadi_t, casadi_y),
                                 casadi_y)

        # State Vector Dot
        self.assert_casadi_equal(
            pybamm_y_dot.to_casadi(casadi_t, casadi_y, casadi_y_dot),
            casadi_y_dot)
示例#30
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())