root/branches/newmole/source/cloudy.cpp

Revision 2542, 10.5 kB (checked in by rjrw, 3 weeks ago)

Merged from trunk r2448:2541

  • Property svn:eol-style set to native
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 */
33STATIC void BadStart(void);
34
35/* returns 1 if disaster strikes, 0 if everything appears ok */
36bool 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 */
336STATIC 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.