MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Classes | Macros | Typedefs | Functions | Variables
neutrinos_lra.c File Reference
#include <math.h>
#include <string.h>
#include <bigfile-mpi.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_interp.h>
#include <gsl/gsl_sf_bessel.h>
#include "neutrinos_lra.h"
#include "utils/endrun.h"
#include "utils/mymalloc.h"
#include "petaio.h"
#include "cosmology.h"
#include "powerspectrum.h"
#include "physconst.h"
Include dependency graph for neutrinos_lra.c:

Go to the source code of this file.

Classes

struct  _transfer_init_table
 
struct  _delta_nu_int_params
 

Macros

#define FLOAT_ACC   1e-6
 
#define GSL_VAL   200
 

Typedefs

typedef struct _transfer_init_table _transfer_init_table
 
typedef struct _delta_nu_int_params delta_nu_int_params
 

Functions

void update_delta_tot (_delta_tot_table *const d_tot, const double a, const double delta_cdm_curr[], const double delta_nu_curr[], const int overwrite)
 
void get_delta_nu (Cosmology *CP, const _delta_tot_table *const d_tot, const double a, double delta_nu_curr[], const double mnu)
 
void get_delta_nu_combined (Cosmology *CP, const _delta_tot_table *const d_tot, const double a, double delta_nu_curr[])
 
double specialJ (const double x, const double vcmnubylight, const double nufrac_low)
 
double fslength (Cosmology *CP, const double logai, const double logaf, const double light)
 
static double get_delta_tot (const double delta_nu_curr, const double delta_cdm_curr, const double OmegaNua3, const double Omeganonu, const double Omeganu1, const double particle_nu_fraction)
 
static void delta_tot_first_init (_delta_tot_table *const d_tot, const int nk_in, const double wavenum[], const double delta_cdm_curr[], const double TimeIC)
 
void delta_nu_from_power (struct _powerspectrum *PowerSpectrum, Cosmology *CP, const double Time, const double TimeIC)
 
void powerspectrum_nu_save (struct _powerspectrum *PowerSpectrum, const char *OutputDir, const char *filename, const double Time)
 
void petaio_save_neutrinos (BigFile *bf, int ThisTask)
 
void petaio_read_icnutransfer (BigFile *bf, int ThisTask)
 
void petaio_read_neutrinos (BigFile *bf, int ThisTask)
 
void init_neutrinos_lra (const int nk_in, const double TimeTransfer, const double TimeMax, const double Omega0, const _omega_nu *const omnu, const double UnitTime_in_s, const double UnitLength_in_cm)
 
double fslength_int (const double loga, void *params)
 
static double specialJ_fit (const double x)
 
static double II (const double x, const double qc, const int n)
 
static double Jfrac_high (const double x, const double qc, const double nufrac_low)
 
double get_delta_nu_int (double logai, void *params)
 

Variables

_delta_tot_table delta_tot_table
 
static _transfer_init_table t_init_data
 
static _transfer_init_tablet_init = &t_init_data
 

Detailed Description

Contains calculations for the Fourier-space semi-linear neutrino method described in Ali-Haimoud and Bird 2012. delta_tot_table stores the state of the integrator, which includes the matter power spectrum over all past time. This file contains routines for manipulating this structure; updating it by computing a new neutrino power spectrum, from the non-linear CDM power.

Definition in file neutrinos_lra.c.

Macro Definition Documentation

◆ FLOAT_ACC

#define FLOAT_ACC   1e-6

Floating point accuracy

Definition at line 28 of file neutrinos_lra.c.

◆ GSL_VAL

#define GSL_VAL   200

Number of bins in integrations

Definition at line 30 of file neutrinos_lra.c.

Typedef Documentation

◆ _transfer_init_table

Definition at line 75 of file neutrinos_lra.c.

◆ delta_nu_int_params

Definition at line 616 of file neutrinos_lra.c.

Function Documentation

◆ delta_nu_from_power()

void delta_nu_from_power ( struct _powerspectrum PowerSpectrum,
Cosmology CP,
const double  Time,
const double  TimeIC 
)

Definition at line 134 of file neutrinos_lra.c.

