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

Generated for cloudy by doxygen 1.8.4