mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 15:21:11 +00:00
484 lines
12 KiB
C
484 lines
12 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#ifdef PARALLEL
|
|
#include <mpi.h>
|
|
#endif
|
|
|
|
#include "header.h"
|
|
|
|
|
|
/* These are the parameters for creating the pdf table.
|
|
*/
|
|
int nv1,nr1,nphi1;
|
|
void create_pdf_table();
|
|
double ***ppp,*vvv,*rbin,*phibin,***yy2,FIRSTFLAG=1;
|
|
double BINSIZE;
|
|
|
|
double galaxy_prob_vz(double vel, double rad, double theta)
|
|
{
|
|
static int flag=0,prev_cosmo=0;
|
|
static double *y,*ya,*yb,*y2b,*xb,rv[21],rmin,rmax,dlogr;
|
|
|
|
int i,j,k,irad,iphi;
|
|
double vprob,m1,m2;
|
|
|
|
if(!flag || RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo)
|
|
{
|
|
rmin=1.7*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
|
|
rmax=XI_MAX_RADIUS;
|
|
dlogr=log(rmax/rmin)/(nr1-1);
|
|
|
|
if((RESET_PVZ || RESET_COSMOLOGY!=prev_cosmo) && !ThisTask)
|
|
{
|
|
printf("RESET: creating new table for:\n");
|
|
printf(" > OMEGA_M = %f\n",OMEGA_M);
|
|
printf(" > SIGMA_8 = %f\n",SIGMA_8);
|
|
printf(" > VBIAS = %f\n",VBIAS);
|
|
printf(" > VBIAS_C = %f\n",VBIAS_C);
|
|
fflush(stdout);
|
|
}
|
|
RESET_PVZ=0;
|
|
prev_cosmo=RESET_COSMOLOGY;
|
|
|
|
create_pdf_table();
|
|
|
|
if(!flag)
|
|
{
|
|
y=dvector(1,nphi1);
|
|
ya=dvector(1,nphi1);
|
|
yb=dvector(1,4);
|
|
y2b=dvector(1,4);
|
|
xb=dvector(1,4);
|
|
}
|
|
|
|
flag=1;
|
|
|
|
for(i=1;i<=nr1;++i)
|
|
for(j=1;j<=nphi1;++j)
|
|
spline(vvv,ppp[i][j],nv1,1.0E+30,1.0E+30,yy2[i][j]);
|
|
|
|
}
|
|
if(fabs(vel)>MAXVEL)return(0);
|
|
|
|
if(theta<0)theta*=-1;
|
|
|
|
for(i=1;i<=nr1;++i)
|
|
if(rad<rbin[i])break;
|
|
if(i<3)i=3;
|
|
if(i>nr1-1)i=nr1-1;
|
|
irad=i;
|
|
while(rbin[irad-2]==0)irad++;
|
|
if(irad>nr1-1)
|
|
{
|
|
printf("ERROR CANNOT ITERPOLATE FOR r=%f\n",rad);
|
|
exit(0);
|
|
}
|
|
|
|
for(j=1,i=irad-2;i<=irad+1;++i,++j)
|
|
{
|
|
for(k=1;k<=nphi1;++k)
|
|
{
|
|
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[k]);
|
|
}
|
|
spline(phibin,y,nphi1,1.0E+30,1.0E+30,ya);
|
|
splint(phibin,y,ya,nphi1,theta,&yb[j]);
|
|
xb[j]=rbin[i];
|
|
}
|
|
spline(xb,yb,4,1.0E30,1.0E30,y2b);
|
|
splint(xb,yb,y2b,4,rad,&vprob);
|
|
|
|
if(vprob<0)vprob=0;
|
|
return(vprob);
|
|
|
|
|
|
|
|
irad=i;
|
|
if(irad<2)irad=2;
|
|
if(irad>nr1)irad=nr1;
|
|
iphi = (int)theta/(PI/18.0)+1;
|
|
if(iphi==nphi1)iphi=nphi1-1;
|
|
|
|
|
|
for(j=1,i=irad-1;i<=irad;++i)
|
|
{
|
|
for(k=iphi;k<=iphi+1;++k)
|
|
{
|
|
splint(vvv,ppp[i][k],yy2[i][k],nv1,vel,&y[j++]);
|
|
}
|
|
}
|
|
m1 = (y[1]-y[2])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[1];
|
|
m2 = (y[3]-y[4])/(phibin[iphi]-phibin[iphi+1])*(theta-phibin[iphi])+y[3];
|
|
vprob = (m2-m1)/(rbin[irad]-rbin[irad-1])*(rad-rbin[irad-1])+m1;
|
|
if(vprob<0)vprob=0;
|
|
return(vprob);
|
|
|
|
}
|
|
|
|
/* For consistency, the MAXVEL and BINSIZE variables will be scaled by
|
|
* OMEGA_M^0.6.
|
|
*
|
|
*/
|
|
void create_pdf_table()
|
|
{
|
|
#define NZMASS 19
|
|
|
|
int TEST=1;
|
|
|
|
FILE *fp;
|
|
double dlogr,vbias1,vbias2;
|
|
static int CNT=0;
|
|
|
|
double sgal[NZMASS][NZMASS],sgal_cs[NZMASS][NZMASS],sgal_cc[NZMASS][NZMASS],
|
|
*cf,fdat[10],s2gal[4],wgal[3],**mtemp,
|
|
***ptemp,*vtemp,*temp,*p1temp,*p2temp,*precv,*rvir,*ngal,**ngal2,**ngal2x,*mbin;
|
|
double binsize,ptot,vprob,p0,p1,p2,p3,s1,s2,s3,s4,v1,v,
|
|
mass,mlo,mhi,qromo(),midpnt(),sgal1[NZMASS][NZMASS],hmass[NZMASS],
|
|
sgal2[NZMASS][NZMASS],w1[NZMASS][NZMASS],w2[NZMASS][NZMASS],mass1,mass2,wsum,fac,
|
|
w3[NZMASS][NZMASS],t0,tsum=0,t1,tdiff,frac1,frac2,frac3,frac4,x1,x2,deltar,
|
|
haloweight,immax,mmax,rmax,rmin,exfac,xx1=0,weightsum;
|
|
int i,j,k,n,nzmass,imass=0,irad,im1,im2,istep=1,istart=1,jstart=1,jstep=1,
|
|
idat[10],nitems;
|
|
float f1;
|
|
|
|
CNT++;
|
|
|
|
#ifdef PARALLEL
|
|
istep = 1;
|
|
istart = 1;
|
|
jstart = ThisTask + 1;
|
|
jstep = NTask;
|
|
#endif
|
|
|
|
BINSIZE=20*pow(OMEGA_M/0.3,0.6);
|
|
|
|
rmin=R_MIN_2HALO;
|
|
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
|
|
rmax=XI_MAX_RADIUS;
|
|
nr1=30;
|
|
nv1=301;
|
|
nphi1=9;
|
|
MAXVEL=BINSIZE*floor(nv1/2);
|
|
|
|
|
|
/* This assumes that even if the cosmology is changed, that
|
|
* the dimensions of these arrays won't change.
|
|
*/
|
|
if(FIRSTFLAG)
|
|
{
|
|
vvv=dvector(1,nv1);
|
|
rbin=dvector(1,nr1);
|
|
phibin=dvector(1,nphi1);
|
|
yy2=d3tensor(1,nr1,1,nphi1,1,nv1);
|
|
ppp=d3tensor(1,nr1,1,nphi1,1,nv1);
|
|
FIRSTFLAG=0;
|
|
}
|
|
|
|
if(TEST)
|
|
{
|
|
HOD.pdfs=0;
|
|
HOD.M_min = HOD.M_low = 4.4e11;
|
|
rmin=1.1*pow(3*HOD.M_low/(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT),1.0/3.0);
|
|
}
|
|
|
|
dlogr=log(rmax/rmin)/(nr1-1);
|
|
for(i=1;i<=nr1;++i)
|
|
rbin[i]=rmin*exp((i-1)*dlogr);
|
|
for(i=1;i<=nphi1;++i)
|
|
phibin[i]=(i-0.5)/nphi1*PI/2;
|
|
for(i=1;i<=nv1;++i)
|
|
vvv[i]=-MAXVEL+(i-1)*BINSIZE;
|
|
|
|
nzmass=NUM_POW2MASS_BINS-1;
|
|
|
|
ptemp=d3tensor(0,nzmass-1,0,nzmass-1,1,nv1);
|
|
vtemp=dvector(1,nv1);
|
|
temp=dvector(1,nv1);
|
|
p1temp=dvector(1,nv1);
|
|
p2temp=dvector(1,nv1);
|
|
precv=dvector(1,nv1);
|
|
rvir=dvector(0,nzmass);
|
|
mbin=dvector(0,nzmass);
|
|
|
|
|
|
for(i=1;i<=nr1;++i)
|
|
for(j=1;j<=nphi1;++j)
|
|
for(k=1;k<=nv1;++k)
|
|
ppp[i][j][k]=0;
|
|
|
|
binsize=BINSIZE;
|
|
|
|
fac=sqrt(4.499E-48/2.0)*pow(4*DELTA_HALO*PI*OMEGA_M*RHO_CRIT/3,1.0/6.0)*3.09E19;
|
|
fac=fac*fac;
|
|
|
|
/* w1 -> number of i_sat + j_cen pairs
|
|
* w2 -> number of j_sat + i_cen pairs
|
|
* w3 -> number of i_sat + j_sat pairs
|
|
*
|
|
* Okay, I know that all you have to do is switch the indices on
|
|
* w1 to get w2, but just to keep things really clear, I'll have three
|
|
* different matrices.
|
|
*/
|
|
|
|
for(i=0;i<nzmass;++i)
|
|
for(j=0;j<nzmass;++j)
|
|
{
|
|
mass1=1.5*pow(2.0,i)*HOD.M_low;
|
|
vbias1 = (VBIAS_SLOPE*(log(mass1)-34.5)+VBIAS);
|
|
if(vbias1<0.1)vbias1=0.1;
|
|
|
|
|
|
//vbias1 = 0.4/3*log(mass1)/LOGE_10 - 1;
|
|
//if(vbias1<0.6)vbias1=0.6;
|
|
|
|
/* TEMP-> mass threshold
|
|
*/
|
|
/*
|
|
vbias1=1;
|
|
if(mass1<VBIAS_MASS_THRESHOLD)
|
|
vbias1=VBIAS;
|
|
*/
|
|
vbias1 *= vbias1;
|
|
|
|
mass2=1.5*pow(2.0,j)*HOD.M_low;
|
|
vbias2 = (VBIAS_SLOPE*(log(mass2)-34.5)+VBIAS);
|
|
if(vbias2<0.1)vbias2=0.1;
|
|
|
|
//vbias2 = 0.4/3*log(mass2)/LOGE_10 - 1;
|
|
//if(vbias2<0.6)vbias2=0.6;
|
|
|
|
/* TEMP-> mass threshold
|
|
*/
|
|
/*
|
|
vbias2=1;
|
|
if(mass2<VBIAS_MASS_THRESHOLD)
|
|
vbias2=VBIAS;
|
|
*/
|
|
vbias2 *= vbias2;
|
|
mbin[i]=mass1;
|
|
|
|
s1=vbias1*fac*pow(mass1,0.66666666667);
|
|
s2=vbias2*fac*pow(mass2,0.66666666667);
|
|
sgal[i][j]=s1+s2;
|
|
|
|
s1=fac*pow(mass1,0.66666666667)*VBIAS_C*VBIAS_C;
|
|
sgal_cs[i][j]=s1+s2;
|
|
s2=fac*pow(mass2,0.66666666667)*VBIAS_C*VBIAS_C;
|
|
sgal_cc[i][j]=s1+s2;
|
|
|
|
wsum=N_avg(mass1)*dndM_interp(mass1)*N_avg(mass2)*dndM_interp(mass2);
|
|
w1[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_cen(mass2)*dndM_interp(mass2);
|
|
w2[i][j]=N_sat(mass2)*dndM_interp(mass2)*N_cen(mass1)*dndM_interp(mass1);
|
|
w3[i][j]=N_sat(mass1)*dndM_interp(mass1)*N_sat(mass2)*dndM_interp(mass2);
|
|
|
|
// this is for testing sat-sat 2halo term
|
|
//w1[i][j] = w2[i][j] = 0;
|
|
//wsum = w3[i][j];
|
|
//w1[i][j] = w2[i][j] = w3[i][j] = 0;
|
|
//wsum = w3[i][j];
|
|
//w1[i][j] = w2[i][j] = 0;
|
|
|
|
w1[i][j]/=wsum;
|
|
w2[i][j]/=wsum;
|
|
w3[i][j]/=wsum;
|
|
}
|
|
|
|
/* Calculate the average number of galaxy
|
|
* pairs in each combination of halo mass bins.
|
|
*/
|
|
ngal=dvector(0,nzmass-1);
|
|
ngal2=dmatrix(0,nzmass-1,0,nzmass-1);
|
|
ngal2x=dmatrix(0,nzmass-1,0,nzmass-1);
|
|
|
|
for(i=0;i<nzmass;++i)
|
|
{
|
|
mlo=pow(2.0,i)*HOD.M_low;
|
|
mhi=mlo*2;
|
|
ngal[i]=qromo(func_galaxy_density,log(mlo),log(mhi),midpnt);
|
|
ngal2[i][i]=ngal[i]*ngal[i]*0.5;
|
|
}
|
|
for(i=0;i<nzmass;++i)
|
|
for(j=i+1;j<nzmass;++j)
|
|
ngal2[i][j]=ngal[i]*ngal[j];
|
|
|
|
/* Calculate the virial radius for each halo bin.
|
|
*/
|
|
for(i=0;i<nzmass;++i)
|
|
rvir[i]=pow(3*pow(2.0,i)*HOD.M_low*ROOT2/
|
|
(4*DELTA_HALO*PI*RHO_CRIT*OMEGA_M),1.0/3.0);
|
|
for(i=0;i<nzmass;++i)
|
|
hmass[i] = 1.5*pow(2.0,i)*HOD.M_low;
|
|
|
|
for(k=1;k<=nv1;++k)
|
|
vtemp[k]=vvv[k];
|
|
|
|
/* TEMP TEMP TEMP
|
|
*/
|
|
for(i=0;i<nzmass;++i)
|
|
for(j=i;j<nzmass;++j)
|
|
//ngal2x[i][j] = N_cen(hmass[i])*N_sat(hmass[j]) + N_cen(hmass[j])*N_sat(hmass[i]);
|
|
//ngal2x[i][j] = N_sat(hmass[i])*N_sat(hmass[j]);
|
|
ngal2x[i][j] = N_cen(hmass[i])*N_cen(hmass[j]);
|
|
for(i=0;i<nzmass;++i)
|
|
ngal2x[i][i]/=2;
|
|
|
|
/* For each r/phi combination, first calculate the pdf for all possible
|
|
* halo-halo pairs. Once the h-h pdf is calculates, convolve with the
|
|
* galaxy Gaussian pdf.
|
|
*/
|
|
j=jstart;
|
|
if(NTask==1 && OUTPUT)
|
|
{
|
|
printf("TASK %d starting: %d %d\n",ThisTask,istart,jstart);
|
|
fflush(stdout);
|
|
}
|
|
t0=second();
|
|
for(i=istart;i<=nr1;)
|
|
{
|
|
while(j>nphi1) { i++; j=j-nphi1; }
|
|
if(i>nr1)break;
|
|
jstart=j;
|
|
for(j=jstart;j<=nphi1;j+=jstep)
|
|
{
|
|
t1=second();
|
|
tdiff=timediff(t0,t1);
|
|
tsum+=tdiff;
|
|
t0=second();
|
|
if(NTask==1 && OUTPUT)
|
|
{
|
|
fprintf(stdout,"P(v_z) r[%d]= %5.2f phi[%d]=%4.1f [dt= %.2f T=%7.2f] (task= %d)\n",
|
|
i,rbin[i],j,phibin[j]*180/PI,tdiff,tsum,ThisTask);
|
|
fflush(stdout);
|
|
}
|
|
for(im1=0;im1<nzmass;++im1)
|
|
{
|
|
for(im2=im1;im2<nzmass;++im2)
|
|
{
|
|
/* NEW VERSION, with varying VBIAS_C
|
|
*/
|
|
s1=sgal_cs[im2][im1];
|
|
s2=sgal_cs[im1][im2];
|
|
s3=sgal[im1][im2];
|
|
s4=sgal_cc[im1][im2];
|
|
|
|
s2gal[0]=s1;
|
|
s2gal[1]=s2;
|
|
s2gal[2]=s3;
|
|
s2gal[3]=s4;
|
|
wgal[0]=w1[im1][im2];
|
|
wgal[1]=w2[im1][im2];
|
|
wgal[2]=w3[im1][im2];
|
|
|
|
vdelta_v4(mbin[im1],mbin[im2],rbin[i],phibin[j],BINSIZE,-MAXVEL,nv1,cf,
|
|
temp,p1temp,ptemp[im1][im2],wgal,s2gal);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* Output some stuff for testing purposes
|
|
*/
|
|
if(TEST && (j==1 || j==9))
|
|
//if(j==1 || j==9)
|
|
{
|
|
for(im1=0;im1<nzmass;++im1)
|
|
{
|
|
p0=p1=p2=0;
|
|
for(k=1;k<=nv1;++k)
|
|
{
|
|
v = -MAXVEL + (k-1)*BINSIZE;
|
|
p0 += ptemp[im1][im1][k]*BINSIZE;
|
|
p1 += ptemp[im1][im1][k]*v*BINSIZE;
|
|
p2 += ptemp[im1][im1][k]*v*v*BINSIZE;
|
|
//printf("xTEST%d MASS%d %f %e\n",j,im1+1,ptemp[im1][im1][k]);
|
|
}
|
|
p1 = p1/p0;
|
|
p2 = sqrt(p2/p0 - p1*p1);
|
|
if(!isnan(p0+p1+p2))
|
|
printf("TEST%d MASS%d %e %f %f %f\n",j,im1+1,hmass[im1],rbin[i],-p1,p2);
|
|
}
|
|
}
|
|
|
|
/* Now calculate the galaxy-number-wieghted average
|
|
* of the v_z pdf by summing over all halo-halo pairs.
|
|
* (Using sum of virial radii for halo exclusion.)
|
|
*/
|
|
ptot=0;
|
|
weightsum=0;
|
|
for(k=1;k<=nv1;++k)
|
|
for(ppp[i][j][k]=0,im1=0;im1<nzmass;++im1)
|
|
for(im2=im1;im2<nzmass;++im2)
|
|
{
|
|
if(rbin[i]>rvir[im2]*0.75)
|
|
{
|
|
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*
|
|
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
|
|
if(k==1)weightsum+=ngal2[im1][im2]*
|
|
(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
|
|
}
|
|
continue;
|
|
|
|
if(rbin[i]/(rvir[im1]+rvir[im2])>0.5)
|
|
{
|
|
exfac=1;
|
|
if(rbin[i]/(rvir[im1]+rvir[im2])<1.5)
|
|
exfac=ellipsoidal_exclusion_probability(rvir[im2]/rvir[im1],
|
|
rbin[i]/(rvir[im1]+rvir[im2]));
|
|
/*
|
|
if(rbin[i]<(rvir[im1]+rvir[im2]))
|
|
exfac = 0;
|
|
if(rvir[im2]/rvir[im1]>pow(100.0,.333) && rbin[i]>(rvir[im1]+rvir[im2])*0.5)
|
|
exfac = 1;
|
|
*/
|
|
ppp[i][j][k]+=ptemp[im1][im2][k]*ngal2[im1][im2]*exfac*1*
|
|
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
|
|
if(k==1)weightsum+=ngal2[im1][im2]*exfac*1*
|
|
sqrt(bias_interp(hmass[im1],-1)*bias_interp(hmass[im2],-1));
|
|
}
|
|
}
|
|
//printf("WEIGHTSUM %d %d %e %.0f\n",
|
|
// i,j,weightsum,weightsum*BOX_SIZE*BOX_SIZE*BOX_SIZE);
|
|
if(weightsum>0)
|
|
{
|
|
for(k=1;k<=nv1;++k)
|
|
ppp[i][j][k]/=weightsum;
|
|
// for(k=1;k<=nv1;++k)
|
|
//printf("yTEST %d %d %f %e\n",i,j,vvv[k],ppp[i][j][k]);
|
|
for(ptot=0,k=1;k<=nv1;++k)
|
|
ptot+=ppp[i][j][k]*binsize;
|
|
}
|
|
else
|
|
for(k=1;k<=nv1;++k)
|
|
ppp[i][j][k]=0;
|
|
|
|
}
|
|
}
|
|
|
|
#ifdef PARALLEL
|
|
for(i=1;i<=nr1;++i)
|
|
for(j=1;j<=nphi1;++j)
|
|
{
|
|
for(k=1;k<=nv1;++k)
|
|
temp[k]=ppp[i][j][k];
|
|
MPI_Allreduce(&temp[1],&precv[1],nv1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
|
|
for(k=1;k<=nv1;++k)
|
|
ppp[i][j][k]=precv[k];
|
|
}
|
|
#endif
|
|
|
|
free_d3tensor(ptemp,0,nzmass-1,0,nzmass-1,1,nv1);
|
|
free_dvector(vtemp,1,nv1);
|
|
free_dvector(temp,1,nv1);
|
|
free_dvector(p1temp,1,nv1);
|
|
free_dvector(p2temp,1,nv1);
|
|
free_dvector(precv,1,nv1);
|
|
free_dvector(rvir,0,nzmass);
|
|
free_dvector(mbin,0,nzmass);
|
|
free_dvector(ngal,0,nzmass-1);
|
|
free_dmatrix(ngal2,0,nzmass-1,0,nzmass-1);
|
|
|
|
}
|
|
|
|
|