Exemplo n.º 1
0
    def test_get_auxiliary_domain_repeats(self):
        # Test the method to read number of repeats from auxiliary domains
        mesh = get_1p1d_mesh_for_testing()
        spatial_method = pybamm.SpatialMethod()
        spatial_method.build(mesh)

        # No auxiliary domains
        repeats = spatial_method._get_auxiliary_domain_repeats({})
        self.assertEqual(repeats, 1)

        # Just secondary domain
        repeats = spatial_method._get_auxiliary_domain_repeats(
            {"secondary": ["negative electrode"]})
        self.assertEqual(repeats, mesh["negative electrode"].npts)

        repeats = spatial_method._get_auxiliary_domain_repeats(
            {"secondary": ["negative electrode", "separator"]})
        self.assertEqual(
            repeats, mesh["negative electrode"].npts + mesh["separator"].npts)

        # Just tertiary domain
        repeats = spatial_method._get_auxiliary_domain_repeats({
            "secondary": ["negative electrode", "separator"],
            "tertiary": ["current collector"],
        })
        self.assertEqual(
            repeats,
            (mesh["negative electrode"].npts + mesh["separator"].npts) *
            mesh["current collector"].npts,
        )
Exemplo n.º 2
0
    def test_grad_1plus1d(self):
        mesh = get_1p1d_mesh_for_testing()
        spatial_methods = {"macroscale": pybamm.FiniteVolume()}
        disc = pybamm.Discretisation(mesh, spatial_methods)

        a = pybamm.Variable("a", domain=["negative electrode"])
        b = pybamm.Variable("b", domain=["separator"])
        c = pybamm.Variable("c", domain=["positive electrode"])
        var = pybamm.Concatenation(a, b, c)
        boundary_conditions = {
            var.id: {
                "left": (pybamm.Vector(np.linspace(0, 1, 15)), "Neumann"),
                "right": (pybamm.Vector(np.linspace(0, 1, 15)), "Neumann"),
            }
        }

        disc.bcs = boundary_conditions
        disc.set_variable_slices([var])
        grad_eqn_disc = disc.process_symbol(pybamm.grad(var))

        # Evaulate
        combined_submesh = mesh.combine_submeshes(*var.domain)
        linear_y = np.outer(np.linspace(0, 1, 15),
                            combined_submesh[0].nodes).reshape(-1, 1)

        expected = np.outer(np.linspace(0, 1, 15),
                            np.ones_like(combined_submesh[0].edges)).reshape(
                                -1, 1)
        np.testing.assert_array_almost_equal(
            grad_eqn_disc.evaluate(None, linear_y), expected)
Exemplo n.º 3
0
    def test_neg_pos_bcs(self):
        # 2d macroscale
        mesh = get_1p1d_mesh_for_testing()
        spatial_methods = {
            "macroscale": pybamm.FiniteVolume(),
            "negative particle": pybamm.FiniteVolume(),
            "positive particle": pybamm.FiniteVolume(),
            "current collector": pybamm.FiniteVolume(),
        }
        disc = pybamm.Discretisation(mesh, spatial_methods)

        # var
        var = pybamm.Variable("var", domain="current collector")
        disc.set_variable_slices([var])
        # grad
        grad_eqn = pybamm.grad(var)

        # bcs (on each tab)
        boundary_conditions = {
            var.id: {
                "negative tab": (pybamm.Scalar(1), "Dirichlet"),
                "positive tab": (pybamm.Scalar(0), "Neumann"),
                "no tab": (pybamm.Scalar(8), "Dirichlet"),
            }
        }
        disc.bcs = boundary_conditions

        # check after disc that negative tab goes to left and positive tab goes
        # to right
        disc.process_symbol(grad_eqn)
        self.assertEqual(disc.bcs[var.id]["left"][0].id, pybamm.Scalar(1).id)
        self.assertEqual(disc.bcs[var.id]["left"][1], "Dirichlet")
        self.assertEqual(disc.bcs[var.id]["right"][0].id, pybamm.Scalar(0).id)
        self.assertEqual(disc.bcs[var.id]["right"][1], "Neumann")
Exemplo n.º 4
0
    def test_grad_div_with_bcs_on_tab(self):
        # 2d macroscale
        mesh = get_1p1d_mesh_for_testing()
        spatial_methods = {
            "macroscale": pybamm.FiniteVolume(),
            "negative particle": pybamm.FiniteVolume(),
            "positive particle": pybamm.FiniteVolume(),
            "current collector": pybamm.FiniteVolume(),
        }
        disc = pybamm.Discretisation(mesh, spatial_methods)
        y_test = np.ones(mesh["current collector"][0].npts)

        # var
        var = pybamm.Variable("var", domain="current collector")
        disc.set_variable_slices([var])
        # grad
        grad_eqn = pybamm.grad(var)
        # div
        N = pybamm.grad(var)
        div_eqn = pybamm.div(N)

        # bcs (on each tab)
        boundary_conditions = {
            var.id: {
                "negative tab": (pybamm.Scalar(1), "Dirichlet"),
                "positive tab": (pybamm.Scalar(0), "Neumann"),
            }
        }
        disc.bcs = boundary_conditions
        grad_eqn_disc = disc.process_symbol(grad_eqn)
        grad_eqn_disc.evaluate(None, y_test)
        div_eqn_disc = disc.process_symbol(div_eqn)
        div_eqn_disc.evaluate(None, y_test)

        # bcs (one pos, one not tab)
        boundary_conditions = {
            var.id: {
                "no tab": (pybamm.Scalar(1), "Dirichlet"),
                "positive tab": (pybamm.Scalar(0), "Dirichlet"),
            }
        }
        disc.bcs = boundary_conditions
        grad_eqn_disc = disc.process_symbol(grad_eqn)
        grad_eqn_disc.evaluate(None, y_test)
        div_eqn_disc = disc.process_symbol(div_eqn)
        div_eqn_disc.evaluate(None, y_test)

        # bcs (one neg, one not tab)
        boundary_conditions = {
            var.id: {
                "negative tab": (pybamm.Scalar(1), "Neumann"),
                "no tab": (pybamm.Scalar(0), "Neumann"),
            }
        }
        disc.bcs = boundary_conditions
        grad_eqn_disc = disc.process_symbol(grad_eqn)
        grad_eqn_disc.evaluate(None, y_test)
        div_eqn_disc = disc.process_symbol(div_eqn)
        div_eqn_disc.evaluate(None, y_test)
