Exemple #1
0
    def test_p1_1d_ani(self):
        g = pp.structured.CartGrid(3, 1)
        g.compute_geometry()

        kxx = np.sin(g.cell_centers[0, :]) + 1
        perm = pp.SecondOrderTensor(3, kxx, kyy=1, kzz=1)
        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, bn.size * ["neu"])
        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        M_known = np.matrix(
            [
                [3.4976884, -3.4976884, 0., 0.],
                [-3.4976884, 7.93596501, -4.43827662, 0.],
                [0., -4.43827662, 9.65880718, -5.22053056],
                [0., 0., -5.22053056, 5.22053056],
            ]
        )

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))
Exemple #2
0
    def test_p1_2d_ani_simplex_surf(self):
        g = pp.simplex.StructuredTriangleGrid([1, 1], [1, 1])
        g.compute_geometry()

        kxx = np.square(g.cell_centers[1, :]) + 1
        kyy = np.square(g.cell_centers[0, :]) + 1
        kxy = -np.multiply(g.cell_centers[0, :], g.cell_centers[1, :])
        perm = pp.SecondOrderTensor(3, kxx=kxx, kyy=kyy, kxy=kxy, kzz=1)

        R = cg.rot(np.pi / 3., [1, 1, 0])
        perm.rotate(R)
        g.nodes = np.dot(R, g.nodes)
        g.compute_geometry()

        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, bn.size * ["neu"])
        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        # Matrix computed with an already validated code
        M_known = np.matrix(
            [
                [1.11111111, -0.66666667, -0.66666667, 0.22222222],
                [-0.66666667, 1.5, 0., -0.83333333],
                [-0.66666667, 0., 1.5, -0.83333333],
                [0.22222222, -0.83333333, -0.83333333, 1.44444444],
            ]
        )

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))
Exemple #3
0
    def test_p1_convergence_2d_exact(self):

        p_ex = lambda pt: 2 * pt[0, :] - 3 * pt[1, :] - 9

        for i in np.arange(5):
            g = pp.simplex.StructuredTriangleGrid([3 + i] * 2, [1, 1])
            g.compute_geometry()

            kxx = np.ones(g.num_cells)
            perm = pp.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=1)
            bn = g.get_boundary_nodes()
            bc = pp.BoundaryConditionNode(g, bn, bn.size * ["dir"])
            bc_val = np.zeros(g.num_nodes)
            bc_val[bn] = p_ex(g.nodes[:, bn])

            solver = pp.P1(physics="flow")

            param = pp.Parameters(g)
            param.set_tensor(solver, perm)
            param.set_bc(solver, bc)
            param.set_bc_val(solver, bc_val)
            M, rhs = solver.matrix_rhs(g, {"param": param})

            p = sps.linalg.spsolve(M, rhs)
            err = np.sum(np.abs(p - p_ex(g.nodes)))
            self.assertTrue(np.isclose(err, 0))
Exemple #4
0
    def test_p1_1d(self):
        g = pp.structured.CartGrid(1, 1)
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(3, kxx, kyy=1, kzz=1)
        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, bn.size * ["neu"])

        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        M_known = np.matrix([[1., -1.], [-1., 1.]])

        self.assertTrue(np.allclose(M, M_known))

        solver = pp.P1MassMatrix(physics="flow")
        M = solver.matrix(g, {"param": param}).todense()

        M_known = np.matrix([[2., 1.], [1., 2.]]) / 6.

        self.assertTrue(np.allclose(M, M_known))
