def test_amuse_PowerSphericalPotentialwCutoffPotential(): pp= potential.PowerSphericalPotentialwCutoff(normalize=1.,alpha=1.,rc=0.4) tmax= 2. vo,ro= 180., 9. o= Orbit([1.,0.03,1.03,0.2,0.1,0.4],ro=ro,vo=vo) run_orbitIntegration_comparison(o,pp,tmax,vo,ro) return None
def accMWpot(x,y,z,alpha=1.8, rc=1.9, a=3., b=0.28): x = x/kpctocm y = y/kpctocm z = z/kpctocm r = np.sqrt( x**2 + y**2) bp= gp.PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05) mp= gp.MiyamotoNagaiPotential(a=a/8.,b=b/8.,normalize=.6) nfw= gp.NFWPotential(a=16/8.,normalize=.35) #print(help(MWPotential2014)) #pot = [bp,mp,nfw] pot = MWPotential2014 az = evaluatezforces(pot,r*u.kpc , z*u.kpc)*bovy_conversion.force_in_kmsMyr(Vlsr/1e5,8.122) ar = evaluateRforces(pot,r*u.kpc , z*u.kpc)*bovy_conversion.force_in_kmsMyr(Vlsr/1e5,8.122) ar = ar*1.e5/(1.e6*3.15e7) az = -az*1.e5/(1.e6*3.15e7) ax = -ar*x/r ay = -ar*y/r return ax,ay,az
def setup_potential(params,c,fitc,dblexp,ro,vo,fitvoro=False,b=1.,pa=0., addgas=False): pot= [potential.PowerSphericalPotentialwCutoff(normalize=1.-params[0]-params[1], alpha=1.8,rc=1.9/ro)] if dblexp: if addgas: # add 13 Msun/pc^2 gp= potential.DoubleExponentialDiskPotential(\ amp=0.03333*u.Msun/u.pc**3\ *numpy.exp(ro/2./numpy.exp(params[2])/_REFR0), hz=150.*u.pc, hr=2.*numpy.exp(params[2])*_REFR0/ro, ro=ro,vo=vo) gp.turn_physical_off() gprf= gp.Rforce(1.,0.) dpf= params[0]+gprf if dpf < 0.: dpf= 0. pot.append(\ potential.DoubleExponentialDiskPotential(\ normalize=dpf,hr=numpy.exp(params[2])*_REFR0/ro, hz=numpy.exp(params[3])*_REFR0/ro)) else: pot.append(\ potential.DoubleExponentialDiskPotential(\ normalize=params[0],hr=numpy.exp(params[2])*_REFR0/ro, hz=numpy.exp(params[3])*_REFR0/ro)) else: pot.append(\ potential.MiyamotoNagaiPotential(normalize=params[0], a=numpy.exp(params[2])*_REFR0/ro, b=numpy.exp(params[3])*_REFR0/ro)) if fitc: pot.append(potential.TriaxialNFWPotential(\ normalize=params[1],a=numpy.exp(params[4])*_REFR0/ro, c=params[7+2*fitvoro],b=b,pa=pa)) else: pot.append(potential.TriaxialNFWPotential(\ normalize=params[1],a=numpy.exp(params[4])*_REFR0/ro, c=c,b=b,pa=pa)) if addgas: pot.append(gp) # make sure it's the last return pot
def setup_potential( params: Sequence, c: float, fitc: bool, dblexp: bool, ro: float = REFR0, vo: float = REFV0, fitvoro: bool = False, b: float = 1.0, pa: float = 0.0, addgas: bool = False, ) -> PotentialType: """Set up potential. PowerSphericalPotentialwCutoff MiyamotoNagaiPotential or DoubleExponentialDiskPotential TriaxialNFWPotential Parameters ---------- params c fitc dblexp DoubleExponentialDiskPotential instead if MiyamotoNagaiPotential ro vo fitvoro: bool, optional default False b: float, optional default 1.0 pa: float, optional Position Angle default 0.0 addgas: bool, optional default False """ pot: potential.Potential = [ potential.PowerSphericalPotentialwCutoff( normalize=1.0 - params[0] - params[1], alpha=1.8, rc=1.9 / ro ) ] if dblexp: if addgas: # add 13 Msun/pc^2 gp = potential.DoubleExponentialDiskPotential( amp=0.03333 * u.Msun / u.pc ** 3 * np.exp(ro / 2.0 / np.exp(params[2]) / REFR0), hz=150.0 * u.pc, hr=2.0 * np.exp(params[2]) * REFR0 / ro, ro=ro, vo=vo, ) gp.turn_physical_off() gprf = gp.Rforce(1.0, 0.0) dpf = params[0] + gprf if dpf < 0.0: dpf = 0.0 pot.append( potential.DoubleExponentialDiskPotential( normalize=dpf, hr=np.exp(params[2]) * REFR0 / ro, hz=np.exp(params[3]) * REFR0 / ro, ) ) else: pot.append( potential.DoubleExponentialDiskPotential( normalize=params[0], hr=np.exp(params[2]) * REFR0 / ro, hz=np.exp(params[3]) * REFR0 / ro, ) ) else: pot.append( potential.MiyamotoNagaiPotential( normalize=params[0], a=np.exp(params[2]) * REFR0 / ro, b=np.exp(params[3]) * REFR0 / ro, ) ) if fitc: pot.append( potential.TriaxialNFWPotential( normalize=params[1], a=np.exp(params[4]) * REFR0 / ro, c=params[7 + 2 * fitvoro], b=b, pa=pa, ) ) else: pot.append( potential.TriaxialNFWPotential( normalize=params[1], a=np.exp(params[4]) * REFR0 / ro, c=c, b=b, pa=pa, ) ) if addgas: pot.append(gp) # make sure it's the last return pot
def test_dynamfric_c(): import copy from galpy.orbit import Orbit from galpy.potential.Potential import _check_c from galpy.potential.mwpotentials import McMillan17 #Basic parameters for the test times = numpy.linspace(0., -100., 1001) #~3 Gyr at the Solar circle integrator = 'dop853_c' py_integrator = 'dop853' #Define all of the potentials (by hand, because need reasonable setup) MWPotential3021 = copy.deepcopy(potential.MWPotential2014) MWPotential3021[2] *= 1.5 # Increase mass by 50% pots= [potential.LogarithmicHaloPotential(normalize=1), potential.LogarithmicHaloPotential(normalize=1.3, q=0.9,b=0.7), #nonaxi potential.NFWPotential(normalize=1.,a=1.5), potential.MiyamotoNagaiPotential(normalize=.02,a=10.,b=10.), potential.MiyamotoNagaiPotential(normalize=.6,a=0.,b=3.), # special case potential.PowerSphericalPotential(alpha=2.3,normalize=2.), potential.DehnenSphericalPotential(normalize=4.,alpha=1.2), potential.DehnenCoreSphericalPotential(normalize=4.), potential.HernquistPotential(normalize=1.,a=3.5), potential.JaffePotential(normalize=1.,a=20.5), potential.DoubleExponentialDiskPotential(normalize=0.2, hr=3.,hz=0.6), potential.FlattenedPowerPotential(normalize=3.), potential.FlattenedPowerPotential(normalize=3.,alpha=0), #special case potential.IsochronePotential(normalize=2.), potential.PowerSphericalPotentialwCutoff(normalize=0.3,rc=10.), potential.PlummerPotential(normalize=.6,b=3.), potential.PseudoIsothermalPotential(normalize=.1,a=3.), potential.BurkertPotential(normalize=.2,a=2.5), potential.TriaxialHernquistPotential(normalize=1.,a=3.5, b=0.8,c=0.9), potential.TriaxialNFWPotential(normalize=1.,a=1.5,b=0.8,c=0.9), potential.TriaxialJaffePotential(normalize=1.,a=20.5,b=0.8,c=1.4), potential.PerfectEllipsoidPotential(normalize=.3,a=3.,b=0.7,c=1.5), potential.PerfectEllipsoidPotential(normalize=.3,a=3.,b=0.7,c=1.5, pa=3.,zvec=[0.,1.,0.]), #rotated potential.HomogeneousSpherePotential(normalize=0.02,R=82./8), # make sure to go to dens = 0 part, potential.interpSphericalPotential(\ rforce=potential.HomogeneousSpherePotential(normalize=0.02, R=82./8.), rgrid=numpy.linspace(0.,82./8.,201)), potential.TriaxialGaussianPotential(normalize=.03,sigma=4.,b=0.8,c=1.5,pa=3.,zvec=[1.,0.,0.]), potential.SCFPotential(Acos=numpy.array([[[1.]]]), # same as Hernquist normalize=1.,a=3.5), potential.SCFPotential(Acos=numpy.array([[[1.,0.],[.3,0.]]]), # nonaxi Asin=numpy.array([[[0.,0.],[1e-1,0.]]]), normalize=1.,a=3.5), MWPotential3021, McMillan17 # SCF + DiskSCF ] #tolerances in log10 tol = {} tol['default'] = -7. # Following are a little more difficult tol['DoubleExponentialDiskPotential'] = -4.5 tol['TriaxialHernquistPotential'] = -6. tol['TriaxialNFWPotential'] = -6. tol['TriaxialJaffePotential'] = -6. tol['MWPotential3021'] = -6. tol['HomogeneousSpherePotential'] = -6. tol['interpSphericalPotential'] = -6. # == HomogeneousSpherePotential tol['McMillan17'] = -6. for p in pots: if not _check_c(p, dens=True): continue # dynamfric not in C! pname = type(p).__name__ if pname == 'list': if isinstance(p[0],potential.PowerSphericalPotentialwCutoff) \ and len(p) > 1 \ and isinstance(p[1],potential.MiyamotoNagaiPotential) \ and len(p) > 2 \ and isinstance(p[2],potential.NFWPotential): pname = 'MWPotential3021' # Must be! else: pname = 'McMillan17' #print(pname) if pname in list(tol.keys()): ttol = tol[pname] else: ttol = tol['default'] # Setup orbit, ~ LMC o = Orbit([ 5.13200034, 1.08033051, 0.23323391, -3.48068653, 0.94950884, -1.54626091 ]) # Setup dynamical friction object if pname == 'McMillan17': cdf= potential.ChandrasekharDynamicalFrictionForce(\ GMs=0.5553870441722593,rhm=5./8.,dens=p,maxr=500./8,nr=101) ttimes = numpy.linspace(0., -30., 1001) #~1 Gyr at the Solar circle else: cdf= potential.ChandrasekharDynamicalFrictionForce(\ GMs=0.5553870441722593,rhm=5./8.,dens=p,maxr=500./8,nr=201) ttimes = times # Integrate in C o.integrate(ttimes, p + cdf, method=integrator) # Integrate in Python op = o() op.integrate(ttimes, p + cdf, method=py_integrator) # Compare r (most important) assert numpy.amax(numpy.fabs(o.r(ttimes)-op.r(ttimes))) < 10**ttol, \ 'Dynamical friction in C does not agree with dynamical friction in Python for potential {}'.format(pname) return None