CLASS MANUAL
thermodynamics.c File Reference
#include "thermodynamics.h"
#include "hyrec.h"
+ Include dependency graph for thermodynamics.c:

Functions

int thermodynamics_at_z (struct background *pba, struct thermo *pth, double z, short inter_mode, int *last_index, double *pvecback, double *pvecthermo)
 
int thermodynamics_init (struct precision *ppr, struct background *pba, struct thermo *pth)
 
int thermodynamics_free (struct thermo *pth)
 
int thermodynamics_indices (struct thermo *pth, struct recombination *preco, struct reionization *preio)
 
int thermodynamics_helium_from_bbn (struct precision *ppr, struct background *pba, struct thermo *pth)
 
int thermodynamics_onthespot_energy_injection (struct precision *ppr, struct background *pba, struct recombination *preco, double z, double *energy_rate, ErrorMsg error_message)
 
int thermodynamics_energy_injection (struct precision *ppr, struct background *pba, struct recombination *preco, double z, double *energy_rate, ErrorMsg error_message)
 
int thermodynamics_reionization_function (double z, struct thermo *pth, struct reionization *preio, double *xe)
 
int thermodynamics_get_xe_before_reionization (struct precision *ppr, struct thermo *pth, struct recombination *preco, double z, double *xe)
 
int thermodynamics_reionization (struct precision *ppr, struct background *pba, struct thermo *pth, struct recombination *preco, struct reionization *preio, double *pvecback)
 
int thermodynamics_reionization_sample (struct precision *ppr, struct background *pba, struct thermo *pth, struct recombination *preco, struct reionization *preio, double *pvecback)
 
int thermodynamics_recombination (struct precision *ppr, struct background *pba, struct thermo *pth, struct recombination *preco, double *pvecback)
 
int thermodynamics_recombination_with_hyrec (struct precision *ppr, struct background *pba, struct thermo *pth, struct recombination *preco, double *pvecback)
 
int thermodynamics_recombination_with_recfast (struct precision *ppr, struct background *pba, struct thermo *pth, struct recombination *preco, double *pvecback)
 
int thermodynamics_derivs_with_recfast (double z, double *y, double *dy, void *parameters_and_workspace, ErrorMsg error_message)
 
int thermodynamics_merge_reco_and_reio (struct precision *ppr, struct thermo *pth, struct recombination *preco, struct reionization *preio)
 
int thermodynamics_output_titles (struct background *pba, struct thermo *pth, char titles[_MAXTITLESTRINGLENGTH_])
 

Detailed Description

Documented thermodynamics module

Julien Lesgourgues, 6.09.2010

Deals with the thermodynamical evolution. This module has two purposes:

  • at the beginning, to initialize the thermodynamics, i.e. to integrate the thermodynamical equations, and store all thermodynamical quantities as a function of redshift inside an interpolation table. The current version of recombination is based on RECFAST v1.5. The current version of reionization is based on exactly the same reionization function as in CAMB, in order to make allow for comparison. It should be easy to generalize the module to more complicated reionization histories.
  • to provide a routine which allow other modules to evaluate any thermodynamical quantities at a given redshift value (by interpolating within the interpolation table).

