def pflatten_node_list_list(nls,filename,do_header=True,silent=False):
    """Flatten a list of node lists to a rectangular ascii file.

    pflatten_node_list_list(nls,filename) writes meta data about the node lists
    in nls, which must be either a list or a tuple of valid node lists, to a 
    header of the file filename, and then calls pflatten_node_list(nl,filename)
    for each nl in nls.

    pflatten_node_list_list(...,do_header=False) omits the header.

    See also: pflatten_node_list
    """

    # Make sure we are not wasting our time.
    assert isinstance(nls,(list,tuple)), "argument 1 must be a list or tuple"
    assert isinstance(filename, str), "argument 2 must be a simple string"
    assert isinstance(do_header, bool), "true or false"
    assert isinstance(silent, bool), "true or false"
    for nl in nls:
        assert isinstance(nl,(sph.Spheral.NodeSpace.FluidNodeList3d,
                                  sph.Spheral.SolidMaterial.SolidNodeList3d)
                         ), "argument 1 must contain node lists"

    # Determine if file should be compressed.
    if os.path.splitext(filename)[1] == '.gz':
        import gzip
        open = gzip.open
    else:
        import __builtin__
        open = __builtin__.open

    # Write the header.
    if do_header:
        nbGlobalNodes = 0
        for nl in nls:
            nbGlobalNodes += mpi.allreduce(nl.numInternalNodes, mpi.SUM)
        header = header_template.format(nbGlobalNodes)
        if mpi.rank == 0:
            fid = open(filename,'w')
            fid.write(header)
            fid.close()
            pass
        pass

    # Send contents of nls to be flattened.
    for k in range(len(nls)):
        pflatten_node_list(nls[k],filename,do_header=False,nl_id=k,silent=silent)
        pass

    # And Bob's our uncle.
    return
Exemple #2
0
    def integrate(self, rectangles, function):
        # equivalent to mpi.WORLD.bcast(n,0) or rather a
        # C call to MPI_Bcast(MPI_COMM_WORLD,n,0,&status)
        n = mpi.bcast(rectangles)

        h = 1.0/n
        sum = 0.0
        for i in range(mpi.rank+1,n+1,mpi.procs):
            x = h * (i-0.5)
            sum = sum + function(x)

        myAnswer = h * sum
        answer = mpi.allreduce(myAnswer,mpi.SUM)
        return answer
Exemple #3
0
def computePi( size, nsamples):
    oldpi, pi, mypi,pisum = 0.0,0.0,0.0,0.0
    done = False
    
    inside = 0
    # Monte Carlo bit
    for i in xrange(nsamples):
        x = random.random()
        y = random.random()
        if ((x*x)+(y*y)<1):
            inside+=1
    # 
    sum_inside = mpi.allreduce(inside, 1, mpi.MPI_INT, mpi.MPI_SUM, mpi.MPI_COMM_WORLD) 
    # The "* 4" is needed because we're computing the number of points inside
    # a QUARTER unit circle.  So we're really computing (PI / 4).
    pi = ( sum_inside[0] / (nsamples*size*1.0) ) * 4
    return pi
Exemple #4
0
    def parallelRunTest(self):
        v = 1+(mpi.rank)%2

        results = []
        for kind in ['MAX','MIN','SUM','PROD','LAND',
                     'LOR','LXOR',
                     'MINLOC','MAXLOC' ]:
            function = getattr(mpi,kind)
            try:
                r0 = mpi.allreduce(v,function)
            except RuntimeError,s:
                self.fail("All reduce") 

            try:
                r1 = mpi.reduce(v,function)
            except RuntimeError,s:
                self.fail("All reduce") 
Exemple #5
0
    def parallelRunTest(self):
        #decide on targets
        #values to be reduced
        num1 = mpi.rank
        num2 = 0
        if mpi.rank == 1:
            num2 = 1
        num3 = 1
        string1 = "FoO"
        list1 = [ mpi.rank + 1 ]
        list2 = [ mpi.rank]
        longList = []
        for i in range(2048):
            longList += [ 1 - mpi.rank*mpi.rank, "oOf"]

        #do all reduces
        results = [0,0,0,    0,0,0  ]
        results[0] = mpi.allreduce( num2,   mpi.LOR)
        results[1] = mpi.allreduce( list1,   mpi.LAND)
        results[2] = mpi.allreduce( list2, mpi.SUM)
        results[3] = mpi.allreduce( string1,  mpi.SUM)
        results[4] = mpi.allreduce( list1,  mpi.MAXLOC)
        results[5] = mpi.allreduce( longList,  mpi.MAXLOC)

        #correct answers
        correctAnswers = [ 0,0,[],"",0, () ]
        correctList = []
        correctAnswers[0] = 1
        correctAnswers[1] = 1
        correctAnswers[3] = "FoO"*mpi.procs
        correctAnswers[4] = (mpi.procs-1, [mpi.procs])
        for x in range(mpi.procs):
            correctAnswers[2] += [x]
        for x in range(2048):
            correctList += [1, "oOf"]
        correctAnswers[5] = (0, correctList)

        for x in range(6):
            if results[x] != correctAnswers[x]:
                failString = "All Reduce failed on test " + str(x)
                failString += "\nAllReduce gave result " + str(results[x])
                failString += " while correct answer is "
                failString += str(correctAnswers[x]) + "\n"
                self.fail(failString)
        return
def cooldown(stepsSoFar,timeNow,dt):
    nbGlobalNodes = mpi.allreduce(sum([nl.numInternalNodes for nl in nodeSet]),
                                  mpi.SUM)
    massScale = mPlanet/nbGlobalNodes
    timeScale = 0.1*gravTime
    dashpotParameter = cooldownPower*massScale/timeScale
    for nl in nodeSet:
        v = nl.velocity()
        m = nl.mass()
        u = nl.specificThermalEnergy()
        if cooldownMethod == 'dashpot':
            for k in range(nl.numInternalNodes):
                v[k] *= 1.0 - min(dashpotParameter*dt/m[k], 1)
                u[k] *= 0.0 #TODO: maybe improve this
                pass
            pass
        elif cooldownMethod == 'stomp':
            for k in range(nl.numInternalNodes):
                v[k] *= 1.0 - cooldownPower
                u[k] *= 0.0 #TODO maybe improve this
                pass
            pass
        pass
    pass
Exemple #7
0
    def testIt(self):
        print "Testing TreeDistributedBoundary1d on domain %i of %i domains" % \
              (domainID, nDomains)

        # Set the ghost nodes for each domain distributed NodeList.
        self.domainbc.setAllGhostNodes(self.dataBase)
        self.domainbc.finalizeGhostBoundary()
        for nodes in self.dataBase.nodeLists():
            nodes.neighbor().updateNodes()

        # Exchange the global node ID fields.
        self.domainbc.applyGhostBoundary(self.globalIDField1)
        self.domainbc.applyGhostBoundary(self.globalIDField2)
        self.domainbc.applyGhostBoundary(self.globalIDField3)
        self.domainbc.finalizeGhostBoundary()

        # Iterate over each domain.
        for testProc in xrange(mpi.procs):

            # Test each NodeList.
            for (nodes, globalIDField) in ((self.nodes1, self.globalIDField1),
                                           (self.nodes2, self.globalIDField2),
                                           (self.nodes3, self.globalIDField3)):

                # Tell everyone how many nodes we'll be testing, and iterate
                # over them
                n = mpi.bcast(nodes.numInternalNodes, testProc)
                for i in xrange(n):

                    # Broadcast the position and H from the testing processor.
                    rilocal = Vector1d()
                    Hilocal = SymTensor1d()
                    if mpi.rank == testProc:
                        rilocal = nodes.positions()[i]
                        Hilocal = nodes.Hfield()[i]
                    ri = mpi.bcast(rilocal, testProc)
                    Hi = mpi.bcast(Hilocal, testProc)

                    # Get the global answer set for this node.
                    answer = mpi.allreduce([
                        self.globalIDField1[j] for j in findNeighborNodes(
                            ri, Hi, self.kernelExtent, self.nodes1)
                    ] + [
                        self.globalIDField2[j] for j in findNeighborNodes(
                            ri, Hi, self.kernelExtent, self.nodes2)
                    ] + [
                        self.globalIDField3[j] for j in findNeighborNodes(
                            ri, Hi, self.kernelExtent, self.nodes3)
                    ], mpi.SUM)

                    # Have the testing processor build it's own version.
                    if mpi.rank == testProc:
                        masterLists = vector_of_vector_of_int()
                        coarseNeighbors = vector_of_vector_of_int()
                        refineNeighbors = vector_of_vector_of_int()
                        self.dataBase.setMasterNodeLists(
                            ri, Hi, masterLists, coarseNeighbors)
                        self.dataBase.setRefineNodeLists(
                            ri, Hi, coarseNeighbors, refineNeighbors)
                        assert len(refineNeighbors) == 3
                        refine = []
                        for k, globalIDs in enumerate([
                                self.globalIDField1, self.globalIDField2,
                                self.globalIDField3
                        ]):
                            refine.extend(
                                [globalIDs[j] for j in refineNeighbors[k]])

                        # Check the answer.
                        test = checkNeighbors(refine, answer)
                        if not test:
                            sys.stderr.write("FAILED for node %i\n" % i)
                            refine.sort()
                            answer.sort()
                            sys.stderr.write(" refine: %s\n" % str(refine))
                            sys.stderr.write(" answer: %s\n" % str(answer))
                            sys.stderr.write(
                                "  extra: %s\n" %
                                str([x for x in refine if x not in answer]))
                            sys.stderr.write(
                                "missing: %s\n" %
                                str([x for x in answer if x not in refine]))
                        else:
                            sys.stderr.write("PASSED for node %i\n" % i)
                        assert test
Exemple #8
0
#-------------------------------------------------------------------------------
# Compute the analytic answer.
#-------------------------------------------------------------------------------
import mpi
import NohAnalyticSolution
rlocal = [pos.x for pos in nodes1.positions().internalValues()]
r = mpi.reduce(rlocal, mpi.SUM)
h1 = 1.0/(nPerh*dx)
answer = NohAnalyticSolution.NohSolution(1,
                                         r = r,
                                         v0 = -1.0,
                                         h0 = 1.0/h1)

# Compute the simulated specific entropy.
rho = mpi.allreduce(nodes1.massDensity().internalValues(), mpi.SUM)
Pf = ScalarField("pressure", nodes1)
nodes1.pressure(Pf)
P = mpi.allreduce(Pf.internalValues(), mpi.SUM)
A = [Pi/rhoi**gamma for (Pi, rhoi) in zip(P, rho)]

# The analytic solution for the simulated entropy.
xprof = mpi.allreduce([x.x for x in nodes1.positions().internalValues()], mpi.SUM)
xans, vans, uans, rhoans, Pans, hans = answer.solution(control.time(), xprof)
Aans = [Pi/rhoi**gamma for (Pi, rhoi) in zip(Pans,  rhoans)]
L1 = 0.0
for i in xrange(len(rho)):
  L1 = L1 + abs(rho[i]-rhoans[i])
L1_tot = L1 / len(rho)
if mpi.rank == 0 and outputFile != "None":
 print "L1=",L1_tot,"\n"
Exemple #9
0
def fragmentProperties(nodeList, fragField, strain=None):

    startTime = time.time()

    # Decide what our dimensionality is.
    if isinstance(nodeList, Spheral.NodeList1d):
        Vector = Spheral.Vector1d
        SymTensor = Spheral.SymTensor1d
        ScalarField = Spheral.ScalarField1d
    elif isinstance(nodeList, Spheral.NodeList2d):
        Vector = Spheral.Vector2d
        SymTensor = Spheral.SymTensor2d
        ScalarField = Spheral.ScalarField2d
    elif isinstance(nodeList, Spheral.NodeList3d):
        Vector = Spheral.Vector3d
        SymTensor = Spheral.SymTensor3d
        ScalarField = Spheral.ScalarField3d
    else:
        raise "fragmentProperties ERROR: What the heck is %s!  I expected a NodeList." % str(
            nodeList)

    # Are we compiling stats on the strain?
    usingStrain = not (strain is None)

    # Determine how many fragments there are.
    numFragments = mpi.allreduce(max(list(fragField.internalValues()) + [0]),
                                 mpi.MAX) + 1
    assert numFragments >= 1

    # Prepare the result.
    result = {}
    for i in xrange(numFragments):
        result[i] = {
            "mass": 0.0,
            "num nodes": 0,
            "position": Vector(),
            "velocity": Vector(),
            "volume": 0.0,
            "mass density": 0.0,
            "thermal energy": 0.0,
            "pressure": 0.0,
            "shape tensor": SymTensor(),
            "shape eigen": Vector(),
        }
        if usingStrain:
            result[i]["strain (min)"] = 0.0
            result[i]["strain (max)"] = 0.0
            result[i]["strain (vol)"] = 0.0
    assert len(result) == numFragments

    # Grab the state fields.
    mass = nodeList.mass()
    position = nodeList.positions()
    velocity = nodeList.velocity()
    rho = nodeList.massDensity()
    u = nodeList.specificThermalEnergy()
    P = ScalarField("pressure", nodeList)
    nodeList.pressure(P)

    # Now iterate over the nodes and accumulate the local result.
    for i in xrange(nodeList.numInternalNodes):
        fragID = fragField[i]
        assert fragID < numFragments
        mi = mass[i]
        result[fragID]["mass"] += mi
        result[fragID]["num nodes"] += 1
        result[fragID]["position"] += position[i] * mi
        result[fragID]["velocity"] += velocity[i] * mi
        result[fragID]["volume"] += mi / rho[i]
        result[fragID]["mass density"] += mi * rho[i]
        result[fragID]["thermal energy"] += mi * u[i]
        result[fragID]["pressure"] += mi * P[i]
        if usingStrain:
            sev = strain[i].eigenValues()
            result[fragID]["strain (min)"] += mi * sev.minElement()
            result[fragID]["strain (max)"] += mi * sev.maxElement()
            result[fragID]["strain (vol)"] += mi * sev.sumElements()
    assert fuzzyEqual(sum([result[i]["mass"] for i in result]),
                      sum(nodeList.mass().internalValues()))

    # Reduce for the global fragment properties.
    assert mpi.allreduce(len(result), mpi.SUM) == numFragments * mpi.procs
    for fragID in xrange(numFragments):
        mfrag = mpi.allreduce(result[fragID]["mass"], mpi.SUM)
        assert mfrag > 0.0
        result[fragID]["mass"] = mfrag
        result[fragID]["num nodes"] = mpi.allreduce(
            result[fragID]["num nodes"], mpi.SUM)
        result[fragID]["position"] = mpi.allreduce(result[fragID]["position"],
                                                   mpi.SUM) / mfrag
        result[fragID]["velocity"] = mpi.allreduce(result[fragID]["velocity"],
                                                   mpi.SUM) / mfrag
        result[fragID]["volume"] = mpi.allreduce(result[fragID]["volume"],
                                                 mpi.SUM)
        result[fragID]["mass density"] = mpi.allreduce(
            result[fragID]["mass density"], mpi.SUM) / mfrag
        result[fragID]["thermal energy"] = mpi.allreduce(
            result[fragID]["thermal energy"], mpi.SUM) / mfrag
        result[fragID]["pressure"] = mpi.allreduce(result[fragID]["pressure"],
                                                   mpi.SUM) / mfrag
        if usingStrain:
            result[fragID]["strain (min)"] = mpi.allreduce(
                result[fragID]["strain (min)"], mpi.SUM) / mfrag
            result[fragID]["strain (max)"] = mpi.allreduce(
                result[fragID]["strain (max)"], mpi.SUM) / mfrag
            result[fragID]["strain (vol)"] = mpi.allreduce(
                result[fragID]["strain (vol)"], mpi.SUM) / mfrag

    # Now that we have the center of mass for each fragment, we can evaluate the shape tensors.
    for i in xrange(nodeList.numInternalNodes):
        fragID = fragField[i]
        assert fragID < numFragments
        mi = mass[i]
        dr = position[i] - result[fragID]["position"]
        result[fragID]["shape tensor"] += dr.selfdyad() * mi

    # Reduce the global shapes.
    for fragID in xrange(numFragments):
        mfrag = result[fragID]["mass"]
        assert mfrag > 0.0
        result[fragID]["shape tensor"] = mpi.allreduce(
            result[fragID]["shape tensor"], mpi.SUM) / mfrag
        result[fragID]["shape eigen"] = result[fragID][
            "shape tensor"].eigenValues()

    # That's it.
    assert fuzzyEqual(
        sum([result[i]["mass"] for i in result]),
        mpi.allreduce(sum(nodeList.mass().internalValues()), mpi.SUM))

    stopTime = time.time()
    print "fragmentProperties:  Required %g seconds." % (stopTime - startTime)

    return result
