def write_mesh(geo_filename, preview=False):
    # Initialize the gmsh api.
    gmsh.initialize()

    # Save the mesh with v2 to use it with dolfin-converter application.
    gmsh.option.setNumber("Mesh.MshFileVersion", 2.)

    # Re-open the file.
    gmsh.open(geo_filename)

    # Generate the 2D mesh.
    gmsh.model.mesh.generate(2)  # 2 indicating 2 dimensions.
    msh_filename = geo_filename.split('.geo')[0] + '.msh'
    gmsh.write(msh_filename)

    # Finalize the gmsh processes.
    gmsh.finalize()

    if preview:
        open_gmsh(msh_filename)

    return msh_filename
Beispiel #2
0
def generate__semiCircleMesh( lc1=0.01, lc2=0.05, lc3=0.1, radius=1.0, origin=[0.0,0.0], \
                              th1=-90.0,th2=+90.0, zoffset=0.0, side="+" ):

    # ------------------------------------------------- #
    # --- [1] initialization of the gmsh            --- #
    # ------------------------------------------------- #
    gmsh.initialize()
    gmsh.option.setNumber( "General.Terminal", 1 )
    gmsh.model.add( "model" )

    # ------------------------------------------------- #
    # --- [2] initialize settings                   --- #
    # ------------------------------------------------- #
    ptsDim , lineDim , surfDim , voluDim  =  0,  1,  2,  3
    pts    , line    , surf    , volu     = {}, {}, {}, {}
    ptsPhys, linePhys, surfPhys, voluPhys = {}, {}, {}, {}
    x_, y_, z_, lc_, tag_                 = 0, 1, 2, 3, 4

    # ------------------------------------------------- #
    # --- [3] Modeling                              --- #
    # ------------------------------------------------- #

    initNum       = 1
    x_, y_        = 0, 1
    pth1, pth2    = th1/180.0*np.pi, th2/180.0*np.pi
    xp1           = [ origin[x_]+radius*np.cos(pth1), origin[y_]+radius*np.sin(pth1) ]
    xp2           = [ origin[x_]+radius*np.cos(pth2), origin[y_]+radius*np.sin(pth2) ]
    pts["OP"]     = [ origin[x_], origin[y_], zoffset, lc2, initNum ]
    pts["P1"]     = [    xp1[x_],    xp1[y_], zoffset, lc1, initNum ]
    pts["P2"]     = [    xp2[x_],    xp2[y_], zoffset, lc3, initNum ]

    ang       = 0.5*(pth2-pth1) + pth1
    if   (  ( th2-th1 == 180.0 ) & ( side=="+" ) ):
        xp3   = [ origin[x_] + radius*np.cos( ang ), origin[y_] + radius*np.sin( ang ) ]
    elif (  ( th2-th1 == 180.0 ) & ( side=="-" ) ):
        xp3   = [ origin[x_] - radius*np.cos( ang ), origin[y_] - radius*np.sin( ang ) ]
    else:
        xp3   = [ origin[x_] + radius*np.cos( ang ), origin[y_] + radius*np.sin( ang ) ]
    pts["P3"] = [ xp3[x_], xp3[y_], zoffset, lc2, initNum ]

    for key in list( pts.keys() ):
        pt              = pts[key]
        ( pts[key] )[4] = gmsh.model.occ.addPoint( pt[0], pt[1], pt[2], meshSize=pt[3] )

    line["arc1"] = gmsh.model.occ.addCircleArc( pts["P1"][4], pts["OP"][4], pts["P3"][4] )
    line["arc2"] = gmsh.model.occ.addCircleArc( pts["P3"][4], pts["OP"][4], pts["P2"][4] )

    line["diameter1"] = gmsh.model.occ.addLine( pts["OP"][4], pts["P1"][4] )
    line["diameter2"] = gmsh.model.occ.addLine( pts["P2"][4], pts["OP"][4] )

    LineLoop   = [ + line["diameter1"], + line["arc1"],   \
                   + line["arc2"]     , + line["diameter2"] ]
    LineLoopGroup  = gmsh.model.occ.addCurveLoop( LineLoop )
    surf["sector"] = gmsh.model.occ.addPlaneSurface( [ LineLoopGroup ] )

    # ------------------------------------------------- #
    # --- [4] Physical Grouping                     --- #
    # ------------------------------------------------- #
    gmsh.model.occ.synchronize()
    surfPhys["semicircle"] = gmsh.model.addPhysicalGroup( surfDim, [ surf["sector"] ], tag=201 )

    # ------------------------------------------------- #
    # --- [5] post process                          --- #
    # ------------------------------------------------- #
    gmsh.model.occ.synchronize()
    gmsh.model.mesh.generate(2)
    gmsh.write( "model.geo_unrolled" )
    gmsh.write( "model.msh" )
    gmsh.finalize()
Beispiel #3
0
        volu["cylinder"] = ret[1][1]

    # ------------------------------------------------- #
    # --- [4] PostProcess                           --- #
    # ------------------------------------------------- #
    ret = {"pts": pts, "line": line, "surf": surf, "volu": volu}
    return (ret)


