def test_tab_left_right(self):
        # set variables and submesh types
        var = pybamm.standard_spatial_vars
        var_pts = {var.x_n: 2, var.x_s: 2, var.x_p: 2, var.y: 64, var.z: 64}

        submesh_types = {
            "negative electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "separator":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "current collector":
            pybamm.MeshGenerator(pybamm.ScikitUniform2DSubMesh),
        }

        # set base parameters
        param = pybamm.ParameterValues(
            values={
                "Electrode width [m]": 0.4,
                "Electrode height [m]": 0.5,
                "Negative tab width [m]": 0.1,
                "Negative tab centre y-coordinate [m]": 0.0,
                "Negative tab centre z-coordinate [m]": 0.25,
                "Positive tab centre y-coordinate [m]": 0.4,
                "Positive tab centre z-coordinate [m]": 0.25,
                "Positive tab width [m]": 0.1,
                "Negative electrode thickness [m]": 0.3,
                "Separator thickness [m]": 0.3,
                "Positive electrode thickness [m]": 0.3,
            })

        # check mesh can be built
        geometry = pybamm.battery_geometry(include_particles=False,
                                           current_collector_dimension=2)
        param.process_geometry(geometry)
        pybamm.Mesh(geometry, submesh_types, var_pts)
Esempio n. 2
0
    def test_mesh_coord_sys(self):
        param = pybamm.ParameterValues(
            values={
                "Negative electrode thickness [m]": 0.1,
                "Separator thickness [m]": 0.2,
                "Positive electrode thickness [m]": 0.3,
            })

        geometry = pybamm.battery_geometry()
        param.process_geometry(geometry)

        var = pybamm.standard_spatial_vars
        var_pts = {
            var.x_n: 10,
            var.x_s: 10,
            var.x_p: 12,
            var.r_n: 5,
            var.r_p: 6
        }

        submesh_types = {
            "negative electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "separator": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "negative particle": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive particle": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "current collector": pybamm.MeshGenerator(pybamm.SubMesh0D),
        }

        # create mesh
        mesh = pybamm.Mesh(geometry, submesh_types, var_pts)

        for submesh in mesh.values():
            if not isinstance(submesh, pybamm.SubMesh0D):
                self.assertTrue(submesh.coord_sys in pybamm.KNOWN_COORD_SYS)
Esempio n. 3
0
    def test_read_parameters(self):
        geo = pybamm.geometric_parameters
        L_n = geo.L_n
        L_s = geo.L_s
        L_p = geo.L_p
        L_y = geo.L_y
        L_z = geo.L_z
        tab_n_y = geo.Centre_y_tab_n
        tab_n_z = geo.Centre_z_tab_n
        L_tab_n = geo.L_tab_n
        tab_p_y = geo.Centre_y_tab_p
        tab_p_z = geo.Centre_z_tab_p
        L_tab_p = geo.L_tab_p

        geometry = pybamm.battery_geometry(current_collector_dimension=2)

        self.assertEqual(
            set([x.name for x in geometry.parameters]),
            set([
                x.name for x in [
                    L_n,
                    L_s,
                    L_p,
                    L_y,
                    L_z,
                    tab_n_y,
                    tab_n_z,
                    L_tab_n,
                    tab_p_y,
                    tab_p_z,
                    L_tab_p,
                ]
            ]),
        )
        self.assertTrue(
            all(isinstance(x, pybamm.Parameter) for x in geometry.parameters))
Esempio n. 4
0
    "positive interface current"] = pybamm.interface.CurrentForInverseButlerVolmer(
        model.param, "Positive", "lithium-ion main")
model.submodels[
    "electrolyte diffusion"] = pybamm.electrolyte_diffusion.ConstantConcentration(
        model.param)
model.submodels[
    "electrolyte conductivity"] = pybamm.electrolyte_conductivity.LeadingOrder(
        model.param)
model.submodels["negative sei"] = pybamm.sei.NoSEI(model.param, "Negative")
model.submodels["positive sei"] = pybamm.sei.NoSEI(model.param, "Positive")

# build model
model.build_model()

# create geometry
geometry = pybamm.battery_geometry()

# process model and geometry
param = model.default_parameter_values
param.process_model(model)
param.process_geometry(geometry)

# set mesh
# Note: li-ion base model has defaults for mesh and var_pts
mesh = pybamm.Mesh(geometry, model.default_submesh_types,
                   model.default_var_pts)

# discretise model
# Note: li-ion base model has default spatial methods
disc = pybamm.Discretisation(mesh, model.default_spatial_methods)
disc.process_model(model)
Esempio n. 5
0
 def default_geometry(self):
     return pybamm.battery_geometry(
         current_collector_dimension=self.options["dimensionality"]
     )
Esempio n. 6
0
 def default_geometry(self):
     return pybamm.battery_geometry(
         include_particles=False,
         current_collector_dimension=self.options["dimensionality"],
     )
Esempio n. 7
0
def get_p2d_mesh_for_testing(xpts=None, rpts=10):
    geometry = pybamm.battery_geometry()
    return get_mesh_for_testing(xpts=xpts, rpts=rpts, geometry=geometry)
Esempio n. 8
0
 def test_geometry_error(self):
     with self.assertRaisesRegex(pybamm.GeometryError, "Invalid current"):
         pybamm.battery_geometry(current_collector_dimension=4)
Esempio n. 9
0
    def test_combine_submeshes(self):
        param = pybamm.ParameterValues(
            values={
                "Negative electrode thickness [m]": 0.1,
                "Separator thickness [m]": 0.2,
                "Positive electrode thickness [m]": 0.3,
            })

        geometry = pybamm.battery_geometry()
        param.process_geometry(geometry)

        # provide mesh properties
        var = pybamm.standard_spatial_vars
        var_pts = {
            var.x_n: 10,
            var.x_s: 10,
            var.x_p: 12,
            var.r_n: 5,
            var.r_p: 6
        }
        submesh_types = {
            "negative electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "separator": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive electrode":
            pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "negative particle": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive particle": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "current collector": pybamm.MeshGenerator(pybamm.SubMesh0D),
        }

        # create mesh
        mesh = pybamm.Mesh(geometry, submesh_types, var_pts)

        # create submesh
        submesh = mesh.combine_submeshes("negative electrode", "separator")
        self.assertEqual(submesh.edges[0], 0)
        self.assertEqual(submesh.edges[-1], mesh["separator"].edges[-1])
        np.testing.assert_almost_equal(
            submesh.nodes - np.concatenate(
                [mesh["negative electrode"].nodes, mesh["separator"].nodes]),
            0,
        )
        np.testing.assert_almost_equal(submesh.internal_boundaries,
                                       [0.1 / 0.6])
        with self.assertRaises(pybamm.DomainError):
            mesh.combine_submeshes("negative electrode", "positive electrode")

        # test errors
        geometry = {
            "negative electrode": {
                var.x_n: {
                    "min": 0,
                    "max": 0.5
                }
            },
            "negative particle": {
                var.r_n: {
                    "min": 0.5,
                    "max": 1
                }
            },
        }
        param.process_geometry(geometry)

        mesh = pybamm.Mesh(geometry, submesh_types, var_pts)

        with self.assertRaisesRegex(pybamm.DomainError, "trying"):
            mesh.combine_submeshes("negative electrode", "negative particle")

        with self.assertRaisesRegex(
                ValueError, "Submesh domains being combined cannot be empty"):
            mesh.combine_submeshes()
Esempio n. 10
0
    def test_manufactured_solution_exponential_grid(self):
        param = pybamm.ParameterValues(
            values={
                "Electrode width [m]": 1,
                "Electrode height [m]": 1,
                "Negative tab width [m]": 1,
                "Negative tab centre y-coordinate [m]": 0.5,
                "Negative tab centre z-coordinate [m]": 0,
                "Positive tab width [m]": 1,
                "Positive tab centre y-coordinate [m]": 0.5,
                "Positive tab centre z-coordinate [m]": 1,
                "Negative electrode thickness [m]": 0.3,
                "Separator thickness [m]": 0.3,
                "Positive electrode thickness [m]": 0.3,
            }
        )

        geometry = pybamm.battery_geometry(
            include_particles=False, current_collector_dimension=2
        )
        param.process_geometry(geometry)

        var = pybamm.standard_spatial_vars
        var_pts = {var.x_n: 3, var.x_s: 3, var.x_p: 3, var.y: 32, var.z: 32}

        submesh_types = {
            "negative electrode": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "separator": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "positive electrode": pybamm.MeshGenerator(pybamm.Uniform1DSubMesh),
            "current collector": pybamm.MeshGenerator(
                pybamm.ScikitExponential2DSubMesh
            ),
        }
        mesh = pybamm.Mesh(geometry, submesh_types, var_pts)

        spatial_methods = {
            "macroscale": pybamm.FiniteVolume(),
            "current collector": pybamm.ScikitFiniteElement(),
        }
        disc = pybamm.Discretisation(mesh, spatial_methods)

        # laplace of u = cos(pi*y)*sin(pi*z)
        var = pybamm.Variable("var", domain="current collector")
        laplace_eqn = pybamm.laplacian(var)
        # set boundary conditions ("negative tab" = bottom of unit square,
        # "positive tab" = top of unit square, elsewhere normal derivative is zero)
        disc.bcs = {
            var.id: {
                "negative tab": (pybamm.Scalar(0), "Dirichlet"),
                "positive tab": (pybamm.Scalar(0), "Dirichlet"),
            }
        }
        disc.set_variable_slices([var])
        laplace_eqn_disc = disc.process_symbol(laplace_eqn)
        y_vertices = mesh["current collector"].coordinates[0, :][:, np.newaxis]
        z_vertices = mesh["current collector"].coordinates[1, :][:, np.newaxis]
        u = np.cos(np.pi * y_vertices) * np.sin(np.pi * z_vertices)
        mass = pybamm.Mass(var)
        mass_disc = disc.process_symbol(mass)
        soln = -np.pi ** 2 * u
        np.testing.assert_array_almost_equal(
            laplace_eqn_disc.evaluate(None, u), mass_disc.entries @ soln, decimal=1
        )