for i in range(3): gmsh.model.geo.addLine(i + 1, 4, i + 4) gmsh.model.geo.addCurveLoop([1, 2, 3], 1) gmsh.model.geo.addPlaneSurface([1], 1) gmsh.model.geo.addCurveLoop([1, 5, -4], 2) gmsh.model.geo.addPlaneSurface([2], 2) gmsh.model.geo.addCurveLoop([2, 6, -5], 3) gmsh.model.geo.addPlaneSurface([3], 3) gmsh.model.geo.addCurveLoop([3, 4, -6], 4) gmsh.model.geo.addPlaneSurface([4], 4) l = gmsh.model.geo.addSurfaceLoop([i + 1 for i in range(4)]) gmsh.model.geo.addVolume([l]) gmsh.model.geo.synchronize() gmsh.model.mesh.generate(3) gmsh.write("t2.msh") gmsh.write("t2.geo_unrolled") if '-nopopup' not in sys.argv: gmsh.fltk.run() gmsh.finalize()
factory.addCurveLoop([114, -110, 5, 113], 124) factory.addPlaneSurface([124], 125) factory.addCurveLoop([115, 116, 117, 114], 126) factory.addPlaneSurface([126], 127) # The API to create surface loops ("shells") and volumes is similar to the # one used to create curve loops and surfaces. factory.addSurfaceLoop([127, 119, 121, 123, 125, 11], 128) factory.addVolume([128], 129) # Extrusion works as expected, by providing a vector of (dim, tag) pairs as # input, the translation vector, and a vector of (dim, tag) pairs as output. ov2 = factory.extrude([ov[1]], 0, 0, 0.12) # Mesh sizes associated to geometrical points can be set by passing a vector of # (dim, tag) pairs for the corresponding points. factory.mesh.setSize([(0,103), (0,105), (0,109), (0,102), (0,28), (0, 24), (0,6), (0,5)], lc * 3) model.addPhysicalGroup(3, [129,130], 1) model.setPhysicalName(3, 1, "The volume") factory.synchronize() model.mesh.generate(3) gmsh.write("t2.msh") gmsh.finalize()
# to 1.) Physical groups are also identified by tags, i.e. stricly positive # integers, that should be unique per dimension (0D, 1D, 2D or 3D). Physical # groups can also be given names. # # Here we define a physical curve that groups the left, bottom and right curves # in a single group (with prescribed tag 5); and a physical surface with name # "My surface" (with an automatic tag) containing the geometrical surface 1: #gmsh.model.addPhysicalGroup(1, [1, 2, 4], 5) #ps = gmsh.model.addPhysicalGroup(2, [1]) #gmsh.model.setPhysicalName(2, ps, "My surface") # We can then generate a 2D mesh... gmsh.model.mesh.generate(2) # ... and save it to disk gmsh.write("t1.msh") # Remember that by default, if physical groups are defined, Gmsh will export in # the output mesh file only those elements that belong to at least one physical # group. To force Gmsh to save all elements, you can use # # gmsh.option.setNumber("Mesh.SaveAll", 1) # By default, Gmsh saves meshes in the latest version of the Gmsh mesh file # format (the `MSH' format). You can save meshes in other mesh formats by # specifying a filename with a different extension. For example # # gmsh.write("t1.unv") # # will save the mesh in the UNV format. You can also save the mesh in older # versions of the MSH format: simply set
# Physical groups are defined by providing the dimension of the group (0 for # physical points, 1 for physical curves, 2 for physical surfaces and 3 for # phsyical volumes) followed by a vector of entity tags. The last (optional) # argument is the tag of the new group to create. gmsh.model.addPhysicalGroup(0, [1, 2], 1) gmsh.model.addPhysicalGroup(1, [1, 2], 2) gmsh.model.addPhysicalGroup(2, [1], 6) # Physical names are also defined by providing the dimension and tag of the # entity. gmsh.model.setPhysicalName(2, 6, "My surface") # Before it can be meshed, the internal CAD representation must be synchronized # with the Gmsh model, which will create the relevant Gmsh data structures. This # is achieved by the gmsh.model.geo.synchronize() API call for the built-in CAD # kernel. Synchronizations can be called at any time, but they involve a non # trivial amount of processing; so while you could synchronize the internal CAD # data after every CAD command, it is usually better to minimize the number of # synchronization points. gmsh.model.geo.synchronize() # We can then generate a 2D mesh... gmsh.model.mesh.generate(2) # ... and save it to disk gmsh.write("t1.msh") # This should be called at the end: gmsh.finalize()
def make_gmsh(df, **kwargs): logger.info('create grid') model = gmsh.model factory = model.geo gmsh.initialize() model.add("schism") # gmsh.option.setNumber("General.Terminal", 1) interpolate = kwargs.get('interpolate', False) if interpolate: ddf=gset(df,**kwargs) else: ddf=df lc = kwargs.get('lc', .5) ddf['lc'] = lc ddf = ddf.apply(pd.to_numeric) # save boundary configuration for Line0 rb0=ddf.loc['line0'].copy() if not shapely.geometry.LinearRing(rb0[['lon','lat']].values).is_ccw:# check for clockwise orientation rb0=ddf.loc['line0'].iloc[::-1].reset_index(drop=True) rb0.index=rb0.index+1 # fix index rb0['bounds']=[[i,i+1] for i in rb0.index] rb0['bounds']=rb0.bounds.values.tolist()[:-1]+[[rb0.index[-1],1]] # fix last one #store blines blines={} for tag_ in rb0.tag.unique(): ibs=rb0.loc[rb0.tag==tag_].index.values #ibs lbs=rb0.loc[rb0.tag==tag_].bounds.values.tolist() #lbs ai=np.unique(np.concatenate(lbs)) #ai itags=[i for i in ai if i in ibs] #itags if tag_ > 0: items = set(itags) imask=[set(x).issubset(items) for x in rb0.loc[rb0.tag==tag_].bounds] #imask bi=rb0.loc[rb0.tag==tag_][imask].index.values.tolist() else: bi=rb0.loc[rb0.tag==tag_].index.values.tolist() blines.update({tag_:bi}) al = [j for i in list(blines.values()) for j in i] lover=[x for x in rb0.index if x not in al] for i,v in rb0.loc[lover].iterrows(): nns=rb0.loc[v[5],['tag']].values itag=[x for x in nns if x < 0 ][0] blines.update({itag[0]:blines[itag[0]]+[i]}) land_lines = { your_key: blines[your_key] for your_key in [x for x in blines.keys() if x < 0] } open_lines = { your_key: blines[your_key] for your_key in [x for x in blines.keys() if x > 0] } logger.info('Define geometry') loops=[] islands=[] all_lines=[] ltag=1 for row in rb0.itertuples(index=True, name='Pandas'): factory.addPoint(getattr(row, "lon"),getattr(row, "lat"),getattr(row, "z"),getattr(row, "lc"),getattr(row, "Index")) for row in rb0.itertuples(index=True, name='Pandas'): factory.addLine(getattr(row, "bounds")[0],getattr(row, "bounds")[1],getattr(row, "Index")) lines=rb0.index.values all_lines.append(lines) tag=rb0.index.values[-1] factory.addCurveLoop(lines, tag=ltag) #print(loop) loops.append(ltag) all_lines.append(lines) tag += 1 ltag += 1 for contour in tqdm(ddf.index.levels[0][1:]): rb=ddf.loc[contour].copy() if not shapely.geometry.LinearRing(rb[['lon','lat']].values).is_ccw:# check for clockwise orientation rb=ddf.loc[contour].iloc[::-1].reset_index(drop=True) rb.index=rb.index+tag rb['bounds']=[[i,i+1] for i in rb.index] rb['bounds']=rb.bounds.values.tolist()[:-1]+[[rb.index[-1],rb.index[0]]] # fix last one for row in rb.itertuples(index=True, name='Pandas'): factory.addPoint(getattr(row, "lon"),getattr(row, "lat"),getattr(row, "z"),getattr(row, "lc"),getattr(row, "Index")) for row in rb.itertuples(index=True, name='Pandas'): factory.addLine(getattr(row, "bounds")[0],getattr(row, "bounds")[1],getattr(row, "Index")) lines=rb.index.values all_lines.append(lines) tag=rb.index.values[-1]+1 factory.addCurveLoop(lines,tag=ltag) # print(tag) loops.append(ltag) islands.append(lines) all_lines.append(lines) tag += 1 ltag += 1 factory.addPlaneSurface(loops) logger.info('synchronize') factory.synchronize() ## Group open boundaries lines for key,values in open_lines.items(): gmsh.model.addPhysicalGroup(1, values,1000-int(key)) ## Group land boundaries lines for key,values in land_lines.items(): gmsh.model.addPhysicalGroup(1, values,1000-int(key)) ntag=1 for k in tqdm(range(len(islands))): gmsh.model.addPhysicalGroup(1, islands[k], 2000+ntag) ntag += 1 ps = gmsh.model.addPhysicalGroup(2, [1]) gmsh.model.setPhysicalName(2, ps, "MyMesh") flat_list = [item for sublist in all_lines for item in sublist] ols=[j for i in list(open_lines.values()) for j in i] lists = [x for x in flat_list if x not in ols] model.mesh.field.add("Distance", 1) model.mesh.field.setNumbers(1, "CurvesList", lists) SizeMin = kwargs.get("SizeMin",.1) SizeMax = kwargs.get("SizeMax",.5) DistMin = kwargs.get("DistMin",.01) DistMax = kwargs.get("DistMax",.2) model.mesh.field.add("Threshold", 2); model.mesh.field.setNumber(2, "InField", 1); model.mesh.field.setNumber(2, "SizeMin", SizeMin); model.mesh.field.setNumber(2, "SizeMax", SizeMax); model.mesh.field.setNumber(2, "DistMin", DistMin); model.mesh.field.setNumber(2, "DistMax", DistMax); # Set bgmesh bgmesh = kwargs.get('bgmesh', None) if bgmesh == 'auto': try: logger.info('Read DEM') dem = pdem.dem(**kwargs) res_min = kwargs.get('resolution_min',.01) res_max = kwargs.get('resolution_max',.5) logger.info('Evaluate bgmesh') w = make_bgmesh(dem.Dataset,res_min, res_max) path = kwargs.get('rpath','.') if not os.path.exists(path): # check if run folder exists os.makedirs(path) logger.info('Save bgmesh to {}/bgmesh/bgmesh.pos'.format(path)) fpos = path + '/bgmesh/bgmesh.pos' to_sq(w,fpos) # save bgmesh kwargs.update({'bgmesh':fpos}) model.mesh.field.setNumber(2, "StopAtDistMax", 1); # Merge a post-processing view containing the target anisotropic mesh sizes gmsh.merge(fpos) model.mesh.field.add("PostView", 3) model.mesh.field.setNumber(3, "ViewIndex", 0) model.mesh.field.add("Min", 4) model.mesh.field.setNumbers(4, "FieldsList", [2,3]) model.mesh.field.setAsBackgroundMesh(4) except: logger.warning('bgmesh failed... continuing without background mesh size') model.mesh.field.setAsBackgroundMesh(2) else: model.mesh.field.setAsBackgroundMesh(2) gmsh.option.setNumber('Mesh.MeshSizeExtendFromBoundary',0) gmsh.option.setNumber('Mesh.MeshSizeFromPoints',0) gmsh.option.setNumber('Mesh.MeshSizeFromCurvature',0) logger.info('execute') gmsh.model.mesh.generate(2) # ... and save it to disk rpath = kwargs.get('rpath', '.') logger.info('save mesh') # gmsh.option.setNumber("Mesh.SaveAll", 1) gmsh.write(rpath + '/gmsh/mymesh.msh') # gmsh.write('mymesh.vtk') gmsh.finalize()
factory.addPoint(0.025, 0.15, 0.025, lc, p+1) l = factory.addLine(7, p+1) factory.synchronize() model.mesh.embed(1, [l], 3, 1) # finally, we can embed a surface in a volume factory.addPoint(0.02, 0.12, 0.05, lc, p+2) factory.addPoint(0.04, 0.12, 0.05, lc, p+3) factory.addPoint(0.04, 0.18, 0.05, lc, p+4) factory.addPoint(0.02, 0.18, 0.05, lc, p+5) factory.addLine(p+2, p+3, l+1) factory.addLine(p+3, p+4, l+2) factory.addLine(p+4, p+5, l+3) factory.addLine(p+5, p+2, l+4) ll = factory.addCurveLoop([l+1, l+2, l+3, l+4]) s = factory.addPlaneSurface([ll]) factory.synchronize() model.mesh.embed(2, [s], 3, 1) # create and show the mesh model.mesh.generate(3) gmsh.write("t15.msh") gmsh.fltk.run() gmsh.finalize()
def __init__(self, AP, path_to_geo, S=None, R=None, fmax=1000, num_freq=6, scale=1, order=1, plot=False): self.R = R self.S = S self.path_to_geo = path_to_geo self.fmax = fmax self.num_freq = num_freq self.scale = scale self.order = order self.c0 = np.real(AP.c0) import meshio import gmsh import sys import os filename, file_extension = os.path.splitext(path_to_geo) # print(file_extension) if file_extension == '.geo' or file_extension == '.geo_unrolled' or file_extension == '.brep': gmsh.initialize(sys.argv) gmsh.open(self.path_to_geo) # Open msh # dT = gmsh.model.getEntities() # gmsh.model.occ.dilate(dT,0,0,0,1/scale,1/scale,1/scale) gmsh.option.setNumber("Mesh.MeshSizeMax", (self.c0 * self.scale) / self.fmax / self.num_freq) gmsh.option.setNumber( "Mesh.MeshSizeMin", 0.1 * (self.c0 * self.scale) / self.fmax / self.num_freq) # print((self.c0*self.scale)/self.fmax/self.num_freq) lc = 0 #(self.c0*self.scale)/self.fmax/self.num_freq tg = gmsh.model.occ.getEntities(3) # tg2 = gmsh.model.occ.getEntities(2) if self.R != None: for i in range(len(self.R.coord)): it = gmsh.model.occ.addPoint(self.R.coord[i, 0], self.R.coord[i, 1], self.R.coord[i, 2], lc, -1) gmsh.model.occ.synchronize() gmsh.model.mesh.embed(0, [it], 3, tg[0][1]) if self.S != None: for i in range(len(self.S.coord)): it = gmsh.model.occ.addPoint(self.S.coord[i, 0], self.S.coord[i, 1], self.S.coord[i, 2], lc, -1) gmsh.model.occ.synchronize() gmsh.model.mesh.embed(0, [it], 3, tg[0][1]) # gmsh.model.mesh.embed(0, [15000], 3, tg[0][1]) gmsh.model.mesh.generate(3) gmsh.model.mesh.setOrder(self.order) # gmsh.model.mesh.optimize(method='Relocate3D',force=False) if self.order == 1: elemTy, elemTa, nodeTags = gmsh.model.mesh.getElements(3) self.elem_vol = np.array(nodeTags, dtype=int).reshape(-1, 4) - 1 elemTys, elemTas, nodeTagss = gmsh.model.mesh.getElements(2) self.elem_surf = np.array(nodeTagss, dtype=int).reshape(-1, 3) - 1 vtags, vxyz, _ = gmsh.model.mesh.getNodes() self.nos = vxyz.reshape((-1, 3)) / scale if self.order == 2: elemTy, elemTa, nodeTags = gmsh.model.mesh.getElements(3) self.elem_vol = np.array(nodeTags, dtype=int).reshape(-1, 10) - 1 elemTys, elemTas, nodeTagss = gmsh.model.mesh.getElements(2) self.elem_surf = np.array(nodeTagss, dtype=int).reshape(-1, 6) - 1 vtags, vxyz, _ = gmsh.model.mesh.getNodes() self.nos = vxyz.reshape((-1, 3)) / scale pg = gmsh.model.getPhysicalGroups(2) va = [] vpg = [] for i in range(len(pg)): v = gmsh.model.getEntitiesForPhysicalGroup(2, pg[i][1]) for ii in range(len(v)): # print(v[ii]) vvv = gmsh.model.mesh.getElements(2, v[ii])[1][0] pgones = np.ones_like(vvv) * pg[i][1] va = np.hstack((va, vvv)) # print(pgones) vpg = np.hstack((vpg, pgones)) vas = np.argsort(va) self.domain_index_surf = vpg[vas] # print(vas) pgv = gmsh.model.getPhysicalGroups(3) # print(pgv) vav = [] vpgv = [] for i in range(len(pgv)): vv = gmsh.model.getEntitiesForPhysicalGroup(3, pgv[i][1]) for ii in range(len(vv)): # print(v[ii]) vvv = gmsh.model.mesh.getElements(3, vv[ii])[1][0] pgones = np.ones_like(vvv) * pgv[i][1] vav = np.hstack((vav, vvv)) # print(pgones) vpgv = np.hstack((vpgv, pgones)) vasv = np.argsort(vav) self.domain_index_vol = vpgv[vasv] # gmsh.model.mesh.optimize() gmsh.model.occ.synchronize() if plot: gmsh.fltk.run() # gmsh.fltk.run() path_name = os.path.dirname(self.path_to_geo) gmsh.write(path_name + '/current_mesh2.vtk') self.model = gmsh.model gmsh.finalize() # msh = meshio.read(path_name+'/current_mesh2.vtk') elif file_extension == '.msh' or file_extension == 'vtk': msh = meshio.read(path_to_geo) self.msh = msh # os.remove(path_name+'/current_mesh.msh') if order == 1: self.nos = msh.points / scale self.elem_surf = msh.cells_dict["triangle"] self.elem_vol = msh.cells_dict["tetra"] # self.domain_index_surf = msh.cell_data_dict["CellEntityIds"]["triangle"] # self.domain_index_vol = msh.cell_data_dict["CellEntityIds"]["tetra"] self.domain_index_surf = msh.cell_data_dict["gmsh:physical"][ "triangle"] self.domain_index_vol = msh.cell_data_dict["gmsh:physical"][ "tetra"] # elif order == 2: # self.elem_surf = msh.cells_dict["triangle6"] # self.elem_vol = msh.cells_dict["tetra10"] # self.domain_index_surf = msh.cell_data_dict["gmsh:physical"]["triangle6"] # self.domain_index_vol = msh.cell_data_dict["gmsh:physical"]["tetra10"] elif order == 2: # self.elem_surf = msh.cells_dict["triangle6"] # self.elem_vol = msh.cells_dict["tetra10"] self.domain_index_surf = msh.cell_data_dict["CellEntityIds"][ "triangle6"] self.domain_index_vol = msh.cell_data_dict["CellEntityIds"][ "tetra10"] self.number_ID_faces = np.unique(self.domain_index_surf) self.number_ID_vol = np.unique(self.domain_index_vol) self.NumNosC = len(self.nos) self.NumElemC = len(self.elem_vol)
model.mesh.field.setNumber(2, "LcMax", lc) model.mesh.field.setNumber(2, "DistMin", 0.15) model.mesh.field.setNumber(2, "DistMax", 0.5) model.mesh.field.add("MathEval", 3) model.mesh.field.setString(3, "F", "Cos(4*3.14*x) * Sin(4*3.14*y) / 10 + 0.101") model.mesh.field.add("Distance", 4) model.mesh.field.setNumbers(4, "NodesList", [1]) model.mesh.field.add("MathEval", 5); model.mesh.field.setString(5, "F", "F4^3 + " + str(lc / 100)) model.mesh.field.add("Box", 6) model.mesh.field.setNumber(6, "VIn", lc / 15) model.mesh.field.setNumber(6, "VOut", lc) model.mesh.field.setNumber(6, "XMin", 0.3) model.mesh.field.setNumber(6, "XMax", 0.6) model.mesh.field.setNumber(6, "YMin", 0.3) model.mesh.field.setNumber(6, "YMax", 0.6) model.mesh.field.add("Min", 7) model.mesh.field.setNumbers(7, "FieldsList", [2, 3, 5, 6]) model.mesh.field.setAsBackgroundMesh(7) factory.synchronize() model.mesh.generate(2) gmsh.write("t10.msh") gmsh.finalize()
for t in range(1, 6): x += 0.166 z += 0.166 factory.addSphere(x,y,z,r, 3 + t) holes.append((3, 3 + t)) ov, ovv = factory.fragment([(3,3)], holes) factory.synchronize() lcar1 = .1 lcar2 = .0005 lcar3 = .055 ov = model.getEntities(0); model.mesh.setSize(ov, lcar1); ov = model.getBoundary(holes, False, False, True); model.mesh.setSize(ov, lcar3); eps = 1e-3 ov = model.getEntitiesInBoundingBox(0.5-eps, 0.5-eps, 0.5-eps, 0.5+eps, 0.5+eps, 0.5+eps, 0) model.mesh.setSize(ov, lcar2) model.mesh.generate(3) gmsh.write("t16.msh") gmsh.finalize()
import gmsh gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) gmsh.model.add("periodic") R = 2 gmsh.model.occ.addBox(0, 0, 0, R, R, R) gmsh.model.occ.synchronize() ent = gmsh.model.getEntities(0); gmsh.model.mesh.setSize(ent, 1); gmsh.model.mesh.setSize([(0,1)], 0.01); gmsh.model.mesh.setPeriodic(2, [2], [1], [1,0,0,R, 0,1,0,0, 0,0,1,0, 0,0,0,1]) gmsh.model.mesh.generate(2) #gmsh.model.mesh.setOrder(2) masterTag, nodeTags, nodeMasterTags, tfo = gmsh.model.mesh.getPeriodicNodes(2, 2) print masterTag, nodeTags, nodeMasterTags, tfo gmsh.write("periodic.msh")
# Find bases for relative homology spaces of the domain modulo the four # terminals. gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag], subdomainTags=[terminals_physical_tag], dims=[0,1,2,3]) # Find homology space bases isomorphic to the previous bases: homology spaces # modulo the non-terminal domain surface, a.k.a the thin cuts. gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag], subdomainTags=[complement_physical_tag], dims=[0,1,2,3]) # Find cohomology space bases isomorphic to the previous bases: cohomology # spaces of the domain modulo the four terminals, a.k.a the thick cuts. gmsh.model.mesh.computeCohomology(domainTags=[domain_physical_tag], subdomainTags=[terminals_physical_tag], dims=[0,1,2,3]) # more examples #gmsh.model.mesh.computeHomology() #gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag]) #gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag], subdomainTags=[boundary_physical_tag], dims=[0,1,2,3]) # Generate the mesh and perform the requested homology computations gmsh.model.mesh.generate(3) # Find physical tags of a certain homology or cohomology space chains physicals = gmsh.model.getPhysicalGroups() for pi in physicals: name = gmsh.model.getPhysicalName(pi[0], pi[1]) if(name.find("H^1") == 0): # find tags of all cohomology chains of dimension 1 print("H^1 tag: " + str(pi[1]) + ", name: " + name) gmsh.write("t14.msh") gmsh.finalize()
model = gmsh.model factory = model.occ gmsh.initialize(sys.argv) create_geometry() if RECOMBINE: model.mesh.setRecombine(2,2) model.mesh.setRecombine(2,3) model.mesh.setRecombine(2,4) model.mesh.generate(2) if DEBUG: gmsh.write('poisson.msh') fem_solve() gmsh.option.setNumber("View[0].IntervalsType", 3) gmsh.option.setNumber("View[0].NbIso", 20) gmsh.fltk.run() gmsh.finalize() ## Explanation for the serialization of elementary matrices. ## ## node = numpy.array([[1,2,3]]) # one element with nodes 1,2 and 3 ## col = numpy.repeat(enode[:,:,None],3,axis=2) ## row = numpy.repeat(enode[:,None,:],3,axis=1) ## >>> col
if len(sys.argv) > 2: N = int(sys.argv[2]) if len(sys.argv) > 3: dumpfiles = int(sys.argv[3]) gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) # create a geometrical gmsh.model gmsh.model.add("square") square = gmsh.model.occ.addRectangle(0, 0, 0, 1, 1) gmsh.model.occ.synchronize() # create intial uniform mesh pnts = gmsh.model.getBoundary([(2,square)], True, True, True); gmsh.model.mesh.setSize(pnts, lc) gmsh.model.mesh.generate(2) if dumpfiles: gmsh.write("mesh.msh") mesh = Mesh() # compute and visualize the interpolation error f_nod, err_ele = compute_interpolation_error(mesh.vxyz, mesh.triangles, my_function) f_view = gmsh.view.add("nodal function") gmsh.view.addModelData(f_view, 0, "square", "NodeData", mesh.vtags, f_nod[:,None]) if dumpfiles: gmsh.view.write(f_view, "f.pos") err_view = gmsh.view.add("element-wise error") gmsh.view.addModelData(err_view, 0, "square", "ElementData", mesh.triangles_tags, err_ele[:,None]) if dumpfiles: gmsh.view.write(err_view, "err.pos") # compute and visualize the remeshing size field sf_ele = compute_size_field(mesh.vxyz,mesh.triangles, err_ele, N)
factory.mesh.setTransfiniteSurface(1, "Left", [1,2,3,4]) # Recombine the triangles into quads factory.mesh.setRecombine(2, 1) # Apply an elliptic smoother to the grid gmsh.option.setNumber("Mesh.Smoothing", 100) model.addPhysicalGroup(2, [1], 1) # When the surface has only 3 or 4 control points, the transfinite constraint # can be applied automatically (without specifying the corners explictly). factory.addPoint(0.2, 0.2, 0, 1.0, 7) factory.addPoint(0.2, 0.1, 0, 1.0, 8) factory.addPoint(0, 0.3, 0, 1.0, 9) factory.addPoint(0.25, 0.2, 0, 1.0, 10) factory.addPoint(0.3, 0.1, 0, 1.0, 11) factory.addLine(8, 11, 10) factory.addLine(11, 10, 11) factory.addLine(10, 7, 12) factory.addLine(7, 8, 13) factory.addCurveLoop([13, 10, 11, 12], 14) factory.addPlaneSurface([14], 15) for i in range(10,14): factory.mesh.setTransfiniteCurve(i, 10) factory.mesh.setTransfiniteSurface(15) model.addPhysicalGroup(2, [15], 2) model.mesh.generate(2) gmsh.write("t6.msh") gmsh.finalize()
def mesh_ep_gmshapi(name, Lx, Ly, L0, s, lc, tdim, order=1, msh_file=None, sep=0.1, comm=MPI.COMM_WORLD): if comm.rank == 0: import gmsh # Initialise gmsh and set options gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) gmsh.option.setNumber("Mesh.Algorithm", 6) model = gmsh.model() model.add("Rectangle") model.setCurrent("Rectangle") p0 = model.geo.addPoint(0.0, 0.0, 0, lc, tag=0) p1 = model.geo.addPoint(Lx, 0.0, 0, lc, tag=1) p2 = model.geo.addPoint(Lx, Ly, 0.0, lc, tag=2) p3 = model.geo.addPoint(0, Ly, 0, lc, tag=3) #pLa= model.geo.addPoint(0, Ly/2-s/2, 0, lc, tag=4) pRa = model.geo.addPoint(Lx, Ly / 2 + s / 2 - sep, 0, lc, tag=6) pRb = model.geo.addPoint(Lx, Ly / 2 + s / 2 + sep, 0, lc, tag=7) pLa = model.geo.addPoint(0, Ly / 2 - s / 2 - sep, 0, lc, tag=8) pLb = model.geo.addPoint(0, Ly / 2 - s / 2 + sep, 0, lc, tag=5) plM = model.geo.addPoint(L0, Ly / 2 - s / 2, 0, lc, tag=9) prM = model.geo.addPoint(Lx - L0, Ly / 2 + s / 2, 0, lc, tag=10) # points = [p0, p1, p2, p3] bottom = model.geo.addLine(p0, p1, tag=0) #right = model.geo.addLine(p1, p2, tag=1) rightB = model.geo.addLine(p1, pRa, tag=1) crackBR = model.geo.addLine(pRa, prM, tag=2) crackTR = model.geo.addLine(prM, pRb, tag=3) rightT = model.geo.addLine(pRb, p2, tag=4) top = model.geo.addLine(p2, p3, tag=5) #left=model.geo.addLine(p3, p0, tag=6) leftT = model.geo.addLine(p3, pLb, tag=6) crackTL = model.geo.addLine(pLb, plM, tag=7) crackBL = model.geo.addLine(plM, pLa, tag=8) leftB = model.geo.addLine(pLa, p0, tag=9) #cloop1 = model.geo.addCurveLoop([bottom, right, top, left]) cloop1 = model.geo.addCurveLoop([ crackTR, rightT, top, leftT, crackTL, crackBL, leftB, bottom, rightB, crackBR ]) # surface_1 = model.geo.addPlaneSurface([cloop1]) model.geo.synchronize() surface_entities = [model[1] for model in model.getEntities(tdim)] model.addPhysicalGroup(tdim, surface_entities, tag=5) model.setPhysicalName(tdim, 5, "Rectangle surface") # Set mesh size via points # gmsh.model.mesh.setSize(points, lc) # heuristic # gmsh.model.mesh.optimize("Netgen") # Set geometric order of mesh cells gmsh.model.mesh.setOrder(order) # Define physical groups for subdomains (! target tag > 0) # domain = 1 # gmsh.model.addPhysicalGroup(tdim, [v[1] for v in volumes], domain) # gmsh.model.setPhysicalName(tdim, domain, 'domain') #gmsh.model.addPhysicalGroup(tdim - 2, [9], tag=18) #gmsh.model.setPhysicalName(tdim - 2, 18, "nodeLeftMiddle") gmsh.model.addPhysicalGroup(tdim - 1, [0], tag=10) gmsh.model.setPhysicalName(tdim - 1, 10, "bottom") gmsh.model.addPhysicalGroup(tdim - 1, [5], tag=11) gmsh.model.setPhysicalName(tdim - 1, 11, "top") gmsh.model.addPhysicalGroup(tdim - 1, [6, 7, 8, 9], tag=12) #gmsh.model.addPhysicalGroup(tdim - 1, [6], tag=12) gmsh.model.setPhysicalName(tdim - 1, 12, "left") gmsh.model.addPhysicalGroup(tdim - 1, [1, 2, 3, 4], tag=13) #gmsh.model.addPhysicalGroup(tdim - 1, [1], tag=13) gmsh.model.setPhysicalName(tdim - 1, 13, "right") gmsh.model.addPhysicalGroup(tdim - 1, [7], tag=14) gmsh.model.setPhysicalName(tdim - 1, 14, "Lliptop") gmsh.model.addPhysicalGroup(tdim - 1, [8], tag=15) gmsh.model.setPhysicalName(tdim - 1, 15, "Llipbot") gmsh.model.addPhysicalGroup(tdim - 1, [2], tag=16) gmsh.model.setPhysicalName(tdim - 1, 16, "Rliptop") gmsh.model.addPhysicalGroup(tdim - 1, [3], tag=17) gmsh.model.setPhysicalName(tdim - 1, 17, "Rlipbot") model.mesh.generate(tdim) # Define physical groups for interfaces (! target tag > 0) # surface = 1 # gmsh.model.addPhysicalGroup(tdim - 1, [s[1] for s in surfaces], surface) # gmsh.model.setPhysicalName(tdim - 1, surface, 'surface') """surface_grip_left = 2 gmsh.model.addPhysicalGroup(tdim - 1, [s0], surface_grip_left) gmsh.model.setPhysicalName(tdim - 1, surface_grip_left, 'surface_grip_left') surface_grip_right = 3 gmsh.model.addPhysicalGroup(tdim - 1, [s1], surface_grip_right) gmsh.model.setPhysicalName(tdim - 1, surface_grip_right, 'surface_grip_right') surface_plane_left = 4 gmsh.model.addPhysicalGroup(tdim - 1, [s2], surface_plane_left) gmsh.model.setPhysicalName(tdim - 1, surface_plane_left, 'surface_plane_left') surface_plane_right = 5 gmsh.model.addPhysicalGroup(tdim - 1, [s3], surface_plane_right) gmsh.model.setPhysicalName(tdim - 1, surface_plane_right, 'surface_plane_right')""" # Optional: Write msh file if msh_file is not None: gmsh.write(msh_file) # gmsh.write(name + ".step") return gmsh.model if comm.rank == 0 else None, tdim
s1 = factory.addSurfaceFilling([l1]) s2 = factory.addSurfaceFilling([l2]) s3 = factory.addSurfaceFilling([l3]) s4 = factory.addSurfaceFilling([l4]) s5 = factory.addSurfaceFilling([l5]) s6 = factory.addSurfaceFilling([l6]) s7 = factory.addSurfaceFilling([l7]) s8 = factory.addSurfaceFilling([l8]) sl = factory.addSurfaceLoop([s1, s2, s3, s4, s5, s6, s7, s8]) v = factory.addVolume([sl]) shells.append(sl) return v x = 0; y = 0.75; z = 0; r = 0.09 for t in range(1, 6): x += 0.166 z += 0.166 v = cheeseHole(x, y, z, r, lcar3, shells) model.addPhysicalGroup(3, [v], t) factory.addVolume(shells, 186) model.addPhysicalGroup(3, [186], 10) factory.synchronize() model.mesh.generate(3) gmsh.write("t5.msh") gmsh.finalize()
model = gmsh.model factory = model.occ gmsh.initialize(sys.argv) create_geometry() if RECOMBINE: model.mesh.setRecombine(2, 2) model.mesh.setRecombine(2, 3) model.mesh.setRecombine(2, 4) model.mesh.generate(2) if DEBUG: gmsh.write('poisson.msh') fem_solve() gmsh.option.setNumber("View[0].IntervalsType", 3) gmsh.option.setNumber("View[0].NbIso", 20) gmsh.fltk.run() gmsh.finalize() ## Explanation for the serialization of elementary matrices. ## ## node = numpy.array([[1,2,3]]) # one element with nodes 1,2 and 3 ## col = numpy.repeat(enode[:,:,None],3,axis=2) ## row = numpy.repeat(enode[:,None,:],3,axis=1) ## >>> col
import gmsh import sys gmsh.initialize(sys.argv) gmsh.model.add("square") gmsh.model.geo.addPoint(0, 0, 0, 0.1, 1) gmsh.model.geo.addPoint(1, 0, 0, 0.1, 2) gmsh.model.geo.addPoint(1, 1, 0, 0.1, 3) gmsh.model.geo.addPoint(0, 1, 0, 0.1, 4) gmsh.model.geo.addLine(1, 2, 1) gmsh.model.geo.addLine(2, 3, 2) gmsh.model.geo.addLine(3, 4, 3) # try automatic assignement of tag line4 = gmsh.model.geo.addLine(4, 1) gmsh.model.geo.addCurveLoop([1, 2, 3, line4], 1) gmsh.model.geo.addPlaneSurface([1], 6) gmsh.model.geo.synchronize() gmsh.model.mesh.generate(2) gmsh.write("square.msh")
for n, ss in boundary_surfaces_groups.items(): surface_index = map_boundary_name_to_primitive_surface_index[n] for s in ss: primitives_indices = s_to_is.get(s, None) if primitives_indices is not None: index = primitives_indices[0] surface_name = c.primitives[index].surfaces_names[ surface_index] map_names_to_surfaces.setdefault(surface_name, list()).append(s) for n, ss in map_names_to_surfaces.items(): tag = gmsh.model.addPhysicalGroup(2, ss) gmsh.model.setPhysicalName(2, tag, n) elif args['boundary_type'] == 'all': print("All surfaces") boundary_surfaces = get_boundary_surfaces() for i, s in enumerate(boundary_surfaces): name = 'S{0}'.format(s) tag = gmsh.model.addPhysicalGroup(2, [s]) gmsh.model.setPhysicalName(2, tag, name) else: print("By support.physical_surfaces") physical_surfaces(**physical_surfaces_kwargs) print("Mesh") gmsh.model.mesh.generate(3) gmsh.model.mesh.removeDuplicateNodes() print('Nodes: {0}'.format(len(gmsh.model.mesh.getNodes()[0]))) print("Write: {}".format(args['output_path'])) gmsh.write(args['output_path']) gmsh.finalize()
# We could make only part of the model visible to only mesh this subset: # ent = gmsh.model.getEntities() # gmsh.model.setVisibility(ent, False) # gmsh.model.setVisibility([(3, 5(], True, True) # gmsh.option.setNumber("Mesh.MeshOnlyVisible", 1) # Meshing algorithms can changed globally using options: gmsh.option.setNumber("Mesh.Algorithm", 6) # Frontal-Delaunay for 2D meshes # They can also be set for individual surfaces, e.g. for using `MeshAdapt' on # surface 1: gmsh.model.mesh.setAlgorithm(2, 33, 1) # To generate a curvilinear mesh and optimize it to produce provably valid # curved elements (see A. Johnen, J.-F. Remacle and C. Geuzaine. Geometric # validity of curvilinear finite elements. Journal of Computational Physics # 233, pp. 359-372, 2013; and T. Toulorge, C. Geuzaine, J.-F. Remacle, # J. Lambrechts. Robust untangling of curvilinear meshes. Journal of # Computational Physics 254, pp. 8-26, 2013), you can uncomment the following # lines: # # gmsh.option.setNumber("Mesh.ElementOrder", 2) # gmsh.option.setNumber("Mesh.HighOrderOptimize", 2) gmsh.model.mesh.generate(3) gmsh.write("t5.msh") # gmsh.fltk.run() gmsh.finalize()
factory.addLine(4, 1, 4) factory.addCurveLoop([4, 1, -2, 3], 1) factory.addPlaneSurface([1], 1) model.addPhysicalGroup(0, [1, 2], 1) model.addPhysicalGroup(1, [1, 2], 2) model.addPhysicalGroup(2, [1], 6) model.setPhysicalName(2, 6, "My surface") # ...end of copy h = 0.1 angle = 90. # Extruding the mesh in addition to the geometry works as in .geo files: the # number of elements for each layer and the (end) height of each layer are # specified in two vectors. ov = factory.extrude([(2,1)], 0, 0, h, [8,2], [0.5,1]) #/ Rotational and twisted extrusions are available as well with the built-in CAD # kernel. The last (optional) argument for the Extrude/Revolve/Twist commands # specified whether the extruded mesh should be recombined or not. ov = factory.revolve([(2,28)], -0.1,0,0.1, 0,1,0, -math.pi/2, [7]) ov = factory.twist([(2,50)], 0,0.15,0.25, -2*h,0,0, 1,0,0, angle*math.pi/180., [10], [], True) model.addPhysicalGroup(3, [1, 2, ov[1][1]], 101) factory.synchronize() model.mesh.generate(3) gmsh.write("t3.msh") gmsh.finalize()
def save_geometry(self, filename: str): # filename is typically a geo_unrolled or brep file self.synchronize() gmsh.write(filename)
factory = model.occ FILENAME_STEM = __file__.split(".")[0] MSH_FILENAME = f"{FILENAME_STEM}.msh" gmsh.initialize(sys.argv) gmsh.option.setNumber("General.Terminal", 1) gmsh.option.setNumber("Mesh.Algorithm", 6) gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 1.0) gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 1.0) model.add(FILENAME_STEM) p1 = model.geo.addPoint(10.0, 0.0, 0.0, 1.0) p2 = model.geo.addPoint(10.0, 10.0, 0.0, 1.0) l1 = model.geo.addLine(p1, p2) s1 = model.geo.extrude([(1, l1)], 0.0, 0.0, 10.0, numElements=[10], recombine=True) model.geo.extrude(s1, 1.0, 0.0, 0.0, numElements=[1], recombine=True) model.geo.synchronize() model.mesh.generate(3) gmsh.write(MSH_FILENAME) gmsh.finalize()
def write_brep(self, filename=None): self.synchronize() if filename is None: filename = self.model_name gmsh.write(filename + '.brep')
eps = 1e-4 s = [] for i in range(1, N): xx = xmin if (dir == 'X') else xmax yy = ymin if (dir == 'Y') else ymax zz = zmin if (dir == 'Z') else zmax s.extend(gmsh.model.getEntitiesInBoundingBox( xmin - eps + i * tx, ymin - eps + i * ty, zmin - eps + i * tz, xx + eps + i * tx, yy + eps + i * ty, zz + eps + i * tz, 2)) # ...and remove all the other entities (here directly in the model, as we # won't modify any OpenCASCADE entities later on): dels = gmsh.model.getEntities(2) for e in s: dels.remove(e) gmsh.model.removeEntities(gmsh.model.getEntities(3)) gmsh.model.removeEntities(dels) gmsh.model.removeEntities(gmsh.model.getEntities(1)) gmsh.model.removeEntities(gmsh.model.getEntities(0)) # Finally, let's specify a global mesh size and mesh the partitioned model: gmsh.option.setNumber("Mesh.MeshSizeMin", 3) gmsh.option.setNumber("Mesh.MeshSizeMax", 3) gmsh.model.mesh.generate(3) gmsh.write("t20.msh") # Launch the GUI to see the results: if '-nopopup' not in sys.argv: gmsh.fltk.run() gmsh.finalize()
def mesh_V( a, h, L, n, gamma, de, de2, key=0, show=False, filename='mesh.unv', order=1, ): """ Create a 2D mesh of a notched three-point flexure specimen using GMSH. a = height of the notch h = height of the specimen L = width of the specimen n = width of the load interface gamma = notch angle de = density of elements at specimen de2 = density of elements at the notch and crack key = 0 -> create model for Fenicxs (default) 1 -> create model for Cast3M show = False -> doesn't open Gmsh to vizualise the mesh (default) True -> open Gmsh to vizualise the mesh filename = name and format of the output file for key = 1 order = order of the function of form """ gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) gmsh.option.setNumber("Mesh.Algorithm", 5) hopen = a * np.tan((gamma / 2.0) * np.pi / 180) c0 = h / 40 load_len = n tdim = 2 model = gmsh.model() model.add('TPB') model.setCurrent('TPB') #Generating the points of the geometrie p0 = model.geo.addPoint(0.0, a, 0.0, de2, tag=0) p1 = model.geo.addPoint(hopen, 0.0, 0.0, de, tag=1) p2 = model.geo.addPoint(L / 2, 0.0, 0.0, de, tag=2) p3 = model.geo.addPoint(L / 2, h, 0.0, de, tag=3) p4 = model.geo.addPoint(0.0, h, 0.0, de, tag=4) if key == 0: p5 = model.geo.addPoint(-L / 2, h, 0.0, de, tag=5) p6 = model.geo.addPoint(-L / 2, 0.0, 0.0, de, tag=6) p7 = model.geo.addPoint(-hopen, 0.0, 0.0, de, tag=7) #Load facet p21 = model.geo.addPoint(load_len, h, 0.0, de, tag=30) p22 = model.geo.addPoint(-load_len, h, 0.0, de, tag=31) elif key == 1: p20 = model.geo.addPoint(0, a + c0, 0, de2, tag=20) #Creating the lines by connecting the points notch_right = model.geo.addLine(p0, p1, tag=8) bot_right = model.geo.addLine(p1, p2, tag=9) right = model.geo.addLine(p2, p3, tag=10) #top_right = model.geo.addLine(p3, p4, tag=11) if key == 0: top_right = model.geo.addLine(p3, p21, tag=11) top_left = model.geo.addLine(p22, p5, tag=12) left = model.geo.addLine(p5, p6, tag=13) bot_left = model.geo.addLine(p6, p7, tag=14) notch_left = model.geo.addLine(p7, p0, tag=15) #Load facet load_right = model.geo.addLine(p21, p4, tag=32) load_left = model.geo.addLine(p4, p22, tag=33) elif key == 1: top_right = model.geo.addLine(p3, p4, tag=11) sym_plan = model.geo.addLine(p4, p20, tag=21) fissure = model.geo.addLine(p20, p0, tag=22) #Creating the surface using the lines created if key == 0: perimeter = model.geo.addCurveLoop([ notch_right, bot_right, right, top_right, load_right, load_left, top_left, left, bot_left, notch_left ]) elif key == 1: perimeter = model.geo.addCurveLoop( [notch_right, bot_right, right, top_right, sym_plan, fissure]) surface = model.geo.addPlaneSurface([perimeter]) #model.geo.addSurfaceLoop([surface,16]) model.mesh.setOrder(order) #Creating Physical Groups to extract data from the geometrie if key == 0: gmsh.model.addPhysicalGroup(tdim - 1, [left], tag=101) gmsh.model.setPhysicalName(tdim - 1, 101, 'Left') gmsh.model.addPhysicalGroup(tdim - 1, [right], tag=102) gmsh.model.setPhysicalName(tdim - 1, 102, 'Right') gmsh.model.addPhysicalGroup(tdim - 2, [p6], tag=103) gmsh.model.setPhysicalName(tdim - 2, 103, 'Left_point') gmsh.model.addPhysicalGroup(tdim - 2, [p2], tag=104) gmsh.model.setPhysicalName(tdim - 2, 104, 'Right_point') gmsh.model.addPhysicalGroup(tdim - 2, [p4], tag=105) gmsh.model.setPhysicalName(tdim - 2, 105, 'Load_point') gmsh.model.addPhysicalGroup(tdim - 2, [p0], tag=106) gmsh.model.setPhysicalName(tdim - 2, 106, 'Notch_point') gmsh.model.addPhysicalGroup(tdim - 1, [load_right], tag=107) gmsh.model.setPhysicalName(tdim - 1, 107, 'load_right') gmsh.model.addPhysicalGroup(tdim - 1, [load_left], tag=108) gmsh.model.setPhysicalName(tdim - 1, 108, 'load_left') gmsh.model.addPhysicalGroup(tdim, [surface], tag=110) gmsh.model.setPhysicalName(tdim, 110, 'mesh_surface') #Cast3M can't read Physical Groups of points (dim = 0). Instead, we check the number in the mesh and input in manually in the code. #The number of a node doesn't change if it's in a point of the geometry if key == 1: gmsh.model.addPhysicalGroup(tdim, [surface], tag=110) gmsh.model.setPhysicalName(tdim, 110, 'mesh_surface') gmsh.model.addPhysicalGroup(tdim - 1, [fissure], tag=111) gmsh.model.setPhysicalName(tdim - 1, 111, 'fissure') gmsh.model.addPhysicalGroup(tdim - 1, [sym_plan], tag=112) gmsh.model.setPhysicalName(tdim - 1, 112, 'sym_plan') #gmsh.model.addPhysicalGroup(tdim-2, [p20], tag=113) #gmsh.model.setPhysicalName(tdim-2, 113, 'Crack_tip') #gmsh.model.addPhysicalGroup(tdim-2, [p4], tag=114) #gmsh.model.setPhysicalName(tdim-2, 114, 'Load_point') #gmsh.model.addPhysicalGroup(tdim-2, [p2], tag=115) #gmsh.model.setPhysicalName(tdim-2, 115,'Right_point') #Generating the mesh model.geo.synchronize() model.mesh.generate(tdim) if show: gmsh.fltk.run() if key == 1: gmsh.write(filename) return gmsh.model
while times[i] < t: i += 1 alpha = (t - times[i - 1]) / (times[i] - times[i - 1]) print(t, i, alpha) for j in range(len(temps[i])): temp_inst[j] = [ temps[i - 1][j][0] + alpha * (temps[i][j][0] - temps[i - 1][j][0]) ] gmsh.view.addModelData(view_inst, step, "", kind, tags, temp_inst, t) step += 1 t += dt gmsh.view.remove(0) gmsh.fltk.initialize() for i in range(step): print(i) gmsh.option.setNumber("View[0].TimeStep", i) gmsh.fltk.update() gmsh.write("temp-valve-smooth-%03d.png" % i) gmsh.finalize() print("all frames dumped, now run") print( "ffmpeg -y -framerate 20 -f image2 -i temp-valve-smooth-%03d.png temp-valve-smooth.mp4" ) print("to get a video")
def draw_GMSH( output, sym, boundary_prop, boundary_list, surface_label, is_antiper=False, is_remove_vent=False, is_remove_slotS=False, is_remove_slotR=False, is_lam_only_S=False, is_lam_only_R=False, kgeo_fineness=1, kmesh_fineness=1, user_mesh_dict={}, path_save="GMSH_model.msh", is_sliding_band=False, is_airbox=False, transform_list=[], is_set_labels=False, ): """Draws a machine mesh in GMSH format Parameters ---------- output : Output Output object sym : int the symmetry applied on the stator and the rotor (take into account antiperiodicity) boundary_prop : dict dictionary to match FEA boundary conditions (dict values) with line labels (dict keys) that are set in the build_geometry methods boundary_list : list list of boundary condition names surface_label : dict dict for the translation of the actual surface labels into FEA software compatible labels is_remove_vent : bool True to remove the ventilation ducts (Default value = False) is_remove_slotS : bool True to solve without slot effect on the Stator (Default value = False) is_remove_slotR : bool True to solve without slot effect on the Rotor (Default value = False) kgeo_fineness : float global coefficient to adjust geometry fineness kmesh_fineness : float global coefficient to adjust mesh fineness is_antiper: bool To apply antiperiodicity boundary conditions is_lam_only_S: bool Draw only stator lamination is_lam_only_R: bool Draw only rotor lamination Returns ------- GMSH_dict : dict Dictionnary containing the main parameters of GMSH File """ # check some input parameter if is_lam_only_S and is_lam_only_R: raise InputError( "Only 'is_lam_only_S' or 'is_lam_only_R' can be True at the same time" ) # get machine machine = output.simu.machine mesh_dict = {} tol = 1e-6 # Default stator mesh element size mesh_size_S = machine.stator.Rext / 100.0 mesh_size_R = machine.rotor.Rext / 25.0 # For readibility model = gmsh.model factory = model.geo # Start a new model gmsh.initialize(sys.argv) gmsh.option.setNumber("General.Terminal", int(False)) gmsh.option.setNumber("Geometry.CopyMeshingMethod", 1) gmsh.option.setNumber("Geometry.PointNumbers", 0) gmsh.option.setNumber("Geometry.LineNumbers", 0) gmsh.option.setNumber("Mesh.CharacteristicLengthMin", min(mesh_size_S, mesh_size_R)) gmsh.option.setNumber("Mesh.CharacteristicLengthMax", max(mesh_size_S, mesh_size_R)) model.add("Pyleecan") # build geometry alpha = 0 rotor_list = list() rotor_list.extend(machine.shaft.build_geometry(sym=sym, alpha=alpha)) rotor_list.extend(machine.rotor.build_geometry(sym=sym, alpha=alpha)) stator_list = list() stator_list.extend(machine.stator.build_geometry(sym=sym, alpha=alpha)) # set origin oo = factory.addPoint(0, 0, 0, 0, tag=-1) gmsh_dict = { 0: { "tag": 0, "label": "origin", "with_holes": False, 1: { "tag": 0, "n_elements": 1, "bc_name": None, "begin": {"tag": oo, "coord": complex(0.0, 0.0)}, "end": {"tag": None, "coord": None}, "cent": {"tag": None, "coord": None}, "arc_angle": None, "line_angle": None, }, } } nsurf = 0 # number of surfaces if not is_lam_only_S: for surf in rotor_list: nsurf += 1 #print(surf.label) gmsh_dict.update( { nsurf: { "tag": None, "label": surface_label.get(surf.label, "UNKNOWN"), } } ) if "Lamination_Rotor" in surf.label: gmsh_dict[nsurf]["with_holes"] = True lam_rotor_surf_id = nsurf else: gmsh_dict[nsurf]["with_holes"] = False # comp. number of elements on the lines & override by user values in case mesh_dict = surf.comp_mesh_dict(element_size=mesh_size_R) if user_mesh_dict: # check if dict is not None nor empty mesh_dict.update(user_mesh_dict) # add all lines of the current surface to the gmsh_dict for line in surf.get_lines(): # When symmetry is 1 the shaft surface is substrtacted from Rotor Lam instead if sym == 1 and line.label == "Lamination_Rotor_Yoke_Radius_Int": continue n_elem = mesh_dict.get(line.label) n_elem = n_elem if n_elem is not None else 0 bc_name = get_boundary_condition(line, boundary_prop) # Gmsh built-in engine does not allow arcs larger than 180deg # so arcs are split into two if ( isinstance(line, Arc) and abs(line.get_angle() * 180.0 / cmath.pi) >= 180.0 ): rot_dir = 1 if line.is_trigo_direction == True else -1 arc1 = Arc2( begin=line.get_begin(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) arc2 = Arc2( begin=arc1.get_end(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) for arc in [arc1, arc2]: _add_line_to_dict( geo=factory, line=arc, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size_R, n_elements=n_elem, bc=bc_name, ) elif isinstance(line, Arc) and ( abs(line.get_angle() * 180.0 / cmath.pi) <= tol ): # Don't draw anything, this is a circle and usually is repeated ? pass else: _add_line_to_dict( geo=factory, line=line, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size_R, n_elements=n_elem, bc=bc_name, ) lam_and_holes = list() ext_lam_loop = None rotor_cloops = list() # loop though all (surface) entries of the rotor lamination for s_data in gmsh_dict.values(): lloop = [] # skip this surface dataset if it is the origin if s_data["label"] == "origin": continue # build a lineloop of the surfaces lines for lvalues in s_data.values(): if type(lvalues) is not dict: continue lloop.extend([lvalues["tag"]]) cloop = factory.addCurveLoop(lloop) if "MAGNET" in s_data["label"]: rotor_cloops.extend([cloop]) # search for the holes to substract from rotor lam if "ROTOR_LAM" in s_data["label"]: ext_lam_loop = cloop else: # MachineSIPSM does not have holes in rotor lam # only shaft is taken out if symmetry is one if isinstance(machine, MachineSIPMSM): if sym == 1 and s_data["label"] == "SHAFT": lam_and_holes.extend([cloop]) else: if sym == 1: lam_and_holes.extend([cloop]) elif s_data["label"] != "SHAFT": lam_and_holes.extend([cloop]) else: pass # Shaft, magnets and magnet pocket surfaces are created if not is_lam_only_R: s_data["tag"] = factory.addPlaneSurface([cloop], tag=-1) pg = model.addPhysicalGroup(2, [s_data["tag"]]) model.setPhysicalName(2, pg, s_data["label"]) # Finally rotor lamination is built if ext_lam_loop is not None: lam_and_holes.insert(0, ext_lam_loop) gmsh_dict[lam_rotor_surf_id]["tag"] = factory.addPlaneSurface( lam_and_holes, tag=-1 ) pg = model.addPhysicalGroup(2, [gmsh_dict[lam_rotor_surf_id]["tag"]]) model.setPhysicalName(2, pg, gmsh_dict[lam_rotor_surf_id]["label"]) # rotor_cloops = lam_and_holes # store rotor dict rotor_dict = gmsh_dict.copy() # init new dict for stator gmsh_dict = { 0: { "tag": 0, "label": "origin", "with_holes": False, 1: { "tag": 0, "n_elements": 1, "bc_name": None, "begin": {"tag": oo, "coord": complex(0.0, 0.0)}, "end": {"tag": None, "coord": None}, "cent": {"tag": None, "coord": None}, }, } } # nsurf = 0 if not is_lam_only_R: stator_cloops = [] for surf in stator_list: nsurf += 1 gmsh_dict.update( { nsurf: { "tag": None, "label": surface_label.get(surf.label, "UNKNOWN"), } } ) if surf.label.find("Lamination_Stator") != -1: gmsh_dict[nsurf]["with_holes"] = True else: gmsh_dict[nsurf]["with_holes"] = False # comp. number of elements on the lines & override by user values in case mesh_dict = surf.comp_mesh_dict(element_size=mesh_size_S) if user_mesh_dict: # check if dict is not None nor empty mesh_dict.update(user_mesh_dict) # add all lines of the current surface to the gmsh_dict for line in surf.get_lines(): n_elem = mesh_dict.get(line.label) n_elem = n_elem if n_elem is not None else 0 bc_name = get_boundary_condition(line, boundary_prop) # Gmsh built-in engine does not allow arcs larger than 180deg # so arcs are split into two if ( isinstance(line, Arc) and abs(line.get_angle() * 180.0 / cmath.pi) >= 180.0 ): rot_dir = 1 if line.is_trigo_direction == True else -1 arc1 = Arc2( begin=line.get_begin(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) arc2 = Arc2( begin=arc1.get_end(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) for arc in [arc1, arc2]: _add_line_to_dict( geo=factory, line=arc, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size_S, n_elements=n_elem, bc=bc_name, ) else: _add_line_to_dict( geo=factory, line=line, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size_S, n_elements=n_elem, bc=bc_name, ) for s_data in gmsh_dict.values(): lloop = [] # skip this surface dataset if it is the origin if s_data["label"] == "origin": continue # build a lineloop of the surfaces lines for lvalues in s_data.values(): if type(lvalues) is not dict: continue lloop.extend([lvalues["tag"]]) cloop = factory.addCurveLoop(lloop) stator_cloops.append(cloop) # Winding surfaces are created if (s_data["label"].find("STATOR_LAM") != -1) or (not is_lam_only_S): s_data["tag"] = factory.addPlaneSurface([cloop], tag=-1) pg = model.addPhysicalGroup(2, [s_data["tag"]]) model.setPhysicalName(2, pg, s_data["label"]) # stator_dict = gmsh_dict.copy() gmsh_dict.update(rotor_dict) if is_sliding_band and (not is_lam_only_R) and (not is_lam_only_S): sb_list = get_sliding_band(sym=sym, machine=machine) else: sb_list = [] # Default sliding mesh element size mesh_size = 2.0 * cmath.pi * machine.rotor.Rext / 360.0 # nsurf = 0 for surf in sb_list: nsurf += 1 gmsh_dict.update( { nsurf: { "tag": None, "label": surface_label.get(surf.label, "UNKNOWN"), } } ) for line in surf.get_lines(): n_elem = mesh_dict.get(line.label) n_elem = n_elem if n_elem is not None else 0 bc_name = get_boundary_condition(line, boundary_prop) # Gmsh built-in engine does not allow arcs larger than 180deg # so arcs are split into two if ( isinstance(line, Arc) and abs(line.get_angle() * 180.0 / cmath.pi) >= 180.0 ): rot_dir = 1 if line.is_trigo_direction == True else -1 arc1 = Arc2( begin=line.get_begin(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) arc2 = Arc2( begin=arc1.get_end(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) for arc in [arc1, arc2]: _add_agline_to_dict( geo=factory, line=arc, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, ) else: _add_agline_to_dict( geo=factory, line=line, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, ) for s_data in gmsh_dict.values(): lloop = [] # skip this surface dataset if it is the origin if s_data["label"] == "origin" or not ( "AG_" in s_data["label"] or "SB_" in s_data["label"] ): continue # build a lineloop of the surfaces lines for lvalues in s_data.values(): if type(lvalues) is not dict: continue lloop.extend([lvalues["tag"]]) if lloop: cloop = factory.addCurveLoop(lloop) if "AG_INT" in s_data["label"] and isinstance(machine, MachineSIPMSM): s_data["tag"] = factory.addPlaneSurface([cloop] + rotor_cloops, tag=-1) else: s_data["tag"] = factory.addPlaneSurface([cloop], tag=-1) pg = model.addPhysicalGroup(2, [s_data["tag"]]) model.setPhysicalName(2, pg, s_data["label"]) if is_airbox and (not is_lam_only_R) and (not is_lam_only_S): ab_list = get_air_box(sym=sym, machine=machine) else: ab_list = [] # Default airbox mesh element size mesh_size = machine.stator.Rext / 50.0 for surf in ab_list: nsurf += 1 gmsh_dict.update( { nsurf: { "tag": None, "label": surface_label.get(surf.label, "UNKNOWN"), } } ) for line in surf.get_lines(): n_elem = mesh_dict.get(line.label) n_elem = n_elem if n_elem is not None else 0 bc_name = get_boundary_condition(line, boundary_prop) # Gmsh built-in engine does not allow arcs larger than 180deg # so arcs are split into two if ( isinstance(line, Arc) and abs(line.get_angle() * 180.0 / cmath.pi) >= 180.0 ): rot_dir = 1 if line.get_angle() > 0 else -1 arc1 = Arc2( begin=line.get_begin(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) arc2 = Arc2( begin=arc1.get_end(), center=line.get_center(), angle=rot_dir * cmath.pi / 2.0, label=line.label, ) for arc in [arc1, arc2]: _add_line_to_dict( geo=factory, line=arc, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, ) else: _add_line_to_dict( geo=factory, line=line, d=gmsh_dict, idx=nsurf, mesh_size=mesh_size, n_elements=n_elem, bc=bc_name, ) for s_id, s_data in gmsh_dict.items(): lloop = [] if s_id == 0: continue for lvalues in s_data.values(): if s_data["label"].find("AIRBOX") != -1: if type(lvalues) is not dict: continue lloop.extend([lvalues["tag"]]) else: continue if lloop: cloop = factory.addCurveLoop(lloop) s_data["tag"] = factory.addPlaneSurface([cloop], tag=-1) pg = model.addPhysicalGroup(2, [s_data["tag"]]) model.setPhysicalName(2, pg, s_data["label"]) # Set boundary conditions in gmsh lines for propname in boundary_list: bc_id = [] for s_data in gmsh_dict.values(): for lvalues in s_data.values(): if type(lvalues) is not dict: continue if lvalues["bc_name"] == propname: bc_id.extend([abs(lvalues["tag"])]) if bc_id: pg = model.addPhysicalGroup(1, bc_id) model.setPhysicalName(1, pg, propname) # Set all line labels as physical groups if is_set_labels: groups = {} for s_data in gmsh_dict.values(): for lvalues in s_data.values(): if ( type(lvalues) is not dict or "label" not in lvalues or not lvalues["label"] ): continue if lvalues["label"] not in groups.keys(): groups[lvalues["label"]] = [] groups[lvalues["label"]].append(abs(lvalues["tag"])) for label, tags in groups.items(): pg = model.addPhysicalGroup(1, tags) model.setPhysicalName(1, pg, label) factory.synchronize() # save mesh or geo file depending on file extension filename, file_extension = splitext(path_save) if file_extension == ".geo": gmsh.write(filename + ".geo_unrolled") replace(filename + ".geo_unrolled", filename + file_extension) else: gmsh.model.mesh.generate(2) gmsh.write(path_save) #gmsh.fltk.run() # Uncomment to launch Gmsh GUI gmsh.finalize() return gmsh_dict
gmsh.model.geo.addLine(3, 2, 2) gmsh.model.geo.addLine(3, 4, 3) gmsh.model.geo.addLine(4, 1, 4) gmsh.model.geo.addCurveLoop([4, 1, -2, 3], 1) gmsh.model.geo.addPlaneSurface([1], 1) gmsh.model.geo.synchronize() # Add the post-processing view as a new size field: bg_field = gmsh.model.mesh.field.add("PostView") # Apply the view as the current background mesh size field: gmsh.model.mesh.field.setAsBackgroundMesh(bg_field) # In order to compute the mesh sizes from the background mesh only, and # disregard any other size constraints, one can set: gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0) gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0) gmsh.option.setNumber("Mesh.MeshSizeFromCurvature", 0) # See `t10.py' for additional information: background meshes are actually a # particular case of general "mesh size fields". gmsh.model.mesh.generate(2) gmsh.write("t7.msh") # Launch the GUI to see the results: if '-nopopup' not in sys.argv: gmsh.fltk.run() gmsh.finalize()
dims=[0, 1, 2, 3]) # Find homology space bases isomorphic to the previous bases: homology spaces # modulo the non-terminal domain surface, a.k.a the thin cuts. gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag], subdomainTags=[complement_physical_tag], dims=[0, 1, 2, 3]) # Find cohomology space bases isomorphic to the previous bases: cohomology # spaces of the domain modulo the four terminals, a.k.a the thick cuts. gmsh.model.mesh.computeCohomology(domainTags=[domain_physical_tag], subdomainTags=[terminals_physical_tag], dims=[0, 1, 2, 3]) # more examples # gmsh.model.mesh.computeHomology() # gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag]) # gmsh.model.mesh.computeHomology(domainTags=[domain_physical_tag], # subdomainTags=[boundary_physical_tag], # dims=[0,1,2,3]) # Generate the mesh and perform the requested homology computations gmsh.model.mesh.generate(3) # For more information, see M. Pellikka, S. Suuriniemi, L. Kettunen and # C. Geuzaine. Homology and cohomology computation in finite element # modeling. SIAM Journal on Scientific Computing 35(5), pp. 1195-1214, 2013. gmsh.write("t14.msh") gmsh.finalize()
def mesh_bar_gmshapi(name, Lx, Ly, lc, tdim, order=1, msh_file=None, comm=MPI.COMM_WORLD): """ Create mesh of 3d tensile test specimen according to ISO 6892-1:2019 using the Python API of Gmsh. """ # Perform Gmsh work only on rank = 0 if comm.rank == 0: import gmsh # Initialise gmsh and set options gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) gmsh.option.setNumber("Mesh.Algorithm", 6) model = gmsh.model() model.add("Rectangle") model.setCurrent("Rectangle") p0 = model.geo.addPoint(0.0, 0.0, 0, lc, tag=0) p1 = model.geo.addPoint(Lx, 0.0, 0, lc, tag=1) p2 = model.geo.addPoint(Lx, Ly, 0.0, lc, tag=2) p3 = model.geo.addPoint(0, Ly, 0, lc, tag=3) # points = [p0, p1, p2, p3] bottom = model.geo.addLine(p0, p1, tag=0) right = model.geo.addLine(p1, p2, tag=1) top = model.geo.addLine(p2, p3, tag=2) left = model.geo.addLine(p3, p0, tag=3) cloop1 = model.geo.addCurveLoop([bottom, right, top, left]) # surface_1 = model.geo.addPlaneSurface([cloop1]) model.geo.synchronize() surface_entities = [model[1] for model in model.getEntities(tdim)] model.addPhysicalGroup(tdim, surface_entities, tag=5) model.setPhysicalName(tdim, 5, "Rectangle surface") # Set mesh size via points # gmsh.model.mesh.setSize(points, lc) # heuristic # gmsh.model.mesh.optimize("Netgen") # Set geometric order of mesh cells gmsh.model.mesh.setOrder(order) # Define physical groups for subdomains (! target tag > 0) # domain = 1 # gmsh.model.addPhysicalGroup(tdim, [v[1] for v in volumes], domain) # gmsh.model.setPhysicalName(tdim, domain, 'domain') gmsh.model.addPhysicalGroup(tdim - 1, [3], tag=6) gmsh.model.setPhysicalName(tdim - 1, 6, "left") gmsh.model.addPhysicalGroup(tdim - 1, [1], tag=7) gmsh.model.setPhysicalName(tdim - 1, 7, "right") gmsh.model.addPhysicalGroup(tdim - 1, [2], tag=8) gmsh.model.setPhysicalName(tdim - 1, 8, "top") gmsh.model.addPhysicalGroup(tdim - 1, [0], tag=9) gmsh.model.setPhysicalName(tdim - 1, 9, "bottom") model.mesh.generate(tdim) # Define physical groups for interfaces (! target tag > 0) # surface = 1 # gmsh.model.addPhysicalGroup(tdim - 1, [s[1] for s in surfaces], surface) # gmsh.model.setPhysicalName(tdim - 1, surface, 'surface') """surface_grip_left = 2 gmsh.model.addPhysicalGroup(tdim - 1, [s0], surface_grip_left) gmsh.model.setPhysicalName(tdim - 1, surface_grip_left, 'surface_grip_left') surface_grip_right = 3 gmsh.model.addPhysicalGroup(tdim - 1, [s1], surface_grip_right) gmsh.model.setPhysicalName(tdim - 1, surface_grip_right, 'surface_grip_right') surface_plane_left = 4 gmsh.model.addPhysicalGroup(tdim - 1, [s2], surface_plane_left) gmsh.model.setPhysicalName(tdim - 1, surface_plane_left, 'surface_plane_left') surface_plane_right = 5 gmsh.model.addPhysicalGroup(tdim - 1, [s3], surface_plane_right) gmsh.model.setPhysicalName(tdim - 1, surface_plane_right, 'surface_plane_right')""" # Optional: Write msh file if msh_file is not None: gmsh.write(msh_file) # gmsh.write(name + ".step") return gmsh.model if comm.rank == 0 else None, tdim
def create_stokes_mesh(res): """ Creates a mesh containing a circular obstacle. Inlet marker (left): 1 Oulet marker (right): 2 Wall marker (top/bottom): 3 Obstacle marker: 4 """ try: import gmsh import meshio except ImportError: print("meshio and/or gmsh not installed. Requires the non-python libraries:\n", "- libglu1\n - libxcursor-dev\n - libxinerama1\n And Python libraries:\n" " - h5py", " (pip3 install --no-cache-dir --no-binary=h5py h5py)\n", "- gmsh \n - meshio") exit(1) gmsh.initialize() # Create geometry c = gmsh.model.occ.addPoint(c_x, c_y, 0) p1 = gmsh.model.occ.addPoint(c_x - r_x, c_y, 0) p2 = gmsh.model.occ.addPoint(c_x, c_y + r_x, 0) p3 = gmsh.model.occ.addPoint(c_x + r_x, c_y, 0) p4 = gmsh.model.occ.addPoint(c_x, c_y - r_x, 0) arc_1 = gmsh.model.occ.addEllipseArc(p1, c, p2, p2) arc_2 = gmsh.model.occ.addEllipseArc(p2, c, p3, p3) arc_3 = gmsh.model.occ.addEllipseArc(p3, c, p4, p4) arc_4 = gmsh.model.occ.addEllipseArc(p4, c, p1, p1) obstacle_loop = gmsh.model.occ.addCurveLoop([arc_1, arc_2, arc_3, arc_4]) rectangle = gmsh.model.occ.addRectangle(0, 0, 0, L, H) gmsh.model.occ.synchronize() obstacle_loop = gmsh.model.occ.addCurveLoop([arc_1, arc_2, arc_3, arc_4]) exterior_boundary = gmsh.model.getBoundary([(2, rectangle)]) obstacle = gmsh.model.occ.addPlaneSurface([obstacle_loop]) fluid = gmsh.model.occ.cut([(2, rectangle)], [(2, obstacle)]) gmsh.model.occ.synchronize() # Create physical markers lines = gmsh.model.occ.getEntities(dim=1) walls = [] obstacles = [] for line in lines: com = gmsh.model.occ.getCenterOfMass(line[0], line[1]) if np.allclose(com, [0, H / 2, 0]): gmsh.model.addPhysicalGroup(line[0], [line[1]], inflow_marker) gmsh.model.setPhysicalName(line[0], inflow_marker, "Fluid inlet") elif np.allclose(com, [L, H / 2, 0]): gmsh.model.addPhysicalGroup(line[0], [line[1]], outflow_marker) gmsh.model.setPhysicalName(line[0], outflow_marker, "Fluid outlet") elif np.allclose(com, [L / 2, 0, 0]) or np.allclose(com, [L / 2, H, 0]): walls.append(line[1]) else: obstacles.append(line[1]) gmsh.model.addPhysicalGroup(1, walls, wall_marker) gmsh.model.setPhysicalName(1, wall_marker, "Walls") gmsh.model.addPhysicalGroup(1, obstacles, obstacle_marker) gmsh.model.setPhysicalName(1, obstacle_marker, "Obstacle") # Specify mesh resolution gmsh.model.mesh.field.add("Distance", 1) gmsh.model.mesh.field.setNumbers(1, "EdgesList", obstacles) gmsh.model.mesh.field.add("Threshold", 2) gmsh.model.mesh.field.setNumber(2, "IField", 1) gmsh.model.mesh.field.setNumber(2, "LcMin", res) gmsh.model.mesh.field.setNumber(2, "LcMax", 4 * res) gmsh.model.mesh.field.setNumber(2, "DistMin", 0.5 * r_x) gmsh.model.mesh.field.setNumber(2, "DistMax", 2 * r_x) gmsh.model.mesh.field.add("Min", 5) gmsh.model.mesh.field.setNumbers(5, "FieldsList", [2]) gmsh.model.mesh.field.setAsBackgroundMesh(5) gmsh.model.mesh.generate(2) gmsh.model.addPhysicalGroup(fluid[0][0][0], [fluid[0][0][1]], 12) gmsh.write("mesh.msh") # Read in and convert mesh to msh msh = meshio.read("mesh.msh") line_cells = [] for cell in msh.cells: if cell.type == "triangle": triangle_cells = cell.data elif cell.type == "line": if len(line_cells) == 0: line_cells = cell.data else: line_cells = np.vstack([line_cells, cell.data]) line_data = [] for key in msh.cell_data_dict["gmsh:physical"].keys(): if key == "line": if len(line_data) == 0: line_data = msh.cell_data_dict["gmsh:physical"][key] else: line_data = np.vstack([line_data, msh.cell_data_dict["gmsh:physical"][key]]) elif key == "triangle": triangle_data = msh.cell_data_dict["gmsh:physical"][key] triangle_mesh = meshio.Mesh(points=msh.points[:, :2], cells={"triangle": triangle_cells}, cell_data={"name_to_read": [triangle_data]}) line_mesh = meshio.Mesh(points=msh.points[:, :2], cells=[("line", line_cells)], cell_data={"name_to_read": [line_data]}) meshio.write("mesh.xdmf", triangle_mesh) meshio.write("mf.xdmf", line_mesh)
# Assign a mesh size to all the points: gmsh.model.mesh.setSize(gmsh.model.getEntities(0), lcar1) # Override this constraint on the points of the five spheres: gmsh.model.mesh.setSize(gmsh.model.getBoundary(holes, False, False, True), lcar3) # Select the corner point by searching for it geometrically: eps = 1e-3 ov = gmsh.model.getEntitiesInBoundingBox(0.5 - eps, 0.5 - eps, 0.5 - eps, 0.5 + eps, 0.5 + eps, 0.5 + eps, 0) gmsh.model.mesh.setSize(ov, lcar2) gmsh.model.mesh.generate(3) gmsh.write("t16.msh") # Additional examples created with the OpenCASCADE geometry kernel are available # in `t18.py', `t19.py' and `t20.py', as well as in the `demos/api' directory. # Inspect the log: log = gmsh.logger.get() print("Logger has recorded " + str(len(log)) + " lines") gmsh.logger.stop() # Show the GUI: # gmsh.fltk.run() gmsh.finalize()
if t > times[i]: while times[i] < t: i += 1 alpha = (t-times[i-1])/(times[i]-times[i-1]) print(t,i,alpha) for j in range(len(temps[i])): temp_inst[j] = [temps[i-1][j][0] + alpha * (temps[i][j][0] - temps[i-1][j][0])] gmsh.view.addModelData(view_inst, step, "", kind, tags, temp_inst, t) step += 1 t += dt gmsh.view.remove(0) gmsh.fltk.initialize() for i in range(step): print(i) gmsh.option.setNumber("View[0].TimeStep", i) gmsh.fltk.update() gmsh.write("temp-cylinder-smooth-%03d.png" % i) gmsh.finalize() print("all frames dumped, now run") print("ffmpeg -y -framerate 20 -f image2 -i temp-cylinder-smooth-%03d.png temp-cylinder-smooth.mp4") print("to get a video")
# gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0) # gmsh.option.setNumber("Mesh.MeshSizeFromPoints", 0) # gmsh.model.mesh.field.setAsBackgroundMesh(3) # We can constraint the min and max element sizes to stay within reasonnable values gmsh.option.setNumber("Mesh.MeshSizeMin", Lmesh) gmsh.option.setNumber("Mesh.MeshSizeMax", Lmesh) # Generate 2D mesh mesh = gmsh.model.mesh.generate(2) # Launch the GUI to see the results: gmsh.fltk.run() # Write mesh into a meshio format gmsh.write("single_micro-trench.msh") # close gmsh session gmsh.finalize() # Load geometry g = GeomSetup('single_micro-trench.msh', Verbose=True) # Show existing groups g.ShowGroups() # Plot mesh for some groups g.Plot() # Zoom on the plot (the zoom function for 3D axis in matplotlib 3.3.3 is not working so it has to be done manually) g.SetAxisLim(-Lxbc * 2, Lxbc * 2)
# entities have a "parent", which allows to link the partitioned entity with the # entity it is a subset of. There are other options to govern how physical # groups are treated (Mesh.PartitionCreatePhysicals), and if ghost cells should # be created (Mesh.PartitionCreateGhostCells). if partition_using_metis: gmsh.model.mesh.partition(3) else: gmsh.plugin.setNumber("SimplePartition", "NumSlicesX", 3.) gmsh.plugin.run("SimplePartition") # write the partitioned mesh to disk? if write_file: # create one file per partition? if write_one_file_per_partition: gmsh.option.setNumber("Mesh.PartitionSplitMeshFiles", 1) gmsh.write("partition.msh") # iterate over partitioned entities and print some info entities = gmsh.model.getEntities() for e in entities: partitions = gmsh.model.getPartitions(e[0], e[1]) if len(partitions): print("Entity " + str(e) + " of type " + gmsh.model.getType(e[0], e[1])) print(" - Partition(s): " + str(partitions)) print(" - Parent: " + str(gmsh.model.getParent(e[0], e[1]))) print(" - Boundary: " + str(gmsh.model.getBoundary([e]))) gmsh.fltk.run() gmsh.finalize()
node_coords = np.split(node_coords, len(node_coords) / 3.0) # Getting array of removed nodes to update centerline data _, common_idx_init, _ = np.intersect1d(initial_node_tags, node_tags, return_indices=True) removed_node_tags = np.array([]) # Tags of remote nodes removed_idx_init = np.array( []) # Indices of these removed nodes in the initial array if len(node_tags) != len(initial_node_tags): # Some nodes have been removed removed_node_tags = np.delete(initial_node_tags, common_idx_init) _, removed_idx_init, _ = np.intersect1d(initial_node_tags, removed_node_tags, return_indices=True) # Writing updated mesh gmsh.write(output_filename + "_centerline_mesh-noduplicates.msh") gmsh.finalize() # Converting to xdmf meshio._cli.convert([ output_filename + "_centerline_mesh-noduplicates.msh", output_filename + "_centerline_mesh.xdmf", "--input-format", "gmsh", "--output-format", "xdmf" ]) ### ------------------------------------------------------------- ### ### ------- Update centerline data (mesh without duplicates) ---- ### if len(removed_node_tags) != 0: radius_data = np.load(output_filename + "_centerline_max_radius.npy") radius_data = np.delete(radius_data, removed_idx_init) np.save(path.join(output_filename + "_centerline_max_radius.npy"), radius_data)
TagBox0 = 10 TagBox1 = 11 TagDiMES = 2000 # Create simulation bounding box s0 = gmsh.model.occ.getEntities(2) TagBox0 = gmsh.model.occ.addRectangle(xBox - L, yBox - L, zBox, 2 * L, 2 * L, TagBox0) TagBox1 = gmsh.model.occ.addRectangle(xBox - L, yBox - L, zBox + L, 2 * L, 2 * L, TagBox1) #gmsh.model.occ.remove([(3, TagBox0)]) # Synchronize necessary before mesh setup and generation gmsh.model.occ.synchronize() # We can constraint the min and max element sizes to stay within reasonnable values gmsh.option.setNumber("Mesh.MeshSizeMin", Lmesh) gmsh.option.setNumber("Mesh.MeshSizeMax", Lmesh) # Generate 2D mesh gmsh.model.mesh.generate(2) # Launch the GUI to see the results: gmsh.fltk.run() # Write mesh into a meshio format gmsh.write("large_box.msh") # close gmsh session. Comment when working on the geometry. gmsh.finalize()
def mesh_annulus_gmshapi(name="annulus", iR=0.5, oR=3.0, nR=21, nT=16, x0=0.0, y0=0.0, do_quads=False, progression=1.0, order=1, msh_file=None, comm=MPI.COMM_WORLD): """ Create mesh of 2d annulus using the Python API of Gmsh. """ px, py, pz = x0, y0, 0.0 # center point ax, ay, az = 0.0, 0.0, 1.0 # rotation axis tdim = 2 # target topological dimension # Perform Gmsh work only on rank = 0 if comm.rank == 0: import gmsh # Initialise gmsh and set options gmsh.initialize() gmsh.option.setNumber("General.Terminal", 1) # Add model under given name gmsh.model.add(name) # Create points and line p0 = gmsh.model.geo.addPoint(iR + x0, 0.0 + y0, 0.0) p1 = gmsh.model.geo.addPoint(oR + x0, 0.0 + y0, 0.0) l0 = gmsh.model.geo.addLine(p0, p1) # Create sectors by revolving the cross-sectional line s0 = gmsh.model.geo.revolve([(1, l0)], px, py, pz, ax, ay, az, angle=gmsh.pi / 2, numElements=[nT], recombine=do_quads) s1 = gmsh.model.geo.revolve([s0[0]], px, py, pz, ax, ay, az, angle=gmsh.pi / 2, numElements=[nT], recombine=do_quads) s2 = gmsh.model.geo.revolve([s1[0]], px, py, pz, ax, ay, az, angle=gmsh.pi / 2, numElements=[nT], recombine=do_quads) s3 = gmsh.model.geo.revolve([s2[0]], px, py, pz, ax, ay, az, angle=gmsh.pi / 2, numElements=[nT], recombine=do_quads) # Sync gmsh.model.geo.synchronize() # Define physical groups for subdomains (! target tag > 0) domain = 1 gmsh.model.addPhysicalGroup(tdim, [s0[1][1], s1[1][1], s2[1][1], s3[1][1]], domain) # all sectors gmsh.model.setPhysicalName(tdim, domain, 'domain') # Determine boundaries bs0 = gmsh.model.getBoundary(s0) bs1 = gmsh.model.getBoundary(s1) bs2 = gmsh.model.getBoundary(s2) bs3 = gmsh.model.getBoundary(s3) # Define physical groups for interfaces (! target tag > 0); boundary idx 4 and idx 5 obtained by inspection ring_inner = 1 gmsh.model.addPhysicalGroup( tdim - 1, [bs0[4][1], bs1[4][1], bs2[4][1], bs3[4][1]], ring_inner) gmsh.model.setPhysicalName(tdim - 1, ring_inner, 'ring_inner') ring_outer = 2 gmsh.model.addPhysicalGroup( tdim - 1, [bs0[5][1], bs1[5][1], bs2[5][1], bs3[5][1]], ring_outer) gmsh.model.setPhysicalName(tdim - 1, ring_outer, 'ring_outer') # Sync gmsh.model.geo.synchronize() # Set refinement in radial direction gmsh.model.mesh.setTransfiniteCurve(l0, numNodes=nR, meshType="Progression", coef=progression) # Ensure union jack meshing for triangular elements if not do_quads: gmsh.model.mesh.setTransfiniteSurface(s0[1][1], arrangement="Alternate") gmsh.model.mesh.setTransfiniteSurface(s1[1][1], arrangement="Alternate") gmsh.model.mesh.setTransfiniteSurface(s2[1][1], arrangement="Alternate") gmsh.model.mesh.setTransfiniteSurface(s3[1][1], arrangement="Alternate") # Generate the mesh gmsh.model.mesh.generate() # Set geometric order of mesh cells gmsh.model.mesh.setOrder(order) # Optional: Write msh file if msh_file is not None: gmsh.write(msh_file) return gmsh.model if comm.rank == 0 else None, tdim
def createGeometryAndMesh(): # Clear all models and merge an STL mesh that we would like to remesh (from # the parent directory): gmsh.clear() path = os.path.dirname(os.path.abspath(__file__)) gmsh.merge(os.path.join(path, os.pardir, 't13_data.stl')) # We first classify ("color") the surfaces by splitting the original surface # along sharp geometrical features. This will create new discrete surfaces, # curves and points. # Angle between two triangles above which an edge is considered as sharp, # retrieved from the ONELAB database (see below): angle = gmsh.onelab.getNumber('Parameters/Angle for surface detection')[0] # For complex geometries, patches can be too complex, too elongated or too # large to be parametrized; setting the following option will force the # creation of patches that are amenable to reparametrization: forceParametrizablePatches = gmsh.onelab.getNumber( 'Parameters/Create surfaces guaranteed to be parametrizable')[0] # For open surfaces include the boundary edges in the classification # process: includeBoundary = True # Force curves to be split on given angle: curveAngle = 180 gmsh.model.mesh.classifySurfaces(angle * math.pi / 180., includeBoundary, forceParametrizablePatches, curveAngle * math.pi / 180.) # Create a geometry for all the discrete curves and surfaces in the mesh, by # computing a parametrization for each one gmsh.model.mesh.createGeometry() # Note that if a CAD model (e.g. as a STEP file, see `t20.py') is available # instead of an STL mesh, it is usually better to use that CAD model instead # of the geometry created by reparametrizing the mesh. Indeed, CAD # geometries will in general be more accurate, with smoother # parametrizations, and will lead to more efficient and higher quality # meshing. Discrete surface remeshing in Gmsh is optimized to handle dense # STL meshes coming from e.g. imaging systems, where no CAD is available; it # is less well suited for the poor quality STL triangulations (optimized for # size, with e.g. very elongated triangles) that are usually generated by # CAD tools for e.g. 3D printing. # Create a volume from all the surfaces s = gmsh.model.getEntities(2) l = gmsh.model.geo.addSurfaceLoop([s[i][1] for i in range(len(s))]) gmsh.model.geo.addVolume([l]) gmsh.model.geo.synchronize() # We specify element sizes imposed by a size field, just because we can :-) f = gmsh.model.mesh.field.add("MathEval") if gmsh.onelab.getNumber('Parameters/Apply funny mesh size field?')[0]: gmsh.model.mesh.field.setString(f, "F", "2*Sin((x+y)/5) + 3") else: gmsh.model.mesh.field.setString(f, "F", "4") gmsh.model.mesh.field.setAsBackgroundMesh(f) gmsh.model.mesh.generate(3) gmsh.write('t13.msh')
def main(): arguments = docopt(__doc__) msh_file = arguments['<msh>'] centroid_file = arguments['<centroid>'] out = arguments['<out_prefix>'] radius = arguments['--radius'] or 25 distance = arguments['--distance'] or 1 #Try every alternative of SURF_HEAD n_tag, n_coord, tri = None, None, None for i, s in enumerate(SURF_HEAD): try: n_tag, n_coord, _ = gl.load_gmsh_nodes(msh_file, s) _, _, tri = gl.load_gmsh_elems(msh_file, s) except ValueError: if i == len(SURF_HEAD): raise else: continue else: break tri = tri[0] tri = tri.reshape((len(tri) // 3, -1)) #Load in centroid voxel centroid = np.genfromtxt(centroid_file) #Get minimum euclidean distance eudist = np.linalg.norm(n_coord - centroid, axis=1) min_ind = np.argmin(eudist) #Capture nodes within spherical ROI head_centroid_to_all = np.linalg.norm(n_coord - n_coord[min_ind], axis=1) search_inds = np.where(head_centroid_to_all < radius) #Get relevant triangles to vertices vert_list = n_tag[search_inds] vert_coords = n_coord[search_inds] t_arr = gl.get_relevant_triangles(vert_list, tri) rel_ind = np.where(t_arr > 0) t_rel = tri[rel_ind[0], :] #Get triangle to index mapping u_val = np.unique(t_rel) u_ind = np.arange(0, u_val.shape[0]) #Map each triangle to its index sort_map = {v: i for v, i in zip(u_val, u_ind)} map_func = np.vectorize(lambda x: sort_map[x]) mapped_trigs = map_func(t_rel) rel_verts = np.where(np.isin(n_tag, u_val)) rel_verts_coords = n_coord[rel_verts, :][0] #Compute vertex normals norm_arr = gl.get_vert_norms(mapped_trigs, rel_verts_coords) #Dilate v_norm = np.mean(norm_arr, axis=0) dil_coords = vert_coords + distance * v_norm #Write dilated vertices and mean normal to file np.save(out + "_dilated_coords.npy", dil_coords) np.save(out + "_mean_norm.npy", v_norm) #Generate param surf dil_faces_ind = gl.get_subset_triangles(vert_list, t_rel) dil_faces = t_rel[np.where(dil_faces_ind)].flatten( order='C') + vert_list.max() dil_faces = list(dil_faces) dil_verts = vert_list + vert_list.max() dil_coords = dil_coords.flatten() gmsh.initialize() gmsh.model.add('param_surf') tag = gmsh.model.addDiscreteEntity(2, 2001) gmsh.model.mesh.setNodes(2, tag, nodeTags=dil_verts, coord=dil_coords) gmsh.model.mesh.setElements( 2, tag, [2], elementTags=[range(1, len(dil_faces) // 3 + 1)], nodeTags=[dil_faces]) gmsh.write(out + "_param_surf.msh") gmsh.finalize()
import sys gmsh.initialize(sys.argv) gmsh.option.setNumber("General.Terminal", 1) gmsh.model.add("test"); # add discrete surface with tag 1 gmsh.model.addDiscreteEntity(2, 1) # add 4 mesh nodes gmsh.model.mesh.setNodes(2, 1, [1, 2, 3, 4], # node tags: 1, 2, 3, and 4 [0., 0., 0., # coordinates of node 1 1., 0., 0., # coordinates of node 2 1., 1., 0., # ... 0., 1., 0.]) # add 2 triangles gmsh.model.mesh.setElements(2, 1, [2], # single type : 3-node triangle [[1, 2]], # triangle tags: 1 and 2 [[1, 2, 3, # triangle 1: nodes 1, 2, 3 1, 3, 4]]) # triangle 2: nodes 1, 3, 4 # export the mesh ; use explore.py to read and examine the mesh gmsh.write("test.msh") gmsh.finalize()
factory.addPlaneSurface([1],6) factory.synchronize() ptag = model.addPhysicalGroup(1,[1,2,3,4]) ent = model.getEntitiesForPhysicalGroup(1,ptag) print("new physical group ",ptag,":",ent, type(ent)) model.addPhysicalGroup(2,[6]) print(gmsh.option.getString("General.BuildOptions")) print(gmsh.option.getNumber("Mesh.Algorithm")) gmsh.option.setNumber("Mesh.Algorithm", 3.0) print(gmsh.option.getNumber("Mesh.Algorithm")) model.mesh.generate(2) gmsh.write("square.msh") print("Entities") entities = model.getEntities() for e in entities : print("entity ",e) types,tags,nodes = model.mesh.getElements(e[0],e[1]) for i in range(len(types)): print("type ", types[i]) print("tags : ", list(tags[i])) print("nodes : ", list(nodes[i])) if e[0] == [2] and e[1] == 6 : model.mesh.setElements(e[0],e[1],types,[tags[0][:10]],[nodes[0][:30]]) gmsh.write("mesh_truncated.msh") print("Nodes")
factory.addCircleArc(21,20,24, 16) factory.addCircleArc(24,20,19, 17) factory.addCircleArc(18,23,25, 18) factory.addCircleArc(25,23,22, 19) factory.addLine(21,22, 20) factory.addCurveLoop([17,-15,18,19,-20,16], 21) factory.addPlaneSurface([21], 22) factory.addCurveLoop([11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10], 23) # A surface with one hole is specified using 2 curve loops: factory.addPlaneSurface([23,21], 24) # FIXME: this will be implemented through the gmshView API # View "comments" { # T2(10, -10, 0){ StrCat("Created on ", Today, " with Gmsh") }; # T3(0, 0.11, 0, TextAttributes("Align", "Center", "Font", "Helvetica")){ "Hole" }; # T3(0, 0.09, 0, TextAttributes("Align", "Center")){ "file://[email protected]" }; # T3(-0.01, 0.09, 0, 0){ "file://[email protected],0,0,1,0,1,0" }; # T3(0, 0.12, 0, TextAttributes("Align", "Center")){ "file://[email protected]#" }; # T2(350, -7, 0){ "file://image.png@20x0" }; # }; factory.synchronize() model.mesh.generate(2) gmsh.write("t4.msh") gmsh.finalize()