| 1 | /* The following routines implement all of the fitting formulae in 
 | 
|---|
| 2 | Eisenstein \& Hu (1997) */
 | 
|---|
| 3 | 
 | 
|---|
| 4 | /* There are two sets of routines here.  The first set,
 | 
|---|
| 5 | 
 | 
|---|
| 6 |         TFfit_hmpc(), TFset_parameters(), and TFfit_onek(),
 | 
|---|
| 7 | 
 | 
|---|
| 8 | calculate the transfer function for an arbitrary CDM+baryon universe using
 | 
|---|
| 9 | the fitting formula in Section 3 of the paper.  The second set,
 | 
|---|
| 10 | 
 | 
|---|
| 11 |         TFsound_horizon_fit(), TFk_peak(), TFnowiggles(), and TFzerobaryon(),
 | 
|---|
| 12 | 
 | 
|---|
| 13 | calculate other quantities given in Section 4 of the paper. */
 | 
|---|
| 14 | 
 | 
|---|
| 15 | #include <math.h>
 | 
|---|
| 16 | #include <stdio.h>
 | 
|---|
| 17 | #include <stdlib.h>
 | 
|---|
| 18 | 
 | 
|---|
| 19 | void TFset_parameters(double omega0hh, double f_baryon, double Tcmb);
 | 
|---|
| 20 | double TFfit_onek(double k, double *tf_baryon, double *tf_cdm); 
 | 
|---|
| 21 | 
 | 
|---|
| 22 | void TFfit_hmpc(double omega0, double f_baryon, double hubble, double Tcmb,
 | 
|---|
| 23 |         int numk, double *k, double *tf_full, double *tf_baryon, double *tf_cdm);
 | 
|---|
| 24 | 
 | 
|---|
| 25 | double TFsound_horizon_fit(double omega0, double f_baryon, double hubble);
 | 
|---|
| 26 | double TFk_peak(double omega0, double f_baryon, double hubble);
 | 
|---|
| 27 | double TFnowiggles(double omega0, double f_baryon, double hubble, 
 | 
|---|
| 28 |                 double Tcmb, double k_hmpc);
 | 
|---|
| 29 | double TFzerobaryon(double omega0, double hubble, double Tcmb, double k_hmpc);
 | 
|---|
| 30 | 
 | 
|---|
| 31 | /* ------------------------ DRIVER ROUTINE --------------------------- */
 | 
|---|
| 32 | /* The following is an example of a driver routine you might use. */
 | 
|---|
| 33 | /* Basically, the driver routine needs to call TFset_parameters() to
 | 
|---|
| 34 | set all the scalar parameters, and then call TFfit_onek() for each 
 | 
|---|
| 35 | wavenumber k you desire. */
 | 
|---|
| 36 | 
 | 
|---|
| 37 | /* While the routines use Mpc^-1 units internally, this driver has been
 | 
|---|
| 38 | written to take an array of wavenumbers in units of h Mpc^-1.  On the
 | 
|---|
| 39 | other hand, if you want to use Mpc^-1 externally, you can do this by
 | 
|---|
| 40 | altering the variables you pass to the driver:  
 | 
|---|
| 41 |         omega0 -> omega0*hubble*hubble, hubble -> 1.0           */
 | 
|---|
| 42 | 
 | 
|---|
| 43 | /* INPUT: omega0 -- the matter density (baryons+CDM) in units of critical 
 | 
|---|
| 44 |           f_baryon -- the ratio of baryon density to matter density 
 | 
|---|
| 45 |           hubble -- the Hubble constant, in units of 100 km/s/Mpc
 | 
|---|
| 46 |           Tcmb -- the CMB temperature in Kelvin. T<=0 uses the COBE value 2.728.
 | 
|---|
| 47 |           numk -- the length of the following zero-offset array
 | 
|---|
| 48 |           k[] -- the array of wavevectors k[0..numk-1]  */
 | 