135 {
136  int i;
137  /*This is done on the first timestep: we need nk_nonzero for it to work.*/
139  if(delta_tot_table.ia == 0) {
140  /* Compute delta_nu from the transfer functions if first entry.*/
141  delta_tot_first_init(&delta_tot_table, PowerSpectrum->nonzero, PowerSpectrum->kk, PowerSpectrum->Power, TimeIC);
142  }
143 
144  /*Initialise the first delta_nu*/
147  }
148  for(i = 0; i < PowerSpectrum->nonzero; i++)
149  PowerSpectrum->logknu[i] = log(PowerSpectrum->kk[i]);
150 
151  double * Power_in = PowerSpectrum->Power;
152  /* Rebin the input power if necessary*/
153  if(delta_tot_table.nk != PowerSpectrum->nonzero) {
154  Power_in = (double *) mymalloc("pkint", delta_tot_table.nk * sizeof(double));
155  double * logPower = (double *) mymalloc("logpk", PowerSpectrum->nonzero * sizeof(double));
156  for(i = 0; i < PowerSpectrum->nonzero; i++)
157  logPower[i] = log(PowerSpectrum->Power[i]);
158  gsl_interp * pkint = gsl_interp_alloc(gsl_interp_linear, PowerSpectrum->nonzero);
159  gsl_interp_init(pkint, PowerSpectrum->logknu, logPower, PowerSpectrum->nonzero);
160  gsl_interp_accel * pkacc = gsl_interp_accel_alloc();
161  for(i = 0; i < delta_tot_table.nk; i++) {
162  double logk = log(delta_tot_table.wavenum[i]);
163  if(pkint->xmax < logk || pkint->xmin > logk)
164  Power_in[i] = delta_tot_table.delta_tot[i][delta_tot_table.ia-1];
165  else
166  Power_in[i] = exp(gsl_interp_eval(pkint, PowerSpectrum->logknu, logPower, logk, pkacc));
167  }
168  myfree(logPower);
169  gsl_interp_accel_free(pkacc);
170  gsl_interp_free(pkint);
171  }
172 
173  const double partnu = particle_nu_fraction(&CP->ONu.hybnu, Time, 0);
174  /* If we get called twice with the same scale factor, do nothing: delta_nu
175  * already stores the neutrino power from the current timestep.*/
176  if(1 - partnu > 1e-3 && log(Time)-delta_tot_table.scalefact[delta_tot_table.ia-1] > FLOAT_ACC) {
177  /*We need some estimate for delta_tot(current time) to obtain delta_nu(current time).
178  Even though delta_tot(current time) is not directly used (the integrand vanishes at a = a(current)),
179  it is indeed needed for interpolation */
180  /*It was checked that using delta_tot(current time) = delta_cdm(current time) leads to no more than 2%
181  error on delta_nu (and moreover for large k). Using the last timestep's delta_nu decreases error even more.
182  So we only need one step. */
183  /*This increments the number of stored spectra, although the last one is not yet final.*/
185  /*Get the new delta_nu_curr*/
187  /* Decide whether we save the current time or not */
188  if (Time > exp(delta_tot_table.scalefact[delta_tot_table.ia-2]) + 0.009) {
189  /* If so update delta_tot(a) correctly, overwriting current power spectrum */
191  }
192  /*Otherwise discard the last powerspectrum*/
193  else
195 
196  message(0,"Done getting neutrino power: nk = %d, k = %g, delta_nu = %g, delta_cdm = %g,\n", delta_tot_table.nk, delta_tot_table.wavenum[1], delta_tot_table.delta_nu_last[1], Power_in[1]);
197  /*kspace_prefac = M_nu (analytic) / M_particles */
198  const double OmegaNu_nop = get_omega_nu_nopart(&CP->ONu, Time);
199  const double omega_hybrid = get_omega_nu(&CP->ONu, 1) * partnu / pow(Time, 3);
200  /* Omega0 - Omega in neutrinos + Omega in particle neutrinos = Omega in particles*/
201  PowerSpectrum->nu_prefac = OmegaNu_nop/(delta_tot_table.Omeganonu/pow(Time,3) + omega_hybrid);
202  }
203  double * delta_nu_ratio = (double *) mymalloc2("dnu_rat", delta_tot_table.nk * sizeof(double));
204  double * logwavenum = (double *) mymalloc2("logwavenum", delta_tot_table.nk * sizeof(double));
205  gsl_interp * pkint = gsl_interp_alloc(gsl_interp_linear, delta_tot_table.nk);
206  gsl_interp_accel * pkacc = gsl_interp_accel_alloc();
207  /*We want to interpolate in log space*/
208  for(i=0; i < delta_tot_table.nk; i++) {
209  if(isnan(delta_tot_table.delta_nu_last[i]))
210  endrun(2004,"delta_nu_curr=%g i=%d delta_cdm_curr=%g kk=%g\n",delta_tot_table.delta_nu_last[i],i,Power_in[i],delta_tot_table.wavenum[i]);
211  /*Enforce positivity for sanity reasons*/
212  if(delta_tot_table.delta_nu_last[i] < 0)
214  delta_nu_ratio[i] = delta_tot_table.delta_nu_last[i]/ Power_in[i];
215  logwavenum[i] = log(delta_tot_table.wavenum[i]);
216  }
217  if(delta_tot_table.nk != PowerSpectrum->nonzero)
218  myfree(Power_in);
219  gsl_interp_init(pkint, logwavenum, delta_nu_ratio, delta_tot_table.nk);
220 
221  /*We want to interpolate in log space*/
222  for(i=0; i < PowerSpectrum->nonzero; i++) {
223  if(PowerSpectrum->nonzero == delta_tot_table.nk)
224  PowerSpectrum->delta_nu_ratio[i] = delta_nu_ratio[i];
225  else {
226  double logk = PowerSpectrum->logknu[i];
227  if(logk > pkint->xmax)
228  logk = pkint->xmax;
229  PowerSpectrum->delta_nu_ratio[i] = gsl_interp_eval(pkint, logwavenum, delta_nu_ratio, logk, pkacc);
230  }
231  }
232 
233  gsl_interp_accel_free(pkacc);
234  gsl_interp_free(pkint);
235  myfree(logwavenum);
236  myfree(delta_nu_ratio);
237 }
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define mymalloc2(name, size)
Definition: mymalloc.h:16
#define myfree(x)
Definition: mymalloc.h:19
#define FLOAT_ACC
Definition: neutrinos_lra.c:28
static void delta_tot_first_init(_delta_tot_table *const d_tot, const int nk_in, const double wavenum[], const double delta_cdm_curr[], const double TimeIC)
Definition: neutrinos_lra.c:97
_delta_tot_table delta_tot_table
Definition: neutrinos_lra.c:75
void get_delta_nu_combined(Cosmology *CP, const _delta_tot_table *const d_tot, const double a, double delta_nu_curr[])
void update_delta_tot(_delta_tot_table *const d_tot, const double a, const double delta_cdm_curr[], const double delta_nu_curr[], const int overwrite)
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)
double get_omega_nu_nopart(const _omega_nu *const omnu, const double a)
static Cosmology * CP
Definition: power.c:27
_omega_nu ONu
Definition: cosmology.h:24
double ** delta_tot
Definition: neutrinos_lra.h:27
double * scalefact
Definition: neutrinos_lra.h:29
double * delta_nu_last
Definition: neutrinos_lra.h:33
_hybrid_nu hybnu
double * logknu
Definition: powerspectrum.h:20
double * delta_nu_ratio
Definition: powerspectrum.h:21
double * Power
Definition: powerspectrum.h:10

References CP, _delta_tot_table::delta_nu_last, _powerspectrum::delta_nu_ratio, _delta_tot_table::delta_tot, delta_tot_first_init(), _delta_tot_table::delta_tot_init_done, delta_tot_table, endrun(), FLOAT_ACC, get_delta_nu_combined(), get_omega_nu(), get_omega_nu_nopart(), _omega_nu::hybnu, _delta_tot_table::ia, _powerspectrum::kk, _transfer_init_table::logk, _powerspectrum::logknu, message(), myfree, mymalloc, mymalloc2, _delta_tot_table::nk, _powerspectrum::nonzero, _powerspectrum::nu_prefac, _delta_tot_table::Omeganonu, Cosmology::ONu, particle_nu_fraction(), _powerspectrum::Power, _delta_tot_table::scalefact, update_delta_tot(), and _delta_tot_table::wavenum.

Referenced by compute_neutrino_power().

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

◆ delta_tot_first_init()

static void delta_tot_first_init ( _delta_tot_table *const  d_tot,
const int  nk_in,
const double  wavenum[],
const double  delta_cdm_curr[],
const double  TimeIC 
)
static

Definition at line 97 of file neutrinos_lra.c.

