Esempio n. 1
0
    def test_convergence_rt0_2d_iso_simplex_exact(self):

        p_ex = lambda pt: 2 * pt[0, :] - 3 * pt[1, :] - 9
        u_ex = np.array([-1, 4, 0])

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

            kxx = np.ones(g.num_cells)
            perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kzz=1)
            bf = g.get_boundary_faces()
            bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
            bc_val = np.zeros(g.num_faces)
            bc_val[bf] = p_ex(g.face_centers[:, bf])
            vect = np.vstack((g.cell_volumes, g.cell_volumes,
                              np.zeros(g.num_cells))).ravel(order="F")

            solver = pp.RT0(keyword="flow")

            specified_parameters = {
                "bc": bc,
                "bc_values": bc_val,
                "second_order_tensor": perm,
                "vector_source": vect,
            }
            data = pp.initialize_default_data(g, {}, "flow",
                                              specified_parameters)

            solver.discretize(g, data)
            M, rhs = solver.assemble_matrix_rhs(g, data)
            up = sps.linalg.spsolve(M, rhs)
            p = solver.extract_pressure(g, up, data)
            err = np.sum(np.abs(p - p_ex(g.cell_centers)))

            self.assertTrue(np.isclose(err, 0))

            _ = data[pp.DISCRETIZATION_MATRICES]["flow"][
                solver.vector_proj_key]
            u = solver.extract_flux(g, up, data)
            P0u = solver.project_flux(g, u, data)
            err = np.sum(
                np.abs(P0u -
                       np.tile(u_ex, g.num_cells).reshape((3, -1), order="F")))

            self.assertTrue(np.isclose(err, 0))
Esempio n. 2
0
def solve_elliptic_problem(gb):
    for g, d in gb:
        if g.dim == 2:
            d["param"].set_source("flow", source(g, 0.0))

        dir_bound = g.tags["domain_boundary_faces"].nonzero()[0]
        bc_cond = pp.BoundaryCondition(g, dir_bound, ["dir"] * dir_bound.size)
        d["param"].set_bc("flow", bc_cond)

    gb.add_edge_props("param")
    for e, d in gb.edges():
        g_h = gb.nodes_of_edge(e)[1]
        d["param"] = pp.Parameters(g_h)
    flux = pp.EllipticModel(gb)
    p = flux.solve()
    flux.split("pressure")
    pp.fvutils.compute_discharges(gb)
Esempio n. 3
0
    def test_mvem_3d(self):

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

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

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        vect = np.vstack(
            (7 * g.cell_volumes, 4 * g.cell_volumes, 3 * g.cell_volumes)
        ).ravel(order="F")

        b = self._matrix(g, perm, bc, vect)
        b_known = np.array(
            [
                -0.16666667,
                -0.16666667,
                1.16666667,
                0.08333333,
                1.75,
                2.0,
                0.58333333,
                1.5,
                0.08333333,
                -1.5,
                -2.0,
                -0.08333333,
                -0.58333333,
                -1.75,
                -1.16666667,
                0.16666667,
                -0.08333333,
                0.16666667,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ]
        )

        self.assertTrue(np.allclose(b, b_known))
Esempio n. 4
0
    def test_mvem_1d(self):
        g = pp.CartGrid(3, 1)
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(kxx, kyy=1, kzz=1)
        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        vect = np.vstack(
            (g.cell_volumes, np.zeros(g.num_cells), np.zeros(g.num_cells))
        ).ravel(order="F")

        b = self._matrix(g, perm, bc, vect)
        b_known = np.array(
            [0.16666667, 0.33333333, 0.33333333, 0.16666667, 0.0, 0.0, 0.0]
        )

        self.assertTrue(np.allclose(b, b_known))
