Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    def test_convert_scalar_symbols(self):
        a = pybamm.Scalar(0)
        b = pybamm.Scalar(1)
        c = pybamm.Scalar(-1)
        d = pybamm.Scalar(2)

        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))

        # function
        def sin(x):
            return np.sin(x)

        f = pybamm.Function(sin, b)
        self.assertEqual(f.to_casadi(), casadi.MX(np.sin(1)))

        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))

        # 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))
Ejemplo n.º 3
0
    def test_softminus_softplus(self):
        a = pybamm.Scalar(1)
        b = pybamm.StateVector(slice(0, 1))

        minimum = pybamm.softminus(a, b, 50)
        self.assertAlmostEqual(minimum.evaluate(y=np.array([2]))[0, 0], 1)
        self.assertAlmostEqual(minimum.evaluate(y=np.array([0]))[0, 0], 0)
        self.assertEqual(
            str(minimum),
            "log(1.9287498479639178e-22 + exp(-50.0 * y[0:1])) / -50.0",
        )

        maximum = pybamm.softplus(a, b, 50)
        self.assertAlmostEqual(maximum.evaluate(y=np.array([2]))[0, 0], 2)
        self.assertAlmostEqual(maximum.evaluate(y=np.array([0]))[0, 0], 1)
        self.assertEqual(
            str(maximum),
            "log(5.184705528587072e+21 + exp(50.0 * y[0:1])) / 50.0",
        )

        # Test that smooth min/max are used when the setting is changed
        pybamm.settings.min_smoothing = 10
        pybamm.settings.max_smoothing = 10

        self.assertEqual(str(pybamm.minimum(a, b)),
                         str(pybamm.softminus(a, b, 10)))
        self.assertEqual(str(pybamm.maximum(a, b)),
                         str(pybamm.softplus(a, b, 10)))

        # But exact min/max should still be used if both variables are constant
        a = 1
        b = pybamm.Parameter("b")
        self.assertEqual(str(pybamm.minimum(a, b)), str(pybamm.Minimum(a, b)))
        self.assertEqual(str(pybamm.maximum(a, b)), str(pybamm.Maximum(a, b)))

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