Exemple #1
0
 def test_rhs_set_get(self):
     model = pybamm.BaseModel()
     rhs = {
         pybamm.Symbol("c"): pybamm.Symbol("alpha"),
         pybamm.Symbol("d"): pybamm.Symbol("beta"),
     }
     model.rhs = rhs
     self.assertEqual(rhs, model.rhs)
     # test domains
     rhs = {
         pybamm.Symbol("c", domain=["negative electrode"]): pybamm.Symbol(
             "alpha", domain=["negative electrode"]
         ),
         pybamm.Symbol("d", domain=["positive electrode"]): pybamm.Symbol(
             "beta", domain=["positive electrode"]
         ),
     }
     model.rhs = rhs
     self.assertEqual(rhs, model.rhs)
     # non-matching domains should fail
     with self.assertRaises(pybamm.DomainError):
         model.rhs = {
             pybamm.Symbol("c", domain=["positive electrode"]): pybamm.Symbol(
                 "alpha", domain=["negative electrode"]
             )
         }
Exemple #2
0
 def test_symbol_auxiliary_domains(self):
     a = pybamm.Symbol(
         "a",
         domain="test",
         auxiliary_domains={"secondary": "sec", "tertiary": "tert"},
     )
     self.assertEqual(a.domain, ["test"])
     self.assertEqual(
         a.auxiliary_domains, {"secondary": ["sec"], "tertiary": ["tert"]}
     )
     self.assertEqual(
         a.domains, {"primary": ["test"], "secondary": ["sec"], "tertiary": ["tert"]}
     )
     a = pybamm.Symbol("a", domain=["t", "e", "s"])
     self.assertEqual(a.domain, ["t", "e", "s"])
     with self.assertRaises(TypeError):
         a = pybamm.Symbol("a", domain=1)
     b = pybamm.Symbol("b", domain="test sec")
     with self.assertRaisesRegex(
         pybamm.DomainError, "Domain cannot be the same as an auxiliary domain"
     ):
         b.auxiliary_domains = {"sec": "test sec"}
     with self.assertRaisesRegex(
         pybamm.DomainError, "All auxiliary domains must be different"
     ):
         b = pybamm.Symbol(
             "b",
             domain="test",
             auxiliary_domains={"sec": ["test sec"], "tert": ["test sec"]},
         )
Exemple #3
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}")
        )
Exemple #4
0
 def test_model_dict_behaviour(self):
     model = pybamm.BaseModel()
     key = pybamm.Symbol("c")
     rhs = {key: pybamm.Symbol("alpha")}
     model.rhs = rhs
     self.assertEqual(model[key], rhs[key])
     self.assertEqual(model[key], model.rhs[key])
    def test_base_concatenation(self):
        a = pybamm.Symbol("a", domain="test a")
        b = pybamm.Symbol("b", domain="test b")
        c = pybamm.Symbol("c", domain="test c")
        conc = pybamm.concatenation(a, b, c)
        self.assertEqual(conc.name, "concatenation")
        self.assertEqual(str(conc), "concatenation(a, b, c)")
        self.assertIsInstance(conc.children[0], pybamm.Symbol)
        self.assertEqual(conc.children[0].name, "a")
        self.assertEqual(conc.children[1].name, "b")
        self.assertEqual(conc.children[2].name, "c")
        d = pybamm.Vector([2], domain="test a")
        e = pybamm.Vector([1], domain="test b")
        f = pybamm.Vector([3], domain="test c")
        conc2 = pybamm.concatenation(d, e, f)
        with self.assertRaises(TypeError):
            conc2.evaluate()

        # trying to concatenate non-pybamm symbols
        with self.assertRaises(TypeError):
            pybamm.concatenation(1, 2)

        # concatenation of length 0
        with self.assertRaisesRegex(ValueError,
                                    "Cannot create empty concatenation"):
            pybamm.concatenation()

        # concatenation of lenght 1
        self.assertEqual(pybamm.concatenation(a), a)
