/* Reads mass function in from a file and spline interpolates.
 */
double nbody_massfunction(double m)
{
  static int flag=0,n;
  static double *x,*y,*y2,log10_2,normhi,normlo;
  float x1,x2,x3;
  int i;
  double a,dx;
  char aa[1000];
  FILE *fp;

  if(!flag)
    {
      log10_2=log10(2.0);
      flag++;
      if(!(fp=fopen(Files.MassFuncFile,"r")))
	endrun("ERROR opening MassFuncFile");
      i=0;
      n = filesize(fp);
      fprintf(stderr,"Read %d lines from [%s]\n",n,Files.MassFuncFile);
      x=dvector(1,n);
      y=dvector(1,n);
      y2=dvector(1,n);
      for(i=1;i<=n;++i)
	{
	  fscanf(fp,"%f %f",&x1,&x2);
	  x[i]=log(x1);
	  y[i]=log(x2);
	  fgets(aa,1000,fp);
	}
      spline(x,y,n,2.0E+30,2.0E+30,y2);
      fclose(fp);
      fprintf(stderr,"Minimum halo mass in N-body dndM= %e\n",exp(x[1]));

      normhi = exp(y[n])/halo_mass_function(exp(x[n]));
      normlo = exp(y[1])/halo_mass_function(exp(x[1]));
    }

  m=log(m);
  //  if(m>x[n])return(0);
  /*if(m<x[1])return(0);*/

  splint(x,y,y2,n,m,&a);
  return(exp(a));
}      
示例#2
0
/* It may be a bit costly to run the above function every time you need
 * dn/dM, so here we put the values into an array and then interpolate. 
 *
 * The currentrange of masses calculated is 10^9 to 10^16.7. The tabulation is
 * done in log(M), so the spline interpolation will perform a power-law fit
 * to masses outside this range.
 */
double dndM_interp(double m)
{
  static int flag=0,prev_cosmo=0, n;
  static double *x,*y,*y2;
  int i;
  double dm,max=16.7,min=8,a,m1,m2,dm1;

  if(!flag || RESET_COSMOLOGY!=prev_cosmo)
    {
      n = 200;
      if(!ThisTask && OUTPUT)
	fprintf(stdout,"RESET: resetting mass function for %f %f\n",OMEGA_M,SIGMA_8);
      fflush(stdout);

      if(!flag)
	{
	  x=dvector(1,n);
	  y=dvector(1,n);
	  y2=dvector(1,n);
	}
      flag=1;
      dm=(double)(max-min)/n;
      for(i=1;i<=n;++i)
	{
	  x[i]=pow(10.0,min+i*dm);
	  y[i]=log(halo_mass_function(x[i]));
	  if(isnan(y[i])) { n = i-1; break; }
	  if(isinf(y[i])) { n = i-1; break; }
	  /*
	  if(DELTA_HALO!=200)
	    {
	      //FAKE_DATA: DELTA_HALO==650
	      m1 = halo_mass_conversion2(x[i]*1.01,halo_c200(x[i]*1.01),200.0,650.0);
	      m2 = halo_mass_conversion2(x[i]*0.99,halo_c200(x[i]*0.99),200.0,650.0);
	      dm1 = (x[i]*1.01 - x[i]*0.99)/(m1-m2);
	      y[i] = y[i] + log(dm1);
	      x[i]=(halo_mass_conversion2(x[i],halo_c200(x[i]),200.0,650.0));
	    }
	  */
	  //printf("MF%d %e %e %e\n",RESET_COSMOLOGY,x[i],exp(y[i]),halo_mass_function(x[i]));fflush(stdout);
	  x[i]=log(x[i]);
	  continue;
	}
      spline(x,y,n,2.0E+30,2.0E+30,y2);
      prev_cosmo=RESET_COSMOLOGY;
      //fprintf(stderr,"MMAX %e\n",exp(x[n]));
    }
  m=log(m);
  
  if(m>x[n])return 0;
  splint(x,y,y2,n,m,&a);
  return(exp(a));

}
/* It may be a bit costly to run the above function every time you need
 * dn/dM, so here we put the values into an array and then interpolate. 
 *
 * The currentrange of masses calculated is 10^9 to 10^16.7. The tabulation is
 * done in log(M), so the spline interpolation will perform a power-law fit
 * to masses outside this range.
 */
double dndM_interp(double m)
{
  static int flag=0,prev_cosmo=0, n;
  static double *x,*y,*y2;
  int i;
  double dm,max=16.7,min=8,a,m1,m2,dm1;

  if(!flag || RESET_COSMOLOGY!=prev_cosmo)
    {
      n = 200;
      if(!ThisTask && OUTPUT)
	fprintf(stdout,"RESET: resetting mass function for %f %f\n",OMEGA_M,SIGMA_8);
      fflush(stdout);

      if(!flag)
	{
	  x=dvector(1,n);
	  y=dvector(1,n);
	  y2=dvector(1,n);
	}
      flag=1;
      dm=(double)(max-min)/n;
      for(i=1;i<=n;++i)
	{
	  x[i]=pow(10.0,min+i*dm);
	  y[i]=log(halo_mass_function(x[i]));
	  //printf("MF%d %e %e\n",RESET_COSMOLOGY,x[i],exp(y[i]));fflush(stdout);
	  if(isnan(y[i])) { n = i-1; break; }
	  if(isinf(y[i])) { n = i-1; break; }
	  x[i]=log(x[i]);
	  continue;
	}
      spline(x,y,n,2.0E+30,2.0E+30,y2);
      prev_cosmo=RESET_COSMOLOGY;
      //fprintf(stderr,"MMAX %e\n",exp(x[n]));
    }
  m=log(m);
  if(m>x[n])return 0;
  splint(x,y,y2,n,m,&a);
  return(exp(a));

}