def test_conforming_two_fractures(self):
     f_1 = pp.Fracture(
         np.array([[-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]]).T)
     f_2 = pp.Fracture(
         np.array([[-1, 0, -1], [1, 0, -1], [1, 0, 1], [-1, 0, 1]]).T)
     network = pp.FractureNetwork3d([f_1, f_2])
     mesh_args = {
         "mesh_size_frac": 0.4,
         "mesh_size_bound": 1,
         "mesh_size_min": 0.2
     }
     network.mesh(mesh_args, dfn=True)
Exemple #2
0
    def test_one_to_boundary_3d(self):
        """
        One fracture in 3d going all the way to the boundary
        """

        f_1 = np.array([[1, 5, 5, 1], [1, 1, 1, 1], [1, 1, 3, 3]])
        f_set = [pp.Fracture(f_1)]
        domain = {"xmin": 0, "ymin": 0, "zmin": 0, "xmax": 5, "ymax": 5, "zmax": 5}
        mesh_size_min = 0.1
        mesh_size_frac = 0.1
        mesh_size_bound = 2
        on_boundary = np.array(
            [False, False, False, False, True, True, True, True, True, True, True, True]
        )
        network = pp.FractureNetwork3d(f_set)
        network.impose_external_boundary(domain)
        network.find_intersections()
        network.split_intersections()
        network._insert_auxiliary_points(
            mesh_size_frac=mesh_size_frac,
            mesh_size_min=mesh_size_min,
            mesh_size_bound=mesh_size_bound,
        )
        mesh_size = network._determine_mesh_size(boundary_point_tags=on_boundary)

        decomp = network.decomposition

        # Many of the points should have mesh size of 2, adjust the exceptions below
        mesh_size_known = np.full(
            decomp["points"].shape[1], mesh_size_bound, dtype=np.float
        )

        # Find the points on the fracture
        fracture_poly = np.where(np.logical_not(network.tags["boundary"]))[0]
        self.assertTrue(fracture_poly.size == 1)
        fracture_points = decomp["polygons"][fracture_poly[0]][0]
        # These should have been assigned fracture mesh size
        mesh_size_known[fracture_points] = mesh_size_frac

        # Two of the domain corners are close enough to the fracture to have their
        # mesh size modified from the default boundary value
        origin = np.zeros((3, 1))
        _, ind = pp.utils.setmembership.ismember_rows(origin, decomp["points"])
        mesh_size_known[ind] = np.sqrt(3)

        corner = np.array([5, 0, 0]).reshape((3, 1))
        _, ind = pp.utils.setmembership.ismember_rows(
            corner, decomp["points"], sort=False
        )
        mesh_size_known[ind] = np.sqrt(2)

        self.assertTrue(np.all(np.isclose(mesh_size, mesh_size_known)))
    def test_issue_90(self):
        f_1 = pp.Fracture(
            np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]).T)
        f_2 = pp.Fracture(np.array([[0, 0, 1], [0, 0, -1], [1, 1, -1]]).T)

        mesh_args = {
            "mesh_size_frac": 0.4,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }

        network = pp.FractureNetwork3d([f_1, f_2])
        network.mesh(mesh_args)
    def test_T_intersection_within_plane(self, **kwargs):
        f_1 = pp.Fracture(np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]).T)
        f_2 = pp.Fracture(np.array([[0.5, 0.5, 1], [0.5, 0.5, 0], [0.5, 0.9, 0.0]]).T)

        domain = {"xmin": -1, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -1, "zmax": 2}
        # This test, when used with certain versions of gmsh (<2.15?) gives
        # a mismatch between 2d cells and 3d faces on fracture surfaces. The bug
        # can be located in the .msh-file. To function as a test, we disband the
        # test of cell-face relations.
        mesh_args = {"mesh_size_frac": 0.4, "mesh_size_bound": 1, "mesh_size_min": 0.2}

        network = pp.FractureNetwork3d([f_1, f_2], domain=domain)
        network.mesh(mesh_args)
    def test_one_fracture_touching_two_opposing_boundaries(self):
        """
        Two fractures intersecting along a line.

        The example also sets different characteristic mesh lengths on the boundary
        and at the fractures.

        """

        f_1 = pp.Fracture(np.array([[-2, 2, 2, -2], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        mesh_args, domain = self.kwarguments_and_domain()
        network = pp.FractureNetwork3d([f_1], domain)
        network.mesh(mesh_args)
    def test_three_fractures_sharing_line_same_segment(self, **kwargs):
        """
        Three fractures that all share an intersection line. This can be considered
        as three intersection lines that coincide.
        """
        f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(np.array([[-1, 1, 1, -1], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        f_3 = pp.Fracture(np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}
        mesh_args = {"mesh_size_frac": 0.4, "mesh_size_bound": 1, "mesh_size_min": 0.2}

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        network.mesh(mesh_args)
    def test_issue_58_3(self):
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}
        mesh_args = {
            "mesh_size_frac": 0.5,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2,
            "return_expected": True,
        }

        f_1 = pp.Fracture(np.array([[0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]]))
        f_2 = pp.Fracture(np.array([[0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 1, 1]]))

        network = pp.FractureNetwork3d([f_1, f_2], domain=domain)
        network.mesh(mesh_args)
    def test_three_intersecting_fractures(self, **kwargs):
        """
        Three fractures intersecting, with intersecting intersections (point)
        """

        f_1 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]]))
        f_3 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [-1, -1, 1, 1], [0, 0, 0, 0]]))

        # Add some parameters for grid size
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }

        mesh_args = {
            "mesh_size_frac": 0.5,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }
        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)

        gb = network.mesh(mesh_args)

        isect_0_coord = np.array([[0, 0], [0, 0], [-0.7, 0.8]])
        isect_1_coord = np.array([[-1, 1], [0, 0], [0, 0]])
        isect_2_coord = np.array([[0, 0], [-1, 1], [0, 0]])

        isect_0 = IntersectionInfo(0, 1, isect_0_coord)
        isect_1 = IntersectionInfo(0, 2, isect_1_coord)
        isect_2 = IntersectionInfo(1, 2, isect_2_coord)

        isect_pt = np.array([0, 0, 0]).reshape((-1, 1))

        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2, f_3],
            isect_line=[isect_0, isect_1, isect_2],
            isect_pt=[isect_pt],
            expected_num_1d_grids=6,
            expected_num_0d_grids=1,
        )