Exemple #10
0
def hadesDump0(integrator,
               nsample,
               xmin,
               xmax,
               W,
               isotopes,
               baseFileName,
               baseDirectory=".",
               dumpGhosts=False,
               materials="all"):

    # We currently only support 3-D.
    assert isinstance(integrator, Spheral.Integrator3d)
    assert len(nsample) == 3
    assert isinstance(xmin, Spheral.Vector3d)
    assert isinstance(xmax, Spheral.Vector3d)
    assert isinstance(W, Spheral.TableKernel3d)
    for x in isotopes:
        for xx in x:
            assert len(xx) == 2

    # Prepare to time how long this takes.
    t0 = time.clock()

    # Extract the data base.
    db = integrator.dataBase()

    # If requested, set ghost node info.
    if dumpGhosts and not integrator is None:
        state = Spheral.State3d(db, integrator.physicsPackages())
        derivs = Spheral.StateDerivatives3d(db, integrator.physicsPackages())
        integrator.setGhostNodes()
        integrator.applyGhostBoundaries(state, derivs)

    # Get the set of material names we're going to write.
    if materials == "all":
        materials = [n for n in db.fluidNodeLists()]
    assert len(materials) == len(isotopes)

    # Make sure the output directory exists.
    import mpi
    import os
    if mpi.rank == 0 and not os.path.exists(baseDirectory):
        try:
            os.makedirs(baseDirectory)
        except:
            raise "Cannot create output directory %s" % baseDirectory
    mpi.barrier()

    # Open a file for the output.
    currentTime = integrator.currentTime
    currentCycle = integrator.currentCycle
    filename = baseDirectory + "/" + baseFileName + "-time=%g-cycle=%i.hades" % (
        currentTime, currentCycle)

    if mpi.rank == 0:
        f = open(filename, "wb")

        # Write the header info.
        #f.write(hadesHeader)
        f.write(struct.pack("I", len(materials)))
        f.write(struct.pack("ddd", *tuple(xmin.elements())))
        f.write(struct.pack("ddd", *tuple(xmax.elements())))
        f.write(struct.pack("III", *nsample))
        for materialIsotopes in isotopes:
            f.write(struct.pack("I", len(materialIsotopes)))
            for iso in materialIsotopes:
                f.write(struct.pack("Id", *iso))

    # For each material, sample the mass density and write it out.
    ntot = nsample[0] * nsample[1] * nsample[2]
    for nodes in materials:
        r = Spheral.VectorFieldList3d()
        w = Spheral.ScalarFieldList3d()
        H = Spheral.SymTensorFieldList3d()
        rho = Spheral.ScalarFieldList3d()
        r.appendField(nodes.positions())
        w.appendField(nodes.weight())
        H.appendField(nodes.Hfield())
        rho.appendField(nodes.massDensity())
        fieldListSet = Spheral.FieldListSet3d()
        fieldListSet.ScalarFieldLists.append(rho)
        rhosamp = Spheral.sampleMultipleFields2LatticeMash(
            fieldListSet, r, w, H, W, xmin, xmax, nsample)[0][0][1]
        assert mpi.allreduce(len(rhosamp), mpi.SUM) == ntot
        icum = 0
        for sendProc in xrange(mpi.procs):
            valsproc = [(i, x) for (i, x) in zip(range(ntot), rhosamp)
                        if x > 0.0]
            vals = mpi.bcast(valsproc, sendProc)
            if mpi.rank == 0:
                f.write(struct.pack("I", len(vals)))
                for i, x in vals:
                    f.write(struct.pack("id", i + icum, x))
            icum += len(vals)

    if mpi.rank == 0:
        # Close the file and we're done.
        f.close()

    mpi.barrier()
    print "hadesDump finished: required %0.2f seconds" % (time.clock() - t0)

    return
Exemple #11
0
        result = [pos[i].x, vel[i].x, rho[i], eps[i], P[i]]
    else:
        result = []
    result = mpi.allreduce(result, mpi.SUM)
    return tuple(result)

# Al sample points.
histories = []
tracerNumber = 1
for nodes, samplePositions in ((nodesAl, (-0.0375, -0.0625, -0.9875)),
                               (nodesTa, ( 0.0375,  0.0625,  0.9875))):
    pos = nodes.positions()
    for x0 in samplePositions:
        thpt = [(abs(pos[i].x - x0), i) for i in xrange(nodes.numInternalNodes)] + [(1e100, -1)]
        thpt.sort()
        dxmin = mpi.allreduce(thpt[0][0], mpi.MIN)
        if thpt[0][0] == dxmin:
            i = thpt[0][1]
            indices = [i]
            sys.stderr.write("Tracer %i is node %i @ %s.\n" % (tracerNumber, i, pos[i]))
        else:
            indices = []
        histories.append(NodeHistory(nodes, indices, tp106tracersample, tracerOutputName % tracerNumber, 
                                     labels = ("pos", "vel", "rho", "eps", "P")))
        tracerNumber += 1