Exemple #5
0
    def test_p1_2d_iso_simplex_surf(self):
        g = pp.simplex.StructuredTriangleGrid([1, 1], [1, 1])
        R = cg.rot(-np.pi / 4., [1, 1, -1])
        g.nodes = np.dot(R, g.nodes)
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=1)
        perm.rotate(R)

        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, bn.size * ["neu"])
        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        # Matrix computed with an already validated code
        M_known = np.matrix(
            [
                [1., -0.5, -0.5, 0.],
                [-0.5, 1., 0., -0.5],
                [-0.5, 0., 1., -0.5],
                [0., -0.5, -0.5, 1.],
            ]
        )

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))

        solver = pp.P1MassMatrix(physics="flow")
        M = solver.matrix(g, {"param": param}).todense()

        M_known = (
            np.matrix(
                [
                    [1., 0.25, 0.25, 0.5],
                    [0.25, 0.5, 0., 0.25],
                    [0.25, 0., 0.5, 0.25],
                    [0.5, 0.25, 0.25, 1.],
                ]
            )
            / 6.
        )

        self.assertTrue(np.allclose(M, M_known))
Exemple #6
0
    def test_p1_convergence_1d_not_exact(self):

        p_ex = lambda pt: np.sin(2 * np.pi * pt[0, :])
        source_ex = lambda pt: 4 * np.pi ** 2 * np.sin(2 * np.pi * pt[0, :])

        known_errors = [
            0.0739720694066,
            0.0285777089832,
            0.00791150843359,
            0.00202828006648,
            0.00051026002257,
            0.000127765008718,
            3.19537621983e-05,
        ]

        for i, known_error in zip(np.arange(7), known_errors):
            g = pp.structured.CartGrid(4 * 2 ** i, 1)
            g.compute_geometry()

            kxx = np.ones(g.num_cells)
            perm = pp.SecondOrderTensor(3, kxx, kyy=1, kzz=1)
            bn = g.get_boundary_nodes()
            bc = pp.BoundaryConditionNode(g, bn, bn.size * ["dir"])
            source_val = source_ex(g.nodes)

            solver = pp.P1(physics="flow")
            integral = pp.P1Source(physics="flow")

            param = pp.Parameters(g)
            param.set_tensor(solver, perm)
            param.set_bc(solver, bc)
            param.set_source(solver, source_val)
            M, _ = solver.matrix_rhs(g, {"param": param})
            _, rhs = integral.matrix_rhs(g, {"param": param})

            p = sps.linalg.spsolve(M, rhs)

            mass = pp.P1MassMatrix(physics="flow")
            M = mass.matrix(g, {"param": param})

            error = np.sum(M.dot(np.abs(p - p_ex(g.nodes))))
            self.assertTrue(np.isclose(error, known_error))
Exemple #7
0
    def test_p1_1d_iso_line(self):
        g = pp.structured.CartGrid(3, 1)
        R = cg.rot(np.pi / 6., [0, 0, 1])
        g.nodes = np.dot(R, g.nodes)
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(3, kxx, kyy=1, kzz=1)
        perm.rotate(R)

        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, ["dir", "neu"])
        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        # Matrix computed with an already validated code
        M_known = np.matrix(
            [
                [1., 0., 0., 0.],
                [-3., 6., -3., 0.],
                [0., -3., 6., -3.],
                [0., 0., -3., 3.],
            ]
        )

        self.assertTrue(np.allclose(M, M_known))

        solver = pp.P1MassMatrix(physics="flow")
        M = solver.matrix(g, {"param": param}).todense()

        M_known = (
            np.matrix(
                [[0., 0., 0., 0.], [1., 4., 1., 0.], [0., 1., 4., 1.], [0., 0., 1., 2.]]
            )
            / 18.
        )

        self.assertTrue(np.allclose(M, M_known))
