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_impulse_deltav_plummerstream(): from galpy.df import impulse_deltav_plummer, impulse_deltav_plummerstream from galpy.util import conversion V0, R0= 220., 8. GM= 10.**-2./conversion.mass_in_1010msol(V0,R0) rs= 0.625/R0 b= rs stream_phi= numpy.linspace(-numpy.pi/2.,numpy.pi/2.,201) stream_r= 10./R0 stream_v= 220./V0 x_gc= stream_r*stream_phi v_gc= numpy.tile([0.000001,stream_v,0.000001],(201,1)) w= numpy.array([0.,132.,176])/V0 wmag= numpy.sqrt(numpy.sum(w**2.)) tol= -5. # Plummer sphere kick kick= impulse_deltav_plummer(v_gc[101],x_gc[101],-b,w,GM,rs) # Kick from stream with length 0.01 r_s (should be ~Plummer sphere) dt= 0.01*rs*R0/wmag/V0*conversion.freq_in_kmskpc(V0,R0) stream_kick= impulse_deltav_plummerstream(\ v_gc[101],x_gc[101],-b,w,lambda t: GM/dt,rs,-dt/2.,dt/2.) assert numpy.all(numpy.fabs((kick-stream_kick)/kick) < 10.**tol), 'Short stream impulse kick calculation does not agree with Plummer calculation by %g' % (numpy.amax(numpy.fabs((kick-stream_kick)/kick))) # Same for a bunch of positions kick= impulse_deltav_plummer(v_gc,x_gc,-b,w,GM,rs) # Kick from stream with length 0.01 r_s (should be ~Plummer sphere) dt= 0.01*rs*R0/wmag/V0*conversion.freq_in_kmskpc(V0,R0) stream_kick=\ impulse_deltav_plummerstream(\ v_gc,x_gc,-b,w,lambda t: GM/dt,rs,-dt/2.,dt/2.) assert numpy.all((numpy.fabs((kick-stream_kick)/kick) < 10.**tol)*(numpy.fabs(kick) >= 10**-4.)\ +(numpy.fabs((kick-stream_kick)) < 10**tol)*(numpy.fabs(kick) < 10**-4.)), 'Short stream impulse kick calculation does not agree with Plummer calculation by rel: %g, abs: %g' % (numpy.amax(numpy.fabs((kick-stream_kick)/kick)[numpy.fabs(kick) >= 10**-4.]),numpy.amax(numpy.fabs((kick-stream_kick))[numpy.fabs(kick) < 10**-3.]))
def test_impulse_deltav_plummer_subhalo_perpendicular(): from galpy.df import impulse_deltav_plummer tol= -10. kick= impulse_deltav_plummer(numpy.array([[0.,numpy.pi,0.]]), numpy.array([0.]), 3., numpy.array([0.,numpy.pi/2.,0.]), 1.5,4.) # Should be B&T (8.152) assert numpy.fabs(kick[0,0]-2.*1.5*3./numpy.pi*2./25.) < 10.**tol, 'Perpendicular kick of subhalo perpendicular not as expected' assert numpy.fabs(kick[0,2]+2.*1.5*3./numpy.pi*2./25.) < 10.**tol, 'Perpendicular kick of subhalo perpendicular not as expected' # Same for along z kick= impulse_deltav_plummer(numpy.array([[0.,0.,numpy.pi]]), numpy.array([0.]), 3., numpy.array([0.,0.,numpy.pi/2.]), 1.5,4.) # Should be B&T (8.152) assert numpy.fabs(kick[0,0]-2.*1.5*3./numpy.pi*2./25.) < 10.**tol, 'Perpendicular kick of subhalo perpendicular not as expected' assert numpy.fabs(kick[0,1]-2.*1.5*3./numpy.pi*2./25.) < 10.**tol, 'Perpendicular kick of subhalo perpendicular not as expected' return None
def test_impulse_deltav_plummer_curved_subhalo_perpendicular(): from galpy.df import impulse_deltav_plummer, \ impulse_deltav_plummer_curvedstream 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.) curved_kick= impulse_deltav_plummer_curvedstream(\ numpy.array([[3.4,0.,0.]]), numpy.array([[4.,0.,0.]]), 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), 1.5,4.) # Should be equal assert numpy.all(numpy.fabs(kick-curved_kick) < 10.**tol), 'curved Plummer kick does not agree with straight kick for straight track' # 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.]), 1.5,4.) xpos= numpy.array([xpos,numpy.zeros(100),numpy.zeros(100)]).T curved_kick= impulse_deltav_plummer_curvedstream(\ v, xpos, 3., numpy.array([0.,numpy.pi/2.,0.]), numpy.array([0.,0.,0.]), numpy.array([3.4,0.,0.]), 1.5,4.) # Should be equal assert numpy.all(numpy.fabs(kick-curved_kick) < 10.**tol), 'curved Plummer kick does not agree with straight kick for straight track' return None
def test_impulse_deltav_plummerstream_tmaxerror(): from galpy.df import impulse_deltav_plummer, impulse_deltav_plummerstream from galpy.util import conversion V0, R0= 220., 8. GM= 10.**-2./conversion.mass_in_1010msol(V0,R0) rs= 0.625/R0 b= rs stream_phi= numpy.linspace(-numpy.pi/2.,numpy.pi/2.,201) stream_r= 10./R0 stream_v= 220./V0 x_gc= stream_r*stream_phi v_gc= numpy.tile([0.000001,stream_v,0.000001],(201,1)) w= numpy.array([0.,132.,176])/V0 wmag= numpy.sqrt(numpy.sum(w**2.)) tol= -5. # Same for infinite integration limits kick= impulse_deltav_plummer(v_gc[101],x_gc[101],-b,w,GM,rs) # Kick from stream with length 0.01 r_s (should be ~Plummer sphere) dt= 0.01*rs*R0/wmag/V0*conversion.freq_in_kmskpc(V0,R0) with pytest.raises(ValueError) as excinfo: stream_kick= impulse_deltav_plummerstream(\ v_gc[101],x_gc[101],-b,w,lambda t: GM/dt,rs) return None