void Fdbk::CheckParams(PRM prm, struct parameters ¶m) { if(strcmp(achIMF, "MillerScalo") == 0) imf = new MillerScalo(); else if(strcmp(achIMF, "Chabrier") == 0) imf = new Chabrier(); else if(strcmp(achIMF, "Kroupa93") == 0) imf = new Kroupa93(); else if(strcmp(achIMF, "Kroupa01") == 0) imf = new Kroupa01(); sn.imf = imf; #include "physconst.h" if(!prmSpecified(prm, "nSmoothFeedback")) nSmoothFeedback = param.nSmooth; if (sn.dESN > 0.0) bSmallSNSmooth = 1; else bSmallSNSmooth = 0; param.bDoGas = 1; dDeltaStarForm = param.stfm->dDeltaStarForm; dSecUnit = param.dSecUnit; dGmPerCcUnit = param.dGmPerCcUnit; dGmUnit = param.dMsolUnit*MSOLG; dErgUnit = GCGS*pow(param.dMsolUnit*MSOLG, 2.0) /(param.dKpcUnit*KPCCM); dErgPerGmUnit = GCGS*param.dMsolUnit*MSOLG/(param.dKpcUnit*KPCCM); /* eq 3 from McCray + Kafatos (1987) is good both before SN start * exploding and after because Luminosity is essentially constant * Stellar winds: dM/dt ~ 1e-6 M_sun / yr, v ~ 2000 km/s * (cf Castor et al (1975) for theory) */ if (sn.iNSNIIQuantum > 0) { dRadPreFactor = (0.097 / param.dKpcUnit) * pow(param.dGmPerCcUnit/MHYDR,-0.2)* pow(param.dSecUnit/SECONDSPERYEAR / 1e7,0.6); /* Solar metallicity Z from Grevesse & Sauval (1998) SSR 85 161*/ /* TOO LONG dTimePreFactor = 4e6*SECONDSPERYEAR/ param.dSecUnit * pow(0.018,1.5)* pow(param.dGmPerCcUnit/MHYDR,-0.7);*/ } else { /* from McKee and Ostriker (1977) ApJ 218 148 */ dRadPreFactor = pow(10,1.74)/(param.dKpcUnit*1000.0)* pow(MSOLG*param.dMsolUnit/(param.dMeanMolWeight*MHYDR*pow(KPCCM*param.dKpcUnit,3)),-0.16)* pow(0.0001*GCGS*pow(MSOLG*param.dMsolUnit,2)/(pow(KPCCM*param.dKpcUnit,4)*KBOLTZ),-0.2); } if (bShortCoolShutoff){ /* end of snowplow */ dTimePreFactor = SECONDSPERYEAR*pow(10,5.92)/(param.dSecUnit)* pow(MSOLG*param.dMsolUnit/(param.dMeanMolWeight*MHYDR*pow(KPCCM*param.dKpcUnit,3)),0.27)* pow(0.0001*GCGS*pow(MSOLG*param.dMsolUnit,2)/(pow(KPCCM*param.dKpcUnit,4)*KBOLTZ),-0.64); } else { /* t_{max}*/ dTimePreFactor = dExtraCoolShutoff*SECONDSPERYEAR*pow(10,6.85)/(dSecUnit)* pow(MSOLG*param.dMsolUnit/(param.dMeanMolWeight*MHYDR*pow(KPCCM*param.dKpcUnit,3)),0.32)* pow(0.0001*GCGS*pow(MSOLG*param.dMsolUnit,2)/(pow(KPCCM*param.dKpcUnit,4)*KBOLTZ),-0.70); } dMaxCoolShutoff *= SECONDSPERYEAR/param.dSecUnit; }
int FC_MAIN(int argc,char **argv) { MDL mdl; MSR msr; FILE *fpLog = NULL; char achFile[256]; /*DEBUG use MAXPATHLEN here (& elsewhere)? -- DCR*/ double dTime; double E=0,T=0,U=0,Eth=0,L[3]={0,0,0},F[3]={0,0,0},W=0; double dMultiEff=0; long lSec=0,lStart; int i,iStep,iSec=0,iStop=0; uint64_t nActive; #ifdef TINY_PTHREAD_STACK static int first = 1; static char **save_argv; /* * Hackery to get around SGI's tiny pthread stack. * Main will be called twice. The second time, argc and argv * will be garbage, so we have to save them from the first. * Another way to do this would involve changing the interface * to mdlInitialize(), so that this hackery could be hidden * down there. */ if (first) { save_argv = malloc((argc+1)*sizeof(*save_argv)); for (i = 0; i < argc; i++) save_argv[i] = strdup(argv[i]); save_argv[argc] = NULL; } else { argv = save_argv; } first = 0; #endif /* TINY_PTHREAD_STACK */ #ifdef USE_BT bt_initialize(); #endif #ifdef ENABLE_FE feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); #endif #ifndef CCC /* no stdout buffering */ setbuf(stdout,(char *) NULL); #endif lStart=time(0); #ifdef USE_MDL_IO mdlInitialize(&mdl,argv,main_ch,main_io); #else mdlInitialize(&mdl,argv,main_ch,0); #endif for (argc = 0; argv[argc]; argc++); /* some MDLs can trash argv */ printf("%s\n", PACKAGE_STRING ); msrInitialize(&msr,mdl,argc,argv); /* ** Establish safety lock. */ if (!msrGetLock(msr)) { msrFinish(msr); mdlFinish(mdl); return 1; } /* ** Output the host names to make troubleshooting easier */ msrHostname(msr); /* ** Read in the binary file, this may set the number of timesteps or ** the size of the timestep when the zto parameter is used. */ #ifdef USE_GRAFIC if (prmSpecified(msr->prm,"nGrid")) { dTime = msrGenerateIC(msr); msrInitStep(msr); if (prmSpecified(msr->prm,"dSoft")) msrSetSoft(msr,msrSoft(msr)); } else { #endif if ( msr->param.achInFile[0] ) { dTime = msrRead(msr,msr->param.achInFile); msrInitStep(msr); if (msr->param.bAddDelete) msrGetNParts(msr); if (prmSpecified(msr->prm,"dRedFrom")) { double aOld, aNew; aOld = csmTime2Exp(msr->param.csm,dTime); aNew = 1.0 / (1.0 + msr->param.dRedFrom); dTime = msrAdjustTime(msr,aOld,aNew); /* Seriously, we shouldn't need to send parameters *again*. When we remove sending parameters, we should remove this. */ msrInitStep(msr); } if (prmSpecified(msr->prm,"dSoft")) msrSetSoft(msr,msrSoft(msr)); } else { #ifdef USE_PYTHON if ( !msr->param.achScriptFile[0] ) { #endif printf("No input file specified\n"); return 1; } #ifdef USE_PYTHON } #endif #ifdef USE_GRAFIC } #endif if ( msr->param.bWriteIC ) { msrBuildIoName(msr,achFile,0); msrWrite( msr,achFile,dTime,msr->param.bWriteIC-1); } /* ** Now we have all the parameters for the simulation we can make a ** log file entry. */ if (msrLogInterval(msr)) { sprintf(achFile,"%s.log",msrOutName(msr)); fpLog = fopen(achFile,"a"); assert(fpLog != NULL); setbuf(fpLog,(char *) NULL); /* no buffering */ /* ** Include a comment at the start of the log file showing the ** command line options. */ fprintf(fpLog,"# "); for (i=0;i<argc;++i) fprintf(fpLog,"%s ",argv[i]); fprintf(fpLog,"\n"); msrLogParams(msr,fpLog); } #ifdef USE_PYTHON /* If a script file was specified, enter analysis mode */ if ( msr->param.achScriptFile[0] ) iStep = 0; else #endif iStep = msrSteps(msr); if (iStep > 0) { if (msrComove(msr)) { msrSwitchTheta(msr,dTime); } /* ** Build tree, activating all particles first (just in case). */ msrActiveRung(msr,0,1); /* Activate all particles */ msrDomainDecomp(msr,0,1,0); msrUpdateSoft(msr,dTime); msrBuildTree(msr,dTime,msr->param.bEwald); if (msrDoGravity(msr)) { msrGravity(msr,0,MAX_RUNG,dTime,msr->param.iStartStep,msr->param.bEwald,&iSec,&nActive); msrMemStatus(msr); if (msr->param.bGravStep) { msrBuildTree(msr,dTime,msr->param.bEwald); msrGravity(msr,0,MAX_RUNG,dTime,msr->param.iStartStep,msr->param.bEwald,&iSec,&nActive); msrMemStatus(msr); } } if (msrDoGas(msr)) { /* Initialize SPH, Cooling and SF/FB and gas time step */ #ifdef COOLING msrCoolSetup(msr,dTime); #endif /* Fix dTuFac conversion of T in InitSPH */ msrInitSph(msr,dTime); } msrCalcEandL(msr,MSR_INIT_E,dTime,&E,&T,&U,&Eth,L,F,&W); dMultiEff = 1.0; if (msrLogInterval(msr)) { (void) fprintf(fpLog,"%e %e %.16e %e %e %e %.16e %.16e %.16e " "%.16e %.16e %.16e %.16e %i %e\n",dTime, 1.0/csmTime2Exp(msr->param.csm,dTime)-1.0, E,T,U,Eth,L[0],L[1],L[2],F[0],F[1],F[2],W,iSec,dMultiEff); } #ifdef PLANETS if (msr->param.bHeliocentric) { msrGravSun(msr); } #ifdef SYMBA msrDriftSun(msr,dTime,0.5*msrDelta(msr)); #endif #endif if ( msr->param.bTraceRelaxation) { msrInitRelaxation(msr); } #ifdef HERMITE if (msr->param.bHermite) { msrActiveRung(msr,0,1); /* Activate all particles */ msrCopy0(msr, dTime); if (msr->param.bAarsethStep) { msrFirstDt(msr); } } #endif for (iStep=msr->param.iStartStep+1;iStep<=msrSteps(msr)&&!iStop;++iStep) { if (msrComove(msr)) { msrSwitchTheta(msr,dTime); } dMultiEff = 0.0; lSec = time(0); #ifdef HERMITE if (msr->param.bHermite) { msrTopStepHermite(msr,iStep-1,dTime, msrDelta(msr),0,0,msrMaxRung(msr),1, &dMultiEff,&iSec); } else #endif #ifdef SYMBA if (msr->param.bSymba) { msrTopStepSymba(msr,iStep-1,dTime, msrDelta(msr),0,0,msrMaxRung(msr),1, &dMultiEff,&iSec); } else #endif { msrTopStepKDK(msr,iStep-1,dTime, msrDelta(msr),0,0,msrMaxRung(msr),1, &dMultiEff,&iSec); } dTime += msrDelta(msr); lSec = time(0) - lSec; msrMemStatus(msr); /* ** Output a log file line if requested. ** Note: no extra gravity calculation required. */ if (msrLogInterval(msr) && iStep%msrLogInterval(msr) == 0) { msrCalcEandL(msr,MSR_STEP_E,dTime,&E,&T,&U,&Eth,L,F,&W); (void) fprintf(fpLog,"%e %e %.16e %e %e %e %.16e %.16e " "%.16e %.16e %.16e %.16e %.16e %li %e\n",dTime, 1.0/csmTime2Exp(msr->param.csm,dTime)-1.0, E,T,U,Eth,L[0],L[1],L[2],F[0],F[1],F[2],W,lSec,dMultiEff); } if ( msr->param.bTraceRelaxation) { msrActiveRung(msr,0,1); /* Activate all particles */ msrDomainDecomp(msr,0,1,0); msrBuildTree(msr,dTime,0); msrRelaxation(msr,dTime,msrDelta(msr),SMX_RELAXATION,0); } /* ** Check for user interrupt. */ iStop = msrCheckForStop(msr); /* ** Check to see if the runtime has been exceeded. */ if (!iStop && msr->param.iWallRunTime > 0) { if (msr->param.iWallRunTime*60 - (time(0)-lStart) < ((int) (lSec*1.5)) ) { printf("RunTime limit exceeded. Writing checkpoint and exiting.\n"); printf(" iWallRunTime(sec): %d Time running: %ld Last step: %ld\n", msr->param.iWallRunTime*60,time(0)-lStart,lSec); iStop = 1; } } /* ** Output if 1) we've hit an output time ** 2) We are stopping ** 3) we're at an output interval */ if (msrOutTime(msr,dTime) || iStep == msrSteps(msr) || iStop || (msrOutInterval(msr) > 0 && iStep%msrOutInterval(msr) == 0) || (msrCheckInterval(msr) > 0 && iStep%msrCheckInterval(msr) == 0)) { msrOutput(msr,iStep,dTime, msrCheckInterval(msr)>0 && (iStep%msrCheckInterval(msr) == 0 || iStep == msrSteps(msr) || iStop)); } } } /* No steps were requested */ else { #ifdef USE_PYTHON if ( msr->param.achScriptFile[0] ) { PPY ppy; ppyInitialize(&ppy,msr,dTime); msr->prm->script_argv[0] = msr->param.achScriptFile; ppyRunScript(ppy,msr->prm->script_argc,msr->prm->script_argv); ppyFinish(ppy); } else { #endif if (msrDoGravity(msr) ||msrDoGas(msr)) { msrActiveRung(msr,0,1); /* Activate all particles */ msrDomainDecomp(msr,0,1,0); msrUpdateSoft(msr,dTime); msrBuildTree(msr,dTime,msr->param.bEwald); if (msrDoGravity(msr)) { msrGravity(msr,0,MAX_RUNG,dTime,msr->param.iStartStep,msr->param.bEwald,&iSec,&nActive); msrMemStatus(msr); if (msr->param.bGravStep) { msrBuildTree(msr,dTime,msr->param.bEwald); msrGravity(msr,0,MAX_RUNG,dTime,msr->param.iStartStep,msr->param.bEwald,&iSec,&nActive); msrMemStatus(msr); } } if (msrDoGas(msr)) { /* Initialize SPH, Cooling and SF/FB and gas time step */ #ifdef COOLING msrCoolSetup(msr,dTime); #endif /* Fix dTuFac conversion of T in InitSPH */ msrInitSph(msr,dTime); } msrUpdateRung(msr,0); /* set rungs for output */ msrCalcEandL(msr,MSR_INIT_E,dTime,&E,&T,&U,&Eth,L,F,&W); dMultiEff = 1.0; if (msrLogInterval(msr)) { (void) fprintf(fpLog,"%e %e %.16e %e %e %e %.16e %.16e " "%.16e %.16e %.16e %.16e %.16e %i %e\n",dTime, 1.0/csmTime2Exp(msr->param.csm,dTime)-1.0, E,T,U,Eth,L[0],L[1],L[2],F[0],F[1],F[2],W,iSec,dMultiEff); } } msrOutput(msr,0,dTime,0); /* JW: Will trash gas density */ #ifdef USE_PYTHON } #endif } if (msrLogInterval(msr)) (void) fclose(fpLog); #ifdef PP_SIMD_BENCHMARK PPDumpStats(); #endif msrFinish(msr); mdlFinish(mdl); return 0; }