source: Sophya/trunk/Cosmo/SimLSS/hu_power.c@ 3756

Last change on this file since 3756 was 3315, checked in by cmv, 18 years ago

add code fct transfert de W.Hu + prog de comparaison avec pkspectrum.cc cmv 24/08/2007

File size: 11.2 KB
Line 
1/* Fitting Formulae for CDM + Baryon + Massive Neutrino (MDM) cosmologies. */
2/* Daniel J. Eisenstein & Wayne Hu, Institute for Advanced Study */
3
4/* There are two primary routines here, one to set the cosmology, the
5other to construct the transfer function for a single wavenumber k.
6You should call the former once (per cosmology) and the latter as
7many times as you want. */
8
9/* TFmdm_set_cosm() -- User passes all the cosmological parameters as
10 arguments; the routine sets up all of the scalar quantites needed
11 computation of the fitting formula. The input parameters are:
12 1) omega_matter -- Density of CDM, baryons, and massive neutrinos,
13 in units of the critical density.
14 2) omega_baryon -- Density of baryons, in units of critical.
15 3) omega_hdm -- Density of massive neutrinos, in units of critical
16 4) degen_hdm -- (Int) Number of degenerate massive neutrino species
17 5) omega_lambda -- Cosmological constant
18 6) hubble -- Hubble constant, in units of 100 km/s/Mpc
19 7) redshift -- The redshift at which to evaluate */
20
21/* TFmdm_onek_mpc() -- User passes a single wavenumber, in units of Mpc^-1.
22 Routine returns the transfer function from the Eisenstein & Hu
23 fitting formula, based on the cosmology currently held in the
24 internal variables. The routine returns T_cb (the CDM+Baryon
25 density-weighted transfer function), although T_cbn (the CDM+
26 Baryon+Neutrino density-weighted transfer function) is stored
27 in the global variable tf_cbnu. */
28
29/* We also supply TFmdm_onek_hmpc(), which is identical to the previous
30 routine, but takes the wavenumber in units of h Mpc^-1. */
31
32/* We hold the internal scalar quantities in global variables, so that
33the user may access them in an external program, via "extern" declarations. */
34
35/* Please note that all internal length scales are in Mpc, not h^-1 Mpc! */
36
37/* -------------------------- Prototypes ----------------------------- */
38
39int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
40 int degen_hdm, double omega_lambda, double hubble, double redshift);
41double TFmdm_onek_mpc(double kk);
42double TFmdm_onek_hmpc(double kk);
43
44#include <math.h>
45#include <stdio.h>
46#include <stdlib.h>
47
48/* Convenience from Numerical Recipes in C, 2nd edition
49------------ COMPLETEMENT DEBILE (cmv) ????????? ------------
50static double sqrarg;
51#define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
52*/
53#define SQR(a) (a*a)
54
55/* ------------------------- Global Variables ------------------------ */
56
57/* The following are set in TFmdm_set_cosm() */
58double alpha_gamma, /* sqrt(alpha_nu) */
59 alpha_nu, /* The small-scale suppression */
60 beta_c, /* The correction to the log in the small-scale */
61 num_degen_hdm, /* Number of degenerate massive neutrino species */
62 f_baryon, /* Baryon fraction */
63 f_bnu, /* Baryon + Massive Neutrino fraction */
64 f_cb, /* Baryon + CDM fraction */
65 f_cdm, /* CDM fraction */
66 f_hdm, /* Massive Neutrino fraction */
67 growth_k0, /* D_1(z) -- the growth function as k->0 */
68 growth_to_z0, /* D_1(z)/D_1(0) -- the growth relative to z=0 */
69 hhubble, /* Need to pass Hubble constant to TFmdm_onek_hmpc() */
70 k_equality, /* The comoving wave number of the horizon at equality*/
71 obhh, /* Omega_baryon * hubble^2 */
72 omega_curv, /* = 1 - omega_matter - omega_lambda */
73 omega_lambda_z, /* Omega_lambda at the given redshift */
74 omega_matter_z, /* Omega_matter at the given redshift */
75 omhh, /* Omega_matter * hubble^2 */
76 onhh, /* Omega_hdm * hubble^2 */
77 p_c, /* The correction to the exponent before drag epoch */
78 p_cb, /* The correction to the exponent after drag epoch */
79 sound_horizon_fit, /* The sound horizon at the drag epoch */
80 theta_cmb, /* The temperature of the CMB, in units of 2.7 K */
81 y_drag, /* Ratio of z_equality to z_drag */
82 z_drag, /* Redshift of the drag epoch */
83 z_equality; /* Redshift of matter-radiation equality */
84
85/* The following are set in TFmdm_onek_mpc() */
86double gamma_eff, /* Effective \Gamma */
87 growth_cb, /* Growth factor for CDM+Baryon perturbations */
88 growth_cbnu, /* Growth factor for CDM+Baryon+Neutrino pert. */
89 max_fs_correction, /* Correction near maximal free streaming */
90 qq, /* Wavenumber rescaled by \Gamma */
91 qq_eff, /* Wavenumber rescaled by effective Gamma */
92 qq_nu, /* Wavenumber compared to maximal free streaming */
93 tf_master, /* Master TF */
94 tf_sup, /* Suppressed TF */
95 y_freestream; /* The epoch of free-streaming for a given scale */
96
97/* Finally, TFmdm_onek_mpc() and TFmdm_onek_hmpc() give their answers as */
98double tf_cb, /* The transfer function for density-weighted
99 CDM + Baryon perturbations. */
100 tf_cbnu; /* The transfer function for density-weighted
101 CDM + Baryon + Massive Neutrino perturbations. */
102
103/* By default, these functions return tf_cb */
104
105/* ------------------------- TFmdm_set_cosm() ------------------------ */
106int TFmdm_set_cosm(double omega_matter, double omega_baryon, double omega_hdm,
107 int degen_hdm, double omega_lambda, double hubble, double redshift)
108/* This routine takes cosmological parameters and a redshift and sets up
109all the internal scalar quantities needed to compute the transfer function. */
110/* INPUT: omega_matter -- Density of CDM, baryons, and massive neutrinos,
111 in units of the critical density. */
112/* omega_baryon -- Density of baryons, in units of critical. */
113/* omega_hdm -- Density of massive neutrinos, in units of critical */
114/* degen_hdm -- (Int) Number of degenerate massive neutrino species */
115/* omega_lambda -- Cosmological constant */
116/* hubble -- Hubble constant, in units of 100 km/s/Mpc */
117/* redshift -- The redshift at which to evaluate */
118/* OUTPUT: Returns 0 if all is well, 1 if a warning was issued. Otherwise,
119 sets many global variables for use in TFmdm_onek_mpc() */
120{
121 double z_drag_b1, z_drag_b2, omega_denom;
122 int qwarn;
123 qwarn = 0;
124
125 theta_cmb = 2.728/2.7; /* Assuming T_cmb = 2.728 K */
126
127 /* Look for strange input */
128 if (omega_baryon<0.0) {
129 fprintf(stderr,
130 "TFmdm_set_cosm(): Negative omega_baryon set to trace amount.\n");
131 qwarn = 1;
132 }
133 if (omega_hdm<0.0) {
134 fprintf(stderr,
135 "TFmdm_set_cosm(): Negative omega_hdm set to trace amount.\n");
136 qwarn = 1;
137 }
138 if (hubble<=0.0) {
139 fprintf(stderr,"TFmdm_set_cosm(): Negative Hubble constant illegal.\n");
140 exit(1); /* Can't recover */
141 } else if (hubble>2.0) {
142 fprintf(stderr,"TFmdm_set_cosm(): Hubble constant should be in units of 100 km/s/Mpc.\n");
143 qwarn = 1;
144 }
145 if (redshift<=-1.0) {
146 fprintf(stderr,"TFmdm_set_cosm(): Redshift < -1 is illegal.\n");
147 exit(1);
148 } else if (redshift>99.0) {
149 fprintf(stderr,
150 "TFmdm_set_cosm(): Large redshift entered. TF may be inaccurate.\n");
151 qwarn = 1;
152 }
153 if (degen_hdm<1) degen_hdm=1;
154 num_degen_hdm = (double) degen_hdm;
155 /* Have to save this for TFmdm_onek_mpc() */
156 /* This routine would crash if baryons or neutrinos were zero,
157 so don't allow that */
158 if (omega_baryon<=0) omega_baryon=1e-5;
159 if (omega_hdm<=0) omega_hdm=1e-5;
160
161 omega_curv = 1.0-omega_matter-omega_lambda;
162 omhh = omega_matter*SQR(hubble);
163 obhh = omega_baryon*SQR(hubble);
164 onhh = omega_hdm*SQR(hubble);
165 f_baryon = omega_baryon/omega_matter;
166 f_hdm = omega_hdm/omega_matter;
167 f_cdm = 1.0-f_baryon-f_hdm;
168 f_cb = f_cdm+f_baryon;
169 f_bnu = f_baryon+f_hdm;
170
171 /* Compute the equality scale. */
172 z_equality = 25000.0*omhh/SQR(SQR(theta_cmb)); /* Actually 1+z_eq */
173 k_equality = 0.0746*omhh/SQR(theta_cmb);
174
175 /* Compute the drag epoch and sound horizon */
176 z_drag_b1 = 0.313*pow(omhh,-0.419)*(1+0.607*pow(omhh,0.674));
177 z_drag_b2 = 0.238*pow(omhh,0.223);
178 z_drag = 1291*pow(omhh,0.251)/(1.0+0.659*pow(omhh,0.828))*
179 (1.0+z_drag_b1*pow(obhh,z_drag_b2));
180 y_drag = z_equality/(1.0+z_drag);
181
182 sound_horizon_fit = 44.5*log(9.83/omhh)/sqrt(1.0+10.0*pow(obhh,0.75));
183
184 /* Set up for the free-streaming & infall growth function */
185 p_c = 0.25*(5.0-sqrt(1+24.0*f_cdm));
186 p_cb = 0.25*(5.0-sqrt(1+24.0*f_cb));
187
188 omega_denom = omega_lambda+SQR(1.0+redshift)*(omega_curv+
189 omega_matter*(1.0+redshift));
190 omega_lambda_z = omega_lambda/omega_denom;
191 omega_matter_z = omega_matter*SQR(1.0+redshift)*(1.0+redshift)/omega_denom;
192 growth_k0 = z_equality/(1.0+redshift)*2.5*omega_matter_z/
193 (pow(omega_matter_z,4.0/7.0)-omega_lambda_z+
194 (1.0+omega_matter_z/2.0)*(1.0+omega_lambda_z/70.0));
195 growth_to_z0 = z_equality*2.5*omega_matter/(pow(omega_matter,4.0/7.0)
196 -omega_lambda + (1.0+omega_matter/2.0)*(1.0+omega_lambda/70.0));
197 growth_to_z0 = growth_k0/growth_to_z0;
198
199 /* Compute small-scale suppression */
200 alpha_nu = f_cdm/f_cb*(5.0-2.*(p_c+p_cb))/(5.-4.*p_cb)*
201 pow(1+y_drag,p_cb-p_c)*
202 (1+f_bnu*(-0.553+0.126*f_bnu*f_bnu))/
203 (1-0.193*sqrt(f_hdm*num_degen_hdm)+0.169*f_hdm*pow(num_degen_hdm,0.2))*
204 (1+(p_c-p_cb)/2*(1+1/(3.-4.*p_c)/(7.-4.*p_cb))/(1+y_drag));
205 alpha_gamma = sqrt(alpha_nu);
206 beta_c = 1/(1-0.949*f_bnu);
207 /* Done setting scalar variables */
208 hhubble = hubble; /* Need to pass Hubble constant to TFmdm_onek_hmpc() */
209 return qwarn;
210}
211
212/* ---------------------------- TFmdm_onek_mpc() ---------------------- */
213
214double TFmdm_onek_mpc(double kk)
215/* Given a wavenumber in Mpc^-1, return the transfer function for the
216cosmology held in the global variables. */
217/* Input: kk -- Wavenumber in Mpc^-1 */
218/* Output: The following are set as global variables:
219 growth_cb -- the transfer function for density-weighted
220 CDM + Baryon perturbations.
221 growth_cbnu -- the transfer function for density-weighted
222 CDM + Baryon + Massive Neutrino perturbations. */
223/* The function returns growth_cb */
224{
225 double tf_sup_L, tf_sup_C;
226 double temp1, temp2;
227
228 qq = kk/omhh*SQR(theta_cmb);
229
230 /* Compute the scale-dependent growth functions */
231 y_freestream = 17.2*f_hdm*(1+0.488*pow(f_hdm,-7.0/6.0))*
232 SQR(num_degen_hdm*qq/f_hdm);
233 temp1 = pow(growth_k0, 1.0-p_cb);
234 temp2 = pow(growth_k0/(1+y_freestream),0.7);
235 growth_cb = pow(1.0+temp2, p_cb/0.7)*temp1;
236 growth_cbnu = pow(pow(f_cb,0.7/p_cb)+temp2, p_cb/0.7)*temp1;
237
238 /* Compute the master function */
239 gamma_eff =omhh*(alpha_gamma+(1-alpha_gamma)/
240 (1+SQR(SQR(kk*sound_horizon_fit*0.43))));
241 qq_eff = qq*omhh/gamma_eff;
242
243 tf_sup_L = log(2.71828+1.84*beta_c*alpha_gamma*qq_eff);
244 tf_sup_C = 14.4+325/(1+60.5*pow(qq_eff,1.11));
245 tf_sup = tf_sup_L/(tf_sup_L+tf_sup_C*SQR(qq_eff));
246
247 qq_nu = 3.92*qq*sqrt(num_degen_hdm/f_hdm);
248 max_fs_correction = 1+1.2*pow(f_hdm,0.64)*pow(num_degen_hdm,0.3+0.6*f_hdm)/
249 (pow(qq_nu,-1.6)+pow(qq_nu,0.8));
250 tf_master = tf_sup*max_fs_correction;
251
252 /* Now compute the CDM+HDM+baryon transfer functions */
253 tf_cb = tf_master*growth_cb/growth_k0;
254 tf_cbnu = tf_master*growth_cbnu/growth_k0;
255 return tf_cb;
256}
257
258/* ---------------------------- TFmdm_onek_hmpc() ---------------------- */
259
260double TFmdm_onek_hmpc(double kk)
261/* Given a wavenumber in h Mpc^-1, return the transfer function for the
262cosmology held in the global variables. */
263/* Input: kk -- Wavenumber in h Mpc^-1 */
264/* Output: The following are set as global variables:
265 growth_cb -- the transfer function for density-weighted
266 CDM + Baryon perturbations.
267 growth_cbnu -- the transfer function for density-weighted
268 CDM + Baryon + Massive Neutrino perturbations. */
269/* The function returns growth_cb */
270{
271 return TFmdm_onek_mpc(kk*hhubble);
272}
273
274
Note: See TracBrowser for help on using the repository browser.