Exemple #9
0
    def test_fracture_cut_not_split_by_domain(self):
        self.setUp()
        f_1 = pp.Fracture(
            np.array([[-1, 2, 2, -1], [0.5, 0.5, 0.5, 0.5], [-1, -1, 0.7,
                                                             0.7]]))

        network = pp.FractureNetwork3d(f_1, domain=self.non_convex_polyhedron)
        mesh_args = {
            "mesh_size_bound": 1,
            "mesh_size_frac": 1,
            "mesh_size_min": 0.1
        }
        gb = network.mesh(mesh_args)
        self.assertTrue(len(gb.grids_of_dimension(2)) == 1)
Exemple #10
0
    def setup(self, num_fracs=1, remove_tags=False):

        domain = {
            "xmin": 0,
            "xmax": 1,
            "ymin": 0,
            "ymax": 1,
            "zmin": 0,
            "zmax": 1
        }

        if num_fracs == 0:
            fl = []

        elif num_fracs == 1:
            fl = [
                pp.Fracture(
                    np.array([[0, 1, 1, 0], [0.5, 0.5, 0.5, 0.5], [0, 0, 1,
                                                                   1]]))
            ]
        elif num_fracs == 2:
            fl = [
                pp.Fracture(
                    np.array([[0, 1, 1, 0], [0.5, 0.5, 0.5, 0.5], [0, 0, 1,
                                                                   1]])),
                pp.Fracture(
                    np.array([[0.5, 0.5, 0.5, 0.5], [0, 1, 1, 0], [0, 0, 1,
                                                                   1]])),
            ]

        elif num_fracs == 3:
            fl = [
                pp.Fracture(
                    np.array([[0, 1, 1, 0], [0.5, 0.5, 0.5, 0.5], [0, 0, 1,
                                                                   1]])),
                pp.Fracture(
                    np.array([[0.5, 0.5, 0.5, 0.5], [0, 1, 1, 0], [0, 0, 1,
                                                                   1]])),
                pp.Fracture(
                    np.array([[0, 1, 1, 0], [0, 0, 1, 1], [0.5, 0.5, 0.5,
                                                           0.5]])),
            ]

        network = pp.FractureNetwork3d(fl, domain)
        mesh_args = {"mesh_size_frac": 0.5, "mesh_size_min": 0.5}
        gb = network.mesh(mesh_args)

        self.set_params(gb)

        return gb
