MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Classes | Macros | Typedefs | Functions
omega_nu_single.h File Reference
#include <gsl/gsl_interp.h>
Include dependency graph for omega_nu_single.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _rho_nu_single
 
struct  _hybrid_nu
 
struct  _omega_nu
 

Macros

#define TNUCMB   (pow(4/11.,1/3.)*1.00328)
 
#define NUSPECIES   3
 

Typedefs

typedef struct _rho_nu_single _rho_nu_single
 
typedef struct _hybrid_nu _hybrid_nu
 
typedef struct _omega_nu _omega_nu
 

Functions

void rho_nu_init (_rho_nu_single *rho_nu_tab, double a0, const double mnu, const double kBtnu)
 
double rho_nu (const _rho_nu_single *rho_nu_tab, const double a, const double kT)
 
void init_hybrid_nu (_hybrid_nu *const hybnu, const double mnu[], const double vcrit, const double light, const double nu_crit_time, const double kBtnu)
 
double particle_nu_fraction (const _hybrid_nu *const hybnu, const double a, int i)
 
double nufrac_low (const double qc)
 
void init_omega_nu (_omega_nu *const omnu, const double MNu[], const double a0, const double HubbleParam, const double tcmb0)
 
double get_omega_nu (const _omega_nu *const omnu, const double a)
 
double get_omega_nu_nopart (const _omega_nu *const omnu, const double a)
 
double get_omegag (const _omega_nu *const omnu, const double a)
 
double omega_nu_single (const _omega_nu *const rho_nu_tab, const double a, const int i)
 

Detailed Description

Routines for computing the matter density in a single neutrino species

Definition in file omega_nu_single.h.

Macro Definition Documentation

◆ NUSPECIES

#define NUSPECIES   3

Number of massive neutrino species: 3 Could be made configurable at some point Neutrino masses are in eV

Definition at line 20 of file omega_nu_single.h.

◆ TNUCMB

#define TNUCMB   (pow(4/11.,1/3.)*1.00328)

Ratio between the massless neutrino temperature and the CMB temperature. Note there is a slight correction from 4/11 due to the neutrinos being slightly coupled at e+- annihilation. See Mangano et al 2005 (hep-ph/0506164) We use the CLASS default value, chosen so that omega_nu = m_nu / 93.14 h^2 At time of writing this is T_nu / T_gamma = 0.71611. See https://github.com/lesgourg/class_public/blob/master/explanatory.ini

Definition at line 16 of file omega_nu_single.h.

Typedef Documentation

◆ _hybrid_nu

typedef struct _hybrid_nu _hybrid_nu

Definition at line 47 of file omega_nu_single.h.

◆ _omega_nu

typedef struct _omega_nu _omega_nu

Definition at line 89 of file omega_nu_single.h.

◆ _rho_nu_single

Definition at line 1 of file omega_nu_single.h.

Function Documentation

◆ get_omega_nu()

double get_omega_nu ( const _omega_nu *const  omnu,
const double  a 
)

Return the total matter density in neutrinos at scale factor a.

Definition at line 57 of file omega_nu_single.c.

58 {
59  double rhonu=0;
60  int mi;
61  for(mi=0; mi<NUSPECIES; mi++) {
62  if(omnu->nu_degeneracies[mi] > 0){
63  rhonu += omnu->nu_degeneracies[mi] * rho_nu(&omnu->RhoNuTab[mi], a, omnu->kBtnu);
64  }
65  }
66  return rhonu/omnu->rhocrit;
67 }
double rho_nu(const _rho_nu_single *rho_nu_tab, const double a, const double kT)
#define NUSPECIES
double rhocrit
int nu_degeneracies[NUSPECIES]
_rho_nu_single RhoNuTab[NUSPECIES]

References _omega_nu::kBtnu, _omega_nu::nu_degeneracies, NUSPECIES, rho_nu(), _omega_nu::rhocrit, and _omega_nu::RhoNuTab.

