vide_public/c_tools/hod/jet_pvz_temp.c

375 lines
9.2 KiB
C

#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "header.h"
double delta_pdf(double delta, double r);
void vdelta_v4(double m0, double m1, double rad, double theta, double binsize,
double v0, int nv, double *a, double *pv, double *pt, double *pz,
double wgal[3], double sgal[4])
{
static double pnorm=-1,flag=0;
static double *rho,*mu,*pdelta;
static int prev_cosmo=0;
int i,j,k,nrho=75,halo_pair_only=0,use_file_coeff=0;
double dlogrho,sintheta,costheta,tan2theta,rho_min,rho_max,w,b0,
collapse_factor,rho200,ptot,v,sigv,rho0,x1,x2,x3,rvir0,rho200t,sigvt,alpha,alphat,
rvir1,rvirmax,rvir2,vfac,sr1,sr2,sr3,sr4,st1,st2,st3,st4,sz1,sz2,sz3,sz4,
gnorm1,gnorm2,gnorm3,gnorm4,vv,pmax,rcrit,sig20,sig10,sig5;
int direction,iend;
double sigz1[76],sigz2[76],sigz3[76],sigz4[76],
g1[76],g2[76],g3[76],g4[76],minp,xfit[3],yfit[3],afit,bfit;
double t0,t1,tt1,tt2;
int ii=0;
double vfac0 = 0.97; /* factor om rho200[t,r]. was 0.97 */
for(i=1;i<=nv;++i)
/* pt[i]=pv[i]=*/ pz[i]=0;
rvir0=(pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0) +
pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0));
rvir1=pow(3*m1/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
rvir2=pow(3*m0/(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
b0=(bias_interp(m0,-1)+bias_interp(m1,-1));
/* 0.5 comes from ellipsoidal halo exclusion.
*/
if(rad<rvir0*0.5)return;
/*if(rad<rvir0)rad=rvir0;*/
rho_min=0.01;
alpha=alphat=pow(rad/35,0.1);
rcrit=4*rvir1;
rcrit=0;
if(rad<=rcrit)
{
x1=rcrit;
x2=pow(x1/35,0.1);
x3=x1*pow(x2,-1.0/(+0.3));
alpha=alphat=pow(rad/x3,+0.3);
}
rcrit=4*rvir1;
rho200 = pow(rad/5.0/sqrt(rvir1),-4.0) + pow(rad/11.5/sqrt(rvir0),-1.3) + 0.5;
rho200t = pow(rad/7.2/sqrt(rvir1),-2.5) + pow(rad/12.6/sqrt(rvir0),-0.8) + 0.48;
rho0 = 1.41*b0 + pow(rad/9.4/rvir1,-2.2);
/* TEMP TEMP TEMP
*/
/* rho0 = 1.38*b0 + pow(rad/9.4/rvir1,-2.2); */
vfac0 = 1.01;
/* If using the bias parameters that fit Warren's sims, use:
*/
/* rho0 = 1.45*b0 + pow(rad/9.4/rvir1,-2.2); */
/* If using the bias parameters for the linear P(k), use:
*/
if(LINEAR_PSP)
rho0 = 1.28*b0 + pow(rad/9.4/rvir1,-2.2);
sintheta=sin(theta);
costheta=cos(theta);
tan2theta=sintheta*sintheta/(costheta*costheta);
if(!flag)
{
flag=1;
mu=dvector(1,nrho);
rho=dvector(1,nrho);
pdelta=dvector(1,nrho);
}
/* Determine the proper limits of the integral over rho
*/
dlogrho=log(1.0E+3/0.01)/(50-1);
pmax=0;
i=0;
for(i=1;i<=50;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
if(pdelta[i]>pmax){ pmax=pdelta[i]; j=i; }
}
pmax*=1.0E-4;
for(i=1;i<j;++i)
if(pdelta[i]>=pmax)break;
rho_min=rho[i];
for(i=j+1;i<50;++i)
if(pdelta[i]<=pmax)break;
rho_max=rho[i];
/* Tabulate the spherical collapse model, density, and p(delta).
*/
dlogrho=log(rho_max/rho_min)/(nrho-1);
ptot=0;
for(i=1;i<=nrho;++i)
{
rho[i]=rho_min*exp((i-1)*dlogrho);
pdelta[i]=exp(-rho0/rho[i])*delta_pdf(rho[i]-1,rad)*rho[i];
ptot+=pdelta[i]*dlogrho;
if(pdelta[i]>pdelta[j])j=i;
x1=-(100*rad)*pow(OMEGA_M,0.6)*(rho[i]-1)/3;
/* If underdense region, use linear theory.
*/
if(rho[i]<=1)
{
mu[i]=x1;
continue;
}
x2=(rad)*spherical_collapse_model(rho[i]-1)*exp(-(4.5/rad/rho[i])*(4.5/rad/rho[i]));
if(x2>0)x2=0;
/* If small separation, use spherical collapse model only.
*/
if(rad<=4)
{
mu[i]=x2;
continue;
}
/* If intermediate separation, use linear combination of v_sph & v_lin.
*/
if(rad<=20)
{
w=-0.62*log(rad)+1.86;
mu[i]=w*x2 + (1-w)*x1;
continue;
}
/* In linear regime. Use linear theory.
*/
mu[i]=x1;
}
if(rad<=rcrit)
for(i=1;i<=nrho;++i)
mu[i]=mu[j];
for(i=1;i<=nrho;++i)
pdelta[i]/=ptot;
vfac=pow(OMEGA_M/0.3,0.6)*(SIGMA_8/0.8)*vfac0;
/* If Halos only, then set all the galaxy velocity dispersions
* and weights to be zero.
*/
if(!HOD.pdfs)
{
sgal[0]=sgal[1]=sgal[2]=0;
wgal[0]=wgal[1]=wgal[2]=0;
}
for(i=1;i<=nrho;++i)
{
sigv=200*pow(rho[i]/rho200,alpha)*vfac;
sigvt=200*pow(rho[i]/rho200t,alphat)*vfac;
sr1=sigv*sigv + sgal[0];
sr2=sigv*sigv + sgal[1];
sr3=sigv*sigv + sgal[2];
sr4=sigv*sigv + sgal[3];
st1=sigvt*sigvt + sgal[0];
st2=sigvt*sigvt + sgal[1];
st3=sigvt*sigvt + sgal[2];
st4=sigvt*sigvt + sgal[3];
sz1=2*(st1+tan2theta*sr1)*costheta*costheta;
sz2=2*(st2+tan2theta*sr2)*costheta*costheta;
sz3=2*(st3+tan2theta*sr3)*costheta*costheta;
sz4=2*(st4+tan2theta*sr4)*costheta*costheta;
sigz1[i]=sz1;
sigz2[i]=sz2;
sigz3[i]=sz3;
sigz4[i]=sz4;
gnorm1=wgal[0]/(RT2PI*sqrt(st1*sr1)*sqrt(1.0/(sr1) + tan2theta/(st1)));
gnorm2=wgal[1]/(RT2PI*sqrt(st2*sr2)*sqrt(1.0/(sr2) + tan2theta/(st2)));
gnorm3=wgal[2]/(RT2PI*sqrt(st3*sr3)*sqrt(1.0/(sr3) + tan2theta/(st3)));
gnorm4=(1-wgal[0]-wgal[1]-wgal[2])/
(RT2PI*sqrt(st4*sr4)*sqrt(1.0/(sr4) + tan2theta/(st4)));
g1[i]=gnorm1;
g2[i]=gnorm2;
g3[i]=gnorm3;
g4[i]=gnorm4;
}
/* Find the mode of the distribution. Start at vz=0 and work either way.
*/
for(k=1,j=nv/2;j<=nv;++j,++k)
{
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(k==2){
if(pz[j-1]>pz[j])direction=-1;
else direction=1;
break;
}
}
direction=1;
if(direction==1)iend=nv;
else iend=1;
for(k=1,j=nv/2-direction;j!=iend;j+=direction,++k)
{
if(pz[j]>0)goto SKIP1;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
SKIP1:
if(k<3)continue;
if(direction>0) {
/*printf("%d %e %e %e\n",j,pz[j],pz[j-1],pz[j-2]);*/
if(pz[j-1]>pz[j] && pz[j-1]>pz[j-2]) {
minp = pz[j-1]*0.001; break; }
} else {
/*printf("%d %e %e %e\n",j,pz[j],pz[j+1],pz[j+2]);*/
if(pz[j+1]>pz[j] && pz[j+1]>pz[j+2]) {
minp = pz[j+1]*0.001; break; }
}
}
for(j=nv/2;j<=nv;++j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && nv-j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=0,i=j-2;i<=j;++i,++k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j+1;i<=nv;++i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Now go from the mode to i=0
*/
for(j=nv/2-1;j>=1;--j)
{
if(pz[j]>0)continue;
for(i=1;i<=nrho;++i)
{
v=v0+(j-1)*binsize;
vv=(v-sintheta*mu[i])*(v-sintheta*mu[i]);
pz[j]+=pdelta[i]*dlogrho/costheta*
(g1[i]*exp(-vv/(sigz1[i])) + g2[i]*exp(-vv/(sigz2[i]))
+ g3[i]*exp(-vv/(sigz3[i])) + g4[i]*exp(-vv/(sigz4[i])));
}
if(pz[j]<=minp && j>=3)break;
}
/* Now extrapolate the rest of the PVD from the last three points.
*/
for(k=2,i=j+2;i>=j;--i,--k)
{
yfit[k]=log(pz[i]);
xfit[k]=v0+(i-1)*binsize;
}
least_squares(xfit,yfit,3,&afit,&bfit);
for(i=j-1;i>0;--i)
pz[i] = exp(afit + bfit*(v0+(i-1)*binsize));
/* Do this just to get rid of any numerical roundoff errors and such.
* (It whould already be one by construction if I didn't have the
* linear extrapolation at the end of each side, but the correction
* shouldn't be much.)
*/
for(ptot=0,i=1;i<=nv;++i)
ptot+=pz[i]*binsize;
for(i=1;i<=nv;++i)
pz[i]/=ptot;
if(isnan(ptot))
{
printf("NAN ptot %f %f %f %f %f %f\n",rho200,rho200t,alpha,rho0,sr4,st4);
fflush(stdout);
for(i=1;i<=nv;++i)
pt[i]=pz[i]=pv[i]=0;
return;
}
return;
}
/* This is the standard log-normal 1-pt distribution of dark
* matter densities (non-linear) at top-hat smoothing scale r.
*/
double delta_pdf(double delta, double r)
{
static int model_prev=0;
static double pnorm=-1,rprev=0,sig0,sig1sqr;
double pnorm1;
if(pnorm<0 || RESET_COSMOLOGY!=model_prev)
{
pnorm1=SIGMA_8/sigmac(8.0);
/*printf("NORM %e %e %e\n",pnorm1,sigmac(8.0),nonlinear_sigmac(8.0));*/
pnorm=pnorm1*sigmac(80.0)/nonlinear_sigmac(80.0);
rprev=0;
/*printf("NORM %e %e %e %e %f\n",pnorm,sigmac(8.0),sigmac(80.0),nonlinear_sigmac(80.0),SIGMA_8);*/
}
if(r!=rprev)
{
sig0=pnorm*nonlinear_sigmac(r);
sig1sqr=log(1+sig0*sig0);
/*printf("NORM %f %f %e %e %e\n",r,sig0,pnorm,nonlinear_sigmac(8.0),sigmac(8.0));*/
}
rprev=r;
model_prev=RESET_COSMOLOGY;
return(1.0/(RT2PI*sqrt(sig1sqr))*exp(-pow(log((1+delta))+sig1sqr*0.5,2.0)/
(2*sig1sqr))/(1+delta));
}