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
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