/*ParseStop parse the stop command */ #include #include "cddefines.h" #include "physconst.h" #include "varypar.h" #include "bounds.h" #include "radius.h" #include "zonecnt.h" #include "stopcalc.h" #include "input.h" #include "bit32.h" #include "ffmtread.h" #include "lgmatch.h" #include "parse.h" void ParseStop(char *chCard) { int lgEOL; long int i, j; double a, effcol, tread; # ifdef DEBUG_FUN fputs( "<+>ParseStop()\n", debug_fp ); # endif /* first scan off a generic number, all subcommands use at least one */ i = 5; a = FFmtRead(chCard,&i,76,&lgEOL); if( lgEOL ) { fprintf( ioQQQ, " There MUST be a number on a STOP line. Sorry.\n" ); puts( "[Stop in ParseStop]" ); exit(1); } if( lgMatch("TEMP",chCard) ) { /* lowest electron temperature allowed before stopping * assumed to be the log of the temperature if <10 * optional keyword LINEAR forces linear */ if( a <= 10. && !lgMatch("LINE",chCard) ) { tread = pow(10.,a); } else { tread = a; } /* tread is linear temperature*/ if( tread < 3. ) { fprintf( ioQQQ, " Temperatures below 3K not allowed. Reset to 3K. Sorry.\n" ); tread = 3.; } if( lgMatch("EXCE",chCard) ) { /* option for this to be highest allowed temperature, * stop temperate exceeds */ StopCalc.T2High = (float)tread; } else { /* this is ending temperature */ StopCalc.tend = (float)tread; StopCalc.TeLowest = (float)MIN2(StopCalc.TeLowest,StopCalc.tend); } } /* stop thickness command */ else if( lgMatch("THIC",chCard) ) { /* decide whether linear or log, * this branch if key linear appears */ if( lgMatch("LINE",chCard) ) { radius.router[0] = a; } else { /* this is default branch, no key, so log */ if( a > 37. && bit32.lgBit32 ) { fprintf( ioQQQ, " thickness too large for a 32 bit cpu?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } radius.router[0] = pow(10.,a); } /* optional parsec unit */ if( lgMatch("PARS",chCard) ) { radius.router[0] *= PARSEC; } /* can stop at different thickness on each iteration */ for( j=1; j < ITRDIM; j++ ) { a = FFmtRead(chCard,&i,76,&lgEOL); if( lgEOL ) { radius.router[j] = radius.router[j-1]; } else { if( lgMatch("LINE",chCard) ) { radius.router[j] = a; } else { if( a > 37. && bit32.lgBit32 ) { fprintf( ioQQQ, " thickness too large for a 32 bit cpu?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } radius.router[j] = pow(10.,a); } if( lgMatch("PARS",chCard) ) { radius.router[j] *= PARSEC; } } } /* vary option */ if( VaryPar.lgVarOn ) { VaryPar.nvarxt[VaryPar.nparm] = 1; strcpy( chVaryPar.chVarFmt[VaryPar.nparm], "STOP THICKNESS %f" ); /* pointer to where to write */ VaryPar.nvfpnt[VaryPar.nparm] = input.nRead; /* log of temp will be pointer */ VaryPar.vparm[0][VaryPar.nparm] = (float)log10(radius.router[0]); VaryPar.vincr[VaryPar.nparm] = 0.5; ++VaryPar.nparm; } } /* stop optical depth at some energy */ else if( lgMatch("OPTI",chCard) ) { if( a > 37. && bit32.lgBit32 ) { fprintf( ioQQQ, " optical depth too big for a 32 bit cpu?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } /* tau must be a log, and second number is energy where tau specified */ StopCalc.tauend = (float)pow(10.,a); StopCalc.taunu = (float)FFmtRead(chCard,&i,76,&lgEOL); if( lgEOL ) { if( lgMatch("LYMA",chCard) ) { /* largest Lyman limit optical depth */ StopCalc.taunu = 1.; } else if( lgMatch("BALM",chCard) ) { /* stop at this balmer continuum optical depth */ StopCalc.taunu = 0.25; } else { fprintf( ioQQQ, " There must be a second number, the energy in Ryd. Sorry.\n" ); puts( "[Stop in ParseStop]" ); exit(1); } } else { /* if second number is negative then log of energy in rydbergs */ if( StopCalc.taunu < 0. ) { StopCalc.taunu = (float)pow(10.,StopCalc.taunu); } /* check that energy is within bounds of code */ if( StopCalc.taunu < bounds.emm || StopCalc.taunu > bounds.egamry ) { fprintf( ioQQQ, " The energy must be in the range %10.2e to %10.2e. It was %10.2e. Sorry.\n", bounds.emm, bounds.egamry, StopCalc.taunu ); puts( "[Stop in ParseStop]" ); exit(1); } } } /* stop at a particular zone, for each iteration */ else if( lgMatch("ZONE",chCard) ) { /* stop after computing this zone */ ZoneCnt.nend[0] = (long)a; ZoneCnt.lgZoneSet = TRUE; /* this tells code that we intend to stop at this zone, so caution not generated*/ ZoneCnt.lgEndDflt = FALSE; for( j=1; j < ITRDIM; j++ ) { ZoneCnt.nend[j] = (long)FFmtRead(chCard,&i,76,&lgEOL); /* if eol on this iteration, set to previous. In most cases * all will be equal to the first */ if( lgEOL ) ZoneCnt.nend[j] = ZoneCnt.nend[j-1]; } } /* stop at this electron fraction, relative to hydrogen */ else if( lgMatch("EFRA",chCard) ) { if( a <= 0. ) { StopCalc.StopElecFrac = (float)pow(10.,a); } else { StopCalc.StopElecFrac = (float)a; } } /* stop at a particular column density */ else if( lgMatch("COLU",chCard) ) { /* stop at an effective column density */ if( lgMatch("EFFE",chCard) ) { /* actually stop at certain optical depth at 1keV */ effcol = pow(10.,a); StopCalc.tauend = (float)(effcol*2.14e-22); StopCalc.taunu = 73.5; /* vary option */ if( VaryPar.lgVarOn ) { VaryPar.nvarxt[VaryPar.nparm] = 1; strcpy( chVaryPar.chVarFmt[VaryPar.nparm], "STOP EFFECTIVE COLUMN DENSITY %f" ); /* pointer to where to write */ VaryPar.nvfpnt[VaryPar.nparm] = input.nRead; /* log of temp will be pointer */ VaryPar.vparm[0][VaryPar.nparm] = (float)log10(effcol); VaryPar.vincr[VaryPar.nparm] = 0.5; ++VaryPar.nparm; } } else if( lgMatch("IONI",chCard) ) { /* this is ionized column */ if( a > 37. && bit32.lgBit32 ) { fprintf( ioQQQ, " column too big for a 32 bit cpu?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } StopCalc.colpls = (float)pow(10.,a); /* vary option */ if( VaryPar.lgVarOn ) { VaryPar.nvarxt[VaryPar.nparm] = 1; strcpy( chVaryPar.chVarFmt[VaryPar.nparm], "STOP IONIZED COLUMN DENSITY %f" ); /* pointer to where to write */ VaryPar.nvfpnt[VaryPar.nparm] = input.nRead; /* log of temp will be pointer */ VaryPar.vparm[0][VaryPar.nparm] = (float)log10(StopCalc.colpls); VaryPar.vincr[VaryPar.nparm] = 0.5; ++VaryPar.nparm; } } /* stop at a neutral column */ else if( lgMatch("NEUT",chCard) ) { StopCalc.colnut = (float)pow(10.,a); /* vary option */ if( VaryPar.lgVarOn ) { VaryPar.nvarxt[VaryPar.nparm] = 1; strcpy( chVaryPar.chVarFmt[VaryPar.nparm], "STOP NEUTRAL COLUMN DENSITY %f"); /* pointer to where to write */ VaryPar.nvfpnt[VaryPar.nparm] = input.nRead; /* log of temp will be pointer */ VaryPar.vparm[0][VaryPar.nparm] = (float)log10(StopCalc.colnut); VaryPar.vincr[VaryPar.nparm] = 0.5; ++VaryPar.nparm; } } /* fall through default is total hydrogen column density */ else { /* both HII and HI */ if( a > 37. && bit32.lgBit32 ) { fprintf( ioQQQ, " column too big for a 32 bit cpu?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } StopCalc.HColStop = (float)pow(10.,a); /* vary option */ if( VaryPar.lgVarOn ) { VaryPar.nvarxt[VaryPar.nparm] = 1; strcpy( chVaryPar.chVarFmt[VaryPar.nparm], "STOP COLUMN DENSITY %f" ); /* pointer to where to write */ VaryPar.nvfpnt[VaryPar.nparm] = input.nRead; /* log of temp will be pointer */ VaryPar.vparm[0][VaryPar.nparm] = (float)log10(StopCalc.HColStop); VaryPar.vincr[VaryPar.nparm] = 0.5; ++VaryPar.nparm; } } } /* stop when electron density falls below this value, linear or log */ else if( lgMatch("EDEN",chCard) ) { /* stop if electron density falls below this value * LINEAR option */ if( lgMatch("LINE",chCard) ) { StopCalc.StopElecDensity = (float)a; } else { StopCalc.StopElecDensity = (float)pow(10.,a); } } /* stop at a particular line ratio */ else if( lgMatch("LINE",chCard) ) { /* first line wavelength, then intensity relative to Hbeta for stop * if third number is entered, it is wl of line in denominator */ StopCalc.nstpl = MIN2(StopCalc.nstpl+1,MXSTPL); StopCalc.ipStopLin1[StopCalc.nstpl-1] = (long)a; /* save line wavelength */ StopCalc.LineStopWl[StopCalc.nstpl-1] = (long)a; StopCalc.stpint[StopCalc.nstpl-1] = (float)FFmtRead(chCard,&i,76, &lgEOL); if( lgEOL ) { fprintf( ioQQQ, " There MUST be a relative intensity entered. Sorry.\n" ); puts( "[Stop in ParseStop]" ); exit(1); } StopCalc.ipStopLin2[StopCalc.nstpl-1] = (long)FFmtRead(chCard,&i, 76,&lgEOL); if( lgEOL ) { StopCalc.ipStopLin2[StopCalc.nstpl-1] = 1; } else { if( StopCalc.ipStopLin2[StopCalc.nstpl-1] <= 100 || StopCalc.ipStopLin2[StopCalc.nstpl-1] > 10000 ) { fprintf( ioQQQ, " is the 3rd value correct?\n" ); puts( "[Stop in ParseStop]" ); exit(1); } } } /* oops! no keyword that we could find */ else { fprintf( ioQQQ, " keyword error for STOP line, line image follows;\n" ); fprintf( ioQQQ, "==%s==\n" , chCard); puts( "[Stop in ParseStop]" ); exit(1); } # ifdef DEBUG_FUN fputs( " <->ParseStop()\n", debug_fp ); # endif return; }