Exemplo n.º 5
0
    def test_broadcast_checks(self):
        child = pybamm.Symbol("sym", domain=["negative electrode"])
        symbol = pybamm.BoundaryGradient(child, "left")
        mesh = get_mesh_for_testing()
        spatial_method = pybamm.SpatialMethod()
        spatial_method.build(mesh)
        with self.assertRaisesRegex(TypeError, "Cannot process BoundaryGradient"):
            spatial_method.boundary_value_or_flux(symbol, child)

        mesh = get_1p1d_mesh_for_testing()
        spatial_method = pybamm.SpatialMethod()
        spatial_method.build(mesh)
        with self.assertRaisesRegex(NotImplementedError, "Cannot process 2D symbol"):
            spatial_method.boundary_value_or_flux(symbol, child)
Exemplo n.º 6
0
    def test_extrapolate_2d_models(self):
        # create discretisation
        mesh = get_p2d_mesh_for_testing()
        method_options = {
            "extrapolation": {
                "order": "linear",
                "use bcs": False
            }
        }
        spatial_methods = {
            "macroscale": pybamm.FiniteVolume(method_options),
            "negative particle": pybamm.FiniteVolume(method_options),
            "positive particle": pybamm.FiniteVolume(method_options),
            "current collector": pybamm.FiniteVolume(method_options),
        }
        disc = pybamm.Discretisation(mesh, spatial_methods)

        # Microscale
        var = pybamm.Variable("var", domain="negative particle")
        extrap_right = pybamm.BoundaryValue(var, "right")
        disc.set_variable_slices([var])
        extrap_right_disc = disc.process_symbol(extrap_right)
        self.assertEqual(extrap_right_disc.domain, [])
        # domain for boundary values must now be explicitly set
        extrap_right.domain = ["negative electrode"]
        disc.set_variable_slices([var])
        extrap_right_disc = disc.process_symbol(extrap_right)
        self.assertEqual(extrap_right_disc.domain, ["negative electrode"])
        # evaluate
        y_macro = mesh["negative electrode"][0].nodes
        y_micro = mesh["negative particle"][0].nodes
        y = np.outer(y_macro, y_micro).reshape(-1, 1)
        # extrapolate to r=1 --> should evaluate to y_macro
        np.testing.assert_array_almost_equal(
            extrap_right_disc.evaluate(y=y)[:, 0], y_macro)

        var = pybamm.Variable("var", domain="positive particle")
        extrap_right = pybamm.BoundaryValue(var, "right")
        disc.set_variable_slices([var])
        extrap_right_disc = disc.process_symbol(extrap_right)
        self.assertEqual(extrap_right_disc.domain, [])
        # domain for boundary values must now be explicitly set
        extrap_right.domain = ["positive electrode"]
        disc.set_variable_slices([var])
        extrap_right_disc = disc.process_symbol(extrap_right)
        self.assertEqual(extrap_right_disc.domain, ["positive electrode"])

        # 2d macroscale
        mesh = get_1p1d_mesh_for_testing()
        disc = pybamm.Discretisation(mesh, spatial_methods)
        var = pybamm.Variable("var", domain="negative electrode")
        extrap_right = pybamm.BoundaryValue(var, "right")
        disc.set_variable_slices([var])
        extrap_right_disc = disc.process_symbol(extrap_right)
        self.assertEqual(extrap_right_disc.domain, [])

        # test extrapolate to "negative tab" gives same as "left" and
        # "positive tab" gives same "right" (see get_mesh_for_testing)
        var = pybamm.Variable("var", domain="current collector")
        disc.set_variable_slices([var])
        submesh = mesh["current collector"]
        constant_y = np.ones_like(submesh[0].nodes[:, np.newaxis])

        extrap_neg = pybamm.BoundaryValue(var, "negative tab")
        extrap_neg_disc = disc.process_symbol(extrap_neg)
        extrap_left = pybamm.BoundaryValue(var, "left")
        extrap_left_disc = disc.process_symbol(extrap_left)
        np.testing.assert_array_equal(
            extrap_neg_disc.evaluate(None, constant_y),
            extrap_left_disc.evaluate(None, constant_y),
        )

        extrap_pos = pybamm.BoundaryValue(var, "positive tab")
        extrap_pos_disc = disc.process_symbol(extrap_pos)
        extrap_right = pybamm.BoundaryValue(var, "right")
        extrap_right_disc = disc.process_symbol(extrap_right)
        np.testing.assert_array_equal(
            extrap_pos_disc.evaluate(None, constant_y),
            extrap_right_disc.evaluate(None, constant_y),
        )