Referenced by check_units(), compute_mass(), delta_nu_from_power(), delta_tot_first_init(), get_long_range_timestep_dloga(), get_omega_nu_nopart(), growth(), hubble_function(), init_cosmology(), init_neutrinos_lra(), init_transfer_table(), main(), parse_transfer(), test_get_omega_nu(), and update_delta_tot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_omega_nu_nopart()

double get_omega_nu_nopart ( const _omega_nu *const  omnu,
const double  a 
)

Return the total matter density in neutrinos at scale factor a , excluding active particles.

Definition at line 71 of file omega_nu_single.c.

72 {
73  double omega_nu = get_omega_nu(omnu, a);
74  double part_nu = get_omega_nu(omnu, 1) * particle_nu_fraction(&omnu->hybnu, a, 0) / (a*a*a);
75  return omega_nu - part_nu;
76 }
double particle_nu_fraction(const _hybrid_nu *const hybnu, const double a, const int i)
double get_omega_nu(const _omega_nu *const omnu, const double a)
_hybrid_nu hybnu

References get_omega_nu(), _omega_nu::hybnu, and particle_nu_fraction().

Referenced by check_omega(), delta_nu_from_power(), delta_tot_first_init(), get_delta_nu_combined(), potential_transfer(), test_hybrid_neutrinos(), and update_delta_tot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_omegag()

double get_omegag ( const _omega_nu *const  omnu,
const double  a 
)

Return the photon matter density at scale factor a

Definition at line 79 of file omega_nu_single.c.

80 {
81  const double omegag = 4*STEFAN_BOLTZMANN/(LIGHTCGS*LIGHTCGS*LIGHTCGS)*pow(omnu->tcmb0,4)/omnu->rhocrit;
82  return omegag/pow(a,4);
83 }
#define STEFAN_BOLTZMANN
#define LIGHTCGS
Definition: physconst.h:18

References LIGHTCGS, _omega_nu::rhocrit, STEFAN_BOLTZMANN, and _omega_nu::tcmb0.

Referenced by test_get_omegag().

Here is the caller graph for this function:

◆ init_hybrid_nu()

void init_hybrid_nu ( _hybrid_nu *const  hybnu,
const double  mnu[],
const double  vcrit,
const double  light,
const double  nu_crit_time,
const double  kBtnu 
)

Set up parameters for the hybrid neutrinos

Parameters
hybnuinitialised structure
mnuarray of neutrino masses in eV
vcritCritical velocity above which to treat neutrinos with particles. Note this is unperturbed velocity TODAY To get velocity at redshift z, multiply by (1+z)
lightspeed of light in internal units
nu_crit_timecritical time to make neutrino particles live
kBtnuBoltzmann constant times neutrino temperature. Dimensionful factor.

Definition at line 235 of file omega_nu_single.c.

236 {
237  hybnu->enabled=1;
238  int i;
239  hybnu->nu_crit_time = nu_crit_time;
240  hybnu->vcrit = vcrit / light;
241  for(i=0; i< NUSPECIES; i++) {
242  const double qc = mnu[i] * vcrit / light / kBtnu;
243  hybnu->nufrac_low[i] = nufrac_low(qc);
244  }
245 }
double nufrac_low(const double qc)
double nu_crit_time
double nufrac_low[NUSPECIES]

References _hybrid_nu::enabled, _hybrid_nu::nu_crit_time, nufrac_low(), _hybrid_nu::nufrac_low, NUSPECIES, and _hybrid_nu::vcrit.

Referenced by init_cosmology(), and test_hybrid_neutrinos().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_omega_nu()

void init_omega_nu ( _omega_nu *const  omnu,
const double  MNu[],
const double  a0,
const double  HubbleParam,
const double  tcmb0 
)

Initialise the neutrino structure, do the time integration and allocate memory for the subclass rho_nu_single

Parameters
omnustructure to initialise
MNuarray of neutrino masses in eV. Three entries.
a0initial scale factor.
HubbleParamHubble parameter h0, eg, 0.7.
tcmb0Redshift zero CMB temperature.

Definition at line 20 of file omega_nu_single.c.

