Beispiel #1
0
 def setUp(self):
     # Use the same grid file with different names
     self.grid1 = readGrid(
         os.path.abspath(os.path.join(baseDir,
                                      "../examples/717_wl_L2.cgns")))
     self.grid1.name = "grid1"
     self.grid2 = readGrid(
         os.path.abspath(os.path.join(baseDir,
                                      "../examples/717_wl_L2.cgns")))
     self.grid2.name = "grid2"
     self.grids = [self.grid1, self.grid2]
Beispiel #2
0
    def combineCGNS(self, combinedFile="combined.cgns", additionalGrids=[], skipList=[], eraseFiles=True):
        """
        This will gather all newly generated grids and combine them in a single CGNS file.
        This only works for CGNS output files.

        Parameters
        ----------
        combinedFile : str
            The name of the combined output file.

        additionalGrids : list
            The filenames of any grids that were not generated by the current pyHypMulti object, but
            should still be included in the combined output file.

        skipList : list
            The keys of any generated grids that should not be included in the combined output file.

        eraseFiles : bool
            If True, we erase the individual files that are combined.

        """

        # Run cgnsUtilities on the root processor
        if self.comm.rank == 0:

            # Add generated grids that we do not want to skip
            selectedGrids = []
            gridList = []
            for i in range(self.numGrids):
                if self.results["name"][i] not in skipList:
                    filename = self.results["outputFile"][i]
                    selectedGrids.append(filename)
                    grid = readGrid(filename)
                    gridList.append(grid)

            # Add any additional grids
            for filename in additionalGrids:
                grid = readGrid(filename)
                gridList.append(grid)

            # Call the combine function in cgnsUtilities
            combined = combineGrids(gridList)
            combined.writeToCGNS(combinedFile)
            print(f"Combined CGNS files into: {combinedFile}")

            # Erase input files
            if eraseFiles:
                for filename in selectedGrids:
                    os.remove(filename)

        # Wait for root process to finish before returning
        self.comm.Barrier()
Beispiel #3
0
    def writeGrid(self, baseName=None):
        """
        Write the grids of each instance

        Parameters
        ----------
        baseName : str or None
            a base namve that will be used to generate filenames for
            all instance mesh files.

        Ney Secco 2017-03
        """

        # We need to reexplode the original file
        if self.myID == 0:

            # Load the CGNS file
            combined_file = cs.readGrid(self.CGNSFile)

            # Explode the CGNS file by zones (this will only work if the user used cgns_utils combine
            # to create the input CGNS file, since the explosion uses the domain names)
            grids, zoneNames = cs.explodeByZoneName(combined_file)

            # Save temporary grid files with the exploded zones
            for grid, zoneName in zip(grids, zoneNames):
                grid.writeToCGNS("_" + zoneName + ".cgns")

            # Delete grids to free space
            del grids
            del combined_file

        # Assign baseName if user provided none
        if baseName is None:
            baseName = "IDWarpMulti"

        # Loop over all instances to write their meshes
        for instanceID, mesh in enumerate(self.meshes):

            # Generate a fileName
            fileName = baseName + "_inst%03d.cgns" % (instanceID)

            # Call function to write the mesh of the current instance
            mesh.writeGrid(fileName)

        # Now the root proc can remove the temporary grid files
        if self.myID == 0:
            for zoneName in zoneNames:
                os.system("rm _" + zoneName + ".cgns")
Beispiel #4
0
    def writeCGNS(self, fileName):
        """After we have generated a grid, write it out in a properly
        formatted 1-Cell wide CGNS file suitable for running in SUmb."""

        if not self.gridGenerated:
            raise Error("No grid has been generated! Run the run() " "command before trying to write the grid!")

        self.hyp.writecgns(fileName)

        # Possibly perform autoconnect using cgns_utils
        if self.comm.rank == 0 and self.getOption("autoConnect"):
            grid = readGrid(fileName)
            grid.connect()
            grid.writeToCGNS(fileName)

        self.comm.barrier()
 def setUp(self):
     self.grid = readGrid(
         os.path.abspath(os.path.join(baseDir,
                                      "../examples/717_wl_L2.cgns")))