98 {
99  int ik;
100  d_tot->nk=nk_in;
101  const double OmegaNua3=get_omega_nu_nopart(d_tot->omnu, d_tot->TimeTransfer)*pow(d_tot->TimeTransfer,3);
102  const double OmegaNu1 = get_omega_nu(d_tot->omnu, 1);
103  gsl_interp_accel *acc = gsl_interp_accel_alloc();
104  gsl_interp * spline;
105  if(t_init->NPowerTable > 2)
106  spline = gsl_interp_alloc(gsl_interp_cspline,t_init->NPowerTable);
107  else
108  spline = gsl_interp_alloc(gsl_interp_linear,t_init->NPowerTable);
109  gsl_interp_init(spline,t_init->logk,t_init->T_nu,t_init->NPowerTable);
110  /*Check we have a long enough power table: power tables are in log_10*/
111  if(log10(wavenum[d_tot->nk-1]) > t_init->logk[t_init->NPowerTable-1])
112  endrun(2,"Want k = %g but maximum in CLASS table is %g\n",wavenum[d_tot->nk-1], pow(10, t_init->logk[t_init->NPowerTable-1]));
113  for(ik=0;ik<d_tot->nk;ik++) {
114  /* T_nu contains T_nu / T_cdm.*/
115  double T_nubyT_nonu = gsl_interp_eval(spline,t_init->logk,t_init->T_nu,log10(wavenum[ik]),acc);
116  /*Initialise delta_nu_init to use the first timestep's delta_cdm_curr
117  * so that it includes potential Rayleigh scattering. */
118  d_tot->delta_nu_init[ik] = delta_cdm_curr[ik]*T_nubyT_nonu;
119  const double partnu = particle_nu_fraction(&d_tot->omnu->hybnu, TimeIC, 0);
120  /*Initialise the first delta_tot*/
121  d_tot->delta_tot[ik][0] = get_delta_tot(d_tot->delta_nu_init[ik], delta_cdm_curr[ik], OmegaNua3, d_tot->Omeganonu, OmegaNu1, partnu);
122  /*Set up the wavenumber array*/
123  d_tot->wavenum[ik] = wavenum[ik];
124  }
125  gsl_interp_accel_free(acc);
126  gsl_interp_free(spline);
127 
128  /*If we are not restarting, make sure we set the scale factor*/
129  d_tot->scalefact[0]=log(TimeIC);
130  d_tot->ia=1;
131  return;
132 }
static double get_delta_tot(const double delta_nu_curr, const double delta_cdm_curr, const double OmegaNua3, const double Omeganonu, const double Omeganu1, const double particle_nu_fraction)
Definition: neutrinos_lra.c:67
static _transfer_init_table * t_init
Definition: neutrinos_lra.c:91
double * delta_nu_init
Definition: neutrinos_lra.h:31
const _omega_nu * omnu
Definition: neutrinos_lra.h:37

References _delta_tot_table::delta_nu_init, _delta_tot_table::delta_tot, endrun(), get_delta_tot(), get_omega_nu(), get_omega_nu_nopart(), _omega_nu::hybnu, _delta_tot_table::ia, _transfer_init_table::logk, _delta_tot_table::nk, _transfer_init_table::NPowerTable, _delta_tot_table::Omeganonu, _delta_tot_table::omnu, particle_nu_fraction(), _delta_tot_table::scalefact, t_init, _transfer_init_table::T_nu, _delta_tot_table::TimeTransfer, and _delta_tot_table::wavenum.

Referenced by delta_nu_from_power().

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

◆ fslength()

double fslength ( Cosmology CP,
const double  logai,
const double  logaf,
const double  light 
)

Free-streaming length (times Mnu/k_BT_nu, which is dimensionless) for a non-relativistic particle of momentum q = T0, from scale factor ai to af. Arguments:

Parameters
logailog of initial scale factor
logaflog of final scale factor
mnuNeutrino mass in eV
lightspeed of light in internal length units.
Returns
free-streaming length in Unit_Length/Unit_Time (same units as light parameter).

Definition at line 553 of file neutrinos_lra.c.

554 {
555  double abserr;
556  double fslength_val;
557  gsl_function F;
558  gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_VAL);
559  F.function = &fslength_int;
560  F.params = CP;
561  if(logai >= logaf)
562  return 0;
563  gsl_integration_qag (&F, logai, logaf, 0, 1e-6,GSL_VAL,6,w,&(fslength_val), &abserr);
564  gsl_integration_workspace_free (w);
565  return light*fslength_val;
566 }
#define GSL_VAL
Definition: neutrinos_lra.c:30
double fslength_int(const double loga, void *params)

References CP, fslength_int(), and GSL_VAL.

Referenced by get_delta_nu(), and test_fslength().

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

◆ fslength_int()

double fslength_int ( const double  loga,
void *  params 
)

Definition at line 536 of file neutrinos_lra.c.

537 {
538  Cosmology * CP = (Cosmology *) params;
539  /*This should be M_nu / k_B T_nu (which is dimensionless)*/
540  const double a = exp(loga);
541  return 1./a/(a*hubble_function(CP, a));
542 }
double hubble_function(const Cosmology *CP, double a)
Definition: cosmology.c:58

References CP, and hubble_function().

Referenced by fslength().

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

◆ get_delta_nu()

void get_delta_nu ( Cosmology CP,
const _delta_tot_table *const  d_tot,
const double  a,
double  delta_nu_curr[],
const double  mnu 
)

Main function: given tables of wavenumbers, total delta at Na earlier times (< = a), and initial conditions for neutrinos, computes the current delta_nu.

Parameters
d_totInitialised structure for storing total matter density.
aCurrent scale factor.
delta_nu_currPointer to array to store square root of neutrino power spectrum. Main output.
mnuNeutrino mass in eV.

Definition at line 667 of file neutrinos_lra.c.

668 {
669  double fsl_A0a,deriv_prefac;
670  int ik;
671  /* Variable is unused unless we have hybrid neutrinos,
672  * but we define it anyway to save ifdeffing later.*/
673  double qc = 0;
674  /*Number of stored power spectra. This includes the initial guess for the next step*/
675  const int Na = d_tot->ia;
676  const double mnubykT = mnu /d_tot->omnu->kBtnu;
677  /*Tolerated integration error*/
678  double relerr = 1e-6;
679 // message(0,"Start get_delta_nu: a=%g Na =%d wavenum[0]=%g delta_tot[0]=%g m_nu=%g\n",a,Na,wavenum[0],d_tot->delta_tot[0][Na-1],mnu);
680 
681  fsl_A0a = fslength(CP, log(d_tot->TimeTransfer), log(a),d_tot->light);
682  /*Precompute factor used to get delta_nu_init. This assumes that delta ~ a, so delta-dot is roughly 1.*/
683  deriv_prefac = d_tot->TimeTransfer*(hubble_function(CP, d_tot->TimeTransfer)/d_tot->light)* d_tot->TimeTransfer;
684  for (ik = 0; ik < d_tot->nk; ik++) {
685  /* Initial condition piece, assuming linear evolution of delta with a up to startup redshift */
686  /* This assumes that delta ~ a, so delta-dot is roughly 1. */
687  /* Also ignores any difference in the transfer functions between species.
688  * This will be good if all species have similar masses, or
689  * if two species are massless.
690  * Also, since at early times the clustering is tiny, it is very unlikely to matter.*/
691  /*For zero mass neutrinos just use the initial conditions piece, modulating to zero inside the horizon*/
692  const double specJ = specialJ(d_tot->wavenum[ik]*fsl_A0a/(mnubykT > 0 ? mnubykT : 1),qc, d_tot->omnu->hybnu.nufrac_low[0]);
693  delta_nu_curr[ik] = specJ*d_tot->delta_nu_init[ik] *(1.+ deriv_prefac*fsl_A0a);
694  }
695  /* Check whether the particle neutrinos are active at this point.
696  * If they are we want to truncate our integration.
697  * Only do this is hybrid neutrinos are activated in the param file.*/
698  const double partnu = particle_nu_fraction(&d_tot->omnu->hybnu, a, 0);
699  if(partnu > 0) {
700 /* message(0,"Particle neutrinos gravitating: a=%g partnu: %g qc is: %g\n",a, partnu,qc); */
701  /*If the particles are everything, be done now*/
702  if(1 - partnu < 1e-3)
703  return;
704  qc = d_tot->omnu->hybnu.vcrit * mnubykT;
705  /*More generous integration error for particle neutrinos*/
706  relerr /= (1.+1e-5-particle_nu_fraction(&d_tot->omnu->hybnu,a,0));
707  }
708  /*If only one time given, we are still at the initial time*/
709  /*If neutrino mass is zero, we are not accurate, just use the initial conditions piece*/
710  if(Na > 1 && mnubykT > 0){
711  delta_nu_int_params params;
712  params.acc = gsl_interp_accel_alloc();
713  gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_VAL);
714  gsl_function F;
715  F.function = &get_delta_nu_int;
716  F.params=&params;
717  /*Use cubic interpolation*/
718  if(Na > 2) {
719  params.spline=gsl_interp_alloc(gsl_interp_cspline,Na);
720  }
721  /*Unless we have only two points*/
722  else {
723  params.spline=gsl_interp_alloc(gsl_interp_linear,Na);
724  }
725  params.scale=d_tot->scalefact;
726  params.mnubykT=mnubykT;
727  params.qc = qc;
728  params.nufrac_low = d_tot->omnu->hybnu.nufrac_low[0];
729  /* Massively over-sample the free-streaming lengths.
730  * Interpolation is least accurate where the free-streaming length -> 0,
731  * which is exactly where it doesn't matter, but
732  * we still want to be safe. */
733  int Nfs = Na*16;
734  params.fs_acc = gsl_interp_accel_alloc();
735  params.fs_spline=gsl_interp_alloc(gsl_interp_cspline,Nfs);
736  params.CP = CP;
737  /*Pre-compute the free-streaming lengths, which are scale-independent*/
738  double * fslengths = (double *) mymalloc("fslengths", Nfs* sizeof(double));
739  double * fsscales = (double *) mymalloc("fsscales", Nfs* sizeof(double));
740  for(ik=0; ik < Nfs; ik++) {
741  fsscales[ik] = log(d_tot->TimeTransfer) + ik*(log(a) - log(d_tot->TimeTransfer))/(Nfs-1.);
742  fslengths[ik] = fslength(CP, fsscales[ik], log(a),d_tot->light);
743  }
744  params.fslengths = fslengths;
745  params.fsscales = fsscales;
746 
747  if(!params.spline || !params.acc || !w || !params.fs_spline || !params.fs_acc || !fslengths || !fsscales)
748  endrun(2016,"Error initialising and allocating memory for gsl interpolator and integrator.\n");
749 
750  gsl_interp_init(params.fs_spline,params.fsscales,params.fslengths,Nfs);
751  for (ik = 0; ik < d_tot->nk; ik++) {
752  double abserr,d_nu_tmp;
753  params.k=d_tot->wavenum[ik];
754  params.delta_tot=d_tot->delta_tot[ik];
755  gsl_interp_init(params.spline,params.scale,params.delta_tot,Na);
756  gsl_integration_qag (&F, log(d_tot->TimeTransfer), log(a), 0, relerr,GSL_VAL,6,w,&d_nu_tmp, &abserr);
757  delta_nu_curr[ik] += d_tot->delta_nu_prefac * d_nu_tmp;
758  }
759  gsl_integration_workspace_free (w);
760  gsl_interp_free(params.spline);
761  gsl_interp_accel_free(params.acc);
762  myfree(fsscales);
763  myfree(fslengths);
764  }
765 // for(ik=0; ik< 3; ik++)
766 // message(0,"k %g d_nu %g\n",wavenum[d_tot->nk/8*ik], delta_nu_curr[d_tot->nk/8*ik]);
767  return;
768 }
double fslength(Cosmology *CP, const double logai, const double logaf, const double light)
double get_delta_nu_int(double logai, void *params)
double specialJ(const double x, const double vcmnubylight, const double nufrac_low)
gsl_interp_accel * acc
gsl_interp_accel * fs_acc
gsl_interp * fs_spline
double delta_nu_prefac
Definition: neutrinos_lra.h:23
double nufrac_low[NUSPECIES]

References _delta_nu_int_params::acc, _delta_nu_int_params::CP, CP, _delta_tot_table::delta_nu_init, _delta_tot_table::delta_nu_prefac, _delta_nu_int_params::delta_tot, _delta_tot_table::delta_tot, endrun(), _delta_nu_int_params::fs_acc, _delta_nu_int_params::fs_spline, fslength(), _delta_nu_int_params::fslengths, _delta_nu_int_params::fsscales, get_delta_nu_int(), GSL_VAL, hubble_function(), _omega_nu::hybnu, _delta_tot_table::ia, _delta_nu_int_params::k, _omega_nu::kBtnu, _delta_tot_table::light, _delta_nu_int_params::mnubykT, myfree, mymalloc, _delta_tot_table::nk, _delta_nu_int_params::nufrac_low, _hybrid_nu::nufrac_low, _delta_tot_table::omnu, particle_nu_fraction(), _delta_nu_int_params::qc, _delta_nu_int_params::scale, _delta_tot_table::scalefact, specialJ(), _delta_nu_int_params::spline, _delta_tot_table::TimeTransfer, _hybrid_nu::vcrit, and _delta_tot_table::wavenum.

Referenced by get_delta_nu_combined().

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

◆ get_delta_nu_combined()

void get_delta_nu_combined ( Cosmology CP,
const _delta_tot_table *const  d_tot,
const double  a,
double  delta_nu_curr[] 
)