21 {
22  int mi;
23  /*Explicitly disable hybrid neutrinos*/
24  omnu->hybnu.enabled=0;
25  /*CMB temperature*/
26  omnu->tcmb0 = tcmb0;
27  /*Neutrino temperature times k_B*/
28  omnu->kBtnu = BOLEVK * TNUCMB * tcmb0;
29  /*Store conversion between rho and omega*/
30  omnu->rhocrit = (3 * HUBBLE * HubbleParam * HUBBLE * HubbleParam)/ (8 * M_PI * GRAVITY);
31  /*First compute which neutrinos are degenerate with each other*/
32  for(mi=0; mi<NUSPECIES; mi++){
33  int mmi;
34  omnu->nu_degeneracies[mi]=0;
35  for(mmi=0; mmi<mi; mmi++){
36  if(fabs(MNu[mi] -MNu[mmi]) < FLOAT_ACC){
37  omnu->nu_degeneracies[mmi]+=1;
38  break;
39  }
40  }
41  if(mmi==mi) {
42  omnu->nu_degeneracies[mi]=1;
43  }
44  }
45  /*Now allocate a table for the species we want*/
46  for(mi=0; mi<NUSPECIES; mi++){
47  if(omnu->nu_degeneracies[mi]) {
48  rho_nu_init(&omnu->RhoNuTab[mi], a0, MNu[mi], omnu->kBtnu);
49  }
50  else
51  omnu->RhoNuTab[mi].loga = 0;
52  }
53 }
#define FLOAT_ACC
void rho_nu_init(_rho_nu_single *const rho_nu_tab, double a0, const double mnu, const double kBtnu)
#define TNUCMB
#define HUBBLE
Definition: physconst.h:25
#define GRAVITY
Definition: physconst.h:5
#define BOLEVK
Definition: physconst.h:13

References BOLEVK, _hybrid_nu::enabled, FLOAT_ACC, GRAVITY, HUBBLE, _omega_nu::hybnu, _omega_nu::kBtnu, _rho_nu_single::loga, _omega_nu::nu_degeneracies, NUSPECIES, rho_nu_init(), _omega_nu::rhocrit, _omega_nu::RhoNuTab, _omega_nu::tcmb0, and TNUCMB.

Referenced by init_cosmology(), test_allocate_delta_tot_table(), test_get_omega_nu(), test_get_omegag(), test_hybrid_neutrinos(), test_omega_nu_init_degenerate(), test_omega_nu_init_nondeg(), test_omega_nu_single(), and test_omega_nu_single_exact().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nufrac_low()

double nufrac_low ( const double  qc)

Integrate the fermi-dirac kernel between 0 and qc to find the fraction of neutrinos that are particles

Definition at line 219 of file omega_nu_single.c.

220 {
221  /*These functions are so smooth that we don't need much space*/
222  gsl_integration_workspace * w = gsl_integration_workspace_alloc (100);
223  double abserr;
224  gsl_function F;
225  F.function = &fermi_dirac_kernel;
226  F.params = NULL;
227  double total_fd;
228  gsl_integration_qag (&F, 0, qc, 0, 1e-6,100,GSL_INTEG_GAUSS61, w,&(total_fd), &abserr);
229  /*divided by the total F-D probability (which is 3 Zeta(3)/2 ~ 1.8 if MAX_FERMI_DIRAC is large enough*/
230  total_fd /= 1.5*1.202056903159594;
231  gsl_integration_workspace_free (w);
232  return total_fd;
233 }
double fermi_dirac_kernel(double x, void *params)

References fermi_dirac_kernel().

Referenced by init_hybrid_nu(), Jfrac_high(), test_hybrid_neutrinos(), and test_nufrac_low().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ omega_nu_single()

double omega_nu_single ( const _omega_nu *const  rho_nu_tab,
const double  a,
const int  i 
)

Return the matter density in a single neutrino species

Parameters
rho_nu_tabstructure containing pre-computed matter density values.
iindex of neutrino species we want
ascale factor desired

Definition at line 267 of file omega_nu_single.c.