Esempio n. 5
0
def setup_2d_1d(nx, simplex_grid=False):
    frac1 = np.array([[0.2, 0.8], [0.5, 0.5]])
    frac2 = np.array([[0.5, 0.5], [0.8, 0.2]])
    fracs = [frac1, frac2]
    if not simplex_grid:
        gb = pp.meshing.cart_grid(fracs, nx, physdims=[1, 1])
    else:
        mesh_kwargs = {}
        mesh_size = 0.08
        mesh_kwargs = {
            "mesh_size_frac": mesh_size,
            "mesh_size_bound": 2 * mesh_size,
            "mesh_size_min": mesh_size / 20,
        }
        domain = {"xmin": 0, "ymin": 0, "xmax": 1, "ymax": 1}
        gb = pp.meshing.simplex_grid(fracs, domain, **mesh_kwargs)

    gb.compute_geometry()
    gb.assign_node_ordering()
    gb.add_node_props(["param"])
    for g, d in gb:
        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(3, kxx)
        a = 0.01 / np.max(nx)
        a = np.power(a, gb.dim_max() - g.dim)
        param = pp.Parameters(g)
        param.set_tensor("flow", perm)
        param.set_aperture(a)
        if g.dim == 2:
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            bound = pp.BoundaryCondition(g, bound_faces.ravel("F"),
                                         ["dir"] * bound_faces.size)
            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces] = g.face_centers[1, bound_faces]
            param.set_bc("flow", bound)
            param.set_bc_val("flow", bc_val)
        d["param"] = param

    for e, d in gb.edges():
        gl, _ = gb.nodes_of_edge(e)
        d_l = gb.node_props(gl)
        d["kn"] = 1.0 / np.mean(d_l["param"].get_aperture())

    return gb
Esempio n. 6
0
    def test_zero_pressure(self):
        g = self.grid()

        bf = np.where(g.tags["domain_boundary_faces"].ravel())[0]
        bc_type = bf.size * ["dir"]
        bound = pp.BoundaryCondition(g, bf, bc_type)

        fd = pp.Mpfa("flow")
        data = make_dictionary(g, bound)

        p = self.pressure(fd, g, data)

        self.assertTrue(np.allclose(p, np.zeros_like(p)))

        matrix_dictionary = data[pp.DISCRETIZATION_MATRICES]["flow"]
        bound_p = matrix_dictionary["bound_pressure_cell"] * p + matrix_dictionary[
            "bound_pressure_face"
        ] * np.zeros(g.num_faces)
        self.assertTrue(np.allclose(bound_p, np.zeros_like(bound_p)))
Esempio n. 7
0
    def test_linear_pressure_dirichlet_conditions(self):
        g = self.grid()

        bf = np.where(g.tags["domain_boundary_faces"].ravel())[0]
        bc_type = bf.size * ["dir"]
        bound = pp.BoundaryCondition(g, bf, bc_type)

        fd = pp.Mpfa("flow")

        bc_val = 1 * g.face_centers[0] + 2 * g.face_centers[1]
        data = make_dictionary(g, bound, bc_val)
        p = self.pressure(fd, g, data)

        matrix_dictionary = data[pp.DISCRETIZATION_MATRICES]["flow"]
        bound_p = (
            matrix_dictionary["bound_pressure_cell"] * p
            + matrix_dictionary["bound_pressure_face"] * bc_val
        )
        self.assertTrue(np.allclose(bound_p[bf], bc_val[bf]))
Esempio n. 8
0
    def test_zero_force(self):
        """
        test that nothing moves if nothing is touched
        """
        g = self.gb3d.grids_of_dimension(3)[0]

        data = {"param": pp.Parameters(g)}
        bound = pp.BoundaryCondition(g, g.get_all_boundary_faces(), "dir")

        data["param"].set_bc("mechanics", bound)

        solver = pp.FracturedMpsa()

        A, b = solver.matrix_rhs(g, data)
        u = np.linalg.solve(A.A, b)
        T = solver.traction(g, data, u)

        self.assertTrue(np.all(np.abs(u) < 1e-10))
        self.assertTrue(np.all(np.abs(T) < 1e-10))