Exemple #6
0
 def test_symbol_domains(self):
     a = pybamm.Symbol("a", domain="test")
     self.assertEqual(a.domain, ["test"])
     a = pybamm.Symbol("a", domain=["t", "e", "s"])
     self.assertEqual(a.domain, ["t", "e", "s"])
     with self.assertRaises(TypeError):
         a = pybamm.Symbol("a", domain=1)
Exemple #7
0
    def test_broadcast_to_edges(self):
        a = pybamm.Symbol("a")
        broad_a = pybamm.PrimaryBroadcastToEdges(a, ["negative electrode"])
        self.assertEqual(broad_a.name, "broadcast to edges")
        self.assertEqual(broad_a.children[0].name, a.name)
        self.assertEqual(broad_a.domain, ["negative electrode"])
        self.assertTrue(broad_a.evaluates_on_edges())

        a = pybamm.Symbol(
            "a",
            domain=["negative particle"],
            auxiliary_domains={"secondary": "current collector"},
        )
        broad_a = pybamm.SecondaryBroadcastToEdges(a, ["negative electrode"])
        self.assertEqual(broad_a.domain, ["negative particle"])
        self.assertEqual(
            broad_a.auxiliary_domains,
            {
                "secondary": ["negative electrode"],
                "tertiary": ["current collector"]
            },
        )
        self.assertTrue(broad_a.evaluates_on_edges())

        a = pybamm.Symbol("a")
        broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"],
                                              "current collector")
        self.assertEqual(broad_a.domain, ["negative electrode"])
        self.assertEqual(broad_a.auxiliary_domains["secondary"],
                         ["current collector"])
        self.assertTrue(broad_a.evaluates_on_edges())
Exemple #8
0
    def test_div(self):
        # divergence of scalar symbol should fail
        a = pybamm.Symbol("a")
        with self.assertRaisesRegex(
                pybamm.DomainError,
                "Cannot take divergence of 'a' since its domain is empty",
        ):
            pybamm.Divergence(a)

        # divergence of variable evaluating on edges should fail
        a = pybamm.PrimaryBroadcast(pybamm.Scalar(1), "test")
        with self.assertRaisesRegex(TypeError, "evaluates on nodes"):
            pybamm.Divergence(a)

        # divergence of broadcast should return broadcasted zero
        a = pybamm.PrimaryBroadcastToEdges(pybamm.Variable("a"), "test domain")
        div = pybamm.div(a)
        self.assertIsInstance(div, pybamm.PrimaryBroadcast)
        self.assertIsInstance(div.child, pybamm.PrimaryBroadcast)
        self.assertIsInstance(div.child.child, pybamm.Scalar)
        self.assertEqual(div.child.child.value, 0)

        # otherwise divergence should work
        a = pybamm.Symbol("a", domain="test domain")
        div = pybamm.Divergence(pybamm.Gradient(a))
        self.assertEqual(div.domain, a.domain)
Exemple #9
0
    def test_secondary_broadcast(self):
        a = pybamm.Symbol(
            "a",
            domain=["negative particle"],
            auxiliary_domains={"secondary": "current collector"},
        )
        broad_a = pybamm.SecondaryBroadcast(a, ["negative electrode"])
        self.assertEqual(broad_a.domain, ["negative particle"])
        self.assertEqual(
            broad_a.auxiliary_domains,
            {
                "secondary": ["negative electrode"],
                "tertiary": ["current collector"]
            },
        )

        a = pybamm.Symbol("a", domain="negative particle")
        with self.assertRaisesRegex(pybamm.DomainError,
                                    "Secondary broadcast from particle"):
            pybamm.SecondaryBroadcast(a, "current collector")
        a = pybamm.Symbol("a", domain="negative electrode")
        with self.assertRaisesRegex(pybamm.DomainError,
                                    "Secondary broadcast from electrode"):
            pybamm.SecondaryBroadcast(a, "negative particle")

        a = pybamm.Symbol("a", domain="current collector")
        with self.assertRaisesRegex(pybamm.DomainError,
                                    "Cannot do secondary broadcast"):
            pybamm.SecondaryBroadcast(a, "electrode")