268 {
269  /*Deal with case where we want a species degenerate with another one*/
270  if(omnu->nu_degeneracies[i] == 0) {
271  int j;
272  for(j=i; j >=0; j--)
273  if(omnu->nu_degeneracies[j]){
274  i = j;
275  break;
276  }
277  }
278  double omega_nu = rho_nu(&omnu->RhoNuTab[i], a,omnu->kBtnu)/omnu->rhocrit;
279  double omega_part = rho_nu(&omnu->RhoNuTab[i], 1,omnu->kBtnu)/omnu->rhocrit;
280  omega_part *= particle_nu_fraction(&omnu->hybnu, a, i)/(a*a*a);
281  omega_nu -= omega_part;
282  return omega_nu;
283 
284 }

References _omega_nu::hybnu, _omega_nu::kBtnu, _omega_nu::nu_degeneracies, particle_nu_fraction(), rho_nu(), _omega_nu::rhocrit, and _omega_nu::RhoNuTab.

Referenced by get_delta_nu_combined(), parse_transfer(), test_get_omega_nu(), test_hybrid_neutrinos(), test_omega_nu_single(), and test_omega_nu_single_exact().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ particle_nu_fraction()

double particle_nu_fraction ( const _hybrid_nu *const  hybnu,
const double  a,
int  i 
)

Get fraction of neutrinos currently followed by particles.

Parameters
hybnuStructure with hybrid neutrino parameters.
iindex of neutrino species to use.
aredshift of interest.
Returns
the fraction of neutrinos currently traced by particles. 0 when neutrinos are fully analytic at early times.

Definition at line 251 of file omega_nu_single.c.

252 {
253  /*Return zero if hybrid neutrinos not enabled*/
254  if(!hybnu->enabled)
255  return 0;
256  /*Just use a redshift cut for now. Really we want something more sophisticated,
257  * based on the shot noise and average overdensity.*/
258  if (a > hybnu->nu_crit_time){
259  return hybnu->nufrac_low[i];
260  }
261  return 0;
262 }

References _hybrid_nu::enabled, _hybrid_nu::nu_crit_time, and _hybrid_nu::nufrac_low.

Referenced by delta_nu_from_power(), delta_tot_first_init(), get_delta_nu(), get_delta_tot(), get_omega_nu_nopart(), gravpm_force(), omega_nu_single(), test_hybrid_neutrinos(), and update_delta_tot().

Here is the caller graph for this function:

◆ rho_nu()

double rho_nu ( const _rho_nu_single rho_nu_tab,
const double  a,
const double  kT 
)

Computes the neutrino density for a single neutrino species at a given redshift, either by looking up in a table, or a simple calculation in the limits, or by direct integration.

Parameters
rho_nu_tabPre-computed table of values
aRedshift desired.
kTBoltzmann constant times neutrino temperature. Dimensionful factor.
Returns
neutrino density in g cm^-3

Definition at line 180 of file omega_nu_single.c.

181 {
182  double rho_nu_val;
183  double amnu=a*rho_nu_tab->mnu;
184  const double kTamnu2=(kT*kT/amnu/amnu);
185  /*Do it analytically if we are in a regime where we can
186  * The next term is 141682 (kT/amnu)^8.
187  * At kT/amnu = 8, higher terms are larger and the series stops converging.
188  * Don't go lower than 50 here. */
189  if(NU_SW*NU_SW*kTamnu2 < 1){
190  /*Heavily non-relativistic*/
191  rho_nu_val = non_rel_rho_nu(a, kT, amnu, kTamnu2);
192  }
193  else if(amnu < 1e-6*kT){
194  /*Heavily relativistic*/
195  rho_nu_val=rel_rho_nu(a, kT);
196  }
197  else{
198  const double loga = log(a);
199  /* Deal with early time case. In practice no need to be very accurate
200  * so assume relativistic.*/
201  if (!rho_nu_tab->loga || loga < rho_nu_tab->loga[0])
202  rho_nu_val = rel_rho_nu(a,kT);
203  else
204  rho_nu_val=gsl_interp_eval(rho_nu_tab->interp,rho_nu_tab->loga,rho_nu_tab->rhonu,loga,rho_nu_tab->acc);
205  }
206  return rho_nu_val;
207 }
static double non_rel_rho_nu(const double a, const double kT, const double amnu, const double kTamnu2)
#define NU_SW
static double rel_rho_nu(const double a, const double kT)
gsl_interp * interp
gsl_interp_accel * acc

