root/branches/newmole/source/cloudy.cpp
| Revision 2542, 10.5 kB (checked in by rjrw, 3 weeks ago) | |
|---|---|
|
|
| Line | |
|---|---|
| 1 | /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and |
| 2 | * others. For conditions of distribution and use see copyright notice in license.txt */ |
| 3 | /*cloudy the main routine, this IS Cloudy, return 0 normal exit, 1 error exit, |
| 4 | * called by maincl when used as standalone program */ |
| 5 | /*BadStart announce that things are so bad the calculation cannot even start */ |
| 6 | #include "cddefines.h" |
| 7 | #include "punch.h" |
| 8 | #include "noexec.h" |
| 9 | #include "lines.h" |
| 10 | #include "abund.h" |
| 11 | #include "continuum.h" |
| 12 | #include "warnings.h" |
| 13 | #include "atmdat.h" |
| 14 | #include "prt.h" |
| 15 | #include "conv.h" |
| 16 | #include "parse.h" |
| 17 | #include "dynamics.h" |
| 18 | #include "init.h" |
| 19 | #include "opacity.h" |
| 20 | #include "state.h" |
| 21 | #include "rt.h" |
| 22 | #include "assertresults.h" |
| 23 | #include "zones.h" |
| 24 | #include "iterations.h" |
| 25 | #include "plot.h" |
| 26 | #include "radius.h" |
| 27 | #include "grid.h" |
| 28 | #include "cloudy.h" |
| 29 | #include "ionbal.h" |
| 30 | #include "dense.h" |
| 31 | |
| 32 | /*BadStart announce that things are so bad the calculation cannot even start */ |
| 33 | STATIC void BadStart(void); |
| 34 | |
| 35 | /* returns 1 if disaster strikes, 0 if everything appears ok */ |
| 36 | bool cloudy(void) |
| 37 | { |
| 38 | bool lgOK, |
| 39 | /* will be used to remember why we stopped, |
| 40 | * return error exit in some cases */ |
| 41 | lgBadEnd; |
| 42 | |
| 43 | /* |
| 44 | * this is the main routine to drive the modules that compute a model |
| 45 | * when cloudy is used as a stand-alone program |
| 46 | * the main program (maincl) calls cdInit then cdDrive |
| 47 | * this sub is called by cdDrive which returns upon exiting |
| 48 | * |
| 49 | * this routine uses the following variables: |
| 50 | * |
| 51 | * nzone |
| 52 | * this is the zone number, and is incremented here |
| 53 | * is zero during search phase, 1 for first zone at illuminated face |
| 54 | * logical function iter_end_check returns a true condition if NZONE reaches |
| 55 | * NEND(ITER), the limit to the number of zones in this iteration |
| 56 | * nzone is totally controlled in this subroutine |
| 57 | * |
| 58 | * iteration |
| 59 | * this is the iteration number, it is 1 for the first iteration |
| 60 | * and is incremented in this subroutine at the end of each iteration |
| 61 | * |
| 62 | * iterations.itermx |
| 63 | * this is the limit to the number of iterations, and is entered |
| 64 | * by the user |
| 65 | * This routine returns when iteration > iterations.itermx |
| 66 | */ |
| 67 | |
| 68 | /* nzone is zero while initial search for conditions takes place |
| 69 | * and is incremented to 1 for start of first zone */ |
| 70 | nzone = 0; |
| 71 | fnzone = 0.; |
| 72 | |
| 73 | /* iteration is iteration number, calculation is complete when iteration > iterations.itermx */ |
| 74 | iteration = 1; |
| 75 | |
| 76 | /* flag for error exit */ |
| 77 | lgBadEnd = false; |
| 78 | |
| 79 | /* this initializes variables at the start of each simulation |
| 80 | * in a grid, before the parser is called - this must set any values |
| 81 | * that may be changed by the command parser */ |
| 82 | InitDefaultsPreparse(); |
| 83 | |
| 84 | /* scan in and parse input data */ |
| 85 | ParseCommands(); |
| 86 | |
| 87 | /* fix abundances of elements, in abundances.cpp */ |
| 88 | AbundancesSet(); |
| 89 | |
| 90 | ASSERT(lgElemsConserved()); |
| 91 | |
| 92 | /* one time creation of some variables */ |
| 93 | InitCoreloadPostparse(); |
| 94 | |
| 95 | /* initialize vars that can only be done after parsing the commands |
| 96 | * sets up CO network since this depends on which elements are on |
| 97 | * and whether chemistry is enabled */ |
| 98 | InitSimPostparse(); |
| 99 | |
| 100 | /* ContCreateMesh calls fill to set up continuum energy mesh if first call, |
| 101 | * otherwise reset to original mesh. |
| 102 | * This is AFTER ParseCommands so that |
| 103 | * path and mesh size can be set with commands before mesh is set */ |
| 104 | ContCreateMesh(); |
| 105 | |
| 106 | /* create several data sets by allocating memory and reading in data files, |
| 107 | * but only if this is first call */ |
| 108 | atmdat_readin(); |
| 109 | |
| 110 | /* fix pointers to ionization edges and frequency array |
| 111 | * calls iso_create |
| 112 | * this routine only returns if this is a later call of code */ |
| 113 | ContCreatePointers(); |
| 114 | |
| 115 | /* Badnell_rec_init This code is written by Terry Yun, 2005 * |
| 116 | * It reads dielectronic recombination rate coefficient fits into 3D arrays */ |
| 117 | Badnell_rec_init(); |
| 118 | |
| 119 | ASSERT(lgElemsConserved()); |
| 120 | |
| 121 | /* set continuum normalization, continuum itself, and ionization stage limits */ |
| 122 | if( ContSetIntensity() ) |
| 123 | { |
| 124 | /* this happens when disaster strikes in the initial setup of the continuum intensity array, |
| 125 | * BadStart is in this file, below */ |
| 126 | BadStart(); |
| 127 | return(true); |
| 128 | } |
| 129 | |
| 130 | ASSERT(lgElemsConserved()); |
| 131 | |
| 132 | /* print header */ |
| 133 | PrtHeader(); |
| 134 | |
| 135 | /* this is an option to stop after initial setup */ |
| 136 | if( noexec.lgNoExec ) |
| 137 | return(false); |
| 138 | |
| 139 | /* guess some outward optical depths, set inward optical depths, |
| 140 | * also calls RT_line_all so escape probabilities ok before printout of trace */ |
| 141 | RT_tau_init(); |
| 142 | |
| 143 | /* generate initial set of opacities, but only if this is the first call |
| 144 | * in this core load |
| 145 | * grains only exist AFTER this routine exits */ |
| 146 | OpacityCreateAll(); |
| 147 | |
| 148 | ASSERT(lgElemsConserved()); |
| 149 | |
| 150 | /* this checks that various parts of the code still work properly */ |
| 151 | SanityCheck("begin"); |
| 152 | |
| 153 | /* option to recover state from previous calculation */ |
| 154 | if( state.lgGet_state ) |
| 155 | state_get_put( "get" ); |
| 156 | |
| 157 | ASSERT(lgElemsConserved()); |
| 158 | |
| 159 | /* find the initial temperature, punt if initial conditions outside range of code, |
| 160 | * abort condition set by flag lgAbort */ |
| 161 | if( ConvInitSolution() ) |
| 162 | { |
| 163 | BadStart(); |
| 164 | return(true); |
| 165 | } |
| 166 | |
| 167 | /* set thickness of first zone */ |
| 168 | radius_first(); |
| 169 | |
| 170 | /* find thickness of next zone */ |
| 171 | if( radius_next() ) |
| 172 | { |
| 173 | BadStart(); |
| 174 | return(true); |
| 175 | } |
| 176 | |
| 177 | /* set up some zone variables, correct continuum for sphericity, |
| 178 | * after return, radius is equal to the inner radius, not outer radius |
| 179 | * of this zone */ |
| 180 | ZoneStart("init"); |
| 181 | |
| 182 | /* print all abundances, gas phase and grains, in abundances.c */ |
| 183 | /* >>chng 06 mar 05, move AbundancesPrt() after ZoneStart("init") so that |
| 184 | * GrnVryDpth() gives correct values for the inner face of the cloud, PvH */ |
| 185 | AbundancesPrt(); |
| 186 | |
| 187 | /* this is an option to stop after printing header only */ |
| 188 | if( prt.lgOnlyHead ) |
| 189 | return(false); |
| 190 | |
| 191 | plot("FIRST"); |
| 192 | |
| 193 | /* outer loop is over number of iterations |
| 194 | * >>chng 05 mar 12, chng from test on true to not aborting */ |
| 195 | while( !lgAbort ) |
| 196 | { |
| 197 | IterStart(); |
| 198 | nzone = 0; |
| 199 | fnzone = 0.; |
| 200 | |
| 201 | /* loop over zones across cloud for this iteration, |
| 202 | * iter_end_check checks whether model is complete and this iteration is done |
| 203 | * returns true is current iteration is complete |
| 204 | * calls PrtZone to print zone results */ |
| 205 | while( !iter_end_check() ) |
| 206 | { |
| 207 | /* the zone number, 0 during search phase, first zone is 1 */ |
| 208 | ++nzone; |
| 209 | /* this is the zone number plus the number of calls to bottom solvers |
| 210 | * from top pressure solver, divided by 100 */ |
| 211 | fnzone = (double)nzone; |
| 212 | |
| 213 | /* use changes in opacity, temperature, ionization, to fix new dr for next zone */ |
| 214 | /* >>chng 03 oct 29, move radius_next up to here from below, so that |
| 215 | * precise correct zone thickness will be used in current zone, so that |
| 216 | * column density and thickness will be exact |
| 217 | * abort condition is possible */ |
| 218 | if( radius_next() ) |
| 219 | break; |
| 220 | |
| 221 | /* following sets zone thickness, drad, to drnext */ |
| 222 | /* set variable dealing with new radius, in zones.c */ |
| 223 | ZoneStart("incr"); |
| 224 | |
| 225 | /* converge the pressure-temperature-ionization solution for this zone |
| 226 | * NB ignoring return value - should be ok (return 1 for abort) |
| 227 | * we can't break here in case of abort since there is still housekeeping |
| 228 | * that must be done in following routines */ |
| 229 | ConvPresTempEdenIoniz(); |
| 230 | |
| 231 | /* generate diffuse emission from this zone, add to outward & reflected beams */ |
| 232 | RT_diffuse(); |
| 233 | |
| 234 | /* do work associated with incrementing this radius, |
| 235 | * total attenuation and dilution of radiation fields takes place here, |
| 236 | * reflected continuum incremented here |
| 237 | * various mean and extremes of solution are also remembered here */ |
| 238 | radius_increment(); |
| 239 | |
| 240 | /* increment optical depths */ |
| 241 | RT_tau_inc(); |
| 242 | |
| 243 | /* fill in emission line array, adds outward lines */ |
| 244 | /* >>chng 99 dec 29, moved to here from below RT_tau_inc, |
| 245 | * lines adds lines to outward beam, |
| 246 | * and these are attenuated in radius_increment */ |
| 247 | lines(); |
| 248 | |
| 249 | /* possibly punch out some results from this zone */ |
| 250 | PunchDo("MIDL"); |
| 251 | |
| 252 | /* do some things to finish out this zone */ |
| 253 | ZoneEnd(); |
| 254 | } |
| 255 | /* end loop over zones */ |
| 256 | |
| 257 | /* close out this iteration, in startenditer.c */ |
| 258 | IterEnd(); |
| 259 | |
| 260 | /* print out some comments, generate warning and cautions*/ |
| 261 | PrtComment(); |
| 262 | |
| 263 | /* punch stuff only needed on completion of this iteration */ |
| 264 | PunchDo("LAST" ); |
| 265 | |
| 266 | /* second call to plot routine, to complete plots for this iteration */ |
| 267 | plot("SECND"); |
| 268 | |
| 269 | /* print out the results */ |
| 270 | PrtFinal(); |
| 271 | |
| 272 | /*ConvIterCheck check whether model has converged or whether more iterations |
| 273 | * are needed - implements the iter to convergence command */ |
| 274 | ConvIterCheck(); |
| 275 | |
| 276 | /* reset limiting and initial optical depth variables */ |
| 277 | RT_tau_reset(); |
| 278 | |
| 279 | /* option to save state */ |
| 280 | if( state.lgPut_state ) |
| 281 | state_get_put( "put" ); |
| 282 | |
| 283 | /* >>chng 06 mar 03 move block to here, had been after PrtFinal, |
| 284 | * so that save state will save reset optical depths */ |
| 285 | /* this is the normal exit, occurs if we reached limit to number of iterations, |
| 286 | * or if code has set busted */ |
| 287 | /* >>chng 06 mar 18, add flag for time dependent simulation completed */ |
| 288 | if( iteration > iterations.itermx || lgAbort || dynamics.lgStatic_completed ) |
| 289 | break; |
| 290 | |
| 291 | /* increment iteration counter */ |
| 292 | ++iteration; |
| 293 | |
| 294 | /* reinitialize some variables to initial conditions at previous first zone |
| 295 | * routine in startenditer.c */ |
| 296 | IterRestart(); |
| 297 | |
| 298 | /* reset zone number to 0 - done here since this is only routine that sets nzone */ |
| 299 | nzone = 0; |
| 300 | fnzone = 0.; |
| 301 | |
| 302 | ZoneStart("init"); |
| 303 | |
| 304 | /* find new initial temperature, punt if initial conditions outside range of code, |
| 305 | * abort condition set by flag lgAbort */ |
| 306 | if( ConvInitSolution() ) |
| 307 | { |
| 308 | lgBadEnd = true; |
| 309 | break; |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | ClosePunchFiles( false ); |
| 314 | |
| 315 | /* this checks that various parts of the code worked properly */ |
| 316 | SanityCheck("final"); |
| 317 | |
| 318 | /* check whether any asserts were present and failed. |
| 319 | * return is true if ok, false if not. routine also checks |
| 320 | * number of warnings and returns false if not ok */ |
| 321 | lgOK = lgCheckAsserts(ioQQQ); |
| 322 | |
| 323 | if( lgOK && !warnings.lgWarngs && !lgBadEnd) |
| 324 | { |
| 325 | /* no failed asserts or warnings */ |
| 326 | return(false); |
| 327 | } |
| 328 | else |
| 329 | { |
| 330 | /* there were failed asserts or warnings */ |
| 331 | return(true); |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /*BadStart announce that things are so bad the calculation cannot even start */ |
| 336 | STATIC void BadStart(void) |
| 337 | { |
| 338 | char chLine[INPUT_LINE_LENGTH]; |
| 339 | |
| 340 | DEBUG_ENTRY( "BadStart()" ); |
| 341 | |
| 342 | /* initialize the line saver */ |
| 343 | wcnint(); |
| 344 | sprintf( warnings.chRgcln[0], " Calculation stopped because initial conditions out of bounds." ); |
| 345 | sprintf( chLine, " W-Calculation could not begin." ); |
| 346 | warnin(chLine); |
| 347 | |
| 348 | if( grid.lgGrid ) |
| 349 | { |
| 350 | /* possibly punch out some results from this zone when doing grid |
| 351 | * since grid punch files expect something at this grid point */ |
| 352 | PunchDo("MIDL"); |
| 353 | PunchDo("LAST" ); |
| 354 | } |
| 355 | return; |
| 356 | } |
Note: See TracBrowser
for help on using the browser.
