def mesh_mc_from_meshio(mesh, check=False): """ Convert a meshio mesh to a medcoupling mesh Args: mesh (meshio mesh): Mesh object check (bool): Check if the medcoupling mesh is consist """ # Initialization mesh_mc = mc.MEDCouplingUMesh("mesh", meshdim(mesh)) # Point coordinates coords = mc.DataArrayDouble(mesh.points.copy()) mesh_mc.setCoords(coords) # Cells cells_dict = mesh.cells_dict conn = np.array([], dtype=np.int32) conn_index = np.array([], dtype=np.int32) for celltype in cells_dict: celltype_ = meshio_to_mc_type[celltype] ncells_celltype, npoints_celltype = cells_dict[celltype].shape col_celltype = celltype_ * np.ones((ncells_celltype, 1), dtype=np.int32) conn_celltype = np.hstack([col_celltype, cells_dict[celltype]]).flatten() conn_index_celltype = len(conn) + (1 + npoints_celltype) * np.arange( ncells_celltype, dtype=np.int32 ) conn = np.hstack([conn, conn_celltype]) conn_index = np.hstack([conn_index, conn_index_celltype]) conn_index = np.hstack([conn_index, [len(conn)]]).astype(np.int32) conn = mc.DataArrayInt(conn.astype(np.int32)) conn_index = mc.DataArrayInt(conn_index) mesh_mc.setConnectivity(conn, conn_index) if check: mesh_mc.checkConsistency() return mesh_mc
def mesh_square_with_RightTriangles(xmin=0, xmax=1., ymin=0, ymax=1., nx=10, ny=10, mesh_name="squareWithRightTriangles"): dx = (xmax - xmin) / nx dy = (ymax - ymin) / ny print("Meshing a rectangle with Right Triangles nx=", nx, "ny=", ny, "ncells=", 2 * nx * ny) # Building the coordinates of the first initial triangle d_up = mc.DataArrayDouble(3, 2) d_up[0, 0] = 0 d_up[0, 1] = 0 d_up[1, 0] = 0 d_up[1, 1] = dy d_up[2, 0] = dx d_up[2, 1] = 0 d_up.setInfoOnComponents(["X [m]", "Y [m]"]) # Building the coordinates of the second initial triangle d_down = mc.DataArrayDouble(3, 2) d_down[0, 0] = dx d_down[0, 1] = dy d_down[1, 0] = 0 d_down[1, 1] = dy d_down[2, 0] = dx d_down[2, 1] = 0 d_down.setInfoOnComponents(["X [m]", "Y [m]"]) # translations of the cells : translationToPerform = [[xmin + i * dx, ymin + j * dy] for i in range(nx) for j in range(ny)] ds = (2 * len(translationToPerform)) * [None] for pos, t in enumerate(translationToPerform): ds[2 * pos] = d_up[:] # Perform a deep copy of d_up and place it at position 'pos' in ds ds[2 * pos] += t # Adding a vector to a set of coordinates does a translation ds[2 * pos + 1] = d_down[:] # Perform a deep copy of d_down and place it at position 'pos' in ds ds[2 * pos + 1] += 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(2 * nx * ny) for i in range(2 * nx * ny): cell_connec = [3 * i, 3 * i + 1, 3 * i + 2] mesh.insertNextCell(mc.NORM_TRI3, 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 = [] #print(barycenters) 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
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 range(ncells): cell_connec = [4*i,4*i+1,4*i+2,4*i+3) mesh.insertNextCell(mc.NORM_QUAD4, 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 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 range(nx * ny): cell_connec = [ 6 * i, 6 * i + 1, 6 * i + 2, 6 * i + 3, 6 * i + 4, 6 * i + 5 ] 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_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 range(ncells): cell_connec = o2n[6 * i, 6 * i + 1, 6 * i + 2, 6 * i + 3, 6 * i + 4, 6 * i + 5] 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 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 range(nx*ny): cell_connec = [4*i,4*i+1,4*i+2,4*i+3) mesh.insertNextCell(mc.NORM_QUAD4, 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_EquilateralTriangles( xmin=0, xmax=1, ymin=0, ymax=1, ny=10, mesh_name="squareWithEquilateralTriangles"): h = (ymax - ymin) / ny #hauteur d'un seul triangle lenght = 2 * h / math.sqrt(3.) # longueur du coté d'un triangle radius = 2 * h / 3. # rayon du cercle circonscrit nx = int((xmax - xmin) / lenght) print("Meshing a square with Equilateral Triangles nx=", nx, "ny=", ny, "ncells=", nx * ny) # Building the coordinates of the initial triangle, centered at 0,0 and pointing upward d_up = mc.DataArrayDouble(3, 2) d_up[0, 0] = radius * math.sqrt(3.) / 2 d_up[0, 1] = -radius / 2 d_up[1, 0] = 0 d_up[1, 1] = radius d_up[2, 0] = -radius * math.sqrt(3.) / 2 d_up[2, 1] = -radius / 2 d_up.setInfoOnComponents(["X [m]", "Y [m]"]) # Building the coordinates of the initial triangle, centered at 0,0 and pointing downward (symetry around x axis : change the sign of the y coordinate) d_down = mc.DataArrayDouble(3, 2) d_down[0, 0] = radius * math.sqrt(3.) / 2 d_down[0, 1] = radius / 2 d_down[1, 0] = 0 d_down[1, 1] = -radius d_down[2, 0] = -radius * math.sqrt(3.) / 2 d_down[2, 1] = radius / 2 d_down.setInfoOnComponents(["X [m]", "Y [m]"]) print("Uniform arrays ?", d_up.magnitude().isUniform(radius, 1e-12), d_down.magnitude().isUniform(radius, 1e-12)) # translations of the cells : translationToPerform_up = [[ xmin + radius * math.sqrt(3.) / 2 + (i % 2) * lenght / 2 + lenght * j, ymin + radius / 2 + h * i ] for i in range(ny) for j in range(nx)] translationToPerform_down = [[ xmin + radius * math.sqrt(3.) / 2 + ((i + 1) % 2) * lenght / 2 + lenght * j, ymin + h - radius / 2 + h * i ] for i in range(ny) for j in range(nx)] ds = (len(translationToPerform_up) + len(translationToPerform_down)) * [None] for pos, t_up in enumerate(translationToPerform_up): ds[2 * pos] = d_up[:] # Perform a deep copy of d_up and place it at position 'pos' in ds ds[2 * pos] += t_up # Adding a vector to a set of coordinates does a translation pass for pos, t_down in enumerate(translationToPerform_down): ds[2 * pos + 1] = d_down[:] # Perform a deep copy of d_down and place it at position 'pos' in ds ds[2 * pos + 1] += t_down # 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(2 * nx * ny) for i in range(2 * nx * ny): cell_connec = [3 * i, 3 * i + 1, 3 * i + 2] mesh.insertNextCell(mc.NORM_TRI3, 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 = [] #print(barycenters) for i, coord in enumerate(barycenters): x, y = coord if abs(x - xmin - lenght / 4) < tol: # ids_left.append(i) elif abs(x - xmin - lenght * nx - lenght / 4) < 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