Exemple #10
0
 def test_symbol_diff(self):
     a = pybamm.Symbol("a")
     b = pybamm.Symbol("b")
     self.assertIsInstance(a.diff(a), pybamm.Scalar)
     self.assertEqual(a.diff(a).evaluate(), 1)
     self.assertIsInstance(a.diff(b), pybamm.Scalar)
     self.assertEqual(a.diff(b).evaluate(), 0)
Exemple #11
0
    def test_gradient(self):
        # gradient of scalar symbol should fail
        a = pybamm.Symbol("a")
        with self.assertRaisesRegex(
                pybamm.DomainError,
                "Cannot take gradient of 'a' since its domain is empty"):
            pybamm.Gradient(a)

        # gradient of variable evaluating on edges should fail
        a = pybamm.PrimaryBroadcastToEdges(pybamm.Scalar(1), "test")
        with self.assertRaisesRegex(TypeError, "evaluates on edges"):
            pybamm.Gradient(a)

        # gradient of broadcast should return broadcasted zero
        a = pybamm.PrimaryBroadcast(pybamm.Variable("a"), "test domain")
        grad = pybamm.grad(a)
        self.assertIsInstance(grad, pybamm.PrimaryBroadcastToEdges)
        self.assertIsInstance(grad.child, pybamm.PrimaryBroadcast)
        self.assertIsInstance(grad.child.child, pybamm.Scalar)
        self.assertEqual(grad.child.child.value, 0)

        # otherwise gradient should work
        a = pybamm.Symbol("a", domain="test domain")
        grad = pybamm.Gradient(a)
        self.assertEqual(grad.children[0].name, a.name)
        self.assertEqual(grad.domain, a.domain)
Exemple #12
0
    def test_upwind_downwind(self):
        # upwind of scalar symbol should fail
        a = pybamm.Symbol("a")
        with self.assertRaisesRegex(
                pybamm.DomainError,
                "Cannot upwind 'a' since its domain is empty"):
            pybamm.Upwind(a)

        # upwind of variable evaluating on edges should fail
        a = pybamm.PrimaryBroadcastToEdges(pybamm.Scalar(1), "test")
        with self.assertRaisesRegex(TypeError, "evaluate on nodes"):
            pybamm.Upwind(a)

        # otherwise upwind should work
        a = pybamm.Symbol("a", domain="test domain")
        upwind = pybamm.upwind(a)
        self.assertIsInstance(upwind, pybamm.Upwind)
        self.assertEqual(upwind.children[0].name, a.name)
        self.assertEqual(upwind.domain, a.domain)

        # also test downwind
        a = pybamm.Symbol("a", domain="test domain")
        downwind = pybamm.downwind(a)
        self.assertIsInstance(downwind, pybamm.Downwind)
        self.assertEqual(downwind.children[0].name, a.name)
        self.assertEqual(downwind.domain, a.domain)
Exemple #13
0
 def test_algebraic_set_get(self):
     model = pybamm.BaseModel()
     algebraic = {
         pybamm.Symbol("b"): pybamm.Symbol("c") - pybamm.Symbol("a")
     }
     model.algebraic = algebraic
     self.assertEqual(algebraic, model.algebraic)
 def test_domain_error(self):
     a = pybamm.Symbol("a")
     b = pybamm.Symbol("b")
     with self.assertRaisesRegex(
             pybamm.DomainError,
             "Cannot concatenate child 'a' with empty domain"):
         pybamm.DomainConcatenation([a, b], None)