Exemple #11
0
    def test_unstruct_tetrahedron(self):
        box = {"xmin": 0, "xmax": 1, "ymin": 0, "ymax": 1, "zmin": 0, "zmax": 1}
        network = pp.FractureNetwork3d([], domain=box)
        mesh_args = {"mesh_size_frac": 3, "mesh_size_min": 3}
        gb = network.mesh(mesh_args)
        g = gb.grids_of_dimension(3)[0]
        c = pp.FourthOrderTensor(np.ones(g.num_cells), np.ones(g.num_cells))
        robin_weight = 1.0

        bot = g.face_centers[2] < 1e-10
        top = g.face_centers[2] > 1 - 1e-10
        west = g.face_centers[0] < 1e-10
        east = g.face_centers[0] > 1 - 1e-10
        north = g.face_centers[1] > 1 - 1e-10
        south = g.face_centers[1] < 1e-10

        dir_ind = np.ravel(np.argwhere(west + top))
        neu_ind = np.ravel(np.argwhere(bot))
        rob_ind = np.ravel(np.argwhere(east + north + south))

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

        def u_ex(x):
            return np.vstack((x[1], x[0], 0 * x[2]))

        def T_ex(faces):
            if np.size(faces) == 0:
                return np.atleast_2d(np.array([]))
            sigma = np.array([[0, 2, 0], [2, 0, 0], [0, 0, 0]])
            T_r = [np.dot(sigma, g.face_normals[:, f]) for f in faces]
            return np.vstack(T_r).T

        u_bound = np.zeros((3, g.num_faces))

        sgn_n = g.sign_of_faces(neu_ind)
        sgn_r = g.sign_of_faces(rob_ind)

        u_bound[:, dir_ind] = u_ex(g.face_centers[:, dir_ind])
        u_bound[:, neu_ind] = T_ex(neu_ind) * sgn_n
        u_bound[:, rob_ind] = (
            T_ex(rob_ind) * sgn_r
            + robin_weight * u_ex(g.face_centers[:, rob_ind]) * g.face_areas[rob_ind]
        )
        u, T = self.solve_mpsa(g, c, robin_weight, bnd, u_bound)

        self.assertTrue(np.allclose(u, u_ex(g.cell_centers).ravel("F")))
        self.assertTrue(np.allclose(T, T_ex(np.arange(g.num_faces)).ravel("F")))
    def test_sinle_fracture_aligned_with_axis(self):
        # Test of method FractureNetwork.bounding_box() to inquire about
        # network extent
        f1 = pp.Fracture(np.array([[0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]]),
                         check_convexity=False)

        network = pp.FractureNetwork3d([f1])
        d = network.bounding_box()

        self.assertTrue(d["xmin"] == 0)
        self.assertTrue(d["xmax"] == 1)
        self.assertTrue(d["ymin"] == 0)
        self.assertTrue(d["ymax"] == 1)
        self.assertTrue(d["zmin"] == 0)
        self.assertTrue(d["zmax"] == 0)
    def test_three_fractures_split_segments(self, **kwargs):
        """
        Three fractures that all intersect along the same line, but with the
        intersection between two of them forming an extension of the intersection
        of all three.
        """
        f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [-1, 1, 1, -1], [-0.5, -0.5, 0.5, 0.5]])
        )
        f_3 = pp.Fracture(np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}
        mesh_args = {"mesh_size_frac": 0.4, "mesh_size_bound": 1, "mesh_size_min": 0.2}

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        network.mesh(mesh_args)
    def test_one_fracture_intersected_by_two(self, **kwargs):
        """
        One fracture, intersected by two other (but no point intersections)
        """

        f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]])
        )
        f_3 = pp.Fracture(f_2.p + np.array([0.5, 0, 0]).reshape((-1, 1)))

        # Add some parameters for grid size
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}
        mesh_args = {"mesh_size_frac": 0.4, "mesh_size_bound": 1, "mesh_size_min": 0.2}

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        network.mesh(mesh_args)
def create_grid() -> Tuple[pp.Grid, dict, dict]:
    """ Ivar ex3 grid"""
    # Define the three fractures
    n_points = 16

    # Injection
    f_1 = pp.EllipticFracture(
        np.array([10, 3.5, -3]), 11, 18, 0.5, 0, 0, num_points=n_points,
    )
    f_2 = pp.EllipticFracture(
        np.array([1, 5, 1]),
        15,
        10,
        np.pi * 0,
        np.pi / 4.0,
        np.pi / 2.0,
        num_points=n_points,
    )
    # Production
    f_3 = pp.EllipticFracture(
        np.array([-13, 0, 0]), 20, 10, 0.5, np.pi / 3, np.pi / 1.6, num_points=n_points,
    )
    fractures = [f_1, f_2, f_3]

    # Define the domain
    size = 50
    box = {
        "xmin": -size,
        "xmax": size,
        "ymin": -size,
        "ymax": size,
        "zmin": -size,
        "zmax": size,
    }
    mesh_size = 3.2
    mesh_args = {
        "mesh_size_frac": mesh_size,
        "mesh_size_min": 0.5 * mesh_size,
        "mesh_size_bound": 3 * mesh_size,
    }
    # Make a fracture network
    network = pp.FractureNetwork3d(fractures, domain=box)
    # Generate the mixed-dimensional mesh
    gb = network.mesh(mesh_args)
    return gb, box, mesh_args
    def test_no_fracture(self):
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }
        network = pp.FractureNetwork3d(domain=domain)
        mesh_args = {
            "mesh_size_bound": 1,
            "mesh_size_frac": 1,
            "mesh_size_min": 0.1
        }
        gb = network.mesh(mesh_args)

        self.check_gb(gb, domain)