Beispiel #6
0
options["tip"] = tip_dict

# Run pyHypMulti
hyp = pyHypMulti(options=options, commonOptions=commonOptions)
MPI.COMM_WORLD.barrier()
# rst near_field (end)

# ======================================================================
#        Combine Near-Field
# ======================================================================
# rst combine_near_field (beg)
# read the grids
wing = "%s/near_wing_vol_%s.cgns" % (args.output_dir, args.level)
tip = "%s/near_tip_vol_%s.cgns" % (args.output_dir, args.level)

wingGrid = readGrid(wing)
tipGrid = readGrid(tip)

gridList = [wingGrid, tipGrid]

# combine grids
combinedGrid = combineGrids(gridList)

# move to y=0
combinedGrid.symmZero("y")
# rst combine_near_field (end)

# ======================================================================
#        Generate Far-Field
# ======================================================================
# rst far_field (beg)
Beispiel #7
0
def main():
    parser = get_parser()
    # Get the arguments we need!
    args = parser.parse_args()

    # -------------------------------------------
    #         Selection of the task
    # -------------------------------------------

    # The time combine is special. First we generate the list of files we
    # need to deal with.
    if args.mode == "timeCombine":
        # Get the directory name where the baseName is:
        path = os.path.dirname(os.path.abspath(args.baseName))

        # Get the full list of files in this directory:
        allFiles = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
        files = []

        parts = args.baseName.split("%d")
        maxLength = 0
        for f in allFiles:
            if (parts[0] == "" or parts[0] in f) and (parts[1] == "" or parts[1] in f):
                # Make sure there is a .cgns in there somwhere
                if ".cgns" in f:
                    files.append(f)
                    maxLength = max(maxLength, len(f))
                    files = sorted(files)

        if args.outFile is None:
            outFile = "unsteady.plt"
        else:
            outFile = args.outFile

        # Now we make a character array of the file names, and hand if off to
        # fortran for all the actual reading/writing.
        fileNames = numpy.zeros((len(files), 256), "c")
        for i in range(len(files)):
            fileNames[i, 0 : len(files[i])] = files[i]

        libcgns_utils.utils.time_combine(fileNames, outFile)
        sys.exit(0)

    if args.mode == "testBlock":
        nx = args.nx
        ny = args.ny
        nz = args.nz
        X = numpy.zeros((nx, ny, nz, 3))
        Xcart = []
        Xcart.append(numpy.linspace(0, 1, nx))
        Xcart.append(numpy.linspace(0, 1, ny))
        Xcart.append(numpy.linspace(0, 1, nz))
        Xx, Xy, Xz = numpy.meshgrid(Xcart[0], Xcart[1], Xcart[2], indexing="ij")
        X[:, :, :, 0] = Xx
        X[:, :, :, 1] = Xy
        X[:, :, :, 2] = Xz
        b = Block("domain.00001", [nx, ny, nz], X)
        # Add bocos so we can run it:
        b.addBoco(Boco("iMin", BC["bcfarfield"], [[1, 1], [1, ny], [1, nz]], "far"))
        b.addBoco(Boco("iMax", BC["bcfarfield"], [[nx, nx], [1, ny], [1, nz]], "far"))
        b.addBoco(Boco("jMin", BC["bcsymmetryplane"], [[1, nx], [1, 1], [1, nz]], "sym"))
        b.addBoco(Boco("jMax", BC["bcsymmetryplane"], [[1, nx], [ny, ny], [1, nz]], "sym"))
        b.addBoco(Boco("kMin", BC["bcwallviscous"], [[1, nx], [1, ny], [1, 1]], "wall"))
        b.addBoco(Boco("kMax", BC["bcfarfield"], [[1, nx], [1, ny], [nz, nz]], "far"))
        g = Grid()
        g.addBlock(b)
        g.writeToCGNS(args.outFile)
        sys.exit(0)

    # The 'combine' function is done first sicne it is the only function
    # that reads multiple cgns files.
    if args.mode == "combine":
        grids = []
        for fName in args.gridFiles:
            grid = readGrid(fName)
            grids.append(grid)

        combinedGrid = combineGrids(grids)
        combinedGrid.writeToCGNS(args.outFile)

        # This task is now finished
        sys.exit(0)

    if args.mode == "explicitCart":
        # This task doesn't have args.gridFile so do it first
        xMin = [args.xmin, args.ymin, args.zmin]
        xMax = [args.xmax, args.ymax, args.zmax]

        simpleCart(xMin, xMax, args.dh, args.hExtra, args.nExtra, args.sym, args.mgcycle, args.outFile)

        sys.exit(0)

    if args.mode == "plot3d2cgns":
        # This doesn't read a cgns file so do this first too.
        convertPlot3d(args.plot3dFile, args.gridFile)
        sys.exit(0)

    # Get the current working grid 'curGrid' by reading the input
    curGrid = readGrid(args.gridFile)

    # The following are "special" and done first since they do not
    # have a CGNS output.

    if args.mode == "extractSurface":
        curGrid.extractSurface(args.surfFile)
        sys.exit(0)

    if args.mode == "extractSpecifiedSurface":
        curGrid.extractSpecifiedSurface(
            args.surfFile, args.blockID, args.imin, args.imax, args.jmin, args.jmax, args.kmin, args.kmax
        )
        sys.exit(0)

    if args.mode == "cgns2plot3d":
        curGrid.writePlot3d(args.plot3dFile)
        sys.exit(0)

    if args.mode == "blockSizes":
        curGrid.printBlockInfo()
        sys.exit(0)

    # Determine if we have an output file:
    try:
        if args.outFile is None:
            # Determine where to put a file:
            dirpath = tempfile.mkdtemp()

            # Define a temp output file
            outFileName = os.path.join(dirpath, "tmp.cgns")
        else:
            outFileName = args.outFile
    except Exception:
        outFile = None

    # Perform one of the following actions:
    if args.mode == "flip":
        curGrid.flip(args.axis)

    elif args.mode == "scale":
        curGrid.scale(args.scale)

    elif args.mode == "mirror":
        curGrid = mirrorGrid(curGrid, args.axis, args.tol)

    elif args.mode == "coarsen":
        curGrid.coarsen()

    elif args.mode == "refine":
        curGrid.refine(args.axes)

    elif args.mode == "split":
        curGrid = splitGrid(curGrid, args.splitFile)

    elif args.mode == "merge":
        curGrid = mergeGrid(curGrid)

    elif args.mode == "connect":
        if args.connectSelf:
            curGrid.connectSelfOnly(args.tol)
        else:
            curGrid.connect(args.tol)

    elif args.mode == "divide":
        curGrid = divideGrid(curGrid)

    elif args.mode == "autoBC":
        curGrid.autoBC(args.radius, args.sym, [args.xOffset, args.yOffset, args.zOffset])

    elif args.mode == "overwriteFamilies":
        curGrid.overwriteFamilies(args.familyFile)

    elif args.mode == "writeSubfaceFamily":
        curGrid.writeSubfaceFamily(args.familyFile)

    elif args.mode == "copyFamilyInfo":
        sourceGrid = readGrid(args.sourceFile)
        curGrid.copyFamilyInfo(sourceGrid)

    elif args.mode == "overwriteBC":
        curGrid.overwriteBCs(args.bcFile)

    elif args.mode == "removeBC":
        curGrid.removeBCs()

    elif args.mode == "rebunch":
        curGrid.rebunch(args.spacing, args.extraCells, args.nodes)

    elif args.mode == "randomize":
        curGrid.randomize(args.seed, args.keepRHS)

    elif args.mode == "reorder":
        curGrid.reorder(args.intDigits)

    elif args.mode == "symmZero":
        curGrid.symmZero(args.sym)

    elif args.mode == "symmZeroNoBC":
        curGrid.symmZeroNoBC(args.sym, args.tol)

    elif args.mode == "double2D":
        curGrid.double2D()

    elif args.mode == "removeBlocks":
        curGrid.removeBlocks(args.blockIDs)

    elif args.mode == "cartesian":
        found_overset = False
        for block in curGrid.blocks:
            for boco in block.bocos:
                if boco.type == BC["bcoverset"]:
                    found_overset = True
        if found_overset:
            curGrid.cartesian(args.cartFile, args.outFile)
        else:
            print("The CGNS file has no overset boundary conditions")
        sys.exit(0)

    elif args.mode == "simpleCart":
        curGrid.simpleCart(args.dh, args.hExtra, args.nExtra, args.sym, args.mgcycle, args.outFile)
        sys.exit(0)

    elif args.mode == "simpleOCart":
        curGrid.simpleOCart(args.dh, args.hExtra, args.nExtra, args.sym, args.mgcycle, args.outFile)
        sys.exit(0)

    elif args.mode == "translate":
        curGrid.translate(args.dx, args.dy, args.dz)

    elif args.mode == "rotate":
        curGrid.rotate(args.vx, args.vy, args.vz, args.theta)

    elif args.mode == "autoOversetBC":
        curGrid.autoOversetBC(args.sym, args.connectSelf, args.tol)

    elif args.mode == "autoNearfieldBC":
        curGrid.autoNearfieldBC(args.sym)

    elif args.mode == "autoFarfieldBC":
        curGrid.autoFarfieldBC(args.sym)

    elif args.mode == "fillOpenBCs":
        curGrid.fillOpenBCs(BC[args.bocoType], args.famName)

    elif args.mode == "include":
        toWrite = []
        for spec in args.rangeSpec.split(","):
            if "-" in spec:
                tmp = spec.split("-")
                start = int(tmp[0])
                end = int(tmp[1])
            else:
                start = int(spec)
                end = int(spec)
            for i in range(start, end + 1):
                toWrite.append(i)
        toWrite = numpy.unique(toWrite)
        toWrite.sort()
        curGrid.writeToCGNSSelected(args.outFile, toWrite)
        sys.exit(0)

    elif args.mode == "section":
        if len(curGrid.blocks) != 1:
            print("section command works only on grids with 1 block")
            sys.exit(0)
        curGrid.blocks[0].section(args.iStart, args.iEnd, args.jStart, args.jEnd, args.kStart, args.kEnd)

    elif args.mode == "explode":
        # Split original multiblock grid in a list of single-block grids
        gridList = explodeGrid(curGrid)

        # Check if the user gave a reference name. Otherwise, use the input name as reference
        if args.outFile is None:
            # Get the base name
            outFile = os.path.splitext(os.path.basename(args.gridFile))[0]
        else:
            outFile = args.outFile

        # Generate a list of names for the files by adding integers to the reference name
        fileNames = [outFile + "_%03d" % index + ".cgns" for index in range(1, len(gridList) + 1)]

        # Save each grid
        for index in range(len(gridList)):
            gridList[index].writeToCGNS(fileNames[index])

        # Finish execution
        sys.exit(0)

    elif args.mode == "explodeKmin":
        # Split original multiblock grid in a list of single-block grids
        # that contains just the K = 1 face
        gridList = explodeGrid(curGrid, kMin=True)

        # Check if the user gave a reference name. Otherwise, use the input name as reference
        if args.outFile is None:
            # Get the base name
            outFile = os.path.splitext(os.path.basename(args.gridFile))[0]
        else:
            outFile = args.outFile

        # Generate a list of names for the files by adding integers to the reference name
        fileNames = [outFile + "_%03d" % index + ".xyz" for index in range(1, len(gridList) + 1)]

        # Save each grid
        for index in range(len(gridList)):
            gridList[index].writePlot3d(fileNames[index])

        # Finish execution
        sys.exit(0)

    elif args.mode == "explodeByZoneName":
        # Split original multiblock grid into a list of multiblock grids
        # that correspond to each component based on zone names
        gridList, nameList = explodeByZoneName(curGrid)

        # Save each grid
        for grid in gridList:
            fileName = grid.name
            grid.writeToCGNS(fileName + ".cgns")

        # Finish execution
        sys.exit(0)

    elif args.mode == "info":
        curGrid.printInfo()
        sys.exit(0)

    elif args.mode == "extrude":
        curGrid.extrude(args.direction)

    elif args.mode == "revolve":
        if args.normalDirection == args.axis:
            print("ERROR: Normal direction and revolve axis cannot be the same. Exiting...")
            sys.exit(0)
        curGrid.revolve(args.normalDirection, args.axis, args.startAngle, args.endAngle, args.nThetas)

    elif args.mode == "extractConv":
        # extracts the convergence history contained in the CGNS file and saves it in a pickle file

        # Check if the user gave a reference name. Otherwise, use the input name as reference
        if args.outFile is None:

            # Get the base name
            outFile = os.path.splitext(os.path.basename(args.gridFile))[0]

            # Add extension based on output type
            if args.outType == "pickle":
                outFile = outFile + ".pickle"
            elif args.outType == "tecplot":
                outFile = outFile + ".dat"

        else:
            outFile = args.outFile

        # The function readGrid already read all the convergence history arrays.
        # Now we just need to save them in a file!
        if args.outType == "pickle":
            with open(outFile, "w") as fid:
                pickle.dump(curGrid.convArray, fid)

        elif args.outType == "tecplot":

            # Create a single 2D array that will contain all data
            data = []

            # Get the number of iterations
            numIter = len(curGrid.convArray[curGrid.convArray.keys()[0]])

            # Append iteration counter
            data.append(range(1, numIter + 1))

            for entry in curGrid.convArray.keys():
                data.append(curGrid.convArray[entry])

            # Convert data to array
            data = numpy.array(data).T

            # Write tecplot results
            write_tecplot_file(outFile, "Convergence", ["Iteration"] + curGrid.convArray.keys(), data)

        # Print log
        print("Saved convergence history into:")
        print(outFile)

        # Finish execution
        sys.exit(0)

    # Write out the grid.
    curGrid.writeToCGNS(outFileName)

    # Possibly copy back to the original:
    if args.outFile is None:
        shutil.copyfile(outFileName, args.gridFile)
        shutil.rmtree(dirpath)
