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
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()
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()
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'}
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)