def compare_evolutions(): ''' Compare precession averaged and orbit averaged integrations. Plot the evolution of xi, J, S and their relative differences between the two approaches. Since precession-averaged estimates of S require a random sampling, this plot will look different every time this routine is executed. Output is saved in ./spin_angles.pdf. **Run using** import precession.test precession.test.compare_evolutions() ''' fig = pylab.figure(figsize=(6, 6)) # Create figure object and axes L, Ws, Wm, G = 0.85, 0.15, 0.3, 0.03 # Sizes ax_Sd = fig.add_axes([0, 0, L, Ws]) # bottom-small ax_S = fig.add_axes([0, Ws, L, Wm]) # bottom-main ax_Jd = fig.add_axes([0, Ws + Wm + G, L, Ws]) # middle-small ax_J = fig.add_axes([0, Ws + Ws + Wm + G, L, Wm]) # middle-main ax_xid = fig.add_axes([0, 2 * (Ws + Wm + G), L, Ws]) # top-small ax_xi = fig.add_axes([0, Ws + 2 * (Ws + Wm + G), L, Wm]) # top-main q = 0.8 # Mass ratio. Must be q<=1. chi1 = 0.6 # Primary spin. Must be chi1<=1 chi2 = 1. # Secondary spin. Must be chi2<=1 M, m1, m2, S1, S2 = precession.get_fixed(q, chi1, chi2) # Total-mass units M=1 ri = 100. * M # Initial separation. rf = 10. * M # Final separation. r_vals = numpy.linspace(ri, rf, 1001) # Output requested Ji = 2.24 # Magnitude of J: Jmin<J<Jmax as given by J_lim xi = -0.5 # Effective spin: xi_low<xi<xi_up as given by xi_allowed Jf_P = precession.evolve_J(xi, Ji, r_vals, q, S1, S2) # Pr.av. integration Sf_P = [ precession.samplingS(xi, J, q, S1, S2, r) for J, r in zip(Jf_P[0::10], r_vals[0::10]) ] # Resample S (reduce output for clarity) Sb_min, Sb_max = zip(*[ precession.Sb_limits(xi, J, q, S1, S2, r) for J, r in zip(Jf_P, r_vals) ]) # Envelopes S = numpy.average([precession.Sb_limits(xi, Ji, q, S1, S2, ri)]) # Initialize S Jf_O, xif_O, Sf_O = precession.orbit_averaged(Ji, xi, S, r_vals, q, S1, S2) # Orb.av. integration Pcol, Ocol, Dcol = 'blue', 'red', 'green' Pst, Ost = 'solid', 'dashed' ax_xi.axhline(xi, c=Pcol, ls=Pst, lw=2) # Plot xi, pr.av. (constant) ax_xi.plot(r_vals, xif_O, c=Ocol, ls=Ost, lw=2) # Plot xi, orbit averaged ax_xid.plot(r_vals, (xi - xif_O) / xi * 1e11, c=Dcol, lw=2) # Plot xi deviations (rescaled) ax_J.plot(r_vals, Jf_P, c=Pcol, ls=Pst, lw=2) # Plot J, pr.av. ax_J.plot(r_vals, Jf_O, c=Ocol, ls=Ost, lw=2) # Plot J, orb.av ax_Jd.plot(r_vals, (Jf_P - Jf_O) / Jf_O * 1e3, c=Dcol, lw=2) # Plot J deviations (rescaled) ax_S.scatter(r_vals[0::10], Sf_P, facecolor='none', edgecolor=Pcol) # Plot S, pr.av. (resampled) ax_S.plot(r_vals, Sb_min, c=Pcol, ls=Pst, lw=2) # Plot S, pr.av. (envelopes) ax_S.plot(r_vals, Sb_max, c=Pcol, ls=Pst, lw=2) # Plot S, pr.av. (envelopes) ax_S.plot(r_vals, Sf_O, c=Ocol, ls=Ost, lw=2) # Plot S, orb.av (evolved) ax_Sd.plot(r_vals[0::10], (Sf_P - Sf_O[0::10]) / Sf_O[0::10], c=Dcol, lw=2) # Plot S deviations # Options for nice plotting for ax in [ax_xi, ax_xid, ax_J, ax_Jd, ax_S, ax_Sd]: ax.set_xlim(ri, rf) ax.yaxis.set_label_coords(-0.16, 0.5) ax.spines['left'].set_lw(1.5) ax.spines['right'].set_lw(1.5) for ax in [ax_xi, ax_J, ax_S]: ax.spines['top'].set_lw(1.5) for ax in [ax_xid, ax_Jd, ax_Sd]: ax.axhline(0, c='black', ls='dotted') ax.spines['bottom'].set_lw(1.5) for ax in [ax_xid, ax_J, ax_Jd, ax_S]: ax.set_xticklabels([]) ax_xi.set_ylim(-0.55, -0.45) ax_J.set_ylim(0.4, 2.3) ax_S.set_ylim(0.24, 0.41) ax_xid.set_ylim(-0.2, 1.2) ax_Jd.set_ylim(-3, 5.5) ax_Sd.set_ylim(-0.7, 0.7) ax_xid.yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(0.5)) ax_Jd.yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(2)) ax_S.yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(0.05)) ax_Sd.yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(0.5)) ax_xi.xaxis.set_ticks_position('top') ax_xi.xaxis.set_label_position('top') ax_Sd.set_xlabel("$r/M$") ax_xi.set_xlabel("$r/M$") ax_xi.set_ylabel("$\\xi$") ax_J.set_ylabel("$J/M^2$") ax_S.set_ylabel("$S/M^2$") ax_xid.set_ylabel("$\\Delta\\xi/\\xi \;[10^{-11}]$") ax_Jd.set_ylabel("$\\Delta J/J \;[10^{-3}]$") ax_Sd.set_ylabel("$\\Delta S / S$") fig.savefig("compare_evolutions.pdf", bbox_inches='tight') # Save pdf file
def phase_resampling(): ''' Precessional phase resampling. The magnidute of the total spin S is sampled according to |dS/dt|^-1, which correspond to a flat distribution in t(S). Output is saved in ./phase_resampling.pdf and data stored in `precession.storedir'/phase_resampling_.dat **Run using** import precession.test precession.test.phase_resampling() ''' fig = pylab.figure(figsize=(6, 6)) #Create figure object and axes ax_tS = fig.add_axes([0, 0, 0.6, 0.6]) #bottom-left ax_td = fig.add_axes([0.65, 0, 0.3, 0.6]) #bottom-right ax_Sd = fig.add_axes([0, 0.65, 0.6, 0.3]) #top-left q = 0.5 # Mass ratio. Must be q<=1. chi1 = 0.3 # Primary spin. Must be chi1<=1 chi2 = 0.9 # Secondary spin. Must be chi2<=1 M, m1, m2, S1, S2 = precession.get_fixed(q, chi1, chi2) # Total-mass units M=1 r = 200. * M # Separation. Must be r>10M for PN to be valid J = 3.14 # Magnitude of J: Jmin<J<Jmax as given by J_lim xi = -0.01 # Effective spin: xi_low<xi<xi_up as given by xi_allowed Sb_min, Sb_max = precession.Sb_limits(xi, J, q, S1, S2, r) # Limits in S tau = precession.precession_period(xi, J, q, S1, S2, r) # Precessional period d = 2000 # Size of the statistical sample precession.make_temp() # Create store directory, if necessary filename = precession.storedir + "/phase_resampling.dat" # Output file name if not os.path.isfile(filename): # Compute and store data if not present out = open(filename, "w") out.write("# q chi1 chi2 r J xi d\n") # Write header out.write("# " + ' '.join([str(x) for x in (q, chi1, chi2, r, J, xi, d)]) + "\n") # S and t values for the S(t) plot S_vals = numpy.linspace(Sb_min, Sb_max, d) t_vals = numpy.array([ abs( precession.t_of_S(Sb_min, S, Sb_min, Sb_max, xi, J, q, S1, S2, r)) for S in S_vals ]) # Sample values of S from |dt/dS|. Distribution should be flat in t. S_sample = numpy.array( [precession.samplingS(xi, J, q, S1, S2, r) for i in range(d)]) t_sample = numpy.array([ abs( precession.t_of_S(Sb_min, S, Sb_min, Sb_max, xi, J, q, S1, S2, r)) for S in S_sample ]) # Continuous distributions (normalized) S_distr = numpy.array([ 2. * abs(precession.dtdS(S, xi, J, q, S1, S2, r) / tau) for S in S_vals ]) t_distr = numpy.array([2. / tau for t in t_vals]) out.write("# S_vals t_vals S_sample t_sample S_distr t_distr\n") for Sv, tv, Ss, ts, Sd, td in zip(S_vals, t_vals, S_sample, t_sample, S_distr, t_distr): out.write(' '.join([str(x) for x in (Sv, tv, Ss, ts, Sd, td)]) + "\n") out.close() else: # Read S_vals, t_vals, S_sample, t_sample, S_distr, t_distr = numpy.loadtxt( filename, unpack=True) # Rescale all time values by 10^-6, for nicer plotting tau *= 1e-6 t_vals *= 1e-6 t_sample *= 1e-6 t_distr /= 1e-6 ax_tS.plot(S_vals, t_vals, c='blue', lw=2) # S(t) curve ax_td.plot(t_distr, t_vals, lw=2., c='red') # Continous distribution P(t) ax_Sd.plot(S_vals, S_distr, lw=2., c='red') # Continous distribution P(S) ax_td.hist(t_sample, bins=60, range=(0, tau / 2.), normed=True, histtype='stepfilled', color="blue", alpha=0.4, orientation="horizontal") # Histogram P(t) ax_Sd.hist(S_sample, bins=60, range=(Sb_min, Sb_max), normed=True, histtype='stepfilled', color="blue", alpha=0.4) # Histogram P(S) # Options for nice plotting ax_tS.set_xlim(Sb_min, Sb_max) ax_tS.set_ylim(0, tau / 2.) ax_tS.set_xlabel("$S/M^2$") ax_tS.set_ylabel("$t/(10^6 M)$") ax_td.set_xlim(0, 0.5) ax_td.set_ylim(0, tau / 2.) ax_td.set_xlabel("$P(t)$") ax_td.set_yticklabels([]) ax_Sd.set_xlim(Sb_min, Sb_max) ax_Sd.set_ylim(0, 20) ax_Sd.set_xticklabels([]) ax_Sd.set_ylabel("$P(S)$") fig.savefig("phase_resampling.pdf", bbox_inches='tight') # Save pdf file