Пример #1
0
    def test_power(self):
        a = pybamm.Symbol("a")
        b = pybamm.Symbol("b")
        pow1 = pybamm.Power(a, b)
        self.assertEqual(pow1.name, "**")
        self.assertEqual(pow1.children[0].name, a.name)
        self.assertEqual(pow1.children[1].name, b.name)

        a = pybamm.Scalar(4)
        b = pybamm.Scalar(2)
        pow2 = pybamm.Power(a, b)
        self.assertEqual(pow2.evaluate(), 16)
Пример #2
0
 def get_coupled_variables(self, variables):
     variables.update(self._get_standard_surface_variables(variables))
     variables.update(self._get_mechanical_results(variables))
     T = variables[self.domain + " electrode temperature"]
     if self.domain == "Negative":
         k_cr = self.param.k_cr_n(T)
         m_cr = self.param.m_cr_n
         b_cr = self.param.b_cr_n
     else:
         k_cr = self.param.k_cr_p(T)
         m_cr = self.param.m_cr_p
         b_cr = self.param.b_cr_p
     stress_t_surf = variables[self.domain +
                               " particle surface tangential stress"]
     l_cr = variables[self.domain + " particle crack length"]
     # # compressive stress will not lead to crack propagation
     dK_SIF = stress_t_surf * b_cr * pybamm.Sqrt(
         np.pi * l_cr) * (stress_t_surf >= 0)
     dl_cr = k_cr * pybamm.Power(dK_SIF, m_cr) / self.param.t0_cr
     variables.update({
         self.domain + " particle cracking rate":
         dl_cr,
         "X-averaged " + self.domain.lower() + " particle cracking rate":
         pybamm.x_average(dl_cr),
     })
     return variables
Пример #3
0
    def _stress_driven_LAM_full(self, variables):
        # This is loss of active material model by mechanical effects
        stress_t_surf = variables[self.domain + " particle surface tangential stress"]
        stress_r_surf = variables[self.domain + " particle surface radial stress"]
        if self.domain == "Negative":
            beta_LAM = self.param.beta_LAM_n
            stress_critical = self.param.stress_critical_n
            m_LAM = self.param.m_LAM_n
        else:
            beta_LAM = self.param.beta_LAM_p
            stress_critical = self.param.stress_critical_p
            m_LAM = self.param.m_LAM_p

        stress_h_surf = (stress_r_surf + 2 * stress_t_surf) / 3
        # compressive stress make no contribution
        stress_h_surf *= stress_h_surf > 0
        # assuming the minimum hydrostatic stress is zero for full cycles
        stress_h_surf_min = stress_h_surf * 0
        j_stress_LAM = (
            -beta_LAM
            * pybamm.Power(
                (stress_h_surf - stress_h_surf_min) / stress_critical,
                m_LAM,
            )
            / self.param.t0_cr
        )
        return j_stress_LAM
Пример #4
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))
Пример #5
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))
Пример #6
0
def simplified_power(left, right):
    left, right = simplify_elementwise_binary_broadcasts(left, right)

    # Check for Concatenations and Broadcasts
    out = simplified_binary_broadcast_concatenation(left, right,
                                                    simplified_power)
    if out is not None:
        return out

    # anything to the power of zero is one
    if pybamm.is_scalar_zero(right):
        return pybamm.ones_like(left)

    # zero to the power of anything is zero
    if pybamm.is_scalar_zero(left):
        return pybamm.Scalar(0)

    # anything to the power of one is itself
    if pybamm.is_scalar_one(right):
        return left

    if isinstance(left, Multiplication):
        # Simplify (a * b) ** c to (a ** c) * (b ** c)
        # if (a ** c) is constant or (b ** c) is constant
        if left.left.is_constant() or left.right.is_constant():
            l_left, l_right = left.orphans
            new_left = l_left**right
            new_right = l_right**right
            if new_left.is_constant() or new_right.is_constant():
                return new_left * new_right
    elif isinstance(left, Division):
        # Simplify (a / b) ** c to (a ** c) / (b ** c)
        # if (a ** c) is constant or (b ** c) is constant
        if left.left.is_constant() or left.right.is_constant():
            l_left, l_right = left.orphans
            new_left = l_left**right
            new_right = l_right**right
            if new_left.is_constant() or new_right.is_constant():
                return new_left / new_right

    return pybamm.simplify_if_constant(pybamm.Power(left, right))
Пример #7
0
    def test_to_equation(self):
        # Test print_name
        pybamm.Addition.print_name = "test"
        self.assertEqual(pybamm.Addition(1, 2).to_equation(), sympy.symbols("test"))

        # Test Power
        self.assertEqual(pybamm.Power(7, 2).to_equation(), 49)

        # Test Division
        self.assertEqual(pybamm.Division(10, 2).to_equation(), 5)

        # Test Matrix Multiplication
        arr1 = pybamm.Array([[1, 0], [0, 1]])
        arr2 = pybamm.Array([[4, 1], [2, 2]])
        self.assertEqual(
            pybamm.MatrixMultiplication(arr1, arr2).to_equation(),
            sympy.Matrix([[4.0, 1.0], [2.0, 2.0]]),
        )

        # Test EqualHeaviside
        self.assertEqual(pybamm.EqualHeaviside(1, 0).to_equation(), False)

        # Test NotEqualHeaviside
        self.assertEqual(pybamm.NotEqualHeaviside(2, 4).to_equation(), True)
Пример #8
0
 def __rpow__(self, other):
     """return a :class:`Power` object"""
     return pybamm.simplify_if_constant(pybamm.Power(other, self),
                                        keep_domains=True)
Пример #9
0
 def __rpow__(self, other):
     """return a :class:`Power` object"""
     if isinstance(other, (Symbol, numbers.Number)):
         return pybamm.Power(other, self)
     else:
         raise NotImplementedError