cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
parse_compile.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 /*ParseCompile compile Werner or kurucz model atmospheres into cloudy format, originally by K Volk,
4  * also compile opacity and grains */
5 #include "cddefines.h"
6 #include "continuum.h"
7 #include "dense.h"
8 #include "iso.h"
9 #include "grains.h"
10 #include "rfield.h"
11 #include "stars.h"
12 #include "parser.h"
13 
15 {
16  long int ncell;
17  char
20  chSTB99[FILENAME_PATH_LENGTH_2];
21 
22  DEBUG_ENTRY( "ParseCompile()" );
23 
24  /* >>chng 01 aug 24, remove compile opacity command */
25  /* this option to compile opacities into file for later use */
26  if( p.nMatch("OPAC") )
27  {
28  fprintf( ioQQQ, "The COMPILE OPACITIES command is currently not supported\n" );
30 
31 # if 0
32  /* calls fill to set up continuum energy mesh if first call,
33  * otherwise reset to original mesh */
35 
36  /* read in some external data files, but only if this is first call */
37  atmdat_readin();
38 
39  /* first generate the frequency array */
41 
43 
44  /* say that we want to compile the opacities */
45  opac.lgCompileOpac = true;
46 
47  /* generate initial set of opacities but only if this is the first call
48  * in this coreload */
50 
51  fprintf(ioQQQ,
52  "Success!! Created file opacity.opc\nMake sure this is on the path.\n" );
54 # endif
55  }
56 
57  /* >>chng 00 apr 27, modified for arbitrary file names by PvH
58  *
59  * this option to compile grains into file for later use
60  *
61  * the command supports the following syntax:
62  *
63  * COMPILE GRAINS
64  * compile a standard set of opacity files
65  *
66  * COMPILE GRAINS <refr-ind-file> <size-distr-file> [ <no-bins> ]
67  * compile a single opacity file
68  *
69  * Remarks:
70  * - the parameters of this command can be supplied in arbitrary order.
71  * - the file names can either be supplied as names between quotes or
72  * as keywords; it is allowed to use a filename between quotes for
73  * one file and a keyword for the other file; both names have to be
74  * present in either form, there are no defaults.
75  * - filenames are recognized by their extension: .rfi or .mix for
76  * refractive index files, and .szd for size distribution files,
77  * this allows their sequence to be arbitrary.
78  * - the number-of-bins parameter is optional, it is defaulted to 10.
79  *
80  * NB NB NB NB NB NB NB NB NB NB NB NB NB
81  *
82  * - in order not to upset FFmtRead for reading the number-of-bins
83  * parameter, all file names and keywords should be read first and
84  * erased after being read ! to assure that all digits are erased,
85  * the keywords 0M010, 0M100 and 1M000 are matched on all 5 characters.
86  * if keywords are known not to contain digits or minus signs, erasing
87  * is not necessary of course....
88  */
89  if( p.nMatch("GRAI") )
90  {
91 
92  /* calls fill to set up continuum energy mesh if first call,
93  * otherwise reset to original mesh */
95  /* >>chng 06 dec 13, this had been followed by calls to atmdat_readin &
96  * ConCreatePointer which had problems because the code was not
97  * fully initialized yet. Compile stars and compile grains would
98  * fail on mallocing an array of length zero */
99 
100  chRFI[0] = '\0';
101  chSZD[0] = '\0';
102 
103  /* get first filename (either .rfi or .szd file) */
104  if( p.nMatch( "\"" ) )
105  {
106  string chRead;
107  if (p.GetQuote(chRead ))
108  p.StringError();
109  if( strstr_s(chRead.c_str(),".rfi") != NULL || strstr_s(chRead.c_str(),".mix") != NULL )
110  {
111  strcpy(chRFI,chRead.c_str());
112  }
113  else if( strstr_s(chRead.c_str(),".szd") != NULL )
114  {
115  strcpy(chSZD,chRead.c_str());
116  }
117  else
118  {
119  fprintf( ioQQQ, " filename %s has unknown extension, sorry\n" , chRead.c_str() );
121  }
122  }
123 
124  /* get second filename (either .rfi or .szd file) */
125  if( p.nMatch( "\"" ) )
126  {
127  string chRead;
128  if (p.GetQuote(chRead ))
129  p.StringError();
130  if( strstr_s(chRead.c_str(),".rfi") != NULL || strstr_s(chRead.c_str(),".mix") != NULL )
131  {
132  strcpy(chRFI,chRead.c_str());
133  }
134  else if( strstr_s(chRead.c_str(),".szd") != NULL )
135  {
136  strcpy(chSZD,chRead.c_str());
137  }
138  else
139  {
140  fprintf( ioQQQ, " filename %s has unknown extension, sorry\n" , chRead.c_str() );
142  }
143  }
144 
145  /* if no .rfi file was supplied between quotes, check for keywords */
146  if( chRFI[0] == '\0' )
147  {
148  /* check on index of refraction names */
149  if( p.nMatchErase("AC1-") )
150  {
151  /* amorphous carbon from Rouleau & Martin 1991 */
152  strcpy(chRFI , "ac1-amcarb.rfi" );
153  /* erase this keyword, it upsets FFmtRead */
154  }
155  else if( p.nMatchErase("BE1-"))
156  {
157  /* amorphous carbon from Rouleau & Martin 1991 */
158  strcpy(chRFI , "be1-amcarb.rfi" );
159  /* erase this keyword, it upsets FFmtRead */
160  }
161  else if( p.nMatch( "GRAP") )
162  {
163  /* graphite */
164  strcpy(chRFI , "graphite.rfi" );
165  }
166  else if( p.nMatch( "SILI" ) )
167  {
168  /* astronomical silicate */
169  strcpy(chRFI , "silicate.rfi" );
170  }
171  else if( p.nMatch( " SIC" ) )
172  {
173  /* alpha-SiC */
174  strcpy(chRFI , "sic.rfi" );
175  }
176  else if( p.nMatch( " PAH" ) )
177  {
178  /* original PAHs */
179  strcpy(chRFI , "pah1.rfi" );
180  }
181  else if( p.nMatch( "GREY" ) || p.nMatch( "GRAY" ))
182  {
183  strcpy(chRFI , "grey.rfi" );
184  }
185  }
186 
187  /* if no .szd file was supplied between quotes, check for keywords */
188  if( chSZD[0] == '\0' )
189  {
190  /* check on size distribution */
191  if( p.nMatchErase("0M010") )
192  {
193  strcpy(chSZD , "0m010.szd" );
194  }
195  else if( p.nMatchErase("0M100") )
196  {
197  strcpy(chSZD , "0m100.szd" );
198  }
199  else if( p.nMatchErase("1M000") )
200  {
201  strcpy(chSZD , "1m000.szd" );
202  }
203  else if( p.nMatch( "ORIO" ) )
204  {
205  strcpy(chSZD , "orion.szd" );
206  }
207  else if( p.nMatch( " ISM" ) )
208  {
209  strcpy(chSZD , "ism.szd" );
210  }
211  else if( p.nMatchErase("AB08") )
212  {
213  /* Abel et al., 2008 size distribution */
214  strcpy(chSZD , "ab08.szd" );
215  }
216  else if( p.nMatchErase("C15") )
217  {
218  /* small PAH, 15 C atoms */
219  strcpy(chSZD , "c15.szd" );
220  }
221  else if( p.nMatchErase("C120") )
222  {
223  /* large PAH, 120 C atoms */
224  strcpy(chSZD , "c120.szd" );
225  }
226  }
227 
228  /* the user has to supply either both the .rfi and .szd files, or neither
229  * (to compile the complete standard set of files); anything else is illegal */
230  if( chRFI[0] == '\0' && chSZD[0] != '\0' )
231  {
232  fprintf(ioQQQ,"Sorry, but I did not recognize a refractive index file.\n");
233  fprintf(ioQQQ,"Supply a file name between quotes or one of the following ");
234  fprintf(ioQQQ,"keywords: ac1-amcarb, be1-amcarb, graphite, silicate, grey, pah\n");
236  }
237 
238  if( chSZD[0] == '\0' && chRFI[0] != '\0' )
239  {
240  fprintf(ioQQQ,"Sorry, but I did not recognize a size distribution file.\n");
241  fprintf(ioQQQ,"Supply a file name between quotes or one of the following ");
242  fprintf(ioQQQ,"keywords: 0m010, 0m100, 1m000, ism, orion, c15, c120, ab08\n");
244  }
245 
246  /* compile the complete standard set of files */
247  if( chRFI[0] == '\0' && chSZD[0] == '\0' )
248  {
249  /* ism graphite, single bin */
250  mie_write_opc( "graphite.rfi" , "ism.szd" , 1 );
251 
252  /* ism silicate, single bin */
253  mie_write_opc( "silicate.rfi" , "ism.szd" , 1 );
254 
255  /* ism graphite, 10 bins */
256  mie_write_opc( "graphite.rfi" , "ism.szd" , 10 );
257 
258  /* ism silicate, 10 bins */
259  mie_write_opc( "silicate.rfi" , "ism.szd" , 10 );
260 
261  /* orion graphite, single bin */
262  mie_write_opc( "graphite.rfi" , "orion.szd" , 1 );
263 
264  /* orion silicate, single bin */
265  mie_write_opc( "silicate.rfi" , "orion.szd" , 1 );
266 
267  /* orion graphite, 10 bins */
268  mie_write_opc( "graphite.rfi" , "orion.szd" , 10 );
269 
270  /* orion silicate, 10 bins */
271  mie_write_opc( "silicate.rfi" , "orion.szd" , 10 );
272 
273  /* 0.01 micron silicate */
274  mie_write_opc( "silicate.rfi" , "0m010.szd" , 1 );
275 
276  /* 0.1 micron silicate */
277  mie_write_opc( "silicate.rfi" , "0m100.szd" , 1 );
278 
279  /* 1 micron silicate */
280  mie_write_opc( "silicate.rfi" , "1m000.szd" , 1 );
281 
282  /* 0.01 micron graphite */
283  mie_write_opc( "graphite.rfi" , "0m010.szd" , 1 );
284 
285  /* 0.1 micron graphite */
286  mie_write_opc( "graphite.rfi" , "0m100.szd" , 1 );
287 
288  /* 1 micron graphite */
289  mie_write_opc( "graphite.rfi" , "1m000.szd" , 1 );
290 
291  /* grey single bin */
292  mie_write_opc( "grey.rfi" , "ism.szd" , 1 );
293 
294  /* grey resolved distribution */
295  mie_write_opc( "grey.rfi" , "ism.szd" , 10 );
296 
297  /* small pah */
298  mie_write_opc( "pah1.rfi" , "c15.szd" , 1 );
299 
300  /* large pah */
301  mie_write_opc( "pah1.rfi" , "c120.szd" , 1 );
302 
303  /* distributed pah */
304  mie_write_opc( "pah1.rfi" , "ab08.szd" , 10 );
305 
306  /* single pah */
307  mie_write_opc( "pah1.rfi" , "ab08.szd" , 1 );
308  }
309  /* this option is to compile a single type of grain */
310  else
311  {
312  ncell = (long)p.FFmtRead();
313  if( p.lgEOL() )
314  {
315  /* the default, 10 cells */
316  ncell = 10;
317  }
318  if( ncell <= 0 )
319  {
320  fprintf(ioQQQ,"Number of bins must be positive. Sorry.\n");
322  }
323  /* this actually does the work */
324  mie_write_opc( chRFI , chSZD , ncell );
325  }
326 
327  fprintf(ioQQQ,
328  "Success!! Created grain opacity file(s).\nMake sure this directory is on the path.\n" );
330  }
331 
332  /* compile recombination coefficients command */
333  else if( p.nMatch("RECO") && p.nMatch("COEF") )
334  {
335  long ipISO;
336  int nelem;
337 
338  if( p.nMatch("H-LI") )
339  ipISO = ipH_LIKE;
340  else if( p.nMatch("HE-L") )
341  ipISO = ipHE_LIKE;
342  else
343  {
344  fprintf(ioQQQ,"Sorry, but I did not recognize an iso sequence.\n");
345  fprintf(ioQQQ,"The available options are H-like and He-like.\nSorry.\n");
347  }
348 
349  /* compile he-like command - compiles table of recombination coeficients */
350  iso_ctrl.lgCompileRecomb[ipISO] = true;
351 
352  /* we will want to create the rec coefficient for a large number of levels, then stop.
353  * this sets the number of levels to a large number. macro is in helike.h */
354  for( nelem = ipISO; nelem < LIMELM; nelem++)
355  {
356  long maxN;
357  dense.lgElmtOn[nelem] = true;
358  iso_sp[ipISO][nelem].nCollapsed_max = 0;
359 
360  if( nelem == ipISO )
361  maxN = RREC_MAXN;
362  else
363  maxN = LIKE_RREC_MAXN( nelem );
364 
365  iso_sp[ipISO][nelem].n_HighestResolved_max = maxN;
366 
367  iso_update_num_levels( ipISO, nelem );
368  }
369  }
370 
371  else if( p.nMatch("STAR") )
372  {
373  bool lgProblems = false;
374 
375  /* check that frequency mesh is set up */
377 
378  if( p.nMatch( "\"" ))
379  {
380  /* this is branch for for user-supplied *.ascii file */
381 
382  /* this will both scan in whatever label is inside the quotes in OrgCard,
383  * but also remove the contents there and in chCard,
384  * so that following keywords will not trigger off it */
385  string chRead;
386  if (p.GetQuote( chRead ))
387  p.StringError();
388 
389  const char *ptr;
390  if( ( ptr = strstr_s( chRead.c_str(), "." ) ) != NULL )
391  {
392  if( strncmp( ptr, ".asc", 4 ) == 0 )
393  {
394  lgProblems = GridCompile( chRead.c_str() );
395  }
396  else if( strncmp( ptr, ".stb", 4 ) == 0 )
397  {
398  // keyword to only include the stellar component
399  // default is to include both the stellar and nebular component
400  sb_mode mode;
401  if( p.nMatch( "STEL" ) )
402  mode = SB_STELLAR;
403  else if( p.nMatch( "NEBU" ) )
404  mode = SB_NEBULAR;
405  else
406  mode = SB_TOTAL;
407  strncpy( chSTB99, chRead.c_str(), FILENAME_PATH_LENGTH_2 );
408  string chASC(chRead.c_str(), ptr);
409  chASC += ".ascii";
410  fprintf( ioQQQ, " Creating %s....\n", chASC.c_str() );
411  lgProblems = StarburstInitialize( chSTB99, chASC.c_str(), mode );
412  lgProblems = lgProblems || GridCompile( chASC.c_str() );
413  }
414  else
415  {
416  fprintf( ioQQQ, " I did not recognize this file extension: %s\n", ptr );
417  lgProblems = true;
418  }
419  }
420  else
421  {
422  fprintf( ioQQQ, " I did not find any file extension: %s\n", chRead.c_str() );
423  lgProblems = true;
424  }
425  }
426  else
427  {
428  /* this branch is intended to convert ascii versions of stellar
429  * atmosphere grids into a direct access version for faster access.
430  * the original file is usually named *.ascii, and the new direct
431  * access file will always be named *.mod.
432  * - if the *.ascii file does not exist, the grid will be skipped
433  * - if the *.ascii file exists, but the *.mod file does not, or is
434  * out of date, a new *.mod file will be generated
435  * - if the *.mod file is up to date, it will not be touched. */
436 
437  process_counter pc;
438 
439  /* These are the current Atlas grids */
440  lgProblems = lgProblems || AtlasCompile(pc);
441  /* do the costar OB stars */
442  lgProblems = lgProblems || CoStarCompile(pc);
443  /* legacy Atlas grid - for backward compatibility only */
444  lgProblems = lgProblems || Kurucz79Compile(pc);
445  /* Mihalas grid - for backward compatibility only */
446  lgProblems = lgProblems || MihalasCompile(pc);
447  /* do the rauch PN central stars */
448  lgProblems = lgProblems || RauchCompile(pc);
449  /* do the Starburst99 sample output */
450  lgProblems = lgProblems || StarburstCompile(pc);
451  /* do the Tlusty OSTAR2002 grid */
452  lgProblems = lgProblems || TlustyCompile(pc);
453  /* do the Werner PN central stars - for backward compatibility only */
454  lgProblems = lgProblems || WernerCompile(pc);
455  /* WMBASIC O-star grid by Pauldrach */
456  lgProblems = lgProblems || WMBASICCompile(pc);
457 
458  if( pc.nFound == 0 )
459  {
460  fprintf( ioQQQ, "\n PROBLEM - No ascii files were found!\n" );
461  fprintf( ioQQQ, " Did you change directory to where the stellar atmosphere files are?\n" );
462  fprintf( ioQQQ, " This command will only work on files in the local directory. Sorry.\n" );
463  lgProblems = true;
464  }
465  else
466  {
467  fprintf( ioQQQ, "\n %d ascii file(s) found", pc.nFound );
468  if( pc.notProcessed > 0 )
469  fprintf( ioQQQ, ", %d file(s) up to date", pc.notProcessed );
470  if( pc.nOK > 0 )
471  fprintf( ioQQQ, ", %d update(s) OK", pc.nOK );
472  if( pc.nFail > 0 )
473  fprintf( ioQQQ, ", %d update(s) failed", pc.nFail );
474  int nSkip = pc.nFound - pc.notProcessed - pc.nOK - pc.nFail;
475  if( nSkip > 0 )
476  fprintf( ioQQQ, ", %d file(s) skipped after failure", nSkip );
477  fprintf( ioQQQ, ".\n" );
478  }
479  }
480 
481  if( lgProblems )
482  {
483  fprintf( ioQQQ, "\n Problems occurred during the compilation - check output.\n" );
484  }
485  else
486  {
487  fprintf( ioQQQ, "\n The compilation was successful!\n" );
488  fprintf( ioQQQ, "\n Good Luck!!\n\n\n" );
489  }
490 
491  cdEXIT( lgProblems ? ES_FAILURE : ES_SUCCESS );
492  }
493  else
494  {
495  fprintf( ioQQQ, " One of the keywords, GRAINS, RECO COEF, or STARS, must appear.\n" );
496  fprintf( ioQQQ, " Sorry.\n" );
498  }
499 
500  return;
501 }
bool nMatch(const char *chKey) const
Definition: parser.h:140
int WernerCompile(process_counter &pc)
Definition: stars.cpp:1620
bool GridCompile(const char *InName)
Definition: stars.cpp:721
double FFmtRead(void)
Definition: parser.cpp:438
const int ipHE_LIKE
Definition: iso.h:65
const int FILENAME_PATH_LENGTH_2
Definition: cddefines.h:296
t_opac opac
Definition: opacity.cpp:5
t_isoCTRL iso_ctrl
Definition: iso.cpp:9
void OpacityCreateAll(void)
bool lgCompileRecomb[NISO]
Definition: iso.h:400
int notProcessed
Definition: stars.h:32
long int nCollapsed_max
Definition: iso.h:518
int TlustyCompile(process_counter &pc)
Definition: stars.cpp:1491
int GetQuote(string &chLabel)
Definition: parser.cpp:184
const char * strstr_s(const char *haystack, const char *needle)
Definition: cddefines.h:1315
bool nMatchErase(const char *chKey)
Definition: parser.h:163
int nFound
Definition: stars.h:31
FILE * ioQQQ
Definition: cddefines.cpp:7
Definition: parser.h:42
NORETURN void StringError() const
Definition: parser.cpp:174
t_dense dense
Definition: global.cpp:15
int RauchCompile(process_counter &pc)
Definition: stars.cpp:970
t_iso_sp iso_sp[NISO][LIMELM]
Definition: iso.cpp:11
void ParseCompile(Parser &p)
void Badnell_rec_init(void)
void iso_update_num_levels(long ipISO, long nelem)
long int n_HighestResolved_max
Definition: iso.h:536
void ContCreatePointers(void)
void ContCreateMesh()
int AtlasCompile(process_counter &pc)
Definition: stars.cpp:452
int Kurucz79Compile(process_counter &pc)
Definition: stars.cpp:872
bool lgMeshSetUp() const
Definition: mesh.h:75
bool StarburstCompile(process_counter &pc)
Definition: stars.cpp:1467
void mie_write_opc(const char *, const char *, long int)
Definition: grains_mie.cpp:274
t_rfield rfield
Definition: rfield.cpp:9
int CoStarCompile(process_counter &pc)
Definition: stars.cpp:622
#define EXIT_FAILURE
Definition: cddefines.h:168
bool lgCompileOpac
Definition: opacity.h:204
#define cdEXIT(FAIL)
Definition: cddefines.h:484
#define LIKE_RREC_MAXN(A_)
Definition: iso.h:100
bool lgElmtOn[LIMELM]
Definition: dense.h:160
int MihalasCompile(process_counter &pc)
Definition: stars.cpp:918
#define ASSERT(exp)
Definition: cddefines.h:617
const int ipH_LIKE
Definition: iso.h:64
const int LIMELM
Definition: cddefines.h:307
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:729
bool lgEOL(void) const
Definition: parser.h:103
Definition: stars.h:26
void atmdat_readin(void)
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1217
int WMBASICCompile(process_counter &pc)
Definition: stars.cpp:1713
sb_mode
Definition: stars.h:25
#define RREC_MAXN
Definition: iso.h:97
bool StarburstInitialize(const char chInName[], const char chOutName[], sb_mode mode)
Definition: stars.cpp:1348
#define EXIT_SUCCESS
Definition: cddefines.h:166