def storeOrphanNodesIfAny(self, arrayOfGlobalIdsOfOrphanNodes): """ Args arrayOfGlobalIdsOfOrphanNodes : tous les noeuds a charger """ if arrayOfGlobalIdsOfOrphanNodes.empty(): self._orphan_coords = mc.DataArrayDouble([]) self._orphan_global_ids = mc.DataArrayInt([]) self._orphan_fam_ids = mc.DataArrayInt([]) self._orphan_num_ids = mc.DataArrayInt([]) else: dt, it, _ = self._medFileUMesh.getTime() vmin = arrayOfGlobalIdsOfOrphanNodes.getMinValueInArray() vmax = arrayOfGlobalIdsOfOrphanNodes.getMaxAbsValueInArray() dataFromFile = mc.MEDFileUMesh.LoadPartCoords( self._medFileDataContext.getFileName(), self._medFileDataContext.getMeshName(), dt, it, self._medFileUMesh.getCoords().getInfoOnComponents(), vmin, vmax + 1) idsInLoadedArrays = arrayOfGlobalIdsOfOrphanNodes - vmin self._orphan_coords = dataFromFile[0][idsInLoadedArrays] self._orphan_global_ids = arrayOfGlobalIdsOfOrphanNodes self._orphan_fam_ids = None if dataFromFile[2]: self._orphan_fam_ids = dataFromFile[2][idsInLoadedArrays] self._orphan_num_ids = None if dataFromFile[3]: self._orphan_num_ids = dataFromFile[3][idsInLoadedArrays]
def field_mc_from_meshio( mesh, field_name, on="points", mesh_mc=None, nature="IntensiveMaximum" ): """ Convert a meshio field to a medcoupling field Args: mesh (meshio mesh): Mesh object field_name (str): Name of the field defined in the ``meshio`` mesh on (str): Support of the field (``points`` or ``cells``) mesh_mc (medcoupling mesh): MEDCoupling mesh of the current ``meshio`` mesh nature (str): Physical nature of the field (``IntensiveMaximum``, ``IntensiveConservation``, ``ExtensiveMaximum`` or ``ExtensiveConservation``) """ assert on in ["points", "cells"] if on == "points": field = mc.MEDCouplingFieldDouble(mc.ON_NODES, mc.NO_TIME) else: field = mc.MEDCouplingFieldDouble(mc.ON_CELLS, mc.NO_TIME) field.setName(field_name) if mesh_mc is None: mesh_mc = mesh_mc_from_meshio(mesh) field.setMesh(mesh_mc) # Point fields if on == "points": assert field_name in mesh.point_data field.setArray(mc.DataArrayDouble(mesh.point_data[field_name].copy())) else: # Cell fields assert on == "cells" assert field_name in mesh.cell_data_dict array = None celltypes_mc = mesh_mc.getAllGeoTypesSorted() for celltype_mc in celltypes_mc: celltype = mc_to_meshio_type[celltype_mc] assert celltype in mesh.cell_data_dict[field_name] values = mesh.cell_data_dict[field_name][celltype] if array is None: array = values else: array = np.concatenate([array, values]) field.setArray(mc.DataArrayDouble(array)) field.setNature(eval("mc." + nature)) return field
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 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 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