# ======================================== #
# ===  実行部                          === #
# ======================================== #
if (__name__ == "__main__"):

    gmsh.initialize()
    gmsh.option.setNumber("General.Terminal", 1)
    gmsh.model.add("example")

    lc = 0.10
    xc = [0.0, 0.0, 0.0]
    radius = 1.0
    delta = [0.0, 0.0, 1.0]
    generate__cylinder( lc=lc, xc=xc, radius=radius, \
                        defineVolu=True, extrude_delta=delta )

    gmsh.model.occ.synchronize()
    gmsh.model.mesh.generate(3)
    gmsh.write("example.geo_unrolled")
    gmsh.write("example.msh")
    gmsh.finalize()
Beispiel #4
0
    def execute(self, context):
        scene = context.scene

        try:
            import gmsh_api.gmsh as gmsh

            if scene.blendmsh.initialized:
                filename = bpy.context.active_object.name
                active_object = bpy.context.active_object

                physical_group_faces = OrderedDict()
                bpy.ops.object.mode_set(mode='OBJECT')
                for _face in bpy.context.active_object.data.polygons:
                    if 'GROUP' in active_object.data.materials[
                            _face.material_index].name_full:
                        group_id = str(active_object.data.materials[
                            _face.material_index].name_full)

                        # GMSH INDEX STARTS FROM 1, HENCE '_face.index + 1'
                        if group_id not in physical_group_faces.keys():
                            physical_group_faces[group_id] = set(
                                [_face.index + 1])
                        else:
                            physical_group_faces[group_id].add(_face.index + 1)

                data = self.get_raw_data(
                    os.path.join(scene.blendmsh.workspace_path,
                                 filename + '.stl'))

                points = OrderedDict()
                edges = OrderedDict()
                triangles = OrderedDict()
                curve_loop = OrderedDict()

                geo_points = OrderedDict()
                geo_edges = OrderedDict()

                i = 1
                for _surface in data:
                    for _vertex in _surface:
                        if _vertex not in points.keys():
                            points[_vertex] = i
                            geo_points[i] = _vertex
                            i += 1

                for i, _data in enumerate(data):
                    triangles[i + 1] = [
                        points[_data[0]], points[_data[1]], points[_data[2]]
                    ]

                i = 1
                for _triangle in triangles.values():
                    for _edge in self.get_edge_indices(_triangle):
                        if _edge not in edges.keys(
                        ) and _edge[::-1] not in edges.keys():
                            edges[_edge] = i
                            geo_edges[i] = _edge
                            i += 1

                for _triangle_id in triangles.keys():
                    curve_loop[_triangle_id] = []
                    for connection in self.get_curve_loop(
                            triangles[_triangle_id]):
                        if connection in edges.keys():
                            curve_loop[_triangle_id].append(edges[connection])
                        elif connection[::-1] in edges.keys():
                            curve_loop[_triangle_id].append(
                                -1 * edges[connection[::-1]])

                all_physical_group_faces = set()
                for _face_lists in physical_group_faces.values():
                    for _face_id in _face_lists:
                        all_physical_group_faces.add(_face_id)

                gmsh.initialize()
                gmsh.option.setNumber('General.Terminal', 1)

                lc = scene.blendmsh.cl_max
                geo = gmsh.model.geo

                for _point in points.keys():
                    geo.addPoint(_point[0], _point[1], _point[2], lc,
                                 points[_point])

                for _edge in edges.keys():
                    geo.addLine(_edge[0], _edge[1], edges[_edge])

                for _curve_id in curve_loop.keys():
                    geo.addCurveLoop([
                        curve_loop[_curve_id][0], curve_loop[_curve_id][1],
                        curve_loop[_curve_id][2]
                    ], _curve_id)
                    surf_temp = geo.addPlaneSurface([_curve_id], _curve_id)

                    if _curve_id in all_physical_group_faces:
                        gmsh.model.addPhysicalGroup(2, [surf_temp], _curve_id)

                sl = geo.addSurfaceLoop(list(curve_loop.keys()))
                _ = geo.addVolume([sl])

                gmsh.model.geo.synchronize()

                gmsh.option.setNumber("Mesh.Algorithm",
                                      int(scene.blendmsh.algorithm))
                gmsh.option.setNumber("Mesh.ElementOrder",
                                      int(scene.blendmsh.element_order))
                gmsh.option.setNumber("Mesh.Optimize", 1)
                gmsh.option.setNumber("Mesh.QualityType", 2)
                gmsh.option.setNumber("Mesh.SaveAll", 1)
                gmsh.model.mesh.generate(int(scene.blendmsh.mesh_dimension))

                gmsh.write(
                    os.path.join(scene.blendmsh.workspace_path,
                                 filename + scene.blendmsh.output_file_format))
                gmsh.finalize()

                self.report({'INFO'}, '{} file written to {}'.format(
                    filename + scene.blendmsh.output_file_format,
                    scene.blendmsh.workspace_path))
                return {'FINISHED'}

            else:
                self.report({
                    'ERROR'
                }, 'Kindly initialize geometry before defining physical groups.'
                            )
                return {'CANCELLED'}

        except ModuleNotFoundError:
            self.report(
                {'ERROR'},
                'Couldnot import Gmsh module, Kindly re-install it manually.')
            return {'CANCELLED'}