References _rho_nu_single::acc, _rho_nu_single::interp, _rho_nu_single::loga, _rho_nu_single::mnu, non_rel_rho_nu(), NU_SW, rel_rho_nu(), and _rho_nu_single::rhonu.

Referenced by get_omega_nu(), and omega_nu_single().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rho_nu_init()

void rho_nu_init ( _rho_nu_single rho_nu_tab,
double  a0,
const double  mnu,
const double  kBtnu 
)

Initialise the tables for matter density in a single neutrino species, by doing numerical integration.

Parameters
rho_nu_tabStructure to initialise
a0First scale factor in rho_nu_tab. Do not try and evaluate rho_nu at higher redshift!
mnuneutrino mass to compute neutrino matter density for in eV
kBtnuBoltzmann constant times neutrino temperature. Dimensionful factor.

Definition at line 119 of file omega_nu_single.c.

120 {
121  int i;
122  double abserr;
123  /* Tabulate to 1e-3, unless earlier requested.
124  * Need early times for growth function.*/
125  if(a0 > 1e-3)
126  a0 = 1e-3;
127  /* Do not need a table when relativistic*/
128  if(a0 * mnu < 1e-6 * kBtnu)
129  a0 = 1e-6 * kBtnu / mnu;
130  /*Make the table over a slightly wider range than requested, in case there is roundoff error*/
131  const double logA0=log(a0)-log(1.2);
132  const double logaf=log(NU_SW*kBtnu/mnu)+log(1.2);
133  gsl_function F;
134  F.function = &rho_nu_int;
135  /*Initialise constants*/
136  rho_nu_tab->mnu = mnu;
137  /*Shortcircuit if we don't need to do the integration*/
138  if(mnu < 1e-6*kBtnu || logaf < logA0)
139  return;
140 
141  /*Allocate memory for arrays*/
142  rho_nu_tab->loga = (double *) mymalloc("rho_nu_table",2*NRHOTAB*sizeof(double));
143  rho_nu_tab->rhonu = rho_nu_tab->loga+NRHOTAB;
144  rho_nu_tab->acc = gsl_interp_accel_alloc();
145  rho_nu_tab->interp=gsl_interp_alloc(gsl_interp_cspline,NRHOTAB);
146  if(!rho_nu_tab->interp || !rho_nu_tab->acc || !rho_nu_tab->loga)
147  endrun(2035,"Could not initialise tables for neutrino matter density\n");
148 
149  gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_VAL);
150  for(i=0; i< NRHOTAB; i++){
151  double param[2];
152  rho_nu_tab->loga[i]=logA0+i*(logaf-logA0)/(NRHOTAB-1);
153  param[0]=mnu*exp(rho_nu_tab->loga[i]);
154  param[1] = kBtnu;
155  F.params = &param;
156  gsl_integration_qag (&F, 0, 500*kBtnu,0 , 1e-9,GSL_VAL,6,w,&(rho_nu_tab->rhonu[i]), &abserr);
157  rho_nu_tab->rhonu[i]=rho_nu_tab->rhonu[i]/pow(exp(rho_nu_tab->loga[i]),4)*get_rho_nu_conversion();
158  }
159  gsl_integration_workspace_free (w);
160  gsl_interp_init(rho_nu_tab->interp,rho_nu_tab->loga,rho_nu_tab->rhonu,NRHOTAB);
161  return;
162 }
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define NRHOTAB
#define GSL_VAL
double get_rho_nu_conversion()
double rho_nu_int(double q, void *params)

References _rho_nu_single::acc, endrun(), get_rho_nu_conversion(), GSL_VAL, _rho_nu_single::interp, _rho_nu_single::loga, _rho_nu_single::mnu, mymalloc, NRHOTAB, NU_SW, rho_nu_int(), and _rho_nu_single::rhonu.

Referenced by init_omega_nu(), and test_rho_nu_init().

Here is the call graph for this function:
Here is the caller graph for this function: