cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cloudy.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2022 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 "save.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 "monitor_results.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 "called.h"
31 #include "dense.h"
32 
33 /*BadStart announce that things are so bad the calculation cannot even start */
34 STATIC void BadStart();
35 
36 /* returns 1 if disaster strikes, 0 if everything appears ok */
37 bool cloudy()
38 {
39  DEBUG_ENTRY( "cloudy()" );
40 
41  bool lgOK;
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  /* this initializes variables at the start of each simulation
77  * in a grid, before the parser is called - this must set any values
78  * that may be changed by the command parser */
80 
81  /* Read the isotope data and allocate the required space */
82  LoadIsotopes();
83 
84  /* scan in and parse input data */
85  ParseCommands();
86 
87  /* option to parse main input script again after grid finished -> no execution needed */
88  if( grid.lgParseOnly )
89  return false;
90 
91  /* fix abundances of elements, in abundances.cpp */
92  AbundancesSet();
93 
95 
96  /* one time creation of some variables */
98 
99  /* initialize vars that can only be done after parsing the commands
100  * sets up CO network since this depends on which elements are on
101  * and whether chemistry is enabled */
103 
104  /* ContCreateMesh calls fill to set up continuum energy mesh if first call,
105  * otherwise reset to original mesh.
106  * This is AFTER ParseCommands so that
107  * path and mesh size can be set with commands before mesh is set */
108  ContCreateMesh();
109 
110  /* create several data sets by allocating memory and reading in data files,
111  * but only if this is first call */
112  atmdat_readin();
113 
114  /* fix pointers to ionization edges and frequency array
115  * calls iso_create
116  * this routine only returns if this is a later call of code */
118 
120 
121  /* Badnell_rec_init This code is written by Terry Yun, 2005 *
122  * It reads dielectronic recombination rate coefficient fits into 3D arrays */
124 
126 
127  /* set continuum normalization, continuum itself, and ionization stage limits */
129 
131 
132  SetPrintLineCol();
133 
134  /* print header */
135  PrtHeader();
136 
137  /* this is an option to stop after initial setup */
138  if( noexec.lgNoExec )
139  return false;
140 
141  /* guess some outward optical depths, set inward optical depths,
142  * also calls RT_line_all so escape probabilities ok before printout of trace */
143  RT_tau_init();
144 
145  /* generate initial set of opacities, but only if this is the first call
146  * in this core load
147  * grains only exist AFTER this routine exits */
149 
151 
152  /* this checks that various parts of the code still work properly */
153  SanityCheck("begin");
154 
155  /* option to recover state from previous calculation */
156  if( state.lgGet_state )
157  state_get_put( "get" );
158 
160 
161  /* find the initial temperature, punt if initial conditions outside range of code,
162  * abort condition set by flag lgAbort */
163  if( ConvInitSolution() )
164  {
165  // create line stacks for possible printout before bailing out
166  LineStackCreate();
167  BadStart();
168  return true;
169  }
170  // create line stacks ...
171  LineStackCreate();
172 
173  /* set thickness of first zone */
174  radius_first();
175 
176  /* find thickness of next zone */
177  if( radius_next() )
178  {
179  BadStart();
180  return true;
181  }
182 
183  /* set up some zone variables, correct continuum for sphericity,
184  * after return, radius is equal to the inner radius, not outer radius
185  * of this zone */
186  ZoneStart("init");
187 
188  /* print all abundances, gas phase and grains, in abundances.c */
189  /* >>chng 06 mar 05, move AbundancesPrt() after ZoneStart("init") so that
190  * GrnVryDpth() gives correct values for the inner face of the cloud, PvH */
191  AbundancesPrt();
192 
193  /* this is an option to stop after printing header only */
194  if( prt.lgOnlyHead )
195  return false;
196 
197  plot("FIRST");
198 
199  /* outer loop is over number of iterations
200  * >>chng 05 mar 12, chng from test on true to not aborting */
201  while( !lgAbort )
202  {
203  IterStart();
204  nzone = 0;
205  fnzone = 0.;
206 
207  /* loop over zones across cloud for this iteration,
208  * iter_end_check checks whether model is complete and this iteration is done
209  * returns true is current iteration is complete
210  * calls PrtZone to print zone results */
211  while( !iter_end_check() )
212  {
213  /* the zone number, 0 during search phase, first zone is 1 */
214  ++nzone;
215  /* this is the zone number plus the number of calls to bottom solvers
216  * from top pressure solver, divided by 100 */
217  fnzone = (double)nzone;
218 
219  /* use changes in opacity, temperature, ionization, to fix new dr for next zone */
220  /* >>chng 03 oct 29, move radius_next up to here from below, so that
221  * precise correct zone thickness will be used in current zone, so that
222  * column density and thickness will be exact
223  * abort condition is possible */
224  if( radius_next() )
225  break;
226 
227  /* following sets zone thickness, drad, to drnext */
228  /* set variable dealing with new radius, in zones.c */
229  ZoneStart("incr");
230 
231  /* converge the pressure-temperature-ionization solution for this zone
232  * NB ignoring return value - should be ok (return 1 for abort)
233  * we can't break here in case of abort since there is still housekeeping
234  * that must be done in following routines */
236 
237  /* generate diffuse emission from this zone, add to outward & reflected beams */
238  RT_diffuse();
239 
240  /* do work associated with incrementing this radius,
241  * total attenuation and dilution of radiation fields takes place here,
242  * reflected continuum incremented here
243  * various mean and extremes of solution are also remembered here */
245 
246  /* attenuation of diffuse and beamed continua */
247  RT_continuum();
248 
249  /* increment optical depths
250  * final evaluation of line rates and cooling */
251  RT_tau_inc();
252 
253  /* fill in emission line array, adds outward lines */
254  /* >>chng 99 dec 29, moved to here from below RT_tau_inc,
255  * lines adds lines to outward beam,
256  * and these are attenuated in radius_increment */
257  lines();
258 
259  /* possibly save out some results from this zone */
260  SaveDo("MIDL");
261 
262  /* do some things to finish out this zone */
263  ZoneEnd();
264 
265  // default false due to slow time - set true with set check energy every zone
266  // to allow per zone check of energy conservation, relatively slow
267  // when chianti is fully enabled
269  {
270  /* Ensure that energy has been conserved. Complain and punt if not */
271  if( !lgConserveEnergy() )
272  {
273  fprintf( ioQQQ, " PROBLEM DISASTER Energy was not conserved at zone %li\n", nzone );
274  ShowMe();
275  lgAbort = true;
276  }
277  }
278  }
279  /* end loop over zones */
280 
281  /* close out this iteration, in iter_startend.c */
282  IterEnd();
283 
284  /* print out some comments, generate warning and cautions*/
285  PrtComment();
286 
287  /* save stuff only needed on completion of this iteration */
288  SaveDo("LAST" );
289 
290  /* second call to plot routine, to complete plots for this iteration */
291  plot("SECND");
292 
293  /* print out the results */
294  PrtFinal();
295 
296  /*ConvIterCheck check whether model has converged or more iterations
297  * are needed - implements the iter to convergence command
298  * acts by setting iterations.itermx to iteration if converged*/
299  ConvIterCheck();
300 
301  /* option to save state */
302  if( state.lgPut_state )
303  state_get_put( "put" );
304 
305  /* >>chng 06 mar 03 move block to here, had been after PrtFinal,
306  * so that save state will save reset optical depths */
307  /* this is the normal exit, occurs if we reached limit to number of iterations,
308  * or if code has set busted */
309  /* >>chng 06 mar 18, add flag for time dependent simulation completed */
311  break;
312 
313  /* reset limiting and initial optical depth variables */
314  RT_tau_reset();
315 
316  /* increment iteration counter */
317  ++iteration;
318 
319  /* reinitialize some variables to initial conditions at previous first zone
320  * routine in startenditer.c */
321  IterRestart();
322 
323  /* reset zone number to 0 - done here since this is only routine that sets nzone */
324  nzone = 0;
325  fnzone = 0.;
326 
327  ZoneStart("init");
328 
329  /* find new initial temperature, punt if initial conditions outside range of code,
330  * if ConvInitSolution() fails, lgAbort will always be true, so we check that */
331  if( ConvInitSolution() )
332  break;
333  }
334 
335  CloseSaveFiles( false );
336 
337  /* this checks that various parts of the code worked properly */
338  SanityCheck("final");
339 
340  if( called.lgTalk )
341  {
342  fprintf(ioQQQ,"---------------Convergence statistics---------------\n");
343  fprintf(ioQQQ,"%10.3g mean iterations/state convergence\n",((double)conv.getCounter("CONV_BASE_LOOPS"))/
344  (MAX2((double)conv.getCounter("CONV_BASE_CALLS"),1.0)));
345  fprintf(ioQQQ,"%10.3g mean cx acceleration loops/iteration\n",((double)conv.getCounter("CONV_BASE_ACCELS"))/
346  (MAX2((double)conv.getCounter("CONV_BASE_LOOPS"),1.0)));
347  fprintf(ioQQQ,"%10.3g mean iso convergence loops/ion solve\n",((double)conv.getCounter("ISO_LOOPS"))/
348  (MAX2((double)conv.getCounter("ION_SOLVES"),1.0)));
349  fprintf(ioQQQ,"%10.3g mean steps/chemistry solve\n",((double)conv.getCounter("MOLE_SOLVE_STEPS"))/
350  (MAX2((double)conv.getCounter("MOLE_SOLVE"),1.0)));
351  fprintf(ioQQQ,"%10.3g mean step length searches/chemistry step\n",((double)conv.getCounter("NEWTON_LOOP"))/
352  (MAX2((double)conv.getCounter("NEWTON"),1.0)));
353  fprintf(ioQQQ,"----------------------------------------------------\n\n");
354  }
355 
356  /* check whether any asserts were present and failed.
357  * return is true if ok, false if not. routine also checks
358  * number of warnings and returns false if not ok */
359  lgOK = lgCheckMonitors(ioQQQ);
360 
361  if( lgOK && !warnings.lgWarngs && !lgAbort )
362  {
363  /* no failed asserts or warnings */
364  return false;
365  }
366  else
367  {
368  /* there were failed asserts or warnings */
369  return true;
370  }
371 }
372 
373 /*BadStart announce that things are so bad the calculation cannot even start */
375 {
376  char chLine[INPUT_LINE_LENGTH];
377 
378  DEBUG_ENTRY( "BadStart()" );
379 
380  /* initialize the line saver */
381  warnings.zero();
382  sprintf( warnings.chRgcln[0], " Calculation stopped because initial conditions out of bounds." );
383  sprintf( chLine, " W-Calculation could not begin." );
384  warnin(chLine);
385 
386  if( grid.lgGrid )
387  {
388  /* possibly save out some results from this zone when doing grid
389  * since grid save files expect something at this grid point */
390  SaveDo("MIDL");
391  SaveDo("LAST" );
392  }
393  return;
394 }
void InitSimPostparse(void)
void plot(const char *chCall)
Definition: plot.cpp:39
void PrtFinal(void)
Definition: prt_final.cpp:555
bool lgPut_state
Definition: state.h:29
void radius_first(void)
bool lgParseOnly
Definition: grid.h:44
bool lgGrid
Definition: grid.h:41
bool cloudy()
Definition: cloudy.cpp:37
void ZoneEnd(void)
void OpacityCreateAll(void)
bool lgCheckEnergyEveryZone
Definition: continuum.h:102
void AbundancesSet(void)
Definition: abundances.cpp:145
STATIC void BadStart()
Definition: cloudy.cpp:374
t_warnings warnings
Definition: warnings.cpp:11
int iter_end_check(void)
t_conv conv
Definition: conv.cpp:5
void CloseSaveFiles(bool lgFinal)
t_noexec noexec
Definition: noexec.cpp:4
FILE * ioQQQ
Definition: cddefines.cpp:7
void RT_tau_inc(void)
Definition: rt_tau_inc.cpp:40
void SanityCheck(const char *chJob)
long int nzone
Definition: cddefines.cpp:14
bool lgTalk
Definition: called.h:12
char chRgcln[2][INPUT_LINE_LENGTH]
Definition: warnings.h:34
t_dynamics dynamics
Definition: dynamics.cpp:42
bool lgNoExec
Definition: noexec.h:14
void ZoneStart(const char *chMode)
bool lgStatic_completed
Definition: dynamics.h:111
void IterEnd(void)
void SaveDo(const char *chTime)
Definition: save_do.cpp:460
void warnin(const char *chLine)
Definition: warnings.h:74
void lines(void)
Definition: prt_lines.cpp:35
void RT_diffuse(void)
Definition: rt_diffuse.cpp:35
void ParseCommands(void)
long int iteration
Definition: cddefines.cpp:16
void RT_tau_reset(void)
void Badnell_rec_init(void)
void ContCreatePointers(void)
void IterRestart(void)
void ContCreateMesh()
void AbundancesPrt(void)
Definition: abundances.cpp:31
void PrtComment(void)
Definition: prt_comment.cpp:66
#define STATIC
Definition: cddefines.h:118
bool lgConserveEnergy()
Definition: energy.cpp:311
t_continuum continuum
Definition: continuum.cpp:6
void RT_continuum(void)
long getCounter(const long type) const
Definition: conv.h:325
void LineStackCreate(void)
bool lgOnlyHead
Definition: prt.h:224
const int INPUT_LINE_LENGTH
Definition: cddefines.h:301
void resolveLevels()
Definition: prt.cpp:224
void PrtHeader(void)
Definition: prt_header.cpp:17
t_iterations iterations
Definition: iterations.cpp:6
t_state state
Definition: state.cpp:18
t_grid grid
Definition: grid.cpp:5
t_prt prt
Definition: prt.cpp:14
void radius_increment(void)
long int itermx
Definition: iterations.h:37
#define ASSERT(exp)
Definition: cddefines.h:613
void ConvIterCheck(void)
t_prt_matrix matrix
Definition: prt.h:238
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
bool lgGet_state
Definition: state.h:29
int radius_next(void)
void RT_tau_init(void)
Definition: rt_tau_init.cpp:28
int ConvPresTempEdenIoniz(void)
#define MAX2(a, b)
Definition: cddefines.h:824
void state_get_put(const char chJob[])
Definition: state.cpp:83
bool lgCheckMonitors(FILE *ioMONITOR)
void atmdat_readin(void)
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
void zero(void)
Definition: warnings.cpp:13
void InitDefaultsPreparse(void)
bool lgElemsConserved(void)
Definition: dense.cpp:119
void LoadIsotopes()
Definition: isotopes.cpp:9
double fnzone
Definition: cddefines.cpp:15
void ShowMe(void)
Definition: service.cpp:205
void InitCoreloadPostparse(void)
bool ConvInitSolution()
bool lgWarngs
Definition: warnings.h:44
t_called called
Definition: called.cpp:4
void IterStart(void)
bool lgAbort
Definition: cddefines.cpp:10
void SetPrintLineCol()
Definition: prt.cpp:28
void ContSetIntensity()