Beispiel #1
0
#-------------------------------------------------------------------------------
# If requested, write out the state in a global ordering to a file.
#-------------------------------------------------------------------------------
from SpheralGnuPlotUtilities import multiSort
mof = mortonOrderIndices(db)
mo = createList(mof)
rhoprof = createList(db.fluidMassDensity)
Pprof = createList(hydro.pressure())
vprof = [v.x for v in createList(db.fluidVelocity)]
epsprof = createList(db.fluidSpecificThermalEnergy)
hprof = [1.0/Hi.xx for Hi in createList(db.fluidHfield)]

rmin = x0
rmax = x2
if mpi.rank == 0:
    multiSort(mo, xprof, rhoprof, Pprof, vprof, epsprof, hprof)
    if outputFile != "None":
        outputFile = os.path.join(dataDir, outputFile)
        f = open(outputFile, "w")
        f.write(("#  " + 19*"'%s' " + "\n") % ("x", "rho", "P", "v", "eps", "A", "h", "mo",
                                               "rhoans", "Pans", "vans", "Aans", "hans",
                                               "x_UU", "rho_UU", "P_UU", "v_UU", "eps_UU", "h_UU"))
        for (xi, rhoi, Pi, vi, epsi, Ai, hi, mi,
             rhoansi, Pansi, vansi, Aansi, hansi) in zip(xprof, rhoprof, Pprof, vprof, epsprof, A, hprof, mo,
                                                         rhoans, Pans, vans, Aans, hans):
            f.write((7*"%16.12e " + "%i " + 5*"%16.12e " + 6*"%i " + '\n') % 
                    (xi, rhoi, Pi, vi, epsi, Ai, hi, mi,
                     rhoansi, Pansi, vansi, Aansi, hansi,
                     unpackElementUL(packElementDouble(xi)),
                     unpackElementUL(packElementDouble(rhoi)),
                     unpackElementUL(packElementDouble(Pi)),
Beispiel #2
0
        "epsans", "hans"
    ]
    stuff = [
        xprof, mprof, rhoprof, Pprof, vprof, epsprof, hprof, rhoans, Pans,
        vans, uans, hans
    ]
    if CRKSPH:
        A0prof = mpi.reduce(hydro.A0()[0].internalValues(), mpi.SUM)
        Aprof = mpi.reduce(hydro.A()[0].internalValues(), mpi.SUM)
        Bprof = mpi.reduce([x.x for x in hydro.B()[0].internalValues()],
                           mpi.SUM)
        labels += ["A0", "A", "B"]
        stuff += [A0prof, Aprof, Bprof]

    if mpi.rank == 0:
        multiSort(*tuple(stuff))
        f = open(outputFile, "w")
        f.write(("#  " + len(labels) * "'%s' " + "\n") % tuple(labels))
        for tup in zip(*tuple(stuff)):
            assert len(tup) == len(labels)
            f.write((len(tup) * "%16.12e " + "\n") % tup)
        f.close()

        # While we're at it compute and report the error norms.
        import Pnorm
        print "\tQuantity \t\tL1 \t\t\tL2 \t\t\tLinf"
        if normOutputFile != "None":
            f = open(normOutputFile, "a")
            if writeOutputLabel:
                f.write(
                    ("#" + 13 * "%17s " + "\n") %
Beispiel #3
0
    assert hrfield.numElements == n
    assert htfield.numElements == n
    positions = Hfield.nodeList().positions()
    for i in xrange(n):
        runit = positions[i].unitVector()
        tunit = Vector(-(positions[i].y), positions[i].x).unitVector()
        hrfield[i] = (Hfield[i] * runit).magnitude()
        htfield[i] = (Hfield[i] * tunit).magnitude()
hr = mpi.allreduce(list(hrfl[0].internalValues()), mpi.SUM)
ht = mpi.allreduce(list(htfl[0].internalValues()), mpi.SUM)

Aans = None
if mpi.rank == 0:
    from SpheralGnuPlotUtilities import multiSort
    import Pnorm
    multiSort(r, rho, v, eps, P, A, hr, ht)
    rans, vans, epsans, rhoans, Pans, hans = answer.solution(control.time(), r)
    Aans = [Pi / (rhoi**gamma) for (Pi, rhoi) in zip(Pans, rhoans)]
    print "\tQuantity \t\tL1 \t\t\tL2 \t\t\tLinf"
    #f = open("MCTesting.txt", "a")
    #f.write(("CL=%g, Cq=%g \t") %(Cl, Cq))
    for (name, data, ans) in [("Mass Density", rho, rhoans),
                              ("Pressure", P, Pans), ("Velocity", v, vans),
                              ("Thermal E", eps, epsans), ("Entropy", A, Aans),
                              ("hr", hr, hans)]:
        assert len(data) == len(ans)
        error = [data[i] - ans[i] for i in xrange(len(data))]
        Pn = Pnorm.Pnorm(error, r)
        L1 = Pn.gridpnorm(1, rmin, rmax)
        L2 = Pn.gridpnorm(2, rmin, rmax)
        Linf = Pn.gridpnorm("inf", rmin, rmax)
Beispiel #4
0
 # Report the error norms.
 rmin, rmax = 0.05, 0.35
 r = mpi.allreduce(
     [x.magnitude() for x in nodes1.positions().internalValues()], mpi.SUM)
 rho = mpi.allreduce(list(nodes1.massDensity().internalValues()), mpi.SUM)
 v = mpi.allreduce(
     [x.magnitude() for x in nodes1.velocity().internalValues()], mpi.SUM)
 eps = mpi.allreduce(list(nodes1.specificThermalEnergy().internalValues()),
                     mpi.SUM)
 Pf = ScalarField("pressure", nodes1)
 nodes1.pressure(Pf)
 P = mpi.allreduce(list(Pf.internalValues()), mpi.SUM)
 if mpi.rank == 0:
     from SpheralGnuPlotUtilities import multiSort
     import Pnorm
     multiSort(r, rho, v, eps, P)
     rans, vans, epsans, rhoans, Pans, hans = answer.solution(
         control.time(), r)
     with open("Converge.txt", "a") as myfile:
         myfile.write("%s %s %s %s " % (nx, ny, nz, nx + ny + nz))
         print "\tQuantity \t\tL1 \t\t\tL2 \t\t\tLinf"
         for (name, data, ans) in [("Mass Density", rho, rhoans),
                                   ("Pressure", P, Pans),
                                   ("Velocity", v, vans),
                                   ("Thermal E", eps, epsans)]:
             assert len(data) == len(ans)
             error = [data[i] - ans[i] for i in xrange(len(data))]
             Pn = Pnorm.Pnorm(error, r)
             L1 = Pn.gridpnorm(1, rmin, rmax)
             L2 = Pn.gridpnorm(2, rmin, rmax)
             Linf = Pn.gridpnorm("inf", rmin, rmax)
Beispiel #5
0
v = mpi.allreduce([x.magnitude() for x in nodes1.velocity().internalValues()], mpi.SUM)
eps = mpi.allreduce(list(nodes1.specificThermalEnergy().internalValues()), mpi.SUM)
Pf = ScalarField("pressure", nodes1)
nodes1.pressure(Pf)
P = mpi.allreduce(list(Pf.internalValues()), mpi.SUM)
A = mpi.allreduce([Pi/(rhoi**gamma) for (Pi, rhoi) in zip(Pf.internalValues(), nodes1.massDensity().internalValues())], mpi.SUM)

Hinverse = db.newFluidSymTensorFieldList()
db.fluidHinverse(Hinverse)
hr = mpi.allreduce([x.xx for x in Hinverse[0].internalValues()], mpi.SUM)

Aans = None
if mpi.rank == 0:
    from SpheralGnuPlotUtilities import multiSort
    import Pnorm
    multiSort(r, rho, v, eps, P, A, hr)
    rans, vans, epsans, rhoans, Pans, hans = answer.solution(control.time(), r)
    Aans = [Pi/(rhoi**gamma) for (Pi, rhoi) in zip(Pans, rhoans)]
    print "\tQuantity \t\tL1 \t\t\tL2 \t\t\tLinf"
    #f = open("MCTesting.txt", "a")
    #f.write(("CL=%g, Cq=%g \t") %(Cl, Cq))
    for (name, data, ans) in [("Mass Density", rho, rhoans),
                              ("Pressure", P, Pans),
                              ("Velocity", v, vans),
                              ("Thermal E", eps, epsans),
                              ("Entropy", A, Aans),
                              ("hr", hr, hans)]:
        assert len(data) == len(ans)
        error = [data[i] - ans[i] for i in xrange(len(data))]
        Pn = Pnorm.Pnorm(error, r)
        L1 = Pn.gridpnorm(1, rmin, rmax)
Beispiel #6
0
    def __init__(self, nr, densityProfileMethod,
                 rmin = 0.0,
                 rmax = 1.0,
                 thetaMin = 0.0,
                 thetaMax = pi,
                 nNodePerh = 2.01,
                 offset=None,
                 m0ForMassMatching=None):
        
        assert nr > 0
        assert rmin >= 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 nNodePerh > 0.0
        assert offset is None or len(offset)==3
        
        if offset is None:
            self.offset = Vector2d(0,0)
        else:
            self.offset = Vector2d(offset[0],offset[1])
        
        self.nr         = nr
        self.rmin       = rmin
        self.rmax       = rmax
        self.thetaMin   = thetaMin
        self.thetaMax   = thetaMax
        self.nNodePerh  = nNodePerh
        
        self.xmin       = Vector2d(-2.0*rmax,-2.0*rmax)
        self.xmax       = Vector2d(2.0*rmax,2.0*rmax)
        
        # no reason to support a constant density method here, just use a regular lattice for that
        self.densityProfileMethod = densityProfileMethod
        
        # Determine how much total mass there is in the system.
        targetMass = self.integrateTotalMass(self.densityProfileMethod,
                                                 rmin, rmax,
                                                 thetaMin, thetaMax)

        
        #targetMass = self.integrateTotalMass(self.densityProfileMethod,
        #                                         rmax)
        
        targetN         = pi*(nr**2)
        self.m0         = targetMass/targetN
        self.vol        = pi*(rmax**2)
        # what this means is this currently only supports creating a full sphere and then
        # cutting out the middle to rmin if rmin > 0
        
        if m0ForMassMatching is None:
            self.rho0       = targetMass/self.vol
        else:
            self.m0 = m0ForMassMatching
            self.rho0 = targetN*self.m0/self.vol
        
        print "Found total mass = {0:3.3e} with rho0 = {1:3.3e}".format(targetMass,self.rho0)
    
        # compute kappa first
        # k = 3/(self.rho0*rmax**3) * targetMass/(4.0*pi)
        # print "Found kappa={0:3.3f}. Was that what you expected?".format(k)
        
        nlat = nr
        
        # create the unstretched lattice
        self.xl, self.yl, self.ml, self.Hl = \
            self.latticeDistribution(nlat,
                                     self.rho0,
                                     self.m0,
                                     self.xmin,    # (xmin, ymin, zmin)
                                     self.xmax,    # (xmax, ymax, zmax)
                                     self.rmax,
                                     self.nNodePerh)


        self.rl = []
        for i in xrange(len(self.xl)):
            self.rl.append(sqrt(self.xl[i]**2+self.yl[i]**2))
        
        print "Sorting unstretched lattice... %d elements" % len(self.rl)
        
        multiSort(self.rl,self.xl,self.yl)
        
        self.x = []
        self.y = []
        self.m = []
        self.H = []
        
        nx  = 2*nlat+1
        eta = (self.xmax[0] - self.xmin[0])/nx
        
        print "Stretching lattice..."

        dr  = eta * 0.01    # this will essentially be the error in the new dumb way
        r0p = 0
        rp  = 0
        rn  = 0
        for i in xrange(1,len(self.rl)):
            #print "%d / %d" % (i,len(self.rl))
            r0 = self.rl[i]
            if (abs(r0-r0p)/r0>1e-10):
                sol     = r0**2*self.rho0/2.0
                iter    = int(10*rmax // dr)
                fn      = 0
                for j in xrange(iter+1):
                    rj  = dr*j
                    rjj = dr*(j+1)
                    fj  = rj * densityProfileMethod(rj)
                    fjj = rjj * densityProfileMethod(rjj)
                    fn  = fn + 0.5*(fj+fjj)*dr
                    if (fn>=sol):
                        rn = rj
                        break
            r0p = r0
            if (rn <= rmax and rn > rmin):
                self.x.append(self.xl[i] * rn/r0)
                self.y.append(self.yl[i] * rn/r0)
                self.m.append(self.ml[i])
                self.H.append(self.Hl[i])
    
        seededMass = sum(self.m)
        
        mAdj = targetMass / seededMass
        for i in xrange(len(self.m)):
            self.m[i] = self.m[i] * mAdj

        
        # Initialize the base class.  If "serialInitialization" is True, this
        # is where the points are broken up between processors as well.
        serialInitialization = True
        NodeGeneratorBase.__init__(self, serialInitialization,
                                   self.x, self.y, self.m, self.H)
    
        return
Beispiel #7
0
 Hfield = state.symTensorFields(HydroFieldNames.H)
 S = state.symTensorFields(SolidFieldNames.deviatoricStress)
 ps = state.scalarFields(SolidFieldNames.plasticStrain)
 rprof = mpi.reduce([x.magnitude() for x in internalValues(pos)], mpi.SUM)
 rhoprof = mpi.reduce(internalValues(rho), mpi.SUM)
 Pprof = mpi.reduce(internalValues(P), mpi.SUM)
 vprof = mpi.reduce([v.x for v in internalValues(vel)], mpi.SUM)
 epsprof = mpi.reduce(internalValues(eps), mpi.SUM)
 hprof = mpi.reduce([2.0 / (H.Trace()) for H in internalValues(Hfield)],
                    mpi.SUM)
 sprof = mpi.reduce([x.xx for x in internalValues(S)], mpi.SUM)
 psprof = mpi.reduce(internalValues(ps), mpi.SUM)
 mof = mortonOrderIndices(db)
 mo = mpi.reduce(internalValues(mof), mpi.SUM)
 if mpi.rank == 0:
     multiSort(mo, rprof, rhoprof, Pprof, vprof, epsprof, hprof, sprof,
               psprof)
     f = open(outputFile, "w")
     f.write(("#" + 17 * ' "%16s"' + "\n") %
             ("r", "rho", "P", "v", "eps", "h", "S", "plastic strain", "m",
              "int(r)", "int(rho)", "int(P)", "int(v)", "int(eps)",
              "int(h)", "int(S)", "int(ps)"))
     for (ri, rhoi, Pi, vi, epsi, hi, si, psi,
          mi) in zip(rprof, rhoprof, Pprof, vprof, epsprof, hprof, sprof,
                     psprof, mo):
         f.write((8 * "%16.12e " + 9 * "%i " + "\n") %
                 (ri, rhoi, Pi, vi, epsi, hi, si, psi, mi,
                  unpackElementUL(packElementDouble(ri)),
                  unpackElementUL(packElementDouble(rhoi)),
                  unpackElementUL(packElementDouble(Pi)),
                  unpackElementUL(packElementDouble(vi)),
                  unpackElementUL(packElementDouble(epsi)),
Beispiel #8
0
 from SpheralGnuPlotUtilities import multiSort
 mof = mortonOrderIndices(db)
 mo = mpi.reduce(mof[0].internalValues(), mpi.SUM)
 mprof = mpi.reduce(nodes1.mass().internalValues(), mpi.SUM)
 rhoprof = mpi.reduce(nodes1.massDensity().internalValues(), mpi.SUM)
 P = ScalarField("pressure", nodes1)
 nodes1.pressure(P)
 Pprof = mpi.reduce(P.internalValues(), mpi.SUM)
 vprof = mpi.reduce([v.x for v in nodes1.velocity().internalValues()],
                    mpi.SUM)
 epsprof = mpi.reduce(nodes1.specificThermalEnergy().internalValues(),
                      mpi.SUM)
 hprof = mpi.reduce([1.0 / H.xx for H in nodes1.Hfield().internalValues()],
                    mpi.SUM)
 if mpi.rank == 0:
     multiSort(xprof, rhoprof, Pprof, vprof, epsprof, hprof, mo, rhoans,
               Pans, vans, uans, hans)
     f = open(outputFile, "w")
     f.write(("#  " + 20 * "'%s' " + "\n") %
             ("x", "m", "rho", "P", "v", "eps", "h", "mo", "rhoans", "Pans",
              "vans", "epsans", "hans", "x_UU", "m_UU", "rho_UU", "P_UU",
              "v_UU", "eps_UU", "h_UU"))
     for (xi, mi, rhoi, Pi, vi, epsi, hi, moi, rhoansi, Pansi, vansi, uansi,
          hansi) in zip(xprof, mprof, rhoprof, Pprof, vprof, epsprof, hprof,
                        mo, rhoans, Pans, vans, uans, hans):
         f.write(
             (7 * "%16.12e " + "%i " + 5 * "%16.12e " + 7 * "%i " + '\n') %
             (xi, mi, rhoi, Pi, vi, epsi, hi, moi, rhoansi, Pansi, vansi,
              uansi, hansi, unpackElementUL(packElementDouble(xi)),
              unpackElementUL(packElementDouble(mi)),
              unpackElementUL(packElementDouble(rhoi)),
              unpackElementUL(packElementDouble(Pi)),
Beispiel #9
0
        [v.magnitude() for v in nodes.velocity().internalValues()], mpi.SUM)
    velx = mpi.reduce([v.x for v in nodes.velocity().internalValues()],
                      mpi.SUM)
    vely = mpi.reduce([v.y for v in nodes.velocity().internalValues()],
                      mpi.SUM)
    epsprof = mpi.reduce(nodes.specificThermalEnergy().internalValues(),
                         mpi.SUM)
    hprof = mpi.reduce(
        [1.0 / sqrt(H.Determinant()) for H in nodes.Hfield().internalValues()],
        mpi.SUM)
    mof = mortonOrderIndices(db)
    mo = mpi.reduce(mof[0].internalValues(), mpi.SUM)

    if mpi.rank == 0:
        rprof = [sqrt(xi * xi + yi * yi) for xi, yi in zip(xprof, yprof)]
        multiSort(rprof, mo, xprof, yprof, rhoprof, Pprof, vprof, epsprof,
                  hprof, velx, vely)
        L1 = 0.0
        vazprof = []
        for i in xrange(len(xprof)):
            rhat = (Vector(xprof[i], yprof[i]) - Vector(xc, yc)).unitVector()
            vel_vec = Vector(velx[i], vely[i])
            vazprof.append((vel_vec - vel_vec.dot(rhat) * rhat).magnitude())
            vans = 0.0
            if rprof[i] < 0.2:
                vans = 5 * rprof[i]
            elif rprof[i] < 0.4:
                vans = 2.0 - 5.0 * rprof[i]
            else:
                vans = 0.0
            L1 = L1 + abs(vazprof[i] - vans)
        L1 = L1 / len(xprof)
Beispiel #10
0
                  mpi.SUM)
eps = mpi.allreduce(list(nodes1.specificThermalEnergy().internalValues()),
                    mpi.SUM)
Pf = ScalarField("pressure", nodes1)
nodes1.pressure(Pf)
P = mpi.allreduce(list(Pf.internalValues()), mpi.SUM)
A = mpi.allreduce([
    Pi / (rhoi**gamma)
    for (Pi, rhoi) in zip(Pf.internalValues(),
                          nodes1.massDensity().internalValues())
], mpi.SUM)

rans, vans, epsans, rhoans, Pans, Aans, hans = answer.solution(
    control.time(), r)
from SpheralGnuPlotUtilities import multiSort
multiSort(r, rho, v, eps, P, A, rhoans, vans, epsans, Pans, hans)

if mpi.rank == 0:
    from SpheralGnuPlotUtilities import multiSort
    import Pnorm
    multiSort(r, rho, v, eps, P, A)
    print "\tQuantity \t\tL1 \t\t\tL2 \t\t\tLinf"
    for (name, data, ans) in [("Mass Density", rho, rhoans),
                              ("Pressure", P, Pans), ("Velocity", v, vans),
                              ("Thermal E", eps, epsans),
                              ("Entropy", A, Aans)]:
        assert len(data) == len(ans)
        error = [data[i] - ans[i] for i in xrange(len(data))]
        Pn = Pnorm.Pnorm(error, r)
        L1 = Pn.gridpnorm(1, rmin, rmax)
        L2 = Pn.gridpnorm(2, rmin, rmax)
Beispiel #11
0
gamma = db.newFluidScalarFieldList(0.0, "specific heat ratio")
db.fluidGamma(gamma)
gammaList = createList(gamma)

rho = createList(db.fluidMassDensity)
P = createList(hydro.pressure)
A = [Pi / rhoi**gammai for (Pi, rhoi, gammai) in zip(P, rho, gammaList)]

# The analytic solution for the simulated entropy.
xprof = [x.x for x in createList(db.fluidPosition)]
vxprof = [v.x for v in createList(db.fluidVelocity)]
vyprof = [v.y for v in createList(db.fluidVelocity)]
vzprof = [v.z for v in createList(db.fluidVelocity)]
epsprof = createList(db.fluidSpecificThermalEnergy)
hprof = [1.0 / Hi.xx for Hi in createList(db.fluidHfield)]
multiSort(xprof, rho, P, A, vxprof, vyprof, vzprof, epsprof, hprof)
xans, vans, uans, rhoans, Pans, hans, gammaans = answer.solution(
    control.time(), xprof)
Aans = [
    Pi / rhoi**gammai for (Pi, rhoi, gammai) in zip(Pans, rhoans, gammaans)
]
csAns = [
    sqrt(gammai * Pi / rhoi)
    for (Pi, rhoi, gammai) in zip(Pans, rhoans, gammaans)
]

if graphics:

    rhoPlot, velPlot, epsPlot, PPlot, HPlot = plotState(db,
                                                        plotStyle="rx",
                                                        filterFunc=plotFilter)
Beispiel #12
0
    vprof1 = []
    vprof2 = []
    if mpi.rank == 0:
        for i in xrange(np1):
            vprof1.append(xprof1[i] * vx1[i] / rprof1[i] +
                          yprof1[i] * vy1[i] / rprof1[i])
        for i in xrange(np2):
            vprof2.append(xprof2[i] * vx2[i] / rprof2[i] +
                          yprof2[i] * vy2[i] / rprof2[i])

    mof = mortonOrderIndices(db)
    mo1 = mpi.reduce(mof[0].internalValues(), mpi.SUM)
    mo2 = mpi.reduce(mof[1].internalValues(), mpi.SUM)
    if mpi.rank == 0:
        multiSort(rprof1, mo1, xprof1, yprof1, rhoprof1, Pprof1, vprof1)
        multiSort(rprof2, mo2, xprof2, yprof2, rhoprof2, Pprof2, vprof2)
        f = open(outputFile, "w")
        f.write("r x y rho P v mortonOrder\n")
        for (ri, xi, yi, rhoi, Pi, vi, mi) in zip(rprof1, xprof1, yprof1,
                                                  rhoprof1, Pprof1, vprof1,
                                                  mo1):
            f.write((7 * "%16.12e " + "\n") % (ri, xi, yi, rhoi, Pi, vi, mi))
        for (ri, xi, yi, rhoi, Pi, vi, mi) in zip(rprof2, xprof2, yprof2,
                                                  rhoprof2, Pprof2, vprof2,
                                                  mo2):
            f.write((7 * "%16.12e " + "\n") % (ri, xi, yi, rhoi, Pi, vi, mi))

        f.close()
        if comparisonFile != "None":
            comparisonFile = os.path.join(dataDir, comparisonFile)
Beispiel #13
0
    def __init__(self,
                 nr,
                 densityProfileMethod,
                 rmin=0.0,
                 rmax=1.0,
                 thetaMin=0.0,
                 thetaMax=pi,
                 phiMin=0.0,
                 phiMax=2.0 * pi,
                 nNodePerh=2.01,
                 offset=None,
                 m0ForMassMatching=None):

        assert nr > 0
        assert rmin >= 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

        if offset is None:
            self.offset = Vector3d(0, 0, 0)
        else:
            self.offset = Vector3d(offset[0], offset[1], offset[2])

        self.nr = nr
        self.rmin = rmin
        self.rmax = rmax
        self.thetaMin = thetaMin
        self.thetaMax = thetaMax
        self.phiMin = phiMin
        self.phiMax = phiMax
        self.nNodePerh = nNodePerh

        self.xmin = Vector3d(-2.0 * rmax, -2.0 * rmax, -2.0 * rmax)
        self.xmax = Vector3d(2.0 * rmax, 2.0 * rmax, 2.0 * rmax)

        # no reason to support a constant density method here, just use a regular lattice for that
        self.densityProfileMethod = densityProfileMethod

        # Determine how much total mass there is in the system.
        targetMass = self.integrateTotalMass(self.densityProfileMethod, rmin,
                                             rmax, thetaMin, thetaMax, phiMin,
                                             phiMax)

        #targetMass = self.integrateTotalMass(self.densityProfileMethod,
        #                                         rmax)

        targetN = 4.0 / 3.0 * pi * (nr**3)
        self.m0 = targetMass / targetN
        self.vol = 4.0 / 3.0 * pi * (rmax**3)
        # what this means is this currently only supports creating a full sphere and then
        # cutting out the middle to rmin if rmin > 0

        if m0ForMassMatching is None:
            self.rho0 = targetMass / self.vol
        else:
            self.m0 = m0ForMassMatching
            self.rho0 = targetN * self.m0 / self.vol

        print "Found total mass = {0:3.3e} with rho0 = {1:3.3e}".format(
            targetMass, self.rho0)

        # compute kappa first
        # k = 3/(self.rho0*rmax**3) * targetMass/(4.0*pi)
        # print "Found kappa={0:3.3f}. Was that what you expected?".format(k)

        nlat = nr

        # create the unstretched lattice
        self.xl, self.yl, self.zl, self.ml, self.Hl = \
            self.latticeDistribution(nlat,
                                     self.rho0,
                                     self.m0,
                                     self.xmin,    # (xmin, ymin, zmin)
                                     self.xmax,    # (xmax, ymax, zmax)
                                     self.rmax,
                                     self.nNodePerh)

        self.rl = []
        for i in xrange(len(self.xl)):
            self.rl.append(sqrt(self.xl[i]**2 + self.yl[i]**2 + self.zl[i]**2))

        print "Sorting unstretched lattice... %d elements" % len(self.rl)

        multiSort(self.rl, self.xl, self.yl, self.zl)

        self.x = []
        self.y = []
        self.z = []
        self.m = []
        self.H = []

        nx = 2 * nlat + 1
        eta = (self.xmax[0] - self.xmin[0]) / nx

        print "Stretching lattice..."

        dr = eta * 0.01  # this will essentially be the error in the new dumb way
        r0p = 0
        rp = 0
        rn = 0
        npp = len(self.rl) / procs
        rankmin = (npp * rank) if (rank > 0) else (1)
        rankmax = (npp * (rank + 1)) if (rank < procs - 1) else (len(self.rl))
        for i in xrange(rankmin, rankmax):
            #print "%d / %d" % (i,len(self.rl))
            r0 = self.rl[i]
            if (abs(r0 - r0p) / r0 > 1e-10):
                sol = r0**3 * self.rho0 / 3.0
                iter = int(10 * rmax // dr)
                fn = 0
                for j in xrange(iter + 1):
                    rj = dr * j
                    rjj = dr * (j + 1)
                    fj = rj**2 * densityProfileMethod(rj)
                    fjj = rjj**2 * densityProfileMethod(rjj)
                    fn = fn + 0.5 * (fj + fjj) * dr
                    if (fn >= sol):
                        rn = rj
                        break
            r0p = r0
            if (rn <= rmax and rn > rmin):
                self.x.append(self.xl[i] * rn / r0)
                self.y.append(self.yl[i] * rn / r0)
                self.z.append(self.zl[i] * rn / r0)
                self.m.append(self.ml[i])
                self.H.append(self.Hl[i])

        seededMass = sum(self.m)
        seededMass = mpi.allreduce(seededMass, mpi.SUM)

        mAdj = targetMass / seededMass
        for i in xrange(len(self.m)):
            self.m[i] = self.m[i] * mAdj
        '''
        rp  = 0
        r0p = 0
        rn  = 0
        for i in xrange(1,len(self.rl)+1):
            if (self.rl[i] <= rmax):
                r0 = self.rl[i]
                if (abs(r0-r0p)/r0>1e-10):
                    eta = r0-r0p
                    print "Found eta={0:3.3e} @ r0,rp = {1:3.3e},{2:3.3e}".format(eta,r0,rp)
                    stretch = self.nrFunc(k,self.rho0,r0,eta,rp,self.densityProfileMethod,eta/100.0)
                    # want to do a check here to determine the range based on slope of function
                    lrmax = rmax
                    if self.dfunc(r0,eta,rp,eta/100.0,self.densityProfileMethod) > 0:
                        lrmax = r0
                    rn = newtonRaphsonFindRoot(stretch,0,lrmax,1.0e-15, 1.0e-15)
                rp  = rn
                r0p = r0
        
        
        for ix in xrange(nr):
            idx = (2*nr+1)*nr*(2*nr+2)
            i   = ix + nr + 1 + idx
            mi  = i - 2*ix
            j   = idx + (2*nr+1)*ix
            mj  = idx - (2*nr+1)*ix
            k   = idx + ix*(2*nr+1)**2
            mk  = idx - ix*(2*nr+1)**2
            print i
            r0 = sqrt(self.x[i]*self.x[i] + self.y[i]*self.y[i] + self.z[i]*self.z[i])
            rn = r0
            dr = eta/10.0
            
            myFunc = myClass()
            #rn = self.rootFind(rn,k,self.rho0,r0,eta,rp,dr,r0,self.densityProfileMethod,ns)
            #self.x[i] = self.x[i] * rn/r0
            #self.y[i] = self.y[i] * rn/r0
            #self.z[i] = self.z[i] * rn/r0
            #rp = rn
        
        '''

        # Initialize the base class.  If "serialInitialization" is True, this
        # is where the points are broken up between processors as well.
        serialInitialization = False
        NodeGeneratorBase.__init__(self, serialInitialization, self.x, self.y,
                                   self.z, self.m, self.H)

        return