Exemple #15
0
    def test_broadcast_to_edges(self):
        a = pybamm.Symbol("a")

        # primary
        broad_a = pybamm.PrimaryBroadcastToEdges(a, ["negative electrode"])
        self.assertEqual(broad_a.name, "broadcast to edges")
        self.assertEqual(broad_a.children[0].name, a.name)
        self.assertEqual(broad_a.domain, ["negative electrode"])
        self.assertTrue(broad_a.evaluates_on_edges("primary"))
        self.assertFalse(broad_a.broadcasts_to_nodes)
        self.assertEqual(broad_a.reduce_one_dimension(), a)

        # secondary
        a = pybamm.Symbol(
            "a",
            domain=["negative particle"],
            auxiliary_domains={"secondary": "current collector"},
        )
        broad_a = pybamm.SecondaryBroadcastToEdges(a, ["negative electrode"])
        self.assertEqual(broad_a.domain, ["negative particle"])
        self.assertEqual(
            broad_a.auxiliary_domains,
            {
                "secondary": ["negative electrode"],
                "tertiary": ["current collector"]
            },
        )
        self.assertTrue(broad_a.evaluates_on_edges("primary"))
        self.assertFalse(broad_a.broadcasts_to_nodes)

        # full
        a = pybamm.Symbol("a")
        broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"],
                                              "current collector")
        self.assertEqual(broad_a.domain, ["negative electrode"])
        self.assertEqual(broad_a.auxiliary_domains["secondary"],
                         ["current collector"])
        self.assertTrue(broad_a.evaluates_on_edges("primary"))
        self.assertFalse(broad_a.broadcasts_to_nodes)
        self.assertEqual(
            broad_a.reduce_one_dimension().id,
            pybamm.PrimaryBroadcastToEdges(a, "current collector").id,
        )
        broad_a = pybamm.FullBroadcastToEdges(a, ["negative electrode"], {})
        self.assertEqual(broad_a.reduce_one_dimension(), a)

        broad_a = pybamm.FullBroadcastToEdges(
            a,
            "negative particle",
            {
                "secondary": "negative electrode",
                "tertiary": "current collector"
            },
        )
        self.assertEqual(
            broad_a.reduce_one_dimension().id,
            pybamm.FullBroadcastToEdges(a, "negative electrode",
                                        "current collector").id,
        )
    def test_addition(self):
        a = pybamm.Symbol("a")
        b = pybamm.Symbol("b")
        summ = pybamm.Addition(a, b)
        self.assertEqual(summ.children[0].name, a.name)
        self.assertEqual(summ.children[1].name, b.name)

        # test simplifying
        summ2 = pybamm.Scalar(1) + pybamm.Scalar(3)
        self.assertEqual(summ2.id, pybamm.Scalar(4).id)
Exemple #17
0
    def test_concatenation(self):
        a = pybamm.Symbol("a")
        b = pybamm.Symbol("b")
        c = pybamm.Symbol("c")

        # create discretisation
        disc = get_discretisation_for_testing()

        conc = disc.concatenate(a, b, c)
        self.assertIsInstance(conc, pybamm.NumpyConcatenation)
Exemple #18
0
 def test_symbol_repr(self):
     """
     test that __repr___ returns the string
     `__class__(id, name, parent expression)`
     """
     a = pybamm.Symbol("a")
     b = pybamm.Symbol("b")
     c = pybamm.Symbol("c", domain=["test"])
     d = pybamm.Symbol("d",
                       domain=["test"],
                       auxiliary_domains={"sec": "other test"})
     hex_regex = r"\-?0x[0-9,a-f]+"
     self.assertRegex(
         a.__repr__(),
         r"Symbol\(" + hex_regex +
         r", a, children\=\[\], domain\=\[\], auxiliary_domains\=\{\}\)",
     )
     self.assertRegex(
         b.__repr__(),
         r"Symbol\(" + hex_regex +
         r", b, children\=\[\], domain\=\[\], auxiliary_domains\=\{\}\)",
     )
     self.assertRegex(
         c.__repr__(),
         r"Symbol\(" + hex_regex +
         r", c, children\=\[\], domain\=\['test'\], auxiliary_domains\=\{\}\)",
     )
     self.assertRegex(
         d.__repr__(),
         r"Symbol\(" + hex_regex +
         r", d, children\=\[\], domain\=\['test'\]" +
         r", auxiliary_domains\=\{'sec': \"\['other test'\]\"\}\)",
     )
     self.assertRegex(
         (a + b).__repr__(),
         r"Addition\(" + hex_regex +
         r", \+, children\=\['a', 'b'\], domain=\[\]",
     )
     self.assertRegex(
         (c * d).__repr__(),
         r"Multiplication\(" + hex_regex +
         r", \*, children\=\['c', 'd'\], domain=\['test'\]" +
         r", auxiliary_domains\=\{'sec': \"\['other test'\]\"\}\)",
     )
     self.assertRegex(
         pybamm.grad(a).__repr__(),
         r"Gradient\(" + hex_regex +
         r", grad, children\=\['a'\], domain=\[\], auxiliary_domains\=\{\}\)",
     )
     self.assertRegex(
         pybamm.grad(c).__repr__(),
         r"Gradient\(" + hex_regex +
         r", grad, children\=\['c'\], domain=\['test'\]" +
         r", auxiliary_domains\=\{\}\)",
     )
 def test_binary_operator(self):
     a = pybamm.Symbol("a")
     b = pybamm.Symbol("b")
     bin = pybamm.BinaryOperator("binary test", a, b)
     self.assertEqual(bin.children[0].name, a.name)
     self.assertEqual(bin.children[1].name, b.name)
     c = pybamm.Scalar(1)
     d = pybamm.Scalar(2)
     bin2 = pybamm.BinaryOperator("binary test", c, d)
     with self.assertRaises(NotImplementedError):
         bin2.evaluate()
