Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
ccl_massfunc.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <string.h>
5 
6 #include <gsl/gsl_integration.h>
7 #include <gsl/gsl_interp.h>
8 #include <gsl/gsl_spline.h>
9 #include <gsl/gsl_errno.h>
10 
11 #include "ccl.h"
12 #include "ccl_params.h"
13 
14 
15 /*----- ROUTINE: dc_NakamuraSuto -----
16 INPUT: cosmology, scale factor
17 TASK: Computes the peak threshold: delta_c(z) assuming LCDM.
18 Cosmology dependence of the critical linear density according to the spherical-collapse model.
19 Fitting function from Nakamura & Suto (1997; arXiv:astro-ph/9710107).
20 */
21 double dc_NakamuraSuto(ccl_cosmology *cosmo, double a, int *status){
22 
23  double Om_mz = ccl_omega_x(cosmo, a, ccl_species_m_label, status);
24  double dc0 = (3./20.)*pow(12.*M_PI,2./3.);
25  double dc = dc0*(1.+0.012299*log10(Om_mz));
26 
27  return dc;
28 
29 }
30 
31 /*----- ROUTINE: Dv_BryanNorman -----
32 INPUT: cosmology, scale factor
33 TASK: Computes the virial collapse density contrast with respect to the matter density assuming LCDM.
34 Cosmology dependence of the virial collapse density according to the spherical-collapse model
35 Fitting function from Bryan & Norman (1998; arXiv:astro-ph/9710107)
36 */
37 double Dv_BryanNorman(ccl_cosmology *cosmo, double a, int *status){
38 
39  double Om_mz = ccl_omega_x(cosmo, a, ccl_species_m_label, status);
40  double x = Om_mz-1.;
41  double Dv0 = 18.*pow(M_PI,2);
42  double Dv = (Dv0+82.*x-39.*pow(x,2))/Om_mz;
43 
44  return Dv;
45 
46 }
47 
48 /*----- ROUTINE: r_delta -----
49 INPUT: cosmology, halo mass, scale factor, halo overdensity
50 TASK: Computes comoving halo radius assuming the overdensity criteria
51 */
52 double r_delta(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status){
53 
54  double rho_matter = ccl_rho_x(cosmo, 1., 1, 1, status);
55 
56  return pow(halomass*3.0/(4.0*M_PI*rho_matter*odelta),1.0/3.0);
57 
58 }
59 
60 // This checks to make sure all necessary halo mass function parameters have been set-up,
61 // as well as associated splines.
63 {
64  if(cosmo->computed_hmfparams)
65  return;
66 
67  // declare parameter splines on case-by-case basis
68  switch(cosmo->config.mass_function_method) {
69  case ccl_tinker10:{
70  double delta[9] = {200.0, 300.0, 400.0, 600.0, 800.0, 1200.0, 1600.0, 2400.0, 3200.0};
71  double lgdelta[9];
72  double alpha[9] = {0.368, 0.363, 0.385, 0.389, 0.393, 0.365, 0.379, 0.355, 0.327};
73  double beta[9] = {0.589, 0.585, 0.544, 0.543, 0.564, 0.623, 0.637, 0.673, 0.702};
74  double gamma[9] ={0.864, 0.922, 0.987, 1.09, 1.20, 1.34, 1.50, 1.68, 1.81};
75  double phi[9] = {-0.729, -0.789, -0.910, -1.05, -1.20, -1.26, -1.45, -1.50, -1.49};
76  double eta[9] = {-0.243, -0.261, -0.261, -0.273, -0.278, -0.301, -0.301, -0.319, -0.336};
77  int nd = 9;
78  int i;
79 
80  for(i=0; i<nd; i++) {
81  lgdelta[i] = log10(delta[i]);
82  }
83 
84  gsl_spline * alphahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
85  *status = gsl_spline_init(alphahmf, lgdelta, alpha, nd);
86  if (*status) {
87  gsl_spline_free(alphahmf);
88  *status = CCL_ERROR_SPLINE ;
89  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating alpha(D) spline\n");
90  return;
91  }
92 
93  gsl_spline * betahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
94  *status = gsl_spline_init(betahmf, lgdelta, beta, nd);
95  if (*status) {
96  gsl_spline_free(alphahmf);
97  gsl_spline_free(betahmf);
98  *status = CCL_ERROR_SPLINE ;
99  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating beta(D) spline\n");
100  return;
101  }
102 
103  gsl_spline * gammahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
104  *status = gsl_spline_init(gammahmf, lgdelta, gamma, nd);
105  if (*status) {
106  gsl_spline_free(alphahmf);
107  gsl_spline_free(betahmf);
108  gsl_spline_free(gammahmf);
109  *status = CCL_ERROR_SPLINE ;
110  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating gamma(D) spline\n");
111  return;
112  }
113 
114  gsl_spline * phihmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
115  *status = gsl_spline_init(phihmf, lgdelta, phi, nd);
116  if (*status) {
117  gsl_spline_free(alphahmf);
118  gsl_spline_free(betahmf);
119  gsl_spline_free(gammahmf);
120  gsl_spline_free(phihmf);
121  *status = CCL_ERROR_SPLINE ;
122  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating phi(D) spline\n");
123  return;
124  }
125 
126  gsl_spline * etahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
127  *status = gsl_spline_init(etahmf, lgdelta, eta, nd);
128  if (*status) {
129  gsl_spline_free(alphahmf);
130  gsl_spline_free(betahmf);
131  gsl_spline_free(gammahmf);
132  gsl_spline_free(phihmf);
133  gsl_spline_free(etahmf);
134  *status = CCL_ERROR_SPLINE ;
135  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating eta(D) spline\n");
136  return;
137  }
138  if(cosmo->data.accelerator_d==NULL)
139  cosmo->data.accelerator_d=gsl_interp_accel_alloc();
140  cosmo->data.alphahmf = alphahmf;
141  cosmo->data.betahmf = betahmf;
142  cosmo->data.gammahmf = gammahmf;
143  cosmo->data.phihmf = phihmf;
144  cosmo->data.etahmf = etahmf;
145  cosmo->computed_hmfparams = true;
146 
147  break;
148  }
149  case ccl_tinker:{
150  double delta[9] = {200.0, 300.0, 400.0, 600.0, 800.0, 1200.0, 1600.0, 2400.0, 3200.0};
151  double lgdelta[9];
152  double alpha[9] = {0.186, 0.200, 0.212, 0.218, 0.248, 0.255, 0.260, 0.260, 0.260};
153  double beta[9] = {1.47, 1.52, 1.56, 1.61, 1.87, 2.13, 2.30, 2.53, 2.66};
154  double gamma[9] ={2.57, 2.25, 2.05, 1.87, 1.59, 1.51, 1.46, 1.44, 1.41};
155  double phi[9] = {1.19, 1.27, 1.34, 1.45, 1.58, 1.80, 1.97, 2.24, 2.44};
156  int nd = 9;
157  int i;
158 
159  for(i=0; i<nd; i++) {
160  lgdelta[i] = log10(delta[i]);
161  }
162 
163  gsl_spline * alphahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
164  *status = gsl_spline_init(alphahmf, lgdelta, alpha, nd);
165  if (*status) {
166  gsl_spline_free(alphahmf);
167  *status = CCL_ERROR_SPLINE ;
168  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating alpha(D) spline\n");
169  return;
170  }
171 
172  gsl_spline * betahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
173  *status = gsl_spline_init(betahmf, lgdelta, beta, nd);
174  if (*status) {
175  gsl_spline_free(alphahmf);
176  gsl_spline_free(betahmf);
177  *status = CCL_ERROR_SPLINE ;
178  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating beta(D) spline\n");
179  return;
180  }
181 
182  gsl_spline * gammahmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
183  *status = gsl_spline_init(gammahmf, lgdelta, gamma, nd);
184  if (*status) {
185  gsl_spline_free(alphahmf);
186  gsl_spline_free(betahmf);
187  gsl_spline_free(gammahmf);
188  *status = CCL_ERROR_SPLINE ;
189  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating gamma(D) spline\n");
190  return;
191  }
192 
193  gsl_spline * phihmf = gsl_spline_alloc(D_SPLINE_TYPE, nd);
194  *status = gsl_spline_init(phihmf, lgdelta, phi, nd);
195  if (*status) {
196  gsl_spline_free(alphahmf);
197  gsl_spline_free(betahmf);
198  gsl_spline_free(gammahmf);
199  gsl_spline_free(phihmf);
200  *status = CCL_ERROR_SPLINE ;
201  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_hmfparams(): Error creating phi(D) spline\n");
202  return;
203  }
204 
205  if(cosmo->data.accelerator_d==NULL)
206  cosmo->data.accelerator_d=gsl_interp_accel_alloc();
207  cosmo->data.alphahmf = alphahmf;
208  cosmo->data.betahmf = betahmf;
209  cosmo->data.gammahmf = gammahmf;
210  cosmo->data.phihmf = phihmf;
211  cosmo->computed_hmfparams = true;
212 
213  break;
214  }
215  default:
216  // Error message could go here if we decide to make this public facing.
217  // Currently not accessible from the API though.
218  break;
219  }
220 }
221 
222 //TODO: some of these are unused, many are included in ccl.h
223 
224 /*----- ROUTINE: ccl_massfunc_f -----
225 INPUT: cosmology+parameters, a halo mass, and scale factor
226 TASK: Outputs fitting function for use in halo mass function calculation;
227  currently only supports:
228  ccl_tinker (arxiv 0803.2706 )
229  ccl_tinker10 (arxiv 1001.3162 )
230  ccl_angulo (arxiv 1203.3216 )
231  ccl_watson (arxiv 1212.0095 )
232  ccl_shethtormen (arxiv 9901122)
233 */
234 static double massfunc_f(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
235 {
236  double fit_A, fit_a, fit_b, fit_c, fit_d, fit_p, overdensity_delta;
237  double Omega_m_a;
238  double delta_c_Tinker, nu;
239 
240  double sigma=ccl_sigmaM(cosmo, halomass, a, status);
241  int gslstatus;
242 
243  switch(cosmo->config.mass_function_method) {
244 
245  // Equation (10) in arxiv: 9901122
246  // Note that Sheth & Tormen (1999) use nu=(dc/sigma)^2 whereas we use nu=dc/sigma
247  case ccl_shethtormen:
248 
249  // Check if odelta is outside the interpolated range
250  if (odelta != Dv_BryanNorman(cosmo, a, status)) {
251  *status = CCL_ERROR_HMF_DV;
252  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: massfunc_f(): Sheth-Tormen called with not virial Delta_v\n");
253  return NAN;
254  }
255 
256  // ST mass function fitting parameters
257  fit_A = 0.21616;
258  fit_p = 0.3;
259  fit_a = 0.707;
260 
261  // nu = delta_c(z) / sigma(M)
262  nu = dc_NakamuraSuto(cosmo, a, status)/ccl_sigmaM(cosmo, halomass, a, status);
263 
264  return nu*fit_A*(1.+pow(fit_a*pow(nu,2),-fit_p))*exp(-fit_a*pow(nu,2)/2.);
265 
266  case ccl_tinker:
267 
268  // Check if odelta is outside the interpolated range
269  if ((odelta < 200) || (odelta > 3200)) {
270  *status = CCL_ERROR_HMF_INTERP;
271  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: massfunc_f(): Tinker 2008 only supported in range of Delta = 200 to Delta = 3200.\n");
272  return NAN;
273  }
274 
275  // Compute HMF parameter (alpha, beta, gamma, phi) splines if they haven't
276  // been computed already
277  if (!cosmo->computed_hmfparams) {
278  ccl_cosmology_compute_hmfparams(cosmo, status);
279  ccl_check_status(cosmo, status);
280  }
281  gslstatus = gsl_spline_eval_e(cosmo->data.alphahmf, log10(odelta), cosmo->data.accelerator_d,&fit_A);
282  gslstatus |= gsl_spline_eval_e(cosmo->data.betahmf, log10(odelta), cosmo->data.accelerator_d,&fit_a);
283  gslstatus |= gsl_spline_eval_e(cosmo->data.gammahmf, log10(odelta), cosmo->data.accelerator_d,&fit_b);
284  gslstatus |= gsl_spline_eval_e(cosmo->data.phihmf, log10(odelta), cosmo->data.accelerator_d,&fit_c);
285  fit_d = pow(10, -1.0*pow(0.75 / log10(odelta / 75.0), 1.2));
286 
287  fit_A = fit_A*pow(a, 0.14);
288  fit_a = fit_a*pow(a, 0.06);
289  fit_b = fit_b*pow(a, fit_d);
290  if(gslstatus != GSL_SUCCESS) {
291  ccl_raise_gsl_warning(gslstatus, "ccl_massfunc.c: ccl_massfunc_f():");
292  *status |= gslstatus;
293  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_massfunc_f(): interpolation error for Tinker MF\n");
294  return NAN;
295  }
296  return fit_A*(pow(sigma/fit_b,-fit_a)+1.0)*exp(-fit_c/sigma/sigma);
297  break;
298  case ccl_tinker10:
299  // this version uses f(nu) parameterization from Eq. 8 in Tinker et al. 2010
300  // use this for consistency with Tinker et al. 2010 fitting function for halo bias
301 
302  // Check if odelta is outside the interpolated range
303  if ((odelta < 200) || (odelta > 3200)) {
304  *status = CCL_ERROR_HMF_INTERP;
305  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: massfunc_f(): Tinker 2010 only supported in range of Delta = 200 to Delta = 3200.\n");
306  return 0;
307  }
308 
309  if (!cosmo->computed_hmfparams) {
310  ccl_cosmology_compute_hmfparams(cosmo, status);
311  ccl_check_status(cosmo, status);
312  }
313  //critical collapse overdensity assumed in this model
314  delta_c_Tinker = 1.686;
315  nu = delta_c_Tinker/(sigma);
316 
317  gslstatus = gsl_spline_eval_e(cosmo->data.alphahmf, log10(odelta), cosmo->data.accelerator_d,&fit_A); //alpha in Eq. 8
318  gslstatus |= gsl_spline_eval_e(cosmo->data.etahmf, log10(odelta), cosmo->data.accelerator_d,&fit_a); //eta in Eq. 8
319  gslstatus |= gsl_spline_eval_e(cosmo->data.betahmf, log10(odelta), cosmo->data.accelerator_d,&fit_b); //beta in Eq. 8
320  gslstatus |= gsl_spline_eval_e(cosmo->data.gammahmf, log10(odelta), cosmo->data.accelerator_d,&fit_c); //gamma in Eq. 8
321  gslstatus |= gsl_spline_eval_e(cosmo->data.phihmf, log10(odelta), cosmo->data.accelerator_d,&fit_d); //phi in Eq. 8;
322 
323  fit_a *=pow(a, -0.27);
324  fit_b *=pow(a, -0.20);
325  fit_c *=pow(a, 0.01);
326  fit_d *=pow(a, 0.08);
327  if(gslstatus != GSL_SUCCESS) {
328  ccl_raise_gsl_warning(gslstatus, "ccl_massfunc.c: ccl_massfunc_f():");
329  *status |= gslstatus;
330  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_massfunc_f(): interpolation error for Tinker 2010 MF\n");
331  return NAN;
332  }
333  return nu*fit_A*(1.+pow(fit_b*nu,-2.*fit_d))*pow(nu, 2.*fit_a)*exp(-0.5*fit_c*nu*nu);
334  break;
335 
336  case ccl_watson:
337  if(odelta!=200.) {
338  *status = CCL_ERROR_HMF_INTERP;
339  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_massfunc_f(): Watson HMF only supported for Delta = 200.\n");
340  return NAN;
341  }
342  // these parameters from: Angulo et al 2012 (arxiv 1203.3216 )
343  Omega_m_a = ccl_omega_x(cosmo, a, ccl_species_m_label,status);
344  fit_A = Omega_m_a*(0.990*pow(a,3.216)+0.074);
345  fit_a = Omega_m_a*(5.907*pow(a,3.599)+2.344);
346  fit_b = Omega_m_a*(3.136*pow(a,3.058)+2.349);
347  fit_c = 1.318;
348 
349  return fit_A*(pow(sigma/fit_b,-fit_a)+1.0)*exp(-fit_c/sigma/sigma);
350 
351  case ccl_angulo:
352  if(odelta!=200.) {
353  *status = CCL_ERROR_HMF_INTERP;
354  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_massfunc_f(): Angulo HMF only supported for Delta = 200.\n");
355  return NAN;
356  }
357  // these parameters from: Watson et al 2012 (arxiv 1212.0095 )
358  fit_A = 0.201;
359  fit_a = 2.08;
360  fit_b = 1.7;
361  fit_c = 1.172;
362 
363  return fit_A*pow( (fit_a/sigma)+1.0, fit_b)*exp(-fit_c/sigma/sigma);
364 
365  default:
366  *status = CCL_ERROR_MF;
368  "ccl_massfunc.c: ccl_massfunc(): Unknown or non-implemented mass function method: %d \n",
370  return NAN;
371  }
372 }
373 
374 static double ccl_halo_b1(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
375 {
376  double fit_A, fit_B, fit_C, fit_a, fit_b, fit_c, fit_p, overdensity_delta, y;
377  double delta_c_Tinker, nu;
378  double sigma=ccl_sigmaM(cosmo,halomass,a, status);
379  switch(cosmo->config.mass_function_method) {
380 
381  // Equation (12) in arXiv: 9901122
382  // Derived using the peak-background split applied to the mass function in the same paper
383  // Note that Sheth & Tormen (1999) use nu=(dc/sigma)^2 whereas we use nu=dc/sigma
384  case ccl_shethtormen:
385 
386  // Check if Delta_v is the virial Delta_v
387  if (odelta != Dv_BryanNorman(cosmo, a, status)) {
388  *status = CCL_ERROR_HMF_DV;
389  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: halo_b1(): Sheth-Tormen called with not virial Delta_v\n");
390  return NAN;
391  }
392 
393  // ST bias fitting parameters (which are the same as for the mass function)
394  fit_p = 0.3;
395  fit_a = 0.707;
396 
397  // Cosmology dependent delta_c and nu
398  double delta_c = dc_NakamuraSuto(cosmo, a, status);
399  nu = delta_c/ccl_sigmaM(cosmo, halomass, a, status);
400 
401  return 1.+(fit_a*pow(nu,2)-1.+2.*fit_p/(1.+pow(fit_a*pow(nu,2),fit_p)))/delta_c;
402 
403  //this version uses b(nu) parameterization, Eq. 6 in Tinker et al. 2010
404  // use this for consistency with Tinker et al. 2010 fitting function for halo bias
405  case ccl_tinker10:
406  y = log10(odelta);
407  //critical collapse overdensity assumed in this model
408  delta_c_Tinker = 1.686;
409  //peak height - note that this factorization is incorrect for e.g. massive neutrino cosmologies
410  nu = delta_c_Tinker/(sigma);
411  // Table 2 in https://arxiv.org/pdf/1001.3162.pdf
412  fit_A = 1.0 + 0.24*y*exp(-pow(4./y,4.));
413  fit_a = 0.44*y-0.88;
414  fit_B = 0.183;
415  fit_b = 1.5;
416  fit_C = 0.019+0.107*y+0.19*exp(-pow(4./y,4.));
417  fit_c = 2.4;
418 
419  return 1.-fit_A*pow(nu,fit_a)/(pow(nu,fit_a)+pow(delta_c_Tinker,fit_a))+fit_B*pow(nu,fit_b)+fit_C*pow(nu,fit_c);
420  break;
421 
422  default:
423  *status = CCL_ERROR_MF;
425  "ccl_massfunc.c: ccl_halo_b1(): No b(M) fitting function implemented for mass_function_method: %d \n",
427  return 0;
428  }
429 }
430 
432 {
433  if(cosmo->computed_sigma)
434  return;
435 
436  // create linearly-spaced values of the mass.
437  int nm=ccl_splines->LOGM_SPLINE_NM;
439 
440  // create space for y, to be filled with sigma and dlnsigma_dlogm
441  double * y = malloc(sizeof(double)*nm);
442  double smooth_radius;
443  double na, nb;
444 
445  // start up of GSL pointers
446  int gslstatus = 0;
447  gsl_spline *logsigma;
448  gsl_spline *dlnsigma_dlogm;
449 
450  if (m==NULL ||
451  (fabs(m[0]-ccl_splines->LOGM_SPLINE_MIN)>1e-5) ||
452  (fabs(m[nm-1]-ccl_splines->LOGM_SPLINE_MAX)>1e-5) ||
453  (m[nm-1]>10E17)
454  ) {
455  *status = CCL_ERROR_LINSPACE;
456  ccl_cosmology_set_status_message(cosmo,"ccl_cosmology_compute_sigmas(): Error creating linear spacing in m\n");
457  }
458 
459  // fill in sigma, if no errors have been triggered at this time.
460  if (*status == 0) {
461  for (int i=0; i<nm; i++) {
462  smooth_radius = ccl_massfunc_m2r(cosmo, pow(10,m[i]), status);
463  y[i] = log10(ccl_sigmaR(cosmo, smooth_radius, 1., status));
464  }
465  logsigma = gsl_spline_alloc(M_SPLINE_TYPE, nm);
466  *status = gsl_spline_init(logsigma, m, y, nm);
467  }
468 
469  if (*status !=0 ) {
470  *status = CCL_ERROR_SPLINE ;
471  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_sigma(): Error creating sigma(M) spline\n");
472  }
473 
474  // again, making splines assuming nothing bad has happened to this point
475 
476  if (*status == 0 ) {
477  for (int i=0; i<nm; i++) {
478  if(i==0) {
479  gslstatus |= gsl_spline_eval_e(logsigma, m[i], NULL,&na);
480  gslstatus |= gsl_spline_eval_e(logsigma, m[i]+ccl_splines->LOGM_SPLINE_DELTA/2., NULL,&nb);
481  y[i] = (na-nb)*log(10.);
482  y[i] = 2.*y[i] / ccl_splines->LOGM_SPLINE_DELTA;
483  }
484  else if (i==nm-1) {
485  gslstatus |= gsl_spline_eval_e(logsigma, m[i]-ccl_splines->LOGM_SPLINE_DELTA/2., NULL,&na);
486  gslstatus |= gsl_spline_eval_e(logsigma, m[i], NULL,&nb);
487  y[i] = (na-nb)*log(10.);
488  y[i] = 2.*y[i] / ccl_splines->LOGM_SPLINE_DELTA;
489  }
490  else {
491  gslstatus |= gsl_spline_eval_e(logsigma, m[i]-ccl_splines->LOGM_SPLINE_DELTA/2., NULL,&na);
492  gslstatus |= gsl_spline_eval_e(logsigma, m[i]+ccl_splines->LOGM_SPLINE_DELTA/2., NULL,&nb);
493  y[i] = (na-nb)*log(10.);
494  y[i] = y[i] / ccl_splines->LOGM_SPLINE_DELTA;
495  }
496  }
497  }
498 
499  if(gslstatus != GSL_SUCCESS) {
500  ccl_raise_gsl_warning(gslstatus, "ccl_massfunc.c: ccl_cosmology_compute_sigma():");
501  *status |= gslstatus;
502  *status = CCL_ERROR_SPLINE ;
503  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_sigma(): Error evaluating grid points for dlnsigma/dlogM spline\n");
504  }
505 
506  if(*status==0) {
507  dlnsigma_dlogm = gsl_spline_alloc(M_SPLINE_TYPE, nm);
508  *status = gsl_spline_init(dlnsigma_dlogm, m, y, nm);
509  if(cosmo->data.accelerator_m==NULL)
510  cosmo->data.accelerator_m=gsl_interp_accel_alloc();
511  }
512 
513  if(*status!=0) {
514  *status = CCL_ERROR_SPLINE ;
515  ccl_cosmology_set_status_message(cosmo, "ccl_massfunc.c: ccl_cosmology_compute_sigma(): Error creating dlnsigma/dlogM spline\n");
516  }
517 
518 
519  cosmo->data.logsigma = logsigma;
520  cosmo->data.dlnsigma_dlogm = dlnsigma_dlogm;
521  cosmo->computed_sigma = true;
522 
523  free(m);
524  free(y);
525  if(*status != 0) {
526  gsl_spline_free(logsigma);
527  gsl_spline_free(dlnsigma_dlogm);
528  }
529  return;
530 }
531 
532 /*----- ROUTINE: ccl_dlninvsig_dlogm -----
533 INPUT: ccl_cosmology *cosmo, double halo mass in units of Msun
534 TASK: returns the value of the derivative of ln(sigma^-1) with respect to log10 in halo mass.
535 */
536 
537 static double ccl_dlninvsig_dlogm(ccl_cosmology *cosmo, double halomass, int*status)
538 {
539  if (!cosmo->computed_sigma) {
540  ccl_cosmology_compute_sigma(cosmo, status);
541  ccl_check_status(cosmo, status);
542  }
543 
544  double val, logmass;
545 
546  logmass = log10(halomass);
547 
548  int gslstatus = gsl_spline_eval_e(cosmo->data.dlnsigma_dlogm, logmass, cosmo->data.accelerator_m,&val);
549  if(gslstatus != GSL_SUCCESS) {
550  ccl_raise_gsl_warning(gslstatus, "ccl_massfunc.c: ccl_massfunc():");
551  *status |= gslstatus;
552  }
553  ccl_check_status(cosmo, status);
554 
555  return val;
556 }
557 
558 /*----- ROUTINE: ccl_massfunc -----
559 INPUT: ccl_cosmology * cosmo, double halo mass in units of Msun, double scale factor
560 TASK: returns halo mass function as dn/dlog10(m) in comoving Msun^-1 Mpc^-3 (haloes per mass interval per volume)
561 */
562 double ccl_massfunc(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
563 {
564  if (cosmo->params.N_nu_mass>0){
565  *status = CCL_ERROR_NOT_IMPLEMENTED;
566  ccl_cosmology_set_status_message(cosmo, "ccl_background.c: ccl_cosmology_compute_growth(): Support for the halo mass function in cosmologies with massive neutrinos is not yet implemented.\n");
567  return NAN;
568  }
569 
570  double f, rho_m;
571 
572  rho_m = RHO_CRITICAL*cosmo->params.Omega_m*cosmo->params.h*cosmo->params.h;
573  f=massfunc_f(cosmo,halomass,a,odelta,status);
574 
575  return f*rho_m*ccl_dlninvsig_dlogm(cosmo,halomass,status)/halomass;
576 }
577 
578 /*----- ROUTINE: ccl_halob1 -----
579 INPUT: ccl_cosmology * cosmo, double halo mass in units of Msun, double scale factor
580 TASK: returns dimensionless linear halo bias
581 */
582 double ccl_halo_bias(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
583 {
584  if (cosmo->params.N_nu_mass>0){
585  *status = CCL_ERROR_NOT_IMPLEMENTED;
586  ccl_cosmology_set_status_message(cosmo, "ccl_background.c: ccl_cosmology_compute_growth(): Support for the halo bias in cosmologies with massive neutrinos is not yet implemented.\n");
587  return NAN;
588  }
589 
590 
591  if (!cosmo->computed_sigma) {
592  ccl_cosmology_compute_sigma(cosmo, status);
593  ccl_check_status(cosmo, status);
594  }
595 
596  double f;
597  f = ccl_halo_b1(cosmo,halomass,a,odelta, status);
598  ccl_check_status(cosmo, status);
599  return f;
600 }
601 /*---- ROUTINE: ccl_massfunc_m2r -----
602 INPUT: ccl_cosmology * cosmo, halomass in units of Msun
603 TASK: takes halo mass and converts to halo radius
604  in units of Mpc.
605 */
606 double ccl_massfunc_m2r(ccl_cosmology *cosmo, double halomass, int *status)
607 {
608  double rho_m, smooth_radius;
609 
610  // Comoving matter density
611  //rho_m = RHO_CRITICAL*cosmo->params.Omega_m*cosmo->params.h*cosmo->params.h;
612  rho_m = ccl_rho_x(cosmo, 1., ccl_species_m_label, 1, status);
613 
614  smooth_radius = pow((3.0*halomass) / (4*M_PI*rho_m), (1.0/3.0));
615 
616  return smooth_radius;
617 }
618 
619 /*----- ROUTINE: ccl_sigma_M -----
620 INPUT: ccl_cosmology * cosmo, double halo mass in units of Msun, double scale factor
621 TASK: returns sigma from the sigmaM interpolation. Also computes the sigma interpolation if
622 necessary.
623 */
624 double ccl_sigmaM(ccl_cosmology *cosmo, double halomass, double a, int *status)
625 {
626  if (cosmo->params.N_nu_mass>0){
627  *status = CCL_ERROR_NOT_IMPLEMENTED;
628  ccl_cosmology_set_status_message(cosmo, "ccl_background.c: ccl_cosmology_compute_growth(): Support for the sigma(M) function in cosmologies with massive neutrinos is not yet implemented.\n");
629  return NAN;
630  }
631 
632  double sigmaM;
633  // Check if sigma has already been calculated
634  if (!cosmo->computed_sigma) {
635  ccl_cosmology_compute_sigma(cosmo, status);
636  ccl_check_status(cosmo, status);
637  }
638 
639  double lgsigmaM;
640 
641  int gslstatus = gsl_spline_eval_e(cosmo->data.logsigma,
642  log10(halomass),
643  cosmo->data.accelerator_m,&lgsigmaM);
644 
645  if(gslstatus != GSL_SUCCESS) {
646  ccl_raise_gsl_warning(gslstatus, "ccl_massfunc.c: ccl_sigmaM():");
647  *status |= gslstatus;
648  }
649 
650  // Interpolate to get sigma
651  sigmaM = pow(10,lgsigmaM)*ccl_growth_factor(cosmo, a, status);
652  ccl_check_status(cosmo, status);
653  return sigmaM;
654 }
gsl_interp_accel * accelerator_m
Definition: ccl_core.h:93
static void ccl_cosmology_compute_hmfparams(ccl_cosmology *cosmo, int *status)
Definition: ccl_massfunc.c:62
void ccl_raise_gsl_warning(int gslstatus, const char *msg,...)
Definition: ccl_error.c:75
double ccl_omega_x(ccl_cosmology *cosmo, double a, ccl_species_x_label label, int *status)
double ccl_halo_bias(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
Definition: ccl_massfunc.c:582
double ccl_massfunc_m2r(ccl_cosmology *cosmo, double halomass, int *status)
Definition: ccl_massfunc.c:606
#define CCL_ERROR_NOT_IMPLEMENTED
Definition: ccl_error.h:25
ccl_parameters params
Definition: ccl_core.h:124
double ccl_growth_factor(ccl_cosmology *cosmo, double a, int *status)
double dc_NakamuraSuto(ccl_cosmology *cosmo, double a, int *status)
Definition: ccl_massfunc.c:21
static double ccl_halo_b1(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
Definition: ccl_massfunc.c:374
void ccl_check_status(ccl_cosmology *cosmo, int *status)
Definition: ccl_error.c:88
double LOGM_SPLINE_MAX
Definition: ccl_params.h:26
double r_delta(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
Definition: ccl_massfunc.c:52
#define CCL_ERROR_HMF_INTERP
Definition: ccl_error.h:20
#define M_SPLINE_TYPE
Definition: ccl_constants.h:10
ccl_spline_params * ccl_splines
Definition: ccl_core.c:47
CCL_BEGIN_DECLS double * ccl_linear_spacing(double xmin, double xmax, int N)
Definition: ccl_utils.c:14
double h
Definition: ccl_core.h:33
double ccl_sigmaM(ccl_cosmology *cosmo, double halomass, double a, int *status)
Definition: ccl_massfunc.c:624
#define M_PI
Definition: ccl_constants.h:22
#define CCL_ERROR_SPLINE
Definition: ccl_error.h:13
gsl_spline * betahmf
Definition: ccl_core.h:105
gsl_spline * alphahmf
Definition: ccl_core.h:104
gsl_interp_accel * accelerator_d
Definition: ccl_core.h:94
static double massfunc_f(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
Definition: ccl_massfunc.c:234
#define CCL_ERROR_LINSPACE
Definition: ccl_error.h:11
void ccl_cosmology_compute_sigma(ccl_cosmology *cosmo, int *status)
Definition: ccl_massfunc.c:431
void ccl_cosmology_set_status_message(ccl_cosmology *cosmo, const char *status_message,...)
Definition: ccl_core.c:792
static double beta[2][28][8]
Definition: ccl_emu17.c:32
double LOGM_SPLINE_DELTA
Definition: ccl_params.h:23
static CCL_BEGIN_DECLS double x[111][8]
#define CCL_ERROR_MF
Definition: ccl_error.h:19
gsl_spline * phihmf
Definition: ccl_core.h:107
double ccl_massfunc(ccl_cosmology *cosmo, double halomass, double a, double odelta, int *status)
Definition: ccl_massfunc.c:562
gsl_spline * logsigma
Definition: ccl_core.h:100
double ccl_rho_x(ccl_cosmology *cosmo, double a, ccl_species_x_label label, int is_comoving, int *status)
gsl_spline * gammahmf
Definition: ccl_core.h:106
bool computed_hmfparams
Definition: ccl_core.h:132
double Dv_BryanNorman(ccl_cosmology *cosmo, double a, int *status)
Definition: ccl_massfunc.c:37
mass_function_t mass_function_method
Definition: ccl_config.h:114
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
gsl_spline * dlnsigma_dlogm
Definition: ccl_core.h:101
static int m[2]
Definition: ccl_emu17.c:25
static double ccl_dlninvsig_dlogm(ccl_cosmology *cosmo, double halomass, int *status)
Definition: ccl_massfunc.c:537
ccl_configuration config
Definition: ccl_core.h:125
gsl_spline * etahmf
Definition: ccl_core.h:108
double Omega_m
Definition: ccl_core.h:21
double LOGM_SPLINE_MIN
Definition: ccl_params.h:25
#define RHO_CRITICAL
Definition: ccl_constants.h:61
double ccl_sigmaR(ccl_cosmology *cosmo, double R, double a, int *status)
Definition: ccl_power.c:1715
ccl_data data
Definition: ccl_core.h:126
#define D_SPLINE_TYPE
Definition: ccl_constants.h:11
#define CCL_ERROR_HMF_DV
Definition: ccl_error.h:31
bool computed_sigma
Definition: ccl_core.h:131