The logic is the following:

  • in a first step, the code assumes that there is no reionization, and computes the ionization fraction, Thomson scattering rate, baryon temperature, etc., using RECFAST. The result is stored in a temporary table 'recombination_table' (within a temporary structure of type 'recombination') for each redshift in a range 0 < z < z_initial. The sampling in z space is done with a simple linear step size.
  • in a second step, the code adds the reionization history, starting from a redshift z_reio_start. The ionization fraction at this redshift is read in the previous recombination table in order to ensure a perfect matching. The code computes the ionization fraction, Thomson scattering rate, baryon temperature, etc., using a given parametrization of the reionization history. The result is stored in a temporary table 'reionization_table' (within a temporary structure of type 'reionization') for each redshift in the range 0 < z < z_reio_start. The sampling in z space is found automatically, given the precision parameter 'reionization_sampling'.
  • in a third step, the code merges the two tables 'recombination_table' and 'reionization_table' inside the table 'thermodynamics_table', and the temporary structures 'recombination' and 'reionization' are freed. In 'thermodynamics_table', the sampling in z space is the one defined in the recombination algorithm for z_reio_start < z < z_initial, and the one defined in the reionization algorithm for 0 < z < z_reio_start.
  • at this stage, only a few columns in the table 'thermodynamics_table' have been filled. In a fourth step, the remaining columns are filled, using some numerical integration/derivation routines from the 'array.c' tools module.
  • small detail: one of the columns contains the maximum variation rate of a few relevant thermodynamical quantities. This rate will be used for defining automatically the sampling step size in the perturbation module. Hence, the exact value of this rate is unimportant, but its order of magnitude at a given z defines the sampling precision of the perturbation module. Hence, it is harmless to use a smoothing routine in order to make this rate look nicer, although this will not affect the final result significantly. The last step in the thermodynamics_init module is to perform this smoothing.

In summary, the following functions can be called from other modules:

  1. thermodynamics_init() at the beginning (but after background_init())
  2. thermodynamics_at_z() at any later time
  3. thermodynamics_free() at the end, when no more calls to thermodynamics_at_z() are needed

Function Documentation

◆ thermodynamics_at_z()

int thermodynamics_at_z ( struct background pba,
struct thermo pth,
double  z,
short  inter_mode,
int *  last_index,
double *  pvecback,
double *  pvecthermo 
)

Thermodynamics quantities at given redshift z.

Evaluates all thermodynamics quantities at a given value of the redshift by reading the pre-computed table and interpolating.

Parameters
pbaInput: pointer to background structure
pthInput: pointer to the thermodynamics structure (containing pre-computed table)
zInput: redshift
inter_modeInput: interpolation mode (normal or growing_closeby)
last_indexInput/Output: index of the previous/current point in the interpolation array (input only for closeby mode, output for both)
pvecbackInput: vector of background quantities (used only in case z>z_initial for getting ddkappa and dddkappa; in that case, should be already allocated and filled, with format short_info or larger; in other cases, will be ignored)
pvecthermoOutput: vector of thermodynamics quantities (assumed to be already allocated)
Returns
the error status

Summary:

  • define local variables
  • interpolate in table with array_interpolate_spline() (normal mode) or array_interpolate_spline_growing_closeby() (closeby mode)

◆ thermodynamics_init()

int thermodynamics_init ( struct precision ppr,
struct background pba,
struct thermo pth 
)

Initialize the thermo structure, and in particular the thermodynamics interpolation table.

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput/Output: pointer to initialized thermo structure
Returns
the error status

