/home66/gary/public_html/cloudy/c08_branch/source/parse_compile.cpp

Go to the documentation of this file.
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and
00002  * others.  For conditions of distribution and use see copyright notice in license.txt */
00003 /*ParseCompile compile Werner or kurucz model atmospheres into cloudy format, originally by K Volk,
00004  * also compile opacity and grains  */
00005 #include "cddefines.h"
00006 #include "continuum.h"
00007 #include "atmdat.h"
00008 #include "dense.h"
00009 #include "iso.h"
00010 #include "helike_recom.h"
00011 #include "grains.h"
00012 #include "rfield.h"
00013 #include "stars.h"
00014 #include "parse.h"
00015 #include "input.h"
00016 
00017 void ParseCompile(char *chCard )
00018 {
00019         bool lgEOL;
00020         long int i , ncell;
00021         char chRead[FILENAME_PATH_LENGTH_2],
00022           chRFI[FILENAME_PATH_LENGTH_2],
00023           chSZD[FILENAME_PATH_LENGTH_2],
00024           chSTB99[FILENAME_PATH_LENGTH_2],
00025           *ptr;
00026 
00027 
00028         DEBUG_ENTRY( "ParseCompile()" );
00029 
00030         /* >>chng 01 aug 24, remove compile opacity command */
00031         /* this option to compile opacities into file for later use */
00032         if( nMatch("OPAC",chCard) )
00033         {
00034                 fprintf( ioQQQ, "The COMPILE OPACITIES command is currently not supported\n" );
00035                 cdEXIT(EXIT_FAILURE);
00036 
00037 #       if 0
00038                 /* calls fill to set up continuum energy mesh if first call, 
00039                  * otherwise reset to original mesh */
00040                 ContCreateMesh();
00041 
00042                 /* read in some external data files, but only if this is first call */
00043                 atmdat_readin();
00044 
00045                 /* first generate the frequency array */
00046                 ContCreatePointers();
00047 
00048                 Badnell_rec_init();
00049 
00050                 /* say that we want to compile the opacities */
00051                 opac.lgCompileOpac = true;
00052 
00053                 /* generate initial set of opacities but only if this is the first call 
00054                  * in this coreload */
00055                 OpacityCreateAll();
00056 
00057                 fprintf(ioQQQ, 
00058                         "Success!!  Created file opacity.opc\nMake sure this is on the path.\n" );
00059                 cdEXIT(EXIT_SUCCESS);
00060 #       endif
00061         }
00062 
00063         /* >>chng 00 apr 27, modified for arbitrary file names by PvH
00064          *
00065          * this option to compile grains into file for later use
00066          *
00067          * the command supports the following syntax:
00068          *
00069          * COMPILE GRAINS
00070          *     compile a standard set of opacity files
00071          *
00072          * COMPILE GRAINS <refr-ind-file> <size-distr-file> [ <no-bins> ]
00073          *     compile a single opacity file
00074          *
00075          * Remarks:
00076          * - the parameters of this command can be supplied in arbitrary order.
00077          * - the file names can either be supplied as names between quotes or
00078          *   as keywords; it is allowed to use a filename between quotes for
00079          *   one file and a keyword for the other file; both names have to be
00080          *   present in either form, there are no defaults.
00081          * - filenames are recognized by their extension: .rfi or .mix for
00082          *   refractive index files, and .szd for size distribution files,
00083          *   this allows their sequence to be arbitrary.
00084          * - the number-of-bins parameter is optional, it is defaulted to 10.
00085          *
00086          * NB NB NB NB NB NB NB NB NB NB NB NB NB
00087          *
00088          * - in order not to upset FFmtRead for reading the number-of-bins
00089          *   parameter, all file names and keywords should be read first and
00090          *   erased after being read ! to assure that all digits are erased,
00091          *   the keywords 0M010, 0M100 and 1M000 are matched on all 5 characters.
00092          *   if keywords are known not to contain digits or minus signs, erasing
00093          *   is not necessary of course....
00094          */
00095         if( nMatch("GRAI",chCard) )
00096         {
00097 
00098                 /* calls fill to set up continuum energy mesh if first call, 
00099                  * otherwise reset to original mesh */
00100                 ContCreateMesh();
00101                 /* >>chng 06 dec 13, this had been followed by calls to atmdat_readin &
00102                  * ConCreatePointer which had problems because the code was not
00103                  * fully initialized yet.  Compile stars and compile grains would
00104                  * fail on mallocing an array of length zero */
00105 
00106                 chRFI[0] = '\0';
00107                 chSZD[0] = '\0';
00108 
00109                 /* get first filename (either .rfi or .szd file) */
00110                 if( strchr( chCard,'\"' ) != NULL )
00111                 {
00112                         GetQuote(chRead,chCard, true );
00113                         if( strstr(chRead,".rfi") != NULL || strstr(chRead,".mix") != NULL ) 
00114                         {
00115                                 strcpy(chRFI,chRead);
00116                         }
00117                         else if( strstr(chRead,".szd") != NULL ) 
00118                         {
00119                                 strcpy(chSZD,chRead);
00120                         }
00121                         else 
00122                         {
00123                                 fprintf( ioQQQ, " filename %s has unknown extension, sorry\n" , chRead );
00124                                 cdEXIT(EXIT_FAILURE);
00125                         }
00126                 }
00127 
00128                 /* get second filename (either .rfi or .szd file) */
00129                 if( strchr( chCard,'\"' ) != NULL )
00130                 {
00131                         GetQuote(chRead,chCard, true );
00132                         if( strstr(chRead,".rfi") != NULL || strstr(chRead,".mix") != NULL ) 
00133                         {
00134                                 strcpy(chRFI,chRead);
00135                         }
00136                         else if( strstr(chRead,".szd") != NULL ) 
00137                         {
00138                                 strcpy(chSZD,chRead);
00139                         }
00140                         else 
00141                         {
00142                                 fprintf( ioQQQ, " filename %s has unknown extension, sorry\n" , chRead );
00143                                 cdEXIT(EXIT_FAILURE);
00144                         }
00145                 }
00146 
00147                 /* if no .rfi file was supplied between quotes, check for keywords */
00148                 if( chRFI[0] == '\0' ) 
00149                 {
00150                         /* check on index of refraction names */
00151                         if( (ptr = strstr(chCard,"AC1-")) != NULL )
00152                         {
00153                                 /* amorphous carbon from Rouleau & Martin 1991 */
00154                                 strcpy(chRFI , "ac1-amcarb.rfi" );
00155                                 /* erase this keyword, it upsets FFmtRead */
00156                                 strncpy(ptr,"    ",4);
00157                         }
00158                         else if( (ptr = strstr(chCard,"BE1-")) != NULL )
00159                         {
00160                                 /* amorphous carbon from Rouleau & Martin 1991 */
00161                                 strcpy(chRFI , "be1-amcarb.rfi" );
00162                                 /* erase this keyword, it upsets FFmtRead */
00163                                 strncpy(ptr,"    ",4);
00164                         }
00165                         else if( nMatch( "GRAP" , chCard ) )
00166                         {
00167                                 /* graphite */
00168                                 strcpy(chRFI , "graphite.rfi" );
00169                         }
00170                         else if( nMatch( "SILI" , chCard ) )
00171                         {
00172                                 /* astronomical silicate */
00173                                 strcpy(chRFI , "silicate.rfi" );
00174                         }
00175                         else if( nMatch( " PAH" , chCard ) )
00176                         {
00177                                 /* astronomical silicate */
00178                                 strcpy(chRFI , "pah1.rfi" );
00179                         }
00180                         else if( nMatch( "GREY" , chCard ) || nMatch( "GRAY" , chCard ))
00181                         {
00182                                 strcpy(chRFI , "grey.rfi" );
00183                         }
00184                 }
00185 
00186                 /* if no .szd file was supplied between quotes, check for keywords */
00187                 if( chSZD[0] == '\0' ) 
00188                 {
00189                         /* check on size distribution */
00190                         if( (ptr = strstr(chCard,"0M010")) != NULL )
00191                         {
00192                                 strcpy(chSZD , "0m010.szd" );
00193                                 /* erase this keyword, it upsets FFmtRead */
00194                                 strncpy(ptr,"     ",5);
00195                         }
00196                         else if( (ptr = strstr(chCard,"0M100")) != NULL )
00197                         {
00198                                 strcpy(chSZD , "0m100.szd" );
00199                                 /* erase this keyword, it upsets FFmtRead */
00200                                 strncpy(ptr,"     ",5);
00201                         }
00202                         else if( (ptr = strstr(chCard,"1M000")) != NULL )
00203                         {
00204                                 strcpy(chSZD , "1m000.szd" );
00205                                 /* erase this keyword, it upsets FFmtRead */
00206                                 strncpy(ptr,"     ",5);
00207                         }
00208                         else if( nMatch( "ORIO" , chCard ) )
00209                         {
00210                                 strcpy(chSZD , "orion.szd" );
00211                         }
00212                         else if( nMatch( " ISM" , chCard ) )
00213                         {
00214                                 strcpy(chSZD , "ism.szd" );
00215                         }
00216                         else if( (ptr = strstr(chCard,"AB08")) != NULL )
00217                         {
00218                                 /* Abel et al., 2008 size distribution */
00219                                 strcpy(chSZD , "ab08.szd" );
00220                                 strncpy(ptr,"    ",4);
00221                         }
00222                         else if( (ptr = strstr(chCard,"0N341")) != NULL )
00223                         {
00224                                 /* small PAH, 15 C atoms */
00225                                 strcpy(chSZD , "0n341.szd" );
00226                                 strncpy(ptr,"     ",5);
00227                         }
00228                         else if( (ptr = strstr(chCard,"0N682")) != NULL )
00229                         {
00230                                 /* large PAH, 120 c atoms */
00231                                 strcpy(chSZD , "0n682.szd" );
00232                                 strncpy(ptr,"     ",5);
00233                         }
00234                 }
00235 
00236                 /* the user has to supply either both the .rfi and .szd files, or neither
00237                  * (to compile the complete standard set of files); anything else is illegal */
00238                 if( chRFI[0] == '\0' && chSZD[0] != '\0' )
00239                 {
00240                         fprintf(ioQQQ,"Sorry, but I did not recognize a refractive index file.\n");
00241                         fprintf(ioQQQ,"Supply a file name between quotes or one of the following ");
00242                         fprintf(ioQQQ,"keywords: ac1-amcarb, be1-amcarb, graphite, silicate, grey, pah\n");
00243                         cdEXIT(EXIT_FAILURE);
00244                 }
00245 
00246                 if( chSZD[0] == '\0' && chRFI[0] != '\0' )
00247                 {
00248                         fprintf(ioQQQ,"Sorry, but I did not recognize a size distribution file.\n");
00249                         fprintf(ioQQQ,"Supply a file name between quotes or one of the following ");
00250                         fprintf(ioQQQ,"keywords: 0m010, 0m100, 1m000, ism, orion, on341, 0n682, ab08\n");
00251                         cdEXIT(EXIT_FAILURE);
00252                 }
00253 
00254                 /* compile the complete standard set of files */
00255                 if( chRFI[0] == '\0' && chSZD[0] == '\0' )
00256                 {
00257                         /* ism graphite, single bin */
00258                         mie_write_opc( "graphite.rfi" , "ism.szd" , 1 );
00259 
00260                         /* ism silicate, single bin */
00261                         mie_write_opc( "silicate.rfi" , "ism.szd" , 1 );
00262 
00263                         /* ism graphite, 10 bins */
00264                         mie_write_opc( "graphite.rfi" , "ism.szd" , 10 );
00265 
00266                         /* ism silicate, 10 bins */
00267                         mie_write_opc( "silicate.rfi" , "ism.szd" , 10 );
00268 
00269                         /* orion graphite, single bin */
00270                         mie_write_opc( "graphite.rfi" , "orion.szd" , 1 );
00271 
00272                         /* orion silicate, single bin */
00273                         mie_write_opc( "silicate.rfi" , "orion.szd" , 1 );
00274 
00275                         /* orion graphite, 10 bins */
00276                         mie_write_opc( "graphite.rfi" , "orion.szd" , 10 );
00277 
00278                         /* orion silicate, 10 bins */
00279                         mie_write_opc( "silicate.rfi" , "orion.szd" , 10 );
00280 
00281                         /* 0.01 micron silicate */
00282                         mie_write_opc( "silicate.rfi" , "0m010.szd" , 1 );
00283 
00284                         /* 0.1 micron silicate */
00285                         mie_write_opc( "silicate.rfi" , "0m100.szd" , 1 );
00286 
00287                         /* 1 micron silicate */
00288                         mie_write_opc( "silicate.rfi" , "1m000.szd" , 1 );
00289 
00290                         /* 0.01 micron graphite */
00291                         mie_write_opc( "graphite.rfi" , "0m010.szd" , 1 );
00292 
00293                         /* 0.1 micron graphite */
00294                         mie_write_opc( "graphite.rfi" , "0m100.szd" , 1 );
00295 
00296                         /* 1 micron graphite */
00297                         mie_write_opc( "graphite.rfi" , "1m000.szd" , 1 );
00298 
00299                         /* grey single bin */
00300                         mie_write_opc( "grey.rfi" , "ism.szd" , 1 );
00301 
00302                         /* grey resolved distribution */
00303                         mie_write_opc( "grey.rfi" , "ism.szd" , 10 );
00304 
00305                         /* small pah */
00306                         mie_write_opc( "pah1.rfi" , "0n341.szd" , 1 );
00307 
00308                         /* large pah */
00309                         mie_write_opc( "pah1.rfi" , "0n682.szd" , 1 );
00310 
00311                         /* distributed pah */
00312                         mie_write_opc( "pah1.rfi" , "ab08.szd" , 10 );
00313 
00314                         /* single pah */
00315                         mie_write_opc( "pah1.rfi" , "ab08.szd" , 1 );
00316                 }
00317                 /* this option is to compile a single type of grain */
00318                 else
00319                 {
00320                         i = 5;
00321                         ncell = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00322                         if( lgEOL )
00323                         {
00324                                 /* the default, 10 cells */
00325                                 ncell = 10;
00326                         }
00327                         if( ncell <= 0 )
00328                         {
00329                                 fprintf(ioQQQ,"Number of bins must be positive.  Sorry.\n");
00330                                 cdEXIT(EXIT_FAILURE);
00331                         }
00332                         /* this actually does the work */
00333                         mie_write_opc( chRFI , chSZD , ncell );
00334                 }
00335 
00336                 fprintf(ioQQQ, 
00337                         "Success!!  Created grain opacity file(s).\nMake sure this directory is on the path.\n" );
00338                 cdEXIT(EXIT_SUCCESS);
00339         }
00340 
00341         /* compile recombination coefficients command */
00342         else if( nMatch("RECO",chCard) && nMatch("COEF",chCard) )
00343         {
00344                 long ipISO;
00345                 int nelem;
00346 
00347                 if( nMatch("H-LI",chCard) )
00348                         ipISO = ipH_LIKE;
00349                 else if( nMatch("HE-L",chCard) )
00350                         ipISO = ipHE_LIKE;
00351                 else
00352                 {
00353                         fprintf(ioQQQ,"Sorry, but I did not recognize an iso sequence.\n");
00354                         fprintf(ioQQQ,"The available options are H-like and He-like.\nSorry.\n");
00355                         cdEXIT(EXIT_FAILURE);
00356                 }
00357 
00358                 /* compile he-like command - compiles table of recombination coeficients */
00359                 iso.lgCompileRecomb[ipISO] = true;
00360 
00361                 /* we will want to create the rec coefficient for a large number of levels, then stop.
00362                  * this sets the number of levels to a large number.  macro is in helike.h */
00363                 for( nelem = ipISO; nelem < LIMELM; nelem++)
00364                 {
00365                         long maxN;
00366                         dense.lgElmtOn[nelem] = true;
00367                         iso.nCollapsed_max[ipISO][nelem] = 0;
00368 
00369                         if( nelem == ipISO )
00370                                 maxN = RREC_MAXN;
00371                         else
00372                                 maxN = LIKE_RREC_MAXN( nelem );
00373 
00374                         iso.n_HighestResolved_max[ipISO][nelem] = maxN;
00375 
00376                         iso_update_num_levels( ipISO, nelem );
00377                 }
00378         }
00379 
00380         else if( nMatch("GAUN",chCard) )
00381         {
00382                 /* compile gaunt command - compiles table of free free gaunt factors */
00383                 rfield.lgCompileGauntFF = true;
00384         }
00385 
00386         else if( nMatch("STAR",chCard) )
00387         {
00388                 bool lgProblems = false;
00389 
00390                 /* calls fill to set up continuum energy mesh if first call, 
00391                  * otherwise reset to original mesh */
00392                 ContCreateMesh();
00393                 /* >>chng 06 dec 13, this had been followed by calls to atmdat_readin &
00394                 * ConCreatePointer which had problems because the code was not
00395                 * fully initialized yet.  Compile stars and compile grains would
00396                 * fail on mallocing an array of length zero */
00397 
00398                 if( strchr( input.chOrgCard,'\"' ) != NULL )
00399                 {
00400                         /* this is branch for for user-supplied *.ascii file */
00401 
00402                         /* this will both scan in whatever label is inside the quotes in OrgCard, 
00403                          * but also remove the contents there and in chCard,
00404                          * so that following keywords will not trigger off it */
00405                         GetQuote( chRead, chCard, true );
00406 
00407                         if( ( ptr = strstr( chRead, "." ) ) != NULL )
00408                         {
00409                                 if( strncmp( ptr, ".asc", 4 ) == 0 )
00410                                 {
00411                                         lgProblems = GridCompile( chRead );
00412                                 }
00413                                 else if( strncmp( ptr, ".stb", 4 ) == 0 )
00414                                 {
00415                                         strncpy( chSTB99, chRead, FILENAME_PATH_LENGTH_2 );
00416                                         strncpy( ptr, ".ascii", FILENAME_PATH_LENGTH_2 - (ptr-chRead) );
00417                                         lgProblems = StarburstInitialize( chSTB99, chRead );
00418                                         lgProblems = lgProblems || GridCompile( chRead );
00419                                 }
00420                                 else
00421                                 {
00422                                         fprintf( ioQQQ, " I did not recognize this file extension: %s\n", ptr );
00423                                         lgProblems = true;
00424                                 }
00425                         }
00426                         else
00427                         {
00428                                 fprintf( ioQQQ, " I did not find any file extension: %s\n", chRead );
00429                                 lgProblems = true;
00430                         }
00431                 }
00432                 else
00433                 {
00434                         /* this branch is intended to convert ascii versions of stellar
00435                          * atmosphere grids into a direct access version for faster access.
00436                          * the original file is usually named *.ascii, and the new direct
00437                          * access file will always be named *.mod.
00438                          * - if the *.ascii file does not exist, the grid will be skipped
00439                          * - if the *.ascii file exists, but the *.mod file does not, or is
00440                          *   out of date, a new *.mod file will be generated
00441                          * - if the *.mod file is up to date, it will not be touched. */
00442 
00443                         process_counter pc;
00444 
00445                         /* These are the current Atlas grids */
00446                         lgProblems = lgProblems || AtlasCompile(pc);
00447                         /* do the costar OB stars */
00448                         lgProblems = lgProblems || CoStarCompile(pc);
00449                         /* legacy Atlas grid - for backward compatibility only */
00450                         lgProblems = lgProblems || Kurucz79Compile(pc);
00451                         /* Mihalas grid - for backward compatibility only */
00452                         lgProblems = lgProblems || MihalasCompile(pc);
00453                         /* do the rauch PN central stars */
00454                         lgProblems = lgProblems || RauchCompile(pc);
00455                         /* do the Starburst99 sample output */
00456                         lgProblems = lgProblems || StarburstCompile(pc);
00457                         /* do the Tlusty OSTAR2002 grid */
00458                         lgProblems = lgProblems || TlustyCompile(pc);
00459                         /* do the Werner PN central stars - for backward compatibility only */
00460                         lgProblems = lgProblems || WernerCompile(pc);
00461                         /* WMBASIC O-star grid by Pauldrach */
00462                         lgProblems = lgProblems || WMBASICCompile(pc);
00463 
00464                         if( pc.nFound == 0 )
00465                         {
00466                                 fprintf( ioQQQ, "\n PROBLEM - No ascii files were found!\n" );
00467                                 fprintf( ioQQQ, " Did you change directory to where the stellar atmosphere files are?\n" );
00468                                 fprintf( ioQQQ, " This command will only work on files in the local directory. Sorry.\n" );
00469                                 lgProblems = true;
00470                         }
00471                         else
00472                         {
00473                                 fprintf( ioQQQ, "\n %d ascii file(s) found", pc.nFound );
00474                                 if( pc.notProcessed > 0 )
00475                                         fprintf( ioQQQ, ", %d file(s) up to date", pc.notProcessed );
00476                                 if( pc.nOK > 0 )
00477                                         fprintf( ioQQQ, ", %d update(s) OK", pc.nOK );
00478                                 if( pc.nFail > 0 )
00479                                         fprintf( ioQQQ, ", %d update(s) failed", pc.nFail );
00480                                 int nSkip = pc.nFound - pc.notProcessed - pc.nOK - pc.nFail;
00481                                 if( nSkip > 0 )
00482                                         fprintf( ioQQQ, ", %d file(s) skipped after failure", nSkip );
00483                                 fprintf( ioQQQ, ".\n" );
00484                         }
00485                 }
00486 
00487                 if( lgProblems )
00488                 {
00489                         fprintf( ioQQQ, "\n Problems occurred during the compilation - check output.\n" );
00490                 }
00491                 else
00492                 {
00493                         fprintf( ioQQQ, "\n The compilation was successful!\n" );
00494                         fprintf( ioQQQ, 
00495                                  " The portable ascii files are no longer needed and may be deleted to save space.\n" );
00496                         fprintf( ioQQQ, "\n Good Luck!!\n\n\n" );
00497                 }
00498 
00499                 cdEXIT(lgProblems);
00500         }
00501         else
00502         {
00503                 fprintf( ioQQQ, " One of the keywords, GRAINS, HE-LIKE, GAUNT, or STARS, must appear.\n" );
00504                 fprintf( ioQQQ, " Sorry.\n" );
00505                 cdEXIT(EXIT_FAILURE);
00506         }
00507 
00508         return;
00509 }

Generated on Mon Feb 16 12:01:25 2009 for cloudy by  doxygen 1.4.7