cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
grid_do.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 /*grid_do called by cdDrive, this returns 0 if things went ok, 1 for disaster */
4 #include "cddefines.h"
5 #include "conv.h"
6 #include "input.h"
7 #include "called.h"
8 #include "version.h"
9 #include "init.h"
10 #include "prt.h"
11 #include "trace.h"
12 #include "grainvar.h"
13 #include "parse.h"
14 #include "grid.h"
15 #include "atmdat.h"
16 #include "flux.h"
17 
18 /* grid_do called by cdDrive, calls gridXspec or lgOptimize_do, returns false if ok, true for disaster */
19 bool grid_do()
20 {
21  char chLine[INPUT_LINE_LENGTH],
22  chNote[8];
23  long int i,
24  ii,
25  j;
26  realnum ptem[LIMPAR];
27 
28  DEBUG_ENTRY( "grid_do()" );
29 
30  /* main driver for optimization runs
31  * Drives cloudy to grid variables;*/
32 
33  /* code originally written by R.F. Carswell, IOA Cambridge */
34 
35  /* this will be number of times grid calls cloudy */
36  optimize.nOptimiz = 0;
37 
38  /* variables with optimizer */
39  for( i=0; i < LIMPAR; i++ )
40  {
41  optimize.OptIncrm[i] = 0.;
42  optimize.varang[i][0] = -FLT_MAX;
43  optimize.varang[i][1] = FLT_MAX;
44  /* this should be overwritten by format of vary line */
45  strcpy( optimize.chVarFmt[i], "error - no optimizer line image was set" );
46  }
47 
48  /* necessary to do this to keep all lines in */
49  prt.lgFaintOn = false;
50  conv.LimFail = 1000;
51 
52  /* this initializes variables at the start of each simulation
53  * in a grid, before the parser is called - this must set any values
54  * that may be changed by the command parser */
56 
57  /* Read the isotope data and allocate the required space */
58  LoadIsotopes();
59 
60  optimize.lgInitialParse = true;
61 
62  /* call READR the first time to scan off all variable options */
63  /* this is just an initial parsing to get the number of iterations and
64  * the number of varied parameters. The other Init* routines are not
65  * called after this because this is all done again later for each grid point */
66  ParseCommands();
67 
68  optimize.lgInitialParse = false;
69 
70  /* >>chng 00 aug 09, return memory allocated for grains, they are not used, PvH */
71  gv.clear();
72 
74 
75  /* option to change default increments; if zero then leave as is */
76  for( i=0; i < LIMPAR; i++ )
77  {
78  if( optimize.OptIncrm[i] != 0. )
79  {
81  }
82  }
83 
84  if( called.lgTalk )
85  {
86  /* check that at least 1 observed quantity was entered */
87  unsigned long nObsQuant = optimize.xLineInt_Obs.size() + optimize.ContNFnu.size() +
88  optimize.temp_obs.size() + optimize.ColDen_Obs.size();
89  if( optimize.lgOptLum )
90  nObsQuant++;
91  if( optimize.lgOptDiam )
92  nObsQuant++;
93  if( nObsQuant == 0 && !grid.lgGrid )
94  {
95  fprintf( ioQQQ, " The input stream has vary commands, but\n" );
96  fprintf( ioQQQ, " no observed quantities were entered. Whats up?\n" );
97  fprintf( ioQQQ, " Use the NO VARY command if you intended to disable optimization.\n" );
99  }
100 
101  /* check that the total number of parameters to vary is greater than 1 */
102  if( optimize.nvary < 1 )
103  {
104  fprintf( ioQQQ, " No parameters to vary were entered. Whats up?\n" );
106  }
107 
108  if( optimize.nvary > long(nObsQuant) && !grid.lgGrid )
109  {
110  fprintf( ioQQQ, " PROBLEM - More parameters are varied then there are observables.\n" );
111  fprintf( ioQQQ, " PROBLEM - This run may not converge as a result.\n" );
112  fprintf( ioQQQ, " PROBLEM - Please reduce the number of free parameters,"
113  " or add more observables.\n" );
114  }
115 
116  if( strcmp(optimize.chOptRtn,"XSPE") == 0 && optimize.nRangeSet != optimize.nvary )
117  {
118  fprintf( ioQQQ, " Every parameter with a VARY option must have a GRID specified,\n" );
119  fprintf( ioQQQ, " and the GRID must be specified after the VARY option.\n" );
120  fprintf( ioQQQ, " These requirements were not satisfied for %ld parameter(s).\n",
121  abs(optimize.nvary - optimize.nRangeSet) );
123  }
124 
125  /* lgTrOptm set with trace grid command */
126  if( trace.lgTrOptm )
127  {
128  for( i=0; i < optimize.nvary; i++ )
129  {
130  /*print the command format as debugging aid */
131  fprintf( ioQQQ, "%s\n", optimize.chVarFmt[i]);
132 
133  /* now generate the actual command with parameter,
134  * there will be from 1 to 3 numbers on the line */
135  if( optimize.nvarxt[i] == 1 )
136  {
137  /* case with 1 parameter */
138  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i] );
139  }
140 
141  else if( optimize.nvarxt[i] == 2 )
142  {
143  /* case with 2 parameter */
144  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i],
145  optimize.vparm[1][i]);
146  }
147 
148  else if( optimize.nvarxt[i] == 3 )
149  {
150  /* case with 3 parameter */
151  sprintf( chLine, optimize.chVarFmt[i],
152  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i] );
153  }
154 
155  else if( optimize.nvarxt[i] == 4 )
156  {
157  /* case with 4 parameter */
158  sprintf( chLine, optimize.chVarFmt[i],
159  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
160  optimize.vparm[3][i] );
161  }
162 
163  else if( optimize.nvarxt[i] == 5 )
164  {
165  /* case with 5 parameter */
166  sprintf( chLine, optimize.chVarFmt[i],
167  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
168  optimize.vparm[3][i], optimize.vparm[4][i]);
169  }
170 
171  else
172  {
173  fprintf(ioQQQ,"The number of variable options on this line makes no sense to me1\n");
175  }
176 
177  /* print the resulting command line*/
178  fprintf( ioQQQ, "%s\n", chLine );
179  }
180  }
181 
182  /* say who we are */
183  if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
184  fprintf( ioQQQ, "%58cGrid Driver\n", ' ' );
185  else
186  fprintf( ioQQQ, "%54cOptimization Driver\n", ' ' );
187  int indent = (int)((122 - strlen(t_version::Inst().chVersion))/2);
188  fprintf( ioQQQ, "%*cCloudy %s\n\n",indent,' ',t_version::Inst().chVersion);
189  fprintf( ioQQQ, "%23c**************************************%7.7s**************************************\n",
190  ' ', t_version::Inst().chDate );
191  fprintf( ioQQQ, "%23c*%81c*\n", ' ', ' ' );
192 
193  /* now echo initial input quantities with flag for vary */
194  /* first loop steps over all command lines entered */
195  for( i=0; i <= input.nSave; i++ )
196  {
197  /* put space to start line, overwrite if vary found */
198  strcpy( chNote, " " );
199  /* loop over all vary commands, see if this is one */
200  for( j=0; j < optimize.nvary; j++ )
201  {
202  /* input.nSave is on C array counting, rest are on fortran */
203  if( i == optimize.nvfpnt[j] )
204  {
205  /* this is a vary command, put keyword at start */
206  strcpy( chNote, "VARY>>>" );
207  }
208  }
209 
210  // exclude lines from init files
211  if( input.InclLevel[i] == 0 )
212  fprintf( ioQQQ, "%22.7s * %-80s*\n", chNote, input.chCardSav[i] );
213  }
214  fprintf( ioQQQ, "%23c*%81c*\n", ' ', ' ' );
215  fprintf( ioQQQ, "%23c***********************************************************************************\n\n\n", ' ' );
216 
217  /* option to trace logical flow within this sub */
218  if( optimize.lgOptimFlow )
219  {
220  for( j=0; j < optimize.nvary; j++ )
221  {
222  i = optimize.nvfpnt[j];
223  fprintf( ioQQQ, " trace:%80.80s\n", input.chCardSav[i]);
224  fprintf( ioQQQ, "%80.80s\n", optimize.chVarFmt[j]);
225  fprintf( ioQQQ, " number of variables on line:%4ld\n",
226  optimize.nvarxt[j] );
227  fprintf( ioQQQ, " Values:" );
228  for( ii=1; ii <= optimize.nvarxt[j]; ii++ )
229  {
230  fprintf( ioQQQ, "%10.2e", optimize.vparm[ii-1][j] );
231  }
232  fprintf( ioQQQ, "\n" );
233  }
234  }
235 
236  if( strcmp(optimize.chOptRtn,"PHYM") == 0 )
237  {
238  fprintf( ioQQQ, " Up to %ld iterations will be performed,\n",
240  fprintf( ioQQQ, " and the final version of the input file will be written to the file %s\n",
241  chOptimFileName );
242 
243  fprintf( ioQQQ, " The Phymir method will be used" );
244  if( optimize.lgParallel )
245  {
246  if( cpu.i().lgMPI() )
247  fprintf( ioQQQ, " in MPI mode.\n" );
248  else
249  fprintf( ioQQQ, " in parallel mode.\n" );
250 
251  fprintf( ioQQQ, " The maximum no. of CPU's to be used is %ld.\n",
252  optimize.useCPU );
253  }
254  else
255  fprintf( ioQQQ, " in sequential mode.\n" );
256  }
257 
258  else if( strcmp(optimize.chOptRtn,"SUBP") == 0 )
259  {
260  fprintf( ioQQQ, " Up to %ld iterations will be performed,\n",
262  fprintf( ioQQQ, " and the final version of the input file will be written to the file %s\n",
263  chOptimFileName );
264 
265  fprintf( ioQQQ, " The Subplex method will be used.\n" );
266  }
267 
268  else if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
269  {
270  fprintf( ioQQQ, " Producing grid output.\n" );
271  }
272 
273  else
274  {
275  fprintf( ioQQQ, " I do not understand what method to use.\n" );
276  fprintf( ioQQQ, " Sorry.\n" );
278  }
279 
280  fprintf( ioQQQ, "\n %ld parameter(s) will be varied. The first lines, and the increments are:\n",
281  optimize.nvary );
282 
283  for( i=0; i < optimize.nvary; i++ )
284  {
285  optimize.varmax[i] = -FLT_MAX;
286  optimize.varmin[i] = FLT_MAX;
287  /* write formatted to output using the format held in chVarFmt(np) */
288 
289  /* now generate the actual command with parameter,
290  * there will be from 1 to 3 numbers on the line */
291  if( optimize.nvarxt[i] == 1 )
292  {
293  /* case with 1 parameter */
294  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i] );
295  }
296 
297  else if( optimize.nvarxt[i] == 2 )
298  {
299  /* case with 2 parameter */
300  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i], optimize.vparm[1][i]);
301  }
302 
303  else if( optimize.nvarxt[i] == 3 )
304  {
305  /* case with 3 parameter */
306  sprintf( chLine, optimize.chVarFmt[i],
307  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i] );
308  }
309 
310  else if( optimize.nvarxt[i] == 4 )
311  {
312  /* case with 4 parameter */
313  sprintf( chLine, optimize.chVarFmt[i],
314  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
315  optimize.vparm[3][i] );
316  }
317 
318  else if( optimize.nvarxt[i] == 5 )
319  {
320  /* case with 5 parameter */
321  sprintf( chLine, optimize.chVarFmt[i],
322  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
323  optimize.vparm[3][i], optimize.vparm[4][i]);
324  }
325 
326  else
327  {
328  fprintf(ioQQQ,"The number of variable options on this line makes no sense to me2\n");
330  }
331 
332  fprintf( ioQQQ, "\n %s\n", chLine );
333  if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
334  {
335  if( grid.paramValuesFromList[i].size() != 0U )
336  {
337  fprintf( ioQQQ, " %li parameters read from list.\n", grid.numParamValues[i] );
338  }
339  else
340  {
341  fprintf( ioQQQ, " %s increment is %.3g, the limits are %.3g to %.3g\n",
342  grid.lgLinearIncrements[i] ? "Linear" : "Log",
344  }
345  }
346  else
347  fprintf( ioQQQ, " Initial increment is %.3g, the limits are %.3g to %.3g\n",
348  optimize.vincr[i], optimize.varang[i][0], optimize.varang[i][1] );
349  }
350  }
351 
352  if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
353  {
354  if( called.lgTalk )
355  {
356  if( cpu.i().lgMPI() )
357  fprintf( ioQQQ, "\n Running in MPI grid mode on %ld CPUs. ", cpu.i().nCPU() );
358  else if( grid.lgParallel )
359  fprintf( ioQQQ, "\n Running in parallel grid mode on %d CPUs. ", grid.useCPU );
360  else
361  fprintf( ioQQQ, "\n Running in single-CPU grid mode. " );
362  fprintf( ioQQQ, "I will now start to write the input files.\n\n" );
363  }
364 
365  for( j=0; j < optimize.nvary; j++ )
366  ptem[j] = grid.paramLimits[j][0];
367  for( j=optimize.nvary; j < LIMPAR; j++ )
368  {
369  ptem[j] = 0.f;
370  grid.paramIncrements[j] = 0.f;
371  grid.lgLinearIncrements[j] = false;
372  }
373 
374  gridXspec(ptem,optimize.nvary);
375 
376  if( called.lgTalk )
377  {
378  fprintf( ioQQQ, " **************************************************\n" );
379  fprintf( ioQQQ, " **************************************************\n" );
380  fprintf( ioQQQ, " **************************************************\n" );
381  fprintf( ioQQQ, "\n Writing input files has been completed.\n\n\n" );
382  }
383  }
384  else
385  {
386  called.lgTalk = false;
387  /* this flag is needed to turn print on to have effect */
388  called.lgTalkIsOK = false;
389 
391  }
392 
393  return lgAbort;
394 }
long int nSave
Definition: input.h:102
realnum varmax[LIMPAR]
Definition: optimize.h:187
long int nRangeSet
Definition: optimize.h:204
t_input input
Definition: input.cpp:12
bool lgGrid
Definition: grid.h:41
vector< realnum > ColDen_Obs
Definition: optimize.h:214
long int nvfpnt[LIMPAR]
Definition: optimize.h:198
t_cpu_i & i()
Definition: cpu.h:419
vector< Flux > ContNFnu
Definition: optimize.h:244
t_conv conv
Definition: conv.cpp:5
long int nOptimiz
Definition: optimize.h:250
realnum varang[LIMPAR][2]
Definition: optimize.h:201
char chVarFmt[LIMPAR][FILENAME_PATH_LENGTH_2]
Definition: optimize.h:267
FILE * ioQQQ
Definition: cddefines.cpp:7
realnum vparm[LIMEXT][LIMPAR]
Definition: optimize.h:192
bool lgTalk
Definition: called.h:12
bool lgInitialParse
Definition: optimize.h:182
static t_version & Inst()
Definition: cddefines.h:209
void ParseCommands(void)
long int nIterOptim
Definition: optimize.h:209
t_trace trace
Definition: trace.cpp:5
long numParamValues[LIMPAR]
Definition: grid.h:60
bool lgParallel
Definition: optimize.h:263
long int nparm
Definition: optimize.h:204
bool lgTrOptm
Definition: trace.h:64
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
const int INPUT_LINE_LENGTH
Definition: cddefines.h:301
bool lgFaintOn
Definition: prt.h:245
vector< realnum > xLineInt_Obs
Definition: optimize.h:225
#define cdEXIT(FAIL)
Definition: cddefines.h:482
const long LIMPAR
Definition: optimize.h:61
vector< realnum > paramValuesFromList[LIMPAR]
Definition: grid.h:35
t_optimize optimize
Definition: optimize.cpp:6
t_grid grid
Definition: grid.cpp:5
realnum vincr[LIMPAR]
Definition: optimize.h:195
t_prt prt
Definition: prt.cpp:14
void clear()
Definition: grainvar.h:468
char chOptRtn[5]
Definition: optimize.h:268
long int LimFail
Definition: conv.h:228
bool grid_do(void)
Definition: grid_do.cpp:19
bool lgLinearIncrements[LIMPAR]
Definition: grid.h:36
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
long useCPU
Definition: optimize.h:265
bool lgMPI() const
Definition: cpu.h:391
unsigned int useCPU
Definition: grid.h:50
vector< realnum > temp_obs
Definition: optimize.h:231
realnum paramIncrements[LIMPAR]
Definition: grid.h:34
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
bool lgOptDiam
Definition: optimize.h:236
realnum varmin[LIMPAR]
Definition: optimize.h:188
void gridXspec(realnum *, long)
void InitDefaultsPreparse(void)
long nCPU() const
Definition: cpu.h:388
bool lgOptLum
Definition: optimize.h:259
bool lgOptimize_do(void)
Definition: optimize_do.cpp:12
char chCardSav[NKRD][INPUT_LINE_LENGTH]
Definition: input.h:74
GrainVar gv
Definition: grainvar.cpp:5
static t_cpu cpu
Definition: cpu.h:427
void LoadIsotopes()
Definition: isotopes.cpp:9
realnum paramLimits[LIMPAR][2]
Definition: grid.h:33
realnum OptIncrm[LIMPAR]
Definition: optimize.h:201
bool lgOptimFlow
Definition: optimize.h:252
char chOptimFileName[INPUT_LINE_LENGTH]
Definition: optimize.cpp:7
long int nvarxt[LIMPAR]
Definition: optimize.h:198
t_called called
Definition: called.cpp:4
long int nvary
Definition: optimize.h:204
bool lgTalkIsOK
Definition: called.h:23
bool lgParallel
Definition: grid.h:47
bool lgAbort
Definition: cddefines.cpp:10
int InclLevel[NKRD]
Definition: input.h:91