Function which wraps three get_delta_nu calls to get delta_nu three times, so that the final value is for all neutrino species

Definition at line 494 of file neutrinos_lra.c.

495 {
496  const double Omega_nu_tot=get_omega_nu_nopart(d_tot->omnu, a);
497  int mi;
498  /*Initialise delta_nu_curr*/
499  memset(delta_nu_curr, 0, d_tot->nk*sizeof(double));
500  /*Get each neutrinos species and density separately and add them to the total.
501  * Neglect perturbations in massless neutrinos.*/
502  for(mi=0; mi<NUSPECIES; mi++) {
503  if(d_tot->omnu->nu_degeneracies[mi] > 0) {
504  int ik;
505  double * delta_nu_single = (double *) mymalloc("delta_nu_single", sizeof(double) * d_tot->nk);
506  const double omeganu = d_tot->omnu->nu_degeneracies[mi] * omega_nu_single(d_tot->omnu, a, mi);
507  get_delta_nu(CP, d_tot, a, delta_nu_single,d_tot->omnu->RhoNuTab[mi].mnu);
508  for(ik=0; ik<d_tot->nk; ik++)
509  delta_nu_curr[ik]+=delta_nu_single[ik]*omeganu/Omega_nu_tot;
510  myfree(delta_nu_single);
511  }
512  }
513  return;
514 }
void get_delta_nu(Cosmology *CP, const _delta_tot_table *const d_tot, const double a, double delta_nu_curr[], const double mnu)
double omega_nu_single(const _omega_nu *const omnu, const double a, int i)
#define NUSPECIES
int nu_degeneracies[NUSPECIES]
_rho_nu_single RhoNuTab[NUSPECIES]

References CP, get_delta_nu(), get_omega_nu_nopart(), _rho_nu_single::mnu, myfree, mymalloc, _delta_tot_table::nk, _omega_nu::nu_degeneracies, NUSPECIES, omega_nu_single(), _delta_tot_table::omnu, and _omega_nu::RhoNuTab.

Referenced by delta_nu_from_power().

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

◆ get_delta_nu_int()

double get_delta_nu_int ( double  logai,
void *  params 
)

GSL integration kernel for get_delta_nu

Definition at line 652 of file neutrinos_lra.c.

653 {
654  delta_nu_int_params * p = (delta_nu_int_params *) params;
655  double fsl_aia = gsl_interp_eval(p->fs_spline,p->fsscales,p->fslengths,logai,p->fs_acc);
656  double delta_tot_at_a = gsl_interp_eval(p->spline,p->scale,p->delta_tot,logai,p->acc);
657  double specJ = specialJ(p->k*fsl_aia/p->mnubykT, p->qc, p->nufrac_low);
658  double ai = exp(logai);
659  return fsl_aia/(ai*hubble_function(p->CP, ai)) * specJ * delta_tot_at_a;
660 }

References _delta_nu_int_params::acc, _delta_nu_int_params::CP, _delta_nu_int_params::delta_tot, _delta_nu_int_params::fs_acc, _delta_nu_int_params::fs_spline, _delta_nu_int_params::fslengths, _delta_nu_int_params::fsscales, hubble_function(), _delta_nu_int_params::k, _delta_nu_int_params::mnubykT, _delta_nu_int_params::nufrac_low, _delta_nu_int_params::qc, _delta_nu_int_params::scale, specialJ(), and _delta_nu_int_params::spline.

Referenced by get_delta_nu().

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

◆ get_delta_tot()

static double get_delta_tot ( const double  delta_nu_curr,
const double  delta_cdm_curr,
const double  OmegaNua3,
const double  Omeganonu,
const double  Omeganu1,
const double  particle_nu_fraction 
)
inlinestatic

Combine the CDM and neutrino power spectra together to get the total power. OmegaNua3 = OmegaNu(a) * a^3 Omeganonu = Omega0 - OmegaNu(1) Omeganu1 = OmegaNu(1)

Definition at line 67 of file neutrinos_lra.c.

68 {
69  const double fcdm = 1 - OmegaNua3/(Omeganonu + Omeganu1);
70  return fcdm * (delta_cdm_curr + delta_nu_curr * OmegaNua3/(Omeganonu + Omeganu1*particle_nu_fraction));
71 }

References particle_nu_fraction().

Referenced by delta_tot_first_init(), and update_delta_tot().

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

◆ II()

static double II ( const double  x,
const double  qc,
const int  n 
)
inlinestatic

Definition at line 590 of file neutrinos_lra.c.

591 {
592  return (n*n+n*n*n*qc+n*qc*x*x - x*x)* qc*gsl_sf_bessel_j0(qc*x) + (2*n+n*n*qc+qc*x*x)*cos(qc*x);
593 }

Referenced by Jfrac_high().

Here is the caller graph for this function:

◆ init_neutrinos_lra()

void init_neutrinos_lra ( const int  nk_in,
const double  TimeTransfer,
const double  TimeMax,
const double  Omega0,
const _omega_nu *const  omnu,
const double  UnitTime_in_s,
const double  UnitLength_in_cm 
)

Allocates memory for delta_tot_table.

Parameters
nk_inNumber of bins stored in each power spectrum.
TimeTransferScale factor of the transfer functions.
TimeMaxFinal scale factor up to which we will need memory.
Omega0Matter density at z=0.
omnuPointer to structure containing pre-computed tables for evaluating neutrino matter densities.
UnitTime_in_sTime unit of the simulation in s.
UnitLength_in_cmLength unit of the simulation in cm

Definition at line 450 of file neutrinos_lra.c.