Esempio n. 9
0
def setup_2d_1d(nx, simplex_grid=False):
    if not simplex_grid:
        frac1 = np.array([[0.2, 0.8], [0.5, 0.5]])
        frac2 = np.array([[0.5, 0.5], [0.8, 0.2]])
        fracs = [frac1, frac2]

        gb = pp.meshing.cart_grid(fracs, nx, physdims=[1, 1])
    else:
        p = np.array([[0.2, 0.8, 0.5, 0.5], [0.5, 0.5, 0.8, 0.2]])
        e = np.array([[0, 2], [1, 3]])
        domain = {"xmin": 0, "ymin": 0, "xmax": 1, "ymax": 1}
        network = pp.FractureNetwork2d(p, e, domain)
        mesh_size = 0.08
        mesh_kwargs = {"mesh_size_frac": mesh_size, "mesh_size_min": mesh_size / 20}

        gb = network.mesh(mesh_kwargs)

    gb.compute_geometry()
    gb.assign_node_ordering()
    aperture = 0.01 / np.max(nx)
    for g, d in gb:
        a = np.power(aperture, gb.dim_max() - g.dim) * np.ones(g.num_cells)
        kxx = np.ones(g.num_cells) * a
        perm = pp.SecondOrderTensor(kxx)
        specified_parameters = {"second_order_tensor": perm}
        if g.dim == 2:
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            bound = pp.BoundaryCondition(
                g, bound_faces.ravel("F"), ["dir"] * bound_faces.size
            )
            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces] = g.face_centers[1, bound_faces]
            specified_parameters.update({"bc": bound, "bc_values": bc_val})

        pp.initialize_default_data(g, d, "flow", specified_parameters)

    for e, d in gb.edges():
        gl, _ = gb.nodes_of_edge(e)
        mg = d["mortar_grid"]
        kn = 1.0 / aperture
        d[pp.PARAMETERS] = pp.Parameters(mg, ["flow"], [{"normal_diffusivity": kn}])
        d[pp.DISCRETIZATION_MATRICES] = {"flow": {}}
    return gb
Esempio n. 10
0
    def test_simplex_3d_sub_face(self):
        """
        Test that we reconstruct the exact solution on subfaces
        """
        nx = 2
        ny = 2
        nz = 2
        g = pp.StructuredTetrahedralGrid([nx, ny, nz], physdims=[1, 1, 1])
        g.compute_geometry()
        s_t = pp.fvutils.SubcellTopology(g)

        kxx = 10 * np.ones(g.num_cells)
        k = pp.SecondOrderTensor(kxx)

        bc = pp.BoundaryCondition(g)
        bc.is_dir[g.get_all_boundary_faces()] = True
        bc.is_neu[bc.is_dir] = False
        bc = pp.fvutils.boundary_to_sub_boundary(bc, s_t)

        p_b = np.sum(-g.face_centers, axis=0)
        p_b = p_b[s_t.fno_unique]

        mpfa = pp.Mpfa("flow")
        flux, bound_flux, p_t_cell, p_t_bound = mpfa.mpfa(g,
                                                          k,
                                                          bc,
                                                          eta=0,
                                                          inverter="python")

        div = pp.fvutils.scalar_divergence(g)

        hf2f = pp.fvutils.map_hf_2_f(nd=1, g=g)
        P = sps.linalg.spsolve(div * hf2f * flux,
                               -div * hf2f * bound_flux * p_b)

        P_hf = p_t_cell * P + p_t_bound * p_b
        _, IA = np.unique(s_t.fno_unique, True)
        P_f = P_hf[IA]

        self.assertTrue(
            np.all(np.abs(P + np.sum(g.cell_centers, axis=0)) < 1e-10))
        self.assertTrue(
            np.all(np.abs(P_f + np.sum(g.face_centers, axis=0)) < 1e-10))
Esempio n. 11
0
    def test_no_neumann(self):
        g = pp.CartGrid([2, 2], physdims=[1, 1])
        g.compute_geometry()
        k = pp.SecondOrderTensor(2, np.ones(g.num_cells))
        robin_weight = 1.5

        bot = g.face_centers[1] < 1e-10
        top = g.face_centers[1] > 1 - 1e-10
        left = g.face_centers[0] < 1e-10
        right = g.face_centers[0] > 1 - 1e-10

        dir_ind = np.ravel(np.argwhere(top + left))
        rob_ind = np.ravel(np.argwhere(bot + right))

        names = ["dir"] * len(dir_ind) + ["rob"] * len(rob_ind)
        bnd_ind = np.hstack((dir_ind, rob_ind))
        bnd = pp.BoundaryCondition(g, bnd_ind, names)

        flux, bound_flux, _, _ = pp.numerics.fv.mpfa._mpfa_local(
            g, k, bnd, robin_weight=robin_weight
        )

        div = pp.fvutils.scalar_divergence(g)

        rob_ex = [robin_weight * .25, robin_weight * .75, 1, 1]
        u_bound = np.zeros(g.num_faces)
        u_bound[dir_ind] = g.face_centers[1, dir_ind]
        u_bound[rob_ind] = rob_ex * g.face_areas[rob_ind]

        a = div * flux
        b = -div * bound_flux * u_bound

        p = np.linalg.solve(a.A, b)

        u_ex = [
            np.dot(g.face_normals[:, f], np.array([0, -1, 0]))
            for f in range(g.num_faces)
        ]
        u_ex = np.array(u_ex).ravel("F")
        p_ex = g.cell_centers[1]

        self.assertTrue(np.allclose(p, p_ex))
        self.assertTrue(np.allclose(flux * p + bound_flux * u_bound, u_ex))
