def getEpsilonDist(group='gal', nBins=50, epsCut=2., center='pot'): """Returns a histogram of dimension 2 x nbins of stellar epsilons (jz/jcirc) and mass-fraction. epsCut defines the histogram bound in both directions. Center can be either 'pot' or 'com'""" numRotBins = 400 #number of points at which we linearly interpolate radiusVCM = 0.25 #fraction of group radius to use when calculating COM velocity radiusAngMom = 0.25 #fraction of group radius to use when calculating stellar angular momentum a = charm.getTime() if ((group in charm.getGroups()==False)) & (group !='gal'): print "Group does not exist, please try again." return if (group == 'gal'): rgal = quesoConfig.rgalFraction*virialgroup.getVirialGroup() center=findcenter.findCenter(group2='virialGroup', method=center) charm.createGroupAttributeSphere('gal', 'All', 'position', center[0], center[1], center[2], rgal) else: center=findcenter.findCenter(group2=group, method=center) # Find maximum radius charm.createGroup_Family('tmp',group,'star') maxRad = getgroupradius.getGroupRadius('tmp', center) massDist = [0]*(numRotBins+1) rad = [0]*(numRotBins+1) radialStep = maxRad/numRotBins #populate mass bins for i in range(numRotBins+1): charm.createGroupAttributeSphere('tmp', 'All', 'position', center[0], center[1], center[2], radialStep*i) massDist[i] = charm.getAttributeSum('tmp','star','mass') massDist[i] += charm.getAttributeSum('tmp','dark','mass') massDist[i] += charm.getAttributeSum('tmp','gas' ,'mass') #Note: I tried shells instead of spheres and it made no real difference. rad[i] = radialStep*i vCM = getVelCMStars(center2=center, radius=radiusVCM*maxRad) #COM velocity angMomVec = getNormalStarAngMom(center2=center, radius=radiusAngMom*maxRad, comVel=vCM) #Ang Mom Velocity #vCM = getVelCMStars(center2=center, radius=10/(a*quesoConfig.kpcunit)) #COM velocity #angMomVec = getNormalStarAngMom(center2=center, radius=6/(a*quesoConfig.kpcunit), comVel=vCM) #Ang Mom Velocity param = (center, vCM, angMomVec, maxRad, numRotBins,massDist, nBins,epsCut) charm.createGroupAttributeSphere('tmp', 'All', 'position', center[0], center[1], center[2], maxRad) charm.createGroup_Family('tmp',group,'star') #calc total stellar mass for mass weighted average reduceResult = charm.reduceParticle('tmp', mapEpsilon, reduceEpsilon, param) sMass = charm.getAttributeSum('tmp','star', 'mass') epsilonDist = [0]*nBins eps = [0]*nBins for i in range(nBins): eps[i] = -epsCut+ 2*epsCut/nBins*(i) for i in range(len(reduceResult)): try: bin = reduceResult[i][0] epsilonDist[bin] = reduceResult[i][1]/sMass #return the mass fraction except:{} return (eps, epsilonDist)
def calcGalacticCoordinates(angMomGroup=None, center ='pot'): '''Assigns particles a position in the galactic coordinate system. galVelocity = (v+Hr). angMomGroup''' #=========================================================================== # --Overview-- # 1.Form transformation matrix # 2.Translate the coordinates to the center of the galaxy (or COM velocity) # 3.Rotate the coordinate system to be aligned with the angular momentum vector # 4.Write information to vector attributes #=========================================================================== if ((angMomGroup in charm.getGroups())==False) & (angMomGroup!=None): print "Group does not exist, please try again." return ############################## # Actual Routine ############################## if (angMomGroup==None): angMomGroup = 'angMomGroup' cnt = findcenter.findCenter(method=center) virialRadius = virialgroup.getVirialGroup() charm.createGroupAttributeSphere('angMomGroup', 'All', 'position', cnt[0], cnt[1], cnt[2], virialRadius*quesoConfig.rgalFraction) charm.createGroup_Family('angMomGroup', 'angMomGroup', 'gas') charm.createGroup_AttributeRange('angMomGroup', 'angMomGroup', 'temperature', 0, quesoConfig.coldGasTemp) else: cnt = findcenter.findCenter(group2=angMomGroup,method=center) angmom.getAngMomVector(group=angMomGroup,center=center) # Transformation Matrix galZ = vectormath.normalizeVector(angmom.getAngMomVector(group=angMomGroup,center=center)) galX = vectormath.normalizeVector(vectormath.crossVectors((0,1,0),galZ)) galY = vectormath.normalizeVector(vectormath.crossVectors(galZ,galX)) transMatrix = (galX, galY, galZ) fHubble = quesoConfig.fHubble0*math.sqrt(quesoConfig.omega0/charm.getTime()**3+(1-quesoConfig.omega0)) # Galactic Position charm.createVectorAttribute('star','galPosition') charm.createVectorAttribute('gas', 'galPosition') charm.createVectorAttribute('dark','galPosition') param = (cnt, transMatrix) charm.runLocalParticleCodeGroup('All', calcGalPosition, param) # Galactic velocity vCM=angmom.getVelCM(angMomGroup) param = (cnt, transMatrix,vCM, fHubble) charm.createVectorAttribute('star','galVelocity') charm.createVectorAttribute('gas', 'galVelocity') charm.createVectorAttribute('dark','galVelocity') charm.runLocalParticleCodeGroup('All', calcGalVelocity, param) return
def getHalfMassRadius(group, center='pot') : """Returns the current stellar half mass radius.""" #get the current galactic stellar mass rgal = 0.1*virialgroup.getVirialGroup() center = findcenter.findCenter(group2=group,method=center) halfMass = getFamilyAttributeSum(center,rgal,'star','mass')/2.0 if (halfMass == 0 ): print "Halfmass is zero inside rgal. Are there stars inside rgal yet?." return (0,0) #Bisection Method to locate half mass epsilon = .01 count = 0 maxIterations = 50 a = charm.getTime() leftr = .1/(a*quesoConfig.kpcunit) rightr = 50/(a*quesoConfig.kpcunit) midpoint = (leftr + rightr)/2.0 leftMass = getFamilyAttributeSum(center,leftr ,'star','mass')-halfMass #Initialize values rightMass = getFamilyAttributeSum(center,rightr ,'star','mass')-halfMass #offset to find root midMass = getFamilyAttributeSum(center,midpoint,'star','mass')-halfMass #offset so we can find root #Bisection to find halfmass radius using initialMass and mass #Run until values converge within epsilon or reach max count while (count<maxIterations) and (math.fabs((leftMass-rightMass)/halfMass) > epsilon*2.0): midpoint = (leftr + rightr)/2.0 #if (math.fabs(leftMass-rightMass)/halfMass < 4*epsilon):break leftMass = getFamilyAttributeSum(center,leftr ,'star','mass')-halfMass #Initialize values rightMass= getFamilyAttributeSum(center,rightr ,'star','mass')-halfMass #offset to find root midMass = getFamilyAttributeSum(center,midpoint,'star','mass')-halfMass #offset so we can find root #print str((leftMass,midMass,rightMass)) + " " + str(math.fabs(leftMass-rightMass)/halfMass) +str((leftr,midpoint,rightr)) if (leftMass*midMass<0) : rightr = midpoint elif (rightMass*midMass<0): leftr = midpoint elif (midMass==0) : break elif (leftMass*midMass>0) and (rightMass*midMass>0): print "\nStellar half mass radius will not converge. Try larger bounds." return count += 1 #Don't get stuck in a loop if (count==maxIterations): print "\nDid not converge in " + str(maxIterations) + " iterations. Try smaller bounds or raise epsilon in source." return resultVec=midpoint #already in units of kpc taking into account the expansion factor #print resultVec[i] return resultVec