コード例 #1
0
    def test_flip_axis(self):
        """
        We want to test the rotation of mixed conditions, but this is not so easy to
        compare because rotating the basis will change the type of boundary condition
        that is applied in the different directions. This test overcomes that by flipping
        the x- and y-axis and the flipping the boundary conditions also.
        """
        g = pp.CartGrid([2, 2], [1, 1])
        g.compute_geometry()
        nf = g.num_faces
        basis = np.array([[[0] * nf, [1] * nf], [[1] * nf, [0] * nf]])
        bc = pp.BoundaryConditionVectorial(g)
        west = g.face_centers[0] < 1e-7
        south = g.face_centers[1] < 1e-7
        north = g.face_centers[1] > 1 - 1e-7
        east = g.face_centers[0] > 1 - 1e-7
        bc.is_dir[0, west] = True
        bc.is_rob[1, west] = True
        bc.is_rob[0, north] = True
        bc.is_neu[1, north] = True
        bc.is_dir[0, south] = True
        bc.is_neu[1, south] = True
        bc.is_dir[:, east] = True
        bc.is_neu[bc.is_dir + bc.is_rob] = False
        k = pp.FourthOrderTensor(np.random.rand(g.num_cells),
                                 np.random.rand(g.num_cells))
        # Solve without rotations
        stress, bound_stress, _, _ = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        div = pp.fvutils.vector_divergence(g)

        u_bound = np.random.rand(g.dim, g.num_faces)
        u = np.linalg.solve((div * stress).A,
                            -div * bound_stress * u_bound.ravel("F"))

        # Solve with rotations
        bc = pp.BoundaryConditionVectorial(g)
        bc.basis = basis
        bc.is_dir[1, west] = True
        bc.is_rob[0, west] = True
        bc.is_rob[1, north] = True
        bc.is_neu[0, north] = True
        bc.is_dir[1, south] = True
        bc.is_neu[0, south] = True
        bc.is_dir[:, east] = True
        bc.is_neu[bc.is_dir + bc.is_rob] = False
        stress_b, bound_stress_b, _, _ = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        u_bound_b = np.sum(basis * u_bound, axis=1)
        u_b = np.linalg.solve((div * stress_b).A,
                              -div * bound_stress_b * u_bound_b.ravel("F"))
        # Assert that solutions are the same
        self.assertTrue(np.allclose(u, u_b))