#-------------------------------------------------------------------------------
# Build the controller.
#-------------------------------------------------------------------------------
control = SpheralController(integrator, WT,
                            statsStep = statsStep,
Exemple #12
0
    def sample(self, cycle, ttime, dt):

        # Import the geometry appropriate Spheral types.
        assert self.geometry in ("1d", "2d", "3d", "RZ")
        exec("from Spheral%s import *" % self.geometry)

        # Do we need to initialize anything?
        if self.initializefunc:
            self.initializefunc()

        # How many sample values are we going for?
        for nodeListi, nodeList in enumerate(self.db.fluidNodeLists()):
            if nodeList.numNodes > 0:
                nvals = len(self.samplefunc(nodeListi, 0))
        assert nvals > 0

        # Prepare empty slots in the history.
        self.cycleHistory.append(cycle)
        self.timeHistory.append(ttime)
        self.sampleHistory.append([0.0] * nvals)
        Wsum = 0.0

        # Grab position and H FieldLists.
        positions = self.db.globalPosition
        H = self.db.globalHfield

        # Prepare the Neighbor information for sampling at this pos, and walk the neighbors.
        self.db.setMasterNodeLists(self.position, SymTensor.zero)
        self.db.setRefineNodeLists(self.position, SymTensor.zero)
        for nodeListj, nodeList in enumerate(self.db.fluidNodeLists()):
            for j in nodeList.neighbor().coarseNeighborList:

                # Compute the weighting for this position.
                posj = positions(nodeListj, j)
                Hj = H(nodeListj, j)
                Wj = self.W.kernelValue(
                    (Hj * (posj - self.position)).magnitude(), 1.0)**2
                Wsum += Wj

                # Use the user supplied method to extract the field values for this (nodeList, index)
                fieldvals = self.samplefunc(nodeListj, j)
                assert len(fieldvals) == nvals

                # Increment the sampled values for this position.
                for i in xrange(nvals):
                    self.sampleHistory[-1][i] += Wj * fieldvals[i]

        # Normalize the measurements.
        Wsum = max(1.0e-10, mpi.allreduce(Wsum, mpi.SUM))
        for i in xrange(nvals):
            self.sampleHistory[-1][i] = mpi.allreduce(
                self.sampleHistory[-1][i], mpi.SUM) / Wsum

        # Update the history file.
        if mpi.rank == 0:
            assert self.file is not None
            samplestr = ""
            for x in self.sampleHistory[-1]:
                samplestr += str(x) + " "
            self.file.write("%i \t %g \t %s\n" % (cycle, ttime, samplestr))
            self.file.flush()

        return
Exemple #13
0
def hadesDump(integrator,
              nsample,
              xmin,
              xmax,
              W,
              baseFileName,
              baseDirectory=".",
              procDirBaseName="domains",
              mask=None,
              materials=None):

    # Currently suppport 2D and 3D.
    db = integrator.dataBase()
    if db.nDim == 2:
        import Spheral2d as sph
    elif db.nDim == 3:
        import Spheral3d as sph
    else:
        raise RuntimeError, "hadesDump ERROR: must be 2D or 3D"

    # Prepare to time how long this takes.
    t0 = time.clock()

    # Get the set of material names we're going to write.
    if materials is None:
        materials = list(db.fluidNodeLists())

    # HACK!  We are currently restricting to writing single material output!
    assert len(materials) == 1

    # Make sure the output directory exists.
    if mpi.rank == 0 and not os.path.exists(baseDirectory):
        try:
            os.makedirs(baseDirectory)
        except:
            raise RuntimeError, "Cannot create output directory %s" % baseDirectory
    mpi.barrier()

    # Sample the density.
    ntot = reduce(mul, nsample)
    for nodes in materials:
        print "hadesDump: sampling density for %s..." % nodes.name
        r = sph.VectorFieldList()
        H = sph.SymTensorFieldList()
        rho = sph.ScalarFieldList()
        r.appendField(nodes.positions())
        H.appendField(nodes.Hfield())
        rho.appendField(nodes.massDensity())

        mf = nodes.mass()
        rhof = nodes.massDensity()
        wf = sph.ScalarField("volume", nodes)
        for i in xrange(nodes.numNodes):
            wf[i] = mf[i] / max(1e-100, rhof[i])
        w = sph.ScalarFieldList()
        w.copyFields()
        w.appendField(wf)
        #w.appendField(sph.ScalarField("weight", nodes, 1.0))

        fieldListSet = sph.FieldListSet()
        fieldListSet.ScalarFieldLists.append(rho)
        localMask = sph.IntFieldList()
        if mask is None:
            localMask.copyFields()
            localMask.appendField(sph.IntField("mask", nodes, 1))
        else:
            localMask.appendField(mask.fieldForNodeList(nodes))

        scalar_samples = sph.vector_of_vector_of_double()
        vector_samples = sph.vector_of_vector_of_Vector()
        tensor_samples = sph.vector_of_vector_of_Tensor()
        symTensor_samples = sph.vector_of_vector_of_SymTensor()
        nsample_vec = sph.vector_of_int(db.nDim)
        for i in xrange(db.nDim):
            nsample_vec[i] = nsample[i]

        sph.sampleMultipleFields2Lattice(fieldListSet, r, w, H, localMask, W,
                                         xmin, xmax, nsample_vec,
                                         scalar_samples, vector_samples,
                                         tensor_samples, symTensor_samples)
        print "Generated %i scalar fields" % len(scalar_samples)

        # Rearrange the sampled data into rectangular blocks due to Silo's quad mesh limitations.
        rhosamp, xminblock, xmaxblock, nblock, jsplit = shuffleIntoBlocks(
            db.nDim, scalar_samples[0], xmin, xmax, nsample)
        if rhosamp:
            print "rho range: ", min(rhosamp), max(rhosamp)
        print "     xmin: ", xmin
        print "     xmax: ", xmax
        print "xminblock: ", xminblock
        print "xmaxblock: ", xmaxblock
        print "   nblock: ", nblock
        assert mpi.allreduce(len(rhosamp), mpi.SUM) == ntot

    # Write the master file.
    maxproc = writeMasterSiloFile(ndim=db.nDim,
                                  nblock=nblock,
                                  jsplit=jsplit,
                                  baseDirectory=baseDirectory,
                                  baseName=baseFileName,
                                  procDirBaseName=procDirBaseName,
                                  materials=materials,
                                  rhosamp=rhosamp,
                                  label="Spheral++ cartesian sampled output",
                                  time=integrator.currentTime,
                                  cycle=integrator.currentCycle)

    # Write the process files.
    writeDomainSiloFile(ndim=db.nDim,
                        jsplit=jsplit,
                        maxproc=maxproc,
                        baseDirectory=baseDirectory,
                        baseName=baseFileName,
                        procDirBaseName=procDirBaseName,
                        materials=materials,
                        rhosamp=rhosamp,
                        xminblock=xminblock,
                        xmaxblock=xmaxblock,
                        nblock=nblock,
                        label="Spheral++ cartesian sampled output",
                        time=integrator.currentTime,
                        cycle=integrator.currentCycle,
                        pretendRZ=db.isRZ)

    mpi.barrier()
    print "hadesDump finished: required %0.2f seconds" % (time.clock() - t0)
    return
Exemple #14
0
elif problem == "cylindrical":
    bcs = [
        ReflectingBoundary(Plane(Vector(z0, r0), Vector(1.0, 0.0))),
        ReflectingBoundary(Plane(Vector(z1, r0), Vector(-1.0, 0.0))),
        ReflectingBoundary(Plane(Vector(z0, r2), Vector(0.0, -1.0)))
    ]
    if r0 > 0.0:
        bcs.append(ReflectingBoundary(Plane(Vector(z0, r0), Vector(0.0, 1.0))))
else:
    assert problem == "spherical"
    boundNodes = vector_of_int()
    pos = nodes2.positions()
    for i in xrange(nodes2.numInternalNodes):
        if pos[i].magnitude() > rmax2:
            boundNodes.append(i)
    print "Selected %i boundary nodes" % mpi.allreduce(len(boundNodes),
                                                       mpi.SUM)
    denialPlane = Plane(Vector(-2.0 * rmax2, 0.0), Vector(
        1.0, 0.0))  # A fake denial plane since we're working in circles.
    bcs = [
        ReflectingBoundary(Plane(Vector(0.0, 0.0), Vector(1.0, 0.0))),
        ConstantBoundary(nodes2, boundNodes, denialPlane)
    ]

for bc in bcs:
    for p in packages:
        p.appendBoundary(bc)

#-------------------------------------------------------------------------------
# Construct an integrator.
#-------------------------------------------------------------------------------
integrator = IntegratorConstructor(db)
Exemple #15
0
    def __init__(self,
                 surface,
                 rho,
                 nx,
                 nNodePerh=2.01,
                 SPH=False,
                 rejecter=None):
        self.surface = surface
        self.rho0 = rho

        # Figure out bounds and numbers of nodes to scan the volume with.
        xmin = surface.xmin
        xmax = surface.xmax
        box = xmax - xmin
        assert box.minElement > 0.0
        dx = box.x / nx
        ny = max(1, int(box.y / dx + 0.5))
        nz = max(1, int(box.z / dx + 0.5))

        # Some local geometry.
        ntot0 = nx * ny * nz
        dy = box.y / ny
        dz = box.z / nz
        volume = box.x * box.y * box.z
        self.m0 = rho * volume / ntot0
        hx = 1.0 / (nNodePerh * dx)
        hy = 1.0 / (nNodePerh * dy)
        hz = 1.0 / (nNodePerh * dz)
        self.H0 = SymTensor(hx, 0.0, 0.0, 0.0, hy, 0.0, 0.0, 0.0, hz)

        # Build the intial positions.
        pos0 = fillFacetedVolume(surface, nx, mpi.rank, mpi.procs)

        # Something strange here...
        pos = pos0  # [p for p in pos0 if surface.contains(p)]
        nsurface = mpi.allreduce(len(pos), mpi.SUM)

        # Apply any rejecter.
        print "Applying rejection..."
        if rejecter:
            mask = [rejecter.accept(ri.x, ri.y, ri.z) for ri in pos]
        else:
            mask = [True] * len(pos)
        n0 = len(pos)
        self.x = [pos[i].x for i in xrange(n0) if mask[i]]
        self.y = [pos[i].y for i in xrange(n0) if mask[i]]
        self.z = [pos[i].z for i in xrange(n0) if mask[i]]
        n = len(self.x)

        # Pick a mass per point so we get exactly the correct total mass inside the surface
        # before any rejection.
        M0 = surface.volume * self.rho0
        self.m0 = M0 / nsurface
        self.m = [self.m0] * n

        # At this point we have a less than optimal domain decomposition, but this will
        # be redistributed later anyway so take it and run.
        self.rho = [self.rho0] * n
        self.H = [self.H0] * n
        NodeGeneratorBase.__init__(self, False, self.m)
        return
    def __init__(self, nx, ny, rho, xmin, xmax, nNodePerh=2.01, SPH=False):
        assert nx > 0
        assert ny > 0
        assert len(xmin) == 2
        assert len(xmax) == 2
        assert xmax[0] >= xmin[0]
        assert xmax[1] >= xmin[1]
        assert nNodePerh > 0.0

        # Remember the input.
        self.nx = nx
        self.ny = ny
        self.xmin = xmin
        self.xmax = xmax

        # If the user provided a constant for rho, then use the constantRho
        # class to provide this value.
        if type(rho) == type(1.0):
            self.rho = ConstantRho(rho)
        else:
            self.rho = rho

        # Compute the number of domains in each direction.
        lx = xmax[0] - xmin[0]
        ly = xmax[1] - xmin[1]
        nxdomains = int(sqrt(lx / ly * mpi.procs) + 0.1)
        nydomains = int(mpi.procs / nxdomains + 0.1)
        assert nxdomains * nydomains == mpi.procs

        # The number of nodes per domain.
        nxperdomain = nx / nxdomains
        nxremainder = nx % nxdomains
        nyperdomain = ny / nydomains
        nyremainder = ny % nydomains
        assert nxremainder < nxdomains
        assert nyremainder < nydomains

        # Compute the value for H.
        dx = lx / nx
        dy = ly / ny
        hx = nNodePerh * dx
        hy = nNodePerh * dy
        assert hx > 0.0 and hy > 0.0
        H0 = SymTensor2d(1.0 / hx, 0.0, 0.0, 1.0 / hy)
        if SPH:
            hxy = sqrt(hx * hy)
            H0 = SymTensor2d.one / hxy

        # The mass per node.
        m0 = lx * ly * rho / (nx * ny)
        assert m0 > 0.0

        # Compute our domain indicies.
        ixdomain = mpi.rank % nxdomains
        iydomain = mpi.rank / nxdomains
        ixmin = nodeindex(ixdomain, nxperdomain, nxremainder)
        ixmax = nodeindex(ixdomain + 1, nxperdomain, nxremainder)
        iymin = nodeindex(iydomain, nyperdomain, nyremainder)
        iymax = nodeindex(iydomain + 1, nyperdomain, nyremainder)
        assert ixmin < ixmax
        assert ixmin >= 0 and ixmax <= nx
        assert iymin < iymax
        assert iymin >= 0 and iymax <= ny

        # Now fill in the node values for this domain.
        self.x = []
        self.y = []
        self.m = []
        self.H = []
        for iy in xrange(iymin, iymax):
            for ix in xrange(ixmin, ixmax):
                self.x.append(xmin[0] + (ix + 0.5) * dx)
                self.y.append(xmin[1] + (iy + 0.5) * dy)
                self.m.append(m0)
                self.H.append(H0)
        assert mpi.allreduce(len(self.x), mpi.SUM) == nx * ny

        # Initialize the base class.
        NodeGeneratorBase.__init__(self, False)

        return
    disp = Vector((rImpactor + rTarget)*cos(pi/180.0*angle_impact),
                  (rImpactor + rTarget)*sin(pi/180.0*angle_impact),
                  0.0)
    for i in xrange(impactorGenerator.localNumNodes()):
        impactorGenerator.x[i] += disp.x
        impactorGenerator.y[i] += disp.y
        impactorGenerator.z[i] += disp.z

    print "Starting node distribution..."
    distributeNodes3d((target, targetGenerator),
                      (impactor,  impactorGenerator))

    nGlobalNodes = 0
    for n in nodeSet:
        print "Generator info for %s" % n.name
        print "   Minimum number of nodes per domain : ", mpi.allreduce(n.numInternalNodes, mpi.MIN)
        print "   Maximum number of nodes per domain : ", mpi.allreduce(n.numInternalNodes, mpi.MAX)
        print "               Global number of nodes : ", mpi.allreduce(n.numInternalNodes, mpi.SUM)
        nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
    del n
    print "Total number of (internal) nodes in simulation: ", nGlobalNodes
    print "Ratio of impactor/target node mass : ", impactor.mass().max()/target.mass().max()
    
    # Intialize the impactor velocity.
    vel = impactor.velocity()
    for i in xrange(impactor.numInternalNodes):
        vel[i].x = -vImpact

# Construct a DataBase to hold our node lists.
db = DataBase()
for n in nodeSet:
    def __init__(self, nx, ny, nz, rho, xmin, xmax, nNodePerh=2.01, SPH=False):
        assert nx > 0
        assert ny > 0
        assert nz > 0
        assert len(xmin) == 3
        assert len(xmax) == 3
        assert xmax[0] >= xmin[0]
        assert xmax[1] >= xmin[1]
        assert xmax[2] >= xmin[2]
        assert nNodePerh > 0.0

        # Remember the input.
        self.nx = nx
        self.ny = ny
        self.nz = nz
        self.xmin = xmin
        self.xmax = xmax

        # If the user provided a constant for rho, then use the constantRho
        # class to provide this value.
        if type(rho) == type(1.0):
            self.rho = ConstantRho(rho)
        else:
            self.rho = rho

        # Compute the number of domains in each direction.
        lx = xmax[0] - xmin[0]
        ly = xmax[1] - xmin[1]
        lz = xmax[2] - xmin[2]
        nxdomains = int((lx * lx / (ly * lz) * mpi.procs)**(1.0 / 3.0) + 0.1)
        nydomains = int(ly / lx * nxdomains + 0.1)
        nzdomains = int(lz / lx * nxdomains + 0.1)
        assert nxdomains * nydomains * nzdomains == mpi.procs

        # The number of nodes per domain.
        nxperdomain = nx / nxdomains
        nxremainder = nx % nxdomains
        nyperdomain = ny / nydomains
        nyremainder = ny % nydomains
        nzperdomain = nz / nzdomains
        nzremainder = nz % nzdomains
        assert nxremainder < nxdomains
        assert nyremainder < nydomains
        assert nzremainder < nzdomains

        # Compute the value for H.
        dx = lx / nx
        dy = ly / ny
        dz = lz / nz
        hx = nNodePerh * dx
        hy = nNodePerh * dy
        hz = nNodePerh * dz
        assert hx > 0.0 and hy > 0.0 and hz > 0.0
        H0 = SymTensor3d(1.0 / hx, 0.0, 0.0, 0.0, 1.0 / hy, 0.0, 0.0, 0.0,
                         1.0 / hz)
        if SPH:
            hxyz = (hx * hy * hz)**(1.0 / 3.0)
            H0 = SymTensor3d.one / hxyz

        # The mass per node.
        m0 = lx * ly * lz * rho / (nx * ny * nz)
        assert m0 > 0.0

        # Compute our domain indicies.
        ixdomain = mpi.rank % nxdomains
        iydomain = (mpi.rank / nxdomains) % nydomains
        izdomain = mpi.rank / (nxdomains * nydomains)
        ixmin = nodeindex(ixdomain, nxperdomain, nxremainder)
        ixmax = nodeindex(ixdomain + 1, nxperdomain, nxremainder)
        iymin = nodeindex(iydomain, nyperdomain, nyremainder)
        iymax = nodeindex(iydomain + 1, nyperdomain, nyremainder)
        izmin = nodeindex(izdomain, nzperdomain, nzremainder)
        izmax = nodeindex(izdomain + 1, nzperdomain, nzremainder)
        assert ixmin < ixmax
        assert ixmin >= 0 and ixmax <= nx
        assert iymin < iymax
        assert iymin >= 0 and iymax <= ny
        assert izmin < izmax
        assert izmin >= 0 and izmax <= nz

        # Now fill in the node values for this domain.
        self.x = []
        self.y = []
        self.z = []
        self.m = []
        self.H = []
        for iz in xrange(izmin, izmax):
            for iy in xrange(iymin, iymax):
                for ix in xrange(ixmin, ixmax):
                    self.x.append(xmin[0] + (ix + 0.5) * dx)
                    self.y.append(xmin[1] + (iy + 0.5) * dy)
                    self.z.append(xmin[2] + (iz + 0.5) * dz)
                    self.m.append(m0)
                    self.H.append(H0)
        assert mpi.allreduce(len(self.x), mpi.SUM) == nx * ny * nz

        # Initialize the base class.
        NodeGeneratorBase.__init__(self, False)

        return
    print "Generating node distribution."
    generator = GenerateNodeDistribution2d(nx,
                                           ny,
                                           rho0,
                                           seed,
                                           xmin = xmin1,
                                           xmax = xmax2,
                                           nNodePerh = nPerh)
    distributeNodes2d((nodes, generator))
    output('mpi.reduce(nodes.numInternalNodes, mpi.MIN)')
    output('mpi.reduce(nodes.numInternalNodes, mpi.MAX)')
    output('mpi.reduce(nodes.numInternalNodes, mpi.SUM)')

    m = nodes.mass()
    rho = nodes.massDensity()
    print "Area sum: ", mpi.allreduce(sum([m[i]/rho[i] for i in xrange(nodes.numInternalNodes)]), mpi.SUM)

    # Construct the flaws.
    localFlawsBA = weibullFlawDistributionBenzAsphaug(volume,
                                                      1.0,
                                                      randomSeed,
                                                      kWeibull,
                                                      mWeibull,
                                                      nodes,
                                                      1,
                                                      1)
    localFlawsO = weibullFlawDistributionOwen(randomSeed,
                                              kWeibull,
                                              mWeibull,
                                              nodes,
                                              1,     # numFlawsPerNode
    print "Generating the hydrostatic planet"

    genIron = GenerateIcosahedronMatchingProfile3d(nrPlanet,
                                                     rhoProfile,
                                                     rmin = 0.0,
                                                     rmax = rCore,
                                                     nNodePerh=nPerh,
                                                   rMaxForMassMatching=rPlanet)
    genGranite = GenerateIcosahedronMatchingProfile3d(nrPlanet,
                                                    rhoProfile,
                                                    rmin = rCore,
                                                    rmax = rPlanet,
                                                    nNodePerh=nPerh,
                                                      rMaxForMassMatching=rPlanet)

    msum = mpi.allreduce(sum(genIron.m + [0.0]), mpi.SUM)
    msum += mpi.allreduce(sum(genGranite.m + [0.0]), mpi.SUM)
    assert msum > 0.0
    print "Found planet mass = %g kg." % (msum*units.unitMassKg)



    
    print "Starting node distribution..."
    if mpi.procs > 1:
        from VoronoiDistributeNodes import distributeNodes3d
    else:
        from DistributeNodes import distributeNodes3d
    distributeNodes3d((nodesIron,genIron),(nodesGranite,genGranite))
    #distributor((nodes1,genPlanet))
    #distributor((nodes3,genCollider))
Exemple #21
0
output("db.numFluidNodeLists")

#-------------------------------------------------------------------------------
# Construct constant velocity boundary conditions to be applied to the rod ends.
#-------------------------------------------------------------------------------
x0Nodes = vector_of_int()
x1Nodes = vector_of_int()
[
    x0Nodes.append(i) for i in xrange(nodes.numInternalNodes)
    if nodes.positions()[i].x < -0.5 * length + 5 * dx
]
[
    x1Nodes.append(i) for i in xrange(nodes.numInternalNodes)
    if nodes.positions()[i].x > 0.5 * length - 5 * dx
]
print "Selected %i constant velocity nodes." % (mpi.allreduce(
    len(x0Nodes) + len(x1Nodes), mpi.SUM))

# Set the nodes we're going to control to one single velocity at each end.
v0 = mpi.allreduce(min([nodes.velocity()[i].x for i in x0Nodes] + [100.0]),
                   mpi.MIN)
v1 = mpi.allreduce(max([nodes.velocity()[i].x for i in x1Nodes] + [-100.0]),
                   mpi.MAX)
for i in x0Nodes:
    nodes.velocity()[i].x = v0
for i in x1Nodes:
    nodes.velocity()[i].x = v1

xbc0 = ConstantVelocityBoundary(nodes, x0Nodes)
xbc1 = ConstantVelocityBoundary(nodes, x1Nodes)

bcs = [xbc0, xbc1]
Exemple #22
0
                                 distributionType="lattice",
                                 xmin=(-R0, -R0, -R0),
                                 xmax=(R0, R0, R0),
                                 rmin=0.0,
                                 rmax=R0,
                                 nNodePerh=nPerh,
                                 SPH=not asph)
distributeNodes((nodes, gen))

# Force the mass to be exactly the desired total.
mass = nodes.mass()
M1 = mass.sumElements()
for i in xrange(nodes.numInternalNodes):
    mass[i] *= M0 / M1

print "Num internal nodes for ", nodes.name, " : ", mpi.allreduce(
    nodes.numInternalNodes, mpi.SUM)
print "Total mass: ", mass.sumElements()

# Set specific thermal energy.
eps0 = 0.05
eps = nodes.specificThermalEnergy()
for i in xrange(nodes.numInternalNodes):
    eps[i] = eps0

#-------------------------------------------------------------------------------
# Construct a DataBase to hold our node list
#-------------------------------------------------------------------------------
db = DataBase()
output("db")
output("db.appendNodeList(nodes)")
output("db.numNodeLists")
Exemple #23
0
    def setUp(self):
        global itest
        eos = GammaLawGasMKS(5.0 / 3.0, 1.0)
        self.nodes = makeFluidNodeList("test nodes %i" % itest,
                                       eos,
                                       numInternal=nperdomain,
                                       nPerh=2.01,
                                       hmin=1.0e-5,
                                       hmax=0.3)
        itest += 1
        self.pos = self.nodes.positions()
        self.H = self.nodes.Hfield()

        # Figure out the domain bounding volumes.
        dxproc = (x1 - x0) / nxproc
        dyproc = (y1 - y0) / nxproc
        dzproc = (z1 - z0) / nxproc

        ixproc = rank % nxproc
        iyproc = (rank % nxyproc) / nxproc
        izproc = rank / nxyproc
        xminproc = Vector(x0 + ixproc * dxproc, y0 + iyproc * dyproc,
                          z0 + izproc * dzproc)
        xmaxproc = Vector(x0 + (ixproc + 1) * dxproc,
                          y0 + (iyproc + 1) * dyproc,
                          z0 + (izproc + 1) * dzproc)

        # Randomly seed the generators.  We choose from random cells in order
        # to keep nodes from getting too close together.
        xyznodes_all = []
        occupiedCells = set()
        for k in xrange(n):
            i = rangen.randint(0, ncell)
            while i in occupiedCells:
                i = rangen.randint(0, ncell)
            ix = i % nxcell
            iy = (i % nxycell) / nxcell
            iz = i / nxycell
            xyznodes_all.append(
                Vector((ix + 0.5) * dxcell, (iy + 0.5) * dycell,
                       (iz + 0.5) * dzcell))
            occupiedCells.add(i)
        assert len(occupiedCells) == n
        xyznodes_all = mpi.bcast(xyznodes_all)
        xyznodes = [
            v for v in xyznodes_all if testPointInBox(v, xminproc, xmaxproc)
        ]
        dxavg = (x1 - x0) / nx
        dyavg = (y1 - y0) / ny
        dzavg = (z1 - z0) / nz
        self.dxmin = dxavg
        assert mpi.allreduce(len(xyznodes), mpi.SUM) == n

        # Now we can set the node conditions.
        self.nodes.numInternalNodes = len(xyznodes)
        for i in xrange(len(xyznodes)):
            self.pos[i] = xyznodes[i]
            self.H[i] = SymTensor(1.0 / (2.0 * dxavg), 0.0, 0.0, 0.0,
                                  1.0 / (2.0 * dyavg), 0.0, 0.0, 0.0,
                                  1.0 / (2.0 * dzavg))
        self.nodes.neighbor().updateNodes()

        # Fix up the H's.
        #iterateThoseHs(self.nodes)
        return
Exemple #24
0
        zmin=zminCuAnvil,
        zmax=zmaxCuAnvil,
        nNodePerh=nPerh,
        SPH=(NodeListConstructor is SphNodeList))

    distributeNodes3d(
        (nodesSteel, generatorTube), (nodesPlug, generatorPlug),
        (nodesProj, generatorProj), (nodesSteelAnvil, generatorSteelAnvil),
        (nodesFoamAnvil, generatorFoamAnvil), (nodesCuAnvil, generatorCuAnvil))
    nGlobalNodes = 0
    for n in nodeSet:
        print "Generator info for %s" % n.name
        output("    mpi.allreduce(n.numInternalNodes, mpi.MIN)")
        output("    mpi.allreduce(n.numInternalNodes, mpi.MAX)")
        output("    mpi.allreduce(n.numInternalNodes, mpi.SUM)")
        nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
    del n
    print "Total number of (internal) nodes in simulation: ", nGlobalNodes

    # Bevel the inner opening surface of the target tube.
    numNodesBeveled = bevelTubeEntrance(nodesSteel, 3, tubeOpeningAngle,
                                        rtubeInner, tubeThickness, zBevelBegin)
    print "Beveled %i nodes in the tube opening." % mpi.allreduce(
        numNodesBeveled, mpi.SUM)

    # Adjust the diameter of the projectile inward a bit, so it will slide
    # into the tube properly.
    drProj = compressProjectile * nPerh * rproj / nrproj
    projMultiplier = (rproj - drProj) / rproj
    for i in xrange(nodesProj.numInternalNodes):
        nodesProj.positions()[i].x *= projMultiplier
