def prerelaxNodeDistribution(self,
                                 hourglass,
                                 rho,
                                 maxIterations=100,
                                 tol=1.0e-5):

        # What did the user pass in for rho?
        if type(rho) == type(1.0):
            rho = ConstantRho(rho)

        db = self.integrator.dataBase
        nodeLists = db.fluidNodeLists()
        boundaries = self.integrator.uniqueBoundaryConditions()
        allpackages = self.integrator.physicsPackages()
        packages = eval("vector_of_Physics%id()" % db.nDim)
        packages.append(hourglass)

        # A helpful method for setting the density.
        def setRho():
            for nodes in nodeLists:
                pos = nodes.positions()
                massDensity = nodes.massDensity()
                for i in xrange(nodes.numInternalNodes):
                    massDensity[i] = rho(pos[i])

        setRho()

        # Iterate until we're done.
        iter = 0
        maxDisp = 2.0 * tol
        while (iter < maxIterations and maxDisp > tol):
            iter += 1
            oldpos = db.fluidPosition
            oldpos.copyFields()
            state = eval("State%id(db, allpackages)" % db.nDim)
            derivs = eval("StateDerivatives%id(db, allpackages)" % db.nDim)
            self.integrator.initialize(state, derivs)
            state.update(derivs, 1.0, 0.0, 1.0)
            self.integrator.enforceBoundaries()
            self.integrator.applyGhostBoundaries()
            self.integrator.postStateUpdate()
            self.integrator.finalizeGhostBoundaries()
            self.integrator.finalize(0.0, 0.0, db, state, derivs)

            # Check the displacements.
            maxDisp = 0.0
            newpos = db.fluidPosition
            for (oldf, newf) in zip(oldpos, newpos):
                maxDisp = max([(old - new).magnitude() for old, new in zip(
                    oldf.internalValues(), newf.internalValues())] + [0.0])
            maxDisp = mpi.allreduce(maxDisp, mpi.MAX)
            print " --> Iteration %i : max change = %g" % (iter, maxDisp)

        # That's about it.
        setRho()
        return
Beispiel #2
0
def distributeNodesInRange1d(listOfNodeTuples,
                             nPerh = 2.01,
                             reverse = False):


    # Count how many nodes total we need to distribute.
    numNodesPerNodeList = []
    for nodeTuple in listOfNodeTuples:
        assert len(nodeTuple) == 2 or len(nodeTuple) == 4
        if len(nodeTuple) == 2:
            numNodesPerNodeList.append(sum([n for n, rho, (x1, x2) in nodeTuple[1]]))
        else:
            numNodesPerNodeList.append(nodeTuple[1])
    totalNumNodes = sum(numNodesPerNodeList)

    # Determine the global node ID range for this domain.
    nNodesPerDomain = totalNumNodes/mpi.procs
    minNodeID = mpi.rank*nNodesPerDomain
    if mpi.rank == mpi.procs - 1:
        maxNodeID = totalNumNodes
    else:
        maxNodeID = minNodeID + nNodesPerDomain

    # Iterate over each NodeList and assign its nodes.
    nCumulative = 0
    for nodeTuple in listOfNodeTuples:
        if len(nodeTuple) == 2:
            nodes, initialConditions = nodeTuple
            pos = nodes.positions()
            mass = nodes.mass()
            H = nodes.Hfield()
            rho = nodes.massDensity()
            for n, rho0, (x0, x1) in initialConditions:
                if type(rho0) == float:
                    rhof = ConstantRho(rho0)
                else:
                    rhof = rho0
                if minNodeID <= (nCumulative + n) and maxNodeID >= nCumulative:
                    iglobal0 = max(minNodeID, nCumulative)
                    iglobal1 = min(maxNodeID, nCumulative + n)
                    numNewNodes = iglobal1 - iglobal0
                    nodeOffset = iglobal0 - nCumulative
                    indexOffset = nodes.numInternalNodes
                    nodes.numInternalNodes += numNewNodes
                    dx = (x1 - x0)/max(1, n)
                    Hi = SymTensor1d(1.0/max(nodes.hmin, min(nodes.hmax, nPerh*dx)))
                    for i in xrange(numNewNodes):
                        if reverse:
                            xi = x1 - (nodeOffset + i + 0.5)*dx
                        else:
                            xi = x0 + (nodeOffset + i + 0.5)*dx
                        pos[indexOffset + i].x = xi
                        mass[indexOffset + i] = dx*rhof(xi)
                        rho[indexOffset + i] = rhof(xi)
                        H[indexOffset + i] = Hi
                nCumulative += n
        else:
            nodes, n, rho0, (x0, x1) = nodeTuple
            if type(rho0) == float:
                rhof = ConstantRho(rho0)
            else:
                rhof = rho0
            pos = nodes.positions()
            mass = nodes.mass()
            H = nodes.Hfield()
            rho = nodes.massDensity()
            if minNodeID <= (nCumulative + n) and maxNodeID >= nCumulative:
                iglobal0 = max(minNodeID, nCumulative)
                iglobal1 = min(maxNodeID, nCumulative + n)
                numNewNodes = iglobal1 - iglobal0
                assert numNewNodes > 0
                nodeOffset = iglobal0 - nCumulative
                indexOffset = nodes.numInternalNodes
                nodes.numInternalNodes += numNewNodes
                dx = (x1 - x0)/max(1, n)
                Hi = SymTensor1d(1.0/max(nodes.hmin, min(nodes.hmax, nPerh*dx)))
                for i in xrange(numNewNodes):
                    if reverse:
                        xi = x1 - (nodeOffset + i + 0.5)*dx
                    else:
                        xi = x0 + (nodeOffset + i + 0.5)*dx
                    pos[indexOffset + i].x = xi
                    mass[indexOffset + i] = dx*rhof(xi)
                    rho[indexOffset + i] = rhof(xi)
                    H[indexOffset + i] = Hi
            nCumulative += n

    # Set neighbor information.
    #Neighbor1d.setBoundingBox()
    for nodeTuple in listOfNodeTuples:
        nodes = nodeTuple[0]
        nodes.neighbor().updateNodes()
        assert nodes.neighbor().valid()

    return