コード例 #2
0
    def test_rotation(self):
        # we do a 45 degree rotation
        g = pp.CartGrid([1, 1])
        bc = pp.BoundaryConditionVectorial(g)
        subcell_topology = pp.fvutils.SubcellTopology(g)
        bc.basis = np.array(
            [[[1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [-1, -1, -1, -1]]]
        )

        BM = pp.fvutils.ExcludeBoundaries(subcell_topology, bc, g.dim).basis_matrix

        bm_ref = np.array(
            [
                [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
                [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
                [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
                [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
                [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
                [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
                [1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0],
                [0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0],
                [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
                [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0],
                [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0],
                [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0],
                [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1],
            ]
        )
        self.assertTrue(np.allclose(BM.A, bm_ref))
コード例 #3
0
    def test_structured_triang(self):
        nx = 1
        ny = 1
        g = pp.StructuredTriangleGrid([nx, ny], physdims=[1, 1])
        g.compute_geometry()

        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

        is_dir = left
        is_neu = top
        is_rob = right + bot

        bnd = pp.BoundaryConditionVectorial(g)
        bnd.is_neu[:] = False

        bnd.is_dir[:, is_dir] = True
        bnd.is_rob[:, is_rob] = True
        bnd.is_neu[:, is_neu] = True

        sc_top = pp.fvutils.SubcellTopology(g)
        bnd = pp.fvutils.boundary_to_sub_boundary(bnd, sc_top)
        bnd_excl = pp.fvutils.ExcludeBoundaries(sc_top, bnd, g.dim)

        rhs = pp.numerics.fv.mpsa.create_bound_rhs(bnd, bnd_excl, sc_top, g,
                                                   True)
        hf2f = pp.fvutils.map_hf_2_f(sc_top.fno_unique, sc_top.subfno_unique,
                                     g.dim)
        rhs = rhs * hf2f.T

        rhs_known = np.array([
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
            [0.0, 0.0, 0.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, 0.0, 0.0, 0.0],
            [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        ])

        self.assertTrue(np.all(np.abs(rhs_known - rhs) < 1e-12))
コード例 #4
0
    def test_changing_bc(self):
        """
        We test that we can change the boundary condition
        """
        g = pp.StructuredTriangleGrid([2, 2], physdims=(1, 1))
        g.compute_geometry()
        bc = pp.BoundaryConditionVectorial(g)
        k = pp.FourthOrderTensor(g.dim, np.ones(g.num_cells),
                                 np.ones(g.num_cells))
        stress_neu, bound_stress_neu = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")

        bc.is_dir[:, g.get_all_boundary_faces()] = True
        bc.is_neu[bc.is_dir] = False

        stress_dir, bound_stress_dir = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        # Partiall should give same result as full
        faces = g.get_all_boundary_faces()
        stress, bound_stress = pp.numerics.fv.mpsa.mpsa_update_partial(
            stress_neu,
            bound_stress_neu,
            g,
            k,
            bc,
            faces=faces,
            inverter="python")

        self.assertTrue(np.allclose((stress - stress_dir).data, 0))
        self.assertTrue(np.allclose((bound_stress - bound_stress_dir).data, 0))
コード例 #5
0
    def test_changing_bc_by_cells(self):
        """
        Test that we can change the boundary condition by specifying the boundary cells
        """
        g = pp.StructuredTetrahedralGrid([2, 2, 2], physdims=(1, 1, 1))
        g.compute_geometry()
        bc = pp.BoundaryConditionVectorial(g)
        k = pp.FourthOrderTensor(g.dim, np.ones(g.num_cells),
                                 np.ones(g.num_cells))
        stress_neu, bound_stress_neu = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")

        faces = g.face_centers[2] < 1e-10

        bc.is_rob[:, faces] = True
        bc.is_neu[bc.is_rob] = False

        stress_rob, bound_stress_rob = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        # Update should not change anything
        cells = np.argwhere(g.cell_faces[faces, :])[:, 1].ravel()
        cells = np.unique(cells)

        stress, bound_stress = pp.numerics.fv.mpsa.mpsa_update_partial(
            stress_neu,
            bound_stress_neu,
            g,
            k,
            bc,
            cells=cells,
            inverter="python")

        self.assertTrue(np.allclose((stress - stress_rob).data, 0))
        self.assertTrue(np.allclose((bound_stress - bound_stress_rob).data, 0))
コード例 #6
0
 def test_default(self):
     g = pp.CartGrid([1, 1])
     bc = pp.BoundaryConditionVectorial(g)
     subcell_topology = pp.fvutils.SubcellTopology(g)
     BM = pp.fvutils.ExcludeBoundaries(subcell_topology, bc, g.dim).basis_matrix
     bm_ref = np.eye(2 * 2 * 4)
     self.assertTrue(np.allclose(BM.A, bm_ref))
コード例 #7
0
ファイル: test_mpsa_partial.py プロジェクト: zabonah/porepy
    def test_cart_2d(self):
        """
        When not changing the parameters the output should equal the input
        """
        g = pp.CartGrid([1, 1], physdims=(1, 1))
        g.compute_geometry()
        bc = pp.BoundaryConditionVectorial(g)
        k = pp.FourthOrderTensor(np.ones(g.num_cells), np.ones(g.num_cells))

        stress_full, bound_stress_full, hf_cell_full, hf_bound_full = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")

        # Update should not change anything
        faces = np.array([0, 3])
        stress, bound_stress, hf_cell, hf_bound = pp.numerics.fv.mpsa.mpsa_update_partial(
            stress_full,
            bound_stress_full,
            hf_cell_full,
            hf_bound_full,
            g,
            k,
            bc,
            faces=faces,
            inverter="python",
        )

        self.assertTrue(np.allclose((stress - stress_full).data, 0))
        self.assertTrue(np.allclose((bound_stress - bound_stress_full).data,
                                    0))
        self.assertTrue(np.allclose((hf_cell - hf_cell_full).data, 0))
        self.assertTrue(np.allclose((hf_bound - hf_bound_full).data, 0))
コード例 #8
0
    def test_uniform_displacement(self):

        g_list = setup_grids.setup_2d()

        for g in g_list:
            bound_faces = np.argwhere(
                np.abs(g.cell_faces).sum(axis=1).A.ravel("F") == 1)
            bound = pp.BoundaryConditionVectorial(g, bound_faces.ravel("F"),
                                                  ["dir"] * bound_faces.size)
            constit = setup_stiffness(g)

            # Python inverter is most efficient for small problems
            stress, bound_stress, _, _ = mpsa.mpsa(g,
                                                   constit,
                                                   bound,
                                                   inverter="python")

            div = fvutils.vector_divergence(g)
            a = div * stress

            d_x = np.random.rand(1)
            d_y = np.random.rand(1)
            d_bound = np.zeros((g.dim, g.num_faces))
            d_bound[0, bound.is_dir[0]] = d_x
            d_bound[1, bound.is_dir[1]] = d_y

            rhs = div * bound_stress * d_bound.ravel("F")

            d = np.linalg.solve(a.todense(), -rhs)

            traction = stress * d + bound_stress * d_bound.ravel("F")

            self.assertTrue(np.max(np.abs(d[::2] - d_x)) < 1e-8)
            self.assertTrue(np.max(np.abs(d[1::2] - d_y)) < 1e-8)
            self.assertTrue(np.max(np.abs(traction)) < 1e-8)
コード例 #9
0
    def test_cart_2d(self):
        g = pp.CartGrid([2, 1], physdims=(1, 1))
        g.compute_geometry()
        right = g.face_centers[0] > 1 - 1e-10
        top = g.face_centers[1] > 1 - 1e-10

        bc = pp.BoundaryConditionVectorial(g)
        bc.is_dir[:, top] = True
        bc.is_dir[0, right] = True

        bc.is_neu[bc.is_dir] = False

        g = true_2d(g)

        subcell_topology = pp.fvutils.SubcellTopology(g)
        # Mat boundary to subfaces
        bc = pp.fvutils.boundary_to_sub_boundary(bc, subcell_topology)
        bound_exclusion = pp.fvutils.ExcludeBoundaries(subcell_topology, bc,
                                                       g.dim)
        cell_node_blocks = np.array([[0, 0, 0, 0, 1, 1, 1, 1],
                                     [0, 1, 3, 4, 1, 2, 4, 5]])
        ncasym_np = np.arange(32 * 32).reshape((32, 32))
        ncasym = sps.csr_matrix(ncasym_np)
        pp.Mpsa("")._eliminate_ncasym_neumann(ncasym, subcell_topology,
                                              bound_exclusion,
                                              cell_node_blocks, 2)
        eliminate_ind = np.array([0, 1, 16, 17, 26, 27])
        ncasym_np[eliminate_ind] = 0
        self.assertTrue(np.allclose(ncasym.A, ncasym_np))
コード例 #10
0
    def setup_biot(self):
        g = pp.CartGrid([5, 5])
        g.compute_geometry()
        stiffness = pp.FourthOrderTensor(np.ones(g.num_cells),
                                         np.ones(g.num_cells))
        bnd = pp.BoundaryConditionVectorial(g)

        specified_data = {
            "fourth_order_tensor": stiffness,
            "bc": bnd,
            "inverter": "python",
            "biot_alpha": 1,
        }
        keyword_mech = "mechanics"
        keyword_flow = "flow"
        data = pp.initialize_default_data(g, {},
                                          keyword_mech,
                                          specified_parameters=specified_data)
        data = pp.initialize_default_data(g, data, keyword_flow)

        discr = pp.Biot()
        discr.discretize(g, data)
        div_u = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.div_u_matrix_key]
        bound_div_u = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.bound_div_u_matrix_key]
        stab = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.stabilization_matrix_key]
        grad_p = data[pp.DISCRETIZATION_MATRICES][keyword_mech][
            discr.grad_p_matrix_key]
        bound_pressure = data[pp.DISCRETIZATION_MATRICES][keyword_mech][
            discr.bound_pressure_matrix_key]

        return g, stiffness, bnd, div_u, bound_div_u, grad_p, stab, bound_pressure
コード例 #11
0
    def test_changing_bc_by_nodes(self):
        """
        Test that we can change the boundary condition by specifying the boundary nodes
        """
        g = pp.CartGrid([2, 2], physdims=(1, 1))
        g.compute_geometry()
        bc = pp.BoundaryConditionVectorial(g)
        k = pp.FourthOrderTensor(g.dim, np.ones(g.num_cells),
                                 np.ones(g.num_cells))
        stress_neu, bound_stress_neu = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        faces = g.face_centers[1] > 1 - 1e-10

        bc.is_dir[:, faces] = True
        bc.is_neu[bc.is_dir] = False

        stress_dir, bound_stress_dir = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")
        # Update should not change anything
        nodes = np.array([3, 5, 4, 6, 7, 8])
        stress, bound_stress = pp.numerics.fv.mpsa.mpsa_update_partial(
            stress_neu,
            bound_stress_neu,
            g,
            k,
            bc,
            nodes=nodes,
            inverter="python")

        self.assertTrue(np.allclose((stress - stress_dir).data, 0))
        self.assertTrue(np.allclose((bound_stress - bound_stress_dir).data, 0))
コード例 #12
0
    def setup(self):
        g = pp.CartGrid([5, 5])
        g.compute_geometry()
        stiffness = pp.FourthOrderTensor(np.ones(g.num_cells),
                                         np.ones(g.num_cells))
        bnd = pp.BoundaryConditionVectorial(g)

        specified_data = {
            "fourth_order_tensor": stiffness,
            "bc": bnd,
            "inverter": "python",
        }
        keyword = "mechanics"
        data = pp.initialize_default_data(g, {},
                                          keyword,
                                          specified_parameters=specified_data)

        discr = pp.Mpsa(keyword)
        discr.discretize(g, data)
        stress = data[pp.DISCRETIZATION_MATRICES][keyword][
            discr.stress_matrix_key]
        bound_stress = data[pp.DISCRETIZATION_MATRICES][keyword][
            discr.bound_stress_matrix_key]

        return g, stiffness, bnd, stress, bound_stress
コード例 #13
0
ファイル: test_mpsa_partial.py プロジェクト: zabonah/porepy
    def test_no_change_input(self):
        """
        The input matrices should not be changed
        """
        g = pp.CartGrid([4, 4], physdims=(1, 1))
        g.compute_geometry()
        bc = pp.BoundaryConditionVectorial(g)
        k = pp.FourthOrderTensor(np.ones(g.num_cells), np.ones(g.num_cells))

        stress, bound_stress, hf_cell, hf_bound = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, inverter="python")

        stress_old = stress.copy()
        bound_stress_old = bound_stress.copy()
        hf_cell_old = hf_cell.copy()
        hf_bound_old = hf_bound.copy()

        # Update should not change anything
        faces = np.array([0, 4, 5, 6])
        _ = pp.numerics.fv.mpsa.mpsa_update_partial(
            stress,
            bound_stress,
            hf_cell,
            hf_bound,
            g,
            k,
            bc,
            faces=faces,
            inverter="python",
        )

        self.assertTrue(np.allclose((stress - stress_old).data, 0))
        self.assertTrue(np.allclose((bound_stress - bound_stress_old).data, 0))
        self.assertTrue(np.allclose((hf_cell - hf_cell_old).data, 0))
        self.assertTrue(np.allclose((hf_bound - hf_bound_old).data, 0))
コード例 #14
0
    def test_mix(self):
        nx = 2
        ny = 1
        g = pp.CartGrid([nx, ny], physdims=[1, 1])
        g.compute_geometry()
        basis = np.random.rand(g.dim, g.dim, g.num_faces)

        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

        bc = pp.BoundaryConditionVectorial(g)
        bc.is_neu[:] = False

        bc.is_dir[0, left] = True
        bc.is_neu[1, left] = True

        bc.is_rob[0, right] = True
        bc.is_dir[1, right] = True

        bc.is_neu[0, bot] = True
        bc.is_rob[1, bot] = True

        bc.is_rob[0, top] = True
        bc.is_dir[1, top] = True

        self.run_test(g, basis, bc)
コード例 #15
0
 def make_boundary_conditions(self, g):
     bound_faces = g.get_all_boundary_faces()
     bound_flow = pp.BoundaryCondition(g, bound_faces.ravel("F"),
                                       ["dir"] * bound_faces.size)
     bound_mech = pp.BoundaryConditionVectorial(g, bound_faces.ravel("F"),
                                                ["dir"] * bound_faces.size)
     return bound_mech, bound_flow
 def _bc_type(self, g: pp.Grid) -> pp.BoundaryConditionVectorial:
     """
     We set Neumann values imitating an anisotropic background stress regime on all
     but three faces, which are fixed to ensure a unique solution.
     """
     bc = pp.BoundaryConditionVectorial(g, g.get_all_boundary_faces(),
                                        "dir")
     return bc
コード例 #17
0
    def setup(self):
        g = pp.CartGrid([5, 5])
        g.compute_geometry()
        stiffness = pp.FourthOrderTensor(np.ones(g.num_cells), np.ones(g.num_cells))
        bnd = pp.BoundaryConditionVectorial(g)
        stress, bound_stress, _, _ = mpsa.mpsa(g, stiffness, bnd, inverter="python")

        return g, stiffness, bnd, stress, bound_stress
コード例 #18
0
 def bc_type_mechanics(self, g):
     all_bf, east, west, north, south, top, bottom = self.domain_boundary_sides(
         g)
     bc = pp.BoundaryConditionVectorial(g, north + south, "dir")
     frac_face = g.tags["fracture_faces"]
     bc.is_neu[:, frac_face] = False
     bc.is_dir[:, frac_face] = True
     return bc
コード例 #19
0
 def _bc_type_mechanics(self, g) -> pp.BoundaryConditionVectorial:
     """
     Dirichlet values at top and bottom.
     """
     all_bf, east, west, north, south, _, _ = self._domain_boundary_sides(g)
     dir_faces = south + north + g.tags["fracture_faces"]
     bc = pp.BoundaryConditionVectorial(g, dir_faces, "dir")
     return bc
コード例 #20
0
    def test_uniform_strain(self):
        g_list = setup_grids.setup_2d()

        for g in g_list:
            bound_faces = np.argwhere(
                np.abs(g.cell_faces).sum(axis=1).A.ravel("F") == 1)
            bound = pp.BoundaryConditionVectorial(g, bound_faces.ravel("F"),
                                                  ["dir"] * bound_faces.size)
            mu = 1
            l = 1
            constit = setup_stiffness(g, mu, l)

            # Python inverter is most efficient for small problems
            stress, bound_stress, _, _ = mpsa.mpsa(g,
                                                   constit,
                                                   bound,
                                                   inverter="python")

            div = fvutils.vector_divergence(g)
            a = div * stress

            xc = g.cell_centers
            xf = g.face_centers

            gx = np.random.rand(1)
            gy = np.random.rand(1)

            dc_x = np.sum(xc * gx, axis=0)
            dc_y = np.sum(xc * gy, axis=0)
            df_x = np.sum(xf * gx, axis=0)
            df_y = np.sum(xf * gy, axis=0)

            d_bound = np.zeros((g.dim, g.num_faces))

            d_bound[0, bound.is_dir[0]] = df_x[bound.is_dir[0]]
            d_bound[1, bound.is_dir[1]] = df_y[bound.is_dir[1]]

            rhs = div * bound_stress * d_bound.ravel("F")

            d = np.linalg.solve(a.todense(), -rhs)

            traction = stress * d + bound_stress * d_bound.ravel("F")

            s_xx = (2 * mu + l) * gx + l * gy
            s_xy = mu * (gx + gy)
            s_yx = mu * (gx + gy)
            s_yy = (2 * mu + l) * gy + l * gx

            n = g.face_normals
            traction_ex_x = s_xx * n[0] + s_xy * n[1]
            traction_ex_y = s_yx * n[0] + s_yy * n[1]

            self.assertTrue(np.max(np.abs(d[::2] - dc_x)) < 1e-8)
            self.assertTrue(np.max(np.abs(d[1::2] - dc_y)) < 1e-8)
            self.assertTrue(
                np.max(np.abs(traction[::2] - traction_ex_x)) < 1e-8)
            self.assertTrue(
                np.max(np.abs(traction[1::2] - traction_ex_y)) < 1e-8)
コード例 #21
0
    def test_unit_slip(self):
        """
        test unit slip of fractures
        """
        frac = np.array([[1, 1, 1], [1, 2, 1], [2, 2, 1], [2, 1, 1]]).T
        physdims = np.array([3, 3, 2])
        g = pp.meshing.cart_grid([frac], [3, 3, 2],
                                 physdims=physdims).grids_of_dimension(3)[0]

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

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

        frac_slip = np.zeros((g.dim, g.num_faces))
        frac_bnd = g.tags["fracture_faces"]
        frac_slip[:, frac_bnd] = np.ones((g.dim, np.sum(frac_bnd)))

        data["param"].set_slip_distance(frac_slip.ravel("F"))

        solver = pp.FracturedMpsa()

        A, b = solver.matrix_rhs(g, data, inverter="python")
        u = np.linalg.solve(A.A, b)

        u_f = solver.extract_frac_u(g, u)
        u_c = solver.extract_u(g, u)
        u_c = u_c.reshape((3, -1), order="F")

        # obtain fracture faces and cells
        frac_faces = g.frac_pairs
        frac_left = frac_faces[0]
        frac_right = frac_faces[1]

        cell_left = np.ravel(np.argwhere(g.cell_faces[frac_left, :])[:, 1])
        cell_right = np.ravel(np.argwhere(g.cell_faces[frac_right, :])[:, 1])

        # Test traction
        T = solver.traction(g, data, u)
        T = T.reshape((3, -1), order="F")
        T_left = T[:, frac_left]
        T_right = T[:, frac_right]

        self.assertTrue(np.allclose(T_left, T_right))

        # we have u_lhs - u_rhs = 1 so u_lhs should be positive
        self.assertTrue(np.all(u_c[:, cell_left] > 0))
        self.assertTrue(np.all(u_c[:, cell_right] < 0))
        mid_ind = int(round(u_f.size / 2))
        u_left = u_f[:mid_ind]
        u_right = u_f[mid_ind:]
        self.assertTrue(np.all(np.abs(u_left - u_right - 1) < 1e-10))

        # fracture displacement should be symetric since everything else is
        # symetric
        self.assertTrue(np.allclose(u_left, 0.5))
        self.assertTrue(np.allclose(u_right, -0.5))
コード例 #22
0
 def test_neu(self):
     g = pp.StructuredTriangleGrid([2, 2])
     basis = np.random.rand(g.dim, g.dim, g.num_faces)
     bc = pp.BoundaryConditionVectorial(g, g.get_all_boundary_faces(),
                                        "neu")
     # Add a Dirichlet condition so the system is well defined
     bc.is_dir[:, g.get_boundary_faces()[0]] = True
     bc.is_neu[bc.is_dir] = False
     self.run_test(g, basis, bc)
コード例 #23
0
    def test_default_basis_2d(self):
        g = pp.StructuredTriangleGrid([1, 1])
        bc = pp.BoundaryConditionVectorial(g)
        basis_known = np.array([
            [[1.0, 1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0, 0.0]],
            [[0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0, 1.0]],
        ])

        self.assertTrue(np.allclose(bc.basis, basis_known))
コード例 #24
0
    def test_cart_2d(self):
        """
        Test that mpsa gives out the correct matrices for
        reconstruction of the displacement at the faces
        """
        nx = 1
        ny = 1
        g = pp.CartGrid([nx, ny], physdims=[2, 2])
        g.compute_geometry()

        lam = np.array([1])
        mu = np.array([2])
        k = pp.FourthOrderTensor(mu, lam)

        bc = pp.BoundaryConditionVectorial(g)
        _, _, grad_cell, grad_bound = pp.numerics.fv.mpsa.mpsa(
            g, k, bc, hf_disp=True, inverter="python")

        grad_bound_known = np.array([
            [0.10416667, 0.0, 0.0, 0.0, 0.0, -0.02083333, 0.0, 0.0],
            [0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.10416667, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02083333],
            [0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.10416667, 0.0, 0.0, 0.02083333, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.10416667, 0.0, 0.0, 0.0, 0.0, -0.02083333],
            [0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0],
            [-0.02083333, 0.0, 0.0, 0.0, 0.0, 0.10416667, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0],
            [0.0, 0.0, 0.02083333, 0.0, 0.0, 0.10416667, 0.0, 0.0],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0],
            [0.02083333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10416667],
            [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0],
            [0.0, 0.0, -0.02083333, 0.0, 0.0, 0.0, 0.0, 0.10416667],
        ])

        grad_cell_known = np.array([
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
            [1.0, 0.0],
            [0.0, 1.0],
        ])
        self.assertTrue(np.all(np.abs(grad_bound - grad_bound_known) < 1e-7))
        self.assertTrue(np.all(np.abs(grad_cell - grad_cell_known) < 1e-12))
コード例 #25
0
    def test_default_basis_3d(self):
        g = pp.StructuredTetrahedralGrid([1, 1, 1])
        bc = pp.BoundaryConditionVectorial(g)
        basis_known = np.array([
            [[1] * 18, [0] * 18, [0] * 18],
            [[0] * 18, [1] * 18, [0] * 18],
            [[0] * 18, [0] * 18, [1] * 18],
        ])

        self.assertTrue(np.allclose(bc.basis, basis_known))
コード例 #26
0
 def bc_type(self, g):
     _, _, _, north, south, _, _ = self.domain_boundary_sides(g)
     bc = pp.BoundaryConditionVectorial(g, north + south, "dir")
     # Default internal BC is Neumann. We change to Dirichlet for the contact
     # problem. I.e., the mortar variable represents the displacement on the
     # fracture faces.
     frac_face = g.tags["fracture_faces"]
     bc.is_neu[:, frac_face] = False
     bc.is_dir[:, frac_face] = True
     return bc
    def bc_type_mechanics(self, g):
        """
        Dirichlet values at top and bottom.
        """
        all_bf, east, west, north, south, _, _ = self.domain_boundary_sides(g)
        bc = pp.BoundaryConditionVectorial(g, south + north, "dir")
        frac_face = g.tags["fracture_faces"]
        bc.is_neu[:, frac_face] = False
        bc.is_dir[:, frac_face] = True

        return bc
コード例 #28
0
ファイル: mechanics.py プロジェクト: haakon-e/mastersproject
    def bc_type_mechanics(self, g: pp.Grid) -> pp.BoundaryConditionVectorial:  # noqa
        # Define boundary regions
        all_bf = g.get_boundary_faces()
        bc = pp.BoundaryConditionVectorial(g, all_bf, "dir")  # noqa

        # Internal faces are Neumann by default. We change them to
        # Dirichlet for the contact problem. That is: The mortar
        # variable represents the displacement on the fracture faces.
        frac_face = g.tags["fracture_faces"]
        bc.is_neu[:, frac_face] = False
        bc.is_dir[:, frac_face] = True
        return bc
コード例 #29
0
 def bc_type(self, g):
     """ Define type of boundary conditions: Dirichlet on all global boundaries,
     Dirichlet also on fracture faces.
     """
     all_bf = g.get_boundary_faces()
     bc = pp.BoundaryConditionVectorial(g, all_bf, "dir")
     # Default internal BC is Neumann. We change to Dirichlet for the contact
     # problem. I.e., the mortar variable represents the displacement on the
     # fracture faces.
     frac_face = g.tags["fracture_faces"]
     bc.is_neu[:, frac_face] = False
     bc.is_dir[:, frac_face] = True
     return bc
コード例 #30
0
 def bc_type_mechanics(self, g) -> pp.BoundaryConditionVectorial:
     """
     We set Neumann values imitating an anisotropic background stress regime on all
     but three faces, which are fixed to ensure a unique solution.
     """
     all_bf, *_, bottom = self.domain_boundary_sides(g)
     faces = self.faces_to_fix(g)
     # write_fixed_faces_to_csv(g, faces, self)
     bc = pp.BoundaryConditionVectorial(g, faces, "dir")
     frac_face = g.tags["fracture_faces"]
     bc.is_neu[:, frac_face] = False
     bc.is_dir[:, frac_face] = True
     return bc