示例#1
0
 def _binary_jac(self, left_jac, right_jac):
     """ See :meth:`pybamm.BinaryOperator._binary_jac()`. """
     # apply chain rule and power rule
     left, right = self.orphans
     if right.evaluates_to_constant_number():
         return left_jac
     elif left.evaluates_to_constant_number():
         return -right_jac * pybamm.Floor(left / right)
     else:
         return left_jac - right_jac * pybamm.Floor(left / right)
示例#2
0
    def test_floor(self):
        a = pybamm.Symbol("a")
        floora = pybamm.Floor(a)
        self.assertEqual(floora.name, "floor")
        self.assertEqual(floora.children[0].name, a.name)

        b = pybamm.Scalar(3.5)
        floorb = pybamm.Floor(b)
        self.assertEqual(floorb.evaluate(), 3)

        c = pybamm.Scalar(-3.2)
        floorc = pybamm.Floor(c)
        self.assertEqual(floorc.evaluate(), -4)
示例#3
0
    def test_diff(self):
        a = pybamm.StateVector(slice(0, 1))
        y = np.array([5])

        # negation
        self.assertEqual((-a).diff(a).evaluate(y=y), -1)
        self.assertEqual((-a).diff(-a).evaluate(), 1)

        # absolute value
        self.assertEqual((a**3).diff(a).evaluate(y=y), 3 * 5**2)
        self.assertEqual((abs(a**3)).diff(a).evaluate(y=y), 3 * 5**2)
        self.assertEqual((a**3).diff(a).evaluate(y=-y), 3 * 5**2)
        self.assertEqual((abs(a**3)).diff(a).evaluate(y=-y), -3 * 5**2)

        # sign
        self.assertEqual((pybamm.sign(a)).diff(a).evaluate(y=y), 0)

        # floor
        self.assertEqual((pybamm.Floor(a)).diff(a).evaluate(y=y), 0)

        # ceil
        self.assertEqual((pybamm.Ceiling(a)).diff(a).evaluate(y=y), 0)

        # spatial operator (not implemented)
        spatial_a = pybamm.SpatialOperator("name", a)
        with self.assertRaises(NotImplementedError):
            spatial_a.diff(a)
示例#4
0
 def test_jac_of_floor(self):
     y = pybamm.StateVector(slice(0, 10))
     func = pybamm.Floor(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.floor(y_test))
示例#5
0
    def test_to_equation(self):
        a = pybamm.Symbol("a", domain="negative particle")
        b = pybamm.Symbol("b", domain="current collector")
        c = pybamm.Symbol("c", domain="test")

        # Test print_name
        pybamm.Floor.print_name = "test"
        self.assertEqual(pybamm.Floor(-2.5).to_equation(), sympy.symbols("test"))

        # Test Negate
        self.assertEqual(pybamm.Negate(4).to_equation(), -4.0)

        # Test AbsoluteValue
        self.assertEqual(pybamm.AbsoluteValue(-4).to_equation(), 4.0)

        # Test Gradient
        self.assertEqual(pybamm.Gradient(a).to_equation(), sympy_Gradient("a"))

        # Test Divergence
        self.assertEqual(
            pybamm.Divergence(pybamm.Gradient(a)).to_equation(),
            sympy_Divergence(sympy_Gradient(a)),
        )

        # Test BoundaryValue
        self.assertEqual(
            pybamm.BoundaryValue(a, "right").to_equation(), sympy.symbols("a^{surf}")
        )
        self.assertEqual(
            pybamm.BoundaryValue(b, "positive tab").to_equation(), sympy.symbols(str(b))
        )
        self.assertEqual(
            pybamm.BoundaryValue(c, "left").to_equation(), sympy.symbols("c^{left}")
        )
示例#6
0
 def _diff(self, variable):
     """ See :meth:`pybamm.Symbol._diff()`. """
     # apply chain rule and power rule
     left, right = self.orphans
     # derivative if variable is in the base
     diff = left.diff(variable)
     # derivative if variable is in the right term (rare, check separately to avoid
     # unecessarily big tree)
     if any(variable.id == x.id for x in right.pre_order()):
         diff += -pybamm.Floor(left / right) * right.diff(variable)
     return diff
    def test_convert_scalar_symbols(self):
        a = pybamm.Scalar(0)
        b = pybamm.Scalar(1)
        c = pybamm.Scalar(-1)
        d = pybamm.Scalar(2)
        e = pybamm.Scalar(3)
        g = pybamm.Scalar(3.3)

        self.assertEqual(a.to_casadi(), casadi.MX(0))
        self.assertEqual(d.to_casadi(), casadi.MX(2))

        # negate
        self.assertEqual((-b).to_casadi(), casadi.MX(-1))
        # absolute value
        self.assertEqual(abs(c).to_casadi(), casadi.MX(1))
        # floor
        self.assertEqual(pybamm.Floor(g).to_casadi(), casadi.MX(3))
        # ceiling
        self.assertEqual(pybamm.Ceiling(g).to_casadi(), casadi.MX(4))

        # function
        def square_plus_one(x):
            return x**2 + 1

        f = pybamm.Function(square_plus_one, b)
        self.assertEqual(f.to_casadi(), 2)

        def myfunction(x, y):
            return x + y

        f = pybamm.Function(myfunction, b, d)
        self.assertEqual(f.to_casadi(), casadi.MX(3))

        # use classes to avoid simplification
        # addition
        self.assertEqual((pybamm.Addition(a, b)).to_casadi(), casadi.MX(1))
        # subtraction
        self.assertEqual(pybamm.Subtraction(c, d).to_casadi(), casadi.MX(-3))
        # multiplication
        self.assertEqual(
            pybamm.Multiplication(c, d).to_casadi(), casadi.MX(-2))
        # power
        self.assertEqual(pybamm.Power(c, d).to_casadi(), casadi.MX(1))
        # division
        self.assertEqual(pybamm.Division(b, d).to_casadi(), casadi.MX(1 / 2))

        # modulo
        self.assertEqual(pybamm.Modulo(e, d).to_casadi(), casadi.MX(1))

        # minimum and maximum
        self.assertEqual(pybamm.Minimum(a, b).to_casadi(), casadi.MX(0))
        self.assertEqual(pybamm.Maximum(a, b).to_casadi(), casadi.MX(1))