Esempio n. 12
0
    def test_mvem_2d_simplex(self):
        g = pp.StructuredTriangleGrid([1, 1], [1, 1])
        g.compute_geometry()

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

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        vect = np.vstack(
            (2 * g.cell_volumes, 3 * g.cell_volumes, np.zeros(g.num_cells))
        ).ravel(order="F")
        b = self._matrix(g, perm, bc, vect)

        b_known = np.array(
            [-1.33333333, -1.16666667, 0.33333333, 1.16666667, 1.33333333, 0.0, 0.0]
        )

        self.assertTrue(np.allclose(b, b_known))
Esempio n. 13
0
    def test_simplex_3d_dirichlet(self):
        """
        Test that we retrieve a linear solution exactly
        """
        nx = 2
        ny = 2
        nz = 2
        g = pp.StructuredTetrahedralGrid([nx, ny, nz], physdims=[1, 1, 1])
        g.compute_geometry()

        np.random.seed(2)

        kxx = np.ones(g.num_cells)
        k = pp.SecondOrderTensor(kxx)

        s_t = pp.fvutils.SubcellTopology(g)

        bc = pp.BoundaryCondition(g)
        bc.is_dir[g.get_all_boundary_faces()] = True
        bc.is_neu[bc.is_dir] = False

        p0 = 1
        p_b = np.sum(g.face_centers, axis=0) + p0

        mpfa = pp.Mpfa("flow")

        flux, bound_flux, p_t_cell, p_t_bound = mpfa.mpfa(g,
                                                          k,
                                                          bc,
                                                          eta=0,
                                                          inverter="python")

        div = pp.fvutils.scalar_divergence(g)

        P = sps.linalg.spsolve(div * flux, -div * bound_flux * p_b)

        P_f = p_t_cell * P + p_t_bound * p_b

        self.assertTrue(
            np.all(np.abs(P - np.sum(g.cell_centers, axis=0) - p0) < 1e-10))
        self.assertTrue(
            np.all(np.abs(P_f - np.sum(g.face_centers, axis=0) - p0) < 1e-10))
Esempio n. 14
0
    def test_dual_rt0_1d_line(self):
        g = pp.CartGrid(3, 1)
        R = pp.map_geometry.rotation_matrix(np.pi / 6.0, [0, 0, 1])
        g.nodes = np.dot(R, g.nodes)
        g.compute_geometry()

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

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        vect = np.vstack((g.cell_volumes, 0 * g.cell_volumes,
                          0 * g.cell_volumes)).ravel(order="F")

        b = self._matrix(g, perm, bc, vect)
        b_known = np.array(
            [0.14433757, 0.28867513, 0.28867513, 0.14433757, 0.0, 0.0, 0.0])

        self.assertTrue(np.allclose(b, b_known))