Exemple #20
0
    def test_symbol_methods(self):
        a = pybamm.Symbol("a")
        b = pybamm.Symbol("b")

        # unary
        self.assertIsInstance(-a, pybamm.Negate)
        self.assertIsInstance(abs(a), pybamm.AbsoluteValue)
        # special cases
        neg_a = -a
        self.assertEqual(-neg_a, a)
        abs_a = abs(a)
        self.assertEqual(abs(abs_a), abs_a)

        # binary - two symbols
        self.assertIsInstance(a + b, pybamm.Addition)
        self.assertIsInstance(a - b, pybamm.Subtraction)
        self.assertIsInstance(a * b, pybamm.Multiplication)
        self.assertIsInstance(a @ b, pybamm.MatrixMultiplication)
        self.assertIsInstance(a / b, pybamm.Division)
        self.assertIsInstance(a**b, pybamm.Power)
        self.assertIsInstance(a < b, pybamm.Heaviside)
        self.assertIsInstance(a <= b, pybamm.Heaviside)
        self.assertIsInstance(a > b, pybamm.Heaviside)
        self.assertIsInstance(a >= b, pybamm.Heaviside)
        self.assertIsInstance(a % b, pybamm.Modulo)

        # binary - symbol and number
        self.assertIsInstance(a + 2, pybamm.Addition)
        self.assertIsInstance(a - 2, pybamm.Subtraction)
        self.assertIsInstance(a * 2, pybamm.Multiplication)
        self.assertIsInstance(a @ 2, pybamm.MatrixMultiplication)
        self.assertIsInstance(a / 2, pybamm.Division)
        self.assertIsInstance(a**2, pybamm.Power)

        # binary - number and symbol
        self.assertIsInstance(3 + b, pybamm.Addition)
        self.assertEqual((3 + b).children[1].id, b.id)
        self.assertIsInstance(3 - b, pybamm.Subtraction)
        self.assertEqual((3 - b).children[1].id, b.id)
        self.assertIsInstance(3 * b, pybamm.Multiplication)
        self.assertEqual((3 * b).children[1].id, b.id)
        self.assertIsInstance(3 @ b, pybamm.MatrixMultiplication)
        self.assertEqual((3 @ b).children[1].id, b.id)
        self.assertIsInstance(3 / b, pybamm.Division)
        self.assertEqual((3 / b).children[1].id, b.id)
        self.assertIsInstance(3**b, pybamm.Power)
        self.assertEqual((3**b).children[1].id, b.id)

        # error raising
        with self.assertRaisesRegex(
                NotImplementedError,
                "BinaryOperator not implemented for symbols of type"):
            a + "two"
    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)