Exemple #17
0
def setup(tail_folders):
    """ Setup method.

    Set up a fracture network and mesh it.
    """
    pth = Path(os.path.abspath(__file__))
    root = pth.parent / tail_folders
    if not os.path.exists(root):
        os.makedirs(root, exist_ok=True)

    f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
    domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}
    network = pp.FractureNetwork3d([f_1], domain=domain)
    # mesh_args = {"mesh_size_bound": 1, "mesh_size_frac": 2, "mesh_size_min": 0.1}
    mesh_args = {"mesh_size_bound": 10, "mesh_size_frac": 10, "mesh_size_min": 10}
    file_name = str(root / 'test')
    gb = network.mesh(mesh_args=mesh_args, file_name=file_name)
    return network, file_name, gb
    def test_three_intersecting_fractures(self, **kwargs):
        """
        Three fractures intersecting, with intersecting intersections (point)
        """

        f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]])
        )
        f_3 = pp.Fracture(np.array([[-1, 1, 1, -1], [-1, -1, 1, 1], [0, 0, 0, 0]]))

        # Add some parameters for grid size
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}

        mesh_args = {"mesh_size_frac": 0.5, "mesh_size_bound": 1, "mesh_size_min": 0.2}
        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)

        network.mesh(mesh_args)
Exemple #19
0
def create_gb_with_simple_fracture(
    path_head: str, ) -> Tuple[pp.FractureNetwork3d, Path, pp.GridBucket]:
    """ Setup method.

    Set up a fracture network and mesh it.

    Parameters
    ----------
    path_head : str
        head of path to store test files

    Returns
    -------
    network : pp.FractureNetwork3d
    file_name : Path
        path to the gmsh files
        with 'path/to/file_name', but without .geo/.msh endings
    gb : pp.GridBucket
    """
    path = Path(__file__).resolve().parent / "results"
    root = path / path_head
    root.mkdir(parents=True, exist_ok=True)
    file_name = root / "gmsh_frac_file"

    f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
    domain = {
        "xmin": -2,
        "xmax": 2,
        "ymin": -2,
        "ymax": 2,
        "zmin": -2,
        "zmax": 2
    }
    network = pp.FractureNetwork3d([f_1], domain=domain)
    # mesh_args = {"mesh_size_bound": 1, "mesh_size_frac": 2, "mesh_size_min": 0.1}
    mesh_args = {
        "mesh_size_bound": 10,
        "mesh_size_frac": 10,
        "mesh_size_min": 10
    }

    gb = network.mesh(mesh_args=mesh_args, file_name=str(file_name))
    return network, file_name, gb
