vide_public/c_tools/hod/sigmac.c

173 lines
3.5 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "header.h"
/*
* sigmac calls qromo to evaluate the integral
int_0^infty P_s(k) 4 pi k^2 dk / (2pi)^3
where P_s(k) is the power spectrum smoothed through a gaussian
window of radius rgaus and a top hat window of radius rth.
The power spectrum is a power law of index xindx, multiplied by
the square of the CDM transfer function if itrans = 1.
If the smoothing radius [rad] is positive, a top-hat window
function is used.
If [rad<0], a gaussian window function is used.
*/
double rad1;
double func_sigmac(double xk);
double func_sigmac_nl(double xk);
double sigmac_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2, pnorm;
int i,n=100;
double dlogm,max=5.e16,min=1.0e7,a,b,m1,m2,dm1,xi,power,rm,sig,b1,b2,mass;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogm = (log(max) - log(min))/(n-1);
pnorm=SIGMA_8/sigmac(8.0);
for(i=1;i<=n;++i)
{
m = exp((i-1)*dlogm)*min;
rm=pow(3.0*m/(4.0*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
sig=log(pnorm*sigmac(rm));
x[i] = log(m);
y[i] = sig;
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
return exp(a);
}
double sigmac_radius_interp(double m)
{
static int flag=0,prev_cosmo=0;
static double *x,*y,*y2, pnorm;
int i,n=100;
double dlogm,max=80.0,min=0.1,a,b,m1,m2,dm1,xi,power,rm,sig,b1,b2,mass;
if(!flag || RESET_COSMOLOGY!=prev_cosmo)
{
if(!ThisTask && OUTPUT)
fprintf(stdout,"RESET: resetting bias for %f %f\n",OMEGA_M,SIGMA_8);
if(!flag)
{
x=dvector(1,n);
y=dvector(1,n);
y2=dvector(1,n);
}
flag=1;
dlogm = (log(max) - log(min))/(n-1);
pnorm=SIGMA_8/sigmac(8.0);
for(i=1;i<=n;++i)
{
rm = exp((i-1)*dlogm)*min;
sig=log(pnorm*sigmac(rm));
x[i] = log(rm);
y[i] = sig;
}
spline(x,y,n,2.0E+30,2.0E+30,y2);
prev_cosmo=RESET_COSMOLOGY;
}
m=log(m);
splint(x,y,y2,n,m,&a);
return exp(a);
}
double sigmac(double rad)
{
double xk1,s1=1,s2=0,sigma0;
rad1=rad;
xk1 = 1./(2.*PI*mabs(rad));
s1=qromo(func_sigmac,0.0,xk1,midpnt);
s2=qromo(func_sigmac,xk1,1.e20,midinf);
sigma0=sqrt((s1+s2)*(4*PI)/pow(2*PI,3.0));
return sigma0;
}
double func_sigmac(double xk)
{
double xkr,w,psp;
if(rad1>0)
{
xkr = xk*rad1;
w = 3*(sin(xkr)-xkr*cos(xkr))/(xkr*xkr*xkr);
w = w*w;
}
else
{
xkr = -rad1*xk;
w = exp(-xkr*xkr);
}
if(ITRANS>0)
psp=pow(xk,SPECTRAL_INDX)*pow(transfnc(xk),2.0);
else
psp=pow(xk,SPECTRAL_INDX);
psp=psp*w*xk*xk;
return(psp);
}
/* Same as above, but no instead of using the linear
* theory power spectrum, use the non-linear P(k)
*/
double nonlinear_sigmac(double rad)
{
double xk1,s1=1,s2=0,sigma0;
rad1=rad;
xk1 = 1./(2.*PI*mabs(rad));
s1=qromo(func_sigmac_nl,0.0,xk1,midpnt);
s2=qromo(func_sigmac_nl,xk1,1.e20,midinf);
sigma0=sqrt((s1+s2));
return sigma0;
}
double func_sigmac_nl(double xk)
{
double xkr,w,psp;
if(rad1>0)
{
xkr = xk*rad1;
w = 3*(sin(xkr)-xkr*cos(xkr))/(xkr*xkr*xkr);
w = w*w;
}
else
{
xkr = -rad1*xk;
w = exp(-xkr*xkr);
}
psp=nonlinear_power_spectrum(xk);
psp=psp*w/xk;
return(psp);
}