Exemple #8
0
    def test_p1_3d(self):

        g = pp.simplex.StructuredTetrahedralGrid([1, 1, 1], [1, 1, 1])
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=kxx)

        bn = g.get_boundary_nodes()
        bc = pp.BoundaryConditionNode(g, bn, bn.size * ["neu"])
        solver = pp.P1(physics="flow")

        param = pp.Parameters(g)
        param.set_tensor(solver, perm)
        param.set_bc(solver, bc)
        M = solver.matrix(g, {"param": param}).todense()

        M_known = matrix_for_test_p1_3d()

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))

        solver = pp.P1MassMatrix(physics="flow")
        M = solver.matrix(g, {"param": param}).todense()

        M_known = (
            np.matrix(
                [
                    [1., 0.5, 0.5, 0., 0.5, 0., 0., 0.],
                    [0.5, 5., 1.5, 1., 1.5, 1., 2., 0.],
                    [0.5, 1.5, 3., 0.5, 1., 0., 1., 0.],
                    [0., 1., 0.5, 3., 0., 1., 1.5, 0.5],
                    [0.5, 1.5, 1., 0., 3., 0.5, 1., 0.],
                    [0., 1., 0., 1., 0.5, 3., 1.5, 0.5],
                    [0., 2., 1., 1.5, 1., 1.5, 5., 0.5],
                    [0., 0., 0., 0.5, 0., 0.5, 0.5, 1.],
                ]
            )
            / 60.
        )

        self.assertTrue(np.allclose(M, M_known))
Exemple #9
0
def add_data(gb, domain, solver, case):

    if case == 1:
        kf = 1e4
    else:
        kf = 1e-4
    data = {"domain": domain, "aperture": 1e-4, "km": 1, "kf": kf}

    if_solver = solver == "vem" or solver == "rt0" or solver == "p1"
    if_p1 = solver == "p1"

    gb.add_node_props(["param", "is_tangential"])
    for g, d in gb:
        param = Parameters(g)

        if g.dim == 3:
            kxx = np.ones(g.num_cells) * data["km"]
            perm = pp.SecondOrderTensor(3, kxx=kxx)
        else:
            kxx = np.ones(g.num_cells) * data["kf"]
            if if_solver:
                if g.dim == 2:
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=kxx, kzz=1)
                elif g.dim == 1:
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=1, kzz=1)
                else:  # g.dim == 0
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=1, kzz=1)
            else:
                perm = pp.SecondOrderTensor(3, kxx=kxx)

        param.set_tensor("flow", perm)

        aperture = np.power(data["aperture"], gb.dim_max() - g.dim)
        param.set_aperture(aperture * np.ones(g.num_cells))

        param.set_source("flow", np.zeros(g.num_cells))

        if if_p1:  # for P1 a different handling of the boundary conditions
            bound_nodes = g.get_boundary_nodes()
            if bound_nodes.size == 0:
                bc = pp.BoundaryConditionNode(g, np.empty(0), np.empty(0))
                bc_val = np.empty(0)
            else:
                p_press, b_in, b_out = b_pressure_node(g)

                labels = np.array(["neu"] * bound_nodes.size)
                labels[p_press] = "dir"

                bc_val = np.zeros(g.num_nodes)
                bc_val[bound_nodes[b_in]] = 1
                bc_val[bound_nodes[b_out]] = -1
                param.set_bc_val("flow", bc_val)

                bc = pp.BoundaryConditionNode(g, bound_nodes, labels)
        else:
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            if bound_faces.size == 0:
                bc = BoundaryCondition(g, np.empty(0), np.empty(0))
                param.set_bc("flow", bc)
            else:
                p_press, b_in, b_out = b_pressure(g)

                labels = np.array(["neu"] * bound_faces.size)
                labels[p_press] = "dir"

                bc_val = np.zeros(g.num_faces)
                bc_val[bound_faces[b_in]] = 1
                bc_val[bound_faces[b_out]] = -1
                param.set_bc_val("flow", bc_val)

                bc = BoundaryCondition(g, bound_faces, labels)

        param.set_bc("flow", bc)

        d["is_tangential"] = True
        d["param"] = param

    gb.add_edge_props("kn")
    for e, d in gb.edges():
        g_l = gb.nodes_of_edge(e)[0]
        mg = d["mortar_grid"]
        check_P = mg.low_to_mortar_avg()

        kxx = data["kf"]
        gamma = np.power(
            check_P * gb.node_props(g_l, "param").get_aperture(),
            1. / (gb.dim_max() - g_l.dim),
        )
        d["kn"] = kxx * np.ones(mg.num_cells) / gamma