Exemple #25
0
def parallelsum(a):
    if not lparallel: return a
    return mpi.allreduce(a, mpi.SUM)
    def dump(self, simulationTime, cycle, format="ascii"):

        # Build the name of the directory we will be stuffing the viz file
        # into.
        outputdir = self.baseDirectory  # os.path.join(self.baseDirectory, self.baseFileName)

        # Make sure the output directory exists.
        if mpi.rank == 0:
            if not os.path.exists(outputdir):
                try:
                    os.makedirs(outputdir)
                except:
                    raise ValueError, "Cannot create output directory %s" % outputdir
        mpi.barrier()

        # Now build the output file name, including directory.  Make sure
        # the file does not already exist -- if it does we default to overwriting.
        filename = os.path.join(
            outputdir,
            self.baseFileName + "-time=%g-cycle=%i" % (simulationTime, cycle))
        ##         if os.path.exists(filename):
        ##             raise ValueError, "File %s already exists!  Aborting." % filename

        # Did the user provide a FieldList of cell geometries already?
        # start = TIME.clock()
        if self.cells:

            # Yep, so we build a disjoint set of cells as a polytope tessellation.
            mesh = eval("polytope.Tessellation%s()" % self.dimension)
            nDim = eval("Vector%s.nDimensions" % self.dimension)

            # Are we splitting into triangles/tets, or writing the native polygons/polyhera?
            if self.splitCells:
                index2zone = []
                for nodeListi in xrange(len(self.cells)):
                    n = self.cells[nodeListi].numInternalElements
                    for i in xrange(n):
                        celli = self.cells(nodeListi, i)
                        verts = celli.vertices()
                        noldnodes = len(mesh.nodes) / nDim
                        noldfaces = len(mesh.faces)
                        noldcells = len(mesh.cells)
                        for j in xrange(len(verts)):
                            for k in xrange(nDim):
                                mesh.nodes.append(verts[j][k])

                        if nDim == 2:
                            # Build the triangles
                            PCcelli = PolyClipper.Polygon()
                            PolyClipper.convertToPolygon(PCcelli, celli)
                            tris = PolyClipper.splitIntoTriangles(
                                PCcelli, 1e-10)
                            index2zone.append([])
                            mesh.faces.resize(noldfaces + 3 * len(tris))
                            mesh.cells.resize(noldcells + len(tris))
                            for k, tri in enumerate(tris):
                                mesh.faces[noldfaces + 3 * k +
                                           0].append(noldnodes + tri[0])
                                mesh.faces[noldfaces + 3 * k +
                                           0].append(noldnodes + tri[1])
                                mesh.faces[noldfaces + 3 * k +
                                           1].append(noldnodes + tri[1])
                                mesh.faces[noldfaces + 3 * k +
                                           1].append(noldnodes + tri[2])
                                mesh.faces[noldfaces + 3 * k +
                                           2].append(noldnodes + tri[2])
                                mesh.faces[noldfaces + 3 * k +
                                           2].append(noldnodes + tri[0])
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 3 * k)
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 3 * k + 1)
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 3 * k + 2)
                                index2zone[-1].append(noldcells + k)

                        else:
                            # Build the tetrahedra
                            assert nDim == 3
                            PCcelli = PolyClipper.Polyhedron()
                            PolyClipper.convertToPolyhedron(PCcelli, celli)
                            tets = PolyClipper.splitIntoTetrahedra(
                                PCcelli, 1e-10)
                            index2zone.append([])
                            mesh.faces.resize(noldfaces + 4 * len(tets))
                            mesh.cells.resize(noldcells + len(tets))
                            for k, tet in enumerate(tets):
                                mesh.faces[noldfaces + 4 * k +
                                           0].append(noldnodes + tet[0])
                                mesh.faces[noldfaces + 4 * k +
                                           0].append(noldnodes + tet[1])
                                mesh.faces[noldfaces + 4 * k +
                                           0].append(noldnodes + tet[2])

                                mesh.faces[noldfaces + 4 * k +
                                           1].append(noldnodes + tet[1])
                                mesh.faces[noldfaces + 4 * k +
                                           1].append(noldnodes + tet[3])
                                mesh.faces[noldfaces + 4 * k +
                                           1].append(noldnodes + tet[2])

                                mesh.faces[noldfaces + 4 * k +
                                           2].append(noldnodes + tet[3])
                                mesh.faces[noldfaces + 4 * k +
                                           2].append(noldnodes + tet[0])
                                mesh.faces[noldfaces + 4 * k +
                                           2].append(noldnodes + tet[2])

                                mesh.faces[noldfaces + 4 * k +
                                           3].append(noldnodes + tet[0])
                                mesh.faces[noldfaces + 4 * k +
                                           3].append(noldnodes + tet[3])
                                mesh.faces[noldfaces + 4 * k +
                                           3].append(noldnodes + tet[1])

                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 4 * k)
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 4 * k + 1)
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 4 * k + 2)
                                mesh.cells[noldcells + k].append(noldfaces +
                                                                 4 * k + 3)
                                index2zone[-1].append(noldcells + k)

            else:
                index2zone = None
                copy2polytope(self.cells, mesh)
                # for nodeListi in xrange(len(self.cells)):
                #     n = self.cells[nodeListi].numInternalElements
                #     noldcells = len(mesh.cells)
                #     mesh.cells.resize(noldcells + n)
                #     for i in xrange(n):
                #         celli = self.cells(nodeListi, i)
                #         verts = celli.vertices
                #         facets = celli.facets
                #         noldnodes = len(mesh.nodes)/nDim
                #         noldfaces = len(mesh.faces)
                #         mesh.faces.resize(noldfaces + len(facets))
                #         for j in xrange(len(verts)):
                #             for k in xrange(nDim):
                #                 mesh.nodes.append(verts[j][k])
                #         for j in xrange(len(facets)):
                #             mesh.cells[noldcells + i].append(noldfaces + j)
                #             ipoints = facets[j].ipoints
                #             for k in ipoints:
                #                 mesh.faces[noldfaces + j].append(noldnodes + k)

        else:

            # We need to do the full up polytope tessellation.
            # Build the set of generators from our points.
            gens = vector_of_double()
            nDim = eval("Vector%s.nDimensions" % self.dimension)
            xmin = vector_of_double([1e100] * nDim)
            xmax = vector_of_double([-1e100] * nDim)
            for nodes in self._nodeLists:
                pos = nodes.positions()
                for i in xrange(nodes.numInternalNodes):
                    for j in xrange(nDim):
                        gens.append(pos[i][j])
                        xmin[j] = min(xmin[j], pos[i][j])
                        xmax[j] = max(xmax[j], pos[i][j])

            # Check the boundaries for any additional points we want to use for the bounding box.
            for bound in self._boundaries:
                try:
                    pb = dynamicCastBoundaryToPlanarBoundary2d(bound)
                    for p in (pb.enterPlane.point, pb.exitPlane.point):
                        for j in xrange(nDim):
                            xmin[j] = min(xmin[j], p[j])
                            xmax[j] = max(xmax[j], p[j])
                except:
                    pass

            # Globally reduce and puff up a bit.
            for j in xrange(nDim):
                xmin[j] = mpi.allreduce(xmin[j], mpi.MIN)
                xmax[j] = mpi.allreduce(xmax[j], mpi.MAX)
                delta = 0.01 * (xmax[j] - xmin[j])
                xmin[j] -= delta
                xmax[j] += delta

            # Build the PLC.
            plc = polytope.PLC2d()
            plc.facets.resize(4)
            for i in xrange(4):
                plc.facets[i].resize(2)
                plc.facets[i][0] = i
                plc.facets[i][1] = (i + 1) % 4
            plccoords = vector_of_double(8)
            plccoords[0] = xmin[0]
            plccoords[1] = xmin[1]
            plccoords[2] = xmax[0]
            plccoords[3] = xmin[1]
            plccoords[4] = xmax[0]
            plccoords[5] = xmax[1]
            plccoords[6] = xmin[0]
            plccoords[7] = xmax[1]

            # Blago!
            # f = open("generators_%i_of_%i.txt" % (mpi.rank, mpi.procs), "w")
            # f.write("# generators x    y\n")
            # for i in xrange(len(gens)/2):
            #     f.write("%g    %g\n" % (gens[2*i], gens[2*i+1]))
            # f.write("# PLC coords    x     y\n")
            # for i in xrange(len(plccoords)/2):
            #     f.write("%g    %g\n" % (plccoords[2*i], plccoords[2*i+1]))
            # f.close()
            # Blago!

            # Build the tessellation.
            if self.dimension == "2d":
                mesh = polytope.Tessellation2d()
                if "TriangleTessellator2d" in dir(polytope):
                    serial_tessellator = polytope.TriangleTessellator2d()
                else:
                    assert "BoostTessellator2d" in dir(polytope)
                    serial_tessellator = polytope.BoostTessellator2d()
            else:
                assert self.dimension == "3d"
                raise RuntimeError, "Sorry: 3D tessellation silo dumps are not supported yet."
            if mpi.procs > 1:
                tessellator = eval(
                    "polytope.DistributedTessellator%s(serial_tessellator, False, True)"
                    % self.dimension)
            else:
                tessellator = serial_tessellator
            index2zone = tessellator.tessellateDegenerate(
                gens, plccoords, plc, 1.0e-8, mesh)

        # print "Took %g sec to generate cells" % (TIME.clock() - start)
        # start = TIME.clock()

        # Figure out how many of each type of field we're dumping.
        intFields = [
            x for x in self._fields
            if isinstance(x, eval("IntField%s" % self.dimension))
        ]
        #[x for x in self._fields if isinstance(x, eval("UnsignedField%s" % self.dimension))] +
        #[x for x in self._fields if isinstance(x, eval("ULLField%s" % self.dimension))])
        scalarFields = [
            x for x in self._fields
            if isinstance(x, eval("ScalarField%s" % self.dimension))
        ]
        vectorFields = [
            x for x in self._fields
            if isinstance(x, eval("VectorField%s" % self.dimension))
        ]
        tensorFields = [
            x for x in self._fields
            if isinstance(x, eval("TensorField%s" % self.dimension))
        ]
        symTensorFields = [
            x for x in self._fields
            if isinstance(x, eval("SymTensorField%s" % self.dimension))
        ]

        # For tensor fields we like to dump out some extra info.
        for f in (tensorFields + symTensorFields):
            n = f.nodeList()
            tr = eval("ScalarField%s('%s_trace', n)" %
                      (self.dimension, f.name))
            det = eval("ScalarField%s('%s_determinant', n)" %
                       (self.dimension, f.name))
            mineigen = eval("ScalarField%s('%s_eigen_min', n)" %
                            (self.dimension, f.name))
            maxeigen = eval("ScalarField%s('%s_eigen_max', n)" %
                            (self.dimension, f.name))
            fvals = f.internalValues()
            for i in xrange(n.numInternalNodes):
                tr[i] = fvals[i].Trace()
                det[i] = fvals[i].Determinant()
                eigen = fvals[i].eigenValues()
                mineigen[i] = eigen.minElement()
                maxeigen[i] = eigen.maxElement()
            scalarFields += [tr, det, mineigen, maxeigen]
        # print "Took %g sec to build output fields" % (TIME.clock() - start)
        # start = TIME.clock()

        # Write the output.
        timeslice = siloMeshDump(filename,
                                 mesh,
                                 index2zone=index2zone,
                                 nodeLists=self._nodeLists,
                                 time=simulationTime,
                                 cycle=cycle,
                                 intFields=intFields,
                                 scalarFields=scalarFields,
                                 vectorFields=vectorFields,
                                 tensorFields=tensorFields,
                                 symTensorFields=symTensorFields)

        # print "Took %g sec to calls siloMeshDump" % (TIME.clock() - start)
        # start = TIME.clock()

        # Write the master file listing all the time slices.
        if mpi.rank == 0:
            mastername = os.path.join(self.baseDirectory, self.masterFileName)
            mf = open(mastername, "a")
            mf.write("%s\n" % timeslice)
            mf.close()
        mpi.barrier()

        # That's it.
        del mesh
        while gc.collect():
            pass
        return
