def plot_Mf(save=True, ED_I=False): """ Function that generates the plot of the LISA and Taiji monopole response functions. It corresponds to left panel of figure 15 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: save -- option to save the figure in "plots/LISA_Taiji_response.pdf" (default True) ED_I -- option to plot the response function of cross-correlating channels E and D of the LISA-Taiji network (default False) """ plt.figure(figsize=(12, 10)) plt.rc('font', size=30) plt.plot(fs, MAs, color='black', label=r'${\cal M}_{\rm AA} (f)$') plt.plot(fs, MAs_Tai, color='black', ls='-.', label=r'${\cal M}_{\rm CC} (f)$') plt.plot(fs, MTs, color='blue', label=r'${\cal M}_{\rm TT} (f)$') plt.plot(fs, MTs_Tai, color='blue', ls='-.', label=r'${\cal M}_{\rm SS} (f)$') aaux = '' if ED_I == True: gg = np.where(abs(M_ED_I) > 1e-48) plt.plot(fs[gg], abs(M_ED_I[gg]), color='purple', alpha=.5) plt.text(3e-3, 6e-3, r'$|{\cal M}^I_{\rm ED}|$', color='purple') aaux = 'ED' Rf = inte.R_f(fs) L = 3e6 * u.km Rf_Tai = inte.R_f(fs, L=L) plt.plot(fs, Rf, color='black', ls='dashed', lw=.7) plt.plot(fs, Rf_Tai, color='black', ls='dashed', lw=.7) plt.text(5e-2, 7e-2, r'$\tilde {\cal R}^{\rm A, C}(f)$', fontsize=34) plt.xscale('log') plt.yscale('log') plt.xlim(1e-3, 1) plt.ylim(1e-7, 1e0) plt.legend(fontsize=28, frameon=False, loc='center left') plt.xlabel(r'$f$ [Hz]') plt.ylabel(r'${\cal M} (f)$') plot_sets.axes_lines() plt.yticks(np.logspace(-7, 0, 8)) ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) if save: plt.savefig('plots/LISA_Taiji_response' + aaux + '.pdf', bbox_inches='tight')
def plot_noise_PSD(interf='LISA', save=True): """ Function that generates the plot of LISA (Taiji) noise PSD of the channel A (C) and compares with the optical metrology system P_oms and mass acceleration P_acc PSD noises. Arguments: interf -- selects interferometer (default 'LISA', also available 'Taiji') save -- option to save the figure in "plots/noise_PSD_interf.pdf" (default True) """ plt.figure(figsize=(12, 8)) if interf == 'LISA': #plt.plot(fs, PnX, color='blue') plt.plot(fs, PnA, color='red') plt.plot(fs, Pacc, color='blue', ls='-.', lw=.8) plt.plot(fs, Poms, color='blue', ls='-.', lw=.8) yPn = 1e-40 yPoms = 1e-40 yPacc = 6e-43 A = 'A' if interf == 'Taiji': #plt.plot(fs, PnX_Tai, color='blue') plt.plot(fs, PnC, color='red') plt.plot(fs, Pacc_Tai, color='blue', ls='-.', lw=.8) plt.plot(fs, Poms_Tai, color='blue', ls='-.', lw=.8) yPn = 2e-41 yPoms = 2e-41 yPacc = 4e-43 A = 'C' plt.xlabel('$f$ [Hz]') plt.ylabel('noise PSD $(f)$') plt.xscale('log') plt.yscale('log') plt.ylim(1e-43, 1e-30) plt.xlim(1e-5, 1e0) plt.text(1e-1, yPoms, r'$P_{\rm oms} (f)$', color='blue') plt.text(1e-1, yPacc, r'$P_{\rm acc} (f)$', color='blue') plt.text(1e-2, yPn, r'$P_n^{\rm %s} (f)$' % A, color='red') plt.text(1e-1, 1e-32, interf, fontsize=24, bbox=dict(facecolor='none', edgecolor='black', boxstyle='round,pad=.5')) plot_sets.axes_lines() if save: plt.savefig('plots/noise_PSD_' + interf + '.pdf', bbox_inches='tight')
def plot_PM_beltrami(save=True): """ Function that plots the analytical relations between the GW polarization P and the source helicity PM (for magnetic) for the Beltrami field model, compared to the empirical fit obtained in the numerical simulations. It produces figure 14 (appendix A) of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: save -- option to save the figure in plots/PM_beltrami.pdf' (default True) """ plt.figure(figsize=(12, 8)) sigma = np.linspace(0, 1, 100) Sh_sig = .5 + 2 * sigma**2 / (1 + sigma**2)**2 Pm_sig = 2 * sigma / (1 + sigma**2) Sh_sig = .5 * (1 + Pm_sig**2) Ph_sig = Pm_sig / Sh_sig plt.plot(sigma, Pm_sig, ls='dotted', color='red', label=r'${\cal P}_{\rm M}$') plt.plot(sigma, Sh_sig, ls='-.', color='blue', label=r'$\left(1 + {\cal P}_{\rm M}^2\right)/2$') plt.plot(sigma, Ph_sig, color='black', lw=.8, label=r'$2 {\cal P}_{\rm M}/\left(1 + {\cal P}_{\rm M}^2\right)$') plot_sets.axes_lines() plt.xlim(0, 1) plt.ylim(0, 1.1) plt.legend(fontsize=28, loc='lower right', frameon=False) plt.xlabel('$\sigma$') plt.ylabel(r'$\cal P$') ax = plt.gca() ax.tick_params(axis='x', pad=20) plt.yticks(np.linspace(0, 1, 5)) if save: plt.savefig('plots/PM_beltrami.pdf', bbox_inches='tight')
def plot_EGW_vs_kt(runs, rr='ini2', save=True, show=True): """ Function that generates the plot of the compensated GW spectrum as a function of k(t - tini) for the smallest wave numbers of the run. It corresponds to figure 3 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables rr -- string that selects which run to plot (default 'ini2') save -- option to save the resulting figure as plots/EGW_vs_kt.pdf (default True) show -- option to show the resulting figure (default True) """ run = runs.get(rr) k = run.spectra.get('k')[1:] EGW = np.array(run.spectra.get('EGW')[:,1:], dtype='float') t = run.spectra.get('t_EGW') plt.figure(figsize=(10,6)) plt.xscale('log') plt.yscale('log') plt.xlim(1e-2, 40) plt.ylim(8e-8, 1e-5) plt.xlabel('$k (t - 1)$') plt.ylabel(r'$\left[k_* \Omega_{\rm GW} (k, t)/k\right]^{1/2}$') plot_sets.axes_lines() # plot for initial wave numbers plt.plot(k[0]*(t - 1), np.sqrt(EGW[:, 0]*run.kf), color='black', lw=.8, #label='$k = %.0f$'%k[0]) label='$k = 100$') plt.plot(k[1]*(t - 1), np.sqrt(EGW[:, 1]*run.kf), color='red', ls='-.', lw=.8, #label='$k = %.0f$'%k[1]) label='$k = 200$') plt.plot(k[2]*(t - 1), np.sqrt(EGW[:, 2]*run.kf), color='blue', ls='dashed', lw=.8, #label='$k = %.0f$'%k[2]) label='$k = 300$') plt.plot(k[3]*(t - 1), np.sqrt(EGW[:, 3]*run.kf), color='green', ls='dotted', lw=.8, #label='$k = %.0f$'%k[3]) label='$k = 400$') plt.legend(fontsize=22, loc='lower right', frameon=False) if save: plt.savefig('plots/EGW_vs_kt.pdf', bbox_inches='tight') if not show: plt.close()
def plot_Xi_sensitivity_comb(save=True): """ Function that generates the plot of the GW energy density polarization sensitivity obtained by combining the cross-correlated channels of the LISA-Taiji network. Arguments: save -- option to save the figure in "plots/Xi_LISA_Taiji_comb.pdf" (default True) """ plt.figure(figsize=(12, 8)) #plt.rc('font', size=18) plt.plot(fs, XiSAC, color='black', lw=.8, label=r'$h_0^2\, \Xi_{\rm s}^{AC} (f)$') plt.plot(fs, XiSAD, color='blue', ls='dotted', label=r'$h_0^2\, \Xi_{\rm s}^{AD} (f)$') plt.plot(fs, XiSEC, color='red', ls='-.', label=r'$h_0^2\, \Xi_{\rm s}^{EC} (f)$') plt.plot(fs, XiSED, color='green', ls='--', lw=.6, label=r'$h_0^2\, \Xi_{\rm s}^{ED} (f)$') plt.plot(fs, XiS_comb, color='blue', label=r'$h_0^2\, \Xi_{\rm s}^{\rm comb} (f)$') plt.legend(fontsize=20, loc='lower right', frameon=False) plt.xlabel(r'$f$ [Hz]') plt.ylabel(r'$h_0^2\, \Xi_{\rm s} (f)$') plt.xscale('log') plt.yscale('log') plt.ylim(1e-12, 1e-4) plt.xlim(1e-4, 1e-1) plot_sets.axes_lines() if save: plt.savefig('plots/Xi_LISA_Taiji_comb.pdf', bbox_inches='tight')
def plot_Df(save=True): """ Function that generates the plot of the LISA and Taiji dipole response functions. It corresponds to right panel of figure 15 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: save -- option to save the figure in "plots/DEA_LISA_Taiji.pdf" (default True) """ fig, ax0 = plt.subplots(figsize=(12, 10)) # plt.rc('font', size=30) DAE_posneg(fs, DAEs) DAE_posneg(fs, DAEs_Tai, ls='-.') plt.xlim(1e-3, 1) plt.ylim(1e-7, 1) plt.xlabel(r'$f$ [Hz]') plt.ylabel(r'${\cal D}(f)$') plt.xscale('log') plt.yscale('log') plot_sets.axes_lines() plt.text(4.7e-2, 2e-2, r'${\cal D}_{AE}(f)$', fontsize=30) plt.text(1.3e-2, 7e-3, r'${\cal D}_{CD}(f)$', fontsize=30) #plt.text(2.1e-2, 3e-3, r'${\cal D}_{CD}(f)$', fontsize=20) line_pos, = ax0.plot([], [], color='blue', lw=.7, label=r'positive values') line_neg, = ax0.plot([], [], color='red', lw=.7, label=r'negative values') handles = [line_pos, line_neg] lgd = ax0.legend(handles=handles, loc='lower left', fontsize=34, frameon=False) ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) plt.yticks(np.logspace(-7, 0, 8)) if save: plt.savefig('plots/DEA_LISA_Taiji.pdf', bbox_inches='tight')
def plot_sensitivity(save=True): """ Function that generates the plot of LISA and Taiji strain sensitivities. Arguments: save -- option to save the figure in "plots/sensitivity_LISA_Taiji.pdf" (default True) """ plt.figure(figsize=(12, 8)) plt.rc('font', size=20) plt.plot(fs, np.sqrt(SnX), color='red', label='channel X') plt.plot(fs, np.sqrt(SnA), color='blue', label='TDI channel A') plt.plot(fs, np.sqrt(SnT), color='orange', label='TDI channel T', alpha=.6) plt.plot(fs, np.sqrt(SnX_Tai), color='red', ls='-.') plt.plot(fs, np.sqrt(SnC), color='blue', ls='-.') plt.plot(fs, np.sqrt(SnS), color='orange', ls='-.', alpha=.6) gg = np.where(abs(M_ED_I) > 1e-48) plt.plot(fs[gg], np.sqrt(Sn_ED_I[gg]), color='purple', alpha=.5, label='TDI channels ED') plt.legend(fontsize=20) plt.xlabel('$f$ [Hz]') plt.ylabel(r'Strain sensitivity $\left[{\rm Hz}^{-1/2}\right]$') plt.xscale('log') plt.yscale('log') plt.text(1e-1, 3e-19, 'LISA', fontsize=20) plt.text(1e-1, 8e-21, 'Taiji', fontsize=20) plt.ylim(1e-21, 1e-12) plt.xlim(1e-5, 1e0) plot_sets.axes_lines() ax = plt.gca() ytics = 10**np.array(np.linspace(-21, -12, 10)) ax.set_yticks(ytics) if save: plt.savefig('plots/sensitivity_LISA_Taiji.pdf', bbox_inches='tight')
def plot_OmMK_OmGW_vs_t(runs, save=True, show=True): """ Function that generates the plots of the total magnetic/kinetic energy density as a function of time ('OmM_vs_t.pdf') and the GW energy density as a function of time ('OmGW_vs_t.pdf'). It corresponds to figure 5 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables save -- option to save the resulting figure as plots/OmGW_vs_t.pdf (default True) show -- option to show the resulting figure (default True) """ # chose the runs to be shown rrs = ['ini1', 'ini2', 'ini3', 'hel1', 'hel2', 'ac1'] # chose the colors of each run col = ['black', 'red', 'blue', 'red', 'blue', 'black'] # chose the line style for the plots ls = ['solid']*6 ls[3] = 'dashed' ls[4] = 'dashed' ls[5] = 'dashed' plt.figure(1, figsize=(10,6)) plt.figure(2, figsize=(10,6)) j = 0 for i in rrs: run = runs.get(i) k = run.spectra.get('k')[1:] GWs_stat_sp = run.spectra.get('GWs_stat_sp') t = run.ts.get('t')[1:] indst = np.argsort(t) t = t[indst] EEGW = run.ts.get('EEGW')[1:][indst] if run.turb == 'm': EEM = run.ts.get('EEM')[1:][indst] if run.turb == 'k': EEM = run.ts.get('EEK')[1:][indst] plt.figure(1) plt.plot(t, EEGW, color=col[j], lw=.8, ls=ls[j]) # text with run name if i=='ini1': plt.text(1.02, 5e-8, i, color=col[j]) if i=='ini2': plt.text(1.07, 5e-11, i, color=col[j]) if i=='ini3': plt.text(1.2, 6e-9, i, color=col[j]) if i=='hel1': plt.text(1.15, 2e-9, i, color=col[j]) if i=='hel2': plt.text(1.12, 7e-10, i, color=col[j]) if i=='ac1': plt.text(1.2, 1e-7, i, color=col[j]) plt.figure(2) plt.plot(t, EEM, color=col[j], lw=.8, ls=ls[j]) # text with run name if i=='ini1': plt.text(1.01, 8e-2, i, color=col[j]) if i=='ini2': plt.text(1.12, 3e-3, i, color=col[j]) if i=='ini3': plt.text(1.01, 9e-3, i, color=col[j]) if i=='hel1': plt.text(1.15, 1.3e-2, i, color=col[j]) if i=='hel2': plt.text(1.02, 1e-3, i, color=col[j]) if i=='ac1': plt.text(1.17, 1.5e-3, i, color=col[j]) j += 1 plt.figure(1) plt.yscale('log') plt.xlabel('$t$') plt.xlim(1, 1.25) plt.ylim(2e-11, 2e-7) plt.ylabel(r'$\Omega_{\rm GW}$') plot_sets.axes_lines() if save: plt.savefig('plots/OmGW_vs_t.pdf', bbox_inches='tight') if not show: plt.close() plt.figure(2) plt.yscale('log') plt.xlim(1, 1.25) plt.ylim(5e-4, 2e-1) plt.xlabel('$t$') plt.ylabel(r'$\Omega_{\rm M, K}$') plot_sets.axes_lines() if save: plt.savefig('plots/OmM_vs_t.pdf', bbox_inches='tight') if not show: plt.close()
def plot_PGW_vs_PM(runs, save=True): """ Function that generates the plot of the total GW polarization PGW as a function of the total fractional helicity of the sourcing magnetic PM or velocity PK field. It corresponds to figure 6 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary that includes the run variables save -- option to save the figure in plots/PGW_vs_PM.pdf' (default True) """ plt.figure(figsize=(12, 8)) for i in runs: run = runs.get(i) k = run.spectra.get('k') EGW = run.spectra.get('EGW_stat_sp') HGW = run.spectra.get('helEGW_stat_sp') t = run.spectra.get('t_mag') indt = 0 EM = run.spectra.get('mag')[indt, :] HM = run.spectra.get('helmag_comp')[indt, :] PM = np.trapz(HM, k) / np.trapz(EM, k) PGW = np.trapz(HGW, k[1:]) / np.trapz(EGW, k[1:]) if 'i' in i: plt.plot(abs(PM), abs(PGW), 'o', color='blue') else: plt.plot(abs(PM), abs(PGW), 'x', color='red') col = assign_col(i) if col == 'black': sig = 0 if col == 'green': sig = 0.1 if col == 'darkgreen': sig = 0.3 if col == 'orange': sig = 0.5 if col == 'darkorange': sig = 0.7 if col == 'red' or col == 'blue': sig = 1. if col == 'blue': col = 'red' eps = 2 * sig / (1 + sig**2) plt.vlines(eps, 0, 2 * eps / (1 + eps**2), color=col, ls='dashed', lw=0.5) plot_sets.axes_lines() plt.xlim(0, 1.05) plt.ylim(0, 1.1) plt.xlabel(r'$|{\cal P}_{\rm M}|$') plt.ylabel(r'$|{\cal P}_{\rm GW}|$') xx = np.linspace(0, 1.1) plt.plot(xx, xx, lw=.5, ls='dashed', color='black') plt.plot(xx, 2 * xx / (1 + xx**2), lw=.5, ls='dashed', color='black') plt.text(.06, .75, r'${\cal P}_{\rm GW}=2 {\cal P}_{\rm M}' + \ r'/\bigl(1 + {\cal P}_{\rm M}^2\bigr)$', fontsize=24, bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=.2')) plt.text(.3, .2, r'${\cal P}_{\rm GW}={\cal P}_{\rm M} = 2' + \ r'\sigma_{\rm M}/\bigl(1 + \sigma_{\rm M}^2\bigr)$', fontsize=24, bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=.2')) #plt.legend(fontsize=14) line_ini, = plt.plot([], [], 'o', color='blue', label='initial') line_forc, = plt.plot([], [], 'x', color='red', label='forcing (short)') hdls = [ line_ini, line_forc, ] plt.legend(handles=hdls, fontsize=24, loc='upper left', frameon=False) ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) if save: plt.savefig('plots/PGW_vs_PM.pdf', bbox_inches='tight')
def plot_PGW(runs, PPh='GW', type='ini', save=True): """ Function that plots the GW polarization spectra, averaging over times after the GW energy and helicity have entered stationary oscillatory stages (this needs to be previously computed and stored in the run variable, see initialize_JCAP_2021.py). It corresponds to figure 5 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary of variables run with spectral information type -- selects the types of runs to be plotted (default 'ini', other option is 'forc'), i.e., runs with an initial magnetic field ('ini') or runs in which the magnetic field is initially driven during the simulation ('forc') save -- option to save the figure in plots/PGW_'type'_sigma.pdf' (default True) """ plt.rcParams.update({ 'xtick.labelsize': 'xx-large', 'ytick.labelsize': 'xx-large', 'axes.labelsize': 'xx-large' }) if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1'] elif type == 'forc': RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg'] elif type == 'kin': RR = ['K0', 'K01_c', 'K03', 'K05', 'K1'] elif type == 'mag': RR = ['M0', 'M01_c', 'M03', 'M05', 'M1'] if PPh == 'GW': PP = 'GW' if PPh == 'h': PP = 'h' fig, ax = plt.subplots(figsize=(12, 10)) for i in RR: # select colors col = assign_col(i) run = runs.get(i) k = run.spectra.get('k')[1:] PGW = run.spectra.get('P' + PP + '_stat_sp') PGW_min = run.spectra.get('P' + PP + '_min_sp') PGW_max = run.spectra.get('P' + PP + '_max_sp') plt.plot(k, PGW, color=col, lw=2) plt.fill_between(k, PGW_min, PGW_max, alpha=0.3, color=col) for i in range(0, len(k)): plt.vlines(k[i], PGW_min[i], PGW_max[i], color=col, lw=0.6, ls='dashed') plot_sets.axes_lines() plt.xscale('log') plt.xlabel('$k$') plt.ylabel(r'${\cal P}_{\rm %s} (k)$' % PP) sigs = [] plt.xlim(120, 5e4) tp = 'forc' if type == 'forc': sigs = ['0.01', '-0.01', '0.3', '0.5', '0.7', '-1'] cols = ['black', 'black', 'darkgreen', 'orange', 'darkorange', 'blue'] plt.ylim(-1.15, 1.15) plt.yticks(np.linspace(-1, 1, 9)) if PPh == 'GW': xxs = [7e2, 7e2, 7e2, 8e3, 2.5e3, 7e2] yys = [.2, -.25, .4, .55, .9, -.9, -.9] plt.text(3e4, -0.9, '(b)', fontsize=30) else: xxs = [5e2, 5e2, 5e2, 4e3, 3e3, 5e2] yys = [.25, -.25, .5, .5, .7, -.8] plt.text(3e4, -0.9, '(d)', fontsize=30) else: if type == 'ini': tp = 'ini' sigs = ['0.1', '0.3', '0.5', '0.7', '1'] cols = ['green', 'darkgreen', 'orange', 'darkorange', 'red'] if PPh == 'GW': xxs = [1e4, 1e4, 1e4, 1e4, 1e3] yys = [.3, .5, .75, 1.05, 1.05] plt.text(3e4, -0.35, '(a)', fontsize=30) else: xxs = [1.5e4, 1.5e4, 1.5e4, 1.5e4, 1e3] yys = [0.05, 0.35, 0.62, 1.05, 1.05] plt.text(3e4, -0.35, '(c)', fontsize=30) else: line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \ line_s1, line_s1_neg, = get_lines_sig(tp) hdls = [ line_s1, line_s05, line_s03, line_s01, line_s0, ] plt.legend(handles=hdls, fontsize=24, loc='upper right', frameon=False) plt.xlim(120, 3e4) plt.ylim(-.5, 1.2) for i in range(0, len(sigs)): plt.text(xxs[i], yys[i], r'$\sigma_{\rm M}^{\rm %s}=%s$' % (tp, sigs[i]), fontsize=30, color=cols[i]) if save: plt.savefig('plots/P' + PPh + '_' + type + '_sigma.pdf', bbox_inches='tight')
def plot_helicity_vs_t(runs, type='ini', save=True): """ Function that generates the plot of the total magnetic or kinetic helicity as a function of time. It corresponds to figure 4 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary that includes the run variables type -- selects the types of runs to be plotted (default 'ini', other option is 'forc'), i.e., runs with an initial magnetic field ('ini') or runs in which the magnetic field is initially driven during the simulation ('forc') save -- option to save the figure in plots/sigmaM_vs_t_'type'.pdf' (default True) """ if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1'] elif type == 'forc': RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg'] elif type == 'kin': RR = ['K0', 'K01_c', 'K03', 'K05', 'K1'] elif type == 'mag': RR = ['M0', 'M01_c', 'M03', 'M05', 'M1'] plt.figure(figsize=(12, 8)) for i in RR: run = runs.get(i) col = assign_col(i) if run.turb == 'm': sp = 'mag' if run.turb == 'k': sp = 'kin' t = np.array(run.spectra.get('t_hel' + sp), dtype='float')[:, 0] t2 = run.spectra.get('t_' + sp) EM = np.array(run.spectra.get(sp), dtype='float') HkM = run.spectra.get('hel' + sp + '_comp') k = run.spectra.get('k') EMs_mean = np.trapz(EM, k, axis=1) HMs_mean = np.trapz(HkM, k, axis=1) EMs_mean = np.interp(t, t2, EMs_mean) eps = abs(HMs_mean) / EMs_mean plt.plot(t - 1, eps, '.', color=col) if col == 'black': sig = 0 if col == 'green': sig = 0.1 if col == 'darkgreen': sig = 0.3 if col == 'orange': sig = 0.5 if col == 'darkorange': sig = 0.7 if col == 'red' or col == 'blue': sig = 1. eps = 2 * sig / (1 + sig**2) plt.hlines(eps, 1e-5, 5, color=col, ls='dashed', lw=0.5) if type == 'ini': tp = 'ini' else: tp = 'forc' #line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \ # line_s1, line_s1_neg, = get_lines_sig(tp) #hdls1 = [line_s001, line_s01, line_s03, line_s05, line_s07, line_s1,] #plt.legend(handles=hdls1, fontsize=24, loc='center left') MM = 'M' if type == 'kin': MM = 'K' sig_s = r'$\sigma_{\rm %s}^{\rm %s} = $' % (MM, tp) if type != 'forc': plt.text(2.5e-3, .12, sig_s + ' 0.1', color='green', fontsize=24) if type != 'ini': plt.text(2.5e-3, -.08, sig_s + ' 0', color='black', fontsize=24) else: plt.text(2.5e-3, .04, sig_s + ' $\pm 0.01$', color='black', fontsize=24) plt.text(2.5e-3, .47, sig_s + ' 0.3', color='darkgreen', fontsize=24) plt.text(2.5e-3, .72, sig_s + ' 0.5', color='orange', fontsize=24) if type == 'ini' or type == 'forc': plt.text(2.5e-3, .86, sig_s + ' 0.7', color='darkorange', fontsize=24) if type != 'forc': plt.text(2.5e-3, 1.04, sig_s + ' $1$', color='red', fontsize=24) else: plt.text(2.5e-3, 1.04, sig_s + ' $-1$', color='blue', fontsize=24) plot_sets.axes_lines() plt.xscale('log') plt.xlim(2e-3, 5e-1) plt.ylim(-.1, 1.13) if type == 'mag' or type == 'kin': plt.ylim(-.15, 1.13) plt.xlim(2e-3, 1.5e0) plt.xlabel('$\delta t=t-1$') plt.ylabel(r'$|{\cal P}_{\rm M}(t)|$') plt.yticks(np.linspace(0, 1, 5)) if save: plt.savefig('plots/sigmaM_vs_t_' + type + '.pdf', bbox_inches='tight')
def plot_Xi_sensitivity(XiPLSa, XiPLSb, XiPLSa_Tai, XiPLSb_Tai, XiPLS_comb, SNR=10, T=4, save=True): """ Function that generates the plot of LISA and Taiji GW energy density polarization sensitivities and PLS. It corresponds to right panel of figure 16 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: XiPLSa -- polarization PLS of the dipole response function of LISA with beta_max = 2 for T = 1yr and SNR = 1 XiPLSb -- polarization PLS of the dipole response function of LISA with beta_max = 3 for T = 1yr and SNR = 1 XiPLSa_Tai -- polarization PLS of the dipole response function of Taiji with beta_max = 2 for T = 1yr and SNR = 1 XiPLSb_Tai -- polarization PLS of the dipole response function of Taiji with beta_max = 3 for T = 1yr and SNR = 1 XiPLS_comb -- polarization PLS of the LISA-Taiji network for T = 1yr and SNR = 1 SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10) T -- duration of the observations for the plotted PLS in years (default 4) save -- option to save the figure in "plots/Xi_LISA_Taiji.pdf" (default True) """ fact = SNR / np.sqrt(T) fig, ax0 = plt.subplots(figsize=(12, 10)) #plt.rc('font', size=18) plt.plot(fs, XiSAE, color='blue') plt.plot(fs, XiSCD, color='blue', ls='-.') gg = np.where(XiS_comb < 1e5) plt.plot(fs[gg], XiS_comb[gg], color='blue', lw=.6) plt.plot(fs, XiPLSa * fact, color='green') plt.plot(fs, XiPLSb * fact, color='green') plt.plot(fs, XiPLSa_Tai * fact, color='green', ls='-.') plt.plot(fs, XiPLSb_Tai * fact, color='green', ls='-.') plt.plot(fs, XiPLS_comb * fact, color='green', lw=.6) line_XiPLS, = ax0.plot([], [], color='green', label=r'$\Xi_{\rm PLS}^{\rm AE}$') line_XiPLS_Tai, = ax0.plot([], [], color='green', ls='-.', label=r'$\Xi_{\rm PLS}^{\rm CD}$') line_XiPLS_comb, = ax0.plot([], [], color='green', lw=.8, label=r'$\Xi_{\rm PLS}^{\rm comb}$') line_XiSA, = ax0.plot([], [], color='blue', label=r'$\Xi_{\rm s}^{\rm AE}$') line_XiSC, = ax0.plot([], [], color='blue', ls='-.', label=r'$\Omega_{\rm s}^{\rm CD}$') line_XiS_comb, = ax0.plot([], [], color='blue', lw=.8, label=r'$\Xi_{\rm s}^{\rm comb}$') handles = [line_XiSA, line_XiSC, line_XiS_comb] lgd1 = ax0.legend(handles=handles, loc='lower right', fontsize=28, frameon=False) handles2 = [line_XiPLS, line_XiPLS_Tai, line_XiPLS_comb] lgd2 = ax0.legend(handles=handles2, loc='lower left', fontsize=28, frameon=False) ax0.add_artist(lgd1) #plt.legend(fontsize=30, loc='lower right', frameon=False) plt.xlabel(r'$f$ [Hz]') plt.ylabel(r'$h_0^2\, \Xi_{\rm s} (f)$') plt.xscale('log') plt.yscale('log') plt.ylim(1e-14, 1e-2) plt.xlim(1e-5, 1e0) plot_sets.axes_lines() plt.text(1e-1, 8e-9, r'$\beta_{\rm max}=2$', color='green', fontsize=30) plt.text(9e-2, 6e-4, r'$\beta_{\rm max}=3$', color='green', fontsize=30) ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) plt.yticks(np.logspace(-14, -2, 7)) plt.xticks(np.logspace(-5, 0, 6)) if save: plt.savefig('plots/Xi_LISA_Taiji.pdf', bbox_inches='tight')
def plot_EGW_EM_vs_k(runs, rr='ini2', save=True, show=True): """ Function that generates the plot of the magnetic spectrum EM (k) = Omega_M(k)/k at the initial time of turbulence generation and the GW spectrum EGW (k) = Omega_GW(k)/k, averaged over oscillations in time. It corresponds to figure 1 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables rr -- string that selects which run to plot (default 'ini2') save -- option to save the resulting figure as plots/EGW_EM_vs_k_'name_run'.pdf' (default True) show -- option to show the resulting figure (default True) """ plt.figure(figsize=(10,6)) plt.xscale('log') plt.yscale('log') plt.xlim(120, 6e4) plt.ylim(1e-19, 1e-4) plt.xlabel('$k$') plt.ylabel(r'$\Omega_{\rm GW}(k)/k$ and $\Omega_{\rm M}(k)/k$', fontsize=20) run = runs.get(rr) # plot the averaged over times GW spectrum GWs_stat_sp = run.spectra.get('EGW_stat_sp') k = run.spectra.get('k')[1:] plt.plot(k, GWs_stat_sp, color='black') # plot magnetic spectrum at the initial time mag = run.spectra.get('mag')[0, 1:] plt.plot(k, mag, color='black') # plot k^4 line k0 = np.logspace(np.log10(150), np.log10(500), 5) plt.plot(k0, 1e-9*(k0/100)**4, color='black', ls='-.', lw=.7) plt.text(300, 8e-9, r'$\sim\!k^4$', fontsize=20) # plot k^(-5/3) line k0 = np.logspace(np.log10(2000), np.log10(8000), 5) plt.plot(k0, 1e-5*(k0/1000)**(-5/3), color='black', ls='-.', lw=.7) plt.text(5e3, 1.6e-6, r'$\sim\!k^{-5/3}$', fontsize=20) # plot k^(-11/3) line k0 = np.logspace(np.log10(3000), np.log10(30000), 5) plt.plot(k0, 1e-12*(k0/1000)**(-11/3), color='black', ls='-.', lw=.7) plt.text(1e4, 5e-16, r'$\sim\!k^{-11/3}$', fontsize=20) plt.text(1500, 1e-16, r'$\Omega_{\rm GW} (k)/k$', fontsize=20) plt.text(800, 5e-8, r'$\Omega_{\rm M} (k)/k$', fontsize=20) ax = plt.gca() ax.set_xticks([100, 1000, 10000]) ytics = 10**np.array(np.linspace(-19, -5, 7)) ytics2 = 10**np.array(np.linspace(-19, -5, 15)) yticss = ['$10^{-19}$', '', '$10^{-17}$', '', '$10^{-15}$', '', '$10^{-13}$', '', '$10^{-11}$', '', '$10^{-9}$', '', '$10^{-7}$', '', '$10^{-5}$'] ax.set_yticks(ytics2) ax.set_yticklabels(yticss) plot_sets.axes_lines() ax.tick_params(pad=10) if save: plt.savefig('plots/EGW_EM_vs_k_' + run.name_run + '.pdf', bbox_inches='tight') if not show: plt.close()
def plot_OmGW_vs_f(runs, type='ini', T=1e5 * u.MeV, g=100, SNR=10, Td=4, OmM=.1, Xi=False, save=True): """ Function that generates the plot of the GW energy density frequency spectra at present time compared to the LISA, Taiji, BBO, and DECIGO sensitivities and power law sensitivities (PLS). It produces figure 11-13 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary that includes the run variables type -- selects the types of runs to be plotted (default 'ini', other option is 'forc'), i.e., runs with an initial magnetic field ('ini') or runs in which the magnetic field is initially driven during the simulation ('forc') T -- temperature scale (in natural units) at the time of turbulence generation (default 100 GeV, i.e., electroweak scale) g -- number of relativistic degrees of freedom at the time of turbulence generation (default 100, i.e., electroweak scale) SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10) Td -- duration of the mission (in years) of the resulting PLS (default 4) save -- option to save the resulting figure as plots/'OmGW'_'type'_detectors_'Om'.pdf (default True) where 'OmGW' = OmGW or XiGW (for Xi False and True, respectively), 'Om' = OmM005 or OmM01, and 'type' is 'ini' or 'forc' """ # read LISA and Taiji sensitivities CWD = os.getcwd() os.chdir('..') if Xi: fs, LISA_Om, LISA_OmPLS, LISA_Xi, LISA_XiPLS = \ inte.read_sens(SNR=SNR, T=Td, Xi=True) fs_Tai, Taiji_Om, Taiji_OmPLS, Taiji_Xi, Taiji_XiPLS = \ inte.read_sens(SNR=SNR, T=Td, interf='Taiji', Xi=True) fs_comb, LISA_Taiji_Xi, LISA_Taiji_XiPLS = \ inte.read_sens(SNR=SNR, T=Td, interf='comb') fs_comb = fs_comb * u.Hz else: fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td) fs_Tai, Taiji_Om, Taiji_OmPLS = inte.read_sens(SNR=SNR, T=Td, interf='Taiji') dir = 'detector_sensitivity' f_DECIGO, DECIGO_OmPLS = inte.read_csv(dir, 'DECIGO_PLS_SNR10') ff_D = np.logspace(np.log10(f_DECIGO[0]), np.log10(f_DECIGO[-1]), 100) DECIGO_OmPLS = 10**np.interp(ff_D, f_DECIGO, np.log10(DECIGO_OmPLS)) f_DECIGO = ff_D * u.Hz f_BBO, BBO_OmPLS = inte.read_detector_PLIS_Schmitz(det='BBO', SNR=SNR, T=Td) f_BBO = f_BBO * u.Hz fs = fs * u.Hz fs_Tai = fs_Tai * u.Hz os.chdir(CWD) # internal function to compute f, OmGW as present time observables def shift_Omega(run, T, g, ratio, Xi, sp='stat'): hel = '' if Xi: hel = 'hel' EGW = np.array(run.spectra.get(hel + 'EGW_' + sp + '_sp'), dtype='float') * ratio**2 k = run.spectra.get('k')[1:] OmGW = EGW * k f, OmGW = cosmoGW.shift_OmGW_today(k, OmGW, T, g) return f, OmGW plt.rcParams.update({ 'xtick.labelsize': 'xx-large', 'ytick.labelsize': 'xx-large', 'axes.labelsize': 'xx-large' }) if type == 'ini': RR = ['i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1'] elif type == 'forc': RR = ['f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg'] elif type == 'kin': RR = ['K0', 'K01_c', 'K03', 'K05', 'K1'] elif type == 'mag': RR = ['M0', 'M01_c', 'M03', 'M05', 'M1'] fig, ax = plt.subplots(figsize=(12, 10)) for i in RR: # select colors col = assign_col(i) run = runs.get(i) ratio = OmM / run.Ommax f, OmGW = shift_Omega(run, T, g, ratio, Xi, sp='stat') _, OmGW_min = shift_Omega(run, T, g, ratio, Xi, sp='min') _, OmGW_max = shift_Omega(run, T, g, ratio, Xi, sp='max') plt.plot(f, abs(OmGW), color=col, lw=3) #if 'i_s1' not in i: #if type == 'ini' or type == 'forc': plt.fill_between(f, OmGW_min, OmGW_max, alpha=0.1, color=col) for i in range(0, len(f)): plt.vlines(f.value[i], OmGW_min[i], OmGW_max[i], color=col, lw=0.6, ls='dashed') if type == 'ini': tp = 'ini' else: tp = 'forc' line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \ line_s1, line_s1_neg, = get_lines_sig(tp) if type == 'ini': hdls = [ line_s01, line_s03, line_s05, line_s07, line_s1, ] elif type == 'forc': hdls = [ line_s001, line_s03, line_s05, line_s07, line_s1_neg, ] else: hdls = [ line_s0, line_s01, line_s03, line_s05, line_s1, ] plt.legend(handles=hdls, fontsize=24, loc='upper right', framealpha=1) Om = '0.1' if OmM == .05: Om = '0.05' xb = 2e-3 yb = 8e-11 if Xi: xb = 1e-3 yb = 1e-17 MM = 'M' if type == 'kin': MM = 'K' plt.text(xb, yb, r'${\cal E}^{\rm max}_{\rm %s} = %s$' % (MM, Om), fontsize=30, bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=.5')) if type == 'ini': xB = 1.2e-2 yB = 1e-16 xD = 2e-3 yD = 6e-16 if OmM == 0.1: pan = '(a)' else: pan = '(c)' else: xB = 3e-2 yB = 3e-17 xD = 2.5e-2 yD = 1e-15 if OmM == 0.1: pan = '(b)' else: pan = '(d)' if type == 'kin': pan = '(a)' if type == 'mag': pan = '(b)' if Xi: plt.plot(fs, LISA_XiPLS, color='lime', ls='-.', lw=1) plt.text(1.1e-3, 5e-11, 'LISA', fontsize=30, color='lime') plt.plot(fs_Tai, Taiji_XiPLS, color='crimson', ls='-.', lw=1) plt.text(1e-2, 4e-11, 'Taiji', fontsize=30, color='crimson') plt.plot(fs_comb, LISA_Taiji_XiPLS, color='navy', ls='-.', lw=1) plt.text(1e-2, 2e-13, r'LISA--Taiji', fontsize=30, color='navy') else: plt.plot(fs, LISA_OmPLS, color='lime', ls='-.', lw=1) plt.text(7e-3, 4e-12, 'LISA', fontsize=30, color='lime') plt.plot(fs_Tai, Taiji_OmPLS, color='crimson', ls='-.', lw=1) plt.text(1.3e-2, 1e-13, 'Taiji', fontsize=30, color='crimson') plt.plot(f_BBO, BBO_OmPLS, color='navy', ls='-.', lw=1) plt.text(xB, yB, 'BBO', fontsize=30, color='navy') plt.plot(f_DECIGO, DECIGO_OmPLS, color='royalblue', ls='-.', lw=1) plt.text(xD, yD, 'DECIGO', fontsize=30, color='royalblue') plt.text(4e-4, 4e-18, pan, fontsize=30) plot_sets.axes_lines() plt.xscale('log') plt.yscale('log') plt.xlim(3e-4, 2e-1) plt.ylim(1e-18, 1e-8) plt.xlabel('$f$ [Hz]') if Xi: plt.ylabel(r'$h_0^2 |\Xi_{\rm GW} (f)|$') else: plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$') Om_save = 'OmM01' if OmM == 0.05: Om_save = 'OmM005' OmGW_s = 'OmGW' if Xi: OmGW_s = 'XiGW' if save: plt.savefig('plots/%s_%s_detectors_%s.pdf' % (OmGW_s, type, Om_save), bbox_inches='tight')
def plot_efficiency(runs, save=True): """ Function that generates the plot of the GW production efficiency for different runs as a function of time. It corresponds to figure 10 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary that includes the run variables save -- option to save the figure in plots/OmGW_efficiency_vs_t.pdf' (default True) """ plt.figure(figsize=(12, 8)) RR = [ 'i_s01', 'i_s03', 'i_s05', 'i_s07', 'i_s1', 'f_s001', 'f_s001_neg', 'f_s03', 'f_s05', 'f_s07', 'f_s1_neg', 'M0', 'M01_c', 'M03', 'M05', 'M1', 'ini1', 'ini2', 'ini3', 'hel1', 'hel2', 'hel3', 'hel4', 'noh1', 'noh2', 'ac1', 'ac2', 'ac3' ] for i in RR: # select colors col = assign_col(i) run = runs.get(i) t = run.ts.get('t') EGW = run.ts.get('EEGW') if run.turb == 'm': Om = run.OmMmax kf = run.kfM if run.turb == 'k': Om = run.OmKmax kf = run.kfK if abs(kf - 510.9) < 10 or 'M' in i: kf = 708 if abs(kf - 5999) < 100: kf = 7000 lww = 1. ls = 'solid' if 'M' in i: lww = .6 if 'ac' in i or 'hel' in i: lww = .8 ls = 'dotted' if 'ini' in i or 'noh' in i: lww = .8 ls = 'dotted' plt.plot(t - 1, np.sqrt(EGW) / Om * kf, color=col, ls=ls, lw=lww) line_s0, line_s001, line_s01, line_s03, line_s05, line_s07, \ line_s1, line_s1_neg, = get_lines_sig('') hdls1 = [ line_s001, line_s01, line_s03, line_s05, line_s07, line_s1, ] plt.text(.2, np.sqrt(.4), 'initial') plt.text(.08, 3.1, 'forcing (short)') plt.text(.007, 6, 'forcing (short, $k_*\sim 60$)') plt.text(1.2, np.sqrt(30), 'forcing (long)') plt.text(2e-1, 10, 'acoustic') plt.legend(handles=hdls1, fontsize=24, framealpha=1) plot_sets.axes_lines() plt.xlim(6e-3, 4) plt.ylim(1e-1, 2e1) plt.xlabel('$\delta t=t-1$') plt.ylabel( r'$k_*\, \Omega_{\rm GW}^{1/2} (t)/{\cal E}_{\rm M,K}^{\rm max}$') plt.yscale('log') plt.xscale('log') if save: plt.savefig('plots/OmGW_efficiency_vs_t.pdf', bbox_inches='tight')
def plot_MAC(save=True, log=False): """ Function that generates the plot of the helical (V Stokes parameter) monopole responses of the cross-correlated channels of the LISA-Taiji network. It corresponds to figure 18 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: save -- option to save the figure in "plots/Mcross_LISA_Taiji.pdf" (default True) log -- option to plot loglog with absolute values of the response functions (default False) """ plt.figure(figsize=(12, 8)) #plt.rc('font', size=20) lg = '' if log: MAC = abs(M_AC) MAD = abs(M_AD) MEC = abs(M_ED) MED = abs(M_ED) MED_I = abs(M_ED_I) plt.xscale('log') plt.yscale('log') lg = '_log' else: MAC = M_AC MAD = M_AD MEC = M_EC MED = M_ED MED_I = M_ED_I plt.plot(fs, MAC, color='black', label=r'${\cal M}^V_{\rm AC}$') plt.plot(fs, MAD, color='blue', ls='dotted', label=r'${\cal M}^V_{\rm AD}$') plt.plot(fs, MEC, color='red', ls='-.', label=r'${\cal M}^V_{\rm EC}$') plt.plot(fs, MED, color='green', ls='--', label=r'${\cal M}^V_{\rm ED}$') gg = np.where(abs(MED_I) > 1e-48) plt.plot(fs[gg], MED_I[gg], color='purple', alpha=.8, label=r'${\cal M}^I_{\rm ED}$') plt.legend(fontsize=18, frameon=False) plt.xlabel('$f$ [Hz]') plt.ylabel(r'${\cal M} (f)$') plt.xscale('log') if log: plt.xlim(1e-4, 4e-2) plt.ylim(1e-4, 2e-1) else: plt.xlim(3e-5, 4e-2) plt.ylim(-0.08, 0.08) plt.yticks(np.linspace(-.075, .075, 7)) plot_sets.axes_lines() if save: plt.savefig('plots/Mcross_LISA_Taiji' + lg + '.pdf', bbox_inches='tight')
def plot_Xi_sensitivity_dipole(XiPLSa, XiPLSb, XiPLSc, XiPLSd, XiPLSe, XiPLSf, XiPLSg, XiPLS0, XiPLS_comb, interf='LISA', SNR=10, T=4, save=True): """ Function that generates the plot of the GW energy density polarization PLS for different values of beta_max. It corresponds to figure 17 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: XiPLSa -- polarization PLS of the dipole response function of LISA with beta_max = 2 for T = 1yr and SNR = 1 XiPLSb -- polarization PLS of the dipole response function of LISA with beta_max = 3 for T = 1yr and SNR = 1 XiPLSc -- polarization PLS of the dipole response function of LISA with beta_max = 3.7 for T = 1yr and SNR = 1 XiPLSd -- polarization PLS of the dipole response function of LISA with beta_max = 3.95 for T = 1yr and SNR = 1 XiPLSe -- polarization PLS of the dipole response function of LISA with beta_max = 3.999 for T = 1yr and SNR = 1 XiPLSf -- polarization PLS of the dipole response function of LISA with beta_max = 3.999999 for T = 1yr and SNR = 1 XiPLSg -- polarization PLS of the dipole response function of LISA with beta values in (-20, 0)U(5, 20) for T = 1yr and SNR = 1 XiPLS0 -- polarization PLS of the dipole response function of LISA omitting 1/(1 - beta/4) term for T = 1yr and SNR = 1 XiPLS_comb -- polarization PLS of the LISA-Taiji network for T = 1yr and SNR = 1 interf -- selects interferometer (default 'LISA', also available 'Taiji') SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10) T -- duration of the observations for the plotted PLS in years (default 4) save -- option to save the figure in "plots/Xi_PLS_interf.pdf" (default True) """ import pandas as pd fact = SNR / np.sqrt(T) plt.figure(figsize=(12, 10)) if interf == 'LISA': AE = 'AE' ybeta_a = 1.3e-8 ybeta_b = 1.5e-7 ybeta_c = 3e-8 ybeta_d = 1e-7 ybeta_e = 1e-8 ybeta_f = 3e-8 if interf == 'Taiji': AE = 'CD' ybeta_a = 3e-9 ybeta_b = 3.5e-8 ybeta_c = 8e-9 ybeta_d = 3e-8 ybeta_e = 2.5e-9 ybeta_f = 6e-9 # plot PLS using dipole for different beta_max plt.plot(fs, XiPLSa * fact, color='blue', lw=1, label=r'$\Xi_{\rm PLS}^{\rm %s}$' % AE) plt.plot(fs, XiPLSb * fact, color='blue', lw=.8, ls='-.') plt.plot(fs, XiPLSc * fact, color='blue', lw=.8, ls='-.') plt.plot(fs, XiPLSd * fact, color='blue', lw=.8, ls='-.') plt.plot(fs, XiPLSe * fact, color='blue', lw=.8, ls='-.') plt.plot(fs, XiPLSf * fact, color='blue', lw=.8, ls='-.') # plot PLS using dipole ignoring 1/abs(1 - beta/4) term plt.plot(fs, XiPLS0 * fact, color='red', lw=.8, label=r'$\Xi_{\rm PLS}^{0, {\rm %s}}$' % AE) # plot PLS using LISA-Taiji combined network plt.plot(fs, XiPLS_comb * fact, color='green', lw=.8, label=r'$\Xi_{\rm PLS}^{\rm comb}$') # text with values of beta_max plt.text(2.5e-2, ybeta_a / 4, r'$\beta_{\rm max}=2$', color='blue', fontsize=22, bbox=dict(facecolor='white', edgecolor='none', boxstyle='round,pad=.2')) plt.text(3.2e-2, ybeta_b / 4, r'$\beta_{\rm max}=3$', color='blue', fontsize=22, bbox=dict(facecolor='white', edgecolor='none', boxstyle='round,pad=.2')) plt.text(5.3e-3, ybeta_c, r'$\beta_{\rm max}=3.7$', color='blue', fontsize=22, bbox=dict(facecolor='white', edgecolor='none', boxstyle='round,pad=.2')) plt.text(5.5e-3, ybeta_d * 3, r'$\beta_{\rm max}=3.95$', color='blue', fontsize=22, bbox=dict(facecolor='white', edgecolor='none', boxstyle='round,pad=.2')) plt.text(8e-4, ybeta_e, r'$\beta_{\rm max}=3.999$', color='blue', fontsize=22) plt.text(2e-4, ybeta_f * 5, r'$\beta_{\rm max}=3.999999$', fontsize=22, color='blue') plt.hlines(Xiflat * fact, 1e-3, 7e-2, color='blue', lw=.7) plt.hlines(Xiflat_Tai * fact, 1e-3, 7e-2, color='blue', ls='-.', lw=.7) plt.hlines(Xiflat_comb * fact, 1.e-3, 7e-2, color='green', lw=.8) plt.text(3e-2, 1.5e-10, r'$\Xi_{\rm flat}^{\rm AE}$', fontsize=28, color='blue') plt.text(3e-2, 1.7e-11, r'$\Xi_{\rm flat}^{\rm CD}$', fontsize=28, color='blue') plt.text(3e-2, 8e-13, r'$\Xi_{\rm flat}^{\rm comb}$', fontsize=28, color='green') # read reference Xi PLS from Ellis et al 2019 if interf == 'Taiji': dir = '../detector_sensitivity/' df = pd.read_csv(dir + 'XiPLS_Ellisetal19.csv') f = np.array(df['f']) ff = np.logspace(np.log10(f[0]), np.log10(f[-1]), 50) XiGW_PLS_LISA = np.array(df['Xi']) XiGW_PLS_LISA = np.interp(ff, f, XiGW_PLS_LISA) plt.plot(ff, XiGW_PLS_LISA, '.', color='blue', alpha=.4) plt.text(1.15e-2, 1.5e-10, r'$\sim\!f^5$', fontsize=22, color='blue') gg = np.where(XiPLSg > Xiflat_Tai * 1.01) hh = np.where(fs.value[gg] > 4e-3) plt.plot(fs[gg][hh], XiPLSg[gg][hh] * fact, color='blue', lw=.5) plt.legend(fontsize=28, loc='lower left', frameon=False) plt.xlabel(r'$f$ [Hz]') plt.ylabel(r'$h_0^2\, \Xi_{\rm PLS} (f)$') plt.xscale('log') plt.yscale('log') plt.ylim(1e-13, 1e-6) plt.xlim(1e-4, 1e-1) plot_sets.axes_lines() ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) plt.yticks(np.logspace(-13, -6, 8)) if save: plt.savefig('plots/Xi_PLS_' + interf + '.pdf', bbox_inches='tight')
def plot_OmGW_hc_vs_f_ini(runs, T=1e5*u.MeV, g=100, SNR=10, Td=4, save=True, show=True): """ Function that generates the plot of the GW energy density spectrum of initial runs (ini1, ini2, and ini3), compared to the LISA sensitivity and power law sensitivity (PLS). It corresponds to figure 4 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables T -- temperature scale (in natural units) at the time of turbulence generation (default 100 GeV, i.e., electroweak scale) g -- number of relativistic degrees of freedom at the time of turbulence generation (default 100, i.e., electroweak scale) SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10) Td -- duration of the mission (in years) of the resulting PLS (default 4) save -- option to save the resulting figure as plots/OmGW_vs_f_ini.pdf (default True) show -- option to show the resulting figure (default True) """ # read LISA and Taiji sensitivities CWD = os.getcwd() os.chdir('..') #f_LISA, f_LISA_Taiji, LISA_sensitivity, LISA_OmPLS, LISA_XiPLS, \ # Taiji_OmPLS, Taiji_XiPLS, LISA_Taiji_XiPLS = inte.read_sens() fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td) fs = fs*u.Hz os.chdir(CWD) # chose the runs to be shown rrs = ['ini1', 'ini2', 'ini3'] # chose the colors of each run col = ['black', 'red', 'blue'] plt.figure(1, figsize=(12,5)) plt.figure(2, figsize=(12,5)) j = 0 for i in rrs: run = runs.get(i) k = run.spectra.get('k')[1:] EGW_stat = run.spectra.get('EGW_stat_sp') f, OmGW_stat = cosmoGW.shift_OmGW_today(k, EGW_stat*k, T, g) OmGW_stat = np.array(OmGW_stat, dtype='float') hc_stat = cosmoGW.hc_OmGW(f, OmGW_stat) plt.figure(1) plt.plot(f, OmGW_stat, color=col[j], lw=.8) if i == 'ini1': plt.text(5e-2, 1.5e-15, i, color=col[j]) if i == 'ini2': plt.text(3e-2, 2e-17, i, color=col[j]) if i == 'ini3': plt.text(3e-3, 4e-17, i, color=col[j]) plt.figure(2) plt.plot(f, hc_stat, color=col[j], lw=.8) if i == 'ini1': plt.text(5e-2, 1.5e-24, i, color=col[j]) if i == 'ini2': plt.text(1e-2, 3e-24, i, color=col[j]) if i == 'ini3': plt.text(4e-3, 1e-24, i, color=col[j]) j += 1 plt.figure(1) plt.xscale('log') plt.yscale('log') plt.xlim(1e-4, 1e-1) plt.ylim(1e-19, 1e-9) plt.xlabel('$f$ [Hz]') plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$') #plt.plot(f_LISA, LISA_OmPLS, color='lime', ls='dashdot') #plt.plot(f_LISA, LISA_sensitivity, color='lime') plt.plot(fs, LISA_OmPLS, color='lime', ls='dashdot') plt.plot(fs, LISA_Om, color='lime') # plot f^(-8/3) line fs0 = np.logspace(-2.1, -1.5, 5) plt.plot(fs0, 3e-15*(fs0/2e-2)**(-8/3), color='black', ls='dashdot', lw=.7) plt.text(1e-2, 5e-16, '$\sim\!f^{-8/3}$') # plot f line fs0 = np.logspace(-3.45, -2.8, 5) plt.plot(fs0, 2e-13*(fs0/1e-3)**(1), color='black', ls='dashdot', lw=.7) plt.text(4e-4, 3e-13, '$\sim\!f$') ax = plt.gca() ytics2 = 10**np.array(np.linspace(-19, -9, 11)) yticss = ['', '$10^{-18}$', '', '$10^{-16}$', '', '$10^{-14}$', '', '$10^{-12}$', '', '$10^{-10}$', ''] ax.set_yticks(ytics2) ax.set_yticklabels(yticss) plot_sets.axes_lines() if save: plt.savefig('plots/OmGW_vs_f_ini.pdf', bbox_inches='tight') if not show: plt.close() plt.figure(2) plt.xscale('log') plt.yscale('log') plt.xlim(1e-4, 1e-1) plt.ylim(1e-25, 1e-20) plt.xlabel('$f$ [Hz]') plt.ylabel(r'$h_{\rm c}(f)$') LISA_hc_PLS = cosmoGW.hc_OmGW(fs, LISA_OmPLS) LISA_hc = cosmoGW.hc_OmGW(fs, LISA_Om) plt.plot(fs, LISA_hc_PLS, color='lime', ls='dashdot') plt.plot(fs, LISA_hc, color='lime') # plot f^(-1/2) line fs0 = np.logspace(-3.4, -2.6, 5) plt.plot(fs0, 8e-22*(fs0/1e-3)**(-1/2), color='black', ls='dashdot', lw=.7) plt.text(8e-4, 1.5e-21, '$\sim\!f^{-1/2}$') # plot f^(-7/3) line fs0 = np.logspace(-2, -1.4, 5) plt.plot(fs0, 1e-23*(fs0/2e-2)**(-7/3), color='black', ls='dashdot', lw=.7) plt.text(2e-2, 2e-23, '$\sim\!f^{-7/3}$') ax = plt.gca() ytics2 = 10**np.array(np.linspace(-25, -20, 6)) ax.set_yticks(ytics2) plot_sets.axes_lines() if save: plt.savefig('plots/hc_vs_f_ini.pdf', bbox_inches='tight') if not show: plt.close()
def plot_OmGW_hc_vs_f_driven(runs, T=1e5*u.MeV, g=100, SNR=10, Td=4, save=True, show=True): """ Function that generates the plot of the GW energy density spectrum of some of the initially driven runs (ac1, hel1, hel2, hel3, and noh1), compared to the LISA sensitivity and power law sensitivity (PLS). It corresponds to figure 6 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables T -- temperature scale (in natural units) at the time of turbulence generation (default 100 GeV, i.e., electroweak scale) g -- number of relativistic degrees of freedom at the time of turbulence generation (default 100, i.e., electroweak scale) SNR -- signal-to-noise ratio (SNR) of the resulting PLS (default 10) Td -- duration of the mission (in years) of the resulting PLS (default 4) save -- option to save the resulting figure as plots/OmGW_vs_f_driven.pdf (default True) show -- option to show the resulting figure (default True) """ # read LISA and Taiji sensitivities CWD = os.getcwd() os.chdir('..') #f_LISA, f_LISA_Taiji, LISA_sensitivity, LISA_OmPLS, LISA_XiPLS, \ # Taiji_OmPLS, Taiji_XiPLS, LISA_Taiji_XiPLS = inte.read_sens() fs, LISA_Om, LISA_OmPLS = inte.read_sens(SNR=SNR, T=Td) fs = fs*u.Hz os.chdir(CWD) # chose the runs to be shown rrs = ['ac1', 'hel1', 'hel2', 'hel3', 'noh1'] # chose the colors of each run col = ['black', 'red', 'blue', 'blue', 'blue'] # chose the line style for the plots ls = ['solid', 'solid', 'solid', 'dotted', 'dashed'] plt.figure(1, figsize=(12,5)) plt.figure(2, figsize=(12,5)) j = 0 for i in rrs: run = runs.get(i) k = run.spectra.get('k')[1:] EGW_stat = run.spectra.get('EGW_stat_sp') f, OmGW_stat = cosmoGW.shift_OmGW_today(k, EGW_stat*k, T, g) OmGW_stat = np.array(OmGW_stat, dtype='float') hc_stat = cosmoGW.hc_OmGW(f, OmGW_stat) plt.figure(1) # omit largest frequencies where there is not enough numerical accuracy if i == 'hel3': OmGW_stat = OmGW_stat[np.where(f.value<3e-2)] hc_stat = hc_stat[np.where(f.value<3e-2)] f = f[np.where(f.value<3e-2)] if i=='hel3' or i=='hel2' or i=='noh1' or i=='hel1': plt.plot(f, OmGW_stat, color=col[j], ls=ls[j], lw=.8, label=i) else: plt.plot(f, OmGW_stat, color=col[j], ls=ls[j], lw=.8) plt.text(5e-2, 2e-19, i, fontsize=20, color='black') plt.figure(2) if i=='hel3' or i=='hel2' or i=='noh1'or i=='hel1': plt.plot(f, hc_stat, color=col[j], ls=ls[j], lw=.8, label=i) else: plt.plot(f, hc_stat, color=col[j], ls=ls[j], lw=.8) plt.text(3e-3, 5e-22, i, color=col[j]) j += 1 plt.figure(1) plt.xscale('log') plt.yscale('log') plt.xlim(1e-4, 1e-1) plt.ylim(1e-26, 1e-9) plt.xlabel('$f$ [Hz]') plt.ylabel(r'$h_0^2 \Omega_{\rm GW} (f)$') plt.legend(loc='lower left', frameon=False, fontsize=20) plt.plot(fs, LISA_OmPLS, color='lime', ls='dashdot') plt.plot(fs, LISA_Om, color='lime') # plot f^(-5) line fk0 = np.logspace(-2.2, -1.6, 5) plt.plot(fk0, 1e-14*(fk0/1e-2)**(-5), color='black', ls='dashdot', lw=.7) plt.text(1.3e-2, 1e-14, '$\sim\!f^{-5}$') # plot f line fk0 = np.logspace(-3.3, -2.8, 5) plt.plot(fk0, 2e-16*(fk0/1e-3)**(1), color='black', ls='dashdot', lw=.7) plt.text(6e-4, 1e-17, '$\sim\!f$') ax = plt.gca() ytics2 = 10**np.array(np.linspace(-25, -9, 16)) yticss = ['$10^{-25}$', '', '$10^{-23}$', '', '$10^{-21}$', '', '$10^{-19}$','', '$10^{-17}$', '','$10^{-15}$','', '$10^{-13}$', '','$10^{-11}$',''] ax.set_yticks(ytics2) ax.set_yticklabels(yticss) plot_sets.axes_lines() if save: plt.savefig('plots/OmGW_vs_f_driven.pdf', bbox_inches='tight') if not show: plt.close() plt.figure(2) plt.xscale('log') plt.yscale('log') plt.xlim(1e-4, 1e-1) plt.ylim(1e-28, 1e-20) plt.xlabel('$f$ [Hz]') plt.ylabel(r'$h_{\rm c}(f)$') plt.legend(loc='lower left', frameon=False, fontsize=20) LISA_hc_PLS = cosmoGW.hc_OmGW(fs, LISA_OmPLS) LISA_hc = cosmoGW.hc_OmGW(fs, LISA_Om) plt.plot(fs, LISA_hc_PLS, color='lime', ls='dashdot') plt.plot(fs, LISA_hc, color='lime') # plot f^(-7/2) line fk0 = np.logspace(-2.2, -1.6, 5) plt.plot(fk0, 1e-23*(fk0/1e-2)**(-7/2), color='black', ls='dashdot', lw=.7) plt.text(1.3e-2, 1e-23, '$\sim\!f^{-7/2}$') # plot f^(-1/2) line fk0 = np.logspace(-3.3, -2.8, 5) plt.plot(fk0, 2e-23*(fk0/1e-3)**(-1/2), color='black', ls='dashdot', lw=.7) plt.text(6e-4, 3e-24, '$\sim\!f^{-1/2}$') ax = plt.gca() ytics2 = 10**np.array(np.linspace(-28, -20, 9)) ytics2 = 10**np.array(np.linspace(-28, -20, 9)) yticss = ['', '$10^{-27}$', '', '$10^{-25}$', '', '$10^{-23}$', '', '$10^{-21}$', ''] ax.set_yticks(ytics2) ax.set_yticklabels(yticss) plot_sets.axes_lines() if save: plt.savefig('plots/hc_vs_f_driven.pdf', bbox_inches='tight') if not show: plt.close()
def plot_EGW_vs_k_initial_ts(runs, rr='ini2', save=True, show=True): """ Function that generates the plot of the amplitudes of the GW energy density at the first time step, to show the evolution from k^2 to k^0 slopes. It corresponds to a plot generated for a presentation, related to the work A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables rr -- string that selects which run to plot (default 'ini2') save -- option to save the resulting figure as plots/EGW_vs_k_initial_ts.pdf (default True) show -- option to show the resulting figure (default True) """ run = runs.get(rr) EGW = run.spectra.get('EGW')[:, 1:] k = run.spectra.get('k')[1:] t = run.spectra.get('t_GWs') max_sp_EGW = run.spectra.get('EGW_max_sp') plt.figure(figsize=(10,6)) plt.xscale('log') plt.yscale('log') plt.xlabel('$k$') plt.ylabel(r'$\Omega_{\rm GW} (k)/k$') # initial time step GW spectrum plt.plot(k, EGW[0, :], color='black', lw=.7, ls='dashed') # local maximum amplitudes of oscillations at next time step kmax, EGWmax = sp.local_max(k, EGW[1, :]) plt.plot(kmax, EGWmax, color='black', lw=.7, ls='dashed') plt.plot(k[:10], EGW[1, :10], color='black', lw=.7, ls='dashed') # maximum over all times of the GW energy density (amplitude of the # oscillations) plt.plot(k, max_sp_EGW, color='black', lw=1.5) # 6th time step kmax, EGWmax = sp.local_max(k, EGW[5, :]) plt.plot(kmax, EGWmax, color='black', lw=.7, ls='dashed') plt.plot(k[:4], EGW[5, :4], color='black', lw=.7, ls='dashed') # line k^(2.5) k0s = np.linspace(250, 1000) plt.plot(k0s, 3e-19*(k0s/100)**2.5, color='black', ls='dashdot', lw=.7) plt.text(500, 5e-18, '$k^{2.5}$', fontsize=20) # line k^(1/2) k0s = np.linspace(200, 800) plt.plot(k0s, 7e-14*(k0s/100)**0.5, color='black', ls='dashdot', lw=.7) plt.text(500, 3e-13, '$k^{0.5}$', fontsize=20) # line k^(-11/3) k0s = np.linspace(3000, 10000) plt.text(5000, 1e-14, '$k^{-11/3}$', fontsize=20) plt.plot(k0s, 1e-14*(k0s/4e3)**(-11/3), color='black', ls='dashdot', lw=.7) plt.text(3000, 1e-17, r'$t-1=4 \times 10^{-5}$', fontsize=14) plt.text(250, 2e-15, '$t-1=10^{-3}$', fontsize=14) plt.text(130, 8e-15, r'$5 \times 10^{-3}$', fontsize=14) plt.ylim(1e-19, 2e-12) yticks = np.logspace(-19, -12, 8) ax = plt.gca() ax.set_yticks(yticks) plot_sets.axes_lines() ax.tick_params(axis='x', pad=12) if save: plt.savefig('plots/EGW_vs_k_initial_ts.pdf', bbox_inches='tight') if not show: plt.close()
def plot_OmGW_vs_OmMK(runs, save=True, show=True): """ Function that generates the plot of the total (saturated) GW energy density integrated over wave numbers as a function of the magnetic/kinetic energy density. It corresponds to figure 7 of A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. Arguments: runs -- dictionary that includes the run variables save -- option to save the resulting figure as plots/OmGW_vs_OmMK.pdf (default True) show -- option to show the resulting figure (default True) """ # chose the runs to be shown rrs = [s for s in runs] # chose the colors of each run col = ['darkorange', 'darkorange', 'lime', 'red', 'red', 'red', 'lime', 'red', 'red', 'blue', 'blue', 'blue'] plt.figure(figsize=(8,5)) plt.xscale('log') plt.yscale('log') plt.xlabel(r'$\Omega_{\rm M,K}^{\rm max}$') plt.ylabel(r'$\Omega_{\rm GW}^{\rm sat}$') plt.xlim(1e-3, 2e-1) plt.ylim(7e-12, 1e-7) j = 0 for i in runs: run = runs.get(i) if 'noh' in i: plt.scatter(run.Ommax, run.OmGWsat, edgecolors='red', facecolors='none') else: plt.plot(run.Ommax, run.OmGWsat, 'o', color=col[j]) j += 1 OmMs = np.logspace(-2.2, -.8) plt.plot(OmMs, 1.7e-6*OmMs**2, color='darkorange') OmMs = np.logspace(-2.5, -1.5) plt.plot(OmMs, 9e-6*OmMs**2, color='red') OmMs = np.logspace(-2.5, -1.7) plt.plot(OmMs, 1.5e-5*OmMs**2, color='red', ls='dashed', lw=.7) OmMs = np.logspace(-2.8, -1.8) plt.plot(OmMs, 3.5e-4*OmMs**2, color='blue') plot_sets.axes_lines() plt.yticks([1e-11, 1e-10, 1e-9, 1e-8, 1e-7]) plt.text(1.5e-2, 2e-10, 'ini', color='darkorange') plt.text(1.5e-2, 2e-10/2, '$i$=M', color='darkorange') plt.text(2e-2, 2e-8, 'hel', color='red') plt.text(2e-2, 2e-8/2, '$i$=M', color='red') plt.text(2e-3, 1e-8, 'ac', color='blue') plt.text(2e-3, 1e-8/2, '$i$=K', color='blue') plt.text(7e-3, 4e-9, '(ini3)', color='lime') plt.text(5e-3, 1.7e-11, '(hel4)', color='lime') plt.text(3.5e-3, 7e-10, '(noh)', color='red') if save: plt.savefig('plots/OmGW_vs_OmMK.pdf', bbox_inches='tight') if not show: plt.close()
def plot_Omega_sensitivity(OmPLS, OmPLS_Tai, OmPLS_comb, SNR=10, T=4, save=True): """ Function that generates the plot of LISA and Taiji GW energy density sensitivities and PLS. It corresponds to left panel of figure 16 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," submitted to JCAP, https://arxiv.org/abs/2107.05356. Arguments: OmPLS -- power law sensitivity (PLS) of LISA for T = 1yr and SNR = 1 OmPLS_Tai -- power law sensitivity (PLS) of Taiji for T = 1yr and SNR = 1 OmPLS_comb -- power law sensitivity (PLS) of the LISA-Taiji network for T = 1yr and SNR = 1 SNR -- signal-to-noise ratio (SNR) for the plotted PLS (default 10) T -- duration of the observations for the plotted PLS in years (default 4) save -- option to save the figure in "plots/Omega_LISA_Taiji.pdf" (default True) """ import pandas as pd fact = SNR / np.sqrt(T) fig, ax0 = plt.subplots(figsize=(12, 10)) line_OmPLS, = ax0.plot([], [], color='green', label=r'$\Omega_{\rm PLS}^{\rm A}$') line_OmPLS_Tai, = ax0.plot([], [], color='green', ls='-.', label=r'$\Omega_{\rm PLS}^{\rm C}$') line_OmPLS_comb, = ax0.plot([], [], color='green', lw=.8, label=r'$\Omega_{\rm PLS}^{\rm comb}$') line_OmSA, = ax0.plot([], [], color='blue', label=r'$\Omega_{\rm s}^{\rm A}$') line_OmSC, = ax0.plot([], [], color='blue', ls='-.', label=r'$\Omega_{\rm s}^{\rm C}$') line_OmS_comb, = ax0.plot([], [], color='blue', lw=.8, label=r'$\Omega_{\rm s}^{\rm comb}$') line_OmST, = ax0.plot([], [], color='orange', alpha=.5, label=r'$\Omega_{\rm s}^{\rm T}$') line_OmSS, = ax0.plot([], [], color='orange', ls='-.', alpha=.5, label=r'$\Omega_{\rm s}^{\rm S}$') line_OmS_ED_I, = ax0.plot([], [], color='purple', alpha=.5, label=r'$\Omega_{\rm s}^{\rm ED}$') handles = [line_OmSA, line_OmSC, line_OmS_comb] lgd1 = ax0.legend(handles=handles, loc='lower right', fontsize=28, frameon=False) handles2 = [line_OmST, line_OmSS, line_OmS_ED_I] lgd2 = ax0.legend(handles=handles2, loc='upper left', fontsize=28, frameon=False) handles3 = [line_OmPLS, line_OmPLS_Tai, line_OmPLS_comb] lgd3 = ax0.legend(handles=handles3, loc='lower left', fontsize=28, frameon=False) ax0.add_artist(lgd1) ax0.add_artist(lgd2) # plt.rc('font', size=30) plt.plot(fs, OmSA, color='blue') plt.plot(fs, OmST, color='orange', alpha=.5) plt.plot(fs, OmPLS * fact, color='green') plt.plot(fs, OmSC, '-.', color='blue') plt.plot(fs, OmSS, '-.', color='orange', alpha=.5) plt.plot(fs, OmPLS_Tai * fact, '-.', color='green') gg = np.where(abs(M_ED_I) > 1e-48) plt.plot(fs[gg], OmS_ED_I[gg], color='purple', alpha=.5) plt.plot(fs, OmS_comb, color='blue', lw=.8) plt.plot(fs, OmPLS_comb * fact, color='green', lw=.8) # Add reference PLS from Caprini et al 2019 dir = '../detector_sensitivity/' df = pd.read_csv(dir + 'OmegaPLS_Caprinietal19.csv') f = np.array(df['f']) ff = np.logspace(np.log10(f[0]), np.log10(f[-1]), 70) OmGW_PLS_LISA = np.array(df['Omega']) OmGW_PLS_LISA = np.interp(ff, f, OmGW_PLS_LISA) plt.plot(ff, OmGW_PLS_LISA, '.', color='green', alpha=.4) plot_sets.axes_lines() plt.ylim(1e-14, 1e-2) plt.yticks(np.logspace(-14, -2, 8)) plt.xlim(1e-5, 1e0) plt.xlabel('$f$ [Hz]') plt.ylabel(r'$h_0^2\,\Omega_{\rm s} (f)$') plt.xscale('log') plt.yscale('log') ax = plt.gca() ax.tick_params(axis='x', pad=20) ax.tick_params(axis='y', pad=10) plt.yticks(np.logspace(-14, -2, 7)) plt.xticks(np.logspace(-5, 0, 6)) if save: plt.savefig('plots/Omega_LISA_Taiji.pdf', bbox_inches='tight')
def plot_efficiency(runs, save=True, show=True, sqrt=False): """ Function that generates the plot of the total GW energy density compensated by EM^2/kf^2 (efficiency). It corresponds to the runs presented in A. Roper Pol, S. Mandal, A. Brandenburg, T. Kahniashvili, and A. Kosowsky, "Numerical simulations of gravitational waves from early-universe turbulence," Phys. Rev. D 102, 083512 (2020), https://arxiv.org/abs/1903.08585. This plot is analogous to figure 10 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources", https://arxiv.org/abs/2107.05356. Arguments: runs -- dictionary that includes the run variables save -- option to save the resulting figure as plots/efficiency.pdf or plots/efficiency_sqrt.pdf (if sqrt = True) (default True) show -- option to show the resulting figure (default True) sqrt -- option to plot the efficiency defined as the square root of the compensated GW energy density (default False) """ exp = 1 if sqrt: exp = 1/2 plt.figure(1, figsize=(12,8)) plt.xscale('log') plt.yscale('log') plt.xlim(6e-3, 1) plt.ylim(1e-1**exp, 2e2**exp) plt.xlabel('$\delta t = t - 1$') plt.ylabel(r'$q^2 (t) = k_*^2\, \Omega_{\rm GW}$' + \ r'$(t)/({\cal E}_{\rm M, K}^{\rm max})^2$') if sqrt: plt.ylabel(r'$q (t) = k_* \left[\Omega_{\rm GW} (t)\right]^{1/2}$' + \ r'$/{\cal E}_{\rm M, K}^{\rm max}$') for i in runs: # chose colors if 'ini' in i: col = 'green' elif 'hel4' in i: col = 'red' elif 'noh' in i: col = 'black' elif 'ac' in i: col = 'blue' else: col = 'orange' run = runs.get(i) t = run.ts.get('t') EGW = run.ts.get('EEGW') plt.plot(t-1, (EGW/run.Ommax**2*run.kf**2)**exp, color=col) plot_sets.axes_lines() plt.text(3e-1, 70**exp, 'acoustic', color='blue') plt.text(3e-1, 1.5**exp, 'initial', color='green') plt.text(1.3e-1, 2.8**exp, r'helical 1--3', color='orange') plt.text(3e-1, 15**exp, 'helical 4', color='red') plt.text(4e-1, 8.6**exp, 'non-helical', color='black') if save: if sqrt: plt.savefig('plots/efficiency_sqrt.pdf', bbox_inches='tight') else: plt.savefig('plots/efficiency.pdf', bbox_inches='tight') if not show: plt.close()
def plot_EM_EGW(run, save=True): """ Function that plots the magnetic energy and helicity spectra at the time of maximum magnetic energy density. It also plots the GW energy density and helicity spectra, averaging over times after the GW energy has entered a stationary oscillatory stage (this needs to be previously computed and stored in the run variable, see initialize_JCAP_2021.py). It corresponds to figures 1-3 of A. Roper Pol, S. Mandal, A. Brandenburg, and T. Kahniashvili, "Polarization of gravitational waves from helical MHD turbulent sources," https://arxiv.org/abs/2107.05356. Arguments: run -- variable run with spectral information save -- option to save the figure in plots/'name_run'EM_EGW.pdf' (default True) """ # auxiliary functions used in plot_EM_EGW def init_Ay2_Ax(N, Ay, Ax): return N, N * [Ay], N * [Ax] # chose indices to show power law fits and text with k^(a/b) for magnetic # spectrum EM(k) def indices_EM(nm, Ax, Ay): if 'i' in nm: inds_show = [0, 1, 4, 5, 6, 7, 8, 9, 10] inds_show_txt = [0, 6] Ay[0] *= 8 Ay[6] *= 2 if '3' in nm or '5' in nm: inds_show_txt = [0, 7] Ay[7] *= .5 if '5' in nm: Ay[0] *= 2 if nm == 'i_s1': inds_show_txt = [1, 7] Ay[1] *= 20 Ax[1] *= .7 Ay[7] *= .5 else: if '001' in nm: inds_show = [0, 1, 4, 6, 8, 9, 10, 11] inds_show_txt = [1, 4, 6, 10] Ay[1] *= 6 Ax[1] *= .7 Ay[4] *= 25 Ay[6] *= 2 Ay[10] *= 1 / 6000 else: inds_show = [0, 1, 5, 6, 7, 8, 9, 10, 11] inds_show_txt = [0, 5, 7, 10, 11] Ay[0] *= 5 Ay[5] *= 3.5 Ay[7] *= 1 / 10 Ay[10] *= 6e-5 Ay[11] *= 1e-6 Ax[11] *= .9 if '5' in nm: inds_show_txt = [1, 5, 7, 10, 11] Ay[1] *= 10 Ax[1] *= .8 Ay[10] *= 1 / 8 Ay[11] *= 1 / 5 if '7' in nm: inds_show_txt = [0, 5, 7, 9, 10] Ay[5] *= .5 Ay[7] *= 3e-1 Ay[9] *= 1e-4 Ay[10] *= 3e-2 if '1' in nm: inds_show_txt = [0, 5, 7, 9, 10] Ay[0] *= 2 Ax[0] *= .9 Ay[5] *= .3 Ay[7] *= 1e-1 Ay[9] *= 4e-5 Ay[10] *= 1e-2 Ax[10] *= 1.1 return inds_show, inds_show_txt, Ax, Ay # chose indices to show power law fits and text with k^(a/b) for magnetic # helicity spectrum HM(k) def indices_HM(nm, Ax, Ay): inds_show = [] inds_show_txt = [] if 'i' in nm: inds_show = [1, 4, 5, 6, 7, 8] inds_show_txt = [1] Ay[1] *= 80 #Ay[2] *= 100; Ax[2] *= .8 if '3' in nm or '5' in nm: inds_show = [0, 1, 4, 5, 6, 7, 8] inds_show_txt = [0, 1] if '3' in nm: Ay[0] *= 8 if '5' in nm: Ay[0] *= 5 else: if '001' not in nm: inds_show = [0, 4, 5, 6, 7, 8] inds_show_txt = [0, 4, 6, 8] Ay[0] *= 8 Ax[4] *= .7 Ay[6] *= 3e-4 Ay[8] *= 4e-7 Ax[8] *= .7 if '5' in nm: Ax[6] *= .7 Ay[6] *= 15 Ax[8] *= .7 Ay[8] *= 2 if '7' in nm: Ay[4] *= .5 Ax[6] *= .7 Ay[6] *= 7 Ax[8] *= .9 if '1' in nm: Ax[6] *= .7 Ay[6] *= 3 Ay[8] *= 2e-1 Ax[8] *= .8 return inds_show, inds_show_txt, Ax, Ay # chose indices to show power law fits and text with k^(a/b) for GW # spectrum EGW(k) def indices_EGW(nm, Ax, Ay): if 'i' in nm: inds_show = [0, 2, 4, 6, 7, 8, 9, 10] inds_show_txt = [0, 2, 4, 9] Ay[4] *= .6 Ay[9] *= 3e-4 if '5' in nm: inds_show_txt = [0, 2, 4, 7] Ay[7] *= 8e-3 if nm == 'i_s1': Ay[2] *= 1.8 Ay[4] *= 4 Ay2_HGW[3] *= 2.5 else: if '001' in nm: inds_show = [0, 2, 3, 5, 6, 7, 8, 9] inds_show_txt = [0, 2, 7] Ay[2] *= .5 Ay[7] *= 5e-5 else: inds_show = [0, 1, 2, 3, 6, 7, 8, 9, 10, 11] inds_show_txt = [0, 2, 8] Ay[2] *= .5 Ay[8] *= 2e-6 if '5' in nm: inds_show_txt = [0, 2, 7, 10] Ay[2] *= 1.5 Ay[7] *= 1e-5 Ay[10] *= 3e-10 if '7' in nm or '1' in nm: inds_show_txt = [0, 2, 7, 9] Ay[2] *= 2 Ay[7] *= 3e-6 Ay[9] *= 3e-9 return inds_show, inds_show_txt, Ax, Ay # chose indices to show power law fits and text with k^(a/b) for GW # helicity spectrum HGW(k) def indices_HGW(nm, Ax, Ay): inds_show = [] inds_show_txt = [] if 'i' in nm: inds_show = [3, 5, 6, 7, 8] inds_show_txt = [3] if '3' in nm or '5' in nm: inds_show = [1, 2, 3, 5, 6, 7, 8] if '3' in nm: inds_show_txt = [1, 2, 3] Ay[1] *= .3 Ay[2] *= 1.5 Ay[3] *= 3.5 if '5' in nm: inds_show_txt = [2, 3] Ax[2] *= .9 Ay[3] *= 1.5 if nm == 'i_s1': Ay[3] *= 2.5 else: if '001' not in nm: inds_show = [2, 5, 6, 7, 8, 9] inds_show_txt = [2, 6] Ay[6] *= 1e-6 Ax[6] *= .8 if '5' in nm: inds_show_txt = [2, 5] Ay[2] *= 2 Ay[5] *= 1.3e-4 Ax[5] *= .7 if '7' in nm or '1' in nm: Ay[2] *= 1.3 Ay[6] *= .35 Ax[6] *= .9 return inds_show, inds_show_txt, Ax, Ay plt.rcParams.update({ 'xtick.labelsize': 'xx-large', 'ytick.labelsize': 'xx-large', 'axes.labelsize': 'xx-large' }) name = run.name_run k = run.spectra.get('k')[1:] t = run.spectra.get('t_helmag') # read magnetic spectra if run.turb == 'k': EM = np.array(run.spectra.get('kin')[:, 1:], dtype='float') HkM = np.array(run.spectra.get('helkin_comp')[:, 1:], dtype='float') if run.turb == 'm': EM = np.array(run.spectra.get('mag')[:, 1:], dtype='float') HkM = np.array(run.spectra.get('helmag_comp')[:, 1:], dtype='float') # read GW spectra min_GWs = np.array(run.spectra.get('EGW_min_sp'), dtype='float') max_GWs = np.array(run.spectra.get('EGW_max_sp'), dtype='float') mean_GWs = np.array(run.spectra.get('EGW_stat_sp'), dtype='float') min_pos_HGWs = abs( np.array(run.spectra.get('helEGW_pos_min_sp'), dtype='float')) min_neg_HGWs = abs( np.array(run.spectra.get('helEGW_neg_min_sp'), dtype='float')) max_pos_HGWs = abs( np.array(run.spectra.get('helEGW_pos_max_sp'), dtype='float')) max_neg_HGWs = abs( np.array(run.spectra.get('helEGW_neg_max_sp'), dtype='float')) mean_HGWs = np.array(run.spectra.get('helEGW_stat_sp'), dtype='float') # get time that corresponds to maximum of magnetic energy density tini dtk = t[1] - t[0] indt = np.where(abs(t - run.tini) <= dtk / 2)[0][0] fig, ax = plt.subplots(figsize=(12, 10)) plt.xscale('log') plt.yscale('log') #plt.text(3e4, 4e-23, '$k$', fontsize=30) plt.xlabel('$k$') TT = 'M' if run.turb == 'k': TT = 'K' plt.title(r'$E_{\rm %s, GW} (k)$ and $H_{\rm %s, GW} (k)$' % (TT, TT), fontsize=30, pad=15) # specific options for the plots N_EM, Ay2_EM, Ax_EM = init_Ay2_Ax(12, 2., 1.) N_HM, Ay2_HM, Ax_HM = init_Ay2_Ax(10, .04, 1.) N_EGW, Ay2_EGW, Ax_EGW = init_Ay2_Ax(12, 2.5, 1.) N_HGW, Ay2_HGW, Ax_HGW = init_Ay2_Ax(10, .08, .8) Ay_HGW = .2 Ay_HM = .2 if 'i' in name: xleg = 1.5e4 yleg = 5e-13 else: xleg = 8e2 yleg = 5e-20 if '001' in name: yks_H = False else: yks_H = True # choose indices for which to show the power law fits and the power law # text above the fit for each of the runs inds_show_EM, inds_show_txt_EM, Ax_EM, Ay2_EM = \ indices_EM(name, Ax_EM, Ay2_EM) inds_show_HM, inds_show_txt_HM, Ax_HM, Ay2_HM = \ indices_HM(name, Ax_HM, Ay2_HM) inds_show_EGW, inds_show_txt_EGW, Ax_EGW, Ay2_EGW = \ indices_EGW(name, Ax_EGW, Ay2_EGW) inds_show_HGW, inds_show_txt_HGW, Ax_HGW, Ay2_HGW = \ indices_HGW(name, Ax_HGW, Ay2_HGW) if 'i' in name: str_typ = 'ini' else: str_typ = 'forc' if name == 'M0': sig_val = '0' if '01' in name and 'i' in name: sig_val = '0.1' if '01' in name and 'M' in name: sig_val = '0.1' if '01' in name and 'K' in name: sig_val = '0.1' if '3' in name: sig_val = '0.3' if '5' in name: sig_val = '0.5' if '7' in name: sig_val = '0.7' if name == 'i_s1': sig_val = '1' if name == 'M1' or name == 'K1': sig_val = '1' if '001' in name and 'f' in name: if 'neg' in name: sig_val = '-0.01' else: sig_val = '0.01' if name == 'f_s1_neg': sig_val = '-1' str_leg = r'$\sigma^{\rm %s}_{\rm M}=%s$' % (str_typ, sig_val) plot_st(k, EM[indt, :], yks=True, N=N_EM, inds_show=inds_show_EM, inds_show_txt=inds_show_txt_EM, Ay=4, Ay2=Ay2_EM, Ax=Ax_EM) plot_st(k, HkM[indt, :], hel=True, yks=yks_H, N=N_HM, inds_show=inds_show_HM, inds_show_txt=inds_show_txt_HM, Ay=Ay_HM, Ay2=Ay2_HM, Ax=Ax_HM) plot_st(k, mean_GWs, fb=True, yv=True, min_sp=min_GWs, max_sp=max_GWs, yks=True, N=N_EGW, inds_show=inds_show_EGW, Ax=Ax_EGW, inds_show_txt=inds_show_txt_EGW, Ay=4, Ay2=Ay2_EGW) plot_st(k, mean_HGWs, hel=True, fb=True, yv=True, min_sp_neg=min_neg_HGWs, max_sp_neg=max_neg_HGWs, min_sp_pos=min_pos_HGWs, max_sp_pos=max_pos_HGWs, yks=yks_H, N=N_HGW, inds_show=inds_show_HGW, inds_show_txt=inds_show_txt_HGW, Ay=Ay_HGW, Ay2=Ay2_HGW, Ax=Ax_HGW) handles = [] line_mag, = ax.plot([], [], '-', color='black', label=r'$E_{\rm %s}(k)$' % TT) line_helpos, = ax.plot([], [], '.', label=r'$+\frac{1}{2} k H_{\rm %s}(k)$' % TT, color='red') line_helneg, = ax.plot([], [], '.', label=r'$-\frac{1}{2} k H_{\rm %s}(k)$' % TT, color='blue') line_GW, = ax.plot([], [], color='black', label=r'$E_{\rm GW}(k)$') line_HGWpos, = ax.plot([], [], '.', label=r'$+H_{\rm GW} (k)$', color='red') line_HGWneg, = ax.plot([], [], '.', label=r'$-H_{\rm GW}(k)$', color='blue') handles = [line_mag, line_helpos, line_helneg] lgd1 = ax.legend(handles=handles, loc='upper right', fontsize=23, frameon=False) handles2 = [line_GW, line_HGWpos, line_HGWneg] lgd2 = plt.legend(handles=handles2, loc='lower left', fontsize=23, frameon=False) ax = plt.gca() ax.add_artist(lgd1) plt.yticks( [1e-21, 1e-19, 1e-17, 1e-15, 1e-13, 1e-11, 1e-9, 1e-7, 1e-5, 1e-3]) plot_sets.axes_lines() plt.tick_params(axis='y', direction='out', length=10) plt.text(xleg, yleg, str_leg, fontsize=30, bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=.5')) plt.xlim(100, 8e4) plt.ylim(1e-21, 1e-3) if save: plt.savefig('plots/' + run.name_run + 'EM_EGW.pdf', bbox_inches='tight')