MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Macros | Functions
omega_nu_single.c File Reference
#include "omega_nu_single.h"
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
#include <string.h>
#include "physconst.h"
#include "utils/mymalloc.h"
#include "utils/endrun.h"
Include dependency graph for omega_nu_single.c:

Go to the source code of this file.

Macros

#define HBAR   6.582119e-16 /*hbar in units of eV s*/
 
#define STEFAN_BOLTZMANN   5.670373e-5
 
#define NRHOTAB   200
 
#define FLOAT_ACC   1e-6
 
#define GSL_VAL   200
 
#define NU_SW   100
 

Functions

void init_omega_nu (_omega_nu *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 rho_nu_int (double q, void *params)
 
double get_rho_nu_conversion ()
 
void rho_nu_init (_rho_nu_single *const rho_nu_tab, double a0, const double mnu, const double kBtnu)
 
static double non_rel_rho_nu (const double a, const double kT, const double amnu, const double kTamnu2)
 
static double rel_rho_nu (const double a, const double kT)
 
double rho_nu (const _rho_nu_single *rho_nu_tab, const double a, const double kT)
 
double fermi_dirac_kernel (double x, void *params)
 
double nufrac_low (const double qc)
 
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, const int i)
 
double omega_nu_single (const _omega_nu *const omnu, const double a, int i)
 

Macro Definition Documentation

◆ FLOAT_ACC

#define FLOAT_ACC   1e-6

Floating point accuracy

Definition at line 16 of file omega_nu_single.c.

◆ GSL_VAL

#define GSL_VAL   200

Number of bins in integrations

Definition at line 18 of file omega_nu_single.c.

◆ HBAR

#define HBAR   6.582119e-16 /*hbar in units of eV s*/

Definition at line 11 of file omega_nu_single.c.

◆ NRHOTAB

#define NRHOTAB   200

Definition at line 14 of file omega_nu_single.c.

◆ NU_SW

#define NU_SW   100

Value of kT/aM_nu on which to switch from the analytic expansion to the numerical integration

Definition at line 87 of file omega_nu_single.c.

◆ STEFAN_BOLTZMANN

#define STEFAN_BOLTZMANN   5.670373e-5

Definition at line 12 of file omega_nu_single.c.

Function Documentation

◆ fermi_dirac_kernel()

double fermi_dirac_kernel ( double  x,
void *  params 
)

Definition at line 212 of file omega_nu_single.c.

213 {
214  return x * x / (exp(x) + 1);
215 }

Referenced by nufrac_low().

Here is the caller graph for this function:

◆ 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:

◆ get_rho_nu_conversion()

double get_rho_nu_conversion ( )

Definition at line 102 of file omega_nu_single.c.

103 {
104  /*q has units of eV/c, so rho_nu now has units of (eV/c)^4*/
105  double convert=4*M_PI*2; /* The factor of two is for antineutrinos*/
106  /*rho_nu_val now has units of eV^4*/
107  /*To get units of density, divide by (c*hbar)**3 in eV s and cm/s */
108  const double chbar=1./(2*M_PI*LIGHTCGS*HBAR);
109  convert*=(chbar*chbar*chbar);
110  /*Now has units of (eV)/(cm^3)*/
111  /* 1 eV = 1.60217646 × 10-12 g cm^2 s^(-2) */
112  /* So 1eV/c^2 = 1.7826909604927859e-33 g*/
113  /*So this is rho_nu_val in g /cm^3*/
114  convert*=(1.60217646e-12/LIGHTCGS/LIGHTCGS);
115  return convert;
116 }
#define HBAR

References HBAR, and LIGHTCGS.

Referenced by do_exact_rho_nu_integration(), non_rel_rho_nu(), rel_rho_nu(), and rho_nu_init().

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:

◆ non_rel_rho_nu()

static double non_rel_rho_nu ( const double  a,
const double  kT,
const double  amnu,
const double  kTamnu2 
)
inlinestatic

Definition at line 165 of file omega_nu_single.c.

166 {
167  /*The constants are Riemann zetas: 3,5,7 respectively*/
168  return amnu*(kT*kT*kT)/(a*a*a*a)*(1.5*1.202056903159594+kTamnu2*45./4.*1.0369277551433704+2835./32.*kTamnu2*kTamnu2*1.0083492773819229+80325/32.*kTamnu2*kTamnu2*kTamnu2*1.0020083928260826)*get_rho_nu_conversion();
169 }
double get_rho_nu_conversion()

References get_rho_nu_conversion().

Referenced by rho_nu().

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:

◆ rel_rho_nu()

static double rel_rho_nu ( const double  a,
const double  kT 
)
inlinestatic

Definition at line 173 of file omega_nu_single.c.

174 {
175  return 7*pow(M_PI*kT/a,4)/120.*get_rho_nu_conversion();
176 }

References get_rho_nu_conversion().

Referenced by rho_nu().

Here is the call graph for this function:
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 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:

◆ rho_nu_int()

double rho_nu_int ( double  q,
void *  params 
)

Definition at line 91 of file omega_nu_single.c.

92 {
93  double amnu = *((double *)params);
94  double kT = *((double *)params+1);
95  double epsilon = sqrt(q*q+amnu*amnu);
96  double f0 = 1./(exp(q/kT)+1);
97  return q*q*epsilon*f0;
98 }

Referenced by do_exact_rho_nu_integration(), and rho_nu_init().

Here is the caller graph for this function: