Example #1
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)
Example #2
0
    def test_discretise_spatial_variable(self):
        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_method = pybamm.SpatialMethod()
        spatial_method.build(mesh)

        # centre
        x1 = pybamm.SpatialVariable("x", ["negative electrode"])
        x2 = pybamm.SpatialVariable("x", ["negative electrode", "separator"])
        r = pybamm.SpatialVariable("r", ["negative particle"])
        for var in [x1, x2, r]:
            var_disc = spatial_method.spatial_variable(var)
            self.assertIsInstance(var_disc, pybamm.Vector)
            np.testing.assert_array_equal(
                var_disc.evaluate()[:, 0], mesh.combine_submeshes(*var.domain)[0].nodes
            )

        # edges
        x1_edge = pybamm.SpatialVariableEdge("x", ["negative electrode"])
        x2_edge = pybamm.SpatialVariableEdge("x", ["negative electrode", "separator"])
        r_edge = pybamm.SpatialVariableEdge("r", ["negative particle"])
        for var in [x1_edge, x2_edge, r_edge]:
            var_disc = spatial_method.spatial_variable(var)
            self.assertIsInstance(var_disc, pybamm.Vector)
            np.testing.assert_array_equal(
                var_disc.evaluate()[:, 0], mesh.combine_submeshes(*var.domain)[0].edges
            )
    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,
        )
Example #4
0
 def test_basics(self):
     mesh = get_mesh_for_testing()
     spatial_method = pybamm.SpatialMethod(mesh)
     self.assertEqual(spatial_method.mesh, mesh)
     with self.assertRaises(NotImplementedError):
         spatial_method.gradient(None, None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.divergence(None, None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.laplacian(None, None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.gradient_squared(None, None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.integral(None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.indefinite_integral(None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.boundary_integral(None, None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.delta_function(None, None)
     with self.assertRaises(NotImplementedError):
         spatial_method.internal_neumann_condition(None, None, None, None)
Example #5
0
    def test_process_symbol_base(self):
        # create discretisation
        mesh = get_mesh_for_testing()
        spatial_methods = {
            "macroscale": pybamm.SpatialMethod(),
            "negative particle": pybamm.SpatialMethod(),
            "positive particle": pybamm.SpatialMethod(),
            "current collector": pybamm.SpatialMethod(),
        }
        disc = pybamm.Discretisation(mesh, spatial_methods)

        # variable
        var = pybamm.Variable("var")
        var_vec = pybamm.Variable("var vec", domain=["negative electrode"])
        disc.y_slices = {var.id: [slice(53)], var_vec.id: [slice(53, 93)]}
        var_disc = disc.process_symbol(var)
        self.assertIsInstance(var_disc, pybamm.StateVector)
        self.assertEqual(var_disc.y_slices[0], disc.y_slices[var.id][0])

        # variable dot
        var_dot = pybamm.VariableDot("var'")
        var_dot_disc = disc.process_symbol(var_dot)
        self.assertIsInstance(var_dot_disc, pybamm.StateVectorDot)
        self.assertEqual(var_dot_disc.y_slices[0], disc.y_slices[var.id][0])

        # scalar
        scal = pybamm.Scalar(5)
        scal_disc = disc.process_symbol(scal)
        self.assertIsInstance(scal_disc, pybamm.Scalar)
        self.assertEqual(scal_disc.value, scal.value)
        # vector
        vec = pybamm.Vector(np.array([1, 2, 3, 4]))
        vec_disc = disc.process_symbol(vec)
        self.assertIsInstance(vec_disc, pybamm.Vector)
        np.testing.assert_array_equal(vec_disc.entries, vec.entries)
        # matrix
        mat = pybamm.Matrix(np.array([[1, 2, 3, 4], [5, 6, 7, 8]]))
        mat_disc = disc.process_symbol(mat)
        self.assertIsInstance(mat_disc, pybamm.Matrix)
        np.testing.assert_array_equal(mat_disc.entries, mat.entries)

        # binary operator
        bin = var + scal
        bin_disc = disc.process_symbol(bin)
        self.assertIsInstance(bin_disc, pybamm.Addition)
        self.assertIsInstance(bin_disc.children[0], pybamm.StateVector)
        self.assertIsInstance(bin_disc.children[1], pybamm.Scalar)

        bin2 = scal + var
        bin2_disc = disc.process_symbol(bin2)
        self.assertIsInstance(bin2_disc, pybamm.Addition)
        self.assertIsInstance(bin2_disc.children[0], pybamm.Scalar)
        self.assertIsInstance(bin2_disc.children[1], pybamm.StateVector)

        # non-spatial unary operator
        un1 = -var
        un1_disc = disc.process_symbol(un1)
        self.assertIsInstance(un1_disc, pybamm.Negate)
        self.assertIsInstance(un1_disc.children[0], pybamm.StateVector)

        un2 = abs(var)
        un2_disc = disc.process_symbol(un2)
        self.assertIsInstance(un2_disc, pybamm.AbsoluteValue)
        self.assertIsInstance(un2_disc.children[0], pybamm.StateVector)

        # function of one variable
        def myfun(x):
            return np.exp(x)

        func = pybamm.Function(myfun, var)
        func_disc = disc.process_symbol(func)
        self.assertIsInstance(func_disc, pybamm.Function)
        self.assertIsInstance(func_disc.children[0], pybamm.StateVector)

        func = pybamm.Function(myfun, scal)
        func_disc = disc.process_symbol(func)
        self.assertIsInstance(func_disc, pybamm.Function)
        self.assertIsInstance(func_disc.children[0], pybamm.Scalar)

        # function of multiple variables
        def myfun(x, y):
            return np.exp(x) * y

        func = pybamm.Function(myfun, var, scal)
        func_disc = disc.process_symbol(func)
        self.assertIsInstance(func_disc, pybamm.Function)
        self.assertIsInstance(func_disc.children[0], pybamm.StateVector)
        self.assertIsInstance(func_disc.children[1], pybamm.Scalar)

        # boundary value
        bv_left = pybamm.BoundaryValue(var_vec, "left")
        bv_left_disc = disc.process_symbol(bv_left)
        self.assertIsInstance(bv_left_disc, pybamm.MatrixMultiplication)
        self.assertIsInstance(bv_left_disc.left, pybamm.Matrix)
        self.assertIsInstance(bv_left_disc.right, pybamm.StateVector)
        bv_right = pybamm.BoundaryValue(var_vec, "left")
        bv_right_disc = disc.process_symbol(bv_right)
        self.assertIsInstance(bv_right_disc, pybamm.MatrixMultiplication)
        self.assertIsInstance(bv_right_disc.left, pybamm.Matrix)
        self.assertIsInstance(bv_right_disc.right, pybamm.StateVector)

        # not implemented
        sym = pybamm.Symbol("sym")
        with self.assertRaises(NotImplementedError):
            disc.process_symbol(sym)