def test_bAnnulusn(): """ Test of numerical annulus outer moments against point gravity. Tests ----- bqlmn.annulus : function """ mout = gshp.wedge(1, 1, 2, 1, np.pi / 2, 60, 60) mmout2 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, .5])) Qlmb2 = bqlmn.annulus(5, 2 / (np.pi * (2**2 - 1)), 0, 1, 1, 2, np.pi / 2) assert (abs(Qlmb2 - mmout2) < .002).all() mmout3 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, -.5])) Qlmb3 = bqlmn.annulus(5, 2 / (np.pi * (2**2 - 1)), -1, 0, 1, 2, np.pi / 2) assert (abs(Qlmb3 - mmout3) < .002).all() mout3 = gshp.wedge(1, 1, 2, 1, np.pi / 3, 60, 60) mmout3 = pgm.Qmomentsb(5, glb.translate_point_array(mout3, [0, 0, .5])) Qlmb3 = bqlmn.annulus(5, 3 / (np.pi * (2**2 - 1)), 0, 1, 1, 2, np.pi / 3) assert (abs(Qlmb3 - mmout3) < .002).all() mout4 = gshp.wedge(1, 1, 2, 1, np.pi / 4, 60, 60) mmout4 = pgm.Qmomentsb(5, glb.translate_point_array(mout4, [0, 0, .5])) Qlmb4 = bqlmn.annulus(5, 4 / (np.pi * (2**2 - 1)), 0, 1, 1, 2, np.pi / 4) assert (abs(Qlmb4 - mmout4) < .002).all() mout5 = gshp.wedge(1, 1, 2, 1, np.pi / 5, 60, 60) mmout5 = pgm.Qmomentsb(5, glb.translate_point_array(mout5, [0, 0, .5])) Qlmb5 = bqlmn.annulus(5, 5 / (np.pi * (2**2 - 1)), 0, 1, 1, 2, np.pi / 5) assert (abs(Qlmb5 - mmout5) < .002).all()
def test_bTrapezoidn(): """ Test of numerical trapezoid outer moments against point gravity. Tests ----- bqlmn.trapezoid : function """ iR, oR = 1, 2 beta = np.pi / 3 t = 1 vol = (oR - iR) * np.cos(beta) * (oR + iR) * np.sin(beta) * t mout = gshp.trapezoid(1, iR, oR, t, beta, 60, 60) mmout2 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, .5])) Qlmb2 = bqlmn.trapezoid(5, 1 / vol, 0, t, iR, oR, beta) assert (abs(Qlmb2 - mmout2) < .01).all() mmout3 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, -.5])) Qlmb3 = bqlmn.trapezoid(5, 1 / vol, -t, 0, iR, oR, beta) assert (abs(Qlmb3 - mmout3) < .01).all() beta = np.pi / 4 vol = (oR - iR) * np.cos(beta) * (oR + iR) * np.sin(beta) * t mout4 = gshp.trapezoid(1, iR, oR, t, beta, 60, 60) mmout4 = pgm.Qmomentsb(5, glb.translate_point_array(mout4, [0, 0, .5])) Qlmb4 = bqlmn.trapezoid(5, 1 / vol, 0, t, iR, oR, beta) assert (abs(Qlmb4 - mmout4) < .01).all() beta = np.pi / 5 vol = (oR - iR) * np.cos(beta) * (oR + iR) * np.sin(beta) * t mout5 = gshp.trapezoid(1, iR, oR, t, beta, 60, 60) mmout5 = pgm.Qmomentsb(5, glb.translate_point_array(mout5, [0, 0, .5])) Qlmb5 = bqlmn.trapezoid(5, 1 / vol, 0, t, iR, oR, beta) assert (abs(Qlmb5 - mmout5) < .01).all()
def test_bOuter_conen(): """ Test of numerical outer cone outer moments against point gravity. Tests ----- bqlmn.outer_cone : function """ iR, oR = 1, 2 beta = np.pi / 3 H = 1 Hp = H * oR / (oR - iR) vol = beta * (Hp * oR**2 / 3 - H * iR**2 - (Hp - H) * iR**2 / 3) mout = gshp.outer_cone(1, iR, oR, H, beta, 60, 60) mmout2 = pgm.Qmomentsb(5, mout) Qlmb2 = bqlmn.outer_cone(5, 1 / vol, H, iR, oR, beta) assert (abs(Qlmb2 - mmout2) < .005).all() beta = np.pi / 4 vol = beta * (Hp * oR**2 / 3 - H * iR**2 - (Hp - H) * iR**2 / 3) mout4 = gshp.outer_cone(1, iR, oR, H, beta, 60, 60) mmout4 = pgm.Qmomentsb(5, mout4) Qlmb4 = bqlmn.outer_cone(5, 1 / vol, H, iR, oR, beta) assert (abs(Qlmb4 - mmout4) < .01).all() beta = np.pi / 5 vol = beta * (Hp * oR**2 / 3 - H * iR**2 - (Hp - H) * iR**2 / 3) mout5 = gshp.outer_cone(1, iR, oR, H, beta, 60, 60) mmout5 = pgm.Qmomentsb(5, mout5) Qlmb5 = bqlmn.outer_cone(5, 1 / vol, H, iR, oR, beta) assert (abs(Qlmb5 - mmout5) < .01).all()
def test_Q2Q(): """ Check that the outer to outer translate method matches PointGravity. """ R = 100 M = 1 m2 = np.array([[M, R, 0, 0], [M, -R, 0, 0]]) # Get outer moments of points at +/-R Qm2 = pgm.Qmomentsb(10, m2) # Get outer moments of translated points Qm2b = pgm.Qmomentsb(10, glb.translate_point_array(m2, [0.1, 0, 0])) # Find outer moments from inner qm0 and qm0b translated to +/-R Qlmp2 = trs.translate_Qlmb(Qm2, [0.1, 0, 0]) assert (abs(Qlmp2-Qm2b) < 10*np.finfo(float).eps).all()
def test_Q2Q_SS(): """ Check that the outer to outer translate method matches CS translation. """ R = 100 M = 1 m2 = np.array([[M, R, 0, 0], [M, -R, 0, 0]]) # Get outer moments of points at +/-R Qm2 = pgm.Qmomentsb(10, m2) # Get outer moments of translated points Qm2b = pgm.Qmomentsb(10, glb.translate_point_array(m2, [0, 0, 0.1])) # Find outer moments from inner qm0 and qm0b translated to +/-R ssms = trr.transl_newt_z_SS(10, .1) Qlmp2 = trr.apply_trans_mat(Qm2, ssms) assert (abs(Qlmp2-Qm2b) < 10*np.finfo(float).eps).all()
def test_quadrupole_torque(): """ Compare the point matrix calculation to an analytic formulation of a quadrupole torque. Tests ----- glb.point_matrix_gravity : function """ d = 1 R = rand.rand() * 100 + 1.1 m, M = 1, 1 N = 60 L = 10 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) m2 = np.array([[M, R, 0, 0], [M, -R, 0, 0]]) qlm = pgm.qmoments(L, m1) tau = np.zeros(N) ts = np.zeros([60, 3]) d2R2 = d**2 + R**2 tc = np.zeros([N, L + 1], dtype='complex') ts = np.zeros([N, L + 1], dtype='complex') for k in range(N): a = 2 * np.pi * k / N ca = np.cos(a) Q = glb.rotate_point_array(m2, a, [0, 0, 1]) Qlmb = pgm.Qmomentsb(L, Q) tau[k] = 2 * mplb.BIG_G * M * m * d * R * np.sin(a) tau[k] *= 1 / (d2R2 - 2 * d * R * ca)**(3 / 2) - 1 / ( d2R2 + 2 * d * R * ca)**(3 / 2) tlm, tc[k], ts[k] = mplb.torque_lm(L, qlm, Qlmb) # XXX should be np.sum(tc, 1)-tau, but existing sign error! assert (abs(np.sum(tc, 1) + tau) < 10 * np.finfo(float).eps).all()
def test_bAnnulus(): """ Test of explicit annulus outer moments against point gravity. Tests ----- bqlm.annulus : function """ mout = gshp.wedge(1, 1, 2, 1, np.pi / 2, 60, 60) mmout2 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, .5])) Qlmb2 = bqlm.annulus(5, 2 / (np.pi * (2**2 - 1)), 1, 1, 2, 0, np.pi / 2) assert (abs(Qlmb2 - mmout2) < .002).all() mmout3 = pgm.Qmomentsb(5, glb.translate_point_array(mout, [0, 0, -.5])) Qlmb3 = bqlm.annulus(5, 2 / (np.pi * (2**2 - 1)), -1, 1, 2, 0, np.pi / 2) assert (abs(Qlmb3 - mmout3) < .002).all() mout3 = gshp.wedge(1, 1, 2, 1, np.pi / 3, 60, 60) mmout3 = pgm.Qmomentsb(5, glb.translate_point_array(mout3, [0, 0, .5])) Qlmb3 = bqlm.annulus(5, 3 / (np.pi * (2**2 - 1)), 1, 1, 2, 0, np.pi / 3) assert (abs(Qlmb3 - mmout3) < .002).all() mout4 = gshp.wedge(1, 1, 2, 1, np.pi / 4, 60, 60) mmout4 = pgm.Qmomentsb(5, glb.translate_point_array(mout4, [0, 0, .5])) Qlmb4 = bqlm.annulus(5, 4 / (np.pi * (2**2 - 1)), 1, 1, 2, 0, np.pi / 4) assert (abs(Qlmb4 - mmout4) < .002).all() mout5 = gshp.wedge(1, 1, 2, 1, np.pi / 5, 60, 60) mmout5 = pgm.Qmomentsb(5, glb.translate_point_array(mout5, [0, 0, .5])) Qlmb5 = bqlm.annulus(5, 5 / (np.pi * (2**2 - 1)), 1, 1, 2, 0, np.pi / 5) assert (abs(Qlmb5 - mmout5) < .002).all() # Test that a L<5 works (we'll do 3) Qlmb3 = bqlm.annulus(3, 3 / (np.pi * (2**2 - 1)), 1, 1, 2, 0, np.pi / 3) mmout3 = pgm.Qmomentsb(3, glb.translate_point_array(mout3, [0, 0, .5])) assert (np.shape(Qlmb3) == (4, 7)) assert (abs(Qlmb3 - mmout3) < .002).all()
def test_force2(): """ Test gravitational force from point mass at two meters on point mass away from the origin. Tests ----- mplb.multipole_force : function """ m1b = np.array([[1, 0, 0, 1]]) m2 = np.array([[1, 0, 0, 2]]) q1b = pgm.qmoments(20, m1b) q2 = pgm.Qmomentsb(20, m2) # Check force for where m1 is placed force = mplb.multipole_force(20, q1b, q2, 0, 0, 0) assert (abs(force[2] - mplb.BIG_G) < 10 * np.finfo(float).eps) # Check force at if displace inner moments to origin force = mplb.multipole_force(20, q1b, q2, 0, 0, -1) assert (abs(force[2] - mplb.BIG_G / 4) < 10 * np.finfo(float).eps) m1b = np.array([[1, 1, 0, 0]]) m2 = np.array([[1, 2, 0, 0]]) q1b = pgm.qmoments(20, m1b) q2 = pgm.Qmomentsb(20, m2) # Check force for where m1 is placed force = mplb.multipole_force(20, q1b, q2, 0, 0, 0) assert (abs(force[0] - mplb.BIG_G) < 10 * np.finfo(float).eps) # Check force at if displace inner moments to origin force = mplb.multipole_force(20, q1b, q2, -1, 0, 0) assert (abs(force[0] - mplb.BIG_G / 4) < 10 * np.finfo(float).eps) m1b = np.array([[1, 0, 1, 0]]) m2 = np.array([[1, 0, 2, 0]]) q1b = pgm.qmoments(20, m1b) q2 = pgm.Qmomentsb(20, m2) # Check force for where m1 is placed force = mplb.multipole_force(20, q1b, q2, 0, 0, 0) assert (abs(force[1] - mplb.BIG_G) < 10 * np.finfo(float).eps) # Check force at if displace inner moments to origin force = mplb.multipole_force(20, q1b, q2, 0, -1, 0) assert (abs(force[1] - mplb.BIG_G / 4) < 10 * np.finfo(float).eps)
def test_force1(): """ Test gravitational force from point mass at a meter on a point mass at the origin. Tests ----- mplb.multipole_force : function """ m1 = np.array([[1, 0, 0, 0]]) m2 = np.array([[1, 1, 0, 0]]) q1 = pgm.qmoments(10, m1) q2 = pgm.Qmomentsb(10, m2) force = mplb.multipole_force(10, q1, q2, 0, 0, 0) assert (abs(force[0] - mplb.BIG_G) < 10 * np.finfo(float).eps) m2 = np.array([[1, 0, 1, 0]]) q2 = pgm.Qmomentsb(10, m2) force = mplb.multipole_force(10, q1, q2, 0, 0, 0) assert (abs(force[1] - mplb.BIG_G) < 10 * np.finfo(float).eps) m2 = np.array([[1, 0, 0, 1]]) q2 = pgm.Qmomentsb(10, m2) force = mplb.multipole_force(10, q1, q2, 0, 0, 0) assert (abs(force[2] - mplb.BIG_G) < 10 * np.finfo(float).eps)
def test_Q2Q_durso(): """ Check that the outer to outer translate method matches analytic. """ ar = 50 rp = 1 m = 1 m1 = np.array([[m, ar, 0, 0], [-m, -ar, 0, 0]]) # Find outer moments around origin Qm1 = pgm.Qmomentsb(10, m1) # Find outer moments translated by [1, 0, 0] Qlmp = trs.translate_Qlmb(Qm1, [rp, 0, 0]) # Analytic Q22 moment Q22 = (1/4)*np.sqrt(15/2/np.pi)*((ar+rp)**(-3) - (ar-rp)**(-3)) assert abs(Qlmp[2, 12] - Q22) < 10*np.finfo(float).eps
def test_hexapole_torque(): """ Compare the point matrix calculation to an analytic formulation of a hexapole torque. Tests ----- glb.point_matrix_gravity : function """ d = 1 z = rand.randn() * 10 R = rand.rand() * 100 + 1.1 m, M = 1, 1 N = 60 m0 = np.array([m, d, 0, 0]) m1 = np.copy(m0) m2 = np.array([M, R, 0, z]) m3 = np.copy(m2) zhat = [0, 0, 1] for k in range(1, 3): m1 = np.vstack( [m1, glb.rotate_point_array(m0, 2 * k * np.pi / 3, zhat)]) m3 = np.vstack( [m3, glb.rotate_point_array(m2, 2 * k * np.pi / 3, zhat)]) L = 10 qlm = pgm.qmoments(L, m1) tau = np.zeros(N) tc = np.zeros([N, L + 1], dtype='complex') ts = np.zeros([N, L + 1], dtype='complex') d2R2 = d**2 + R**2 + z**2 for k in range(N): a = 2 * np.pi * k / N Q = glb.rotate_point_array(m3, a, zhat) Qlmb = pgm.Qmomentsb(L, Q) fac = 3 * glb.BIG_G * M * m * d * R tau[k] = np.sin(a) / (d2R2 - 2 * d * R * np.cos(a))**(3 / 2) tau[k] += np.sin(a + 2 * np.pi / 3) / ( d2R2 - 2 * d * R * np.cos(a + 2 * np.pi / 3))**(3 / 2) tau[k] += np.sin(a + 4 * np.pi / 3) / ( d2R2 - 2 * d * R * np.cos(a + 4 * np.pi / 3))**(3 / 2) tau[k] *= fac tlm, tc[k], ts[k] = mplb.torque_lm(L, qlm, Qlmb) # XXX should be np.sum(tc, 1)-tau, but existing sign error! assert (abs(np.sum(tc, 1) + tau) < 10 * np.finfo(float).eps).all()
def test_q2Q_SR(): """ Check that the inner to outer translate method matches PointGravity. This translation method is worse for smaller translations. For R=10, the error approaches 1e7*epsilon. """ d = 1 R = 100 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) m2 = glb.translate_point_array(m1, [0, 0, R]) # Create inner moments of each points at +/-r qm0 = pgm.qmoments(10, np.array(m1)) # Get outer moments of points at +/-R Qm2 = pgm.Qmomentsb(10, m2) # Find outer moments from inner qm0 and qm0b translated to +/-R srms = trr.transl_newt_z_SR(10, R) Qlm = trr.apply_trans_mat(qm0, srms) assert (abs(Qlm-Qm2) < 11*np.finfo(float).eps).all()
def test_q2Q(): """ Check that the inner to outer translate method matches PointGravity. This translation method is worse for smaller translations. For R=10, the error approaches 1e7*epsilon. """ d = 1 R = 100 m, M = 1, 1 dr = 99 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) m2 = np.array([[M, R, 0, 0], [M, -R, 0, 0]]) # Create inner moments of each points at +/-r qm0 = pgm.qmoments(10, np.array([m1[0]])) qm0b = pgm.qmoments(10, np.array([m1[1]])) # Get outer moments of points at +/-R Qm2 = pgm.Qmomentsb(10, m2) # Find outer moments from inner qm0 and qm0b translated to +/-R Qlm = trs.translate_q2Q(qm0, [dr, 0, 0]) Qlmb = trs.translate_q2Q(qm0b, [-dr, 0, 0]) assert (abs(Qlm+Qlmb-Qm2) < 11*np.finfo(float).eps).all()