Esempio n. 15
0
    def test_rt0_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)

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        solver = pp.RT0(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_rt0_3d()

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))
Esempio n. 16
0
    def test_rt0_2d_ani_simplex_surf(self):
        g = pp.simplex.StructuredTriangleGrid([1, 1], [1, 1])
        g.compute_geometry()

        al = np.square(g.cell_centers[1, :]) + np.square(g.cell_centers[0, :]) + 1
        kxx = (np.square(g.cell_centers[0, :]) + 1) / al
        kyy = (np.square(g.cell_centers[1, :]) + 1) / al
        kxy = np.multiply(g.cell_centers[0, :], g.cell_centers[1, :]) / al

        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()

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        solver = pp.RT0(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(
            [
                [0.39814815, 0., -0.0462963, -0.15740741, 0., -1., 0.],
                [0., 0.39814815, 0.0462963, 0., -0.15740741, 0., -1.],
                [-0.0462963, 0.0462963, 0.46296296, 0.00925926, -0.00925926, -1., 1.],
                [-0.15740741, 0., 0.00925926, 0.34259259, 0., -1., 0.],
                [0., -0.15740741, -0.00925926, 0., 0.34259259, 0., -1.],
                [-1., 0., -1., -1., 0., 0., 0.],
                [0., -1., 1., 0., -1., 0., 0.],
            ]
        )

        self.assertTrue(np.allclose(M, M.T))
        # We test only the mass-Hdiv part
        self.assertTrue(np.allclose(M, M_known))
def set_bc_mech(gb, top_displacement=0.01):
    """
    Minimal bcs for mechanics.
    """
    a = 1e-2
    physics = "mechanics"
    eps = 1e-10
    last_ind = gb.dim_max() - 1

    for g, d in gb:
        param = d["param"]

        E = 1
        poisson = 0.3
        d["Young"] = E
        d["Poisson"] = poisson
        # Update fields s.a. param.nfaces.
        # TODO: Add update method
        param.__init__(g)
        aperture = np.ones(g.num_cells) * np.power(a, gb.dim_max() - g.dim)
        param.set_aperture(aperture)
        bound_faces = g.get_all_boundary_faces()
        if bound_faces.size > 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            top = bound_face_centers[last_ind, :] > 1 - eps
            bottom = bound_face_centers[last_ind, :] < eps
            left = bound_face_centers[0, :] > 1 - eps
            right = bound_face_centers[0, :] < eps

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

            bc_val = np.zeros((g.dim, g.num_faces))
            bc_dir = bound_faces[top]
            if g.dim > last_ind:
                bc_val[last_ind, bc_dir] = top_displacement

            param.set_bc(physics, pp.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(physics, bc_val.ravel("F"))
            param.set_slip_distance(np.zeros(g.num_faces * g.dim))
Esempio n. 18
0
    def test_1d_heterogeneous_weights(self):
        """ Check that the weights are upwinded.
        """
        g = pp.CartGrid(3, 1)
        g.compute_geometry()

        solver = pp.utils.derived_discretizations.implicit_euler.ImplicitUpwind(
        )
        dis = solver.darcy_flux(g, [2, 0, 0])

        bf = g.tags["domain_boundary_faces"].nonzero()[0]
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        bc_val = np.array([2, 0, 0, 2]).ravel("F")
        specified_parameters = {
            "bc": bc,
            "bc_values": bc_val,
            "darcy_flux": dis,
            "time_step": 1,
            "advection_weight": np.arange(2, 5),
        }
        data = pp.initialize_default_data(g, {}, "transport",
                                          specified_parameters)

        solver.discretize(g, data)

        M, rhs = solver.assemble_matrix_rhs(g, data)
        # First row:    flux x a_w[0] = 2 x 2, which flows out of the cell (+)
        # Second row:   flux x a_w[0] = 2 x 2, which flows into the cell (-)
        #               flux x a_w[1] = 2 x 3, which flows out of the cell (+)
        # Last row:     flux x a_w[1] = 2 x 3,, which flows into the cell (-)
        #               flux x a_w[2] = 2 x 4, which flows out of the cell (+)
        M_known = np.array([[4, 0, 0], [-4, 6, 0], [0, -6, 8]])
        # Left boundary (first cell): Influx x bc_val x advection_weight[0]
        #                                 = 2 x 2 x 2.
        # Right boundary (last cell): outflux => rhs = 0
        rhs_known = np.array([8, 0, 0])

        rtol = 1e-15
        atol = rtol
        self.assertTrue(np.allclose(M.todense(), M_known, rtol, atol))
        self.assertTrue(np.allclose(rhs, rhs_known, rtol, atol))
Esempio n. 19
0
    def test_laplacian_stencil_cart_2d(self):
        """ Apply MPFA on Cartesian grid, should obtain Laplacian stencil. """

        # Set up 3 X 3 Cartesian grid
        g, perm = setup_cart_2d(np.array([3, 3]))

        bnd_faces = np.array([0, 3, 12])
        bound = pp.BoundaryCondition(g, bnd_faces, ["dir"] * bnd_faces.size)

        # Python inverter is most efficient for small problems
        flux, bound_flux, *_ = pp.Mpfa("flow")._flux_discretization(
            g, perm, bound, inverter="python"
        )
        div = g.cell_faces.T
        A = div * flux

        # Checks on interior cell
        mid = 4
        self.assertTrue(A[mid, mid] == 4)
        self.assertTrue(A[mid - 1, mid] == -1)
        self.assertTrue(A[mid + 1, mid] == -1)
        self.assertTrue(A[mid - 3, mid] == -1)
        self.assertTrue(A[mid + 3, mid] == -1)

        # The first cell should have two Dirichlet bnds
        self.assertTrue(A[0, 0] == 6)
        self.assertTrue(A[0, 1] == -1)
        self.assertTrue(A[0, 3] == -1)

        # Cell 3 has one Dirichlet, one Neumann face
        self.assertTrue(A[2, 2] == 4)
        self.assertTrue(A[2, 1] == -1)
        self.assertTrue(A[2, 5] == -1)

        # Cell 2 has one Neumann face
        self.assertTrue(A[1, 1] == 3)
        self.assertTrue(A[1, 0] == -1)
        self.assertTrue(A[1, 2] == -1)
        self.assertTrue(A[1, 4] == -1)

        return A
    def set_param(g, d):
        # Helper method to set parameters.
        # For Mpfa and Mpsa, some of the data is redundant, but that should be fine;
        # it allows us to use a single parameter function
        d[pp.PARAMETERS] = {}
        d[pp.PARAMETERS]["flow"] = {
            "bc": pp.BoundaryCondition(g),
            "bc_values": np.zeros(g.num_faces),
            "second_order_tensor": pp.SecondOrderTensor(np.ones(g.num_cells)),
            "biot_alpha": 1,
            "mass_weight": np.ones(g.num_cells),
        }

        d[pp.PARAMETERS]["mechanics"] = {
            "bc": pp.BoundaryConditionVectorial(g),
            "bc_values": np.zeros(g.num_faces * g.dim),
            "fourth_order_tensor": pp.FourthOrderTensor(
                np.ones(g.num_cells), np.ones(g.num_cells)
            ),
            "biot_alpha": 1,
        }
Esempio n. 21
0
    def test_constant_pressure_simplex_grid(self):
        g = self.simplex_grid()

        bf = np.where(g.tags["domain_boundary_faces"].ravel())[0]
        bc_type = bf.size * ["dir"]
        bound = pp.BoundaryCondition(g, bf, bc_type)

        fd = pp.Mpfa("flow")

        bc_val = np.ones(g.num_faces)
        data = make_dictionary(g, bound, bc_val)
        p = self.pressure(fd, g, data)

        self.assertTrue(np.allclose(p, np.ones_like(p)))

        matrix_dictionary = data[pp.DISCRETIZATION_MATRICES]["flow"]
        bound_p = (
            matrix_dictionary["bound_pressure_cell"] * p
            + matrix_dictionary["bound_pressure_face"] * bc_val
        )
        self.assertTrue(np.allclose(bound_p[bf], bc_val[bf]))
Esempio n. 22
0
def setup_2d_1d(nx, simplex_grid=False):
    if not simplex_grid:
        mesh_args = nx
    else:
        mesh_size = 0.08
        mesh_args = {
            "mesh_size_frac": mesh_size,
            "mesh_size_min": mesh_size / 20
        }

    end_x = [0.2, 0.8]
    end_y = [0.8, 0.2]
    gb, _ = pp.grid_buckets_2d.two_intersecting(mesh_args, end_x, end_y,
                                                simplex_grid)
    aperture = 0.01 / np.max(nx)
    for g, d in gb:
        a = np.power(aperture, gb.dim_max() - g.dim) * np.ones(g.num_cells)
        kxx = np.ones(g.num_cells) * a
        perm = pp.SecondOrderTensor(kxx)
        specified_parameters = {"second_order_tensor": perm}
        if g.dim == 2:
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            bound = pp.BoundaryCondition(g, bound_faces.ravel("F"),
                                         ["dir"] * bound_faces.size)
            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces] = g.face_centers[1, bound_faces]
            specified_parameters.update({"bc": bound, "bc_values": bc_val})

        pp.initialize_default_data(g, d, "flow", specified_parameters)

    for e, d in gb.edges():
        gl, _ = gb.nodes_of_edge(e)
        mg = d["mortar_grid"]
        kn = 1.0 / aperture
        d[pp.PARAMETERS] = pp.Parameters(mg, ["flow"],
                                         [{
                                             "normal_diffusivity": kn
                                         }])
        d[pp.DISCRETIZATION_MATRICES] = {"flow": {}}
    return gb
Esempio n. 23
0
    def set_params(self, gb):
        kw = "flow"
        for g, d in gb:
            parameter_dictionary = {}

            perm = pp.SecondOrderTensor(kxx=np.ones(g.num_cells))
            parameter_dictionary["second_order_tensor"] = perm

            parameter_dictionary["source"] = np.zeros(g.num_cells)

            yf = g.face_centers[1]
            bound_faces = [
                np.where(np.abs(yf - 1) < 1e-4)[0],
                np.where(np.abs(yf) < 1e-4)[0],
            ]
            bound_faces = np.hstack((bound_faces[0], bound_faces[1]))
            labels = np.array(["dir"] * bound_faces.size)
            parameter_dictionary["bc"] = pp.BoundaryCondition(
                g, bound_faces, labels)

            bv = np.zeros(g.num_faces)
            bound_faces = np.where(np.abs(yf - 1) < 1e-4)[0]
            bv[bound_faces] = 1
            parameter_dictionary["bc_values"] = bv
            parameter_dictionary["mpfa_inverter"] = "python"

            d[pp.PARAMETERS] = pp.Parameters(g, [kw], [parameter_dictionary])
            d[pp.DISCRETIZATION_MATRICES] = {"flow": {}}

        gb.add_edge_props("kn")
        kn = 1e7
        for e, d in gb.edges():
            mg = d["mortar_grid"]

            flow_dictionary = {
                "normal_diffusivity": 2 * kn * np.ones(mg.num_cells)
            }
            d[pp.PARAMETERS] = pp.Parameters(keywords=["flow"],
                                             dictionaries=[flow_dictionary])
            d[pp.DISCRETIZATION_MATRICES] = {"flow": {}}
Esempio n. 24
0
    def test_uniform_flow_cart_2d(self):
        # Structured Cartesian grid
        g, perm = setup_cart_2d(np.array([10, 10]))
        bound_faces = np.argwhere(
            np.abs(g.cell_faces).sum(axis=1).A.ravel("F") == 1)
        bound = pp.BoundaryCondition(g, bound_faces.ravel("F"),
                                     ["dir"] * bound_faces.size)

        # Python inverter is most efficient for small problems
        flux, bound_flux, *_ = pp.Mpfa("flow")._flux_discretization(
            g, perm, bound, inverter="python")
        div = g.cell_faces.T

        a = div * flux

        pr_bound, pr_cell, gx, gy = setup_random_pressure_field(g)

        rhs = div * bound_flux * pr_bound
        pr = np.linalg.solve(a.todense(), -rhs)

        p_diff = pr - pr_cell
        self.assertTrue(np.max(np.abs(p_diff)) < 1e-8)
Esempio n. 25
0
    def test_rt0_1d_ani(self):
        g = pp.structured.CartGrid(3, 1)
        g.compute_geometry()

        kxx = 1.0 / (np.sin(g.cell_centers[0, :]) + 1)
        perm = pp.SecondOrderTensor(kxx, kyy=1, kzz=1)
        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        M = self._matrix(g, perm, bc)

        M_known = np.matrix([
            [0.12954401, 0.06477201, 0.0, 0.0, 1.0, 0.0, 0.0],
            [0.06477201, 0.29392463, 0.08219031, 0.0, -1.0, 1.0, 0.0],
            [0.0, 0.08219031, 0.3577336, 0.09667649, 0.0, -1.0, 1.0],
            [0.0, 0.0, 0.09667649, 0.19335298, 0.0, 0.0, -1.0],
            [1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0],
        ])

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))
Esempio n. 26
0
    def test_flow_nz_rhs(self):
        nxs = [1, 3]
        nys = [1, 3]
        for nx in nxs:
            for ny in nys:
                g = pp.CartGrid([nx, ny], physdims=[1, 1])
                g.compute_geometry()
                k = pp.SecondOrderTensor(np.ones(g.num_cells))
                robin_weight = 1.5

                left = g.face_centers[0] < 1e-10
                right = g.face_centers[0] > 1 - 1e-10

                dir_ind = np.ravel(np.argwhere(left))
                rob_ind = np.ravel(np.argwhere(right))

                names = ["dir"] * len(dir_ind) + ["rob"] * len(rob_ind)
                bnd_ind = np.hstack((dir_ind, rob_ind))
                bnd = pp.BoundaryCondition(g, bnd_ind, names)

                p_bound = 1
                rob_bound = 1

                C = (rob_bound - robin_weight * p_bound) / (robin_weight -
                                                            p_bound)
                u_ex = -C * g.face_normals[0]
                p_ex = C * g.cell_centers[0] + p_bound
                self.solve_robin(
                    g,
                    k,
                    bnd,
                    robin_weight,
                    p_bound,
                    rob_bound,
                    dir_ind,
                    rob_ind,
                    p_ex,
                    u_ex,
                )