Exemple #20
0
    def create_grid(self):
        """
        Method that creates and returns the GridBucket of a 3D domain with two
        fractures. The two sides of the fractures are coupled together with a
        mortar grid.
        """
        # define fractures
        f_1 = pp.EllipticFracture(np.array([-0.1, -0.3, -0.8]),
                                  1.5,
                                  1.5,
                                  np.pi / 6.3,
                                  np.pi / 2.2,
                                  np.pi / 4.1,
                                  num_points=8)
        f_2 = pp.EllipticFracture(np.array([1.5, 0.6, 0.8]),
                                  1.5,
                                  1.5,
                                  0,
                                  np.pi / 2.3,
                                  -np.pi / 4.2,
                                  num_points=8)

        # Define a 3d FractureNetwork
        self.fractures = [f_1, f_2]
        network = pp.FractureNetwork3d([f_1, f_2], domain=self.domain)
        # Generate the mixed-dimensional mesh
        gb = network.mesh(self.mesh_args)

        # Remove fracture grid as it is not needed
        for g2 in gb.grids_of_dimension(2):
            gb.remove_node(g2)

        # Define the mortar grid
        meshing.create_mortar_grids(gb)

        g = gb.grids_of_dimension(3)[0]
        data_edge = gb.edge_props((g, g))
        mg = data_edge['mortar_grid']
        # Map the mortars to the subcell grid
        data_edge['mortar_grid_f2c'] = copy.deepcopy(
            mg)  #keep copy of face to cell mortar
        meshing.map_mortar_to_submortar(gb)
        return gb
    def test_two_intersecting_fractures(self, **kwargs):
        """
        Two fractures intersecting along a line.

        The example also sets different characteristic mesh lengths on the boundary
        and at the fractures.

        """

        f_1 = pp.Fracture(np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]])
        )
        domain = {"xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zmin": -2, "zmax": 2}

        mesh_args = {"mesh_size_frac": 0.5, "mesh_size_bound": 1, "mesh_size_min": 0.2}
        network = pp.FractureNetwork3d([f_1, f_2], domain=domain)

        network.mesh(mesh_args)
    def test_two_intersecting_fractures(self, **kwargs):
        """
        Two fractures intersecting along a line.

        The example also sets different characteristic mesh lengths on the boundary
        and at the fractures.

        """

        f_1 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]]))
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }

        mesh_args = {
            "mesh_size_frac": 0.5,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }
        network = pp.FractureNetwork3d([f_1, f_2], domain=domain)

        gb = network.mesh(mesh_args)

        isect_coord = np.array([[0, 0], [0, 0], [-0.7, 0.8]])

        isect = IntersectionInfo(0, 1, isect_coord)

        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2],
            isect_line=[isect],
            expected_num_1d_grids=1,
        )
    def test_one_fracture_intersected_by_two(self, **kwargs):
        """
        One fracture, intersected by two other (but no point intersections)
        """

        f_1 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-0.7, -0.7, 0.8, 0.8]]))
        f_3 = pp.Fracture(f_2.p + np.array([0.5, 0, 0]).reshape((-1, 1)))

        # Add some parameters for grid size
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }
        mesh_args = {
            "mesh_size_frac": 0.4,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        gb = network.mesh(mesh_args)

        isect_0_coord = np.array([[0, 0], [0, 0], [-0.7, 0.8]])

        isect_1_coord = np.array([[0.5, 0.5], [0, 0], [-0.7, 0.8]])

        isect_0 = IntersectionInfo(0, 1, isect_0_coord)
        isect_1 = IntersectionInfo(0, 2, isect_1_coord)
        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2, f_3],
            isect_line=[isect_0, isect_1],
            expected_num_1d_grids=2,
        )
    def test_split_into_octants(self, **kwargs):
        f_1 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[-1, -1, 1, 1], [-1, 1, 1, -1], [0, 0, 0, 0]]))
        f_3 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }
        mesh_args = {
            "mesh_size_frac": 0.4,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        gb = network.mesh(mesh_args)
        isect_0_coord = np.array([[0, 0], [0, 0], [-1, 1]])
        isect_1_coord = np.array([[-1, 1], [0, 0], [0, 0]])
        isect_2_coord = np.array([[0, 0], [-1, 1], [0, 0]])

        isect_0 = IntersectionInfo(0, 2, isect_0_coord)
        isect_1 = IntersectionInfo(0, 1, isect_1_coord)
        isect_2 = IntersectionInfo(1, 2, isect_2_coord)

        isect_pt = np.array([0, 0, 0]).reshape((-1, 1))

        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2, f_3],
            isect_line=[isect_0, isect_1, isect_2],
            isect_pt=[isect_pt],
            expected_num_1d_grids=6,
            expected_num_0d_grids=1,
        )
    def test_two_fractures(self):
        # Test of method FractureNetwork.bounding_box() to inquire about
        # network extent
        f1 = pp.Fracture(np.array([[0, 2, 2, 0], [0, 0, 1, 1], [0, 0, 1, 1]]),
                         check_convexity=False)

        f2 = pp.Fracture(
            np.array([[0, 1, 1, 0], [0, 0, 1, 1], [-1, -1, 1, 1]]),
            check_convexity=False,
        )

        network = pp.FractureNetwork3d([f1, f2])
        d = network.bounding_box()

        self.assertTrue(d["xmin"] == 0)
        self.assertTrue(d["xmax"] == 2)
        self.assertTrue(d["ymin"] == 0)
        self.assertTrue(d["ymax"] == 1)
        self.assertTrue(d["zmin"] == -1)
        self.assertTrue(d["zmax"] == 1)
    def test_one_to_boundar_3d(self):
        """
            One fracture in 3d going all the way to the boundary
            """

        f_1 = np.array([[1, 5, 5, 1], [1, 1, 1, 1], [1, 1, 3, 3]])
        f_set = [pp.Fracture(f_1)]
        domain = {
            "xmin": 0,
            "ymin": 0,
            "zmin": 0,
            "xmax": 5,
            "ymax": 5,
            "zmax": 5
        }
        mesh_size_min = 0.1
        mesh_size_frac = 0.1
        mesh_size_bound = 2
        on_boundary = np.array([
            False, False, False, False, True, True, True, True, True, True,
            True, True
        ])
        network = pp.FractureNetwork3d(f_set)
        network.impose_external_boundary(domain)
        network.find_intersections()
        network.split_intersections()
        network._insert_auxiliary_points(
            mesh_size_frac=mesh_size_frac,
            mesh_size_min=mesh_size_min,
            mesh_size_bound=mesh_size_bound,
        )
        mesh_size = network._determine_mesh_size(
            boundary_point_tags=on_boundary)
        # 0.1 corresponds to fracture corners, 2.0 to domain corners far
        # away from the fracture and the other values to domain corners
        # affected by the
        mesh_size_known = np.array([
            0.1, 0.1, 0.1, 0.1, 2.0, 1.73205081, 2.0, 2.0, 2.0, 1.41421356,
            2.0, 2.0
        ])
        self.assertTrue(np.all(np.isclose(mesh_size, mesh_size_known)))