Exemple #27
0
def writeMasterSiloFile(ndim, nblock, jsplit, baseDirectory, baseName,
                        procDirBaseName, materials, rhosamp, label, time,
                        cycle):

    nullOpts = silo.DBoptlist()

    # Decide which domains have information.
    if len(rhosamp) > 0:
        myvote = mpi.rank + 1
    else:
        myvote = 0
    maxproc = mpi.allreduce(myvote, mpi.MAX)
    assert maxproc <= mpi.procs

    # Pattern for constructing per domain variables.
    domainNamePatterns = [
        os.path.join(procDirBaseName, "domain%i.silo:%%s" % i)
        for i in xrange(maxproc)
    ]
    domainVarNames = Spheral.vector_of_string()
    for iproc, p in enumerate(domainNamePatterns):
        domainVarNames.append(p % "/hblk0/den")
    assert len(domainVarNames) == maxproc

    # We need each domains nblock info.
    nblocks = [nblock]
    for sendproc in xrange(1, maxproc):
        if mpi.rank == sendproc:
            mpi.send(nblock, dest=0, tag=50)
        if mpi.rank == 0:
            nblocks.append(mpi.recv(source=sendproc, tag=50)[0])

    # Create the master file.
    if mpi.rank == 0:
        fileName = os.path.join(baseDirectory, baseName + ".silo")
        f = silo.DBCreate(fileName, SA._DB_CLOBBER, SA._DB_LOCAL, label,
                          SA._DB_HDF5)
        nullOpts = silo.DBoptlist()

        # Write the domain file names and types.
        domainNames = Spheral.vector_of_string()
        meshTypes = Spheral.vector_of_int(maxproc, SA._DB_QUADMESH)
        for p in domainNamePatterns:
            domainNames.append(p % "hblk0/hydro_mesh")
        optlist = silo.DBoptlist(1024)
        assert optlist.addOption(SA._DBOPT_CYCLE, cycle) == 0
        assert optlist.addOption(SA._DBOPT_DTIME, time) == 0
        assert silo.DBPutMultimesh(f, "hydro_mesh", domainNames, meshTypes,
                                   optlist) == 0

        # Write material names.
        material_names = Spheral.vector_of_string()
        matnames = Spheral.vector_of_string(1, "void")
        matnos = Spheral.vector_of_int(1, 0)
        for p in domainNamePatterns:
            material_names.append(p % "/hblk0/Materials")
        for i, name in enumerate([x.name for x in materials]):
            matnames.append(name)
            matnos.append(i + 1)
        assert len(material_names) == maxproc
        assert len(matnames) == len(materials) + 1
        assert len(matnos) == len(materials) + 1
        optlist = silo.DBoptlist(1024)
        assert optlist.addOption(SA._DBOPT_CYCLE, cycle) == 0
        assert optlist.addOption(SA._DBOPT_DTIME, time) == 0
        assert optlist.addOption(SA._DBOPT_MMESH_NAME, "hydro_mesh") == 0
        assert optlist.addOption(SA._DBOPT_MATNAMES, SA._DBOPT_NMATNOS,
                                 matnames) == 0
        assert optlist.addOption(SA._DBOPT_MATNOS, SA._DBOPT_NMATNOS,
                                 matnos) == 0
        assert silo.DBPutMultimat(f, "Materials", material_names, optlist) == 0

        # Write the variables descriptors.
        # We currently hardwire for the single density variable.
        types = Spheral.vector_of_int(maxproc, SA._DB_QUADVAR)
        assert len(domainVarNames) == maxproc
        optlistMV = silo.DBoptlist()
        assert optlistMV.addOption(SA._DBOPT_CYCLE, cycle) == 0
        assert optlistMV.addOption(SA._DBOPT_DTIME, time) == 0
        #assert optlistMV.addOption(SA._DBOPT_TENSOR_RANK, SA._DB_VARTYPE_SCALAR) == 0
        assert optlistMV.addOption(SA._DBOPT_BLOCKORIGIN, 0) == 0
        assert optlistMV.addOption(SA._DBOPT_MMESH_NAME, "hydro_mesh") == 0
        assert silo.DBPutMultivar(f, "den", domainVarNames, types,
                                  optlistMV) == 0

        # Write the dummy variable "akap_0" to tell Hades we're actually Hydra or something.
        assert silo.DBPutQuadvar1(f, "akap_0", "hydro_mesh",
                                  Spheral.vector_of_double(ndim * ndim, 0.0),
                                  Spheral.vector_of_double(), SA._DB_ZONECENT,
                                  Spheral.vector_of_int(ndim, ndim),
                                  nullOpts) == 0

        # Write domain and mesh size info.
        assert silo.DBMkDir(f, "Decomposition") == 0
        assert silo.DBWrite(f, "Decomposition/NumDomains", maxproc) == 0
        assert silo.DBWrite(f, "Decomposition/NumLocalDomains", maxproc) == 0
        assert silo.DBWrite(f, "Decomposition/NumBlocks", 1) == 0
        #assert silo.DBWrite(f, "Decomposition/LocalName", "hblk") == 0
        localDomains = Spheral.vector_of_int()
        domainFiles = Spheral.vector_of_vector_of_int(1)
        for i in xrange(maxproc):
            localDomains.append(i)
            domainFiles[0].append(i)
        assert silo.DBWrite(f, "Decomposition/LocalDomains", localDomains) == 0
        assert silo.DBWrite(f, "DomainFiles", domainFiles) == 0

        for iproc in xrange(maxproc):
            assert silo.DBMkDir(f, "Decomposition/gmap%i" % iproc) == 0
            stuff = Spheral.vector_of_int(12, 0)
            for jdim in xrange(ndim):
                stuff[6 + jdim] = nblocks[iproc][jdim]
            if iproc in (0, maxproc - 1):
                assert silo.DBWrite(
                    f, "Decomposition/gmap%i/NumNeighbors" % iproc, 1) == 0
            else:
                assert silo.DBWrite(
                    f, "Decomposition/gmap%i/NumNeighbors" % iproc, 2) == 0
            assert silo.DBWrite(f, "Decomposition/gmap%i/gmap" % iproc,
                                stuff) == 0

    # Close the file.
    if mpi.rank == 0:
        assert silo.DBClose(f) == 0
        del f

    return maxproc
def pflatten_node_list(nl,filename,do_header=True,nl_id=0,silent=False):
    """Flatten physical field values from a node list to a rectangular ascii file.

    pflatten_node_list(nl,filename) extracts field variables from all nodes of nl,
    which must be a valid node list, and writes them as a rectangular table into
    the text file filename. (A short header is also written, using the # comment
    character so the resulting file can be easily read with numpy.loadtext.) The
    file will be overwritten if it exists. If filename has the .gz extension it
    will be compressed using gzip.

    pflatten_node_list(...,do_header=False) omits the header and appends the 
    flattened nl to the end of the file if one exists.

    pflatten_node_list(...,nl_id=id) places the integer id in the first column
    of every node (row) in the node list. This can be used when appending multiple
    lists to the same file, providing a convenient way to distinguish nodes from
    different lists when the file is later read. The default id (for single node
    list files) is 0.

    The format of the output table is (one line per node):
      id eos_id x y z vx vy vz m rho p T U hmin hmax

    The p in pflatten is for 'parallel', a reminder that all nodes will be
    processed in their local rank, without ever being communicated or collected
    in a single process. Each mpi rank will wait its turn to access the output 
    file, so the writing is in fact serial, but avoids bandwidth and memory waste
    and is thus suitable for large node lists from high-res runs.

    See also: spickle_node_list
    """

    # Make sure we are not wasting our time.
    assert isinstance(nl,(sph.Spheral.NodeSpace.FluidNodeList3d,
                          sph.Spheral.SolidMaterial.SolidNodeList3d)
                      ), "argument 1 must be a node list"
    assert isinstance(filename, str), "argument 2 must be a simple string"
    assert isinstance(do_header, bool), "true or false"
    assert isinstance(silent, bool), "true or false"
    assert isinstance(nl_id, int), "int only idents"
    assert not isinstance(nl_id, bool), "int only idents"

    # Determine if file should be compressed.
    if os.path.splitext(filename)[1] == '.gz':
        import gzip
        open = gzip.open
    else:
        import __builtin__
        open = __builtin__.open

    # Write the header.
    if do_header:
        nbGlobalNodes = mpi.allreduce(nl.numInternalNodes, mpi.SUM)
        header = header_template.format(nbGlobalNodes)
        if mpi.rank == 0:
            fid = open(filename,'w')
            fid.write(header)
            fid.close()
            pass
        pass
     
    # Start collecting data.
    if not silent:
        sys.stdout.write('Flattening ' + nl.label() + ' ' + nl.name + '........')
    
    # Get values of field variables stored in internal nodes.
    xloc = nl.positions().internalValues()
    vloc = nl.velocity().internalValues()
    mloc = nl.mass().internalValues()
    rloc = nl.massDensity().internalValues()
    uloc = nl.specificThermalEnergy().internalValues()
    Hloc = nl.Hfield().internalValues()
    #(pressure and temperature are stored in the eos object.)
    eos = nl.equationOfState()
    ploc = sph.ScalarField('ploc',nl)
    Tloc = sph.ScalarField('loc',nl)
    rref = nl.massDensity()
    uref = nl.specificThermalEnergy()
    eos.setPressure(ploc,rref,uref)
    eos.setTemperature(Tloc,rref,uref)

    # Procs take turns writing internal node values to file.
    for proc in range(mpi.procs):
        if proc == mpi.rank:
            fid = open(filename,'a')
            for nk in range(nl.numInternalNodes):
                line  = "{:2d}  ".format(nl_id)
                line += "{:2d}  ".format(getattr(nl,'eos_id',-1))
                line += "{0.x:+12.5e}  {0.y:+12.5e}  {0.z:+12.5e}  ".format(xloc[nk])
                line += "{0.x:+12.5e}  {0.y:+12.5e}  {0.z:+12.5e}  ".format(vloc[nk])
                line += "{0:+12.5e}  ".format(mloc[nk])
                line += "{0:+12.5e}  ".format(rloc[nk])
                line += "{0:+12.5e}  ".format(ploc[nk])
                line += "{0:+12.5e}  ".format(Tloc[nk])
                line += "{0:+12.5e}  ".format(uloc[nk])
                line += "{0:+12.5e}  ".format(Hloc[nk].Inverse().eigenValues().minElement())
                line += "{0:+12.5e}  ".format(Hloc[nk].Inverse().eigenValues().maxElement())
                line += "\n"
                fid.write(line)
                pass
            fid.close()
            pass
        mpi.barrier()
        pass
     
    # And Bob's our uncle.
    if not silent:
        print "Done."
