|
CLASS MANUAL
|
Include dependency graph for fourier.c:Functions | |
| int | fourier_pk_at_z (struct background *pba, struct fourier *pfo, enum linear_or_logarithmic mode, enum pk_outputs pk_output, double z, int index_pk, double *out_pk, double *out_pk_ic) |
| int | fourier_pk_at_k_and_z (struct background *pba, struct primordial *ppm, struct fourier *pfo, enum pk_outputs pk_output, double k, double z, int index_pk, double *out_pk, double *out_pk_ic) |
| int | fourier_pks_at_kvec_and_zvec (struct background *pba, struct fourier *pfo, enum pk_outputs pk_output, double *kvec, int kvec_size, double *zvec, int zvec_size, double *out_pk, double *out_pk_cb) |
| int | fourier_pk_tilt_at_k_and_z (struct background *pba, struct primordial *ppm, struct fourier *pfo, enum pk_outputs pk_output, double k, double z, int index_pk, double *pk_tilt) |
| int | fourier_sigmas_at_z (struct precision *ppr, struct background *pba, struct fourier *pfo, double R, double z, int index_pk, enum out_sigmas sigma_output, double *result) |
| int | fourier_k_nl_at_z (struct background *pba, struct fourier *pfo, double z, double *k_nl, double *k_nl_cb) |
| int | fourier_init (struct precision *ppr, struct background *pba, struct thermodynamics *pth, struct perturbations *ppt, struct primordial *ppm, struct fourier *pfo) |
| int | fourier_free (struct fourier *pfo) |
| int | fourier_indices (struct precision *ppr, struct background *pba, struct perturbations *ppt, struct primordial *ppm, struct fourier *pfo) |
| int | fourier_get_k_list (struct precision *ppr, struct primordial *ppm, struct perturbations *ppt, struct fourier *pfo) |
| int | fourier_get_tau_list (struct perturbations *ppt, struct fourier *pfo) |
| int | fourier_get_source (struct background *pba, struct perturbations *ppt, struct fourier *pfo, int index_k, int index_ic, int index_tp, int index_tau, double **sources, double *source) |
| int | fourier_pk_linear (struct background *pba, struct perturbations *ppt, struct primordial *ppm, struct fourier *pfo, int index_pk, int index_tau, int k_size, double *lnpk, double *lnpk_ic) |
| int | fourier_pk_analytic_nowiggle (struct precision *ppr, struct background *pba, struct primordial *ppm, struct fourier *pfo) |
| int | fourier_wnw_split (struct precision *ppr, struct background *pba, struct primordial *ppm, struct fourier *pfo) |
| int | fourier_sigmas (struct fourier *pfo, double R, double *lnpk_l, double *ddlnpk_l, int k_size, double k_per_decade, enum out_sigmas sigma_output, double *result) |
| int | fourier_sigma_at_z (struct background *pba, struct fourier *pfo, double R, double z, int index_pk, double k_per_decade, double *result) |
Documented fourier module
Julien Lesgourgues, 6.03.2014
New module replacing an older one present up to version 2.0 The new module is located in a better place in the main, allowing it to compute non-linear correction to
's and not just
. It will also be easier to generalize to new methods. The old implementation of one-loop calculations and TRG calculations has been dropped from this version, they can still be found in older versions.
| int fourier_pk_at_z | ( | struct background * | pba, |
| struct fourier * | pfo, | ||
| enum linear_or_logarithmic | mode, | ||
| enum pk_outputs | pk_output, | ||
| double | z, | ||
| int | index_pk, | ||
| double * | out_pk, | ||
| double * | out_pk_ic | ||
| ) |
Return the P(k,z) for a given redshift z and pk type (_m, _cb) (linear if pk_output = pk_linear, nonlinear if pk_output = pk_nonlinear, nowiggle linear spectrum if pk_output = pk_numerical_nowiggle, analytic approximation to nowiggle linear spectrum if pk_output = pk_analytic_nowiggle)
In the linear case, if there are several initial conditions and the input pointer out_pk_ic is not set to NULL, the function also returns the decomposition into different IC contributions.
In the pk_analytic_nowiggle case, the overall normalisation of the spectrum is currently arbitrary and independent of redhsift.
Hints on input index_pk:
a. if you want the total matter spectrum P_m(k,z), pass in input pfo->index_pk_total (this index is always defined)
b. if you want the power spectrum relevant for galaxy or halos, given by P_cb if there is non-cold-dark-matter (e.g. massive neutrinos) and to P_m otherwise, pass in input pfo->index_pk_cluster (this index is always defined)
c. there is another possible syntax (use it only if you know what you are doing): if pfo->has_pk_m == TRUE you may pass pfo->index_pk_m to get P_m if pfo->has_pk_cb == TRUE you may pass pfo->index_pk_cb to get P_cb
Output format:
| pba | Input: pointer to background structure |
| pfo | Input: pointer to fourier structure |
| mode | Input: linear or logarithmic |
| pk_output | Input: linear, nonlinear, nowiggle... |
| z | Input: redshift |
| index_pk | Input: index of pk type (_m, _cb) |
| out_pk | Output: P(k) returned as out_pk_l[index_k] |
| out_pk_ic | Output: P_ic(k) returned as out_pk_ic[index_k * pfo->ic_ic_size + index_ic1_ic2] |
--> get value of contormal time tau
-> check that tau is in pre-computed table
--> if ln(tau) much too small, raise an error
--> if ln(tau) too small but within tolerance, round it and get right values without interpolating
--> if ln(tau) much too large, raise an error
--> if ln(tau) too large but within tolerance, round it and get right values without interpolating
-> tau is in pre-computed table: interpolate
--> interpolate P_l(k) at tau from pre-computed array
--> interpolate P_ic_l(k) at tau from pre-computed array
--> we requested P_nl(k) at tau where P_l is computed but the NL correction is NOT -> Return P_l
--> interpolate P_nl(k) at tau from pre-computed array
--> interpolate P_l_nw(k) at tau from pre-computed array
--> loop over k
--> convert total spectrum
--> convert contribution of each ic (diagonal elements)
--> convert contribution of each ic (non-diagonal elements)
| int fourier_pk_at_k_and_z | ( | struct background * | pba, |
| struct primordial * | ppm, | ||
| struct fourier * | pfo, | ||
| enum pk_outputs | pk_output, | ||
| double | k, | ||
| double | z, | ||
| int | index_pk, | ||
| double * | out_pk, | ||
| double * | out_pk_ic | ||
| ) |
Return the P(k,z) for a given (k,z) and pk type (_m, _cb) (linear if pk_output = pk_linear, nonlinear if pk_output = pk_nonlinear, nowiggle linear spectrum if pk_output = pk_numerical_nowiggle, analytic approximation to linear nowiggle spectrum if pk_output = pk_analytic_nowiggle)
In the linear case, if there are several initial conditions and the input pointer out_pk_ic is not set to NULL, the function also returns the decomposition into different IC contributions.
Hints on input index_pk:
a. if you want the total matter spectrum P_m(k,z), pass in input pfo->index_pk_total (this index is always defined)
b. if you want the power spectrum relevant for galaxy or halos, given by P_cb if there is non-cold-dark-matter (e.g. massive neutrinos) and to P_m otherwise, pass in input pfo->index_pk_cluster (this index is always defined)
c. there is another possible syntax (use it only if you know what you are doing): if pfo->has_pk_m == TRUE you may pass pfo->index_pk_m to get P_m if pfo->has_pk_cb == TRUE you may pass pfo->index_pk_cb to get P_cb
Output format:
out_pk = P(k) out_pk_ic[diagonal] = P_ic(k) out_pk_ic[non-diagonal] = P_icxic(k)
| pba | Input: pointer to background structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input: pointer to fourier structure |
| pk_output | Input: linear, nonlinear, nowiggle... |
| k | Input: wavenumber in 1/Mpc |
| z | Input: redshift |
| index_pk | Input: index of pk type (_m, _cb) |
| out_pk | Output: pointer to P |
| out_pk_ic | Ouput: P_ic returned as out_pk_ic_l[index_ic1_ic2] |
--> First, get P(k) at the right z (in logarithmic format for more accurate interpolation, and then convert to linear format)
--> interpolate total spectrum
--> convert from logarithmic to linear format
--> interpolate each ic component
--> convert each ic component from logarithmic to linear format
--> deal with case 0 < k < kmin that requires extrapolation P(k) = [some number] * k * P_primordial(k) so P(k) = P(kmin) * (k P_primordial(k)) / (kmin P_primordial(kmin)) (note that the result is accurate only if kmin is such that [a0 kmin] << H0)
This is accurate for the synchronous gauge; TODO: write newtonian gauge case. Also, In presence of isocurvature modes, we assumes for simplicity that the mode with index_ic1_ic2=0 dominates at small k: exact treatment should be written if needed.
--> First, get P(k) at the right z (in linear format)
| int fourier_pks_at_kvec_and_zvec | ( | struct background * | pba, |
| struct fourier * | pfo, | ||
| enum pk_outputs | pk_output, | ||
| double * | kvec, | ||
| int | kvec_size, | ||
| double * | zvec, | ||
| int | zvec_size, | ||
| double * | out_pk, | ||
| double * | out_pk_cb | ||
| ) |
Return the P(k,z) for a grid of (k_i,z_j) passed in input, for all available pk types (_m, _cb), either linear or nonlinear depending on input.
If there are several initial conditions, this function is not designed to return individual contributions.
The main goal of this routine is speed. Unlike fourier_pk_at_k_and_z(), it performs no extrapolation when an input k_i falls outside the pre-computed range [kmin,kmax]: in that case, it just returns P(k,z)=0 for such a k_i
| pba | Input: pointer to background structure |
| pfo | Input: pointer to fourier structure |
| pk_output | Input: pk_linear, pk_nonlinear, nowiggle... |
| kvec | Input: array of wavenumbers in ascending order (in 1/Mpc) |
| kvec_size | Input: size of array of wavenumbers |
| zvec | Input: array of redshifts in arbitrary order |
| zvec_size | Input: size of array of redshifts |
| out_pk | Output: P(k_i,z_j) for total matter (if available) in Mpc**3 |
| out_pk_cb | Output: P_cb(k_i,z_j) for cdm+baryons (if available) in Mpc**3 |
Summary:
--> Loop through k_i's that fall in interval [k_n,k_n+1]
--> for each of them, perform spine interpolation
| int fourier_pk_tilt_at_k_and_z | ( | struct background * | pba, |
| struct primordial * | ppm, | ||
| struct fourier * | pfo, | ||
| enum pk_outputs | pk_output, | ||
| double | k, | ||
| double | z, | ||
| int | index_pk, | ||
| double * | pk_tilt | ||
| ) |
Return the logarithmic slope of P(k,z) for a given (k,z), a given pk type (_m, _cb) (computed with linear P_L if pk_output = pk_linear, nonlinear P_NL if pk_output = pk_nonlinear, nowiggle linear spectrum if pk_output = pk_numerical_nowiggle, analytic approximation to linear nowiggle spectrum if pk_output = pk_analytic_nowiggle)
| pba | Input: pointer to background structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input: pointer to fourier structure |
| pk_output | Input: linear, nonlinear, nowiggle... |
| k | Input: wavenumber in 1/Mpc |
| z | Input: redshift |
| index_pk | Input: index of pk type (_m, _cb) |
| pk_tilt | Output: logarithmic slope of P(k,z) |
| int fourier_sigmas_at_z | ( | struct precision * | ppr, |
| struct background * | pba, | ||
| struct fourier * | pfo, | ||
| double | R, | ||
| double | z, | ||
| int | index_pk, | ||
| enum out_sigmas | sigma_output, | ||
| double * | result | ||
| ) |
This routine computes the variance of density fluctuations in a sphere of radius R at redshift z, sigma(R,z), or other similar derived quantitites, for one given pk type (_m, _cb).
The integral is performed until the maximum value of k_max defined in the perturbation module. Here there is not automatic checking that k_max is large enough for the result to be well converged. E.g. to get an accurate sigma8 at R = 8 Mpc/h, the user should pass at least about P_k_max_h/Mpc = 1.
| ppr | Input: pointer to precision structure |
| pba | Input: pointer to background structure |
| pfo | Input: pointer to fourier structure |
| R | Input: radius in Mpc |
| z | Input: redshift |
| index_pk | Input: type of pk (_m, _cb) |
| sigma_output | Input: quantity to be computed (sigma, sigma', ...) |
| result | Output: result |
| int fourier_k_nl_at_z | ( | struct background * | pba, |
| struct fourier * | pfo, | ||
| double | z, | ||
| double * | k_nl, | ||
| double * | k_nl_cb | ||
| ) |
Return the value of the non-linearity wavenumber k_nl for a given redshift z
| pba | Input: pointer to background structure |
| pfo | Input: pointer to fourier structure |
| z | Input: redshift |
| k_nl | Output: k_nl value |
| k_nl_cb | Ouput: k_nl value of the cdm+baryon part only, if there is ncdm |
| int fourier_init | ( | struct precision * | ppr, |
| struct background * | pba, | ||
| struct thermodynamics * | pth, | ||
| struct perturbations * | ppt, | ||
| struct primordial * | ppm, | ||
| struct fourier * | pfo | ||
| ) |
Initialize the fourier structure, and in particular the nl_corr_density and k_nl interpolation tables.
| ppr | Input: pointer to precision structure |
| pba | Input: pointer to background structure |
| pth | Input: pointer to therodynamics structure |
| ppt | Input: pointer to perturbation structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input/Output: pointer to initialized fourier structure |
--> This module only makes sense for dealing with scalar perturbations, so it should do nothing if there are no scalars
--> Nothing to be done if we don't want the matter power spectrum
--> check applicability of Halofit and HMcode
--> loop over required pk types (_m, _cb)
--> get the linear power spectrum for this time and this type
--> one more call to get the linear power spectrum extrapolated up to very large k, for this time and type, but ignoring the case of multiple initial conditions. Result stored in ln_pk_l_extra (different from non-extrapolated ln_pk_l)
will be needed (as a function of tau), compute array of second derivatives in view of spline interpolation--> First deal with the case where non non-linear corrections requested
--> Then go through common preliminary steps to the HALOFIT and HMcode methods
--> allocate temporary arrays for spectra at each given time/redshift
--> Then go through preliminary steps specific to HMcode
--> Loop over decreasing time/growing redhsift. For each time/redshift, compute P_NL(k,z) using either Halofit or HMcode
--> spline the array of nonlinear power spectrum (only above the first index where it could be computed)
--> free the nonlinear workspace
| int fourier_free | ( | struct fourier * | pfo | ) |
Free all memory space allocated by fourier_init().
| pfo | Input: pointer to fourier structure (to be freed) |
| int fourier_indices | ( | struct precision * | ppr, |
| struct background * | pba, | ||
| struct perturbations * | ppt, | ||
| struct primordial * | ppm, | ||
| struct fourier * | pfo | ||
| ) |
Define indices in the fourier structure, and when possible, allocate arrays in this structure given the index sizes found here
| ppr | Input: pointer to precision structure |
| pba | Input: pointer to background structure |
| ppt | Input: pointer to perturbation structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input/Output: pointer to fourier structure |
will be needed (as a function of tau), compute also the array of second derivatives in view of spline interpolation| int fourier_get_k_list | ( | struct precision * | ppr, |
| struct primordial * | ppm, | ||
| struct perturbations * | ppt, | ||
| struct fourier * | pfo | ||
| ) |
Copy list of k from perturbation module, and extended it if necessary to larger k for extrapolation (currently this extrapolation is required only by HMcode)
| ppr | Input: pointer to precision structure |
| ppm | Input: pointer to primordial structure |
| ppt | Input: pointer to perturbation structure |
| pfo | Input/Output: pointer to fourier structure |
| int fourier_get_tau_list | ( | struct perturbations * | ppt, |
| struct fourier * | pfo | ||
| ) |
Copy list of tau from perturbation module
| ppt | Input: pointer to perturbation structure |
| pfo | Input/Output: pointer to fourier structure |
-> for linear calculations: only late times are considered, given the value z_max_pk inferred from the ionput
-> for non-linear calculations: we wills store a correction factor for all times
| int fourier_get_source | ( | struct background * | pba, |
| struct perturbations * | ppt, | ||
| struct fourier * | pfo, | ||
| int | index_k, | ||
| int | index_ic, | ||
| int | index_tp, | ||
| int | index_tau, | ||
| double ** | sources, | ||
| double * | source | ||
| ) |
Get sources for a given wavenumber (and for a given time, type, ic, mode...) either directly from precomputed valkues (computed ain perturbation module), or by analytic extrapolation
| pba | Input: pointer to background structure |
| ppt | Input: pointer to perturbation structure |
| pfo | Input: pointer to fourier structure |
| index_k | Input: index of required k value |
| index_ic | Input: index of required ic value |
| index_tp | Input: index of required tp value |
| index_tau | Input: index of required tau value |
| sources | Input: array containing the original sources |
| source | Output: desired value of source |
--> Get last source and k, which are used in (almost) all methods
--> Get previous source and k, which are used in best methods
--> Extrapolate by assuming the source to vanish Has terrible discontinuity
--> Extrapolate starting from the maximum value, assuming growth ~ ln(k) Has a terrible bend in log slope, discontinuity only in derivative
--> Extrapolate starting from the maximum value, assuming growth ~ ln(k) Here we use k in h/Mpc instead of 1/Mpc as it is done in the CAMB implementation of HMcode Has a terrible bend in log slope, discontinuity only in derivative
--> Extrapolate assuming source ~ ln(a*k) where a is obtained from the data at k_0 Mostly continuous derivative, quite good
--> Extrapolate assuming source ~ ln(e+a*k) where a is estimated like is done in original HMCode
--> If the user has a complicated model and wants to interpolate differently, they can define their interpolation here and switch to using it instead
| int fourier_pk_linear | ( | struct background * | pba, |
| struct perturbations * | ppt, | ||
| struct primordial * | ppm, | ||
| struct fourier * | pfo, | ||
| int | index_pk, | ||
| int | index_tau, | ||
| int | k_size, | ||
| double * | lnpk, | ||
| double * | lnpk_ic | ||
| ) |
This routine computes all the components of the matter power spectrum P(k), given the source functions and the primordial spectra, at a given time within the pre-computed table of sources (= Fourier transfer functions) of the perturbation module, for a given type (total matter _m or baryon+CDM _cb), and for the same array of k values as in the pre-computed table.
If the input array of k values pfo->ln_k contains wavemumbers larger than those of the pre-computed table, the sources will be extrapolated analytically.
On the opther hand, if the primordial spectrum has sharp features and needs to be sampled on a finer grid than the sources, this function has to be modified to capture the features.
There are two output arrays, because we consider:
– the index_ic1_ic2 labels ordered pairs (index_ic1, index_ic2) (since the primordial spectrum is symmetric in (index_ic1, index_ic2)).
– for diagonal elements (index_ic1 = index_ic2) this arrays contains ln[P(k)] where P(k) is positive by construction.
– for non-diagonal elements this arrays contains the k-dependent cosine of the correlation angle, namely P(k)_(index_ic1, index_ic2)/sqrt[P(k)_index_ic1 P(k)_index_ic2]. E.g. for fully correlated or anti-correlated initial conditions, this non-diagonal element is independent on k, and equal to +1 or -1.
| pba | Input: pointer to background structure |
| ppt | Input: pointer to perturbation structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input: pointer to fourier structure |
| index_pk | Input: index of required P(k) type (_m, _cb) |
| index_tau | Input: index of time |
| k_size | Input: wavenumber array size |
| lnpk | Output: log of matter power spectrum for given type/time, for all wavenumbers |
| lnpk_ic | Output: log of matter power spectrum for given type/time, for all wavenumbers and initial conditions |
--> get primordial spectrum
--> initialize a local variable for P_m(k) and P_cb(k) to zero
--> here we recall the relations relevant for the nomalization fo the power spectrum: For adiabatic modes, the curvature primordial spectrum thnat we just read was: P_R(k) = 1/(2pi^2) k^3 < R R > Thus the primordial curvature correlator is given by: < R R > = (2pi^2) k^-3 P_R(k) So the delta_m correlator reads: P(k) = < delta_m delta_m > = (source_m)^2 < R R > = (2pi^2) k^-3 (source_m)^2 P_R(k)
For isocurvature or cross adiabatic-isocurvature parts, one would just replace one or two 'R' by 'S_i's
--> get contributions to P(k) diagonal in the initial conditions
--> get contributions to P(k) non-diagonal in the initial conditions
| int fourier_pk_analytic_nowiggle | ( | struct precision * | ppr, |
| struct background * | pba, | ||
| struct primordial * | ppm, | ||
| struct fourier * | pfo | ||
| ) |
Compute a smooth analytic approximation to the matter power spectrum today. Store the results in the fourier structure.
| ppr | Input: pointer to precision structure |
| pba | Input: pointer to background structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input/Output: pointer to fourier structure |
| int fourier_wnw_split | ( | struct precision * | ppr, |
| struct background * | pba, | ||
| struct primordial * | ppm, | ||
| struct fourier * | pfo | ||
| ) |
Compute the decomposition of the linear power spectrum into a wiggly and a non-wiggly part. Store the results in the fourier structure.
| ppr | Input: pointer to precision structure |
| pba | Input: pointer to background structure |
| ppm | Input: pointer to primordial structure |
| pfo | Input/Output: pointer to fourier structure |
| int fourier_sigmas | ( | struct fourier * | pfo, |
| double | R, | ||
| double * | lnpk_l, | ||
| double * | ddlnpk_l, | ||
| int | k_size, | ||
| double | k_per_decade, | ||
| enum out_sigmas | sigma_output, | ||
| double * | result | ||
| ) |
Calculate intermediate quantities for hmcode (sigma, sigma', ...) for a given scale R and a given input P(k).
This function has several differences w.r.t. the standard external function non_linear_sigma (format of input, of output, integration stepsize, management of extrapolation at large k, ...) and is overall more precise for sigma(R).
| pfo | Input: pointer to fourier structure |
| R | Input: scale at which to compute sigma |
| lnpk_l | Input: array of ln(P(k)) |
| ddlnpk_l | Input: its spline along k |
| k_size | Input: dimension of array lnpk_l, normally pfo->k_size, but inside hmcode it its increased by extrapolation to pfo->k_extra_size |
| k_per_decade | Input: logarithmic step for the integral (recommended: pass ppr->sigma_k_per_decade) |
| sigma_output | Input: quantity to be computed (sigma, sigma', ...) |
| result | Output: result |
| int fourier_sigma_at_z | ( | struct background * | pba, |
| struct fourier * | pfo, | ||
| double | R, | ||
| double | z, | ||
| int | index_pk, | ||
| double | k_per_decade, | ||
| double * | result | ||
| ) |
This routine computes the variance of density fluctuations in a sphere of radius R at redshift z, sigma(R,z) for one given pk type (_m, _cb).
Try to use instead fourier_sigmas_at_z(). This function is just maintained for compatibility with the deprecated function harmonic_sigma()
The integral is performed until the maximum value of k_max defined in the perturbation module. Here there is not automatic checking that k_max is large enough for the result to be well converged. E.g. to get an accurate sigma8 at R = 8 Mpc/h, the user should pass at least about P_k_max_h/Mpc = 1.
| pba | Input: pointer to background structure |
| pfo | Input: pointer to fourier structure |
| R | Input: radius in Mpc |
| z | Input: redshift |
| index_pk | Input: type of pk (_m, _cb) |
| k_per_decade | Input: logarithmic step for the integral (recommended: pass ppr->sigma_k_per_decade) |
| result | Output: result |