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