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