|---|
| 49 | 
 | 
|---|
| 50 | /* INPUT/OUTPUT: There are three output arrays of transfer functions. 
 | 
|---|
| 51 | All are zero-offset and, if used, must have storage [0..numk-1] declared
 | 
|---|
| 52 | in the calling program.  However, if you substitute the NULL pointer for
 | 
|---|
| 53 | one or more of the arrays, then that particular transfer function won't
 | 
|---|
| 54 | be outputted. The transfer functions are:
 | 
|---|
| 55 | 
 | 
|---|
| 56 |         tf_full[] -- The full fitting formula, eq. (16), for the matter
 | 
|---|
| 57 |                         transfer function. 
 | 
|---|
| 58 |         tf_baryon[] -- The baryonic piece of the full fitting formula, eq. 21.
 | 
|---|
| 59 |         tf_cdm[] -- The CDM piece of the full fitting formula, eq. 17. */
 | 
|---|
| 60 | 
 | 
|---|
| 61 | /* Again, you can set these pointers to NULL in the function call if
 | 
|---|
| 62 | you don't want a particular output. */
 | 
|---|
| 63 | 
 | 
|---|
| 64 | /* Various intermediate scalar quantities are stored in global variables, 
 | 
|---|
| 65 | so that you might more easily access them.  However, this also means that
 | 
|---|
| 66 | you would be better off not simply #include'ing this file in your programs,
 | 
|---|
| 67 | but rather compiling it separately, calling only the driver, and using
 | 
|---|
| 68 | extern declarations to access the intermediate quantities. */
 | 
|---|
| 69 | 
 | 
|---|
| 70 | /* ----------------------------- DRIVER ------------------------------- */
 | 
|---|
| 71 | 
 | 
|---|
| 72 | void TFfit_hmpc(double omega0, double f_baryon, double hubble, double Tcmb,
 | 
|---|
| 73 |         int numk, double *k, double *tf_full, double *tf_baryon, double *tf_cdm)
 | 
|---|
| 74 | /* Remember: k[0..numk-1] is in units of h Mpc^-1. */
 | 
|---|
| 75 | {
 | 
|---|
| 76 |     int j;
 | 
|---|
| 77 |     double tf_thisk, baryon_piece, cdm_piece;
 | 
|---|
| 78 | 
 | 
|---|
| 79 |     TFset_parameters(omega0*hubble*hubble, f_baryon, Tcmb);
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     for (j=0;j<numk;j++) {
 | 
|---|
| 82 |         tf_thisk = TFfit_onek(k[j]*hubble, &baryon_piece, &cdm_piece); 
 | 
|---|
| 83 |         if (tf_full!=NULL) tf_full[j] = tf_thisk;
 | 
|---|
| 84 |         if (tf_baryon!=NULL) tf_baryon[j] = baryon_piece;
 | 
|---|
| 85 |         if (tf_cdm!=NULL) tf_cdm[j] = cdm_piece;
 | 
|---|
| 86 |     }
 | 
|---|
| 87 |     return;
 | 
|---|
| 88 | }
 | 
|---|
| 89 | 
 | 
|---|
| 90 | /* ------------------------ FITTING FORMULAE ROUTINES ----------------- */
 | 
|---|
| 91 | 
 | 
|---|
| 92 | /* There are two routines here.  TFset_parameters() sets all the scalar
 | 
|---|
| 93 | parameters, while TFfit_onek() calculates the transfer function for a 
 | 
|---|
| 94 | given wavenumber k.  TFfit_onek() may be called many times after a single
 | 
|---|
| 95 | call to TFset_parameters() */
 | 
|---|
| 96 | 
 | 
|---|
| 97 | /* Global variables -- We've left many of the intermediate results as 
 | 
|---|
| 98 | global variables in case you wish to access them, e.g. by declaring
 | 
|---|
| 99 | them as extern variables in your main program. */
 | 
