def test_impulse_deltav_general(): from galpy.df import impulse_deltav_plummer, impulse_deltav_general from galpy.potential import PlummerPotential tol= -10. kick= impulse_deltav_plummer(numpy.array([[3.4,0.,0.]]), numpy.array([4.]), 3., numpy.array([0.,numpy.pi/2.,0.]), 1.5,4.) pp= PlummerPotential(amp=1.5,b=4.) general_kick=\ impulse_deltav_general(numpy.array([[3.4,0.,0.]]), numpy.array([4.]), 3., numpy.array([0.,numpy.pi/2.,0.]), pp) assert numpy.all(numpy.fabs(kick-general_kick) < 10.**tol), 'general kick calculation does not agree with Plummer calculation for a Plummer potential' # Same for a bunch of positions v= numpy.zeros((100,3)) v[:,0]= 3.4 xpos= numpy.random.normal(size=100) kick= impulse_deltav_plummer(v, xpos, 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.pi,numpy.exp(1.)) pp= PlummerPotential(amp=numpy.pi,b=numpy.exp(1.)) general_kick=\ impulse_deltav_general(v, xpos, 3., numpy.array([0.,numpy.pi/2.,0.]), pp) assert numpy.all(numpy.fabs(kick-general_kick) < 10.**tol), 'general kick calculation does not agree with Plummer calculation for a Plummer potential' return None
def test_actionAngleTorus_basic(): from galpy.actionAngle import actionAngleTorus from galpy.potential import MWPotential, rl, vcirc, \ FlattenedPowerPotential, PlummerPotential tol= -4. jr= 10.**-10. jz= 10.**-10. aAT= actionAngleTorus(pot=MWPotential) # at R=1, Lz=1 jphi= 1. angler= numpy.linspace(0.,2.*numpy.pi,101) anglephi= numpy.linspace(0.,2.*numpy.pi,101)+1. anglez= numpy.linspace(0.,2.*numpy.pi,101)+2. RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T assert numpy.all(numpy.fabs(RvR[0]-rl(MWPotential,jphi)) < 10.**tol), \ 'circular orbit does not have constant radius for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[1]) < 10.**tol), \ 'circular orbit does not have zero radial velocity for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[2]-vcirc(MWPotential,rl(MWPotential,jphi))) < 10.**tol), \ 'circular orbit does not have constant vT=vc for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[3]) < 10.**tol), \ 'circular orbit does not have zero vertical height for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[4]) < 10.**tol), \ 'circular orbit does not have zero vertical velocity for actionAngleTorus' # at Lz=1.5, using Plummer tol= -3.25 pp= PlummerPotential(normalize=1.) aAT= actionAngleTorus(pot=pp) jphi= 1.5 RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T assert numpy.all(numpy.fabs(RvR[0]-rl(pp,jphi)) < 10.**tol), \ 'circular orbit does not have constant radius for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[1]) < 10.**tol), \ 'circular orbit does not have zero radial velocity for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[2]-vcirc(pp,rl(pp,jphi))) < 10.**tol), \ 'circular orbit does not have constant vT=vc for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[3]) < 10.**tol), \ 'circular orbit does not have zero vertical height for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[4]) < 10.**tol), \ 'circular orbit does not have zero vertical velocity for actionAngleTorus' # at Lz=0.5, using FlattenedPowerPotential tol= -4. fp= FlattenedPowerPotential(normalize=1.) aAT= actionAngleTorus(pot=fp) jphi= 0.5 RvR= aAT(jr,jphi,jz,angler,anglephi,anglez).T assert numpy.all(numpy.fabs(RvR[0]-rl(fp,jphi)) < 10.**tol), \ 'circular orbit does not have constant radius for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[1]) < 10.**tol), \ 'circular orbit does not have zero radial velocity for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[2]-vcirc(fp,rl(fp,jphi))) < 10.**tol), \ 'circular orbit does not have constant vT=vc for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[3]) < 10.**tol), \ 'circular orbit does not have zero vertical height for actionAngleTorus' assert numpy.all(numpy.fabs(RvR[4]) < 10.**tol), \ 'circular orbit does not have zero vertical velocity for actionAngleTorus' return None
def test_impulse_deltav_general_orbit_zeroforce(): from galpy.df import impulse_deltav_plummer_curvedstream, \ impulse_deltav_general_orbitintegration from galpy.potential import PlummerPotential tol= -6. rcurv=10. vp=220. x0 = numpy.array([rcurv,0.,0.]) v0 = numpy.array([0.,vp,0.]) w = numpy.array([1.,numpy.pi/2.,0.]) plummer_kick= impulse_deltav_plummer_curvedstream(\ v0,x0,3.,w,x0,v0,1.5,4.) pp= PlummerPotential(amp=1.5,b=4.) vang=vp/rcurv angrange=numpy.pi maxt=5.*angrange/vang galpot = constantPotential() orbit_kick= impulse_deltav_general_orbitintegration(\ v0,x0,3.,w,x0,v0,pp,maxt,galpot) assert numpy.all(numpy.fabs(orbit_kick-plummer_kick) < 10.**tol), \ 'general kick with acceleration calculation does not agree with Plummer calculation for a Plummer potential, for straight' # Same for a bunch of positions tol= -5. pp= PlummerPotential(amp=numpy.pi,b=numpy.exp(1.)) theta = numpy.linspace(-numpy.pi/4.,numpy.pi/4.,100) xc,yc = rcurv*numpy.cos(theta),rcurv*numpy.sin(theta) Xc = numpy.zeros((100,3)) Xc[:,0]=xc Xc[:,1]=yc vx,vy = -vp*numpy.sin(theta),vp*numpy.cos(theta) V = numpy.zeros((100,3)) V[:,0]=vx V[:,1]=vy plummer_kick= impulse_deltav_plummer_curvedstream(\ V,Xc,3.,w,x0,v0,numpy.pi,numpy.exp(1.)) orbit_kick= impulse_deltav_general_orbitintegration(\ V,Xc,3.,w,x0,v0,pp, maxt, galpot) assert numpy.all(numpy.fabs(orbit_kick-plummer_kick) < 10.**tol), \ 'general kick calculation does not agree with Plummer calculation for a Plummer potential, for curved stream' return None
def test_impulse_deltav_general_fullintegration_fastencounter(): from galpy.df import impulse_deltav_general_orbitintegration, \ impulse_deltav_general_fullplummerintegration from galpy.potential import PlummerPotential, LogarithmicHaloPotential tol= -2. GM=1.5 rs=4. x0 = numpy.array([1.5,0.,0.]) v0 = numpy.array([0.,1.,0.]) #circular orbit w = numpy.array([0.,0.,100.]) # very fast compared to v=1 lp= LogarithmicHaloPotential(normalize=1.) pp= PlummerPotential(amp=GM,b=rs) orbit_kick= impulse_deltav_general_orbitintegration(\ v0,x0,3.,w,x0,v0,pp,5.*numpy.pi,lp) full_kick= impulse_deltav_general_fullplummerintegration(\ v0,x0,3.,w,x0,v0,lp,GM,rs,tmaxfac=10.,N=1000) # Kick should be in the X direction assert numpy.fabs((orbit_kick-full_kick)/full_kick)[0,0] < 10.**tol, \ 'Acceleration kick does not agree with full-orbit-integration kick for fast encounter' assert numpy.all(numpy.fabs((orbit_kick-full_kick))[0,1:] < 10.**tol), \ 'Acceleration kick does not agree with full-orbit-integration kick for fast encounter' return None
pot_disk = MiyamotoNagaiPotential(amp=G * m_disk, a=6.5 * u.kpc, b=0.26 * u.kpc, ro=8., vo=220.) pot_halo = LogarithmicHaloPotential(amp=2 * v_halo**2, q=1., core=12.0 * u.kpc, ro=8., vo=220.) pot = [pot_bulge, pot_disk, pot_halo] m_plummer = 1e9 * u.solMass r_scale_plummer = 3 * u.kpc plummer_pot = PlummerPotential(amp=G * m_plummer, b=r_scale_plummer, ro=10 * u.kpc, vo=20 * u.km / u.s) struct_to_sol = 222288.47 #this many solar masses make up one structural nass unit (the output of mwah) class Data(): def __init__(self, id_val=[], x=[], y=[], z=[], l=[], b=[], r=[], vx=[],
def test_sanders15_leading_setup(): #Imports from galpy.df import streamdf, streamgapdf from galpy.orbit import Orbit from galpy.potential import LogarithmicHaloPotential, PlummerPotential from galpy.actionAngle import actionAngleIsochroneApprox from galpy.util import conversion #for unit conversions lp = LogarithmicHaloPotential(normalize=1., q=0.9) aAI = actionAngleIsochroneApprox(pot=lp, b=0.8) prog_unp_peri = Orbit([ 2.6556151742081835, 0.2183747276300308, 0.67876510797240575, -2.0143395648974671, -0.3273737682604374, 0.24218273922966019 ]) global sdfl_sanders15 V0, R0 = 220., 8. sigv = 0.365 * (10. / 2.)**(1. / 3.) # km/s # Use a Potential object for the impact pp= PlummerPotential(amp=10.**-2.\ /conversion.mass_in_1010msol(V0,R0), b=0.625/R0) import warnings from galpy.util import galpyWarning with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", galpyWarning) sdfl_sanders15= streamgapdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackChunksImpact=29, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0, impactb=0., subhalovel=numpy.array([49.447319, 116.179436, 155.104156])/V0, timpact=0.88/conversion.time_in_Gyr(V0,R0), impact_angle=2.09, subhalopot=pp, nKickPoints=290, deltaAngleTrackImpact=4.5, multi=True) # test multi # Should raise warning bc of deltaAngleTrackImpact, might raise others raisedWarning = False for wa in w: raisedWarning = ( str(wa.message) == "WARNING: deltaAngleTrackImpact angle range large compared to plausible value" ) if raisedWarning: break assert raisedWarning, 'deltaAngleTrackImpact warning not raised when it should have been' assert not sdfl_sanders15 is None, 'sanders15 trailing streamdf setup did not work' # Also setup the unperturbed model global sdfl_sanders15_unp sdfl_sanders15_unp= streamdf(sigv/V0,progenitor=prog_unp_peri, pot=lp,aA=aAI, leading=True,nTrackChunks=26, nTrackIterations=1, sigMeanOffset=4.5, tdisrupt=10.88\ /conversion.time_in_Gyr(V0,R0), Vnorm=V0,Rnorm=R0) assert not sdfl_sanders15_unp is None, \ 'sanders15 unperturbed streamdf setup did not work' return None