Esempio n. 27
0
    def test_rt0_1d_iso(self):
        g = pp.structured.CartGrid(3, 1)
        g.compute_geometry()

        kxx = np.ones(g.num_cells)
        perm = pp.SecondOrderTensor(kxx, kyy=1, kzz=1)
        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])

        M = self._matrix(g, perm, bc)
        M_known = np.matrix([
            [0.11111111, 0.05555556, 0.0, 0.0, 1.0, 0.0, 0.0],
            [0.05555556, 0.22222222, 0.05555556, 0.0, -1.0, 1.0, 0.0],
            [0.0, 0.05555556, 0.22222222, 0.05555556, 0.0, -1.0, 1.0],
            [0.0, 0.0, 0.05555556, 0.11111111, 0.0, 0.0, -1.0],
            [1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0],
        ])

        self.assertTrue(np.allclose(M, M.T))
        self.assertTrue(np.allclose(M, M_known))
Esempio n. 28
0
    def test_mvem_2d_simplex_surf(self):
        g = pp.StructuredTriangleGrid([1, 1], [1, 1])
        R = pp.map_geometry.rotation_matrix(-np.pi / 4.0, [1, 1, -1])
        g.nodes = np.dot(R, g.nodes)
        g.compute_geometry()

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

        bf = g.get_boundary_faces()
        bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"])
        vect = np.vstack(
            (g.cell_volumes, 2 * g.cell_volumes, 0 * g.cell_volumes)
        ).ravel(order="F")

        b = self._matrix(g, perm, bc, vect)
        b_known = np.array(
            [-0.73570226, -0.82197528, -0.17254603, 0.82197528, 0.73570226, 0.0, 0.0]
        )

        self.assertTrue(np.allclose(b, b_known))