|---|
| 100 | /* Note that all internal scales are in Mpc, without any Hubble constants! */
 | 
|---|
| 101 | 
 | 
|---|
| 102 | double  omhh,           /* Omega_matter*h^2 */
 | 
|---|
| 103 |         obhh,           /* Omega_baryon*h^2 */
 | 
|---|
| 104 |         theta_cmb,      /* Tcmb in units of 2.7 K */
 | 
|---|
| 105 |         z_equality,     /* Redshift of matter-radiation equality, really 1+z */
 | 
|---|
| 106 |         k_equality,     /* Scale of equality, in Mpc^-1 */
 | 
|---|
| 107 |         z_drag,         /* Redshift of drag epoch */
 | 
|---|
| 108 |         R_drag,         /* Photon-baryon ratio at drag epoch */
 | 
|---|
| 109 |         R_equality,     /* Photon-baryon ratio at equality epoch */
 | 
|---|
| 110 |         sound_horizon,  /* Sound horizon at drag epoch, in Mpc */
 | 
|---|
| 111 |         k_silk,         /* Silk damping scale, in Mpc^-1 */
 | 
|---|
| 112 |         alpha_c,        /* CDM suppression */
 | 
|---|
| 113 |         beta_c,         /* CDM log shift */
 | 
|---|
| 114 |         alpha_b,        /* Baryon suppression */
 | 
|---|
| 115 |         beta_b,         /* Baryon envelope shift */
 | 
|---|
| 116 |         beta_node,      /* Sound horizon shift */
 | 
|---|
| 117 |         k_peak,         /* Fit to wavenumber of first peak, in Mpc^-1 */
 | 
|---|
| 118 |         sound_horizon_fit,      /* Fit to sound horizon, in Mpc */
 | 
|---|
| 119 |         alpha_gamma;    /* Gamma suppression in approximate TF */
 | 
|---|
| 120 | 
 | 
|---|
| 121 | /* Convenience from Numerical Recipes in C, 2nd edition
 | 
|---|
| 122 | ------------ COMPLETEMENT DEBILE (cmv) ????????? ------------
 | 
|---|
| 123 | static double sqrarg;
 | 
|---|
| 124 | #define SQR(a) ((sqrarg=(a)) == 0.0 ? 0.0 : sqrarg*sqrarg)
 | 
|---|
| 125 | static double cubearg;
 | 
|---|
| 126 | #define CUBE(a) ((cubearg=(a)) == 0.0 ? 0.0 : cubearg*cubearg*cubearg)
 | 
|---|
| 127 | static double pow4arg;
 | 
|---|
| 128 | #define POW4(a) ((pow4arg=(a)) == 0.0 ? 0.0 : pow4arg*pow4arg*pow4arg*pow4arg)
 | 
|---|
| 129 |         Yes, I know the last one isn't optimal; it doesn't appear much */
 | 
|---|
| 130 | #define SQR(a) (a*a)
 | 
|---|
| 131 | #define CUBE(a) (a*a*a)
 | 
|---|
| 132 | #define POW4(a) (a*a*a*a)
 | 
|---|
| 133 | 
 | 
|---|
| 134 | void TFset_parameters(double omega0hh, double f_baryon, double Tcmb)
 | 
|---|
| 135 | /* Set all the scalars quantities for Eisenstein & Hu 1997 fitting formula */
 | 
|---|
| 136 | /* Input: omega0hh -- The density of CDM and baryons, in units of critical dens,
 | 
|---|
| 137 |                 multiplied by the square of the Hubble constant, in units
 | 
|---|
| 138 |                 of 100 km/s/Mpc */
 | 
|---|
| 139 | /*        f_baryon -- The fraction of baryons to CDM */
 | 
|---|
| 140 | /*        Tcmb -- The temperature of the CMB in Kelvin.  Tcmb<=0 forces use
 | 
|---|
| 141 |                         of the COBE value of  2.728 K. */
 | 
