def timing(): ''' This examples compare the numerical performance of `precession.orbit_angles` and `precession.evolve_angles`. Computation is performed twice, first using all the available CPUs and then explicitely disabling the code parallelization. **Run using** import precession.test precession.test.timing() ''' BHsample = [] # Construct a sample of BH binaries N = 100 for i in range(N): q = random.uniform(0, 1) chi1 = random.uniform(0, 1) chi2 = random.uniform(0, 1) M, m1, m2, S1, S2 = precession.get_fixed(q, chi1, chi2) t1 = random.uniform(0, numpy.pi) t2 = random.uniform(0, numpy.pi) dp = random.uniform(0, 2. * numpy.pi) BHsample.append([q, S1, S2, t1, t2, dp]) q_vals, S1_vals, S2_vals, t1i_vals, t2i_vals, dpi_vals = zip( *BHsample) # Traspose python list ri = 1e4 * M # Initial separation rf = 10 * M # Final separation r_vals = [ri, rf] # Intermediate output separations not needed here print " *Integrating a sample of N=%.0f BH binaries from ri=%.0f to rf=%.0f using %.0f CPUs*" % ( N, ri, rf, multiprocessing.cpu_count() ) # Parallel computation used by default t0 = time.time() precession.orbit_angles(t1i_vals, t2i_vals, dpi_vals, r_vals, q_vals, S1_vals, S2_vals) t = time.time() - t0 print "Orbit-averaged: parallel integrations\n\t total time t=%.3fs\n\t time per binary t/N=%.3fs" % ( t, t / N) t0 = time.time() precession.evolve_angles(t1i_vals, t2i_vals, dpi_vals, r_vals, q_vals, S1_vals, S2_vals) t = time.time() - t0 print "Precession-averaged: parallel integrations\n\t total time t=%.3fs\n\t time per binary t/N=%.3fs" % ( t, t / N) precession.empty_temp() # Remove previous checkpoints precession.CPUs = 1 # Force serial computation print " *Integrating a sample of N=%.0f BH binaries from ri=%.0f to rf=%.0f using %.0f CPU*" % ( len(BHsample), ri, rf, precession.CPUs) t0 = time.time() precession.orbit_angles(t1i_vals, t2i_vals, dpi_vals, r_vals, q_vals, S1_vals, S2_vals) t = time.time() - t0 print "Orbit-averaged: serial integrations\n\t total time t=%.3fs\n\t time per binary t/N=%.3fs" % ( t, t / N) t0 = time.time() precession.evolve_angles(t1i_vals, t2i_vals, dpi_vals, r_vals, q_vals, S1_vals, S2_vals) t = time.time() - t0 print "Precession-averaged: serial integrations\n\t total time t=%.3fs\n\t time per binary t/N=%.3fs" % ( t, t / N) precession.empty_temp() # Remove previous checkpoints
def PNwrappers(): ''' Wrappers of the PN integrators. Here we show how to perform orbit-averaged, precession-averaged and hybrid PN inspirals using the various wrappers implemented in the code. We also show how to estimate the final mass, spin and recoil of the BH remnant following a merger. **Run using** import precession.test precession.test.PNwrappers() ''' q = 0.9 # Mass ratio. Must be q<=1. chi1 = 0.5 # Primary spin. Must be chi1<=1 chi2 = 0.5 # Secondary spin. Must be chi2<=1 print "We study a binary with\n\tq=%.3f, chi1=%.3f, chi2=%.3f" % (q, chi1, chi2) M, m1, m2, S1, S2 = precession.get_fixed(q, chi1, chi2) # Total-mass units M=1 ri = 1000 * M # Initial separation. rf = 10. * M # Final separation. rt = 100. * M # Intermediate separation for hybrid evolution. r_vals = numpy.logspace(numpy.log10(ri), numpy.log10(rf), 10) # Output requested t1i = numpy.pi / 4. t2i = numpy.pi / 4. dpi = numpy.pi / 4. # Initial configuration xii, Ji, Si = precession.from_the_angles(t1i, t2i, dpi, q, S1, S2, ri) print "Configuration at ri=%.0f\n\t(xi,J,S)=(%.3f,%.3f,%.3f)\n\t(theta1,theta2,deltaphi)=(%.3f,%.3f,%.3f)" % ( ri, xii, Ji, Si, t1i, t2i, dpi) print " *Orbit-averaged evolution*" print "Evolution ri=%.0f --> rf=%.0f" % (ri, rf) Jf, xif, Sf = precession.orbit_averaged(Ji, xii, Si, r_vals, q, S1, S2) print "\t(xi,J,S)=(%.3f,%.3f,%.3f)" % (xif[-1], Jf[-1], Sf[-1]) t1f, t2f, dpf = precession.orbit_angles(t1i, t2i, dpi, r_vals, q, S1, S2) print "\t(theta1,theta2,deltaphi)=(%.3f,%.3f,%.3f)" % (t1f[-1], t2f[-1], dpf[-1]) Jvec, Lvec, S1vec, S2vec, Svec = precession.Jframe_projection( xii, Si, Ji, q, S1, S2, ri) Lxi, Lyi, Lzi = Lvec S1xi, S1yi, S1zi = S1vec S2xi, S2yi, S2zi = S2vec Lx, Ly, Lz, S1x, S1y, S1z, S2x, S2y, S2z = precession.orbit_vectors( Lxi, Lyi, Lzi, S1xi, S1yi, S1zi, S2xi, S2yi, S2zi, r_vals, q) print "\t(Lx,Ly,Lz)=(%.3f,%.3f,%.3f)\n\t(S1x,S1y,S1z)=(%.3f,%.3f,%.3f)\n\t(S2x,S2y,S2z)=(%.3f,%.3f,%.3f)" % ( Lx[-1], Ly[-1], Lz[-1], S1x[-1], S1y[-1], S1z[-1], S2x[-1], S2y[-1], S2z[-1]) print " *Precession-averaged evolution*" print "Evolution ri=%.0f --> rf=%.0f" % (ri, rf) Jf = precession.evolve_J(xii, Ji, r_vals, q, S1, S2) print "\t(xi,J,S)=(%.3f,%.3f,-)" % (xii, Jf[-1]) t1f, t2f, dpf = precession.evolve_angles(t1i, t2i, dpi, r_vals, q, S1, S2) print "\t(theta1,theta2,deltaphi)=(%.3f,%.3f,%.3f)" % (t1f[-1], t2f[-1], dpf[-1]) print "Evolution ri=%.0f --> infinity" % ri kappainf = precession.evolve_J_backwards(xii, Jf[-1], rf, q, S1, S2) print "\tkappainf=%.3f" % kappainf Jf = precession.evolve_J_infinity(xii, kappainf, r_vals, q, S1, S2) print "Evolution infinity --> rf=%.0f" % rf print "\tJ=%.3f" % Jf[-1] print " *Hybrid evolution*" print "Prec.Av. infinity --> rt=%.0f & Orb.Av. rt=%.0f --> rf=%.0f" % ( rt, rt, rf) t1f, t2f, dpf = precession.hybrid(xii, kappainf, r_vals, q, S1, S2, rt) print "\t(theta1,theta2,deltaphi)=(%.3f,%.3f,%.3f)" % (t1f[-1], t2f[-1], dpf[-1]) print " *Properties of the BH remnant*" Mfin = precession.finalmass(t1f[-1], t2f[-1], dpf[-1], q, S1, S2) print "\tM_f=%.3f" % Mfin chifin = precession.finalspin(t1f[-1], t2f[-1], dpf[-1], q, S1, S2) print "\tchi_f=%.3f, S_f=%.3f" % (chifin, chifin * Mfin**2) vkick = precession.finalkick(t1f[-1], t2f[-1], dpf[-1], q, S1, S2) print "\tvkick=%.5f" % (vkick) # Geometrical units c=1