File size: 4,120 Bytes
bc65052 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
#!/usr/bin/env python
# coding: utf-8
# In[ ]:
# import necessary modules
# uncomment to get plots displayed in notebook
get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from classy import Class
from scipy.optimize import fsolve
# In[ ]:
# a function returning the three masses given the Delta m^2, the total mass, and the hierarchy (e.g. 'IN' or 'IH')
# taken from a piece of MontePython written by Thejs Brinckmann
def get_masses(delta_m_squared_atm, delta_m_squared_sol, sum_masses, hierarchy):
# any string containing letter 'n' will be considered as refering to normal hierarchy
if 'n' in hierarchy.lower():
# Normal hierarchy massive neutrinos. Calculates the individual
# neutrino masses from M_tot_NH and deletes M_tot_NH
#delta_m_squared_atm=2.45e-3
#delta_m_squared_sol=7.50e-5
m1_func = lambda m1, M_tot, d_m_sq_atm, d_m_sq_sol: M_tot**2. + 0.5*d_m_sq_sol - d_m_sq_atm + m1**2. - 2.*M_tot*m1 - 2.*M_tot*(d_m_sq_sol+m1**2.)**0.5 + 2.*m1*(d_m_sq_sol+m1**2.)**0.5
m1,opt_output,success,output_message = fsolve(m1_func,sum_masses/3.,(sum_masses,delta_m_squared_atm,delta_m_squared_sol),full_output=True)
m1 = m1[0]
m2 = (delta_m_squared_sol + m1**2.)**0.5
m3 = (delta_m_squared_atm + 0.5*(m2**2. + m1**2.))**0.5
return m1,m2,m3
else:
# Inverted hierarchy massive neutrinos. Calculates the individual
# neutrino masses from M_tot_IH and deletes M_tot_IH
#delta_m_squared_atm=-2.45e-3
#delta_m_squared_sol=7.50e-5
delta_m_squared_atm = -delta_m_squared_atm
m1_func = lambda m1, M_tot, d_m_sq_atm, d_m_sq_sol: M_tot**2. + 0.5*d_m_sq_sol - d_m_sq_atm + m1**2. - 2.*M_tot*m1 - 2.*M_tot*(d_m_sq_sol+m1**2.)**0.5 + 2.*m1*(d_m_sq_sol+m1**2.)**0.5
m1,opt_output,success,output_message = fsolve(m1_func,sum_masses/3.,(sum_masses,delta_m_squared_atm,delta_m_squared_sol),full_output=True)
m1 = m1[0]
m2 = (delta_m_squared_sol + m1**2.)**0.5
m3 = (delta_m_squared_atm + 0.5*(m2**2. + m1**2.))**0.5
return m1,m2,m3
# In[ ]:
# test of this function, returning the 3 masses for total mass of 0.1eV
m1,m2,m3 = get_masses(2.45e-3,7.50e-5,0.1,'NH')
print ('NH:',m1,m2,m3,m1+m2+m3)
m1,m2,m3 = get_masses(2.45e-3,7.50e-5,0.1,'IH')
print ('IH:',m1,m2,m3,m1+m2+m3)
# In[ ]:
# The goal of this cell is to compute the ratio of P(k) for NH and IH with the same total mass
commonsettings = {'N_ur':0,
'N_ncdm':3,
'output':'mPk',
'P_k_max_1/Mpc':3.0,
# The next line should be uncommented for higher precision (but significantly slower running)
'ncdm_fluid_approximation':3,
# You may uncomment this line to get more info on the ncdm sector from Class:
'background_verbose':1
}
# array of k values in 1/Mpc
kvec = np.logspace(-4,np.log10(3),100)
# array for storing legend
legarray = []
# loop over total mass values
for sum_masses in [0.1, 0.115, 0.13]:
# normal hierarchy
[m1, m2, m3] = get_masses(2.45e-3,7.50e-5, sum_masses, 'NH')
NH = Class()
NH.set(commonsettings)
NH.set({'m_ncdm':str(m1)+','+str(m2)+','+str(m3)})
NH.compute()
# inverted hierarchy
[m1, m2, m3] = get_masses(2.45e-3,7.50e-5, sum_masses, 'IH')
IH = Class()
IH.set(commonsettings)
IH.set({'m_ncdm':str(m1)+','+str(m2)+','+str(m3)})
IH.compute()
pkNH = []
pkIH = []
for k in kvec:
pkNH.append(NH.pk(k,0.))
pkIH.append(IH.pk(k,0.))
NH.struct_cleanup()
IH.struct_cleanup()
# extract h value to convert k from 1/Mpc to h/Mpc
h = NH.h()
plt.semilogx(kvec/h,1-np.array(pkNH)/np.array(pkIH))
legarray.append(r'$\Sigma m_i = '+str(sum_masses)+'$eV')
plt.axhline(0,color='k')
plt.xlim(kvec[0]/h,kvec[-1]/h)
plt.xlabel(r'$k [h \mathrm{Mpc}^{-1}]$')
plt.ylabel(r'$1-P(k)^\mathrm{NH}/P(k)^\mathrm{IH}$')
plt.legend(legarray)
plt.savefig('neutrinohierarchy.pdf')
|