Exemple #29
0
def hadesDump1(integrator,
               nsample,
               xmin,
               xmax,
               W,
               isotopes,
               baseFileName,
               baseDirectory=".",
               mask=None,
               dumpGhosts=True,
               materials="all"):

    # We currently only support 3-D.
    assert isinstance(integrator, Spheral.Integrator3d)
    assert len(nsample) == 3
    assert isinstance(xmin, Spheral.Vector3d)
    assert isinstance(xmax, Spheral.Vector3d)
    assert isinstance(W, Spheral.TableKernel3d)
    for x in isotopes:
        for xx in x:
            assert len(xx) == 2

    # Prepare to time how long this takes.
    t0 = time.clock()

    # Extract the data base.
    db = integrator.dataBase()

    # If requested, set ghost node info.
    if dumpGhosts and not integrator is None:
        state = Spheral.State3d(db, integrator.physicsPackages())
        derivs = Spheral.StateDerivatives3d(db, integrator.physicsPackages())
        integrator.setGhostNodes()
        integrator.applyGhostBoundaries(state, derivs)

    # Get the set of material names we're going to write.
    if materials == "all":
        materials = [n for n in db.fluidNodeLists()]
    assert len(materials) == len(isotopes)

    # HACK!  We are currently restricting to writing single material output!
    assert len(materials) == 1

    # Make sure the output directory exists.
    import mpi
    import os
    if mpi.rank == 0 and not os.path.exists(baseDirectory):
        try:
            os.makedirs(baseDirectory)
        except:
            raise "Cannot create output directory %s" % baseDirectory
    mpi.barrier()

    # Write the density header file.
    print "hadesDump: writing density header..."
    if mpi.rank == 0:
        filename = os.path.join(baseDirectory, baseFileName + ".spr")
        f = open(filename, "w")
        f.write("3\n")
        for i in xrange(3):
            f.write("%i\n" % nsample[i])
            f.write("%f\n" % xmin(i))
            f.write("%f\n" % ((xmax(i) - xmin(i)) / nsample[i]))
        f.write("3\n")
        f.close()
    mpi.barrier()

    # Sample the density.
    ntot = nsample[0] * nsample[1] * nsample[2]
    for nodes in materials:
        print "hadesDump: sampling density for %s..." % nodes.name
        r = Spheral.VectorFieldList3d()
        H = Spheral.SymTensorFieldList3d()
        rho = Spheral.ScalarFieldList3d()
        r.appendField(nodes.positions())
        w.appendField(nodes.weight())
        H.appendField(nodes.Hfield())
        rho.appendField(nodes.massDensity())

        w = Spheral.ScalarFieldList3d()
        w.copyFields()
        w.appendField(Spheral.ScalarField3d("weight", nodes, 1.0))

        fieldListSet = Spheral.FieldListSet3d()
        fieldListSet.ScalarFieldLists.append(rho)
        localMask = Spheral.IntFieldList3d()
        if mask is None:
            localMask.copyFields()
            localMask.appendField(Spheral.IntField3d("mask", nodes, 1))
        else:
            localMask.appendField(mask.fieldForNodeList(nodes))

        scalar_samples = Spheral.vector_of_vector_of_double()
        vector_samples = Spheral.vector_of_vector_of_Vector3d()
        tensor_samples = Spheral.vector_of_vector_of_Tensor3d()
        symTensor_samples = Spheral.vector_of_vector_of_SymTensor3d()
        nsample_vec = Spheral.vector_of_int(3)
        for i in xrange(3):
            nsample_vec[i] = nsample[i]

        Spheral.sampleMultipleFields2Lattice3d(fieldListSet, r, w, H,
                                               localMask, W, xmin, xmax,
                                               nsample_vec, scalar_samples,
                                               vector_samples, tensor_samples,
                                               symTensor_samples)
        print "Generated %i scalar fields" % len(scalar_samples)
        rhosamp = scalar_fields[0]
        nlocal = len(rhosamp)
        assert mpi.allreduce(nlocal, mpi.SUM) == ntot

        print "hadesDump: writing density for %s..." % nodes.name
        filename = os.path.join(baseDirectory, baseFileName + ".sdt")
        for sendProc in xrange(mpi.procs):
            if mpi.rank == sendProc:
                f = open(filename, "ab")
                f.write(struct.pack(nlocal * "f", *tuple(rhosamp)))
                f.close()
            mpi.barrier()

    # Write the material arrays.
    print "hadesDump: writing material flags..."
    filename = os.path.join(baseDirectory, baseFileName + "_mat.sdt")
    for sendProc in xrange(mpi.procs):
        if mpi.rank == sendProc:
            f = open(filename, "ab")
            f.write(struct.pack(nlocal * "i", *(nlocal * (1, ))))
            f.close()
        mpi.barrier()

    # Write the isotopes.
    print "hadesDump: writing isotopics..."
    if mpi.rank == 0:
        filename = os.path.join(baseDirectory, "isos.mat")
        f = open(filename, "w")
        i = 0
        for isofracs in isotopes:
            f.write("isofrac(%i) =" % i)
            for (iso, frac) in isofracs:
                f.write(" %i %f" % (iso, frac))
            f.write("\n")
            i += 1
        f.close()
    mpi.barrier()

    mpi.barrier()
    print "hadesDump finished: required %0.2f seconds" % (time.clock() - t0)
    return
Exemple #30
0
            raise ValueError, "The restarted state does not match!"
        else:
            print "Restart check PASSED."

else:
    control.advance(goalTime, maxSteps)
    control.updateViz(control.totalSteps, integrator.currentTime, 0.0)
    control.dropRestartFile()

#-------------------------------------------------------------------------------
# Plot the results.
#-------------------------------------------------------------------------------
import NohAnalyticSolution
answer = NohAnalyticSolution.NohSolution(3, h0=nPerh * rmax / nx)

r = mpi.allreduce([x.magnitude() for x in nodes1.positions().internalValues()],
                  mpi.SUM)
rho = mpi.allreduce(list(nodes1.massDensity().internalValues()), mpi.SUM)
rans, vans, epsans, rhoans, Pans, hans = answer.solution(control.time(), r)
if mpi.rank == 0:
    L1 = 0.0
    for i in xrange(len(rho)):
        L1 = L1 + abs(rho[i] - rhoans[i])
    L1_tot = L1 / len(rho)
    print "L1=", L1_tot, "\n"
    with open("Converge.txt", "a") as myfile:
        myfile.write("%s %s %s %s %s\n" % (nx, ny, nz, nx + ny + nz, L1_tot))
if graphics:

    # Plot the node positions.
    from SpheralGnuPlotUtilities import *
    def __init__(self,
                 filename,
                 materialName,
                 nNodePerh=2.01,
                 SPH=False,
                 precision=20,
                 Hscalefactor=1.0,
                 extraFields=[],
                 initializeBase=True,
                 readFileToMemory=False,
                 refineNodes=0):

        self.filename = filename
        self.nPerh = nNodePerh
        self.SPH = SPH
        self.extraFields = extraFields

        self.precision = "%" + "%i.%ie" % (precision + 3, precision)

        # For now we restrict to reading from a single (serial) file.
        allfiles = mpi.allreduce([filename], mpi.SUM)
        assert min([x == filename for x in allfiles])
        self.serialfile = True

        # Open the file.
        if mpi.rank == 0:
            f = gzip.open(filename, "r")
            if readFileToMemory:
                self.f = f.readlines()
                f.close()
            else:
                self.f = f
        else:
            self.f = None

        # Read the positions.
        vals = readField2String(materialName, "positions", self.f)
        n = len(vals)
        self.x = []
        self.y = []
        for val in vals:
            x, y = tuple([float(x) for x in val.split()])
            self.x.append(x)
            self.y.append(y)
        assert len(self.x) == n
        assert len(self.y) == n

        # Read the masses.
        vals = readField2String(materialName, "mass", self.f)
        assert len(vals) == n
        self.m = [float(x) for x in vals]
        assert len(self.m) == n

        # Read the mass densities.
        vals = readField2String(materialName, "density", self.f)
        assert len(vals) == n
        self.rho = [float(x) for x in vals]
        assert len(self.rho) == n

        # Read the velocities.
        vals = readField2String(materialName, "velocity", self.f)
        assert len(vals) == n
        self.vx = []
        self.vy = []
        for val in vals:
            vx, vy = tuple([float(x) for x in val.split()])
            self.vx.append(vx)
            self.vy.append(vy)
        assert len(self.vx) == n
        assert len(self.vy) == n

        # Read the specific thermal energies.
        vals = readField2String(materialName, "specificThermalEnergy", self.f)
        assert len(vals) == n
        self.eps = [float(x) for x in vals]
        assert len(self.eps) == n

        # Read the H tensors.
        vals = readField2String(materialName, "Hinverse2", self.f)
        assert len(vals) == n
        self.H = []
        for val in vals:
            Hi2 = SymTensor2d(*tuple([float(x)
                                      for x in val.split()])) * Hscalefactor
            H = Hi2.Inverse().sqrt()
            if SPH:
                hxy = sqrt(H.Determinant())
                H = SymTensor2d.one * hxy
            self.H.append(H)
        assert len(self.H) == n

        # Read in any extra fields the user requested.
        # Note we make the assumption here that any extra fields are in fact scalar fields.
        for fname in extraFields:
            vals = readField2String(materialName, fname, self.f)
            assert len(vals) == n
            self.__dict__[fname] = [float(x) for x in vals]

        # Initialize the base class.
        if initializeBase:
            fields = tuple([
                self.x, self.y, self.m, self.rho, self.vx, self.vy, self.eps,
                self.H
            ] + [self.__dict__[x] for x in extraFields])
            NodeGeneratorBase.__init__(self, self.serialfile, *fields)

        if mpi.rank == 0:
            self.f.close()

        # Apply the requested number of refinements.
        for i in xrange(refineNodes):
            refineNodes2d(self)

        return
Exemple #32
0
               epsPlot=epsPlot,
               PPlot=PPlot)

#-------------------------------------------------------------------------------
# Measure the difference between the simulation and analytic answer.
#-------------------------------------------------------------------------------
# Figure out which of the node we want to measure the error on.
rmin = 0.05
rmax = 0.35
rall = [x.magnitude() for x in nodes.positions().internalValues()]
imask = [
    i for i in xrange(nodes.numInternalNodes)
    if (rall[i] > rmin and rall[i] < rmax)
]
Nlocal = len(imask)
Nglobal = mpi.allreduce(Nlocal, mpi.SUM)

# Find the local profiles.
r = nodes.positions().internalValues()
vel = nodes.velocity().internalValues()
rho = nodes.massDensity().internalValues()
eps = nodes.specificThermalEnergy().internalValues()
P = nodes.pressure().internalValues()
xprof = [rall[i] for i in imask]
vprof = [vel[i].dot(r[i].unitVector()) for i in imask]
rhoprof = [rho[i] for i in imask]
epsprof = [eps[i] for i in imask]
Pprof = [P[i] for i in imask]
Aprof = [Pi / rhoi**gamma for (Pi, rhoi) in zip(Pprof, rhoprof)]