Exemple #22
0
    def test_x_average(self):
        a = pybamm.Scalar(1)
        average_a = pybamm.x_average(a)
        self.assertEqual(average_a.id, a.id)

        average_broad_a = pybamm.x_average(
            pybamm.PrimaryBroadcast(a, ["negative electrode"]))
        self.assertEqual(average_broad_a.evaluate(), np.array([1]))

        conc_broad = pybamm.Concatenation(
            pybamm.PrimaryBroadcast(1, ["negative electrode"]),
            pybamm.PrimaryBroadcast(2, ["separator"]),
            pybamm.PrimaryBroadcast(3, ["positive electrode"]),
        )
        average_conc_broad = pybamm.x_average(conc_broad)
        self.assertIsInstance(average_conc_broad, pybamm.Division)

        for domain in [
            ["negative electrode"],
            ["separator"],
            ["positive electrode"],
            ["negative electrode", "separator", "positive electrode"],
        ]:
            a = pybamm.Symbol("a", domain=domain)
            x = pybamm.SpatialVariable("x", domain)
            av_a = pybamm.x_average(a)
            self.assertIsInstance(av_a, pybamm.Division)
            self.assertIsInstance(av_a.children[0], pybamm.Integral)
            self.assertEqual(av_a.children[0].integration_variable[0].domain,
                             x.domain)
            self.assertEqual(av_a.domain, [])

        a = pybamm.Symbol("a", domain="new domain")
        av_a = pybamm.x_average(a)
        self.assertEqual(av_a.domain, [])
        self.assertIsInstance(av_a, pybamm.Division)
        self.assertIsInstance(av_a.children[0], pybamm.Integral)
        self.assertEqual(av_a.children[0].integration_variable[0].domain,
                         a.domain)
        self.assertIsInstance(av_a.children[1], pybamm.Integral)
        self.assertEqual(av_a.children[1].integration_variable[0].domain,
                         a.domain)
        self.assertEqual(av_a.children[1].children[0].id,
                         pybamm.ones_like(a).id)

        # x-average of symbol that evaluates on edges raises error
        symbol_on_edges = pybamm.PrimaryBroadcastToEdges(1, "domain")
        with self.assertRaisesRegex(
                ValueError,
                "Can't take the x-average of a symbol that evaluates on edges"
        ):
            pybamm.x_average(symbol_on_edges)
Exemple #23
0
    def test_boundary_value(self):
        a = pybamm.Scalar(1)
        boundary_a = pybamm.boundary_value(a, "right")
        self.assertEqual(boundary_a.id, a.id)

        boundary_broad_a = pybamm.boundary_value(
            pybamm.PrimaryBroadcast(a, ["negative electrode"]), "left")
        self.assertEqual(boundary_broad_a.evaluate(), np.array([1]))

        a = pybamm.Symbol("a", domain=["separator"])
        boundary_a = pybamm.boundary_value(a, "right")
        self.assertIsInstance(boundary_a, pybamm.BoundaryValue)
        self.assertEqual(boundary_a.side, "right")
        self.assertEqual(boundary_a.domain, [])
        self.assertEqual(boundary_a.auxiliary_domains, {})
        # test with secondary domain
        a_sec = pybamm.Symbol(
            "a",
            domain=["separator"],
            auxiliary_domains={"secondary": "current collector"},
        )
        boundary_a_sec = pybamm.boundary_value(a_sec, "right")
        self.assertEqual(boundary_a_sec.domain, ["current collector"])
        self.assertEqual(boundary_a_sec.auxiliary_domains, {})
        # test with secondary domain and tertiary domain
        a_tert = pybamm.Symbol(
            "a",
            domain=["separator"],
            auxiliary_domains={
                "secondary": "current collector",
                "tertiary": "bla"
            },
        )
        boundary_a_tert = pybamm.boundary_value(a_tert, "right")
        self.assertEqual(boundary_a_tert.domain, ["current collector"])
        self.assertEqual(boundary_a_tert.auxiliary_domains,
                         {"secondary": ["bla"]})

        # error if boundary value on tabs and domain is not "current collector"
        var = pybamm.Variable("var", domain=["negative electrode"])
        with self.assertRaisesRegex(pybamm.ModelError,
                                    "Can only take boundary"):
            pybamm.boundary_value(var, "negative tab")
            pybamm.boundary_value(var, "positive tab")

        # boundary value of symbol that evaluates on edges raises error
        symbol_on_edges = pybamm.PrimaryBroadcastToEdges(1, "domain")
        with self.assertRaisesRegex(
                ValueError,
                "Can't take the boundary value of a symbol that evaluates on edges",
        ):
            pybamm.boundary_value(symbol_on_edges, "right")
    def test_concatenation_domains(self):
        a = pybamm.Symbol("a", domain=["negative electrode"])
        b = pybamm.Symbol("b", domain=["separator", "positive electrode"])
        c = pybamm.Symbol("c", domain=["test"])
        conc = pybamm.concatenation(a, b, c)
        self.assertEqual(
            conc.domain,
            ["negative electrode", "separator", "positive electrode", "test"],
        )

        # Can't concatenate nodes with overlapping domains
        d = pybamm.Symbol("d", domain=["separator"])
        with self.assertRaises(pybamm.DomainError):
            pybamm.concatenation(a, b, d)