451 {
453  int count;
454  /*Memory allocations need to be done on all processors*/
455  d_tot->nk_allocated=nk_in;
456  d_tot->nk=nk_in;
457  /*Store starting time*/
458  d_tot->TimeTransfer = TimeTransfer;
459  /* Allocate memory for delta_tot here, so that we can have further memory allocated and freed
460  * before delta_tot_init is called. The number nk here should be larger than the actual value needed.*/
461  /*Allocate pointers to each k-vector*/
462  d_tot->namax=ceil(100*(TimeMax-TimeTransfer))+2;
463  d_tot->ia=0;
464  d_tot->delta_tot =(double **) mymalloc("kspace_delta_tot",nk_in*sizeof(double *));
465  /*Allocate list of scale factors, and space for delta_tot, in one operation.*/
466  d_tot->scalefact = (double *) mymalloc("kspace_scalefact",d_tot->namax*(nk_in+1)*sizeof(double));
467  /*Allocate space for delta_nu and wavenumbers*/
468  d_tot->delta_nu_last = (double *) mymalloc("kspace_delta_nu", sizeof(double) * 3 * nk_in);
469  d_tot->delta_nu_init = d_tot->delta_nu_last + nk_in;
470  d_tot->wavenum = d_tot->delta_nu_init + nk_in;
471  /*Allocate actual data. Note that this means data can be accessed either as:
472  * delta_tot[k][a] OR as
473  * delta_tot[0][a+k*namax] */
474  d_tot->delta_tot[0] = d_tot->scalefact+d_tot->namax;
475  for(count=1; count< nk_in; count++)
476  d_tot->delta_tot[count] = d_tot->delta_tot[0] + count*d_tot->namax;
477  /*Allocate space for the initial neutrino power spectrum*/
478  /*Setup pointer to the matter density*/
479  d_tot->omnu = omnu;
480  /*Set the prefactor for delta_nu, and the units system*/
481  d_tot->light = LIGHTCGS * UnitTime_in_s/UnitLength_in_cm;
482  d_tot->delta_nu_prefac = 1.5 *Omega0 * HUBBLE * HUBBLE * pow(UnitTime_in_s,2)/d_tot->light;
483  /*Matter fraction excluding neutrinos*/
484  d_tot->Omeganonu = Omega0 - get_omega_nu(omnu, 1);
485 }
#define HUBBLE
Definition: physconst.h:25
#define LIGHTCGS
Definition: physconst.h:18
static double UnitLength_in_cm
Definition: power.c:26

References _delta_tot_table::delta_nu_init, _delta_tot_table::delta_nu_last, _delta_tot_table::delta_nu_prefac, _delta_tot_table::delta_tot, delta_tot_table, get_omega_nu(), HUBBLE, _delta_tot_table::ia, _delta_tot_table::light, LIGHTCGS, mymalloc, _delta_tot_table::namax, _delta_tot_table::nk, _delta_tot_table::nk_allocated, _delta_tot_table::Omeganonu, _delta_tot_table::omnu, _delta_tot_table::scalefact, _delta_tot_table::TimeTransfer, UnitLength_in_cm, and _delta_tot_table::wavenum.

Referenced by begrun(), and test_allocate_delta_tot_table().

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

◆ Jfrac_high()

static double Jfrac_high ( const double  x,
const double  qc,
const double  nufrac_low 
)
inlinestatic

Definition at line 601 of file neutrinos_lra.c.

602 {
603  double integ=0;
604  int n;
605  for(n=1; n<20; n++)
606  {
607  integ+= -1*pow((-1),n)*exp(-n*qc)/(n*n+x*x)/(n*n+x*x)*II(x,qc,n);
608  }
609  /* Normalise with integral_qc^infty(f_0(q)q^2 dq), same as I(X).
610  * So that as qc-> infinity, this -> specialJ_fit(x)*/
611  integ /= 1.5 * 1.202056903159594 * (1 - nufrac_low);
612  return integ;
613 }
static double II(const double x, const double qc, const int n)
double nufrac_low(const double qc)

References II(), and nufrac_low().

Here is the call graph for this function:

◆ petaio_read_icnutransfer()

void petaio_read_icnutransfer ( BigFile *  bf,
int  ThisTask 
)

Definition at line 317 of file neutrinos_lra.c.

318 {
319 #pragma omp master
320  {
321  t_init->NPowerTable = 2;
322  BigBlock bn;
323  /* Read the size of the ICTransfer block.
324  * If we can't read it, just set it to zero*/
325  if(0 == big_file_mpi_open_block(bf, &bn, "ICTransfers", MPI_COMM_WORLD)) {
326  if(0 != big_block_get_attr(&bn, "Nentry", &t_init->NPowerTable, "u8", 1))
327  endrun(0, "Failed to read attr: %s\n", big_file_get_error_message());
328  if(0 != big_block_mpi_close(&bn, MPI_COMM_WORLD))
329  endrun(0, "Failed to close block %s\n",big_file_get_error_message());
330  }
331  message(0,"Found transfer function, using %d rows.\n", t_init->NPowerTable);
332  t_init->logk = (double *) mymalloc2("Transfer_functions", sizeof(double) * 2*t_init->NPowerTable);
334 
335  /*Defaults: a very small value*/
336  t_init->logk[0] = -100;
337  t_init->logk[t_init->NPowerTable-1] = 100;
338 
339  t_init->T_nu[0] = 1e-30;
340  t_init->T_nu[t_init->NPowerTable-1] = 1e-30;
341 
342  /*Now read the arrays*/
343  BigArray Tnu = {0};
344  BigArray logk = {0};
345 
346  size_t dims[2] = {0, 1};
347  ptrdiff_t strides[2] = {sizeof(double), sizeof(double)};
348  /*The neutrino state is shared between all processors,
349  *so only read on master task and broadcast*/
350  if(ThisTask == 0) {
351  dims[0] = t_init->NPowerTable;
352  }
353  big_array_init(&Tnu, t_init->T_nu, "=f8", 2, dims, strides);
354  big_array_init(&logk, t_init->logk, "=f8", 2, dims, strides);
355  /*This is delta_nu / delta_tot: note technically the most massive eigenstate only.
356  * But if there are significant differences the mass is so low this is basically zero.*/
357  petaio_read_block(bf, "ICTransfers/DELTA_NU", &Tnu, 0);
358  petaio_read_block(bf, "ICTransfers/logk", &logk, 0);
359  /*Also want d_{cdm+bar} / d_tot so we can get d_nu/(d_cdm+d_b)*/
360  double * T_cb = (double *) mymalloc("tmp1", t_init->NPowerTable* sizeof(double));
361  T_cb[0] = 1;
362  T_cb[t_init->NPowerTable-1] = 1;
363  BigArray Tcb = {0};
364  big_array_init(&Tcb, T_cb, "=f8", 2, dims, strides);
365  petaio_read_block(bf, "ICTransfers/DELTA_CB", &Tcb, 0);
366  int i;
367  for(i = 0; i < t_init->NPowerTable; i++)
368  t_init->T_nu[i] /= T_cb[i];
369  myfree(T_cb);
370  /*Broadcast the arrays.*/
371  MPI_Bcast(t_init->logk,2*t_init->NPowerTable,MPI_DOUBLE,0,MPI_COMM_WORLD);
372  }
373 }
int petaio_read_block(BigFile *bf, const char *blockname, BigArray *array, int required)
Definition: petaio.c:562
int ThisTask
Definition: test_exchange.c:23

References endrun(), _transfer_init_table::logk, message(), myfree, mymalloc, mymalloc2, _transfer_init_table::NPowerTable, petaio_read_block(), t_init, _transfer_init_table::T_nu, and ThisTask.

Referenced by petaio_read_snapshot().

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

◆ petaio_read_neutrinos()

void petaio_read_neutrinos ( BigFile *  bf,
int  ThisTask 
)