# Compute the analytic answer on the positions of the nodes.
Exemple #33
0
    def __init__(self,n,densityProfileMethod,
                 rmin = 0.0,
                 rmax = 0.0,
                 thetaMin = 0.0,
                 thetaMax = pi,
                 phiMin = 0.0,
                 phiMax = 2.0*pi,
                 nNodePerh = 2.01,
                 offset = None,
                 rejecter = None,
                 m0 = 0.0):

        assert n > 0
        assert rmin < rmax
        assert thetaMin < thetaMax
        assert thetaMin >= 0.0 and thetaMin <= 2.0*pi
        assert thetaMax >= 0.0 and thetaMax <= 2.0*pi
        assert phiMin < phiMax
        assert phiMin >= 0.0 and phiMin <= 2.0*pi
        assert phiMax >= 0.0 and phiMax <= 2.0*pi
        assert nNodePerh > 0.0
        assert offset is None or len(offset)==3
        
        self.rejecter = None
        if rejecter:
            self.rejecter = rejecter
        
        import random
        
        if offset is None:
            self.offset = Vector3d(0,0,0)
        else:
            self.offset = Vector3d(offset[0],offset[1],offset[2])
        
        self.n = n
        self.rmin = rmin
        self.rmax = rmax
        self.thetaMin = thetaMin
        self.thetaMax = thetaMax
        self.phiMin = phiMin
        self.phiMax = phiMax
        self.nNodePerh = nNodePerh        
        
        # If the user provided a constant for rho, then use the constantRho
        # class to provide this value.
        if type(densityProfileMethod) == type(1.0):
            self.densityProfileMethod = ConstantRho(densityProfileMethod)
        else:
            self.densityProfileMethod = densityProfileMethod
        
        # Determine how much total mass there is in the system.
        self.totalMass = self.integrateTotalMass(self.densityProfileMethod,
                                                     rmin, rmax,
                                                     thetaMin, thetaMax,
                                                     phiMin, phiMax)

        print "Total mass of %g in the range r = (%g, %g), theta = (%g, %g), phi = (%g, %g)" % \
            (self.totalMass, rmin, rmax, thetaMin, thetaMax, phiMin, phiMax)

        # Now set the nominal mass per node.
        if (m0 == 0.0):
            self.m0 = float(self.totalMass/n)
        else:
            self.m0 = float(m0)
            n = int(self.totalMass/self.m0)
        assert self.m0 > 0.0
        print "Nominal mass per node of %f for %d nodes." % (self.m0,n)
        
        from Spheral import SymTensor3d
        self.x = []
        self.y = []
        self.z = []
        self.m = []
        self.H = []

        # first shell is a tetrahedron
        self.positions = []
        nshell = 4
        rhoc = self.densityProfileMethod(0.0)
        print rhoc,self.m0
        mi   = self.m0
        drc  = pow(0.333*mi/rhoc,1.0/3.0)
        print drc
        hi   = nNodePerh*(drc)

        random.seed(nshell)
        dt = random.random()*pi
        dt2 = random.random()*pi
            
        rot = [[1.0,0.0,0.0],[0.0,cos(dt),-sin(dt)],[0.0,sin(dt),cos(dt)]]
        rot2 = [[cos(dt2),0.0,sin(dt2)],[0.0,1.0,0.0],[-sin(dt2),0.0,cos(dt2)]]

        t = sqrt(3.0)/3.0
        p1 = self.rotater([t,t,t],rot,rot2)
        p2 = self.rotater([t,-t,-t],rot,rot2)
        p3 = self.rotater([-t,-t,t],rot,rot2)
        p4 = self.rotater([-t,t,-t],rot,rot2)

        ps = [p1,p2,p3,p4]
        
        for pn in ps:
            self.positions.append(pn)
        mi = self.densityProfileMethod(drc*0.5)*(4.0/3.0*3.14159*drc**3)/4.0

        for pn in ps:
            x = pn[0]*0.5*drc
            y = pn[1]*0.5*drc
            z = pn[2]*0.5*drc

            if rejecter:
                if rejecter.accpet(x,y,z):
                    self.x.append(x)
                    self.y.append(y)
                    self.z.append(z)
                    self.m.append(mi)
                    self.H.append(SymTensor3d.one*(1.0/hi))
            else:
                self.x.append(x)
                self.y.append(y)
                self.z.append(z)
                self.m.append(mi)
                self.H.append(SymTensor3d.one*(1.0/hi))

        # now march up to the surface
        r = 0
        dr = drc
        while r <= rmax:
            r += dr
                
    
        # If requested, shift the nodes.
        if offset:
            for i in xrange(len(self.x)):
                self.x[i] += offset[0]
                self.y[i] += offset[1]
                self.z[i] += offset[2]
            
        print "Generated a total of %i nodes." % mpi.allreduce(len(self.x),mpi.SUM)
        NodeGeneratorBase.__init__(self, False,
                                   self.x, self.y, self.z, self.m, self.H)
        return
def spickle_node_list(nl,filename=None,silent=False):
    """Pack physical field variables from a node list in a dict and pickle.

    (Note: This is not a true pickler class.)

    spickle_node_list(nl,filename) extracts field variables from all nodes of nl,
    which must be a valid node list, and packs them in a dict that is returned
    to the caller. If the optional argument filename is a string then dict will
    also be pickled to a file of that name. The file will be overwritten if it
    exists.

    The s in spickle is for 'serial', a reminder that this method collects all
    nodes of the node list (from all ranks) in a single process. Thus this method
    is mainly useful for interactive work with small node lists. It is the user's
    responsibility to make sure her process has enough memory to hold the returned
    dict.

    See also: pflatten_node_list
    """

    # Make sure we are not wasting our time.
    assert isinstance(nl,(sph.Spheral.NodeSpace.FluidNodeList3d,
                          sph.Spheral.SolidMaterial.SolidNodeList3d)
                      ), "argument 1 must be a node list"
    assert isinstance(silent, bool), "true or false"
    
    # Start collecting data.
    if not silent:
        sys.stdout.write('Pickling ' +  nl.label() + ' ' + nl.name + '........')

    # Get values of field variables stored in internal nodes.
    xloc = nl.positions().internalValues()
    vloc = nl.velocity().internalValues()
    mloc = nl.mass().internalValues()
    rloc = nl.massDensity().internalValues()
    uloc = nl.specificThermalEnergy().internalValues()
    Hloc = nl.Hfield().internalValues()
    #(pressure and temperature are stored in the eos object.)
    eos = nl.equationOfState()
    ploc = sph.ScalarField('ploc',nl)
    Tloc = sph.ScalarField('loc',nl)
    rref = nl.massDensity()
    uref = nl.specificThermalEnergy()
    eos.setPressure(ploc,rref,uref)
    eos.setTemperature(Tloc,rref,uref)

    # Zip fields so that we have all fields for each node in the same tuple.
    #  We do this so we can concatenate everything in a single reduction operation,
    #  to ensure that all fields in one record in the final list belong to the 
    #  same node.
    localFields = zip(xloc, vloc, mloc, rloc, uloc, ploc, Tloc, Hloc)

    # Do a SUM reduction on all ranks.
    #  This works because the + operator for python lists is a concatenation!
    globalFields = mpi.allreduce(localFields, mpi.SUM)

    # Create a dictionary to hold field variables.
    nlFieldDict = dict(name=nl.name,
                       x=[],   # position vector
                       v=[],   # velocity vector
                       m=[],   # mass
                       rho=[], # mass density
                       p=[],   # pressure
                       h=[],   # smoothing ellipsoid axes
                       T=[],   # temperature
                       U=[],   # specific thermal energy
                      )

    # Loop over nodes to fill field values.
    nbGlobalNodes = mpi.allreduce(nl.numInternalNodes, mpi.SUM)
    for k in range(nbGlobalNodes):
        nlFieldDict[  'x'].append((globalFields[k][0].x, globalFields[k][0].y, globalFields[k][0].z))
        nlFieldDict[  'v'].append((globalFields[k][1].x, globalFields[k][1].y, globalFields[k][1].z))
        nlFieldDict[  'm'].append( globalFields[k][2])
        nlFieldDict['rho'].append( globalFields[k][3])
        nlFieldDict[  'U'].append( globalFields[k][4])
        nlFieldDict[  'p'].append( globalFields[k][5])
        nlFieldDict[  'T'].append( globalFields[k][6])
        nlFieldDict[  'h'].append((globalFields[k][7].Inverse().eigenValues().x,
                                   globalFields[k][7].Inverse().eigenValues().y,
                                   globalFields[k][7].Inverse().eigenValues().z,
                                   ))

    # Optionally, pickle the dict to a file.
    if mpi.rank == 0:
        if filename is not None:
            if isinstance(filename, str):
                with open(filename, 'wb') as fid:
                    pickle.dump(nlFieldDict, fid)
                    pass
                pass
            else:
                msg = "Dict NOT pickled to file because " + \
                      "argument 2 is {} instead of {}".format(type(filename), type('x'))
                sys.stderr.write(msg+'\n')
                pass
            pass
        pass
        
    # And Bob's our uncle.
    if not silent:
        print "Done."
    return nlFieldDict
    # at the requested angle.  We'll have it coming in from the positive x direction
    # in the xy plane.
    disp = Vector((rImpactor + rTarget) * cos(pi / 180.0 * angle_impact),
                  (rImpactor + rTarget) * sin(pi / 180.0 * angle_impact), 0.0)
    for i in xrange(impactorGenerator.localNumNodes()):
        impactorGenerator.x[i] += disp.x
        impactorGenerator.y[i] += disp.y
        impactorGenerator.z[i] += disp.z

    print "Starting node distribution..."
    distributeNodes3d((target, targetGenerator), (impactor, impactorGenerator))

    nGlobalNodes = 0
    for n in nodeSet:
        print "Generator info for %s" % n.name
        print "   Minimum number of nodes per domain : ", mpi.allreduce(
            n.numInternalNodes, mpi.MIN)
        print "   Maximum number of nodes per domain : ", mpi.allreduce(
            n.numInternalNodes, mpi.MAX)
        print "               Global number of nodes : ", mpi.allreduce(
            n.numInternalNodes, mpi.SUM)
        nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
    del n
    print "Total number of (internal) nodes in simulation: ", nGlobalNodes
    print "Ratio of impactor/target node mass : ", impactor.mass().max(
    ) / target.mass().max()

    # Intialize the impactor velocity.
    vel = impactor.velocity()
    for i in xrange(impactor.numInternalNodes):
        vel[i].x = -vImpact
Exemple #36
0
    def testPolyhedralMeshParallel(self):
        mesh, void = generatePolyhedralMesh([self.nodes],
                                            xmin=xmin,
                                            xmax=xmax,
                                            generateParallelConnectivity=True)

        neighborDomains = [int(x) for x in mesh.neighborDomains]
        sharedNodes = []
        for ll in mesh.sharedNodes:
            sharedNodes.append([int(x) for x in ll])
        assert len(neighborDomains) == len(mesh.sharedNodes)

        ##         # Check the correct domains are talking to each other.
        ##         nxproc = int(sqrt(numDomains))
        ##         assert nxproc*nxproc == numDomains
        ##         ixproc = rank % nxproc
        ##         iyproc = rank / nxproc
        ##         neighborDomainsAnswer = []
        ##         for iy in xrange(max(0, iyproc - 1), min(nxproc, iyproc + 2)):
        ##             for ix in xrange(max(0, ixproc - 1), min(nxproc, ixproc + 2)):
        ##                 if not (ix == ixproc and iy == iyproc):
        ##                     neighborDomainsAnswer.append(ix + iy*nxproc)
        ##         ok = mpi.allreduce((neighborDomains == neighborDomainsAnswer), mpi.MIN)
        ##         self.failUnless(ok, "Strange neighbor domains for %i : %s ?= %s" % (rank, neighborDomains, neighborDomainsAnswer))

        # Check that the communicated mesh nodes are consistent.
        boxInv = xmax - xmin
        boxInv = Vector(1.0 / boxInv.x, 1.0 / boxInv.y, 1.0 / boxInv.z)
        for sendProc in xrange(numDomains):
            numChecks = mpi.bcast(len(neighborDomains), root=sendProc)
            assert mpi.allreduce(numChecks,
                                 mpi.MIN) == mpi.allreduce(numChecks, mpi.MAX)
            for k in xrange(numChecks):
                if rank == sendProc:
                    ksafe = k
                else:
                    ksafe = 0
                recvProc = mpi.bcast(neighborDomains[ksafe], root=sendProc)
                recvHashes = mpi.bcast([
                    hashPosition(mesh.node(i).position(), xmin, xmax, boxInv)
                    for i in sharedNodes[ksafe]
                ],
                                       root=sendProc)
                recvPos = mpi.bcast(
                    [str(mesh.node(i).position()) for i in sharedNodes[ksafe]],
                    root=sendProc)
                ok = True
                msg = ""
                if rank == recvProc:
                    assert sendProc in neighborDomains
                    kk = neighborDomains.index(sendProc)
                    assert kk < len(sharedNodes)
                    ok = ([
                        hashPosition(
                            mesh.node(i).position(), xmin, xmax, boxInv)
                        for i in sharedNodes[kk]
                    ] == recvHashes)
                    msg = (
                        "Shared node indicies don't match %i %i\n   %s != %s\n    %s\n    %s"
                        % (rank, sendProc,
                           str([
                               hashPosition(
                                   mesh.node(i).position(), xmin, xmax, boxInv)
                               for i in sharedNodes[kk]
                           ]), recvHashes, [
                               str(mesh.node(i).position())
                               for i in sharedNodes[kk]
                           ], recvPos))
                self.failUnless(mpi.allreduce(ok, mpi.MIN), msg)

        # Check that all shared nodes have been found.
        myHashes = [
            hashPosition(mesh.node(i).position(), xmin, xmax, boxInv)
            for i in xrange(mesh.numNodes)
        ]
        myHashSet = set(myHashes)
        for sendProc in xrange(numDomains):
            theirHashSet = mpi.bcast(myHashSet, root=sendProc)
            if sendProc != mpi.rank:
                commonHashes = myHashSet.intersection(theirHashSet)
                self.failIf(
                    len(commonHashes) > 0
                    and (not sendProc in neighborDomains),
                    "Missed a neighbor domain : %i %i : %i" %
                    (mpi.rank, sendProc, len(commonHashes)))
                self.failIf(
                    len(commonHashes) == 0 and (sendProc in neighborDomains),
                    "Erroneously communicating between domains : %i %i" %
                    (mpi.rank, sendProc))
                if len(commonHashes) > 0:
                    k = neighborDomains.index(sendProc)
                    self.failUnless(
                        len(commonHashes) == len(sharedNodes[k]),
                        "Size of shared nodes does not match: %i %i : %i %i" %
                        (mpi.rank, sendProc, len(commonHashes),
                         len(sharedNodes[k])))
                    sharedHashes = set([myHashes[i] for i in sharedNodes[k]])
                    self.failUnless(sharedHashes == commonHashes,
                                    "Set of common hashes does not match")

        return
    Wsum = 0.0
    for nodeID in xrange(nodes1.numInternalNodes):
        Hi = H[nodeID]
        etaij = (Hi * pos[nodeID]).magnitude()
        if smoothSpike:
            Wi = WT.kernelValue(etaij / smoothSpikeScale, 1.0)
        else:
            if etaij < smoothSpikeScale * kernelExtent:
                Wi = 1.0
            else:
                Wi = 0.0
        Ei = Wi * Espike
        epsi = Ei / mass[nodeID]
        eps[nodeID] = epsi
        Wsum += Wi
    Wsum = mpi.allreduce(Wsum, mpi.SUM)
    assert Wsum > 0.0
    for nodeID in xrange(nodes1.numInternalNodes):
        eps[nodeID] /= Wsum
        Esum += eps[nodeID] * mass[nodeID]
        eps[nodeID] += eps0
else:
    i = -1
    rmin = 1e50
    for nodeID in xrange(nodes1.numInternalNodes):
        rij = pos[nodeID].magnitude()
        if rij < rmin:
            i = nodeID
            rmin = rij
        eps[nodeID] = eps0
    rminglobal = mpi.allreduce(rmin, mpi.MIN)
Exemple #38
0
        if pos[i].x < z0 + dz:
            eps[i] += epsi
            Esum += mass[i] * epsi