Exemple #27
0
    def create_grid(self):
        """ Create a 3D grid with one fracture on
        a cube.

        The method assigns the following attributes to self:
            box (dict): Bounding box of the domain, defined by minimum and
                maximum values in each dimension.
            gb (pp.GridBucket): The produced grid bucket.
            Nd (int): Dimensions of the matrix.

        According to requirements by pp.models.ContactMechanics, the following method
        is called after gb is set:
         pp.contact_conditions.set_projections(self.gb)
        """
        domain = {
            'xmin': -2,
            'xmax': 3,
            'ymin': -2,
            'ymax': 3,
            'zmin': -3,
            'zmax': 3
        }
        self.box = domain

        # Fractures denoted by vertices
        f_1 = pp.Fracture(np.array([[0, 1, 2, 0], [0, 0, 1, 1], [0, 0, 1, 1]]))

        network = pp.FractureNetwork3d([f_1], domain=domain)
        mesh_args = {
            'mesh_size_frac': 0.2,
            'mesh_size_min': 0.2,
            'mesh_size_bound': 1
        }
        gb = network.mesh(mesh_args, ensure_matching_face_cell=False)
        self.gb = gb
        self.Nd = self.gb.dim_max
        pp.contact_conditions.set_projections(self.gb)
        print("Number of cells 3D grid ",
              self.gb.grids_of_dimension(3)[0].num_cells)
        breakpoint()
    def test_three_fractures_sharing_line_same_segment(self, **kwargs):
        """
        Three fractures that all share an intersection line. This can be considered
        as three intersection lines that coincide.
        """
        f_1 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [0, 0, 0, 0], [-1, -1, 1, 1]]))
        f_2 = pp.Fracture(
            np.array([[-1, 1, 1, -1], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        f_3 = pp.Fracture(
            np.array([[0, 0, 0, 0], [-1, 1, 1, -1], [-1, -1, 1, 1]]))
        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }
        mesh_args = {
            "mesh_size_frac": 0.4,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        gb = network.mesh(mesh_args)

        isect_coord = np.array([[0, 0], [0, 0], [-1, 1]])
        isect = IntersectionInfo3Frac(0, 1, 2, isect_coord)

        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2, f_3],
            isect_line=[isect],
            expected_num_1d_grids=1,
            expected_num_0d_grids=0,
        )
    def test_T_intersection_is_partially_within_constraint(self, **kwargs):
        # a fracture
        f_1 = pp.Fracture(np.array([[0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]]))
        # a fracture that abuts the first fracture
        f_2 = pp.Fracture(
            np.array([[0.5, 0.5, 0.5, 0.5], [0.3, 1, 1, 0], [0, 0, 1, 1]]))
        # a fracture, to be constraint, that intersects in the same line
        f_3 = pp.Fracture(
            np.array([[0, 1, 1, 0], [0, 0, 1, 1], [-1, 1, 1, -1]]))

        domain = {
            "xmin": -2,
            "xmax": 2,
            "ymin": -2,
            "ymax": 2,
            "zmin": -2,
            "zmax": 2
        }
        mesh_args = {
            "mesh_size_frac": 0.4,
            "mesh_size_bound": 1,
            "mesh_size_min": 0.2
        }

        network = pp.FractureNetwork3d([f_1, f_2, f_3], domain=domain)
        gb = network.mesh(mesh_args, constraints=[2])

        isect_coord = np.array([[0.5, 0.5], [0.3, 1], [0, 0]])
        isect = IntersectionInfo(0, 1, isect_coord)

        self.check_gb(
            gb,
            domain,
            fractures=[f_1, f_2],
            isect_line=[isect],
            expected_num_1d_grids=1,
            expected_num_0d_grids=0,
        )
Exemple #30
0
def import_grid(file_geo, tol):

    frac = pp.Fracture(
        np.array([[0, 10, 10, 0], [0, 0, 10, 10], [8, 2, 2, 8]]) * 10)
    network = pp.FractureNetwork3d([frac], tol=tol)

    domain = {
        "xmin": 0,
        "xmax": 100,
        "ymin": 0,
        "ymax": 100,
        "zmin": 0,
        "zmax": 100
    }
    network.impose_external_boundary(domain)
    network.find_intersections()
    network.split_intersections()
    network.to_gmsh("dummy.geo")

    gb = pp.fracture_importer.dfm_from_gmsh(file_geo, 3, network)
    gb.compute_geometry()

    return gb, domain