Definition at line 376 of file neutrinos_lra.c.

377 {
378 #pragma omp master
379  {
380  size_t nk, ia, ik, i;
381  BigBlock bn;
382  if(0 != big_file_mpi_open_block(bf, &bn, "Neutrino", MPI_COMM_WORLD)) {
383  endrun(0, "Failed to open block at %s:%s\n", "Neutrino",
384  big_file_get_error_message());
385  }
386  if(
387  (0 != big_block_get_attr(&bn, "Nscale", &ia, "u8", 1)) ||
388  (0 != big_block_get_attr(&bn, "Nkval", &nk, "u8", 1))) {
389  endrun(0, "Failed to read attr: %s\n",
390  big_file_get_error_message());
391  }
392  double *delta_tot = (double *) mymalloc("tmp_nusave",ia*nk*sizeof(double));
393  /*Allocate list of scale factors, and space for delta_tot, in one operation.*/
394  if(0 != big_block_get_attr(&bn, "scalefact", delta_tot_table.scalefact, "f8", ia))
395  endrun(0, "Failed to read attr: %s\n", big_file_get_error_message());
396  if(0 != big_block_mpi_close(&bn, MPI_COMM_WORLD)) {
397  endrun(0, "Failed to close block %s\n",
398  big_file_get_error_message());
399  }
400  BigArray deltas = {0};
401  size_t dims[2] = {0, ia};
402  ptrdiff_t strides[2] = {(ptrdiff_t) (sizeof(double)*ia), (ptrdiff_t)sizeof(double)};
403  /*The neutrino state is shared between all processors,
404  *so only read on master task and broadcast*/
405  if(ThisTask == 0) {
406  dims[0] = nk;
407  }
408  big_array_init(&deltas, delta_tot, "=f8", 2, dims, strides);
409  petaio_read_block(bf, "Neutrino/Deltas", &deltas, 1);
410  if(nk > 1Lu*delta_tot_table.nk_allocated || ia > 1Lu*delta_tot_table.namax)
411  endrun(5, "Allocated nk %d na %d for neutrino power but need nk %d na %d\n", delta_tot_table.nk_allocated, delta_tot_table.namax, nk, ia);
412  /*Save a flat memory block*/
413  for(ik=0;ik<nk;ik++)
414  for(i=0;i<ia;i++)
415  delta_tot_table.delta_tot[ik][i] = delta_tot[ik*ia+i];
416  delta_tot_table.nk = nk;
417  delta_tot_table.ia = ia;
418  myfree(delta_tot);
419  /* Read the initial delta_nu. This is basically zero anyway,
420  * so for backwards compatibility do not require it*/
421  BigArray delta_nu = {0};
422  dims[1] = 1;
423  strides[0] = sizeof(double);
425  big_array_init(&delta_nu, delta_tot_table.delta_nu_init, "=f8", 2, dims, strides);
426  petaio_read_block(bf, "Neutrino/DeltaNuInit", &delta_nu, 0);
427  /* Read the k values*/
428  BigArray kvalue = {0};
430  big_array_init(&kvalue, delta_tot_table.wavenum, "=f8", 2, dims, strides);
431  petaio_read_block(bf, "Neutrino/kvalue", &kvalue, 0);
432 
433  /*Broadcast the arrays.*/
434  MPI_Bcast(&(delta_tot_table.ia), 1,MPI_INT,0,MPI_COMM_WORLD);
435  MPI_Bcast(&(delta_tot_table.nk), 1,MPI_INT,0,MPI_COMM_WORLD);
436  MPI_Bcast(delta_tot_table.delta_nu_init,delta_tot_table.nk,MPI_DOUBLE,0,MPI_COMM_WORLD);
437  MPI_Bcast(delta_tot_table.wavenum,delta_tot_table.nk,MPI_DOUBLE,0,MPI_COMM_WORLD);
438 
439  if(delta_tot_table.ia > 0) {
440  /*Broadcast data for scalefact and delta_tot, Delta_tot is allocated as the same block of memory as scalefact.
441  Not all this memory will actually have been used, but it is easiest to bcast all of it.*/
442  MPI_Bcast(delta_tot_table.scalefact,delta_tot_table.namax*(delta_tot_table.nk+1),MPI_DOUBLE,0,MPI_COMM_WORLD);
443  }
444  }
445 }

References _delta_tot_table::delta_nu_init, _delta_tot_table::delta_tot, delta_tot_table, endrun(), _delta_tot_table::ia, myfree, mymalloc, _delta_tot_table::namax, _delta_tot_table::nk, _delta_tot_table::nk_allocated, petaio_read_block(), _delta_tot_table::scalefact, ThisTask, and _delta_tot_table::wavenum.

Referenced by petaio_read_snapshot().

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

◆ petaio_save_neutrinos()

void petaio_save_neutrinos ( BigFile *  bf,
int  ThisTask 
)

Definition at line 265 of file neutrinos_lra.c.

266 {
267 #pragma omp master
268  {
269  double * scalefact = delta_tot_table.scalefact;
270  size_t nk = delta_tot_table.nk, ia = delta_tot_table.ia;
271  size_t ik, i;
272  double * delta_tot = (double *) mymalloc("tmp_delta",nk * ia * sizeof(double));
273  /*Save a flat memory block*/
274  for(ik=0;ik< nk;ik++)
275  for(i=0;i< ia;i++)
276  delta_tot[ik*ia+i] = delta_tot_table.delta_tot[ik][i];
277 
278  BigBlock bn;
279  if(0 != big_file_mpi_create_block(bf, &bn, "Neutrino", NULL, 0, 0, 0, MPI_COMM_WORLD)) {
280  endrun(0, "Failed to create block at %s:%s\n", "Neutrino",
281  big_file_get_error_message());
282  }
283  if ( (0 != big_block_set_attr(&bn, "Nscale", &ia, "u8", 1)) ||
284  (0 != big_block_set_attr(&bn, "scalefact", scalefact, "f8", ia)) ||
285  (0 != big_block_set_attr(&bn, "Nkval", &nk, "u8", 1)) ) {
286  endrun(0, "Failed to write neutrino attributes %s\n",
287  big_file_get_error_message());
288  }
289  if(0 != big_block_mpi_close(&bn, MPI_COMM_WORLD)) {
290  endrun(0, "Failed to close block %s\n",
291  big_file_get_error_message());
292  }
293  BigArray deltas = {0};
294  size_t dims[2] = {0 , ia};
295  /*The neutrino state is shared between all processors,
296  *so only write on master task*/
297  if(ThisTask == 0) {
298  dims[0] = nk;
299  }
300  ptrdiff_t strides[2] = {(ptrdiff_t) (sizeof(double) * ia), (ptrdiff_t) sizeof(double)};
301  big_array_init(&deltas, delta_tot, "=f8", 2, dims, strides);
302  petaio_save_block(bf, "Neutrino/Deltas", &deltas, 1);
303  myfree(delta_tot);
304  /*Now write the initial neutrino power*/
305  BigArray delta_nu = {0};
306  dims[1] = 1;
307  strides[0] = sizeof(double);
308  big_array_init(&delta_nu, delta_tot_table.delta_nu_init, "=f8", 2, dims, strides);
309  petaio_save_block(bf, "Neutrino/DeltaNuInit", &delta_nu, 1);
310  /*Now write the k values*/
311  BigArray kvalue = {0};
312  big_array_init(&kvalue, delta_tot_table.wavenum, "=f8", 2, dims, strides);
313  petaio_save_block(bf, "Neutrino/kvalue", &kvalue, 1);
314  }
315 }
void petaio_save_block(BigFile *bf, const char *blockname, BigArray *array, int verbose)
Definition: petaio.c:587

