/*** Returns the 1D cubic spline interpolated value ***/ double Spline::operator()(double xpt) const { double result; if (dim!=1) error("Spline.operator(): wrong dimension (expected 1) or not initialized."); splint(x1, f1d, d2fdx2, N1, xpt, &result); return result; }
double generate_satellite_galaxy_tab(double mass, double mstarlow, int reset) { static double **mgal, **ngal, **zz, prev_mass = -1, *mhalo, *totsat, *zzh, dlogmh, masslimit; static int n=0, nm, *nn; int i, j, k, iter=0; double mlo, mhi, dm, ngaltot, pmax, p, x, m, mhlo, mhhi, p1, w; if(reset) { if(!n) { n = 100; nm = 100; mgal = dmatrix(1,nm,1,n); ngal = dmatrix(1,nm,1,n); zz = dmatrix(1,nm,1,n); mhalo = dvector(1,nm); totsat = dvector(1,nm); zzh = dvector(1,nm); nn = ivector(1,nm); } mlo = mstarlow; mhi = 12.0; dm = (mhi-mlo)/(n-1); mhlo = 1.0E+11; mhhi = 1.0E+16; dlogmh = log(mhhi/mhlo)/(nm-1); masslimit = mhlo; for(j=1;j<=nm;++j) { ngaltot = 0; pmax = 0; mhalo[j] = exp(dlogmh*(j-1))*mhlo; nn[j] = n; for(i=1;i<=n;++i) { mgal[j][i] = (i-1)*dm + mlo; set_up_hod_for_shmr(pow(10.0,mgal[j][i]-dm/2),pow(10.0,mgal[j][i]+dm/2),wpl.a); p = N_sat(mhalo[j]); if(i==1 && p<=0)masslimit = mhalo[j]; //if(BLUE_FLAG==0) //printf("BUH %d %d %e %e %e\n",j,i,mhalo[j],mgal[j][i],p); if(p<1.0E-10) { nn[j] = i-1; break; } ngal[j][i] = p; if(ngal[j][i]>pmax)pmax=ngal[j][i]; } set_up_hod_for_shmr(pow(10.0,mstarlow),pow(10.0,12.0),wpl.a); totsat[j] = log(N_sat(mhalo[j])); //if(BLUE_FLAG==0) //printf("BUHTOT %e\n",N_sat(mhalo[j])); mhalo[j] = log(mhalo[j]); //printf("> %e %e\n",mhalo[j]/log(10),totsat[j]/log(10)); for(i=1;i<=nn[j];++i) ngal[j][i] /= pmax; for(i=1;i<=nn[j];++i) ngal[j][i] = log(ngal[j][i]); spline(mgal[j],ngal[j],nn[j],1.0E+30,1.0E+30,zz[j]); } spline(mhalo, totsat,nm,1.0E+30,1.0+30,zzh); return; } //if mass<0 just return total number of satellites if(mass<0) { if(-mass<masslimit)return 0; splint(mhalo, totsat, zzh, nm,log(-mass),&p); return exp(p); } // find the mass bins the bracket the input mass mass = log(mass); for(j=2;j<=nm;++j) if(mhalo[j]>mass)break; if(j>nm)j=nm; w = (mass-mhalo[j-1])/dlogmh; // randomly grab while(1) { iter++; m = drand48()*(12.0-mstarlow)+mstarlow; splint(mgal[j],ngal[j],zz[j],nn[j],m,&p); p = exp(p); if(m>mgal[j][nn[j]])p = 0; splint(mgal[j-1],ngal[j-1],zz[j-1],nn[j-1],m,&p1); p1 = exp(p1); if(m>mgal[j-1][nn[j-1]])p1 = 0; p = p*w + p1*(1-w); if(iter>10000){ printf("BOO %e %e %e %e %e\n",exp(mass),m,p,w,p1); m = 9.0; break; } if(drand48()<p)break; } return m; }
double generate_satellite_galaxy(double mass, double mstarlow) { static double *mgal, *ngal, *zz, prev_mass = -1; static int n=0; int i, j, k, iter=0; double mlo, mhi, dm, ngaltot, pmax, p, x, m; if(mass != prev_mass) { if(mass<0)mass = -mass; prev_mass = mass; if(!n) { n = 20; mgal = dvector(1,n); ngal = dvector(1,n); zz = dvector(1,n); } mlo = mstarlow; mhi = 12.0; dm = (mhi-mlo)/(n-1); ngaltot = 0; pmax = 0; for(i=1;i<=n;++i) { mgal[i] = (i-1)*dm + mlo; set_up_hod_for_shmr(pow(10.0,mgal[i]-dm/2),pow(10.0,mgal[i]+dm/2),wpl.a); ngal[i] = N_sat(mass); //printf("%e %f %f\n",mass,mgal[i],ngal[i]); if(ngal[i]>pmax)pmax=ngal[i]; } set_up_hod_for_shmr(pow(10.0,mstarlow),pow(10.0,12.0),wpl.a); ngaltot = N_sat(mass); for(i=1;i<=n;++i) ngal[i] /= pmax; spline(mgal,ngal,n,1.0E+30,1.0E+30,zz); // if reset call, send total number of satellites return ngaltot; } // test while(iter<1000) { iter++; m = drand48()*(12.0-mstarlow)+mstarlow; splint(mgal,ngal,zz,n,m,&p); printf("TEST2 %f %e\n",m,p); } exit(0); // randomly grab while(1) { m = drand48()*(12.0-mstarlow)+mstarlow; splint(mgal,ngal,zz,n,m,&p); if(drand48()<p)break; } return m; }
void initialize_mass_function(double *a1, double *a2, double *a3, double *a4) { int n = 9, i; double *x, *y, *z, at, ztemp; x = dvector(1,n); y = dvector(1,n); z = dvector(1,n); // initialize the overdensities for(i=1;i<=9;i+=2) x[i] = log(200*pow(2.0,(i-1.0)/2.0)); for(i=2;i<=9;i+=2) x[i] = log(300*pow(2.0,(i-2.0)/2.0)); //first parameter y[1] = 1.858659e-01 ; y[2] = 1.995973e-01 ; y[3] = 2.115659e-01 ; y[4] = 2.184113e-01 ; y[5] = 2.480968e-01 ; y[6] = 2.546053e-01 ; y[7] = 2.600000e-01 ; y[8] = 2.600000e-01 ; y[9] = 2.600000e-01 ; spline(x,y,n,1.0E+30,1.0E+30,z); splint(x,y,z,n,log(DELTA_HALO),a1); if(DELTA_HALO>=1600) *a1 = 0.26; //second parameter y[1] = 1.466904e+00 ; y[2] = 1.521782e+00 ; y[3] = 1.559186e+00 ; y[4] = 1.614585e+00 ; y[5] = 1.869936e+00 ; y[6] = 2.128056e+00 ; y[7] = 2.301275e+00 ; y[8] = 2.529241e+00 ; y[9] = 2.661983e+00 ; spline(x,y,n,1.0E+30,1.0E+30,z); splint(x,y,z,n,log(DELTA_HALO),a2); //third parameter y[1] = 2.571104e+00 ; y[2] = 2.254217e+00 ; y[3] = 2.048674e+00 ; y[4] = 1.869559e+00 ; y[5] = 1.588649e+00 ; y[6] = 1.507134e+00 ; y[7] = 1.464374e+00 ; y[8] = 1.436827e+00 ; y[9] = 1.405210e+00 ; spline(x,y,n,1.0E+30,1.0E+30,z); splint(x,y,z,n,log(DELTA_HALO),a3); //fourth parameter y[1] = 1.193958e+00; y[2] = 1.270316e+00; y[3] = 1.335191e+00; y[4] = 1.446266e+00; y[5] = 1.581345e+00; y[6] = 1.795050e+00; y[7] = 1.965613e+00; y[8] = 2.237466e+00; y[9] = 2.439729e+00; spline(x,y,n,1.0E+30,1.0E+30,z); splint(x,y,z,n,log(DELTA_HALO),a4); // now adjust for redshift if(!(REDSHIFT>0))return; ztemp = REDSHIFT; if(REDSHIFT>3) ztemp = 3.0; *a1 *= pow(1+ztemp,-0.14); *a2 *= pow(1+ztemp,-0.14); at = -pow(0.75/log10(DELTA_HALO/75),1.2); at = pow(10.0,at); *a3 *= pow(1+ztemp,-at); }
/* Integrate the RS spectra with the detector response */ double rs_det( double *ex, int *nrs, float *emin, float *de ) { int i,icgs,dlength,j,loc,numt,spec_bins,k,locl,loch,abs_n; double *spec,lambda_cgs,lambda_det,lambda_s,integral,val,cnts2cgs; float *elo,*ehi,*area,spec_emin,spec_de,spec_scale,bandmin, bandmax,emid,te,*spec_e,abs_e[260],abs_sigma[260],y2abs[260], *absorption,sigma,NH; char dirname[300],infile1[300],infile2[300],command[300]; char trash[200],junk[200]; FILE *inp,*pip; void spline(),splint(); /* H column density [10^20 cm^-2] */ NH = 0.0; icgs = 0; /* [icgs = 1 (CGS: erg s^-1 cm^-2], 0 [cnts s^-1] */ *spec = *ex; spec_bins = *nrs; spec_emin = *emin; spec_de = *de; strcpy(dirname,"/dworkin/home/daisuke/Raymond/EffArea/"); strcat(infile1,dirname); strcat(infile2,dirname); strcat(infile1,"chandra_acis-s-bi_0.3-7.0keV.eff"); strcat(infile2,"cross_sections.dat"); /* calculate length of detector area file */ sprintf(command,"wc %s",infile1); pip=popen(command,"r"); fscanf(pip,"%d",&dlength); dlength--; pclose(pip); elo=(float *)calloc(dlength,sizeof(float)); ehi=(float *)calloc(dlength,sizeof(float)); area=(float *)calloc(dlength,sizeof(float)); /* read in detector effective area */ inp=fopen(infile1,"r"); fgets(trash,200,inp); sscanf(trash,"%s %f %f",&junk,&bandmin,&bandmax); printf("# %s: Band is %5.2f:%5.2f with %d energy channels\n", infile1,bandmin,bandmax,dlength); for (i=0;i<dlength;i++) fscanf(inp,"%f %f %f",elo+i,ehi+i,area+i); fclose(inp); /* read in the galactic absorption cross sections */ inp=fopen(infile2,"r"); abs_n=0;while(fgets(trash,200,inp)!=NULL) { if (strncmp(trash,"#",1)) { sscanf(trash,"%f %f",abs_e+abs_n,abs_sigma+abs_n); abs_n++; } } fclose(inp); /* spline this for future use */ spline(abs_e-1,abs_sigma-1,abs_n,0.0,0.0,y2abs-1); /* cycle through rs-spectra, calculating lambdas */ /* exit if spectra don't extend beyond range of detector sensitivity */ if (bandmin<spec_emin || bandmax>spec_emin+spec_de*spec_bins) { printf(" Detector energy range larger than R-S spectra range\n"); exit(0); } spec=(double *)calloc(spec_bins,sizeof(double)); spec_e=(float *)calloc(spec_bins,sizeof(float)); absorption=(float *)calloc(spec_bins,sizeof(float)); for (j=0;j<spec_bins;j++) { spec_e[j]=spec_emin+(float)j*spec_de; /* calculate the absorption cross section at this energy */ if (spec_e[j]<abs_e[0]) sigma=abs_sigma[0]; else { if (spec_e[j]>abs_e[abs_n-1]) sigma=abs_sigma[abs_n-1]; else splint(abs_e-1,abs_sigma-1,y2abs-1,abs_n,spec_e[j],&sigma); } absorption[j]=exp(-1.0*sigma*NH); /* RS spectrum is modified by the galactic absorption */ spec[j]*=absorption[j]; } /* calculate lambda in detector units */ lambda_det=0.0; for (j=0;j<dlength;j++) { /* integrate over spectral emissivity from elo[] to ehi[] */ locl=(int)((elo[j]-spec_emin)/spec_de); loch=(int)((ehi[j]-spec_emin)/spec_de); /* detector bin lies within single R-S bin */ if (locl==loch) integral=area[j]*(ehi[j]-elo[j])*spec[locl]; else {/* detector bin extends over more than one R-S bin */ /* take care of the first partial bin */ integral=(spec_de-(elo[j]-spec_e[locl]))*spec[locl]; /* add all the enclosed bins */ for (k=locl+1;k<loch;k++) integral+=spec_de*spec[k]; /* take care of the last partial bin */ integral+=(ehi[j]-spec_e[loch])*spec[loch]; /* now scale by the area of this detector bin */ integral*=area[j]; } /* convert from cgs to counts */ emid=0.5*(elo[j]+ehi[j]); val=integral/(emid*KEV_2_ERGS); lambda_det+=val; } /* now calculate theoretical lambda in cgs units */ loc=(bandmin-spec_emin)/spec_de; /* initialize using value from first partial bin */ lambda_cgs=(spec_de-(bandmin-spec_e[loc]))*spec[loc]; /* add contribution from all the full bins */ for (j=loc+1;j<spec_bins;j++) { if (bandmax>spec_e[j+1]) lambda_cgs+=spec_de*spec[j]; else break; } /* add contribution from last partial bin */ lambda_cgs+=(bandmax-spec_e[j])*spec[j]; /* calculate conversion from observed count rate to cgs flux */ if (lambda_det>0.0) cnts2cgs=lambda_cgs/lambda_det; else cnts2cgs=0.0; if (icgs ==1) return(lambda_cgs); if (icgs ==0) return(lambda_det); }
void make_tables(FILE *out,t_forcerec *fr,bool bVerbose,char *fn) { static char *fns[3] = { "ctab.xvg", "dtab.xvg", "rtab.xvg" }; FILE *fp; t_tabledata *td; bool bReadTab,bGenTab; real x0,y0,yp,rtab; int i,j,k,nx,nx0,tabsel[etiNR]; set_table_type(tabsel,fr); snew(td,etiNR); fr->tabscale = 0; rtab = fr->rtab; nx0 = 10; nx = 0; /* Check whether we have to read or generate */ bReadTab = FALSE; bGenTab = FALSE; for(i=0; (i<etiNR); i++) { if (tabsel[i] == etabUSER) bReadTab = TRUE; else bGenTab = TRUE; } if (bReadTab) { read_tables(out,fn,td); fr->tabscale = td[0].tabscale; fr->rtab = td[0].x[td[0].nx-1]; nx0 = td[0].nx0; nx = fr->ntab = fr->rtab*fr->tabscale; if (fr->rtab < rtab) fatal_error(0,"Tables in file %s not long enough for cut-off:\n" "\tshould be at least %f nm\n",fn,rtab); } if (bGenTab) { if (!bReadTab) { #ifdef DOUBLE fr->tabscale = 2000.0; #else fr->tabscale = 500.0; #endif nx = fr->ntab = fr->rtab*fr->tabscale; } } snew(fr->coulvdwtab,12*(nx+1)+1); for(k=0; (k<etiNR); k++) { if (tabsel[k] != etabUSER) { init_table(out,nx,nx0,tabsel[k], (tabsel[k] == etabEXPMIN) ? fr->tabscale_exp : fr->tabscale, &(td[k]),!bReadTab); fill_table(&(td[k]),tabsel[k],fr); if (out) fprintf(out,"Generated table with %d data points for %s.\n" "Tabscale = %g points/nm\n", td[k].nx,tabnm[tabsel[k]],td[k].tabscale); } copy2table(td[k].nx,k*4,12,td[k].x,td[k].v,td[k].v2,fr->coulvdwtab,-1); if (bDebugMode() && bVerbose) { fp=xvgropen(fns[k],fns[k],"r","V"); for(i=td[k].nx0+1; (i<td[k].nx-1); i++) { for(j=0; (j<4); j++) { x0=td[k].x[i]+0.25*j*(td[k].x[i+1]-td[k].x[i]); splint(td[k].x,td[k].v,td[k].v2,nx-3,x0,&y0,&yp); if(fp) fprintf(fp,"%15.10e %15.10e %15.10e\n",x0,y0,yp); } } ffclose(fp); } done_tabledata(&(td[k])); } sfree(td); }