|---|
| 142 | /* Output: Nothing, but set many global variables used in TFfit_onek(). 
 | 
|---|
| 143 | You can access them yourself, if you want. */
 | 
|---|
| 144 | /* Note: Units are always Mpc, never h^-1 Mpc. */
 | 
|---|
| 145 | {
 | 
|---|
| 146 |     double z_drag_b1, z_drag_b2;
 | 
|---|
| 147 |     double alpha_c_a1, alpha_c_a2, beta_c_b1, beta_c_b2, alpha_b_G, y;
 | 
|---|
| 148 | 
 | 
|---|
| 149 |     if (f_baryon<=0.0 || omega0hh<=0.0) {
 | 
|---|
| 150 |         fprintf(stderr, "TFset_parameters(): Illegal input.\n");
 | 
|---|
| 151 |         exit(1);
 | 
|---|
| 152 |     }
 | 
|---|
| 153 |     omhh = omega0hh;
 | 
|---|
| 154 |     obhh = omhh*f_baryon;
 | 
|---|
| 155 |     if (Tcmb<=0.0) Tcmb=2.728;  /* COBE FIRAS */
 | 
|---|
| 156 |     theta_cmb = Tcmb/2.7;
 | 
|---|
| 157 | 
 | 
|---|
| 158 |     z_equality = 2.50e4*omhh/POW4(theta_cmb);  /* Really 1+z */
 | 
|---|
| 159 |     k_equality = 0.0746*omhh/SQR(theta_cmb);
 | 
|---|
| 160 | 
 | 
|---|
| 161 |     z_drag_b1 = 0.313*pow(omhh,-0.419)*(1+0.607*pow(omhh,0.674));
 | 
|---|
| 162 |     z_drag_b2 = 0.238*pow(omhh,0.223);
 | 
|---|
| 163 |     z_drag = 1291*pow(omhh,0.251)/(1+0.659*pow(omhh,0.828))*
 | 
|---|
| 164 |                 (1+z_drag_b1*pow(obhh,z_drag_b2));
 | 
|---|
| 165 |     
 | 
|---|
| 166 |     R_drag = 31.5*obhh/POW4(theta_cmb)*(1000/(1+z_drag));
 | 
|---|
| 167 |     R_equality = 31.5*obhh/POW4(theta_cmb)*(1000/z_equality);
 | 
|---|
| 168 | 
 | 
|---|
| 169 |     sound_horizon = 2./3./k_equality*sqrt(6./R_equality)*
 | 
|---|
| 170 |             log((sqrt(1+R_drag)+sqrt(R_drag+R_equality))/(1+sqrt(R_equality)));
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     k_silk = 1.6*pow(obhh,0.52)*pow(omhh,0.73)*(1+pow(10.4*omhh,-0.95));
 | 
|---|
| 173 | 
 | 
|---|
| 174 |     alpha_c_a1 = pow(46.9*omhh,0.670)*(1+pow(32.1*omhh,-0.532));
 | 
|---|
| 175 |     alpha_c_a2 = pow(12.0*omhh,0.424)*(1+pow(45.0*omhh,-0.582));
 | 
|---|
| 176 |     alpha_c = pow(alpha_c_a1,-f_baryon)*
 | 
|---|
| 177 |                 pow(alpha_c_a2,-CUBE(f_baryon));
 | 
|---|
| 178 |     
 | 
|---|
| 179 |     beta_c_b1 = 0.944/(1+pow(458*omhh,-0.708));
 | 
|---|
| 180 |     beta_c_b2 = pow(0.395*omhh, -0.0266);
 | 
|---|
| 181 |     beta_c = 1.0/(1+beta_c_b1*(pow(1-f_baryon, beta_c_b2)-1));
 | 
|---|
| 182 | 
 | 
|---|
| 183 |     y = z_equality/(1+z_drag);
 | 
|---|
| 184 |     alpha_b_G = y*(-6.*sqrt(1+y)+(2.+3.*y)*log((sqrt(1+y)+1)/(sqrt(1+y)-1)));
 | 
|---|
| 185 |     alpha_b = 2.07*k_equality*sound_horizon*pow(1+R_drag,-0.75)*alpha_b_G;
 | 
|---|
| 186 | 
 | 
|---|
| 187 |     beta_node = 8.41*pow(omhh, 0.435);
 | 
|---|
| 188 |     beta_b = 0.5+f_baryon+(3.-2.*f_baryon)*sqrt(pow(17.2*omhh,2.0)+1);
 | 
|---|
| 189 | 
 | 
|---|
| 190 |     k_peak = 2.5*3.14159*(1+0.217*omhh)/sound_horizon;
 | 
|---|
| 191 |     sound_horizon_fit = 44.5*log(9.83/omhh)/sqrt(1+10.0*pow(obhh,0.75));
 | 
|---|
| 192 | 
 | 
|---|
| 193 |     alpha_gamma = 1-0.328*log(431.0*omhh)*f_baryon + 0.38*log(22.3*omhh)*
 | 
|---|
| 194 |                 SQR(f_baryon);
 | 
|---|
| 195 |     
 | 
|---|
| 196 |     return;
 | 
|---|
| 197 | }
 | 