Summary:

  • define local variables
  • initialize pointers, allocate background vector
  • compute and check primordial Helium fraction
  • check energy injection parameters
  • assign values to all indices in the structures with thermodynamics_indices()
  • solve recombination and store values of $ z, x_e, d \kappa / d \tau, T_b, c_b^2 $ with thermodynamics_recombination()
  • if there is reionization, solve reionization and store values of $ z, x_e, d \kappa / d \tau, T_b, c_b^2 $ with thermodynamics_reionization()
  • merge tables in recombination and reionization structures into a single table in thermo structure
  • compute table of corresponding conformal times
  • store initial value of conformal time in the structure
  • fill missing columns (quantities not computed previously but related)
  • –> baryon drag interaction rate time minus one, -[R * kappa'], stored temporarily in column ddkappa
  • –> second derivative of this rate, -[R * kappa']'', stored temporarily in column dddkappa
  • –> compute tau_d = [int_{tau_today}^{tau} dtau -dkappa_d/dtau]
  • –> compute r_d = [int_{tau_ini}^{tau} dtau [1/kappa']
  • –> second derivative with respect to tau of dkappa (in view of spline interpolation)
  • –> first derivative with respect to tau of dkappa (using spline interpolation)
  • –> compute -kappa = [int_{tau_today}^{tau} dtau dkappa/dtau], store temporarily in column "g"
  • –> derivatives of baryon sound speed (only computed if some non-minimal tight-coupling schemes is requested)
  • —> second derivative with respect to tau of cb2
  • —> first derivative with respect to tau of cb2 (using spline interpolation)
  • –> compute visibility: $ g= (d \kappa/d \tau) e^{- \kappa} $
  • —> compute g
  • —> compute exp(-kappa)
  • —> compute g' (the plus sign of the second term is correct, see def of -kappa in thermodynamics module!)
  • —> compute g''
  • —> store g
  • —> compute variation rate
  • smooth the rate (details of smoothing unimportant: only the order of magnitude of the rate matters)
  • fill tables of second derivatives with respect to z (in view of spline interpolation)
  • find maximum of g
  • find conformal recombination time using background_tau_of_z()
  • find damping scale at recombination (using linear interpolation)
  • find time (always after recombination) at which tau_c/tau falls below some threshold, defining tau_free_streaming
  • find baryon drag time (when tau_d crosses one, using linear interpolation) and sound horizon at that time
  • find time above which visibility falls below a given fraction of its maximum
  • if verbose flag set to next-to-minimum value, print the main results

◆ thermodynamics_free()

int thermodynamics_free ( struct thermo pth)

Free all memory space allocated by thermodynamics_init().

Parameters
pthInput/Output: pointer to thermo structure (to be freed)
Returns
the error status

◆ thermodynamics_indices()

int thermodynamics_indices ( struct thermo pth,
struct recombination preco,
struct reionization preio 
)

Assign value to each relevant index in vectors of thermodynamical quantities, as well as in vector containing reionization parameters.

Parameters
pthInput/Output: pointer to thermo structure
precoInput/Output: pointer to recombination structure
preioInput/Output: pointer to reionization structure
Returns
the error status

Summary:

  • define local variables
  • initialization of all indices and flags in thermo structure
  • initialization of all indices and flags in recombination structure
  • initialization of all indices and flags in reionization structure
  • same with parameters of the function $ X_e(z)$

◆ thermodynamics_helium_from_bbn()

int thermodynamics_helium_from_bbn ( struct precision ppr,
struct background pba,
struct thermo pth 
)

Infer the primordial helium fraction from standard BBN, as a function of the baryon density and expansion rate during BBN.

This module is simpler then the one used in arXiv:0712.2826 because it neglects the impact of a possible significant chemical potentials for electron neutrinos. The full code with xi_nu_e could be introduced here later.

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput/Output: pointer to initialized thermo structure
Returns
the error status

Summary:

  • Infer effective number of neutrinos at the time of BBN
  • 8.6173e-11 converts from Kelvin to MeV. We randomly choose 0.1 MeV to be the temperature of BBN
  • compute Delta N_eff as defined in bbn file, i.e. $ \Delta N_{eff}=0$ means $ N_{eff}=3.046$
  • spline in one dimension (along deltaN)
  • interpolate in one dimension (along deltaN)
  • spline in remaining dimension (along omegab)
  • interpolate in remaining dimension (along omegab)
  • deallocate arrays

◆ thermodynamics_onthespot_energy_injection()

int thermodynamics_onthespot_energy_injection ( struct precision ppr,
struct background pba,
struct recombination preco,
double  z,
double *  energy_rate,
ErrorMsg  error_message 
)

In case of non-minimal cosmology, this function determines the energy rate injected in the IGM at a given redshift z (= on-the-spot annihilation). This energy injection may come e.g. from dark matter annihilation or decay.

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
precoInput: pointer to recombination structure
zInput: redshift
energy_rateOutput: energy density injection rate
error_messageOutput: error message
Returns
the error status

◆ thermodynamics_energy_injection()

int thermodynamics_energy_injection ( struct precision ppr,
struct background pba,
struct recombination preco,
double  z,
double *  energy_rate,
ErrorMsg  error_message 
)

In case of non-minimal cosmology, this function determines the effective energy rate absorbed by the IGM at a given redshift (beyond the on-the-spot annihilation). This energy injection may come e.g. from dark matter annihilation or decay.

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
precoInput: pointer to recombination structure
zInput: redshift
energy_rateOutput: energy density injection rate
error_messageOutput: error message
Returns
the error status

◆ thermodynamics_reionization_function()

int thermodynamics_reionization_function ( double  z,
struct thermo pth,
struct reionization preio,
double *  xe 
)

This subroutine contains the reionization function $ X_e(z) $ (one for each scheme; so far, only the function corresponding to the reio_camb scheme is coded)

Parameters
zInput: redshift
pthInput: pointer to thermo structure, to know which scheme is used
preioInput: pointer to reionization structure, containing the parameters of the function $ X_e(z) $
xeOutput: $ X_e(z) $

Summary:

  • define local variables
  • implementation of ionization function similar to the one in CAMB
  • –> case z > z_reio_start
  • –> case z < z_reio_start: hydrogen contribution (tanh of complicated argument)
  • –> case z < z_reio_start: helium contribution (tanh of simpler argument)
  • implementation of binned ionization function similar to astro-ph/0606552
  • –> case z > z_reio_start
  • implementation of many tanh jumps
  • –> case z > z_reio_start
  • implementation of reio_inter
  • –> case z > z_reio_start

◆ thermodynamics_get_xe_before_reionization()

int thermodynamics_get_xe_before_reionization ( struct precision ppr,
struct thermo pth,
struct recombination preco,
double  z,
double *  xe 
)

This subroutine reads $ X_e(z) $ in the recombination table at the time at which reionization starts. Hence it provides correct initial conditions for the reionization function.

Parameters
pprInput: pointer to precision structure
pthInput: pointer to thermo structure
precoInput: pointer to recombination structure
zInput: redshift z_reio_start
xeOutput: $ X_e(z) $ at z

◆ thermodynamics_reionization()

int thermodynamics_reionization ( struct precision ppr,
struct background pba,
struct thermo pth,
struct recombination preco,
struct reionization preio,
double *  pvecback 
)

This routine computes the reionization history. In the reio_camb scheme, this is straightforward if the input parameter is the reionization redshift. If the input is the optical depth, need to find z_reio by dichotomy (trying several z_reio until the correct tau_reio is approached).

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput: pointer to thermo structure
precoInput: pointer to filled recombination structure
preioInput/Output: pointer to reionization structure (to be filled)
pvecbackInput: vector of background quantities (used as workspace: must be already allocated, with format short_info or larger, but does not need to be filled)
Returns
the error status

Summary:

  • define local variables
  • allocate the vector of parameters defining the function $ X_e(z) $
  • (a) if reionization implemented like in CAMB
  • –> set values of these parameters, excepted those depending on the reionization redshift
  • –> if reionization redshift given as an input, initialize the remaining values and fill reionization table
  • –> if reionization optical depth given as an input, find reionization redshift by dichotomy and initialize the remaining values
  • (b) if reionization implemented with reio_bins_tanh scheme
  • (c) if reionization implemented with reio_many_tanh scheme
  • (d) if reionization implemented with reio_inter scheme

◆ thermodynamics_reionization_sample()

int thermodynamics_reionization_sample ( struct precision ppr,
struct background pba,
struct thermo pth,
struct recombination preco,
struct reionization preio,
double *  pvecback 
)

For fixed input reionization parameters, this routine computes the reionization history and fills the reionization table.

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput: pointer to thermo structure
precoInput: pointer to filled recombination structure
preioInput/Output: pointer to reionization structure (to be filled)
pvecbackInput: vector of background quantities (used as workspace: must be already allocated, with format short_info or larger, but does not need to be filled)
Returns
the error status

Summary:

  • define local variables
  • (a) allocate vector of values related to reionization
  • (b) create a growTable with gt_init()
  • (c) first line is taken from thermodynamics table, just before reionization starts
  • –> look where to start in current thermodynamics table
  • –> get redshift
  • –> get $ X_e $
  • –> get $ d \kappa / d z = (d \kappa / d \tau) * (d \tau / d z) = - (d \kappa / d \tau) / H $
  • –> get baryon temperature
  • –> after recombination, Tb scales like (1+z)**2. Compute constant factor Tb/(1+z)**2.
  • –> get baryon sound speed
  • –> store these values in growing table
  • (d) set the maximum step value (equal to the step in thermodynamics table)
  • (e) loop over redshift values in order to find values of z, x_e, kappa' (Tb and cb2 found later by integration). The sampling in z space is found here.
  • (f) allocate reionization_table with correct size
  • (g) retrieve data stored in the growTable with gt_getPtr()
  • (h) copy growTable to reionization_temporary_table (invert order of lines, so that redshift is growing, like in recombination table)
  • (i) free the growTable with gt_free() , free vector of reionization variables
  • (j) another loop on z, to integrate equation for Tb and to compute cb2
  • –> derivative of baryon temperature
  • –> increment baryon temperature
  • –> get baryon sound speed
  • –> spline $ d \tau / dz $ with respect to z in view of integrating for optical depth
  • –> integrate for optical depth

◆ thermodynamics_recombination()

int thermodynamics_recombination ( struct precision ppr,
struct background pba,
struct thermo pth,
struct recombination preco,
double *  pvecback 
)

Integrate thermodynamics with your favorite recombination code.

◆ thermodynamics_recombination_with_hyrec()

int thermodynamics_recombination_with_hyrec ( struct precision ppr,
struct background pba,
struct thermo pth,
struct recombination preco,
double *  pvecback 
)

Integrate thermodynamics with HyRec.

Integrate thermodynamics with HyRec, allocate and fill the part of the thermodynamics interpolation table (the rest is filled in thermodynamics_init()). Called once by thermodynamics_recombination(), from thermodynamics_init().

            HYREC: Hydrogen and Helium Recombination Code
    Written by Yacine Ali-Haimoud and Chris Hirata (Caltech)
Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput: pointer to thermodynamics structure
precoOutput: pointer to recombination structure
pvecbackInput: pointer to an allocated (but empty) vector of background variables

Summary:

  • Fill hyrec parameter structure
  • Build effective rate tables
  • distribute addresses for each table
  • Normalize 2s–1s differential decay rate to L2s1s (can be set by user in hydrogen.h)
  • Compute the recombination history by calling a function in hyrec (no CLASS-like error management here)
  • fill a few parameters in preco and pth
  • allocate memory for thermodynamics interpolation tables (size known in advance) and fill it
  • –> get redshift, corresponding results from hyrec, and background quantities
  • –> store the results in the table

◆ thermodynamics_recombination_with_recfast()

int thermodynamics_recombination_with_recfast ( struct precision ppr,
struct background pba,
struct thermo pth,
struct recombination preco,
double *  pvecback 
)

Integrate thermodynamics with RECFAST.

Integrate thermodynamics with RECFAST, allocate and fill the part of the thermodynamics interpolation table (the rest is filled in thermodynamics_init()). Called once by thermodynamics_recombination, from thermodynamics_init().

RECFAST is an integrator for Cosmic Recombination of Hydrogen and Helium, developed by Douglas Scott (dscot.nosp@m.t@as.nosp@m.tro.u.nosp@m.bc.c.nosp@m.a) based on calculations in the paper Seager, Sasselov & Scott (ApJ, 523, L1, 1999). and "fudge" updates in Wong, Moss & Scott (2008).

Permission to use, copy, modify and distribute without fee or royalty at any tier, this software and its documentation, for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software and documentation, including modifications that you make for internal use or for distribution:

Copyright 1999-2010 by University of British Columbia. All rights reserved.

THIS SOFTWARE IS PROVIDED "AS IS", AND U.B.C. MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, U.B.C. MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

Version 1.5: includes extra fitting function from Rubino-Martin et al. arXiv:0910.4383v1 [astro-ph.CO]

Parameters
pprInput: pointer to precision structure
pbaInput: pointer to background structure
pthInput: pointer to thermodynamics structure
precoOutput: pointer to recombination structure
pvecbackInput: pointer to an allocated (but empty) vector of background variables
Returns
the error status

Summary:

  • define local variables
  • allocate memory for thermodynamics interpolation tables (size known in advance)
  • initialize generic integrator with initialize_generic_integrator()
  • read a few precision/cosmological parameters
  • define the fields of the 'thermodynamics parameter and workspace' structure
  • impose initial conditions at early times
  • loop over redshift steps Nz; integrate over each step with generic_integrator(), store the results in the table using thermodynamics_derivs_with_recfast()
  • –> first approximation: H and Helium fully ionized
  • –> second approximation: first Helium recombination (analytic approximation)
  • –> third approximation: first Helium recombination completed
  • –> fourth approximation: second Helium recombination starts (analytic approximation)
  • –> fifth approximation: second Helium recombination (full evolution for Helium), H recombination starts (analytic approximation)
  • –> last case: full evolution for H and Helium
  • –> store the results in the table
  • cleanup generic integrator with cleanup_generic_integrator()

◆ thermodynamics_derivs_with_recfast()

int thermodynamics_derivs_with_recfast ( double  z,
double *  y,
double *  dy,
void *  parameters_and_workspace,
ErrorMsg  error_message 
)

Subroutine evaluating the derivative with respect to redshift of thermodynamical quantities (from RECFAST version 1.4).

Computes derivatives of the three variables to integrate: $ d x_H / dz, d x_{He} / dz, d T_{mat} / dz $.

This is one of the few functions in the code which are passed to the generic_integrator() routine. Since generic_integrator() should work with functions passed from various modules, the format of the arguments is a bit special:

  • fixed parameters and workspaces are passed through a generic pointer. Here, this pointer contains the precision, background and recombination structures, plus a background vector, but generic_integrator() doesn't know its fine structure.
  • the error management is a bit special: errors are not written as usual to pth->error_message, but to a generic error_message passed in the list of arguments.
Parameters
zInput: redshift
yInput: vector of variable to integrate
dyOutput: its derivative (already allocated)
parameters_and_workspaceInput: pointer to fixed parameters (e.g. indices) and workspace (already allocated)
error_messageOutput: error message

◆ thermodynamics_merge_reco_and_reio()

int thermodynamics_merge_reco_and_reio ( struct precision ppr,
struct thermo pth,
struct recombination preco,
struct reionization preio 
)

This routine merges the two tables 'recombination_table' and 'reionization_table' inside the table 'thermodynamics_table', and frees the temporary structures 'recombination' and 'reionization'.

Parameters
pprInput: pointer to precision structure
pthInput/Output: pointer to thermo structure
precoInput: pointer to filled recombination structure
preioInput: pointer to reionization structure
Returns
the error status

Summary:

  • define local variables
  • first, a little check that the two tables match each other and can be merged
  • find number of redshift in full table = number in reco + number in reio - overlap
  • allocate arrays in thermo structure
  • fill these arrays
  • free the temporary structures

◆ thermodynamics_output_titles()

int thermodynamics_output_titles ( struct background pba,
struct thermo pth,
char  titles[_MAXTITLESTRINGLENGTH_] 
)

Subroutine for formatting thermodynamics output