cloudy
trunk
|
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 }