|---|
| 198 | 
 | 
|---|
| 199 | double TFfit_onek(double k, double *tf_baryon, double *tf_cdm)
 | 
|---|
| 200 | /* Input: k -- Wavenumber at which to calculate transfer function, in Mpc^-1.
 | 
|---|
| 201 |           *tf_baryon, *tf_cdm -- Input value not used; replaced on output if
 | 
|---|
| 202 |                                 the input was not NULL. */
 | 
|---|
| 203 | /* Output: Returns the value of the full transfer function fitting formula.
 | 
|---|
| 204 |                 This is the form given in Section 3 of Eisenstein & Hu (1997).
 | 
|---|
| 205 |           *tf_baryon -- The baryonic contribution to the full fit.
 | 
|---|
| 206 |           *tf_cdm -- The CDM contribution to the full fit. */
 | 
|---|
| 207 | /* Notes: Units are Mpc, not h^-1 Mpc. */
 | 
|---|
| 208 | {
 | 
|---|
| 209 |     double T_c_ln_beta, T_c_ln_nobeta, T_c_C_alpha, T_c_C_noalpha;
 | 
|---|
| 210 |     double q, xx, xx_tilde, q_eff;
 | 
|---|
| 211 |     double T_c_f, T_c, s_tilde, T_b_T0, T_b, f_baryon, T_full;
 | 
|---|
| 212 |     double T_0_L0, T_0_C0, T_0, gamma_eff; 
 | 
|---|
| 213 |     double T_nowiggles_L0, T_nowiggles_C0, T_nowiggles;
 | 
|---|
| 214 | 
 | 
|---|
| 215 |     k = fabs(k);        /* Just define negative k as positive */
 | 
|---|
| 216 |     if (k==0.0) {
 | 
|---|
| 217 |         if (tf_baryon!=NULL) *tf_baryon = 1.0;
 | 
|---|
| 218 |         if (tf_cdm!=NULL) *tf_cdm = 1.0;
 | 
|---|
| 219 |         return 1.0;
 | 
|---|
| 220 |     }
 | 
|---|
| 221 | 
 | 
|---|
| 222 |     q = k/13.41/k_equality;
 | 
|---|
| 223 |     xx = k*sound_horizon;
 | 
|---|
| 224 | 
 | 
|---|
| 225 |     T_c_ln_beta = log(2.718282+1.8*beta_c*q);
 | 
|---|
| 226 |     T_c_ln_nobeta = log(2.718282+1.8*q);
 | 
|---|
| 227 |     T_c_C_alpha = 14.2/alpha_c + 386.0/(1+69.9*pow(q,1.08));
 | 
|---|
| 228 |     T_c_C_noalpha = 14.2 + 386.0/(1+69.9*pow(q,1.08));
 | 
|---|
| 229 | 
 | 
|---|
| 230 |     T_c_f = 1.0/(1.0+POW4(xx/5.4));
 | 
|---|
| 231 |     T_c = T_c_f*T_c_ln_beta/(T_c_ln_beta+T_c_C_noalpha*SQR(q)) +
 | 
|---|
| 232 |             (1-T_c_f)*T_c_ln_beta/(T_c_ln_beta+T_c_C_alpha*SQR(q));
 | 
|---|
| 233 |     
 | 
|---|
| 234 |     s_tilde = sound_horizon*pow(1+CUBE(beta_node/xx),-1./3.);
 | 
|---|
| 235 |     xx_tilde = k*s_tilde;
 | 
|---|
| 236 | 
 | 
|---|
| 237 |     T_b_T0 = T_c_ln_nobeta/(T_c_ln_nobeta+T_c_C_noalpha*SQR(q));
 | 
|---|
| 238 |     T_b = sin(xx_tilde)/(xx_tilde)*(T_b_T0/(1+SQR(xx/5.2))+
 | 
|---|
| 239 |                 alpha_b/(1+CUBE(beta_b/xx))*exp(-pow(k/k_silk,1.4)));
 | 
|---|
| 240 | 
 | 
|---|
| 241 |     f_baryon = obhh/omhh;
 | 
|---|
| 242 |     T_full = f_baryon*T_b + (1-f_baryon)*T_c;
 | 
|---|
| 243 | 
 | 
|---|
| 244 |     /* Now to store these transfer functions */
 | 
|---|
| 245 |     if (tf_baryon!=NULL) *tf_baryon = T_b;
 | 
|---|
| 246 |     if (tf_cdm!=NULL) *tf_cdm = T_c;
 | 
|---|
| 247 |     return T_full;
 | 
|---|
| 248 | }
 | 