Exemple #10
0
def add_data(gb, solver):

    data = {"km": 1, "kf_high": 1e2, "kf_low": 1e-2, "aperture": 1e-2}

    if_solver = solver == "vem" or solver == "rt0" or solver == "p1"
    if_p1 = solver == "p1"

    gb.add_node_props(["param", "is_tangential"])
    for g, d in gb:
        param = pp.Parameters(g)

        if g.dim == 2:
            kxx = np.ones(g.num_cells) * data["km"]
            if if_solver:
                perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=kxx, kzz=1)
            else:
                perm = pp.SecondOrderTensor(3, kxx=kxx)
        elif g.dim == 1:
            if g.cell_centers[1, 0] > 0.25 and g.cell_centers[1, 0] < 0.55:
                kxx = np.ones(g.num_cells) * data["kf_low"]
            else:
                kxx = np.ones(g.num_cells) * data["kf_high"]

            if if_solver:
                perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=1, kzz=1)
            else:
                perm = pp.SecondOrderTensor(3, kxx=kxx)

        param.set_tensor("flow", perm)

        aperture = np.power(data["aperture"], gb.dim_max() - g.dim)
        param.set_aperture(aperture * np.ones(g.num_cells))

        param.set_source("flow", np.zeros(g.num_cells))

        if if_p1:  # for P1 a different handling of the boundary conditions
            bound_nodes = g.get_boundary_nodes()
            if bound_nodes.size == 0:
                bc = pp.BoundaryConditionNode(g, np.empty(0), np.empty(0))
                bc_val = np.empty(0)
            else:
                bound_node_coords = g.nodes[:, bound_nodes]

                top = bound_node_coords[1, :] > domain()["ymax"] - tol()
                bottom = bound_node_coords[1, :] < domain()["ymin"] + tol()

                labels = np.array(["neu"] * bound_nodes.size)
                labels[np.logical_or(top, bottom)] = "dir"

                bc_val = np.zeros(g.num_nodes)
                bc_val[bound_nodes[top]] = 1
                param.set_bc_val("flow", bc_val)

                bc = pp.BoundaryConditionNode(g, bound_nodes, labels)

        else:
            bound_faces = g.get_boundary_faces()
            if bound_faces.size == 0:
                bc = pp.BoundaryCondition(g, np.empty(0), np.empty(0))
            else:
                bound_face_centers = g.face_centers[:, bound_faces]

                top = bound_face_centers[1, :] > domain()["ymax"] - tol()
                bottom = bound_face_centers[1, :] < domain()["ymin"] + tol()

                labels = np.array(["neu"] * bound_faces.size)
                labels[np.logical_or(top, bottom)] = "dir"

                bc_val = np.zeros(g.num_faces)
                bc_val[bound_faces[top]] = 1
                param.set_bc_val("flow", bc_val)

                bc = pp.BoundaryCondition(g, bound_faces, labels)

        param.set_bc("flow", bc)

        d["is_tangential"] = True
        d["param"] = param

    gb.add_edge_props("kn")
    for e, d in gb.edges():
        g_l = gb.nodes_of_edge(e)[0]
        mg = d["mortar_grid"]
        check_P = mg.low_to_mortar_avg()

        if g_l.dim == 1:
            if g_l.cell_centers[1, 0] > 0.25 and g_l.cell_centers[1, 0] < 0.55:
                kxx = data["kf_low"]
            else:
                kxx = data["kf_high"]
        else:
            kxx = data["kf_high"]

        gamma = np.power(
            check_P * gb.node_props(g_l, "param").get_aperture(),
            1.0 / (gb.dim_max() - g_l.dim),
        )
        d["kn"] = kxx * np.ones(mg.num_cells) / gamma