def HS2011_Omega_SO_3p5PN_pt6(m1, m2, n12U, p1U, p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(-(8 / m1 + 9 * m2 / (2 * m1**2)) * dot(n12U, p1U) + (59 / (4 * m1) + 27 / (2 * m2)) * dot(n12U, p2U)) * cross(p1U, p2U)[i]) / r12**3 return Omega1
def f_H_SS_2PN(m1,m2, S1U,S2U, nU, q): S0U = ixp.zerorank1() for i in range(3): S0U[i] = (1 + m2/m1)*S1U[i] + (1 + m1/m2)*S2U[i] global H_SS_2PN mu = m1*m2 / (m1 + m2) H_SS_2PN = mu/(m1 + m2) * (3*dot(S0U,nU)**2 - dot(S0U,S0U)) / (2*q**3)
def f_H_NS_3PN(m1, m2, PU, nU, q): mu = m1 * m2 / (m1 + m2) eta = m1 * m2 / (m1 + m2)**2 pU = ixp.zerorank1() for i in range(3): pU[i] = PU[i] / mu global H_NS_3PN H_NS_3PN = mu * ( +div(1, 128) * (-5 + 35 * eta - 70 * eta**2 + 35 * eta**3) * dot(pU, pU)**4 + div(1, 16) * (+(-7 + 42 * eta - 53 * eta**2 - 5 * eta**3) * dot(pU, pU)**3 + (2 - 3 * eta) * eta**2 * dot(nU, pU)**2 * dot(pU, pU)**2 + 3 * (1 - eta) * eta**2 * dot(nU, pU)**4 * dot(pU, pU) - 5 * eta**3 * dot(nU, pU)**6) / q + (+div(1, 16) * (-27 + 136 * eta + 109 * eta**2) * dot(pU, pU)**2 + div(1, 16) * (+17 + 30 * eta) * eta * dot(nU, pU)**2 * dot(pU, pU) + div(1, 12) * (+5 + 43 * eta) * eta * dot(nU, pU)**4) / q**2 + (+(-div(25, 8) + (div(1, 64) * sp.pi**2 - div(335, 48)) * eta - div(23, 8) * eta**2) * dot(pU, pU) + (-div(85, 16) - div(3, 64) * sp.pi**2 - div(7, 4) * eta) * eta * dot(nU, pU)**2) / q**3 + (+div(1, 8) + (div(109, 12) - div(21, 32) * sp.pi**2) * eta) / q**4)
def HS2011_Omega_SO_3p5PN_pt7(m1, m2, n12U, p1U, p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(181 * m1 * m2 / 16 + 95 * m2**2 / 4 + 75 * m2**3 / (8 * m1)) * cross(n12U, p1U)[i] - (21 * m1**2 / 2 + 473 * m1 * m2 / 16 + 63 * m2**2 / 4) * cross(n12U, p2U)[i]) / r12**4 return Omega1
def cross(vec1,vec2): vec1_cross_vec2 = ixp.zerorank1() LeviCivitaSymbol = ixp.LeviCivitaSymbol_dim3_rank3() for i in range(3): for j in range(3): for k in range(3): vec1_cross_vec2[i] += LeviCivitaSymbol[i][j][k]*vec1[j]*vec2[k] return vec1_cross_vec2
def dE_GW_dt_OBKPSS2015_consts(m1, m2, _n12U, S1U, S2U): # _n12U unused. # define scalars: m = (m1 + m2) nu = m1 * m2 / m**2 delta = (m1 - m2) / m # define vectors: Stot = ixp.zerorank1() Sigma = ixp.zerorank1() l = ixp.zerorank1() l[2] = sp.sympify(1) chi1U = ixp.zerorank1() chi2U = ixp.zerorank1() chi_s = ixp.zerorank1() chi_a = ixp.zerorank1() for i in range(3): Stot[i] = S1U[i] + S2U[i] Sigma[i] = (m1 + m2) / m2 * S2U[i] - (m1 + m2) / m1 * S1U[i] chi1U[i] = S1U[i] / m1**2 chi2U[i] = S2U[i] / m2**2 chi_s[i] = div(1, 2) * (chi1U[i] + chi2U[i]) chi_a[i] = div(1, 2) * (chi1U[i] - chi2U[i]) # define scalars that depend on vectors s_l = dot(Stot, l) / m**2 # s_n = dot(Stot,n12U)/m**2 sigma_l = dot(Sigma, l) / m**2 # sigma_n = dot(Sigma,n12U)/m**2 return nu, delta, l, chi_a, chi_s, s_l, sigma_l
def HS2011_Omega_SO_3p5PN_pt3(m1,m2, n12U, p1U,p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(-9*dot(n12U,p1U)*dot(p1U,p1U)/(16*m1**4) +dot(p1U,p1U)*dot(n12U,p2U)/(m1**3*m2) +27*dot(n12U,p1U)*dot(n12U,p2U)**2/(16*m1**2*m2**2) -dot(n12U,p2U)*dot(p1U,p2U)/(8*m1**2*m2**2) -5*dot(n12U,p1U)*dot(p2U,p2U)/(16*m1**2*m2**2))*cross(p1U,p2U)[i])/r12**2 return Omega1
def HS2011_Omega_SO_3p5PN_pt5(m1,m2, n12U, p1U,p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(+4*dot(n12U,p1U)**2/m1 +13*dot(p1U,p1U)/(2*m1) +5*dot(n12U,p2U)**2/m2 +53*dot(p2U,p2U)/(8*m2) -(211/(8*m1) + 22/m2)*dot(n12U,p1U)*dot(n12U,p2U) -(47/(8*m1) + 5/m2)*dot(p1U,p2U))*cross(n12U,p2U)[i])/r12**3 return Omega1
def HS2011_Omega_SO_3p5PN_pt4(m1,m2, n12U, p1U,p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(-3*m2*dot(n12U,p1U)**2/(2*m1**2) +((-3*m2)/(2*m1**2) + 27*m2**2/(8*m1**3))*dot(p1U,p1U) +(177/(16*m1) + 11/m2)*dot(n12U,p2U)**2 +(11/(2*m1) + 9*m2/(2*m1**2))*dot(n12U,p1U)*dot(n12U,p2U) +(23/(4*m1) + 9*m2/(2*m1**2))*dot(p1U,p2U) -(159/(16*m1) + 37/(8*m2))*dot(p2U,p2U))*cross(n12U,p1U)[i])/r12**3 return Omega1
def f_compute_quantities(mOmega, m1, m2, n12U, S1U, S2U, which_quantity): if not which_quantity in ('dM_dt', 'dE_GW_dt', 'dE_GW_dt_plus_dM_dt'): print("which_quantity == " + str(which_quantity) + " not supported!") sys.exit(1) nu, delta, l, chi_a, chi_s, s_l, sigma_l = dE_GW_dt_OBKPSS2015_consts( m1, m2, n12U, S1U, S2U) x = (mOmega)**div(2, 3) # Compute b_5_Mdot: b_5_Mdot = (-div(1, 4) * (+(1 - 3 * nu) * dot(chi_s, l) * (1 + 3 * dot(chi_s, l)**2 + 9 * dot(chi_a, l)**2) + (1 - nu) * delta * dot(chi_a, l) * (1 + 3 * dot(chi_a, l)**2 + 9 * dot(chi_s, l)**2))) if which_quantity == "dM_dt": return div(32, 5) * nu**2 * x**5 * b_5_Mdot * x**div(5, 2) b = ixp.zerorank1(DIM=10) b[2] = -div(1247, 336) - div(35, 12) * nu b[3] = +4 * sp.pi - 4 * s_l - div(5, 4) * delta * sigma_l b[4] = (-div(44711, 9072) + div(9271, 504) * nu + div(65, 18) * nu**2 + (+div(287, 96) + div(1, 24) * nu) * dot(chi_s, l)**2 - (+div(89, 96) + div(7, 24) * nu) * dot(chi_s, chi_s) + (+div(287, 96) - 12 * nu) * dot(chi_a, l)**2 + (-div(89, 96) + 4 * nu) * dot(chi_a, chi_a) + div(287, 48) * delta * dot(chi_s, l) * dot(chi_a, l) - div(89, 48) * delta * dot(chi_s, chi_a)) b[5] = (-div(8191, 672) * sp.pi - div(9, 2) * s_l - div(13, 16) * delta * sigma_l + nu * (-div(583, 24) * sp.pi + div(272, 9) * s_l + div(43, 4) * delta * sigma_l)) if which_quantity == "dE_GW_dt_plus_dM_dt": b[5] += b_5_Mdot b[6] = (+div(6643739519, 69854400) + div(16, 3) * sp.pi**2 - div(1712, 105) * gamma_EulerMascheroni - div(856, 105) * sp.log(16 * x) + (-div(134543, 7776) + div(41, 48) * sp.pi**2) * nu - div(94403, 3024) * nu**2 - div(775, 324) * nu**3 - 16 * sp.pi * s_l - div(31, 6) * sp.pi * delta * sigma_l) b[7] = ( +(+div(476645, 6804) + div(6172, 189) * nu - div(2810, 27) * nu**2) * s_l + (+div(9535, 336) + div(1849, 126) * nu - div(1501, 36) * nu**2) * delta * sigma_l + (-div(16285, 504) + div(214745, 1728) * nu + div(193385, 3024) * nu**2) * sp.pi) b[8] = (+(-div(3485, 96) * sp.pi + div(13879, 72) * sp.pi * nu) * s_l + (-div(7163, 672) * sp.pi + div(130583, 2016) * sp.pi * nu) * delta * sigma_l) b_sum = sp.sympify(1) for k in range(9): b_sum += b[k] * x**div(k, 2) return div(32, 5) * nu**2 * x**5 * b_sum
def HS2011_Omega_SO_3p5PN_pt2(m1,m2, n12U, p1U,p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(-3*dot(n12U,p1U)*dot(n12U,p2U)*dot(p1U,p1U)/(2*m1**3*m2) -15*dot(n12U,p1U)**2*dot(n12U,p2U)**2/(4*m1**2*m2**2) +3*dot(p1U,p1U)*dot(n12U,p2U)**2/(4*m1**2*m2**2) -dot(p1U,p1U)*dot(p1U,p2U)/(2*m1**3*m2) +dot(p1U,p2U)**2/(2*m1**2*m2**2) +3*dot(n12U,p1U)**2*dot(p2U,p2U)/(4*m1**2*m2**2) -dot(p1U,p1U)*dot(p2U,p2U)/(4*m1**2*m2**2) -3*dot(n12U,p1U)*dot(n12U,p2U)*dot(p2U,p2U)/(2*m1*m2**3) -dot(p1U,p2U)*dot(p2U,p2U)/(2*m1*m2**3))*cross(n12U,p2U)[i])/r12**2 return Omega1
def f_H_SO_3p5PN(m1,m2, n12U,n21U, S1U, S2U, p1U,p2U, r12): Omega1_3p5PNU = ixp.zerorank1() Omega2_3p5PNU = ixp.zerorank1() for i in range(3): Omega1_3p5PNU[i] = HS2011_Omega_SO_3p5PN_pt1(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt2(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt3(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt4(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt5(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt6(m1,m2, n12U, p1U,p2U, r12)[i] Omega1_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt7(m1,m2, n12U, p1U,p2U, r12)[i] Omega2_3p5PNU[i] = HS2011_Omega_SO_3p5PN_pt1(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt2(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt3(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt4(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt5(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt6(m2,m1, n21U, p2U,p1U, r12)[i] Omega2_3p5PNU[i]+= HS2011_Omega_SO_3p5PN_pt7(m2,m1, n21U, p2U,p1U, r12)[i] global H_SO_3p5PN H_SO_3p5PN = dot(Omega1_3p5PNU,S1U) + dot(Omega2_3p5PNU,S2U)
def f_H_SSS_3PN_pt(m1,m2, nU, S1U,S2U, p1U,p2U, r): p2_minus_m2_over_4m1_p1 = ixp.zerorank1() for i in range(3): p2_minus_m2_over_4m1_p1[i] = p2U[i] - m2/(4*m1)*p1U[i] H_SSS_3PN_pt = (+div(3,2)*(+dot(S1U,S1U)*dot(S2U,cross(nU,p1U)) +dot(S1U,nU)*dot(S2U,cross(S1U,p1U)) -5*dot(S1U,nU)**2*dot(S2U,cross(nU,p1U)) +dot(nU,cross(S1U,S2U))*(+dot(S1U,p1U) -5*dot(S1U,nU)*dot(p1U,nU))) -3*m1/(2*m2)*( +dot(S1U,S1U) *dot(S2U,cross(nU,p2U)) +2*dot(S1U,nU) *dot(S2U,cross(S1U,p2U)) -5*dot(S1U,nU)**2*dot(S2U,cross(nU,p2U))) -dot(cross(S1U,nU),p2_minus_m2_over_4m1_p1)*(dot(S1U,S1U) - 5*dot(S1U,nU)**2))/(m1**2*r**4) return H_SSS_3PN_pt
def f_Omega_SO_2p5PN(m1, m2, n12U, p1U, p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (+(+(-div(11, 2) * m2 - 5 * m2 ** 2 / m1) * cross(n12U, p1U)[i] + (6 * m1 + div(15, 2) * m2) * cross(n12U, p2U)[i]) / r12 ** 3 + (+(-div(5, 8) * m2 * dot(p1U, p1U) / m1 ** 3 - div(3, 4) * dot(p1U, p2U) / m1 ** 2 + div(3, 4) * dot(p2U, p2U) / (m1 * m2) - div(3, 4) * dot(n12U, p1U) * dot(n12U, p2U) / m1 ** 2 - div(3, 2) * dot(n12U, p2U) ** 2 / (m1 * m2)) * cross(n12U, p1U)[i] + (dot(p1U, p2U) / (m1 * m2) + 3 * dot(n12U, p1U) * dot(n12U, p2U) / (m1 * m2)) * cross(n12U, p2U)[i] + (div(3, 4) * dot(n12U, p1U) / m1 ** 2 - 2 * dot(n12U, p2U) / (m1 * m2)) * cross(p1U, p2U)[ i]) / r12 ** 2) return Omega1
def HS2011_Omega_SO_3p5PN_pt1(m1,m2, n12U, p1U,p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = ((+7*m2*dot(p1U,p1U)**2/(16*m1**5) +9*dot(n12U,p1U)*dot(n12U,p2U)*dot(p1U,p1U)/(16*m1**4) +3*dot(p1U,p1U)*dot(n12U,p2U)**2/(4*m1**3*m2) +45*dot(n12U,p1U)*dot(n12U,p2U)**3/(16*m1**2*m2**2) +9*dot(p1U,p1U)*dot(p1U,p2U)/(16*m1**4) -3*dot(n12U,p2U)**2*dot(p1U,p2U)/(16*m1**2*m2**2) -3*dot(p1U,p1U)*dot(p2U,p2U)/(16*m1**3*m2) -15*dot(n12U,p1U)*dot(n12U,p2U)*dot(p2U,p2U)/(16*m1**2*m2**2) +3*dot(n12U,p2U)**2*dot(p2U,p2U)/(4*m1*m2**3) -3*dot(p1U,p2U)*dot(p2U,p2U)/(16*m1**2*m2**2) -3*dot(p2U,p2U)**2/(16*m1*m2**3))*cross(n12U,p1U)[i])/r12**2 return Omega1
def f_MOmega(m1,m2, chi1U,chi2U, r): a = ixp.zerorank1(DIM=10) MOmega__a_2_thru_a_4(m1,m2, chi1U[0],chi1U[1],chi1U[2], chi2U[0],chi2U[1],chi2U[2]) a[2] = a_2 a[3] = a_3 a[4] = a_4 MOmega__a_5_thru_a_6(m1,m2, chi1U[0],chi1U[1],chi1U[2], chi2U[0],chi2U[1],chi2U[2]) a[5] = a_5 a[6] = a_6 MOmega__a_7( m1,m2, chi1U[0],chi1U[1],chi1U[2], chi2U[0],chi2U[1],chi2U[2]) a[7] = a_7 global MOmega MOmega = 1 # Term prior to the sum in parentheses for k in range(8): MOmega += a[k]/r**div(k,2) MOmega *= 1/r**div(3,2)
def f_H_Newt__H_NS_1PN__H_NS_2PN(m1,m2, PU, nU, q): mu = m1*m2 / (m1+m2) eta = m1*m2 / (m1+m2)**2 pU = ixp.zerorank1() for i in range(3): pU[i] = PU[i]/mu global H_Newt, H_NS_1PN, H_NS_2PN H_Newt = mu*(+div(1,2)*dot(pU,pU) - 1/q) H_NS_1PN = mu*(+div(1,8)*(3*eta-1)*dot(pU,pU)**2 -div(1,2)*((3+eta)*dot(pU,pU) + eta*dot(nU,pU)**2)/q +div(1,2)/q**2) H_NS_2PN = mu*(+div(1,16)*(1 - 5*eta + 5*eta**2)*dot(pU,pU)**3 +div(1,8)*(+(5 - 20*eta - 3*eta**2)*dot(pU,pU)**2 -2*eta**2*dot(nU,pU)**2*dot(pU,pU) -3*eta**2*dot(nU,pU)**4)/q +div(1,2)*((5+8*eta)*dot(pU,pU) + 3*eta*dot(nU,pU)**2)/q**2 -div(1,4)*(1+3*eta)/q**3)
def f_p_t(m1, m2, chi1U, chi2U, r): q = m2 / m1 # It is assumed that q >= 1, so m2 >= m1. a = ixp.zerorank1(DIM=10) p_t__a_2_thru_a_4(m1, m2, chi1U[0], chi1U[1], chi1U[2], chi2U[0], chi2U[1], chi2U[2]) a[2] = a_2 a[3] = a_3 a[4] = a_4 p_t__a_5_thru_a_6(m1, m2, chi1U[0], chi1U[1], chi1U[2], chi2U[0], chi2U[1], chi2U[2]) a[5] = a_5 a[6] = a_6 p_t__a_7(m1, m2, chi1U[0], chi1U[1], chi1U[2], chi2U[0], chi2U[1], chi2U[2]) a[7] = a_7 global p_t p_t = 1 # Term prior to the sum in parentheses for k in range(8): p_t += a[k] / r**div(k, 2) p_t *= q / (1 + q)**2 * 1 / r**div(1, 2)
# Some references use r, others use q to represent the # distance between the two point masses. This is rather # confusing since q is also used to represent the # mass ratio m2/m1. However, q is the canonical position # variable name in Hamiltonian mechanics, so both are # well justified. It should be obvious which is which # throughout NRPyPN. r, q = sp.symbols('r q', real=True) chi1U = ixp.declarerank1('chi1U') chi2U = ixp.declarerank1('chi2U') # Euler-Mascheroni gamma constant: gamma_EulerMascheroni = sp.EulerGamma # Derived quantities used in Damour et al papers: n12U = ixp.zerorank1() n21U = ixp.zerorank1() p1U = ixp.zerorank1() p2U = ixp.zerorank1() for i in range(3): n12U[i] = +nU[i] n21U[i] = -nU[i] p1U[i] = +pU[i] p2U[i] = -pU[i] # Step 2.a: Define dot and cross product of vectors def dot(vec1,vec2): vec1_dot_vec2 = sp.sympify(0) for i in range(3): vec1_dot_vec2 += vec1[i]*vec2[i] return vec1_dot_vec2
def f_Omega1(m1, m2, n12U, p1U, p2U, r12): Omega1 = ixp.zerorank1() for i in range(3): Omega1[i] = (div(3, 2) * m2 / m1 * cross(n12U, p1U)[i] - 2 * cross(n12U, p2U)[i]) / r12**2 return Omega1