|---|
| 249 | 
 | 
|---|
| 250 | /* ======================= Approximate forms =========================== */
 | 
|---|
| 251 | 
 | 
|---|
| 252 | double TFsound_horizon_fit(double omega0, double f_baryon, double hubble)
 | 
|---|
| 253 | /* Input: omega0 -- CDM density, in units of critical density
 | 
|---|
| 254 |           f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
 | 
|---|
| 255 |           hubble -- Hubble constant, in units of 100 km/s/Mpc */
 | 
|---|
| 256 | /* Output: The approximate value of the sound horizon, in h^-1 Mpc. */
 | 
|---|
| 257 | /* Note: If you prefer to have the answer in  units of Mpc, use hubble -> 1
 | 
|---|
| 258 | and omega0 -> omega0*hubble^2. */ 
 | 
|---|
| 259 | {
 | 
|---|
| 260 |     double omhh, sound_horizon_fit_mpc;
 | 
|---|
| 261 |     omhh = omega0*hubble*hubble;
 | 
|---|
| 262 |     sound_horizon_fit_mpc = 
 | 
|---|
| 263 |         44.5*log(9.83/omhh)/sqrt(1+10.0*pow(omhh*f_baryon,0.75));
 | 
|---|
| 264 |     return sound_horizon_fit_mpc*hubble;
 | 
|---|
| 265 | }
 | 
|---|
| 266 | 
 | 
|---|
| 267 | double TFk_peak(double omega0, double f_baryon, double hubble)
 | 
|---|
| 268 | /* Input: omega0 -- CDM density, in units of critical density
 | 
|---|
| 269 |           f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
 | 
|---|
| 270 |           hubble -- Hubble constant, in units of 100 km/s/Mpc */
 | 
|---|
| 271 | /* Output: The approximate location of the first baryonic peak, in h Mpc^-1 */
 | 
|---|
| 272 | /* Note: If you prefer to have the answer in  units of Mpc^-1, use hubble -> 1
 | 
|---|
| 273 | and omega0 -> omega0*hubble^2. */ 
 | 
|---|
| 274 | {
 | 
|---|
| 275 |     double omhh, k_peak_mpc;
 | 
|---|
| 276 |     omhh = omega0*hubble*hubble;
 | 
|---|
| 277 |     k_peak_mpc = 2.5*3.14159*(1+0.217*omhh)/TFsound_horizon_fit(omhh,f_baryon,1.0);
 | 
|---|
| 278 |     return k_peak_mpc/hubble;
 | 
|---|
| 279 | }
 | 
|---|
| 280 | 
 | 
|---|
| 281 | double TFnowiggles(double omega0, double f_baryon, double hubble, 
 | 
|---|
| 282 |                 double Tcmb, double k_hmpc)
 | 
|---|
| 283 | /* Input: omega0 -- CDM density, in units of critical density
 | 
|---|
| 284 |           f_baryon -- Baryon fraction, the ratio of baryon to CDM density.
 | 
|---|
| 285 |           hubble -- Hubble constant, in units of 100 km/s/Mpc
 | 
|---|
| 286 |           Tcmb -- Temperature of the CMB in Kelvin; Tcmb<=0 forces use of
 | 
|---|
| 287 |                         COBE FIRAS value of 2.728 K
 | 
|---|
| 288 |           k_hmpc -- Wavenumber in units of (h Mpc^-1). */
 | 
|---|
| 289 | /* Output: The value of an approximate transfer function that captures the
 | 
|---|
| 290 | non-oscillatory part of a partial baryon transfer function.  In other words,
 | 
|---|
| 291 | the baryon oscillations are left out, but the suppression of power below
 | 
|---|
| 292 | the sound horizon is included. See equations (30) and (31).  */
 | 
|---|
| 293 | /* Note: If you prefer to use wavenumbers in units of Mpc^-1, use hubble -> 1
 | 
|---|
| 294 | and omega0 -> omega0*hubble^2. */ 
 | 
|---|
| 295 | {
 | 
|---|
| 296 |     double k, omhh, theta_cmb, k_equality, q, xx, alpha_gamma, gamma_eff;
 | 
|---|
| 297 |     double q_eff, T_nowiggles_L0, T_nowiggles_C0;
 | 
|---|
| 298 | 
 | 
|---|
| 299 |     k = k_hmpc*hubble;  /* Convert to Mpc^-1 */
 | 
|---|
| 300 |     omhh = omega0*hubble*hubble;
 | 
|---|
| 301 |     if (Tcmb<=0.0) Tcmb=2.728;  /* COBE FIRAS */
 | 
|---|
| 302 |     theta_cmb = Tcmb/2.7;
 | 
|---|
| 303 | 
 | 
|---|
| 304 |     k_equality = 0.0746*omhh/SQR(theta_cmb);
 | 
|---|
| 305 |     q = k/13.41/k_equality;
 | 
|---|
| 306 |     xx = k*TFsound_horizon_fit(omhh, f_baryon, 1.0);
 | 
|---|
| 307 | 
 | 
|---|
| 308 |     alpha_gamma = 1-0.328*log(431.0*omhh)*f_baryon + 0.38*log(22.3*omhh)*
 | 
|---|
| 309 |                 SQR(f_baryon);
 | 
|---|
| 310 |     gamma_eff = omhh*(alpha_gamma+(1-alpha_gamma)/(1+POW4(0.43*xx)));
 | 
|---|
| 311 |     q_eff = q*omhh/gamma_eff;
 | 
|---|
| 312 | 
 | 
|---|
| 313 |     T_nowiggles_L0 = log(2.0*2.718282+1.8*q_eff);
 | 
|---|
| 314 |     T_nowiggles_C0 = 14.2 + 731.0/(1+62.5*q_eff);
 | 
|---|
| 315 |     return T_nowiggles_L0/(T_nowiggles_L0+T_nowiggles_C0*SQR(q_eff));
 | 
|---|
| 316 | }
 | 
|---|
| 317 | 
 | 
|---|
| 318 | /* ======================= Zero Baryon Formula =========================== */
 | 
|---|
| 319 | 
 | 
|---|
| 320 | double TFzerobaryon(double omega0, double hubble, double Tcmb, double k_hmpc)
 | 
|---|
| 321 | /* Input: omega0 -- CDM density, in units of critical density
 | 
|---|
| 322 |           hubble -- Hubble constant, in units of 100 km/s/Mpc
 | 
|---|
| 323 |           Tcmb -- Temperature of the CMB in Kelvin; Tcmb<=0 forces use of
 | 
|---|
| 324 |                         COBE FIRAS value of 2.728 K
 | 
|---|
| 325 |           k_hmpc -- Wavenumber in units of (h Mpc^-1). */
 | 
|---|
| 326 | /* Output: The value of the transfer function for a zero-baryon universe. */
 | 
|---|
| 327 | /* Note: If you prefer to use wavenumbers in units of Mpc^-1, use hubble -> 1
 | 
|---|
| 328 | and omega0 -> omega0*hubble^2. */ 
 | 
|---|
| 329 | {
 | 
|---|
| 330 |     double k, omhh, theta_cmb, k_equality, q, T_0_L0, T_0_C0;
 | 
|---|
| 331 | 
 | 
|---|
| 332 |     k = k_hmpc*hubble;  /* Convert to Mpc^-1 */
 | 
|---|
| 333 |     omhh = omega0*hubble*hubble;
 | 
|---|
| 334 |     if (Tcmb<=0.0) Tcmb=2.728;  /* COBE FIRAS */
 | 
|---|
| 335 |     theta_cmb = Tcmb/2.7;
 | 
|---|
| 336 | 
 | 
|---|
| 337 |     k_equality = 0.0746*omhh/SQR(theta_cmb);
 | 
|---|
| 338 |     q = k/13.41/k_equality;
 | 
|---|
| 339 | 
 | 
|---|
| 340 |     T_0_L0 = log(2.0*2.718282+1.8*q);
 | 
|---|
| 341 |     T_0_C0 = 14.2 + 731.0/(1+62.5*q);
 | 
|---|
| 342 |     return T_0_L0/(T_0_L0+T_0_C0*q*q);
 | 
|---|
| 343 | }
 | 
|---|
| 344 | 
 | 
|---|
| 345 | 
 | 
|---|
| 346 | /* Added by cmv 24/08/2007 */
 | 
|---|
| 347 | void TFprint_parameters(void)
 | 
|---|
| 348 | {
 | 
|---|
| 349 |   printf("omhh=%g obhh=%g theta_cmb=%g\n",omhh,obhh,theta_cmb);
 | 
|---|
| 350 |   printf("z_equality=%g k_equality=%g R_equality=%g\n",z_equality,k_equality,R_equality);
 | 
|---|
| 351 |   printf("z_drag=%g R_drag=%g sound_horizon=%g\n",z_drag,R_drag,sound_horizon);
 | 
|---|
| 352 |   printf("k_silk=%g\n",k_silk);
 | 
|---|
| 353 |   printf("alpha_c=%g beta_c=%g\n",alpha_c,beta_c);
 | 
|---|
| 354 |   printf("alpha_b=%g beta_b=%g\n",alpha_b,beta_b);
 | 
|---|
| 355 |   printf("beta_node=%g\n",beta_node);
 | 
|---|
| 356 |   printf("k_peak=%g sound_horizon_fit=%g\n",k_peak,sound_horizon_fit);
 | 
|---|
| 357 |   printf("alpha_gamma=%g\n",alpha_gamma);
 | 
|---|
| 358 | }
 | 
|---|