16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, 37,42,44,43,52,57,59,58] mesh3D = mc.MEDCouplingUMesh("mesh3D",3); mesh3D.allocateCells(18); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[110:118]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[228:236]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(mc.NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(mc.NORM_HEXA8,conn[346:354]); myCoords = mc.DataArrayDouble(coords,60,3); myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) mesh3D.setCoords(myCoords); mesh3D.orientCorrectlyPolyhedrons() mesh3D.sortCellsInMEDFileFrmt() mesh3D.checkConsistencyLight() renum = mc.DataArrayInt(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) mesh3D.renumberNodes(renum,60) # Scale coordinates from meters to centimeters mesh3D.getCoords()[:] *= 100. mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) # Identify unique Z values zLev = mesh3D.getCoords()[:,2] zLev = zLev.getDifferentValues(1e-12) zLev.sort() # Extract cells from a given Z level - Solution 1 tmp,cellIdsSol1 = mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) # Idem - Solution 2 bary = mesh3D.computeCellCenterOfMass() baryZ = bary[:,2] cellIdsSol2 = baryZ.findIdsInRange(zLev[1],zLev[2]) # Idem - Solution 3
def mesh_cube_with_cuboids(xmin, xmax, nx, ymin, ymax, ny, zmin, zmax, nz, mesh_name="cubeWithCuboids"): print "Meshing a cube with cuboids nx=", nx, "ny=", ny, "nz=", nz mesh = create3DGrid(xmin, xmax, nx, ymin, ymax, ny, zmin, zmax, nz, mesh_name="Mesh_cube_with_cuboids") myMesh = mesh.buildUnstructured() #--------------- Boundary groups -----------------# # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_2d = myMesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 barycenters = mesh_2d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] ids_front = [] ids_back = [] for i, coord in enumerate(barycenters): x, y, z = coord if abs(y - ymin) < tol: ids_left.append(i) elif abs(y - ymax) < tol: ids_right.append(i) elif abs(z - zmin) < tol: ids_bottom.append(i) elif abs(z - zmax) < tol: ids_top.append(i) elif abs(x - xmin) < tol: ids_back.append(i) elif abs(x - xmax) < tol: ids_front.append(i) else: raise ValueError( "Pb with boundary construction : barycenter does not belong to any border group" ) arr_left = mc.DataArrayInt(ids_left) arr_right = mc.DataArrayInt(ids_right) arr_bottom = mc.DataArrayInt(ids_bottom) arr_top = mc.DataArrayInt(ids_top) arr_front = mc.DataArrayInt(ids_front) arr_back = mc.DataArrayInt(ids_back) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") arr_front.setName("Front") arr_back.setName("Back") # Trie les cellules par type conformément à la convention MED fichier o2n = myMesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, myMesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_2d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) meshMEDFile.addGroup(-1, arr_back) meshMEDFile.addGroup(-1, arr_front) # Check that everything is coherent (will throw if not) myMesh.checkConsistencyLight() filename = mesh_name + ".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch
def mesh_rectangle_with_rectangles(xmin, xmax, nx, ymin, ymax, ny, mesh_name="Mesh_rectangle_with_rectangles"): mesh_dim = 2 dx = (xmax - xmin) / nx dy = (ymax - ymin) / ny mesh = mc.MEDCouplingIMesh(mesh_name, mesh_dim, [nx + 1, ny + 1], [xmin, ymin], [dx, dy]).buildUnstructured() #--------------- Boundary groups -----------------# # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(x - xmin) < tol: ids_left.append(i) elif abs(x - xmax) < tol: ids_right.append(i) elif abs(y - ymin) < tol: ids_bottom.append(i) elif abs(y - ymax) < tol: ids_top.append(i) else: raise ValueError( "Pb with boundary construction : barycenter does not belong to any border group" ) arr_left = mc.DataArrayInt(ids_left) arr_right = mc.DataArrayInt(ids_right) arr_bottom = mc.DataArrayInt(ids_bottom) arr_top = mc.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) # Check that everything is coherent (will throw if not) mesh.checkConsistencyLight() filename = mesh_name + ".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch
for i, coord in enumerate(barycenters): x, y, z = coord if abs(x) < tol: ids_left.append(i) elif abs(x - 1) < tol: ids_right.append(i) elif abs(y) < tol: ids_bottom.append(i) elif abs(y - 1) < tol: ids_top.append(i) elif abs(z) < tol: ids_back.append(i) elif abs(z - 1) < tol: ids_front.append(i) arr_left = MC.DataArrayInt(ids_left) arr_right = MC.DataArrayInt(ids_right) arr_bottom = MC.DataArrayInt(ids_bottom) arr_top = MC.DataArrayInt(ids_top) arr_back = MC.DataArrayInt(ids_back) arr_front = MC.DataArrayInt(ids_front) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") arr_back.setName("Back") arr_front.setName("Front") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt()
def mesh_square_with_cross_triangles(xmin, xmax, nx, ymin, ymax, ny, mesh_name="squareWithCrossTriangles"): print "Meshing a square with cross triangles nx=", nx, "ny=", ny mesh = create2DGrid(xmin, xmax, nx, ymin, ymax, ny, mesh_name="Mesh_rectangle_with_cross_triangles") myQuadMesh = mesh.buildUnstructured() #--------------- Decomposition of each quadrangle into 4 triangles --------------# bary = myQuadMesh.computeCellCenterOfMass() coo = myQuadMesh.getCoords() nT = coo.getNumberOfTuples() coo2 = mc.DataArrayDouble.Aggregate([coo, bary]) # Un QUAD4 est code par [mc.NORM_QUAD4, i1, i2, i3, i4] # On en fait quatre TRI3: # [mc.NORM_TRI3, i1, i2, ib, # mc.NORM_TRI3, i2, i3, ib, # mc.NORM_TRI3, i3, i4, ib, # mc.NORM_TRI3, i4, i1, ib] # # avec ib l'indice du barycentre nCells = myQuadMesh.getNumberOfCells() c, cI = myQuadMesh.getNodalConnectivity( ), myQuadMesh.getNodalConnectivityIndex() cNew, cINew = mc.DataArrayInt(nCells * 16), mc.DataArrayInt(nCells * 4 + 1) # Et hop: cINew.iota() cINew *= 4 for i in range(nCells): blob = c[(cI[i] + 1):cI[i + 1]] # skip type cNew[i * 4 * 4:(i * 4 + 1) * 4] = [mc.NORM_TRI3, blob[0], blob[1], nT + i] cNew[(i * 4 + 1) * 4:(i * 4 + 2) * 4] = [mc.NORM_TRI3, blob[1], blob[2], nT + i] cNew[(i * 4 + 2) * 4:(i * 4 + 3) * 4] = [mc.NORM_TRI3, blob[2], blob[3], nT + i] cNew[(i * 4 + 3) * 4:(i * 4 + 4) * 4] = [mc.NORM_TRI3, blob[3], blob[0], nT + i] myTriMesh = myQuadMesh.deepCopy() myTriMesh.setCoords(coo2) myTriMesh.setConnectivity(cNew, cINew) #--------------- Boundary groups -----------------# # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = myTriMesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(x - xmin) < tol: ids_left.append(i) elif abs(x - xmax) < tol: ids_right.append(i) elif abs(y - ymin) < tol: ids_bottom.append(i) elif abs(y - ymax) < tol: ids_top.append(i) else: raise ValueError( "Pb with boundary construction : barycenter does not belong to any border group" ) arr_left = mc.DataArrayInt(ids_left) arr_right = mc.DataArrayInt(ids_right) arr_bottom = mc.DataArrayInt(ids_bottom) arr_top = mc.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = myTriMesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, myTriMesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) # Check that everything is coherent (will throw if not) myTriMesh.checkConsistencyLight() filename = mesh_name + ".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch
def drawPolarGrid(center_x, center_y, r0, r1, angle0, angle1, n_r, n_theta): """ Build a polar grid, centered at (center_x, center_y), with n_r subdivisions in the radial direction and n_theta subdivisions in the angular direction. The radial coordinates start at r0 and end at r1, and the angular coordinates start at angle0 and end at angle1. Angles should be given in degrees. You can use this script directly in the custom shape catalog. """ if n_r <= 0 or n_theta <= 0: raise ValueError( "Invalid parameter! Number of grid steps n_r and n_theta must be positive" ) if r0 >= r1: raise ValueError( "Invalid parameter r0<r1 ! Start radius must be smaller than end radius" ) if angle0 >= angle1: raise ValueError( "Invalid parameter angle0 < angle1 ! Start angle must be smaller than end angle" ) m = mc.MEDCouplingCMesh("spider_web") arr_r = mc.DataArrayDouble(n_r + 1) arr_r.iota() arr_t = mc.DataArrayDouble(n_theta + 1) arr_t.iota() m.setCoordsAt(0, arr_r) m.setCoordsAt(1, arr_t) m = m.buildUnstructured() # Now the real job: coo = m.getCoords() dr, dtheta = (r1 - r0) / float(n_r), (angle1 - angle0) / float(n_theta) coo[:, 0] = r0 + dr * coo[:, 0] coo[:, 1] = (angle0 + dtheta * coo[:, 1]) * pi / 180.0 coo = coo.fromPolarToCart() m.setCoords(coo) oldNbOfNodes = m.getNumberOfNodes() arr, areNodesMerged, newNbOfNodes = m.mergeNodes(1e-10) print "oldNbOfNodes=", oldNbOfNodes, "newNbOfNodes=", newNbOfNodes print "m.getNumberOfCells()=", m.getNumberOfCells() m.checkConsistencyLight() # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = m.computeSkin() # Trie les cellules par type conformément à la convention MED fichier o2n = m.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, m) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes arr_circle = mc.DataArrayInt(range(mesh_1d.getNumberOfCells())) arr_circle.setName("Circle") meshMEDFile.addGroup(-1, arr_circle) filename = "diskWithSpiderWeb" + str(m.getNumberOfCells()) + ".med" # Write the result into a VTU file that can be read with ParaView m.writeVTK("diskWithSpiderWeb.vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch return m
def createBrickWallMesh(xmin=0., xmax=1., nx=15, ymin=0., ymax=1., ny=15, mesh_name="squareWithBrickWall"): dx = (xmax - xmin) / nx dy = (ymax - ymin) / ny print "Creating BrickWall mesh with nx=", nx, "ny=", ny, "nb cells=", nx * ny # Building the initial rectangular cell, centered at 0,0 d = mc.DataArrayDouble(4, 2) d[0, 0] = -dx / 2 d[0, 1] = dy / 2 d[1, 0] = dx / 2 d[1, 1] = dy / 2 d[2, 0] = dx / 2 d[2, 1] = -dy / 2 d[3, 0] = -dx / 2 d[3, 1] = -dy / 2 d.setInfoOnComponents(["X [m]", "Y [m]"]) print "Uniform array ?", d.magnitude().isUniform( 0.5 * math.sqrt(dx * dx + dy * dy), 1e-10) # translation of the first cell translationToPerform = [[(0.5 * (1 + j % 2) + i) * dx, (0.5 + j) * dy] for i in range(nx) for j in range(ny)] ds = len(translationToPerform) * [None] for pos, t in enumerate(translationToPerform): ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds ds[pos] += t # Adding a vector to a set of coordinates does a translation pass d2 = mc.DataArrayDouble.Aggregate(ds) # Build an unstructured mesh representing the final pattern mesh = mc.MEDCouplingUMesh(mesh_name, 2) mesh.setCoords(d2) print "Mesh dimension is", mesh.getMeshDimension() print "Spatial dimension is", mesh.getCoords().getNumberOfComponents() mesh.allocateCells(nx * ny) for i in xrange(nx * ny): cell_connec = range(4 * i, 4 * (i + 1)) mesh.insertNextCell(mc.NORM_POLYGON, cell_connec) pass # Identifying duplicate nodes oldNbOfNodes = mesh.getNumberOfNodes() arr, areNodesMerged, newNbOfNodes = mesh.mergeNodes(1e-10) print "oldNbOfNodes=", oldNbOfNodes, "newNbOfNodes", newNbOfNodes # Crée des polygones pour rendre conforme les mailles mesh.conformize2D(1e-10) # Check that everything is coherent (will throw if not) mesh.checkConsistencyLight() # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 # PB: getCellsInBoundingBox renvoie aussi les segments qui touchent la bounding box # => On boucle sur les coordonnées des barycentres barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(y - ymin) < tol: ids_bottom.append(i) elif abs(y - ymax) < tol: ids_top.append(i) elif abs(x - xmax) < tol or abs(x - xmax - dx / 4) < tol or abs(x - xmax - dx / 2) < tol: ids_right.append(i) elif abs(x - xmin) < tol or abs(x - xmin - dx / 4) < tol or abs(x - xmin - dx / 2) < tol: ids_left.append(i) else: raise ValueError( "Pb with boundary construction : barycenter does not belong to any border group" ) arr_left = mc.DataArrayInt(ids_left) arr_right = mc.DataArrayInt(ids_right) arr_bottom = mc.DataArrayInt(ids_bottom) arr_top = mc.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) filename = mesh_name + str(nx * ny) + ".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+str(nx*ny)+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch
def mesh_square_with_hexagons(xmin=0,xmax=1,ymin=0,ymax=1,ny=14,mesh_name="squareWithHexagons"): radius=(ymax-ymin)/(ny*math.sqrt(3.)) r = math.sqrt(3.)/2*radius nx = int( 2*(xmax-xmin)/(3.*radius) ) print "Meshing a square with hexagons nx=",nx,"ny=",ny, "ncells=",nx*ny # Building the coordinates of the initial hexagon, centered at 0,0 d = mc.DataArrayDouble(6,2) d[:,0] = radius d[:,1] = range(6) d[:,1] *= math.pi/3. d = d.fromPolarToCart() d.setInfoOnComponents(["X [m]","Y [m]"]) print "Uniform array ?", d.magnitude().isUniform(radius,1e-12) # translations of the first cell translationToPerform = [[xmin+(1.5*j+1)*radius,ymin+(2*i+(j%2)+1)*r] for i in range(ny) for j in range(nx)] ds = len(translationToPerform)*[None] for pos,t in enumerate(translationToPerform): ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds ds[pos] += t # Adding a vector to a set of coordinates does a translation pass d2 = mc.DataArrayDouble.Aggregate(ds) # Build an unstructured mesh representing the final pattern mesh = mc.MEDCouplingUMesh(mesh_name,2) mesh.setCoords(d2) print "Mesh dimension is", mesh.getMeshDimension() print "Spatial dimension is", mesh.getCoords().getNumberOfComponents() mesh.allocateCells(nx*ny) for i in xrange(nx*ny): cell_connec = range(6*i,6*(i+1)) mesh.insertNextCell(mc.NORM_POLYGON, cell_connec) pass # Identifying duplicate nodes oldNbOfNodes=mesh.getNumberOfNodes() arr, areNodesMerged, newNbOfNodes=mesh.mergeNodes(1e-10) print "oldNbOfNodes=",oldNbOfNodes,"newNbOfNodes",newNbOfNodes # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 # PB: getCellsInBoundingBox renvoie aussi les segments qui touchent la bounding box # => On boucle sur les coordonnées des barycentres barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(x-xmin-radius/4) < tol:# ids_left.append(i) elif abs(x-xmin-(1.5*nx+0.25)*radius) < tol: ids_right.append(i) elif abs(y-ymin) < tol or abs(y-ymin-r) < tol or abs(y-ymin-r/2) < tol: ids_bottom.append(i) elif abs(y-ymin-2*r*ny) < tol or abs(y-ymin-2*r*ny-r) < tol or abs(y-ymin-2*r*ny-r/2) < tol: ids_top.append(i) else: raise ValueError("Pb with boundary construction : barycenter does not belong to any border group") arr_left = mc.DataArrayInt(ids_left) arr_right = mc.DataArrayInt(ids_right) arr_bottom = mc.DataArrayInt(ids_bottom) arr_top = mc.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile=ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0,mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1,mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) # Check that everything is coherent (will throw if not) mesh.checkConsistencyLight() filename = mesh_name+".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename,2) # 2 stands for write from scratch
def mesh_disk_with_squares(xcenter=0.,ycenter=0., Radius=1.,n=17,mesh_name="diskWithSquares"): xmin=-Radius xmax=Radius ymin=-Radius ymax=Radius dx = (xmax-xmin)/n dy=(ymax-ymin)/n # Building the initial rectangular cell, centered at 0,0 d = mc.DataArrayDouble(4,2) d[0,0] = -dx/2 d[0,1] = dy/2 d[1,0] = dx/2 d[1,1] = dy/2 d[2,0] = dx/2 d[2,1] = -dy/2 d[3,0] = -dx/2 d[3,1] = -dy/2 d.setInfoOnComponents(["X [m]","Y [m]"]) print "Uniform array ?", d.magnitude().isUniform(0.5*math.sqrt(dx*dx+dy*dy),1e-10) # translation of the first cell translationToPerform = [] for i in range(n) : for j in range(n): if (xcenter-xmin-(0.5+i)*dx)**2+(ycenter-ymin-(0.5+j)*dy)**2<Radius*Radius : translationToPerform.append([xmin+(0.5+i)*dx,ymin+(0.5+j)*dy] ) ncells= len(translationToPerform) print "Meshing a disk with squares ",n," nb of cells=",ncells ds = ncells*[None] for pos,t in enumerate(translationToPerform): ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds ds[pos] += t # Adding a vector to a set of coordinates does a translation pass d2 = mc.DataArrayDouble.Aggregate(ds) # Build an unstructured mesh representing the final pattern mesh = mc.MEDCouplingUMesh(mesh_name,2) mesh.setCoords(d2) print "Mesh dimension is", mesh.getMeshDimension() print "Spatial dimension is", mesh.getCoords().getNumberOfComponents() mesh.allocateCells(ncells) for i in xrange(ncells): cell_connec = range(4*i,4*(i+1)) mesh.insertNextCell(mc.NORM_POLYGON, cell_connec) pass # Identifying duplicate nodes oldNbOfNodes=mesh.getNumberOfNodes() arr, areNodesMerged, newNbOfNodes=mesh.mergeNodes(1e-10) print "oldNbOfNodes=",oldNbOfNodes,"newNbOfNodes",newNbOfNodes # Check that everything is coherent (will throw if not) mesh.checkConsistencyLight() # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile=ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0,mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1,mesh_1d) # Ecrit les groupes arr_circle = mc.DataArrayInt(range(mesh_1d.getNumberOfCells())) arr_circle.setName("Circle") meshMEDFile.addGroup(-1, arr_circle) filename = mesh_name+".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name+".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename,2) # 2 stands for write from scratch
def createLocallyRefinedMesh(nb_segs_x, mesh_name): # First mesh mesh_1 = createMesh(nb_segs_x, 0., 1., 0., mesh_name) amr = MC.MEDCouplingCartesianAMRMesh(mesh_1) # 1er raffinement amr.addPatch([(nb_segs_x / 2, nb_segs_x), (0, nb_segs_x / 2)], [2, 2]) # 2eme raffinement amr[0].addPatch([(nb_segs_x / 2, nb_segs_x), (0, nb_segs_x / 2)], [2, 2]) # Crée un seul maillage avec tous les rafinements mesh = amr.buildUnstructured() mesh.setName(mesh_name) # Merge les noeuds confondus (à faire avant le conformize2D) arr, areNodesMerged, newNbOfNodes = mesh.mergeNodes(1e-10) # Crée des polygones pour rendre conforme les mailles mesh.conformize2D(1e-10) # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 #tol2 = 0 #arr_left = mesh_1d.getCellsInBoundingBox([0-tol, tol, -tol, 1+tol], tol2) #arr_right = mesh_1d.getCellsInBoundingBox([1-tol, 1+tol, -tol, 1+tol], tol2) #arr_bottom = mesh_1d.getCellsInBoundingBox([0-tol, 1+tol, -tol, tol], tol2) #arr_top = mesh_1d.getCellsInBoundingBox([0-tol, 1+tol, 1-tol, 1+tol], tol2) # PB: getCellsInBoundingBox renvoie aussi les segments qui touchent la bounding box # => On boucle sur les coordonnées des barycentres barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(x) < tol: ids_left.append(i) elif abs(x - 1) < tol: ids_right.append(i) elif abs(y) < tol: ids_bottom.append(i) elif abs(y - 1) < tol: ids_top.append(i) arr_left = MC.DataArrayInt(ids_left) arr_right = MC.DataArrayInt(ids_right) arr_bottom = MC.DataArrayInt(ids_bottom) arr_top = MC.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) filename = mesh_name + ".med" meshMEDFile.write(filename, 2) # 2 stands for write from scratch return meshMEDFile
def createCheckerboardMesh(nb_segs_x, mesh_name=""): if not mesh_name: mesh_name = "checkerboard_%ix%i" % (nb_segs_x, nb_segs_x) # First mesh mesh_1 = createMesh(nb_segs_x, 0., 1., 0., mesh_name) amr = MC.MEDCouplingCartesianAMRMesh(mesh_1) # Exemple sur une grille 4x4 ## 1ere diagonale #amr.addPatch([(0, 1), (0, 1)], [2, 2]) #amr.addPatch([(1, 2), (1, 2)], [2, 2]) #amr.addPatch([(2, 3), (2, 3)], [2, 2]) #amr.addPatch([(3, 4), (3, 4)], [2, 2]) ## en-dessous de la diagonale, en bas à droite #amr.addPatch([(0, 1), (2, 3)], [2, 2]) #amr.addPatch([(1, 2), (3, 4)], [2, 2]) ## au-dessus de la diagonale, en haut à gauche #amr.addPatch([(2, 3), (0, 1)], [2, 2]) #amr.addPatch([(3, 4), (1, 2)], [2, 2]) # généralise avec une double boucle for i in range(0, nb_segs_x, 1): if i % 2 == 0: for j in range(0, (nb_segs_x + 1) / 2): amr.addPatch([(i, i + 1), (2 * j, 2 * j + 1)], [2, 2]) else: for j in range(0, nb_segs_x / 2): amr.addPatch([(i, i + 1), (1 + 2 * j, 2 * j + 2)], [2, 2]) # Crée un seul maillage avec tous les rafinements mesh = amr.buildUnstructured() mesh.setName(mesh_name) # Merge les noeuds confondus (à faire avant le conformize2D) arr, areNodesMerged, newNbOfNodes = mesh.mergeNodes(1e-10) # Crée des polygones pour rendre conforme les mailles mesh.conformize2D(1e-10) # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Identifie les segments de chaque côté pour créer les groupes tol = 1e-10 #tol2 = 0 #arr_left = mesh_1d.getCellsInBoundingBox([0-tol, tol, -tol, 1+tol], tol2) #arr_right = mesh_1d.getCellsInBoundingBox([1-tol, 1+tol, -tol, 1+tol], tol2) #arr_bottom = mesh_1d.getCellsInBoundingBox([0-tol, 1+tol, -tol, tol], tol2) #arr_top = mesh_1d.getCellsInBoundingBox([0-tol, 1+tol, 1-tol, 1+tol], tol2) # PB: getCellsInBoundingBox renvoie aussi les segments qui touchent la bounding box # => On boucle sur les coordonnées des barycentres barycenters = mesh_1d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] for i, coord in enumerate(barycenters): x, y = coord if abs(x) < tol: ids_left.append(i) elif abs(x - 1) < tol: ids_right.append(i) elif abs(y) < tol: ids_bottom.append(i) elif abs(y - 1) < tol: ids_top.append(i) arr_left = MC.DataArrayInt(ids_left) arr_right = MC.DataArrayInt(ids_right) arr_bottom = MC.DataArrayInt(ids_bottom) arr_top = MC.DataArrayInt(ids_top) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) filename = mesh_name + ".med" meshMEDFile.write(filename, 2) # 2 stands for write from scratch return meshMEDFile
def mesh_disk_with_hexagons(xcenter=0., ycenter=0., Radius=1., ny=16, mesh_name="diskWithHexagons"): xmin = -Radius xmax = Radius ymin = -Radius ymax = Radius hradius = (ymax - ymin) / (ny * math.sqrt(3.)) r = math.sqrt(3.) / 2 * hradius nx = int(2 * (xmax - xmin) / (3. * hradius)) # Building the coordinates of the initial hexagon, centered at 0,0 d = mc.DataArrayDouble(6, 2) d[:, 0] = hradius d[:, 1] = range(6) d[:, 1] *= math.pi / 3. d = d.fromPolarToCart() d.setInfoOnComponents(["X [m]", "Y [m]"]) print "Uniform array ?", d.magnitude().isUniform(hradius, 1e-12) # translations of the first cell that are inside the circle translationToPerform = [] for i in range(ny): for j in range(nx): if (xcenter - xmin - (1.5 * j + 1) * hradius)**2 + ( ycenter - ymin - (2 * i + (j % 2) + 1) * r)**2 < Radius * Radius: translationToPerform.append([ xmin + (1.5 * j + 1) * hradius, ymin + (2 * i + (j % 2) + 1) * r ]) ncells = len(translationToPerform) print "Meshing a disk with hexagons nx=", nx, "ny=", ny, "nb of cells=", ncells ds = ncells * [None] for pos, t in enumerate(translationToPerform): ds[pos] = d[:] # Perform a deep copy of d and place it at position 'pos' in ds ds[pos] += t # Adding a vector to a set of coordinates does a translation pass # Identifying duplicate tuples d2 = mc.DataArrayDouble.Aggregate(ds) oldNbOfTuples = d2.getNumberOfTuples() c, cI = d2.findCommonTuples(1e-12) tmp = c[cI[0]:cI[0 + 1]] print tmp a = cI.deltaShiftIndex() b = a - 1 myNewNbOfTuples = oldNbOfTuples - sum(b.getValues()) o2n, newNbOfTuples = mc.DataArrayInt.ConvertIndexArrayToO2N( oldNbOfTuples, c, cI) print "Have I got the right number of tuples?" print "myNewNbOfTuples = %d, newNbOfTuples = %d" % (myNewNbOfTuples, newNbOfTuples) assert (myNewNbOfTuples == newNbOfTuples) print "Old number of tuple was ", oldNbOfTuples # Extracting the unique set of tuples d3 = d2.renumberAndReduce(o2n, newNbOfTuples) n2o = o2n.invertArrayO2N2N2O(newNbOfTuples) d3_bis = d2[n2o] print "Are d3 and d3_bis equal ? %s" % (str(d3.isEqual(d3_bis, 1e-12))) # Now build an unstructured mesh representing the final pattern mesh = mc.MEDCouplingUMesh(mesh_name, 2) mesh.setCoords(d3) print "Mesh dimension is", mesh.getMeshDimension() print "Spatial dimension is", mesh.getCoords().getNumberOfComponents() mesh.allocateCells(ncells) for i in xrange(ncells): cell_connec = o2n[6 * i:6 * (i + 1)] mesh.insertNextCell(mc.NORM_POLYGON, cell_connec.getValues()) pass # Check that everything is coherent (will throw if not) mesh.checkConsistencyLight() # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_1d = mesh.computeSkin() # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 1D meshMEDFile.setMeshAtLevel(-1, mesh_1d) # Ecrit les groupes arr_circle = mc.DataArrayInt(range(mesh_1d.getNumberOfCells())) arr_circle.setName("Circle") meshMEDFile.addGroup(-1, arr_circle) filename = mesh_name + ".med" # Write the result into a VTU file that can be read with ParaView #mesh.writeVTK(mesh_name".vtu") # Write the result into a MED file that can be read with Salomé meshMEDFile.write(filename, 2) # 2 stands for write from scratch
def createLocallyRefinedMesh(nb_segs_x, mesh_name): # First mesh mesh_1 = createMesh(nb_segs_x, 0., 1., 0., 0., mesh_name) amr = MC.MEDCouplingCartesianAMRMesh(mesh_1) # 1er raffinement amr.addPatch([(nb_segs_x / 2, nb_segs_x), (0, nb_segs_x / 2), (0, nb_segs_x / 2)], [2, 2, 2]) # 2eme raffinement amr[0].addPatch([(nb_segs_x / 2, nb_segs_x), (0, nb_segs_x / 2), (0, nb_segs_x / 2)], [2, 2, 2]) # Crée un seul maillage avec tous les rafinements mesh = amr.buildUnstructured() mesh.setName(mesh_name) # Merge les noeuds confondus (à faire avant le conformize2D) arr, areNodesMerged, newNbOfNodes = mesh.mergeNodes(1e-10) # Crée des polyèdres pour rendre conforme les mailles mesh.convertAllToPoly() mesh.conformize3D(1e-10) mesh.unPolyze() # Crée les éléments 1D pour pouvoir imposer les conditions aux limites mesh_2d = mesh.computeSkin() # Trie les cellules par type conformément à la convention MED fichier o2n = mesh.sortCellsInMEDFileFrmt() o2n = mesh_2d.sortCellsInMEDFileFrmt() # Identifie les faces de chaque côté pour créer les groupes tol = 1e-10 barycenters = mesh_2d.computeIsoBarycenterOfNodesPerCell() ids_left = [] ids_right = [] ids_bottom = [] ids_top = [] ids_front = [] ids_back = [] for i, coord in enumerate(barycenters): x, y, z = coord if abs(x) < tol: ids_left.append(i) elif abs(x - 1) < tol: ids_right.append(i) elif abs(y) < tol: ids_bottom.append(i) elif abs(y - 1) < tol: ids_top.append(i) elif abs(z) < tol: ids_back.append(i) elif abs(z - 1) < tol: ids_front.append(i) arr_left = MC.DataArrayInt(ids_left) arr_right = MC.DataArrayInt(ids_right) arr_bottom = MC.DataArrayInt(ids_bottom) arr_top = MC.DataArrayInt(ids_top) arr_back = MC.DataArrayInt(ids_back) arr_front = MC.DataArrayInt(ids_front) arr_left.setName("Left") arr_right.setName("Right") arr_bottom.setName("Bottom") arr_top.setName("Top") arr_back.setName("Back") arr_front.setName("Front") meshMEDFile = ML.MEDFileUMesh.New() # Ecrit le maillage 3D meshMEDFile.setMeshAtLevel(0, mesh) # Ecrit le maillage 2D meshMEDFile.setMeshAtLevel(-1, mesh_2d) # Ecrit les groupes meshMEDFile.addGroup(-1, arr_left) meshMEDFile.addGroup(-1, arr_right) meshMEDFile.addGroup(-1, arr_bottom) meshMEDFile.addGroup(-1, arr_top) meshMEDFile.addGroup(-1, arr_back) meshMEDFile.addGroup(-1, arr_front) filename = mesh_name + ".med" meshMEDFile.write(filename, 2) # 2 stands for write from scratch return meshMEDFile