def create_samples(id_range, base_dir): geo = gmsh.GeometryOCC("three_frac_symmetric", verbose=False) # Uniform fractures on sphere #fracture_population = fg.FisherOrientation(0, 0, 0) fracture_population = fg.FisherOrientation(0, 0, np.inf) summary_file = "summary_{}_{}.txt".format(*id_range) full_summary = os.path.join(base_dir, summary_file) for id in range(id_range[0], id_range[1]): dir = "{:06d}".format(id) try: x = Realization(geo, base_dir, dir, fracture_population, summary_file) #print(attr.asdict(x.sample)) x.run() except Exception: pass #geo.show() return full_summary
def generate_mesh(): r""" Create mesh and write it to a file. Parameters ---------- fractures_data : list of FractureData Array of objects defining fractures. max_el_size : double Maximal size of mesh element. file_name : str File name to write mesh into. verbose : {0, 1} If set to 1, messages during mesh generation will be printed. """ # geometry prameters box_size = 600 well_radius = 3 well_length = 300 well_shift = 100 factory = gmsh.GeometryOCC("three_frac_symmetric", verbose=True) gopt = options.Geometry() gopt.Tolerance = 1e-5 gopt.ToleranceBoolean = 1e-3 # gopt.MatchMeshTolerance = 1e-1 # Main box box = factory.box(3 * [box_size]).set_region("box") side = factory.rectangle(2 * [box_size]) side_z0 = side.copy().translate([0, 0, -box_size / 2]) side_z1 = side.copy().translate([0, 0, +box_size / 2]) sides = dict(side_z0=side.copy().translate([0, 0, -box_size / 2]), side_z1=side.copy().translate([0, 0, +box_size / 2]), side_y0=side_z0.copy().rotate([-1, 0, 0], np.pi / 2), side_y1=side_z1.copy().rotate([-1, 0, 0], np.pi / 2), side_x0=side_z0.copy().rotate([0, 1, 0], np.pi / 2), side_x1=side_z1.copy().rotate([0, 1, 0], np.pi / 2)) for name, side in sides.items(): side.modify_regions(name) b_box = box.get_boundary().copy() # two vertical cut-off wells, just permeable part well_z_shift = -well_length / 2 left_center = [-well_shift, 0, 0] right_center = [+well_shift, 0, 0] left_well = factory.cylinder(well_radius, axis=[0, 0, well_length])\ .translate([0,0,well_z_shift]).translate(left_center) right_well = factory.cylinder(well_radius, axis=[0, 0, well_length])\ .translate([0, 0, well_z_shift]).translate(right_center) left_center = [-0.6 * well_shift, 0, 0] right_center = [+0.6 * well_shift, 0, 0] b_right_well = right_well.get_boundary() b_left_well = left_well.get_boundary() # fracutres fractures = [ FractureShape(r, centre, axis, angle, region) for r, centre, axis, angle, region in [( 1.5 * well_shift, left_center, [0, 1, 0], np.pi / 6, 'left_fr' ), (1.5 * well_shift, right_center, [0, 1, 0], np.pi / 6, 'right_fr' ), (well_shift, [0, 0, 0], [0, 1, 0], -np.pi / 3, 'center_fr')] ] fractures = factory.make_fractures(fractures, factory.rectangle()) fractures_group = factory.group(*fractures) # drilled box and its boundary box_drilled = box.cut(left_well, right_well) # fractures, fragmented, fractures boundary fractures_group = fractures_group.intersect(box_drilled.copy()) box_fr, fractures_fr = factory.fragment(box_drilled, fractures_group) b_box_fr = box_fr.get_boundary() b_left_r = b_box_fr.select_by_intersect(b_left_well).set_region( ".left_well") b_right_r = b_box_fr.select_by_intersect(b_right_well).set_region( ".right_well") box_all = [] for name, side_tool in sides.items(): isec = b_box_fr.select_by_intersect(side_tool) box_all.append(isec.modify_regions("." + name)) box_all.extend([box_fr, b_left_r, b_right_r]) b_fractures = factory.group(*fractures_fr.get_boundary_per_region()) b_fractures_box = b_fractures.select_by_intersect(b_box).modify_regions( "{}_box") b_fr_left_well = b_fractures.select_by_intersect( b_left_well).modify_regions("{}_left_well") b_fr_right_well = b_fractures.select_by_intersect( b_right_well).modify_regions("{}_right_well") b_fractures = factory.group(b_fr_left_well, b_fr_right_well, b_fractures_box) mesh_groups = [*box_all, fractures_fr, b_fractures] factory.keep_only(*mesh_groups) factory.remove_duplicate_entities() factory.write_brep() min_el_size = well_radius / 20 fracture_el_size = box_size / 20 max_el_size = box_size / 10 fractures_fr.set_mesh_step(200) #fracture_el_size = field.constant(100, 10000) #frac_el_size_only = field.restrict(fracture_el_size, fractures_fr, add_boundary=True) #field.set_mesh_step_field(frac_el_size_only) mesh = options.Mesh() mesh.ToleranceInitialDelaunay = 0.0001 mesh.CharacteristicLengthFromPoints = True mesh.CharacteristicLengthFromCurvature = True mesh.CharacteristicLengthExtendFromBoundary = 1 mesh.CharacteristicLengthMin = min_el_size mesh.CharacteristicLengthMax = max_el_size mesh.MinimumCurvePoints = 12 factory.make_mesh(mesh_groups) factory.write_mesh(format=gmsh.MeshFormat.msh2) factory.show()
def make_mesh(config_dict, fractures, mesh_name, mesh_file): geom = config_dict["geometry"] fracture_mesh_step = geom['fracture_mesh_step'] dimensions = geom["box_dimensions"] well_z0, well_z1 = geom["well_openning"] well_length = well_z1 - well_z0 well_r = geom["well_effective_radius"] well_dist = geom["well_distance"] print("load gmsh api") from gmsh_api import gmsh from gmsh_api import options from gmsh_api import field factory = gmsh.GeometryOCC(mesh_name, verbose=True) gopt = options.Geometry() gopt.Tolerance = 0.0001 gopt.ToleranceBoolean = 0.001 # gopt.MatchMeshTolerance = 1e-1 # Main box box = factory.box(dimensions).set_region("box") side_z = factory.rectangle([dimensions[0], dimensions[1]]) side_y = factory.rectangle([dimensions[0], dimensions[2]]) side_x = factory.rectangle([dimensions[2], dimensions[1]]) sides = dict(side_z0=side_z.copy().translate([0, 0, -dimensions[2] / 2]), side_z1=side_z.copy().translate([0, 0, +dimensions[2] / 2]), side_y0=side_y.copy().translate([0, 0, -dimensions[1] / 2 ]).rotate([-1, 0, 0], np.pi / 2), side_y1=side_y.copy().translate([0, 0, +dimensions[1] / 2 ]).rotate([-1, 0, 0], np.pi / 2), side_x0=side_x.copy().translate([0, 0, -dimensions[0] / 2 ]).rotate([0, 1, 0], np.pi / 2), side_x1=side_x.copy().translate([0, 0, +dimensions[0] / 2 ]).rotate([0, 1, 0], np.pi / 2)) for name, side in sides.items(): side.modify_regions(name) b_box = box.get_boundary().copy() # two vertical cut-off wells, just permeable part left_center = [-well_dist / 2, 0, 0] right_center = [+well_dist / 2, 0, 0] left_well = factory.cylinder(well_r, axis=[0, 0, well_z1 - well_z0]) \ .translate([0, 0, well_z0]).translate(left_center) right_well = factory.cylinder(well_r, axis=[0, 0, well_z1 - well_z0]) \ .translate([0, 0, well_z0]).translate(right_center) b_right_well = right_well.get_boundary() b_left_well = left_well.get_boundary() print("n fractures:", len(fractures)) fractures = create_fractures_rectangles(factory, fractures, factory.rectangle()) #fractures = create_fractures_polygons(factory, fractures) fractures_group = factory.group(*fractures) #fractures_group = fractures_group.remove_small_mass(fracture_mesh_step * fracture_mesh_step / 10) # drilled box and its boundary box_drilled = box.cut(left_well, right_well) # fractures, fragmented, fractures boundary print("cut fractures by box without wells") fractures_group = fractures_group.intersect(box_drilled.copy()) print("fragment fractures") box_fr, fractures_fr = factory.fragment(box_drilled, fractures_group) print("finish geometry") b_box_fr = box_fr.get_boundary() b_left_r = b_box_fr.select_by_intersect(b_left_well).set_region( ".left_well") b_right_r = b_box_fr.select_by_intersect(b_right_well).set_region( ".right_well") box_all = [] for name, side_tool in sides.items(): isec = b_box_fr.select_by_intersect(side_tool) box_all.append(isec.modify_regions("." + name)) box_all.extend([box_fr, b_left_r, b_right_r]) b_fractures = factory.group(*fractures_fr.get_boundary_per_region()) b_fractures_box = b_fractures.select_by_intersect(b_box).modify_regions( "{}_box") b_fr_left_well = b_fractures.select_by_intersect( b_left_well).modify_regions("{}_left_well") b_fr_right_well = b_fractures.select_by_intersect( b_right_well).modify_regions("{}_right_well") b_fractures = factory.group(b_fr_left_well, b_fr_right_well, b_fractures_box) mesh_groups = [*box_all, fractures_fr, b_fractures] print(fracture_mesh_step) #fractures_fr.set_mesh_step(fracture_mesh_step) factory.keep_only(*mesh_groups) factory.remove_duplicate_entities() factory.write_brep() min_el_size = fracture_mesh_step / 10 fracture_el_size = np.max(dimensions) / 20 max_el_size = np.max(dimensions) / 8 fracture_el_size = field.constant(fracture_mesh_step, 10000) frac_el_size_only = field.restrict(fracture_el_size, fractures_fr, add_boundary=True) field.set_mesh_step_field(frac_el_size_only) mesh = options.Mesh() #mesh.Algorithm = options.Algorithm2d.MeshAdapt # produce some degenerated 2d elements on fracture boundaries ?? #mesh.Algorithm = options.Algorithm2d.Delaunay #mesh.Algorithm = options.Algorithm2d.FrontalDelaunay #mesh.Algorithm3D = options.Algorithm3d.Frontal #mesh.Algorithm3D = options.Algorithm3d.Delaunay mesh.ToleranceInitialDelaunay = 0.01 #mesh.ToleranceEdgeLength = fracture_mesh_step / 5 mesh.CharacteristicLengthFromPoints = True mesh.CharacteristicLengthFromCurvature = True mesh.CharacteristicLengthExtendFromBoundary = 2 mesh.CharacteristicLengthMin = min_el_size mesh.CharacteristicLengthMax = max_el_size mesh.MinimumCirclePoints = 6 mesh.MinimumCurvePoints = 2 #factory.make_mesh(mesh_groups, dim=2) factory.make_mesh(mesh_groups) factory.write_mesh(format=gmsh.MeshFormat.msh2) os.rename(mesh_name + ".msh2", mesh_file)