Beispiel #5
0
def generate_mesh(fractures_data,
                  max_el_size,
                  file_name,
                  verbose=0,
                  shape="circle"):
    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.
    """
    model = gmsh.model
    factory = model.occ
    gmsh.initialize()
    gmsh.option.setNumber("General.Terminal", verbose)
    model.add("test_api")

    # set options
    gmsh.option.setNumber("Geometry.Tolerance", 0)
    gmsh.option.setNumber("Geometry.ToleranceBoolean", 0)
    gmsh.option.setNumber("Geometry.MatchMeshTolerance", 0)
    gmsh.option.setNumber("Mesh.ToleranceInitialDelaunay", 1e-12)
    gmsh.option.setNumber("Mesh.CharacteristicLengthFromPoints", 1)
    gmsh.option.setNumber("Mesh.CharacteristicLengthFromCurvature", 0)
    gmsh.option.setNumber("Mesh.CharacteristicLengthExtendFromBoundary", 0)
    # gmsh.option.setNumber("Mesh.CharacteristicLengthMin", max_el_size*0.01)
    # gmsh.option.setNumber("Mesh.CharacteristicLengthMax", max_el_size)
    # gmsh.option.setNumber("Mesh.MinimumCurvePoints", 5)

    # Generate fractures
    if shape == "circle":
        fractures = generate_disks(factory, fractures_data)
    # elif shape == "rectangle":
    #     fractures = generate_rectangles(factory, fractures_data)
    # elif shape == "ellipse":
    #     fractures = generate_ellipses(factory, fractures_data)

    # set physical id and name of fractures
    fractures_phys_id = model.addPhysicalGroup(2, [x[1] for x in fractures],
                                               -1)
    model.setPhysicalName(2, fractures_phys_id, "fractures")

    # define 3d volume and embed fractures into it
    box = factory.addBox(0, 0, 0, 1, 1, 1)

    factory.synchronize()
    # Embed the model entities of dimension 'dim', and tags 'tag' in the other model entity which is given by
    # dimension (3) and tag (box)
    model.mesh.embed(2, [tag for dim, tag in fractures], 3, box)

    # define physical id of volume and its boundaries
    box_phys_id = model.addPhysicalGroup(3, [box], -1)
    model.setPhysicalName(3, box_phys_id, "box")
    # box_bdry = model.getBoundary([(3,box)], True)
    # box_bdry_left_phys_id = model.addPhysicalGroup(2, [box_bdry[0][1]], -1)
    # box_bdry_right_phys_id = model.addPhysicalGroup(2, [box_bdry[1][1]], -1)
    # model.setPhysicalName(2, box_bdry_left_phys_id, ".left")
    # model.setPhysicalName(2, box_bdry_right_phys_id, ".right")

    # Define fields for mesh refinement
    # Compute the distance from curves, each curve is replaced by NNodesByEdge equidistant nodes
    # and the distance from those nodes is computed.
    model.mesh.field.add("Distance", 1)
    model.mesh.field.setNumber(1, "NNodesByEdge", 100)
    frac_bdry = model.getBoundary(fractures, False, False, False)
    # Set the numerical list option "EdgesList" to list of "frac_bdry" tags for field tag 1.
    model.mesh.field.setNumbers(1, "EdgesList",
                                [tag for dm, tag in frac_bdry if dm == 1])

    # Threshold
    # F = LCMin if Field[IField] <= DistMin,
    # F = LCMax if Field[IField] >= DistMax,
    # F = interpolation between LcMin and LcMax if DistMin < Field[IField] < DistMax
    model.mesh.field.add("Threshold", 2)
    # Index of the field to evaluate (in this case 1 is "Distance")
    model.mesh.field.setNumber(2, "IField", 1)
    # Element size inside DistMin
    model.mesh.field.setNumber(2, "LcMin", max_el_size * 0.03)
    # Element size outside DistMax
    model.mesh.field.setNumber(2, "LcMax", max_el_size)
    # Distance from entity up to which element size will be LcMin, it should depend on particular model
    model.mesh.field.setNumber(2, "DistMin", 0.001)
    # Distance from entity after which element size will be LcMax, it should depend on particular model
    model.mesh.field.setNumber(2, "DistMax", 0.5)

    # Set threshold as the background mesh size field.
    model.mesh.field.setAsBackgroundMesh(2)

    # generate mesh, write to file and output number of entities that produced error
    factory.synchronize()
    gmsh.write(file_name + '.brep')
    model.mesh.generate(3)
    bad_entities = model.mesh.getLastEntityError()
    gmsh.write(file_name)
    gmsh.finalize()

    return len(bad_entities)