elif problem == "cylindrical":
    epsi = Espike / (rho0 * pi * dr * dr)
    for i in xrange(nodes1.numInternalNodes):
        if pos[i].y < r0 + dr:
            eps[i] += epsi
            Esum += mass[i] * epsi
else:
    epsi = 0.5 * Espike / (rho0 * pi * dr * dr * dz)
    for i in xrange(nodes1.numInternalNodes):
        if pos[i].magnitude() < sqrt(dr * dr + dz * dz):
            eps[i] += epsi
            Esum += mass[i] * epsi
Eglobal = mpi.allreduce(Esum, mpi.SUM)
if problem == "planar":
    Eexpect = 0.5 * Espike * pi * (r1 * r1 - r0 * r0)
elif problem == "cylindrical":
    Eexpect = Espike * (z1 - z0)
else:
    Eexpect = 0.5 * Espike
print "Initialized a total energy of", Eglobal, Eexpect, Eglobal / Eexpect
assert fuzzyEqual(Eglobal, Eexpect)

#-------------------------------------------------------------------------------
# Construct a DataBase to hold our node list
#-------------------------------------------------------------------------------
db = DataBase()
output("db")
output("db.appendNodeList(nodes1)")
Exemple #39
0
                      (rTarget + rImpactor) * sin(pi / 180.0 * angleImpact),
                      0.0)
    for k in range(impactorGenerator.localNumNodes()):
        impactorGenerator.x[k] += displace.x
        impactorGenerator.y[k] += displace.y
        impactorGenerator.z[k] += displace.z
        pass

    # Fill node lists using generators and distribute to ranks.
    print "Starting node distribution..."
    distributeNodes3d((target, targetGenerator), (impactor, impactorGenerator))
    nGlobalNodes = 0
    for n in nodeSet:
        print "Generator info for %s" % n.name
        print "   Minimum number of nodes per domain : ", \
              mpi.allreduce(n.numInternalNodes, mpi.MIN)
        print "   Maximum number of nodes per domain : ", \
              mpi.allreduce(n.numInternalNodes, mpi.MAX)
        print "               Global number of nodes : ", \
              mpi.allreduce(n.numInternalNodes, mpi.SUM)
        nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
    del n
    print "Total number of (internal) nodes in simulation: ", nGlobalNodes
    WMR = (max(impactor.mass().max(),
               target.mass().max()) / min(impactor.mass().min(),
                                          target.mass().min()))
    if WMR < 1.5:
        sys.stderr.write("\033[32m")
    else:
        sys.stderr.write("\033[31m")
    print "Worst node mass ratio: {}".format(WMR)
                   0.0)
 for k in range(impactorGenerator.localNumNodes()):
     impactorGenerator.x[k] += displace.x
     impactorGenerator.y[k] += displace.y
     impactorGenerator.z[k] += displace.z
     pass
                                                    
 # Fill node lists using generators and distribute to ranks.
 print "Starting node distribution..."
 distributeNodes3d((target, targetGenerator),
                   (impactor, impactorGenerator))
 nGlobalNodes = 0
 for n in nodeSet:
     print "Generator info for %s" % n.name
     print "   Minimum number of nodes per domain : ", \
           mpi.allreduce(n.numInternalNodes, mpi.MIN)
     print "   Maximum number of nodes per domain : ", \
           mpi.allreduce(n.numInternalNodes, mpi.MAX)
     print "               Global number of nodes : ", \
           mpi.allreduce(n.numInternalNodes, mpi.SUM)
     nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
 del n
 print "Total number of (internal) nodes in simulation: ", nGlobalNodes
 WMR = (max(impactor.mass().max(), target.mass().max())/
        min(impactor.mass().min(), target.mass().min()))
 if WMR < 1.5:
     sys.stderr.write("\033[32m")
 else:
     sys.stderr.write("\033[31m")
 print "Worst node mass ratio: {}".format(WMR)
 sys.stderr.write("\033[0m")
Exemple #41
0
    def __init__(self,
                 ndim,
                 n,
                 rho,
                 boundary,
                 gradrho,
                 holes,
                 centroidFrac,
                 maxIterations,
                 fracTol,
                 tessellationBaseDir,
                 tessellationFileName,
                 nNodePerh,
                 randomseed,
                 maxNodesPerDomain,
                 seedPositions,
                 enforceConstantMassPoints,
                 cacheFileName):

        assert ndim in (2,3)
        assert n > 0

        # Load our handy aliases.
        if ndim == 2:
            import Spheral2d as sph
        else:
            import Spheral3d as sph

        # Did we get passed a function or a constant for the density?
        if type(rho) in (float, int):
            def rhofunc(posi):
                return rho
            rhomax = rho
        else:
            rhofunc = rho
            rhomax = None
        self.rhofunc = rhofunc

        # Some useful geometry.
        box = boundary.xmax - boundary.xmin
        length = box.maxElement()
        boundvol = boundary.volume
        for hole in holes:
            boundvol -= hole.volume
        if boundvol <= 0.0:
            # The holes were not entirely contained in the bounding volume, so we punt.
            boundvol = 0.5*boundary.volume
        boxvol = 1.0
        for idim in xrange(ndim):
            boxvol *= box[idim]
        fracOccupied = min(1.0, boxvol/boundvol)
        assert fracOccupied > 0.0 and fracOccupied <= 1.0

        # If there is an pre-existing cache file, load it instead of doing all the work.
        if not self.restoreState(cacheFileName):

            # Create a temporary NodeList we'll use store and update positions.
            eos = sph.GammaLawGasMKS(2.0, 2.0)
            WT = sph.TableKernel(sph.NBSplineKernel(7), 1000)
            hmax = 2.0*(boundvol/pi*n)**(1.0/ndim)
            nodes = sph.makeFluidNodeList("tmp generator nodes", 
                                          eos,
                                          hmin = 1e-10,
                                          hmax = hmax,
                                          kernelExtent = WT.kernelExtent,
                                          hminratio = 1.0,
                                          nPerh = nNodePerh,
                                          topGridCellSize = 2.0*WT.kernelExtent*hmax)
        
            # Make a first pass looking for the maximum density (roughly).
            pos = nodes.positions()
            mass = nodes.mass()
            rhof = nodes.massDensity()
            H = nodes.Hfield()
            imin, imax = self.globalIDRange(n)
            nlocal = imax - imin
            nodes.numInternalNodes = nlocal
        
            # If the user provided the starting or seed positions, use 'em.
            if seedPositions is not None:
                hi = min(hmax, 2.0 * (boundvol/(pi*n))**(1.0/ndim))
                assert hi > 0.0
                nlocal = len(seedPositions)
                assert mpi.allreduce(nlocal, mpi.SUM) == n
                nodes.numInternalNodes = nlocal
                for i in xrange(nlocal):
                    pos[i] = seedPositions[i]
                    rhoi = rhofunc(pos[i])
                    rhof[i] = rhoi
                    mass[i] = rhoi * boundvol/n  # Not actually correct, but mass will be updated in centroidalRelaxNodes
                    H[i] = sph.SymTensor.one / hi
        
            else:
                # If necessary probe for a maximum density statistically.
                rangen = random.Random(randomseed + mpi.rank)
                if not rhomax:
                    rhomax = 0.0
                    nglobal = 0
                    while nglobal < n:
                        p = boundary.xmin + length*sph.Vector(rangen.random(), rangen.random(), rangen.random())
                        use = boundary.contains(p, False)
                        if use:
                            ihole = 0
                            while use and ihole < len(holes):
                                use = not holes[ihole].contains(p, True)
                                ihole += 1
                        if use:
                            rhomax = max(rhomax, rhofunc(p))
                            i = 1
                        else:
                            i = 0
                        nglobal += mpi.allreduce(i, mpi.SUM)
                    rhomax = mpi.allreduce(rhomax, mpi.MAX)
                print "MedialGenerator: selected a maximum density of ", rhomax
            
                # It's a bit tricky to properly use the Sobol sequence in parallel.  We handle this by searching for the lowest
                # seeds that give us the desired number of points.
                seeds = []
                seed = 0
                while mpi.allreduce(len(seeds), mpi.SUM) < n:
                    localseed = seed + mpi.rank
                    [coords, newseed] = i4_sobol(ndim, localseed)
                    p = boundary.xmin + length*sph.Vector(*tuple(coords))
                    use = boundary.contains(p, False)
                    if use:
                        ihole = 0
                        while use and ihole < len(holes):
                            use = not holes[ihole].contains(p, True)
                            ihole += 1
                    if use:
                        rhoi = rhofunc(p)
                        if rangen.random() < rhoi/rhomax:
                            seeds.append(localseed)
                    seed += mpi.procs
            
                # Drop the highest value seeds to ensure we have the correct number of total points.
                nglobal = mpi.allreduce(len(seeds), mpi.SUM)
                assert n + mpi.procs >= nglobal
                seeds.sort()
                seeds = [-1] + seeds
                while mpi.allreduce(len(seeds), mpi.SUM) > n + mpi.procs:
                    maxseed = mpi.allreduce(seeds[-1], mpi.MAX)
                    assert maxseed > -1
                    if seeds[-1] == maxseed:
                        seeds = seeds[:-1]
                seeds = seeds[1:]
            
                # Load balance the number of seeds per domain.
                if len(seeds) > nlocal:
                    extraseeds = seeds[nlocal:]
                else:
                    extraseeds = []
                extraseeds = mpi.allreduce(extraseeds, mpi.SUM)
                seeds = seeds[:nlocal]
                for iproc in xrange(mpi.procs):
                    ngrab = max(0, nlocal - len(seeds))
                    ntaken = mpi.bcast(ngrab, root=iproc)
                    if mpi.rank == iproc:
                        seeds += extraseeds[:ngrab]
                    extraseeds = extraseeds[ntaken:]
                assert len(extraseeds) == 0
                assert len(seeds) == nlocal
                assert mpi.allreduce(len(seeds), mpi.SUM) == n
            
                # Initialize the desired number of generators in the boundary using the Sobol sequence.
                hi = min(hmax, 2.0 * (boundvol/(pi*n))**(1.0/ndim))
                assert hi > 0.0
                for i, seed in enumerate(seeds):
                    [coords, newseed] = i4_sobol(ndim, seed)
                    p = boundary.xmin + length*sph.Vector(*tuple(coords))
                    rhoi = rhofunc(p)
                    pos[i] = p
                    rhof[i] = rhoi
                    mass[i] = rhoi * boundvol/n  # Not actually correct, but mass will be updated in centroidalRelaxNodes
                    H[i] = sph.SymTensor.one / hi
        
                # Each domain has independently generated the correct number of points, but they are randomly distributed.
                # Before going further it's useful to try and spatially collect the points by domain.
                # We'll use the Spheral Peano-Hilbert space filling curve implementation to do this.
                if mpi.procs > 1:
                    db = sph.DataBase()
                    db.appendNodeList(nodes)
                    maxNodes = max(maxNodesPerDomain, 2*n/mpi.procs)
                    redistributor = sph.PeanoHilbertOrderRedistributeNodes(2.0)
                    redistributor.redistributeNodes(db)
        
            # If we're in parallel we need the parallel boundary.
            if mpi.procs > 1:
                boundaries = [sph.TreeDistributedBoundary.instance()]
            else:
                boundaries = []
        
            # Iterate the points toward centroidal relaxation.
            vol, surfacePoint = centroidalRelaxNodes([(nodes, boundary, holes)],
                                                     W = WT,
                                                     rho = rhofunc,
                                                     gradrho = gradrho,
                                                     boundaries = boundaries,
                                                     fracTol = fracTol,
                                                     centroidFrac = centroidFrac,
                                                     maxIterations = maxIterations,
                                                     tessellationBaseDir = tessellationBaseDir,
                                                     tessellationFileName = tessellationFileName)
        
            # Store the values the descendent generators will need.
            self.vol, self.surface, self.pos, self.m, self.H = [], [], [], [], []
            for i in xrange(nodes.numInternalNodes):
                self.vol.append(vol(0,i))
                self.surface.append(surfacePoint(0,i))
                self.pos.append(sph.Vector(pos[i]))
                self.m.append(vol(0,i) * rhofunc(pos[i]))
                self.H.append(sph.SymTensor(H[i]))
            assert mpi.allreduce(len(self.vol), mpi.SUM) == n
            assert mpi.allreduce(len(self.surface), mpi.SUM) == n
            assert mpi.allreduce(len(self.pos), mpi.SUM) == n
            assert mpi.allreduce(len(self.m), mpi.SUM) == n
            assert mpi.allreduce(len(self.H), mpi.SUM) == n
        
            # If requested, enforce constant mass points.
            if enforceConstantMassPoints:
                msum = mpi.allreduce(sum([0.0] + self.m), mpi.SUM)
                self.m = [msum/n]*len(self.pos)

            # If requested, we can store the state of the generator such that it can be
            # later restored without going through all that work.
            if cacheFileName:
                self.dumpState(cacheFileName)

        return
    # We disturb the lattice symmetry to avoid artificial singularities.
    for k in range(planetGenerator.localNumNodes()):
        planetGenerator.x[k] *= 1.0 + random.uniform(-0.02, 0.02)
        planetGenerator.y[k] *= 1.0 + random.uniform(-0.02, 0.02)
        planetGenerator.z[k] *= 1.0 + random.uniform(-0.02, 0.02)
        pass


    # Fill node list using generators and distribute to ranks.
    print "Starting node distribution..."
    distributeNodes3d((planet, planetGenerator))
    nGlobalNodes = 0
    for n in nodeSet:
        print "Generator info for %s" % n.name
        print "   Minimum number of nodes per domain : ", \
              mpi.allreduce(n.numInternalNodes, mpi.MIN)
        print "   Maximum number of nodes per domain : ", \
              mpi.allreduce(n.numInternalNodes, mpi.MAX)
        print "               Global number of nodes : ", \
              mpi.allreduce(n.numInternalNodes, mpi.SUM)
        nGlobalNodes += mpi.allreduce(n.numInternalNodes, mpi.SUM)
    del n
    print "Total number of (internal) nodes in simulation: ", nGlobalNodes
    
    pass
# The spheral controller needs a DataBase object to hold the node lists.
db = DataBase()
for n in nodeSet:
    db.appendNodeList(n)
del n