/*cloudy the main routine, this IS Cloudy */ #include "cddefines.h" #include "itercnt.h" #include "zonecnt.h" #include "prtheader.h" #include "dopunch.h" #include "badstart.h" #include "setcon.h" #include "prtcomment.h" #include "noexec.h" #include "lines.h" #include "firstdr.h" #include "createpoint.h" #include "createdata.h" #include "nextdr.h" #include "nsset.h" #include "converge.h" #include "tauinc.h" #include "setabundances.h" #include "conorm.h" #include "warngs.h" #include "parse.h" #include "prtfinal.h" #include "opacity.h" #include "update.h" #include "taulines.h" #include "rt.h" #include "assertresults.h" #include "tauout.h" #include "startendzone.h" #include "startenditer.h" #include "lgendfun.h" #include "plot.h" #include "radinc.h" #include "checksanity.h" #include "cloudy.h" /* returns 1 if disaster strikes, 0 if everything is ok */ int cloudy(void) { int lgOK; # ifdef DEBUG_FUN fputs( "<+>cloudy()\n", debug_fp ); # endif /* * this is the main routine to drive the modules that compute a model * when cloudy is used as a stand-alone program * the main program (maincl) calls cdInit then cdDrive * this sub is called by cdDrive which returns upon exiting * * this routine uses the following variables: * * ZoneCnt.nzone * this is the zone number, and is incremented here * logical function lgEndFun returns a true condition if NZONE reaches * NEND(ITER), the limit to the number of zones in this iteration * ZoneCnt.nzone is totally controlled in this subroutine * * IterCnt.iter * this is the iteration number, it is 1 for the first iteration * and is incremented in this subroutine at the end of each iteration * * IterCnt.itermx * this is the limiit to the number of iterations, and is entered * by the user * This routine returns when IterCnt.iter > IterCnt.itermx */ /* NZONE is zero while initial search for conditions takes place */ ZoneCnt.nzone = 0; /* interpret input data */ ParseCommands(); /* create several data sets by reading in data files, * but only if this is first call */ CreateData(); /* ITER is iteration number */ IterCnt.iter = 1; /* fix pointers to ionization edges and frequency array * calls HydroCreate * this routine has internal check for whether ever called before, * if only retuns if this is a later call of code */ CreatePoint(); /* fix abundances of elements */ SetAbundances(); /* find normalization factors for the continua */ conorm(); /* set continuum */ SetCon(&lgOK); /* print header */ PrtHeader(); /* this is an option to stop after printing header only */ if( noexec.lgNoExec ) { return(0); } /* this happens when disaster strikes in the inital setup */ if( !lgOK ) { BadStart(); return(1); } /* set upper and lower stages of ionization of heavies */ nsset(); /* guess some outward optical depths, set inward optical depths, * also calls RTMake so escap probs ok before printout of trace */ tauout(); /* generate inital set of opacities ut only if this is the first call * in this coreload */ OpacityCreate(); /* this checks that various parts of the code still work properly */ CheckSanity(); /* find the initial temperature, punt if initial conditions outside range of code,*/ if( ConvInitTemp() ) { BadStart(); return(1); } /* set thickness of first zone */ FirstDR(); /* find thickness of next zone */ NextDR(); /* set up some zone variables, correct continuum for sphercity, * after return, radius is equal to the inner radius, not outer radius * of this zone */ StartZone("init"); plot("FIRST"); /* will not trip on following test - will return in mid-loop */ /* this is the iterations counter */ while( IterCnt.iter <= IterCnt.itermx + 10 ) { StartIter(); ZoneCnt.nzone = 0; /* main loop to drive model, lgEndFun checks that model not complete */ while( !lgEndFun() ) { ++ZoneCnt.nzone; /* set variable dealing with new radius */ StartZone("incr"); /* converge the pressure-temperature-ionization solution */ ConvPresTempEdenIoniz(); /* use changes in opacity, temperature, ionization, to fix new dr */ NextDR(); /* generate diffuse emission from this zone, add to outward beams */ RTDiffuse(); /* do work associated with incrementing this radius, * total attenuation and dilution of radiation fields takes place here */ RadInc(); /* increment optical depths */ TauInc(); /* >>chng 99 may 4, move lines here from after RTDiffuse */ /* fill in emission line array */ lines(); /* now that optical depths have been incremented, do escape prob */ RTMake(TRUE); /* possibly punch out some results from this zone */ DoPunch("MIDL"); /* do some things to finish out this zone */ EndZone(); } /* close out this iteration */ EndIter(); /* print out some comments, generate warning and cautions*/ PrtComment(); /* punch stuff only needed on last shot */ DoPunch("LAST" ); plot("SECND"); /* print out the results */ PrtFinal(); /* this is the normal exit out, reach limit to number of iterationsw */ if( IterCnt.iter > IterCnt.itermx ) { /* check whether any asserts were present and failed. * return is true if ok, false if not. routine also checks * number of warnings and returns false if not ok */ lgOK = lgCheckAsserts(ioQQQ); # ifdef DEBUG_FUN fputs( " <->cloudy()\n", debug_fp ); # endif if( lgOK && !warngs.lgWarngs ) { /* no failed asserts or warnings */ return(0); } else { /* there were failed asserts or warnings */ return(1); } } /* update limiting optical depth variables */ update(); ++IterCnt.iter; ZoneCnt.nzone = 0; /* reinitialize some variables which may have changed */ RestartIter(); /* now redo escape probabilities */ RTMake(TRUE); StartZone("init"); /* find new first temperature, punt if gas totally cold and molecular */ if( ConvInitTemp() ) { # ifdef DEBUG_FUN fputs( " <->cloudy()\n", debug_fp ); # endif return(1); } } # ifdef DEBUG_FUN fputs( " <->cloudy()\n", debug_fp ); # endif return(0); }