Beispiel #1
0
    def test_no_dynamics_2d(self):
        g_list = setup_grids.setup_2d()
        for g in g_list:
            discr = biot.Biot()

            bound_faces = g.get_all_boundary_faces()
            bound = bc.BoundaryCondition(g, bound_faces.ravel("F"),
                                         ["dir"] * bound_faces.size)
            bound_mech = bc.BoundaryConditionVectorial(
                g, bound_faces.ravel("F"), ["dir"] * bound_faces.size)

            mu = np.ones(g.num_cells)
            c = tensor.FourthOrderTensor(g.dim, mu, mu)
            k = tensor.SecondOrderTensor(g.dim, np.ones(g.num_cells))

            bound_val = np.zeros(g.num_faces)

            param = Parameters(g)
            param.set_bc("flow", bound)
            param.set_bc("mechanics", bound_mech)
            param.set_tensor("flow", k)
            param.set_tensor("mechanics", c)
            param.set_bc_val("mechanics", np.tile(bound_val, g.dim))
            param.set_bc_val("flow", bound_val)
            param.porosity = np.ones(g.num_cells)
            param.biot_alpha = 1
            data = {"param": param, "inverter": "python", "dt": 1}

            A, b = discr.matrix_rhs(g, data)
            sol = np.linalg.solve(A.todense(), b)

            self.assertTrue(
                np.isclose(sol, np.zeros(g.num_cells * (g.dim + 1))).all())
Beispiel #2
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 = bc.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)
Beispiel #3
0
 def setup(self):
     g = CartGrid([5, 5])
     g.compute_geometry()
     stiffness = StiffnessTensor(g.dim, np.ones(g.num_cells),
                                 np.ones(g.num_cells))
     bnd = bc.BoundaryConditionVectorial(g)
     stress, bound_stress = mpsa.mpsa(g, stiffness, bnd, inverter="python")
     return g, stiffness, bnd, stress, bound_stress
