def test_rotateA2(): d = 1 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) qm1 = pgm.qmoments(10, m1) alpha = -np.pi/4 qm1b = pgm.qmoments(10, glb.rotate_point_array(m1, alpha, [0, 0, 1])) qm1c = rot.rotate_qlm(qm1, alpha, 0, 0) assert (abs(qm1c-qm1b) < 20*np.finfo(float).eps).all()
def test_rotateB(): d = 1 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) qm1 = pgm.qmoments(10, m1) beta = np.pi/4 qm1b = pgm.qmoments(10, glb.rotate_point_array(m1, beta, [0, 1, 0])) qm1c = rot.rotate_qlm(qm1, 0, beta, 0) assert (abs(qm1c-qm1b) < 10*np.finfo(float).eps).all()
def test_rotateAB(): d = 1 m = 1 m1 = np.array([[m, d, 0, 0]]) qm1 = pgm.qmoments(10, m1) alpha = -np.pi/4 beta = np.pi/4 # Rotate around z first by alpha m2 = glb.rotate_point_array(m1, alpha, [0, 0, 1]) # Rotate around y second by beta and get new moments qm1b = pgm.qmoments(10, glb.rotate_point_array(m2, beta, [0, 1, 0])) qm1c = rot.rotate_qlm(qm1, 0, beta, alpha) assert (abs(qm1c-qm1b) < 20*np.finfo(float).eps).all()
def test_q2q(): """ Check that the inner to inner translate method matches PointGravity. """ d = 1 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) # Find inner moments around origin qm1 = pgm.qmoments(10, m1) # Find inner moments if translated by [.1, 0, 0] qm1p = pgm.qmoments(10, glb.translate_point_array(m1, [.1, 0, 0])) # Find moments translated by [.1, 0, 0] qlmp = trs.translate_qlm(qm1, [0.1, 0, 0]) assert (abs(qlmp-qm1p) < 11*np.finfo(float).eps).all()
def test_q2q_RR(): """ Check that the inner to inner translate method matches EGA translation. """ d = 1 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) # Find inner moments around origin qm1 = pgm.qmoments(10, m1) # Find inner moments if translated by [.1, 0, 0] qm1p = pgm.qmoments(10, glb.translate_point_array(m1, [0, 0, 0.1])) # Find moments translated by [.1, 0, 0] rrms = trr.transl_newt_z_RR(10, .1) qlmp = trr.apply_trans_mat(qm1, rrms) assert (abs(qlmp-qm1p) < 11*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_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()
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_q2q_durso(): """ Check that the inner to inner translate method matches analytic expression. """ ar = 1 rp = .1 m = 1 m1 = np.array([[m, ar, 0, 0], [-m, -ar, 0, 0]]) # Find inner moments around origin qm1 = pgm.qmoments(4, m1) # Find moments translated by [.1, 0, 0] qlmp = trs.translate_qlm(qm1, [rp, 0, 0]) # Analytic q44 moment q44 = 3*np.sqrt(35/8/np.pi)*(rp*ar**3 + ar*rp**3) assert abs(qlmp[4, 8] - q44) < 11*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_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)
import newt.translations as trs import newt.rotations as rot import newt.translationRecurs as trr """ Script for comparison of translation methods. Fast rotation + z-translation vs regular translation. """ lmax = 20 # Create 2 points with mass1, at x=+/-1 d = 1 m = 1 m1 = np.array([[m, d, 0, 0], [m, -d, 0, 0]]) # Find inner moments around origin qm1 = pgm.qmoments(lmax, m1) # Find inner moments if translated by [.1, 0, 0] rvec = [0.1, 0, 0] qm1p = pgm.qmoments(lmax, glb.translate_point_array(m1, rvec)) # Find moments translated by [.1, 0, 0] using d'Urso, Adelberger tic1 = time.perf_counter() qm1p2 = trs.translate_qlm(qm1, rvec) toc1 = time.perf_counter() # Time the recursive method combined with recursive translation tic2 = time.perf_counter() r = np.sqrt(rvec[0]**2 + rvec[1]**2 + rvec[2]**2) if r == 0 or r == rvec[2]: phi, theta = 0, 0 else: