#include #include #include #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(radpmax){ pmax=pdelta[i]; j=i; } } pmax*=1.0E-4; for(i=1;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)); }