Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #6
0
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
Пример #7
0
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