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-2017 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  fprintf( ioQQQ, "%22.7s * %-80s*\n", chNote, input.chCardSav[i] );
211  }
212  fprintf( ioQQQ, "%23c*%81c*\n", ' ', ' ' );
213  fprintf( ioQQQ, "%23c***********************************************************************************\n\n\n", ' ' );
214 
215  /* option to trace logical flow within this sub */
216  if( optimize.lgOptimFlow )
217  {
218  for( j=0; j < optimize.nvary; j++ )
219  {
220  i = optimize.nvfpnt[j];
221  fprintf( ioQQQ, " trace:%80.80s\n", input.chCardSav[i]);
222  fprintf( ioQQQ, "%80.80s\n", optimize.chVarFmt[j]);
223  fprintf( ioQQQ, " number of variables on line:%4ld\n",
224  optimize.nvarxt[j] );
225  fprintf( ioQQQ, " Values:" );
226  for( ii=1; ii <= optimize.nvarxt[j]; ii++ )
227  {
228  fprintf( ioQQQ, "%10.2e", optimize.vparm[ii-1][j] );
229  }
230  fprintf( ioQQQ, "\n" );
231  }
232  }
233 
234  if( strcmp(optimize.chOptRtn,"PHYM") == 0 )
235  {
236  fprintf( ioQQQ, " Up to %ld iterations will be performed,\n",
238  fprintf( ioQQQ, " and the final version of the input file will be written to the file %s\n",
239  chOptimFileName );
240 
241  fprintf( ioQQQ, " The Phymir method will be used" );
242  if( optimize.lgParallel )
243  {
244  if( cpu.i().lgMPI() )
245  fprintf( ioQQQ, " in MPI mode.\n" );
246  else
247  fprintf( ioQQQ, " in parallel mode.\n" );
248 
249  fprintf( ioQQQ, " The maximum no. of CPU's to be used is %ld.\n",
250  optimize.useCPU );
251  }
252  else
253  fprintf( ioQQQ, " in sequential mode.\n" );
254  }
255 
256  else if( strcmp(optimize.chOptRtn,"SUBP") == 0 )
257  {
258  fprintf( ioQQQ, " Up to %ld iterations will be performed,\n",
260  fprintf( ioQQQ, " and the final version of the input file will be written to the file %s\n",
261  chOptimFileName );
262 
263  fprintf( ioQQQ, " The Subplex method will be used.\n" );
264  }
265 
266  else if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
267  {
268  fprintf( ioQQQ, " Producing grid output.\n" );
269  }
270 
271  else
272  {
273  fprintf( ioQQQ, " I do not understand what method to use.\n" );
274  fprintf( ioQQQ, " Sorry.\n" );
276  }
277 
278  fprintf( ioQQQ, "\n %ld parameter(s) will be varied. The first lines, and the increments are:\n",
279  optimize.nvary );
280 
281  for( i=0; i < optimize.nvary; i++ )
282  {
283  optimize.varmax[i] = -FLT_MAX;
284  optimize.varmin[i] = FLT_MAX;
285  /* write formatted to output using the format held in chVarFmt(np) */
286 
287  /* now generate the actual command with parameter,
288  * there will be from 1 to 3 numbers on the line */
289  if( optimize.nvarxt[i] == 1 )
290  {
291  /* case with 1 parameter */
292  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i] );
293  }
294 
295  else if( optimize.nvarxt[i] == 2 )
296  {
297  /* case with 2 parameter */
298  sprintf( chLine, optimize.chVarFmt[i], optimize.vparm[0][i], optimize.vparm[1][i]);
299  }
300 
301  else if( optimize.nvarxt[i] == 3 )
302  {
303  /* case with 3 parameter */
304  sprintf( chLine, optimize.chVarFmt[i],
305  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i] );
306  }
307 
308  else if( optimize.nvarxt[i] == 4 )
309  {
310  /* case with 4 parameter */
311  sprintf( chLine, optimize.chVarFmt[i],
312  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
313  optimize.vparm[3][i] );
314  }
315 
316  else if( optimize.nvarxt[i] == 5 )
317  {
318  /* case with 5 parameter */
319  sprintf( chLine, optimize.chVarFmt[i],
320  optimize.vparm[0][i], optimize.vparm[1][i], optimize.vparm[2][i],
321  optimize.vparm[3][i], optimize.vparm[4][i]);
322  }
323 
324  else
325  {
326  fprintf(ioQQQ,"The number of variable options on this line makes no sense to me2\n");
328  }
329 
330  fprintf( ioQQQ, "\n %s\n", chLine );
331  if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
332  {
333  if( grid.paramValuesFromList[i].size() != 0U )
334  {
335  fprintf( ioQQQ, " %li parameters read from list.\n", grid.numParamValues[i] );
336  }
337  else
338  {
339  fprintf( ioQQQ, " %s increment is %.3g, the limits are %.3g to %.3g\n",
340  grid.lgLinearIncrements[i] ? "Linear" : "Log",
342  }
343  }
344  else
345  fprintf( ioQQQ, " Initial increment is %.3g, the limits are %.3g to %.3g\n",
346  optimize.vincr[i], optimize.varang[i][0], optimize.varang[i][1] );
347  }
348  }
349 
350  if( strcmp(optimize.chOptRtn,"XSPE") == 0 )
351  {
352  if( called.lgTalk )
353  {
354  if( cpu.i().lgMPI() )
355  fprintf( ioQQQ, "\n Running in MPI grid mode on %ld CPUs. ", cpu.i().nCPU() );
356  else if( grid.lgParallel )
357  fprintf( ioQQQ, "\n Running in parallel grid mode on %d CPUs. ", grid.useCPU );
358  else
359  fprintf( ioQQQ, "\n Running in single-CPU grid mode. " );
360  fprintf( ioQQQ, "I will now start to write the input files.\n\n" );
361  }
362 
363  for( j=0; j < optimize.nvary; j++ )
364  ptem[j] = grid.paramLimits[j][0];
365  for( j=optimize.nvary; j < LIMPAR; j++ )
366  {
367  ptem[j] = 0.f;
368  grid.paramIncrements[j] = 0.f;
369  grid.lgLinearIncrements[j] = false;
370  }
371 
372  gridXspec(ptem,optimize.nvary);
373 
374  if( called.lgTalk )
375  {
376  fprintf( ioQQQ, " **************************************************\n" );
377  fprintf( ioQQQ, " **************************************************\n" );
378  fprintf( ioQQQ, " **************************************************\n" );
379  fprintf( ioQQQ, "\n Writing input files has been completed.\n\n\n" );
380  }
381  }
382  else
383  {
384  called.lgTalk = false;
385  /* this flag is needed to turn print on to have effect */
386  called.lgTalkIsOK = false;
387 
389  }
390 
391  return lgAbort;
392 }
long int nSave
Definition: input.h:62
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:42
vector< realnum > ColDen_Obs
Definition: optimize.h:214
long int nvfpnt[LIMPAR]
Definition: optimize.h:198
t_cpu_i & i()
Definition: cpu.h:415
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:484
const long LIMPAR
Definition: optimize.h:61
vector< realnum > paramValuesFromList[LIMPAR]
Definition: grid.h:36
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:470
char chOptRtn[5]
Definition: optimize.h:268
long int LimFail
Definition: conv.h:230
bool grid_do(void)
Definition: grid_do.cpp:19
bool lgLinearIncrements[LIMPAR]
Definition: grid.h:37
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
long useCPU
Definition: optimize.h:265
bool lgMPI() const
Definition: cpu.h:388
unsigned int useCPU
Definition: grid.h:49
vector< realnum > temp_obs
Definition: optimize.h:231
realnum paramIncrements[LIMPAR]
Definition: grid.h:35
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
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:385
bool lgOptLum
Definition: optimize.h:259
bool lgOptimize_do(void)
Definition: optimize_do.cpp:12
char chCardSav[NKRD][INPUT_LINE_LENGTH]
Definition: input.h:48
GrainVar gv
Definition: grainvar.cpp:5
static t_cpu cpu
Definition: cpu.h:423
void LoadIsotopes()
Definition: isotopes.cpp:9
realnum paramLimits[LIMPAR][2]
Definition: grid.h:34
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:46
bool lgAbort
Definition: cddefines.cpp:10