Beispiel #8
0
    def __init__(self, CGNSFile, optionsDict, comm=None, dtype="d", debug=False):
        """
        Create the MultiUSMesh object.

        INPUTS:

        CGNSFile: string -> file name of the CGNS file. This CGNS file should be generated with
        cgns_utils combine, so that the domain names have the appropriate convention. That is,
        domains will have the same name as their original files. Domains that share the same name
        will be grouped to make an IDWarp instance.

        optionsDict: dictionary of dictionaries -> Dictionary containing dictionaries that will
        be used to initialize multiple IDWarp instances. The keys are domain names and the
        values are dictionaries of standard IDWarp options that will be applied to this domain.
        The domains of the full CGNS file that do not have a corresponding entry in optionsDict will
        not be warped. For instance, if the CGNS file has the domains wing.00000, wing.00001, and wing.00002
        associated with a wing mesh that we want to warp, then optionsDict should have an entry for 'wing'.

        Ney Secco 2017-02
        """

        # Check if cs was imported correctly:
        if cs is None:
            raise Error("cgns_utils could not be loaded correctly. MultiUSMesh " "requires cgns_utils to function.")

        # Assign communicator if we do not have one yet
        if comm is None:
            comm = MPI.COMM_WORLD

        # Check if warp has already been set by the complex version
        try:
            self.warp
        except AttributeError:
            curDir = os.path.basename(os.path.dirname(os.path.realpath(__file__)))
            self.warp = MExt("libidwarp", curDir, debug=debug)._module

        # Store communicator
        self.comm = comm

        # Store original file name
        self.CGNSFile = CGNSFile

        # Store scalar type
        self.dtype = dtype

        # Only the root processor will take the combined CGNS file
        # and explode it by instance.
        if self.myID == 0:

            # Initialize list to store the block IDs that belong to each IDWarp instance.
            # For example, suppose that our combined CGNS file has 21 blocks.
            # Blocks 1 to 5 belong to the fuselage
            # Blocks 6 to 12 belong to the wing
            # Blocks 13 to 21 belong to the background mesh
            # Then cgnsBlockIntervals = [[0,5],[5,12],[12,21]
            self.cgnsBlockIntervals = []

            # Initialize array to store volume nodes CGNS intervals for each instance
            self.cgnsVolNodeIntervals = []

            # Initialize block counter
            blockCounter = 0

            # Initialize node counter
            nodeCounter = 0

            # Load the CGNS file
            combined_file = cs.readGrid(CGNSFile)

            # Explode the CGNS file by zones (this will only work if the user used cgns_utils combine
            # to create the input CGNS file, since the explosion uses the domain names)
            grids, zoneNames = cs.explodeByZoneName(combined_file)

            # Save temporary grid files with the exploded zones
            for grid, zoneName in zip(grids, zoneNames):
                grid.writeToCGNS("_" + zoneName + ".cgns")

                # Store the number of blocks in each zone
                self.cgnsBlockIntervals.append([blockCounter, blockCounter + len(grid.blocks)])

                # Count the number of nodes (here is degrees of freedom or nodes*3
                totalNodes = 0
                for blk in grid.blocks:
                    totalNodes += blk.dims[0] * blk.dims[1] * blk.dims[2] * 3

                # Store the number of volume nodes in each zone
                self.cgnsVolNodeIntervals.append([nodeCounter, nodeCounter + totalNodes])

                # Update block counter
                blockCounter = blockCounter + len(grid.blocks)

                # Update node counter
                nodeCounter = nodeCounter + totalNodes

            # Delete grids to free space
            del grids
            del combined_file

        else:

            # Initialize variables to get results in the end
            zoneNames = None
            self.cgnsBlockIntervals = None
            self.cgnsVolNodeIntervals = None

        # Send information to all procs
        zoneNames = self.comm.bcast(zoneNames, root=0)
        self.cgnsBlockIntervals = self.comm.bcast(self.cgnsBlockIntervals, root=0)
        self.cgnsVolNodeIntervals = self.comm.bcast(self.cgnsVolNodeIntervals, root=0)

        # Get names for nearfield meshes.
        # The nearfield mesh names will be the keys of the options dictionary.
        nearfieldNames = optionsDict.keys()

        # Initialize list of IDWarp instances
        self.meshes = []

        # Initialize list to hold indices of the background zones
        self.backgroundInstanceIDs = []

        # Loop over all zones that we found in the combined CGNS file
        for zoneNumber, zoneName in enumerate(zoneNames):

            # Check if the zone belongs to a nearfield mesh
            if zoneName in nearfieldNames:

                # ------------------------------------------------------
                # READING NEARFIELD MESHES (The ones that will be warped)
                #

                # Assign the name of the temporary CGNS file to the options.
                # This is the file that contains the mesh o a single component.
                # Remember that we should use the temporary grid file.
                optionsDict[zoneName]["gridFile"] = "_" + zoneName + ".cgns"

                # Initialize an IDWarp instance with the current options
                if self.dtype == "d":
                    currMesh = self.warp.USMesh(options=optionsDict[zoneName], comm=self.comm)
                elif self.dtype == "D":
                    currMesh = self.warp.USMesh_C(options=optionsDict[zoneName], comm=self.comm)

            else:

                # We have a background mesh

                # Regenerate the temporary filename for the background grid
                bgFile = "_" + zoneName + ".cgns"

                # ------------------------------------------------------
                # READING BACKGROUND MESHES

                # =========================================================#
                # THIS IS A MESSY (HOPEFULLY TEMPORARY) WAY OF LOADING THE
                # BACKGROUND MESH NODES. IF YOU COME UP WITH A BETTER WAY
                # TO GET volNodes, PLEASE ADD IT HERE.
                # volNodes is a flattened vector that contains the background
                # mesh volume nodes that belong to the current proc.

                # Let's try using IDWarp's CGNS loader to extract the bakground nodes.
                # However, we will have to trick IDWarp in order to do this, since it
                # expects a surface mesh in the file.
                # So we will make a copy of the background mesh file, assign an arbitrary
                # wall surface, and then load it with IDWarp

                # Only the root proc will modify the input file
                if self.myID == 0:

                    # Make a copy of the background mesh file
                    os.system("cp " + bgFile + " tmp_bg_file.cgns")

                    # Create a temporary BC file
                    with open("tmp_bcdata.dat", "w") as fid:
                        fid.write("1 iLow BCwall wall\n")

                    # Use CGNS utils to modify the BCs
                    os.system("cgns_utils overwritebc tmp_bg_file.cgns tmp_bcdata.dat")

                # Create dummy set of options just to load the CGNS file
                dummyOptions = {
                    "gridFile": "tmp_bg_file.cgns",
                    "warpType": "unstructured",
                }

                # Initialize an IDWarp instance with the current options
                if self.dtype == "d":
                    currMesh = self.warp.USMesh(options=dummyOptions, comm=self.comm)
                elif self.dtype == "D":
                    currMesh = self.warp.USMesh_C(options=dummyOptions, comm=self.comm)

                # Initialize a dummy surface in the background mesh
                """
                if self.myID == 0:
                    print('===========================================')
                    print('ATTENTION: This is a dummy initialization for background mesh warping.')
                pts = np.array([[1.0, 0.0, 1.0],
                                [2.0, 0.0, 1.0],
                                [2.0, 1.0, 1.0],
                                [1.0, 1.0, 1.0]])*(self.myID+1)
                conn = np.array([0,1,2,3])
                faceSizes = np.array([4])
                currMesh.setSurfaceDefinition(pts, conn, faceSizes)
                if self.myID == 0:
                    print('Dummy initialization is Done!')
                    print('===========================================')
                """
                if self.myID == 0:
                    print("===========================================")
                    print("ATTENTION: This is a dummy initialization for background mesh warping.")

                currMesh._setInternalSurface()

                if self.myID == 0:
                    print("Dummy initialization is Done!")
                    print("===========================================")

                # The root proc can remove the temporary files
                if self.myID == 0:

                    # Make a copy of the background mesh file
                    os.system("rm tmp_bg_file.cgns")
                    os.system("rm tmp_bcdata.dat")

                # Store the ID of this zone
                self.backgroundInstanceIDs.append(zoneNumber)

            # Append the instance to the list.
            # We will store even the background mesh instances for now,
            # but we will delete them as soon as we call self.setExternalMeshIndices().
            self.meshes.append(currMesh)

        # Now the root proc can remove the temporary grid files
        if self.myID == 0:
            for zoneName in zoneNames:
                os.system("rm _" + zoneName + ".cgns")

        # ------------------------------------------------------
        # Initialize other fields for completness
        self.numSurfNodes = None  # How many solver surface nodes we have in the current proc, for all instances
        self.numVolNodes = None  # How many solver volume nodes we have in the current proc, for all instances
        self.cgnsVolNodeMasks = []  # Mask used to filter which volume nodes given by the solver belong to each instance