Beispiel #4
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 = bc.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)
Beispiel #5
0
    def test_unit_slip(self):
        """
        Unit slip of fractures
        """

        f = np.array([[0, 0, 1], [0, 2, 1], [2, 2, 1], [2, 0, 1]]).T
        g = meshing.cart_grid([f], [2, 2, 2]).grids_of_dimension(3)[0]
        data = {"param": Parameters(g)}

        bound = bc.BoundaryConditionVectorial(g, g.get_all_boundary_faces(),
                                              "dir")
        data["param"].set_bc("mechanics", bound)

        slip = np.ones(g.dim * g.num_faces)
        data["param"].set_slip_distance(slip)

        solver = StaticModel(g, data)
        solver.solve()

        solver.frac_displacement("d_f")
        solver.displacement("d_c")

        solver.save(["d_c"])

        # test cell displacent around fractures
        d_c = data["d_c"]
        d_c = d_c.reshape((3, -1), order="F")
        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
        solver.traction("T")
        T_left = data["T"][:, frac_left]
        T_right = data["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(d_c[:, cell_left] > 0))
        self.assertTrue(np.all(d_c[:, cell_right] < 0))

        # Test fracture displacement
        u_left = data["d_f"][:, :int(round(data["d_f"].shape[1] / 2))]
        u_right = data["d_f"][:, int(round(data["d_f"].shape[1] / 2)):]
        self.assertTrue(np.all(np.abs(u_left - u_right - 1) < 1e-10))
Beispiel #6
0
    def test_conservation_of_momentum(self):
        pts = np.random.rand(3, 9)
        corners = [
            [0, 0, 0, 0, 1, 1, 1, 1],
            [0, 0, 1, 1, 0, 0, 1, 1],
            [0, 1, 0, 1, 0, 1, 0, 1],
        ]
        pts = np.hstack((corners, pts))
        gt = simplex.TetrahedralGrid(pts)
        gc = structured.CartGrid([3, 3, 3], physdims=[1, 1, 1])
        g_list = [gt, gc]
        [g.compute_geometry() for g in g_list]
        for g in g_list:
            g.compute_geometry()
            bot = np.ravel(np.argwhere(g.face_centers[1, :] < 1e-10))
            left = np.ravel(np.argwhere(g.face_centers[0, :] < 1e-10))
            dir_faces = np.hstack((left, bot))
            bound = bc.BoundaryConditionVectorial(g, dir_faces.ravel("F"),
                                                  ["dir"] * dir_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

            bndr = g.get_all_boundary_faces()
            d_x = np.random.rand(bndr.size)
            d_y = np.random.rand(bndr.size)
            d_bound = np.zeros((g.dim, g.num_faces))
            d_bound[0, bndr] = d_x
            d_bound[1, bndr] = 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")
            traction_2d = traction.reshape((g.dim, -1), order="F")
            for cell in range(g.num_cells):
                fid, _, sgn = sps.find(g.cell_faces[:, cell])
                self.assertTrue(
                    np.all(np.sum(traction_2d[:, fid] * sgn, axis=1) < 1e-10))
Beispiel #7
0
    def test_one_cell_a_time_node_keyword(self):
        # Update one and one cell, and verify that the result is the same as
        # with a single computation. The test is similar to what will happen
        # with a memory-constrained splitting.
        g = CartGrid([3, 3])
        g.compute_geometry()

        # Assign random permeabilities, for good measure
        np.random.seed(42)
        mu = np.random.random(g.num_cells)
        lmbda = np.random.random(g.num_cells)
        stiffness = StiffnessTensor(2, mu=mu, lmbda=lmbda)

        stress = sps.csr_matrix((g.num_faces * g.dim, g.num_cells * g.dim))
        bound_stress = sps.csr_matrix(
            (g.num_faces * g.dim, g.num_faces * g.dim))
        faces_covered = np.zeros(g.num_faces, np.bool)

        bnd = bc.BoundaryConditionVectorial(g)
        stress_full, bound_stress_full = mpsa.mpsa(g,
                                                   stiffness,
                                                   bnd,
                                                   inverter="python")

        cn = g.cell_nodes()
        for ci in range(g.num_cells):
            ind = np.zeros(g.num_cells)
            ind[ci] = 1
            nodes = np.squeeze(np.where(cn * ind > 0))
            partial_stress, partial_bound, active_faces = mpsa.mpsa_partial(
                g, stiffness, bnd, nodes=nodes, inverter="python")

            if np.any(faces_covered):
                del_faces = self.expand_indices_nd(
                    np.where(faces_covered)[0], g.dim)
                partial_stress[del_faces, :] *= 0
                partial_bound[del_faces, :] *= 0
            faces_covered[active_faces] = True

            stress += partial_stress
            bound_stress += partial_bound

        self.assertTrue((stress_full - stress).max() < 1e-8)
        self.assertTrue((stress_full - stress).min() > -1e-8)
        self.assertTrue((bound_stress - bound_stress_full).max() < 1e-8)
        self.assertTrue((bound_stress - bound_stress_full).min() > -1e-8)
Beispiel #8
0
    def test_zero_force(self):
        """
        if nothing is touched nothing should happen
        """
        f = np.array([[0, 0, 1], [0, 1, 1], [1, 1, 1], [1, 0, 1]]).T
        g = meshing.cart_grid([f], [4, 4, 2]).grids_of_dimension(3)[0]
        data = {"param": Parameters(g)}

        bound = bc.BoundaryConditionVectorial(g, g.get_all_boundary_faces(),
                                              "dir")
        data["param"].set_bc("mechanics", bound)

        solver = StaticModel(g, data)
        d = solver.solve()
        solver.traction("T")
        self.assertTrue(np.all(d == 0))
        self.assertTrue(np.all(data["T"] == 0))
Beispiel #9
0
    def test_uniform_displacement_neumann(self):
        physdims = [1, 1]
        g_size = [4, 8]
        g_list = [
            structured.CartGrid([n, n], physdims=physdims) for n in g_size
        ]
        [g.compute_geometry() for g in g_list]
        error = []
        for g in g_list:
            bot = np.ravel(np.argwhere(g.face_centers[1, :] < 1e-10))
            left = np.ravel(np.argwhere(g.face_centers[0, :] < 1e-10))
            dir_faces = np.hstack((left, bot))
            bound = bc.BoundaryConditionVectorial(g, dir_faces.ravel("F"),
                                                  ["dir"] * dir_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)
    def test_vectorial_bc(self):
        """
        We mixed bc_val on domain boundary and fracture displacement in
        x-direction.
        """
        frac = np.array([[1, 1, 1], [1, 2, 1], [2, 2, 1], [2, 1, 1]]).T
        physdims = np.array([3, 3, 2])

        g = meshing.cart_grid([frac], [3, 3, 2],
                              physdims=physdims).grids_of_dimension(3)[0]
        data = {'param': Parameters(g)}

        # Define boundary conditions
        bc_val = np.zeros((g.dim, g.num_faces))
        frac_slip = np.zeros((g.dim, g.num_faces))

        frac_bnd = g.tags['fracture_faces']
        dom_bnd = g.tags['domain_boundary_faces']

        frac_slip[0, frac_bnd] = np.ones(np.sum(frac_bnd))
        bc_val[:, dom_bnd] = g.face_centers[:, dom_bnd]

        bound = bc.BoundaryConditionVectorial(g, g.get_all_boundary_faces(),
                                              'dir')

        data['param'].set_bc('mechanics', bound)
        data['param'].set_bc_val('mechanics', bc_val)
        data['param'].set_slip_distance(frac_slip.ravel('F'))
        solver = mpsa.FracturedMpsa()

        A, b = solver.matrix_rhs(g, data)
        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')

        # Test traction
        frac_faces = g.frac_pairs
        frac_left = frac_faces[0]
        frac_right = frac_faces[1]

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

        assert np.allclose(T_left, T_right)

        # we have u_lhs - u_rhs = 1 so u_lhs should be positive
        mid_ind = int(round(u_f.size / 2))
        u_left = u_f[:mid_ind]
        u_right = u_f[mid_ind:]

        true_diff = np.atleast_2d(np.array([1, 0, 0])).T
        u_left = u_left.reshape((3, -1), order='F')
        u_right = u_right.reshape((3, -1), order='F')
        assert np.all(np.abs(u_left - u_right - true_diff) < 1e-10)

        # should have a positive displacement for all cells
        assert np.all(u_c > 0)