Exemple #25
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
Exemple #26
0
 def test_full_broadcast(self):
     a = pybamm.Symbol("a")
     broad_a = pybamm.FullBroadcast(a, ["negative electrode"],
                                    "current collector")
     self.assertEqual(broad_a.domain, ["negative electrode"])
     self.assertEqual(broad_a.auxiliary_domains["secondary"],
                      ["current collector"])
Exemple #27
0
    def test_function_of_one_variable(self):
        a = pybamm.Symbol("a")
        funca = pybamm.Function(test_function, a)
        self.assertEqual(funca.name, "function (test_function)")
        self.assertEqual(str(funca), "test_function(a)")
        self.assertEqual(funca.children[0].name, a.name)

        b = pybamm.Scalar(1)
        sina = pybamm.Function(np.sin, b)
        self.assertEqual(sina.evaluate(), np.sin(1))
        self.assertEqual(sina.name, "function ({})".format(np.sin.__name__))

        c = pybamm.Vector(np.linspace(0, 1))
        cosb = pybamm.Function(np.cos, c)
        np.testing.assert_array_equal(cosb.evaluate(), np.cos(c.evaluate()))

        var = pybamm.StateVector(slice(0, 100))
        y = np.linspace(0, 1, 100)[:, np.newaxis]
        logvar = pybamm.Function(np.log1p, var)
        np.testing.assert_array_equal(logvar.evaluate(y=y), np.log1p(y))

        # use known_evals
        np.testing.assert_array_equal(
            logvar.evaluate(y=y, known_evals={})[0], np.log1p(y)
        )
Exemple #28
0
 def test_name(self):
     a = pybamm.Symbol("a")
     x = np.linspace(0, 1, 200)
     interp = pybamm.Interpolant(x, x, a, "name")
     self.assertEqual(interp.name, "name")
     interp = pybamm.Interpolant(x, x, a)
     self.assertEqual(interp.name, "interpolating_function")
 def test_binary_operator_domains(self):
     # same domain
     a = pybamm.Symbol("a", domain=["negative electrode"])
     b = pybamm.Symbol("b", domain=["negative electrode"])
     bin1 = pybamm.BinaryOperator("binary test", a, b)
     self.assertEqual(bin1.domain, ["negative electrode"])
     # one empty domain
     c = pybamm.Symbol("c", domain=[])
     bin2 = pybamm.BinaryOperator("binary test", a, c)
     self.assertEqual(bin2.domain, ["negative electrode"])
     bin3 = pybamm.BinaryOperator("binary test", c, b)
     self.assertEqual(bin3.domain, ["negative electrode"])
     # mismatched domains
     d = pybamm.Symbol("d", domain=["positive electrode"])
     with self.assertRaises(pybamm.DomainError):
         pybamm.BinaryOperator("binary test", a, d)
 def test_domain_concatenation_domains(self):
     mesh = get_mesh_for_testing()
     # ensure concatenated domains are sorted correctly
     a = pybamm.Symbol("a", domain=["negative electrode"])
     b = pybamm.Symbol("b", domain=["separator", "positive electrode"])
     c = pybamm.Symbol("c", domain=["negative particle"])
     conc = pybamm.DomainConcatenation([c, a, b], mesh)
     self.assertEqual(
         conc.domain,
         [
             "negative electrode",
             "separator",
             "positive electrode",
             "negative particle",
         ],
     )