Beispiel #9
0
def simpleOCart(nearFile,
                dh,
                hExtra,
                nExtra,
                sym,
                mgcycle,
                outFile,
                userOptions=None):
    """
    Generates a Cartesian mesh around the provided grid, surrounded by an O-mesh.

    Parameters
    ----------
    nearFile : str
        The name of the nearfield CGNS file to mesh around.

    dh : float or list of float
        The target edge length of each cell in the Cartesian part of the mesh.
        A list of (x, y, z) lengths can be provided to make non-cubic cells.
        The actual edge lengths will depend on mgcycle.

    hExtra : float
        The distance from the Cartesian mesh boundary to the farfield.

    nExtra : int
        The number of layers to extrude the hyperbolic O-mesh.

    sym : str or list of str
        Axis or plane of symmetry.
        One or more of ('x', 'y', 'z', 'xmin', 'xmax', 'ymin', 'ymax', 'zmin', 'zmax').

    mgcycle : int or list of int
        Number of times mesh should be able to be coarsened for multigrid cycles.
        A list can be provided for nonuniform (x, y, z) coarsening.

    outFile : str
        Output file name.

    userOptions : dict, optional
        The name of the nearfield CGNS file to mesh around.

    """

    # Read the nearfield file
    grid = readGrid(nearFile)

    # First run simpleCart with no extension
    X, dx = grid.simpleCart(dh, 0.0, 0, sym, mgcycle, outFile=None)

    # Pull out the patches from the Cartesian mesh.
    # We have to pay attention to the symmetry and the ordering of the patches
    # to make sure that all the normals are pointing out.
    patches = []

    # First take patches that are opposite from the origin planes
    if "xmax" not in sym:
        patches.append(X[-1, :, :, :])
    if "ymax" not in sym:
        patches.append(X[:, -1, :, :][::-1, :, :])
    if "zmax" not in sym:
        patches.append(X[:, :, -1, :])

    # Then take patches from the origin planes
    if "x" not in sym and "xmin" not in sym:
        patches.append(X[0, :, :, :][::-1, :, :])
    if "y" not in sym and "ymin" not in sym:
        patches.append(X[:, 0, :, :])
    if "z" not in sym and "zmin" not in sym:
        patches.append(X[:, :, 0, :][::-1, :, :])

    # Set up the generic input for pyHyp
    hypOptions = {
        "patches": patches,
        "unattachedEdgesAreSymmetry": True,
        "outerFaceBC": "farfield",
        "autoConnect": True,
        "BC": {},
        "N": nExtra,
        "s0": np.average(dx),
        "marchDist": hExtra,
        "cmax": 3.0,
    }

    # Use user-defined options if provided
    if userOptions is not None:
        hypOptions.update(userOptions)

    # Run pyHyp
    hyp = pyHyp(options=hypOptions)
    hyp.run()

    fName = None
    if MPI.COMM_WORLD.rank == 0:
        dirpath = tempfile.mkdtemp()
        fName = os.path.join(dirpath, "tmp.cgns")

    hyp.writeCGNS(MPI.COMM_WORLD.bcast(fName))

    # Reset symmetry to single axis
    if "x" in sym or "xmin" in sym or "xmax" in sym:
        sym = "x"
    elif "y" in sym or "ymin" in sym or "ymax" in sym:
        sym = "y"
    elif "z" in sym or "zmin" in sym or "zmax" in sym:
        sym = "z"

    if MPI.COMM_WORLD.rank == 0:
        # Read the pyhyp mesh back in and add our additional "X" from above.
        grid = readGrid(fName)
        dims = X.shape[0:3]
        grid.addBlock(Block("interiorBlock", dims, X))
        grid.renameBlocks()
        grid.connect()
        grid.BCs = []
        grid.autoFarfieldBC(sym)
        grid.writeToCGNS(outFile)

        # Delete the temp file
        os.remove(fName)
Beispiel #10
0
 def setUp(self):
     self.grid = readGrid(
         os.path.abspath(
             os.path.join(baseDir, "../examples/block_4x2x3.cgns")))