Esempio n. 29
0
    def test_sign_trouble_two_neumann_sides(self):
        g = pp.CartGrid(np.array([2, 2]), physdims=[2, 2])
        g.compute_geometry()
        bc_val = np.zeros(g.num_faces)
        bc_val[[0, 3]] = 1
        bc_val[[2, 5]] = -1
        t = pp.Tpfa("flow")
        data = make_dictionary(g, pp.BoundaryCondition(g), bc_val)
        t.discretize(g, data)
        t.assemble_matrix_rhs(g, data)
        # The problem is singular, and spsolve does not work well on all systems.
        # Instead, set a consistent solution, and check that the boundary
        # pressure is recovered.
        x = g.cell_centers[0]

        matrix_dictionary = data[pp.DISCRETIZATION_MATRICES]["flow"]
        bound_p = (
            matrix_dictionary["bound_pressure_cell"] * x
            + matrix_dictionary["bound_pressure_face"] * bc_val
        )
        self.assertTrue(bound_p[0] == x[0] - 0.5)
        self.assertTrue(bound_p[2] == x[1] + 0.5)
Esempio n. 30
0
def setup_data(gb, key="flow"):
    """Setup the data"""
    for g, d in gb:
        param = {}
        kxx = np.ones(g.num_cells)
        param["second_order_tensor"] = pp.SecondOrderTensor(kxx)

        if g.dim == gb.dim_max():
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            bound = pp.BoundaryCondition(
                g, bound_faces.ravel("F"), ["dir"] * bound_faces.size
            )
            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces] = g.face_centers[1, bound_faces]
            param["bc"] = bound
            param["bc_values"] = bc_val
            param["aperture"] = np.ones(g.num_cells)
            d[pp.PARAMETERS] = pp.Parameters(g, key, param)
            d[pp.DISCRETIZATION_MATRICES] = {key: {}}

    for _, d in gb.edges():
        d[pp.DISCRETIZATION_MATRICES] = {key: {}}