References _delta_tot_table::delta_nu_init, _delta_tot_table::delta_tot, delta_tot_table, endrun(), _delta_tot_table::ia, myfree, mymalloc, _delta_tot_table::nk, petaio_save_block(), _delta_tot_table::scalefact, ThisTask, and _delta_tot_table::wavenum.

Referenced by petaio_save_snapshot().

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

◆ powerspectrum_nu_save()

void powerspectrum_nu_save ( struct _powerspectrum PowerSpectrum,
const char *  OutputDir,
const char *  filename,
const double  Time 
)

Definition at line 240 of file neutrinos_lra.c.

241 {
242  int i;
243  int ThisTask;
244  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
245  if(ThisTask != 0)
246  return;
247 
248  char * fname = fastpm_strdup_printf("%s/%s-%0.4f.txt", OutputDir, filename, Time);
249  /* Now save the neutrino power spectrum*/
250  FILE * fp = fopen(fname, "w");
251  fprintf(fp, "# in Mpc/h Units \n");
252  fprintf(fp, "# k P_nu(k) Nmodes\n");
253  fprintf(fp, "# a= %g\n", Time);
254  fprintf(fp, "# nk = %d\n", PowerSpectrum->nonzero);
255  for(i = 0; i < PowerSpectrum->nonzero; i++){
256  fprintf(fp, "%g %g %ld\n", PowerSpectrum->kk[i], pow(delta_tot_table.delta_nu_last[i],2), PowerSpectrum->Nmodes[i]);
257  }
258  fclose(fp);
259  myfree(fname);
260  /*Clean up the neutrino memory now we saved the power spectrum.*/
261  gsl_interp_free(PowerSpectrum->nu_spline);
262  gsl_interp_accel_free(PowerSpectrum->nu_acc);
263 }
char * fastpm_strdup_printf(const char *fmt,...)
Definition: string.c:41
gsl_interp_accel * nu_acc
Definition: powerspectrum.h:24
gsl_interp * nu_spline
Definition: powerspectrum.h:23
int64_t * Nmodes
Definition: powerspectrum.h:11

References _delta_tot_table::delta_nu_last, delta_tot_table, fastpm_strdup_printf(), _powerspectrum::kk, myfree, _powerspectrum::Nmodes, _powerspectrum::nonzero, _powerspectrum::nu_acc, _powerspectrum::nu_spline, and ThisTask.

Referenced by gravpm_force().

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

◆ specialJ()

double specialJ ( const double  x,
const double  vcmnubylight,
const double  nufrac_low 
)

Fit to the special function J(x) that is accurate to better than 3% relative and 0.07% absolute

Definition at line 616 of file neutrinos_lra.c.

617 {
618  if( qc > 0 ) {
619  return Jfrac_high(x, qc, nufrac_low);
620  }
621  return specialJ_fit(x);
622 }
static double specialJ_fit(const double x)
static double Jfrac_high(const double x, const double qc, const double nufrac_low)

Referenced by get_delta_nu(), get_delta_nu_int(), and test_specialJ().

Here is the caller graph for this function:

◆ specialJ_fit()

static double specialJ_fit ( const double  x)
inlinestatic

Definition at line 576 of file neutrinos_lra.c.

577 {
578 
579  double x2, x4, x8;
580  if (x <= 0.)
581  return 1.;
582  x2 = x*x;
583  x4 = x2*x2;
584  x8 = x4*x4;
585 
586  return (1.+ 0.0168 * x2 + 0.0407* x4)/(1. + 2.1734 * x2 + 1.6787 * exp(4.1811*log(x)) + 0.1467 * x8);
587 }

◆ update_delta_tot()

void update_delta_tot ( _delta_tot_table *const  d_tot,
const double  a,
const double  delta_cdm_curr[],
const double  delta_nu_curr[],
const int  overwrite 
)

Update the last value of delta_tot in the table with a new value computed from the given delta_cdm_curr and delta_nu_curr. If overwrite is true, overwrite the existing final entry.

Definition at line 519 of file neutrinos_lra.c.

520 {
521  const double OmegaNua3 = get_omega_nu_nopart(d_tot->omnu, a)*pow(a,3);
522  const double OmegaNu1 = get_omega_nu(d_tot->omnu, 1);
523  const double partnu = particle_nu_fraction(&d_tot->omnu->hybnu, a, 0);
524  int ik;
525  if(!overwrite)
526  d_tot->ia++;
527  /*Update the scale factor*/
528  d_tot->scalefact[d_tot->ia-1] = log(a);
529  /* Update delta_tot(a)*/
530  for (ik = 0; ik < d_tot->nk; ik++){
531  d_tot->delta_tot[ik][d_tot->ia-1] = get_delta_tot(delta_nu_curr[ik], delta_cdm_curr[ik], OmegaNua3, d_tot->Omeganonu, OmegaNu1,partnu);
532  }
533 }

References _delta_tot_table::delta_tot, get_delta_tot(), get_omega_nu(), get_omega_nu_nopart(), _omega_nu::hybnu, _delta_tot_table::ia, _delta_tot_table::nk, _delta_tot_table::Omeganonu, _delta_tot_table::omnu, particle_nu_fraction(), and _delta_tot_table::scalefact.

Referenced by delta_nu_from_power().

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

Variable Documentation

◆ delta_tot_table

_delta_tot_table delta_tot_table

◆ t_init

_transfer_init_table* t_init = &t_init_data
static

Definition at line 91 of file neutrinos_lra.c.

Referenced by delta_tot_first_init(), and petaio_read_icnutransfer().

◆ t_init_data

_transfer_init_table t_init_data
static

Definition at line 90 of file neutrinos_lra.c.