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
Esempio n. 2
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
Esempio n. 3
0
    def fractures(self):
        """
        Define the two fractures.
        The first fracture is the one where injection takes place.
        """
        n_points = 4
        # Size
        s = 12
        # Major axis rotation
        major = np.pi / 4
        # Dip
        dip_1, dip_2 = np.pi / 4, np.pi / 4
        # Strike:
        # The values below imply dip about the y and x axis, respectively
        strike, strike_2 = np.pi / 2, 0
        f_1 = pp.EllipticFracture(
            np.array([-10, 0, 0]), s, s, major, strike, dip_1, num_points=n_points
        )

        f_2 = pp.EllipticFracture(
            np.array([10, 0, 0]), s, s, major, strike_2, dip_2, num_points=n_points
        )
        self.fracs = [f_1, f_2]
Esempio n. 4
0
def create_grid():
    file_name = 'fractures.csv'
    data = np.genfromtxt(file_name, delimiter=',')
    data = np.atleast_2d(data)
    centers = data[:, 0:3]
    maj_ax = data[:, 3]
    min_ax = data[:, 4]
    maj_ax_ang = data[:, 5]
    strike_ang = data[:, 6]
    dip_ang = data[:, 7]
    if data.shape[1] == 9:
        num_points = data[:, 8]
    else:
        num_points = 16 * np.ones(data.shape[0])

    frac_list = []

    for i in range(maj_ax.shape[0]):
        frac_list.append(
            pp.EllipticFracture(centers[i, :], maj_ax[i], min_ax[i],
                                maj_ax_ang[i], strike_ang[i], dip_ang[i],
                                num_points[i]))
    frac_network = pp.FractureNetwork(frac_list)
    box = {
        'xmin': -5000,
        'ymin': -5000,
        'zmin': -5000,
        'xmax': 10000,
        'ymax': 10000,
        'zmax': 10000
    }
    gb = pp.meshing.simplex_grid(frac_network,
                                 box,
                                 mesh_size_bound=10000,
                                 mesh_size_frac=500,
                                 mesh_size_min=200)
    return gb
Esempio n. 5
0
def elliptic_network_3d_from_csv(file_name,
                                 has_domain=True,
                                 tol=1e-4,
                                 degrees=False):
    """
    Create the fracture network from a set of 3d fractures stored in a csv file and
    domain. In the csv file, we assume the following structure
    - first line (optional) describes the domain as a rectangle with
      X_MIN, Y_MIN, Z_MIN, X_MAX, Y_MAX, Z_MAX
    - the other lines descibe the N fractures as a elliptic fractures:
      center_x, center_y, center_z, major_axis, minor_axis, major_axis_angle,
                 strike_angle, dip_angle, num_points.
     See EllipticFracture for information about the parameters

    Lines that start with a # are ignored.

    Parameters:
        file_name: name of the file
        has_domain: if the first line in the csv file specify the domain
        tol: (optional) tolerance for the methods

    Return:
        FractureNetwork3d: the fracture network

    """

    # The first line of the csv file defines the bounding box for the domain

    frac_list = []
    # Extract the data from the csv file
    with open(file_name, "r") as csv_file:
        spam_reader = csv.reader(csv_file, delimiter=",")

        # Read the domain first
        if has_domain:
            domain = np.asarray(next(spam_reader), dtype=np.float)
            domain = {
                "xmin": domain[0],
                "xmax": domain[3],
                "ymin": domain[1],
                "ymax": domain[4],
                "zmin": domain[2],
                "zmax": domain[5],
            }

        for row in spam_reader:
            # If the line starts with a '#', we consider this a comment
            if row[0][0] == "#":
                continue

            # Read the data
            data = np.asarray(row, dtype=np.float)
            if not data.size % 9 == 0:
                raise ValueError("Data has to have size 9")

            # Skip empty lines. Useful if the file ends with a blank line.
            if data.size == 0:
                continue
            centers = data[0:3]
            maj_ax = data[3]
            min_ax = data[4]
            maj_ax_ang = data[5] * (1 - degrees + degrees * np.pi / 180)
            strike_ang = data[6] * (1 - degrees + degrees * np.pi / 180)
            dip_ang = data[7] * (1 - degrees + degrees * np.pi / 180)
            num_points = int(data[8])

            frac_list.append(
                pp.EllipticFracture(centers, maj_ax, min_ax, maj_ax_ang,
                                    strike_ang, dip_ang, num_points))
    # Create the network
    if has_domain:
        return pp.FractureNetwork3d(frac_list, tol=tol, domain=domain)
    else:
        return pp.FractureNetwork3d(frac_list, tol=tol)
Esempio n. 6
0
    def create_grid(self):
        """
        Method that creates the GridBucket of a 3D domain with three fractures. 
        The first fracture is the one where injection takes place and
        production takes place in the third fracture. Fractures 1 and 2 intersect.
        """
        # 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,
        )
        self.fractures = [f_1, f_2, f_3]

        # Define the domain
        size = 50
        self.box = {
            "xmin": -size,
            "xmax": size,
            "ymin": -size,
            "ymax": size,
            "zmin": -size,
            "zmax": size,
        }
        # Make a fracture network
        self.network = pp.FractureNetwork3d(self.fractures, domain=self.box)
        # Generate the mixed-dimensional mesh
        # write_fractures_to_csv(self)
        gb = self.network.mesh(self.mesh_args)

        pp.contact_conditions.set_projections(gb)

        self.gb = gb
        self.Nd = self.gb.dim_max()

        # Tag the wells
        self._tag_well_cells()
        self.n_frac = len(gb.grids_of_dimension(self.Nd - 1))
        self.update_all_apertures(to_iterate=False)
        self.update_all_apertures()