예제 #1
0
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
예제 #2
0
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()
예제 #3
0
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)