00001
00002
00003
00004
00005
00006
00007 #include "cddefines.h"
00008 #include "cddrive.h"
00009 #include "physconst.h"
00010 #include "elementnames.h"
00011 #include "input.h"
00012 #include "geometry.h"
00013 #include "prt.h"
00014 #include "opacity.h"
00015 #include "optimize.h"
00016 #include "rfield.h"
00017 #include "map.h"
00018 #include "atomfeii.h"
00019 #include "h2.h"
00020 #include "mole.h"
00021 #include "hmi.h"
00022 #include "version.h"
00023 #include "grainvar.h"
00024 #include "parse.h"
00025 #include "grid.h"
00026 #include "punch.h"
00027
00028 static void ChkUnits( char *chCard);
00029
00030
00031
00032
00033 static bool lgNoClobber[LIMPUN];
00034
00035
00036 static bool lgPunConv_noclobber , lgDROn_noclobber ,
00037 lgPunPoint_noclobber , lgioRecom_noclobber , lgQHPunchFile_noclobber;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 void ParsePunch(char *chCard )
00054 {
00055 char chLabel[INPUT_LINE_LENGTH] ,
00056 chFilename[INPUT_LINE_LENGTH] ,
00057 chSecondFilename[INPUT_LINE_LENGTH];
00058 bool lgEOL,
00059 lgSecondFilename;
00060
00061 long int ipFFmt,
00062 i,
00063 nelem;
00064
00065 #define MAX_HEADER_SIZE 2000
00066
00067 char chHeader[MAX_HEADER_SIZE],
00068 chTemp[MAX_HEADER_SIZE];
00069
00070
00071 DEBUG_ENTRY( "ParsePunch()" );
00072
00073
00074 sprintf( chHeader, "ArNdY38dZ9us4N4e12SEcuQ" );
00075
00076
00077 if( !punch.lgOpenUnits )
00078 {
00079 if( !optimize.lgNoVary && optimize.lgOptimr && !nMatch("XSPE",chCard) )
00080 {
00081 fprintf(ioQQQ,"\n\n WARNING - the code does not support punch output while optimizing.\n");
00082 fprintf(ioQQQ," Remove the punch commands and add them with the final best-fit model.\n");
00083 fprintf(ioQQQ," I will try to soldier on, but anything can happen.\n\n\n");
00084 }
00085
00086 DEBUG_EXIT( "ParsePunch()" );
00087 return;
00088 }
00089
00090
00091 if( punch.npunch > LIMPUN )
00092 {
00093 fprintf( ioQQQ,
00094 "The limit to the number of PUNCH options is %ld. Increase "
00095 "LIMPUN in punch.h if more are needed.\nSorry.\n",
00096 LIMPUN );
00097 puts( "[Stop in ParsePunch]" );
00098 cdEXIT(EXIT_FAILURE);
00099 }
00100
00101
00102 {
00103 static bool lgMustInit=true;
00104 if( lgMustInit )
00105 {
00106 lgMustInit = false;
00107
00108
00109
00110 punch.nLineList = (long int*)MALLOC((size_t)(LIMPUN*sizeof(long int)) );
00111
00112 punch.wlLineList = (float **)MALLOC((size_t)(LIMPUN*sizeof(float *)) );
00113
00114 punch.chLineListLabel = (char***)MALLOC((size_t)(LIMPUN*sizeof(char**)) );
00115
00116
00117 for( i=0; i<LIMPUN; ++i )
00118 {
00119 punch.nLineList[i] = -1;
00120 }
00121
00122
00123
00124 punch.nAverageList = (long int*)MALLOC((size_t)(LIMPUN*sizeof(long int)) );
00125
00126 punch.chAverageSpeciesLabel = (char***)MALLOC((size_t)(LIMPUN*sizeof(char**)) );
00127
00128 punch.chAverageType = (char***)MALLOC((size_t)(LIMPUN*sizeof(char**)) );
00129
00130 punch.nAverageIonList = (int **)MALLOC((size_t)(LIMPUN*sizeof(int *)) );
00131
00132 punch.nAverage2ndPar = (int **)MALLOC((size_t)(LIMPUN*sizeof(int *)) );
00133
00134
00135 for( i=0; i<LIMPUN; ++i )
00136 {
00137 punch.nAverageList[i] = -1;
00138 }
00139 }
00140 }
00141
00142
00143 punch.lgPunchToSeparateFiles[punch.npunch] = false;
00144
00145
00146 if( nMatch("LAST",chCard) )
00147 punch.lgPunLstIter[punch.npunch] = true;
00148 else
00149 punch.lgPunLstIter[punch.npunch] = false;
00150
00151
00152
00153
00154
00155
00156
00157
00158 if( GetQuote( chLabel , chCard , true ) )
00159
00160 TotalInsanity();
00161
00162
00163 if( strcmp(chLabel , "opacity.opc") == 0 )
00164 {
00165 fprintf( ioQQQ, "ParsePunch will not allow punch file name %s, please choose another.\nSorry.\n",
00166 chLabel);
00167 puts( "[Stop in ParsePunch]" );
00168 cdEXIT(EXIT_FAILURE);
00169 }
00170 else if( chLabel[0]==0 )
00171 {
00172 fprintf( ioQQQ, "ParsePunch found a null file name between double quotes, please check command line.\nSorry.\n");
00173 puts( "[Stop in ParsePunch]" );
00174 cdEXIT(EXIT_FAILURE);
00175 }
00176
00177
00178
00179 strcpy( chFilename , punch.chFilenamePrefix );
00180 strcat( chFilename , chLabel );
00181
00182
00183
00184
00185 if( GetQuote( chSecondFilename , chCard , false ) )
00186 lgSecondFilename = false;
00187 else
00188 lgSecondFilename = true;
00189
00190
00191
00192 if( nMatch("CLOB",chCard) )
00193 {
00194 if( nMatch(" NO ",chCard) )
00195 {
00196
00197 lgNoClobber[punch.npunch] = true;
00198 }
00199 else
00200 {
00201
00202 lgNoClobber[punch.npunch] = false;
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 if( !nMatch("O TI",chCard) && nMatch("TITL",chCard))
00212 {
00213 sprintf( chHeader,
00214 "# %s %s\n",
00215 version.chVersion, input.chTitle );
00216 }
00217
00218
00219
00220
00221
00222 if( nMatch("O HA",chCard) )
00223 {
00224 punch.lgHashEndIter = false;
00225 }
00226
00227
00228 if( nMatch("OPAC",chCard) )
00229 {
00230
00231 punch.lgPunchToSeparateFiles[punch.npunch] = true;
00232
00233
00234
00235 ChkUnits(chCard);
00236
00237 strcpy( punch.chPunch[punch.npunch], "OPAC" );
00238 if( nMatch("TOTA",chCard) )
00239 {
00240
00241
00242 strcpy( punch.chOpcTyp[punch.npunch], "TOTL" );
00243 sprintf( chHeader,
00244 "#nu\tTot opac\tAbs opac\tScat opac\tAlbedo\telem\n" );
00245 }
00246
00247 else if( nMatch("FIGU",chCard) )
00248 {
00249
00250 strcpy( punch.chOpcTyp[punch.npunch], "FIGU" );
00251 sprintf( chHeader,
00252 "#nu, H, He, tot opac\n" );
00253 }
00254
00255 else if( nMatch("FINE",chCard) )
00256 {
00257
00258 rfield.lgPunchOpacityFine = true;
00259 strcpy( punch.chOpcTyp[punch.npunch], "FINE" );
00260
00261
00262 ChkUnits(chCard);
00263
00264 sprintf( chHeader,
00265 "#nu\topac\n" );
00266 ipFFmt = 5;
00267
00268
00269 if( nMatch("RANGE",chCard) )
00270 {
00271
00272 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
00273 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
00274 if( lgEOL )
00275 {
00276 fprintf(ioQQQ,"There must be two numbers, the lower and upper energy range in Ryd.\nSorry.\n");
00277 puts( "[Stop in ParsePunch]" );
00278 cdEXIT(EXIT_FAILURE);
00279 }
00280 if( punch.punarg[punch.npunch][0] >=punch.punarg[punch.npunch][1] )
00281 {
00282 fprintf(ioQQQ,"The two energies for the range must be in increasing order.\nSorry.\n");
00283 puts( "[Stop in ParsePunch]" );
00284 cdEXIT(EXIT_FAILURE);
00285 }
00286 }
00287 else
00288 {
00289
00290 punch.punarg[punch.npunch][0] = 0.;
00291 punch.punarg[punch.npunch][1] = 0.;
00292 }
00293
00294 punch.punarg[punch.npunch][2] = (float)FFmtRead(chCard,&ipFFmt,
00295 INPUT_LINE_LENGTH,&lgEOL);
00296
00297
00298 if( lgEOL )
00299 punch.punarg[punch.npunch][2] = 10;
00300
00301 if( punch.punarg[punch.npunch][2] < 1 )
00302 {
00303 fprintf(ioQQQ,"The number of fine opacities to skip must be > 0 \nSorry.\n");
00304 puts( "[Stop in ParsePunch]" );
00305 cdEXIT(EXIT_FAILURE);
00306 }
00307 }
00308
00309 else if( nMatch("GRAI",chCard) )
00310 {
00311
00312 strcpy( punch.chPunch[punch.npunch], "DUSO" );
00313
00314 sprintf( chHeader,
00315 "#grain nu\ttotal(1-g)\tabst\tscat(1-g)\tscat\tscat(1-g)/[abs+scat(1-g)]\n" );
00316 }
00317
00318 else if( nMatch("BREM",chCard) )
00319 {
00320
00321 strcpy( punch.chOpcTyp[punch.npunch], "BREM" );
00322 sprintf( chHeader,
00323 "#nu\tbrem opac\n" );
00324 }
00325
00326 else if( nMatch("SHEL",chCard) )
00327 {
00328
00329 strcpy( punch.chPunch[punch.npunch], "OPAC" );
00330
00331
00332 strcpy( punch.chOpcTyp[punch.npunch], "SHEL" );
00333
00334
00335 ipFFmt = 3;
00336 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,
00337 INPUT_LINE_LENGTH,&lgEOL);
00338
00339
00340 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,
00341 INPUT_LINE_LENGTH,&lgEOL);
00342
00343
00344 punch.punarg[punch.npunch][2] = (float)FFmtRead(chCard,&ipFFmt,
00345 INPUT_LINE_LENGTH,&lgEOL);
00346
00347 if( lgEOL )
00348 {
00349 fprintf( ioQQQ, "There must be IO unit, atom weight, ion, shell\nSorry.\n" );
00350 puts( "[Stop in ParsePunch]" );
00351 cdEXIT(EXIT_FAILURE);
00352 }
00353 sprintf( chHeader,
00354 "#sub shell cross section\n" );
00355 }
00356
00357 else if( nMatch("ELEM",chCard) )
00358 {
00359
00360
00361
00362
00363
00364
00365
00366 if( (nelem = GetElem( chCard ) ) < 0 )
00367 {
00368 fprintf( ioQQQ, "There must be a second keyword on the opacity command. Sorry.\n" );
00369 fprintf( ioQQQ, "Options are total, figure, grain, or element name.\n" );
00370 puts( "[Stop in ParsePunch]" );
00371 cdEXIT(EXIT_FAILURE);
00372 }
00373
00374
00375 strcpy( punch.chOpcTyp[punch.npunch], elementnames.chElementNameShort[nelem] );
00376 }
00377 else
00378 {
00379 fprintf( ioQQQ, " I did not recognize a keyword on this punch opacity command.\n" );
00380 fprintf( ioQQQ, " Sorry.\n" );
00381 puts( "[Stop in ParsePunch]" );
00382 cdEXIT(EXIT_FAILURE);
00383 }
00384 }
00385
00386
00387 else if( nMatch(" H2 ",chCard) )
00388 {
00389
00390
00391 ((void)0);
00392 }
00393
00394 else if( nMatch("ABUN",chCard) )
00395 {
00396
00397 strcpy( punch.chPunch[punch.npunch], "ABUN" );
00398 sprintf( chHeader,
00399 "#abund H" );
00400 for(nelem=ipHELIUM;nelem<LIMELM; ++nelem )
00401 {
00402 sprintf( chTemp, "\t%s",
00403 elementnames.chElementNameShort[nelem] );
00404 strcat( chHeader, chTemp );
00405 }
00406 strcat( chHeader, "\n");
00407 }
00408
00409 else if( nMatch(" AGE",chCard) )
00410 {
00411
00412 strcpy( punch.chPunch[punch.npunch], "AGES" );
00413 sprintf( chHeader,
00414 "#ages depth\tt(cool)\tt(H2 dest)\tt(CO dest)\tt(OH dest)\tt(H rec)\n" );
00415 }
00416
00417 else if( nMatch(" AGN",chCard) )
00418 {
00419
00420 strcpy( punch.chPunch[punch.npunch], " AGN" );
00421
00422
00423
00424 if( nMatch("CHAR",chCard) )
00425 {
00426 strcpy( punch.chPunch[punch.npunch], "CHAG" );
00427 sprintf( chHeader,
00428 "#charge exchange rate coefficnt\n" );
00429 }
00430
00431 else if( nMatch("RECO",chCard) )
00432 {
00433
00434 strcpy( punch.chPunch[punch.npunch], "RECA" );
00435 sprintf( chHeader,
00436 "#Recom rates for AGN3 table\n" );
00437 }
00438
00439 else if( nMatch("OPAC",chCard) )
00440 {
00441
00442 strcpy( punch.chOpcTyp[punch.npunch], " AGN" );
00443 strcpy( punch.chPunch[punch.npunch], "OPAC" );
00444 }
00445
00446 else if( nMatch("HECS",chCard) )
00447 {
00448
00449 strcpy( punch.chPunchArgs[punch.npunch], "HECS" );
00450 sprintf( chHeader,
00451 "#AGN3 he cs \n" );
00452 }
00453
00454 else if( nMatch("HEMI",chCard) )
00455 {
00456
00457 strcpy( punch.chPunchArgs[punch.npunch], "HEMI" );
00458
00459
00460
00461
00462
00463 ChkUnits(chCard);
00464 }
00465 else if( nMatch("RECC",chCard) )
00466 {
00467
00468 strcpy( punch.chPunch[punch.npunch], "HYDr" );
00469 sprintf( chHeader,
00470 "#T\tbAS\tb1\tbB\n" );
00471 }
00472 else
00473 {
00474 fprintf( ioQQQ, " I did not recognize this .\n" );
00475 fprintf( ioQQQ, " Sorry.\n" );
00476 puts( "[Stop in ParsePunch]" );
00477 cdEXIT(EXIT_FAILURE);
00478 }
00479
00480 }
00481
00482 else if( nMatch("ASSE",chCard) )
00483 {
00484
00485 strcpy( punch.chPunch[punch.npunch], "ASSE" );
00486
00487
00488 }
00489
00490 else if( nMatch("AVER",chCard) )
00491 {
00492
00493 strcpy( punch.chPunch[punch.npunch], "AVER" );
00494
00495
00496
00497
00498
00499
00500 punch_average( punch.npunch, "READ", chHeader );
00501
00502 # if 0
00503 long int j;
00504
00505 sprintf( chHeader, "#averages" );
00506 for( j=0; j<punch.nAverageList[punch.npunch]; ++j )
00507 {
00508 sprintf( chTemp, "\t%s ", punch.chAverageType[punch.npunch][j] );
00509 strcat( chHeader, chTemp );
00510 sprintf( chTemp, "%s ", punch.chAverageSpeciesLabel[punch.npunch][j] );
00511 strcat( chHeader, chTemp );
00512 sprintf( chTemp, "%li " , punch.nAverageIonList[punch.npunch][j] );
00513 strcat( chHeader, chTemp );
00514 }
00515 strcat( chHeader, "\n" );
00516 # endif
00517 }
00518
00519
00520 else if( nMatch("CHAR",chCard) && nMatch("TRAN",chCard) )
00521 {
00522
00523
00524
00525 strcpy( punch.chPunch[punch.npunch], "CHAR" );
00526 sprintf( chHeader,
00527 "#charge exchange rate coefficient\n" );
00528 }
00529
00530 else if( nMatch("CHEM",chCard) )
00531 {
00532
00533 if( nMatch( "RATE" , chCard ) )
00534 {
00535
00536
00537 if( nMatch( " CO " , chCard ) )
00538 {
00539
00540 strcpy( punch.chPunch[punch.npunch], "RCO " );
00541 sprintf( chHeader,
00542 "#Depth\tH2O_C3HP_CO_C2H3P\tC2H2_HCOP_CO_C2H3P\tC2H_HCOP_CO_C2H2P\tO_C3H_CO_C2H\t"
00543 "O_C2H2_CO_CH2\tOH_C2H2_CO_CH3\tHCOP_C3_C3HP_CO\tO2_C3_CO_C2_O\tO_C3_CO_C2\t"
00544 "H_COP_CO_HP\tHminus_HCOP_CO_H2\tH2P_CO_HCOP_H\tH2P_CO_COP_H2\tH3P_CO_HCOP_H2\t"
00545 "HeP_CO_OP_C_He\tHeP_CO_O_CP_He\tcrnu_CO_O_C\tCRP_CO_COP_e\tnu_CO_O_C\te_HCOP_CO_H\t"
00546 "C_COP_CO_CP\tC_HCOP_CO_CHP\tC_O_CO_nu\tC_O2_CO_O\tC_OH_CO_H\tC_SiOP_SiP_CO\tCP_OH_CO_HP\t"
00547 "CP_SiO_SiP_CO\tCP_O2_CO_OP\tO_CH_CO_H\tO_CH2_CO_H_H\tO_CH2_CO_H2\tO_COP_CO_OP\tOP_CO_COP_O\t"
00548 "CH_COP_CO_CHP\tCH_HCOP_CO_CH2P\tCH_O2_CO_OH\tCH2_COP_CO_CH2P\tCH2_HCOP_CO_CH3P\t"
00549 "CH2_O2_CO_H2O\tCOP_O2_O2P_CO\tH2O_COP_CO_H2OP\tH2O_HCOP_CO_H3OP\tH2OP_CO_HCOP_OH\t"
00550 "HCOP_SiH_SiH2P_CO\tHCOP_SiO_SiOHP_CO\tOH_COP_CO_OHP\tOH_HCOP_CO_H2OP\tOHP_CO_HCOP_O\t"
00551 "COP_CH4_CO_CH4P\tCO_CH4P_HCOP_CH3\tCO_CH5P_HCOP_CH4\tHP_OCS_HSP_CO\tHeP_OCS_SP_CO_He\t"
00552 "OCNP_e_CO_N\tOCSP_e_S_CO\tOCS_NU_S_CO\tOCS_CRP_S_CO\tC_NO_CO_N\tC_OCN_CO_CN\t"
00553 "C_SO_S_CO\tO_CN_CO_N\tO_HCN_CO_NH\tO_OCN_NO_CO\tO_CS_S_CO\tO_OCS_SO_CO\tOH_HCN_CO_NH2\t"
00554 "CN_NO_N2_CO\tCN_O2_NO_CO\tCO_HS_OCS_H\tCP_SO_SP_CO\tCP_OCS_CSP_CO\tCHP_OCS_HCSP_CO\t"
00555 "NP_CO_NOP_C\tNP_OCS_SP_CO_N\tNHP_CO_HCOP_N\tNHP_CO_OCNP_H\tNH_HCOP_CO_NH2P\t"
00556 "NH2_HCOP_CO_NH3P\tNH3_HCOP_CO_NH4P\tCNP_O2_NOP_CO\tHCNP_CO_HCOP_CN\tCO_HNOP_NO_HCOP\t"
00557 "N2P_OCS_SP_N2_CO\tHCOP_S_HSP_CO\tHCOP_CS_HCSP_CO\tNH_COP_CO_NHP\tNH2_COP_CO_NH2P\t"
00558 "NH3_COP_CO_NH3P\tCNP_CO_COP_CN\tHCN_COP_CO_HCNP\tCO_N2P_N2_COP\tCOP_NO_NOP_CO\t"
00559 "CO_S_OCS_NU\tNP_CO_COP_N\tCOP_S_SP_CO\tC_CO_C2_O\tO_C2_CO_C\tC2_O2_CO_CO\t"
00560 "C2_O2P_COP_CO\tC2_COP_CO_C2P\tC2P_O2_COP_CO\tO_C2H_CO_CH\tO_CCl_Cl_CO\t"
00561 "CO_H2ClP_HCl_HCOP\tHNC_HCOP_HCNHP_CO\tHCN_HCOP_HCNHP_CO\tC2H_COP_CO_C2HP\tC2_HCOP_CO_C2HP\n");
00562 }
00563
00564 else if( nMatch( " OH " , chCard ) )
00565 {
00566 strcpy( punch.chPunch[punch.npunch], "ROH " );
00567 sprintf( chHeader,
00568 "#Depth\tnu_H2O_OH_H\tnu_OH_OHP_e\tnu_OH_O_H\tnu_H2O_OH_H\tnu_OH_OHP_e\tnu_OH_O_H\tcrnu_H2O_OH_H\tcrnu_OH_O_H\tCP_OH_CO_HP\tCP_OH_COP_H\t"
00569 "CP_OH_CO_HP\tCP_OH_COP_H\tCH2_OHP_OH_CH2P\tCH2P_O2_HCOP_OH\tH2O_COP_HCOP_OH\tH2OP_H2O_H3OP_OH\tC_H2OP_OH_CHP\tOP_OH_O2P_H\tOP_OH_OHP_O\tSiP_OH_SiOP_H\t"
00570 "CH_H2OP_OH_CH2P\tCH_OHP_OH_CHP\tCHP_OH_COP_H2\tCHP_O2_COP_OH\tCH2_H2OP_OH_CH3P\tOH_COP_HCOP_O\tOH_H2OP_H3OP_O\tOHP_H2O_H2OP_OH\tOHP_O2_O2P_OH\tOHP_OH_H2OP_O\t"
00571 "O_CH4P_OH_CH3P\tOP_CH4_OH_CH3P\tCH5P_OH_H2OP_CH4\tOHP_C2_C2P_OH\tOH_C2P_C2_OHP\tCH_NO_CN_OH\tNH_O_OH_N\tNH_OH_HNO_H\tO_HNO_NO_OH\tNH2_OH_H2O_NH\t"
00572 "NH2_NO_N2_OH_H\tOH_CN_OCN_H\tOH_S_HS_O\tOH_S_SO_H\tNHP_OH_H2OP_N\tNHP_H2O_OH_NH2P\tNHP_O2_NOP_OH\tO_HSP_SP_OH\tNH2P_OH_H2OP_NH\tNH2P_H2O_NH3P_OH\t"
00573 "NH2_H2OP_NH3P_OH\tNH2P_O2_HNOP_OH\tOH_NH3P_NH4P_O\tOH_HCNP_CN_H2OP\tOH_HNOP_NO_H2OP\tOH_SP_SOP_H\tNH3P_H2O_NH4P_OH\tNH3_H2OP_NH4P_OH\tH2O_CNP_HCNP_OH\tH2OP_S_HSP_OH\t"
00574 "NH_OHP_OH_NHP\tNH2_OHP_OH_NH2P\tOHP_NH3_NH3P_OH\tOH_CNP_CN_OHP\tOH_N2P_N2_OHP\tOHP_NO_NOP_OH\tNP_OH_OHP_N\tOHP_S_SP_OH\tH2OP_HNC_HCNHP_OH\tH2OP_HCN_HCNHP_OH\t"
00575 "H2O_C2P_C2HP_OH\tH2OP_C2_C2HP_OH\tH2OP_C2H_C2H2P_OH\tOHP_C2H_C2HP_OH\tHminus_OH_H2O_e\tHminus_O_OH_e\tHP_OH_OHP_H\tH2s_OH_O_H2_H\tH2s_H2O_OH_H2_H\tH2P_OH_H2OP_H\t"
00576 "H2P_OH_OHP_H2\tH3P_OH_H2OP_H2\tHeP_OH_OP_He_H\tHeP_H2O_OH_He_HP\tH3P_NO2_NOP_OH_H2\tCH_O2_CO_OH\tH2OP_CO_HCOP_OH\tOH_COP_CO_OHP\tOH_HCOP_CO_H2OP\tCH2_OH_H2O_CH\t"
00577 "C_OH_O_CH\tO_CH_OH_C\tO_CH2_OH_CH\tO_H2O_OH_OH\tO_OH_O2_H\tSi_OH_SiO_H\tOH_OH_H2O_O\tO_CH4_OH_CH3\tOH_CH2_O_CH3\tOH_CH3_CH4_O\t"
00578 "OH_CH3_H2O_CH2\tH2O_CH3_OH_CH4\tOH_CH4_H2O_CH3\tN_OH_O_NH\tN_OH_NO_H\tCH2_NO_HCN_OH\tNH_OH_NH2_O\tNH_OH_H2O_N\tNH_H2O_OH_NH2\tNH_NO_N2_OH\t"
00579 "NH_NO2_N2O_OH\tO_NH2_OH_NH\tO_NH3_OH_NH2\tO_HCN_CN_OH\tO_HS_S_OH\tNH2_OH_NH3_O\tOH_NH3_H2O_NH2\tOH_CN_HCN_O\tOH_HCN_CN_H2O\tOH_NO_NO2_H\t"
00580 "OH_N2O_HNO_NO\tOH_CS_OCS_H\tNO_HNO_N2O_OH\tO_C2H2_C2H_OH\tOH_C2H2_C2H_H2O\te_H2OP_OH_H\te_H3OP_OH_H_H\te_H3OP_OH_H2\te_SiOHP_Si_OH\tH_OH_O_H_H\t"
00581 "H_H2O_OH_H_H\tH_OH_O_H2\tH_H2O_OH_H2\tH_OH_H2O_nu\tHminus_H3OP_OH_H2_H\tH_O_OH_nu\tH2_OH_H2O_H\tH2_O_OH_H\tH2_OH_O_H2_H\tH2_H2O_OH_H2_H\t"
00582 "H2_O2_OH_OH\tH_O2_OH_O\tC_OH_CO_H\tOH_HCN_CO_NH2\tOH_C2H2_CO_CH3\tOH_C2H2_CO_CH3\n");
00583 }
00584
00585 else
00586 {
00587 fprintf(ioQQQ," The keyword CO or OH must appear on the PUNCH CHEMISTRY RATES command.\n");
00588 fprintf( ioQQQ, " Sorry.\n" );
00589 puts( "[Stop in ParsePunch]" );
00590 cdEXIT(EXIT_FAILURE);
00591 }
00592
00593 }
00594 }
00595
00596 else if( nMatch("COMP",chCard) )
00597 {
00598
00599 strcpy( punch.chPunch[punch.npunch], "COMP" );
00600 sprintf( chHeader,
00601 "#nu, comup, comdn\n" );
00602 }
00603
00604 else if( nMatch("COOL",chCard) )
00605 {
00606
00607 strcpy( punch.chPunch[punch.npunch], "COOL" );
00608
00609 sprintf( chHeader,
00610 "#depth cm\tTemp K\tHtot erg/cm3/s\tCtot erg/cm3/s\tcool fracs\n" );
00611 }
00612
00613 else if( nMatch("DYNA",chCard) )
00614 {
00615
00616
00617
00618
00619 if( nMatch( "ADVE" , chCard ) )
00620 {
00621
00622 strcpy( punch.chPunch[punch.npunch], "DYNa");
00623 sprintf( chHeader,
00624 "#advection depth\thtot\tCoolHeat\tdCoolHeatdT\tRecomb\tPhoto\ttimestp\n" );
00625 }
00626 else
00627 {
00628 fprintf( ioQQQ, " I did not recognize a sub keyword on this PUNCH DYNAMICS command.\n" );
00629 fprintf( ioQQQ, " Sorry.\n" );
00630 puts( "[Stop in ParsePunch]" );
00631 cdEXIT(EXIT_FAILURE);
00632 }
00633 }
00634
00635 else if( nMatch("ENTH",chCard) )
00636 {
00637
00638 strcpy( punch.chPunch[punch.npunch], "ENTH" );
00639 sprintf( chHeader,
00640 "#depth\tTotal\tExcit\tIoniz\tBind\tKE\tther+PdV\tmag \n" );
00641 }
00642
00643 else if( nMatch("EXEC",chCard) && nMatch("TIME",chCard) )
00644 {
00645
00646 strcpy( punch.chPunch[punch.npunch], "TIME" );
00647 sprintf( chHeader,
00648 "#zone\tdTime\tElapsed t\n" );
00649 }
00650
00651 else if( nMatch("FEII",chCard) || nMatch("FE II",chCard) )
00652 {
00653
00654
00655 if( nMatch("COLU",chCard) && nMatch("DENS",chCard) )
00656 {
00657
00658 strcpy( punch.chPunch[punch.npunch], "FEcl" );
00659
00660
00661 sprintf( chHeader,
00662 "#FeII: energy\tstat wght\tcol den\n" );
00663 }
00664
00665
00666 else if( nMatch("CONT",chCard) )
00667 {
00668
00669 strcpy( punch.chPunch[punch.npunch], "FEco" );
00670
00671 sprintf( chHeader,
00672 "#FeII: Wl(A)\tInt[erg cm-2 s-1]\n" );
00673 }
00674
00675 else if( nMatch("DEPA",chCard) )
00676 {
00677
00678 sprintf( chHeader,
00679 "#FeII departure coefficient \n" );
00680
00681 if( nMatch(" ALL",chCard) )
00682 {
00683
00684 strcpy( punch.chPunch[punch.npunch], "FE2D" );
00685 }
00686 else
00687 {
00688
00689 strcpy( punch.chPunch[punch.npunch], "FE2d" );
00690 }
00691 }
00692
00693 else if( nMatch("FRED",chCard) )
00694 {
00695
00696 sprintf( chHeader,
00697 "#FeII rates \n" );
00698 strcpy( punch.chPunch[punch.npunch], "FE2f" );
00699 }
00700
00701 else if( nMatch("LEVE",chCard) )
00702 {
00703
00704 sprintf( chHeader,
00705 "#FeII energy(wn)\tstat weight\n" );
00706 strcpy( punch.chPunch[punch.npunch], "FE2l" );
00707 }
00708
00709 else if( nMatch("LINE",chCard) )
00710 {
00711
00712
00713
00714
00715
00716 strcpy( punch.chPunch[punch.npunch], "FEli" );
00717
00718
00719 if( nMatch("SHOR",chCard) )
00720 {
00721 FeII.lgShortFe2 = true;
00722 }
00723 else
00724 {
00725 FeII.lgShortFe2 = false;
00726 }
00727
00728
00729 i = 5;
00730
00731
00732 FeII.fe2thresh = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00733 if( lgEOL )
00734 {
00735 FeII.fe2thresh = 0.;
00736 }
00737
00738
00739 if( FeII.fe2thresh < 0. )
00740 {
00741 FeII.fe2thresh = (float)pow(10.f,FeII.fe2thresh);
00742 }
00743
00744
00745
00746 FeII.fe2ener[0] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00747 if( lgEOL )
00748 {
00749 FeII.fe2ener[0] = 0.;
00750 }
00751
00752 FeII.fe2ener[1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
00753 if( lgEOL )
00754 {
00755 FeII.fe2ener[1] = 1e8;
00756 }
00757
00758 if( FeII.fe2ener[0] < 0. || FeII.fe2ener[1] < 0. )
00759 {
00760 FeII.fe2ener[0] = (float)pow(10.f,FeII.fe2ener[0]);
00761 FeII.fe2ener[1] = (float)pow(10.f,FeII.fe2ener[1]);
00762 }
00763
00764
00765 FeII.fe2ener[0] /= (float)WAVNRYD;
00766 FeII.fe2ener[1] /= (float)WAVNRYD;
00767
00768
00769
00770 sprintf( chHeader,
00771 "#FeII hi\tlo\twl(A)\tI\tTau\n" );
00772 }
00773
00774 else if( nMatch("OPTI",chCard) && nMatch("DEPT",chCard) )
00775 {
00776
00777 sprintf( chHeader,
00778 "#FeII hi\tlow\twl(A)\ttau\n" );
00779 strcpy( punch.chPunch[punch.npunch], "FE2o" );
00780 }
00781
00782 else if( nMatch("POPU",chCard) )
00783 {
00784
00785 sprintf( chHeader,
00786 "#FeII level populations [cm^-3]\n" );
00787
00788
00789
00790 if( nMatch("RELA",chCard) )
00791 {
00792 punch.punarg[punch.npunch][2] = 0.;
00793 }
00794 else
00795 {
00796
00797 punch.punarg[punch.npunch][2] = 1.;
00798 }
00799
00800
00801 if( nMatch(" ALL",chCard) )
00802 {
00803
00804 strcpy( punch.chPunch[punch.npunch], "FE2P" );
00805 punch.punarg[punch.npunch][0] = 0.;
00806 punch.punarg[punch.npunch][1] = (float)FeII.nFeIILevel;
00807 }
00808
00809
00810 else if( nMatch("RANG",chCard) )
00811 {
00812
00813 strcpy( punch.chPunch[punch.npunch], "FE2P" );
00814 ipFFmt = 5;
00815 punch.punarg[punch.npunch][0] =
00816 (float)FFmtRead(chCard,&ipFFmt, INPUT_LINE_LENGTH,&lgEOL);
00817 punch.punarg[punch.npunch][1] =
00818 (float)FFmtRead(chCard,&ipFFmt, INPUT_LINE_LENGTH,&lgEOL);
00819 if( lgEOL || punch.punarg[punch.npunch][0] <0 ||
00820 punch.punarg[punch.npunch][0]> punch.punarg[punch.npunch][1] ||
00821 punch.punarg[punch.npunch][1]> FeII.nFeIILevel)
00822 {
00823 fprintf( ioQQQ, "There must be two numbers on this punch FeII populations range command.\n" );
00824 fprintf( ioQQQ, "These give the lower and upper levels for the range of FeII levels.\n" );
00825 fprintf( ioQQQ, "The first must be less than the second and the second must be <= the number of FeII levels.\n" );
00826 fprintf( ioQQQ, "Sorry.\n" );
00827 puts( "[Stop in ParsePunch]" );
00828 cdEXIT(EXIT_FAILURE);
00829 }
00830 }
00831
00832 else
00833 {
00834
00835 strcpy( punch.chPunch[punch.npunch], "FE2p" );
00836 }
00837 }
00838 else
00839 {
00840 fprintf( ioQQQ, "There must be a second keyword on this PUNCH FEII command.\n" );
00841 fprintf( ioQQQ, "The ones I know about are COLUmn, CONTinuum, DEPArture, FRED, LEVEls, LINE, OPTIcal DEPTh, and POPUlations.\n" );
00842 fprintf( ioQQQ, "Sorry.\n" );
00843 puts( "[Stop in ParsePunch]" );
00844 cdEXIT(EXIT_FAILURE);
00845 }
00846 }
00847
00848
00849
00850
00851 else if( nMatch("CONT",chCard) && !nMatch("XSPE",chCard) )
00852 {
00853
00854
00855 punch.lgPunContinuum = true;
00856
00857
00858
00859 ChkUnits(chCard);
00860
00861 if( nMatch("BINS",chCard) )
00862 {
00863
00864 strcpy( punch.chPunch[punch.npunch], "CONB" );
00865
00866 sprintf( chHeader,
00867 "#Continuum binning, enrOrg, Energy, width of cells\n" );
00868 }
00869
00870 else if( nMatch("DIFF",chCard) )
00871 {
00872
00873 strcpy( punch.chPunch[punch.npunch], "COND" );
00874
00875 sprintf( chHeader,
00876 "#energy\t ConEmitLocal \n" );
00877 }
00878
00879 else if( nMatch("EMIT",chCard) )
00880 {
00881
00882 strcpy( punch.chPunch[punch.npunch], "CONE" );
00883
00884 sprintf( chHeader,
00885 "#Energy\treflec\toutward\ttotal\tline\tcont\n" );
00886 }
00887
00888 else if( nMatch("FINE" , chCard ) )
00889 {
00890 rfield.lgPunchOpacityFine = true;
00891
00892 strcpy( punch.chPunch[punch.npunch], "CONf" );
00893
00894 sprintf( chHeader,
00895 "#Energy\tTransmitted\n" );
00896
00897 ipFFmt = 5;
00898
00899 if( nMatch("RANGE",chCard) )
00900 {
00901
00902 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
00903 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
00904 if( lgEOL )
00905 {
00906 fprintf(ioQQQ,"There must be two numbers, the lower and upper energies in Ryd.\nSorry.\n");
00907 puts( "[Stop in ParsePunch]" );
00908 cdEXIT(EXIT_FAILURE);
00909 }
00910 if( punch.punarg[punch.npunch][0] >=punch.punarg[punch.npunch][1] )
00911 {
00912 fprintf(ioQQQ,"The two energies for the range must be in increasing order.\nSorry.\n");
00913 puts( "[Stop in ParsePunch]" );
00914 cdEXIT(EXIT_FAILURE);
00915 }
00916 }
00917 else
00918 {
00919
00920 punch.punarg[punch.npunch][0] = 0.;
00921 punch.punarg[punch.npunch][1] = 0.;
00922 }
00923
00924 punch.punarg[punch.npunch][2] = (float)FFmtRead(chCard,&ipFFmt,
00925 INPUT_LINE_LENGTH,&lgEOL);
00926
00927
00928 if( lgEOL )
00929 punch.punarg[punch.npunch][2] = 10;
00930
00931 if( punch.punarg[punch.npunch][2] < 1 )
00932 {
00933 fprintf(ioQQQ,"The number of fine opacities to skip must be > 0 \nSorry.\n");
00934 puts( "[Stop in ParsePunch]" );
00935 cdEXIT(EXIT_FAILURE);
00936 }
00937 }
00938
00939 else if( nMatch("GRAI",chCard) )
00940 {
00941
00942 strcpy( punch.chPunch[punch.npunch], "CONG" );
00943
00944 sprintf( chHeader,
00945 "#energy\tgraphite\trest\ttotal\n" );
00946 }
00947
00948 else if( nMatch("INCI",chCard) )
00949 {
00950
00951 strcpy( punch.chPunch[punch.npunch], "CONC" );
00952
00953 sprintf( chHeader,
00954 "#Incident Continuum, Enr\tnFn \n" );
00955 }
00956
00957 else if( nMatch("INTE",chCard) )
00958 {
00959
00960 strcpy( punch.chPunch[punch.npunch], "CONi" );
00961
00962 sprintf( chHeader,
00963 "#Continuum interactions, inc, otslin. otscon, ConInterOut, outlin \n" );
00964
00965 ipFFmt = 3;
00966 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,
00967 INPUT_LINE_LENGTH,&lgEOL);
00968 }
00969
00970 else if( nMatch("IONI",chCard) )
00971 {
00972
00973 strcpy( punch.chPunch[punch.npunch], "CONI" );
00974
00975
00976 ipFFmt = 3;
00977 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,
00978 INPUT_LINE_LENGTH,&lgEOL);
00979
00980
00981 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
00982 if( lgEOL )
00983 {
00984 punch.punarg[punch.npunch][1] = 0.01f;
00985 }
00986
00987
00988
00989 if( nMatch("EVER", chCard ) )
00990 {
00991
00992 punch.lgPunchEveryZone[punch.npunch] = true;
00993 punch.nPunchEveryZone[punch.npunch] = 1;
00994 }
00995 else
00996 {
00997
00998 punch.lgPunchEveryZone[punch.npunch] = false;
00999 punch.nPunchEveryZone[punch.npunch] = 1;
01000 }
01001
01002
01003 sprintf( chHeader,
01004 "#cell(on C scale)\tnu\tflux\tflx*cs\tFinc\totsl\totsc\toutlin\toutcon\trate/tot\tintegral\tline\tcont\n" );
01005 }
01006
01007 else if( nMatch("OUTW",chCard) )
01008 {
01009
01010 if( nMatch("LOCA",chCard) )
01011 {
01012 strcpy( punch.chPunch[punch.npunch], "CONo" );
01013 sprintf( chHeader,
01014 "#Local Out ConInterOut+line SvOt*opc pass*opc\n" );
01015 }
01016 else
01017 {
01018 strcpy( punch.chPunch[punch.npunch], "CONO" );
01019 sprintf( chHeader,
01020 "#Out Con OutIncid OutConD OutLinD OutConS\n" );
01021 }
01022 }
01023
01024 else if( nMatch("TRAN",chCard) )
01025 {
01026
01027 strcpy( punch.chPunch[punch.npunch], "CONT" );
01028
01029 sprintf( chHeader,
01030 "#ener\tTran Contin\ttrn coef\n" );
01031 }
01032
01033 else if( nMatch(" TWO",chCard) )
01034 {
01035
01036 strcpy( punch.chPunch[punch.npunch], "CON2" );
01037
01038 sprintf( chHeader,
01039 "#energy\t n_nu\tnuF_nu \n" );
01040 }
01041
01042 else if( nMatch(" RAW",chCard) )
01043 {
01044
01045 strcpy( punch.chPunch[punch.npunch], "CORA" );
01046
01047 sprintf( chHeader,
01048 "#Raw Con anu\tflux\totslin\totscon\tConRefIncid\tConEmitReflec\tConInterOut\toutlin\tConEmitOut\tline\tcont\tnLines\n" );
01049 }
01050
01051 else if( nMatch("REFL",chCard) )
01052 {
01053
01054 strcpy( punch.chPunch[punch.npunch], "CONR" );
01055
01056 sprintf( chHeader,
01057 "#Reflected cont line total albedo ConID\n" );
01058 }
01059
01060 else
01061 {
01062
01063 strcpy( punch.chPunch[punch.npunch], "CON " );
01064 sprintf( chHeader,
01065 "#Cont nu\tincident\ttrans\tDiffOut\tnet trans\treflc\ttotal\tline\tcont\tnLine\n" );
01066
01067
01068
01069 if( nMatch("EVER", chCard ) )
01070 {
01071
01072 punch.lgPunchEveryZone[punch.npunch] = true;
01073
01074 ipFFmt = 5;
01075 punch.nPunchEveryZone[punch.npunch] = (long)FFmtRead(chCard,&ipFFmt,
01076 INPUT_LINE_LENGTH,&lgEOL);
01077 if( lgEOL )
01078 punch.nPunchEveryZone[punch.npunch] = 1;
01079 }
01080 else
01081 {
01082
01083 punch.lgPunchEveryZone[punch.npunch] = false;
01084 punch.nPunchEveryZone[punch.npunch] = 1;
01085 }
01086 }
01087
01088 }
01089
01090
01091
01092
01093 else if( nMatch("CONV",chCard) )
01094 {
01095 if( nMatch("REAS",chCard) )
01096 {
01097
01098 punch.lgPunConv = true;
01099
01100 }
01101 else if( nMatch("ERRO",chCard) )
01102 {
01103
01104
01105 strcpy( punch.chPunch[punch.npunch], "CNVE" );
01106 sprintf( chHeader,
01107 "#depth\tnPres2Ioniz\tP(cor)\tP(cur)\tP%%error\tNE(cor)\tNE(cur)\tNE%%error\tHeat\tCool\tHC%%error\n" );
01108 }
01109 else
01110 {
01111 fprintf( ioQQQ, "There must be a second keyword on this command.\n" );
01112 fprintf( ioQQQ, "The ones I know about are REASON and ERROR.\n" );
01113 fprintf( ioQQQ, "Sorry.\n" );
01114 puts( "[Stop in ParsePunch]" );
01115 cdEXIT(EXIT_FAILURE);
01116 }
01117 }
01118
01119 else if( nMatch(" DR ",chCard) )
01120 {
01121 punch.lgDROn = true;
01122 }
01123 else if( nMatch("ELEM",chCard) && !nMatch("GAMMA" , chCard) )
01124 {
01125
01126
01127 strcpy( punch.chPunch[punch.npunch], "ELEM" );
01128
01129
01130
01131 nelem = GetElem(chCard);
01132
01133
01134 punch.punarg[punch.npunch][0] = (float)nelem;
01135 ASSERT( nelem>=ipHYDROGEN);
01136
01137
01138 punch.punarg[punch.npunch][1] = 0;
01139 if( nMatch("DENS",chCard) )
01140 punch.punarg[punch.npunch][1] = 1.;
01141
01142
01143 sprintf( chHeader, "#depth");
01144
01145
01146 for(i=0; i<=nelem+1;++i )
01147 {
01148 sprintf( chTemp,
01149 "\t%2s%2li", elementnames.chElementSym[nelem],i+1);
01150 strcat( chHeader, chTemp );
01151 }
01152
01153
01154
01155
01156 if( nelem==ipHYDROGEN )
01157 {
01158 sprintf( chTemp, "\tH2");
01159 strcat( chHeader, chTemp );
01160 }
01161 if( nelem==ipCARBON )
01162 {
01163 sprintf( chTemp, "\tC1\tC1*\tC1**\tC2\tC2*\tCO");
01164 strcat( chHeader, chTemp );
01165 }
01166 else if( nelem==ipOXYGEN )
01167 {
01168 sprintf( chTemp, "\tO1\tO1*\tO1**");
01169 strcat( chHeader, chTemp );
01170 }
01171
01172
01173 strcat( chHeader, "\n");
01174 }
01175
01176 else if( nMatch("FITS",chCard) )
01177 {
01178 strcpy( punch.chPunch[punch.npunch], "FITS" );
01179
01180 }
01181
01182 else if( nMatch("GAMM",chCard) )
01183 {
01184
01185 sprintf( chHeader,
01186 "#Photoionization rates \n" );
01187 if( nMatch("ELEMENT" , chCard ) )
01188 {
01189
01190
01191 strcpy( punch.chPunch[punch.npunch], "GAMe" );
01192
01193
01194 nelem = GetElem(chCard);
01195
01196 punch.punarg[punch.npunch][0] = (float)nelem;
01197
01198
01199 ipFFmt = 5;
01200 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,
01201 INPUT_LINE_LENGTH,&lgEOL) - 1;
01202 if( lgEOL )
01203 NoNumb( chCard );
01204 if( punch.punarg[punch.npunch][1]<0 || punch.punarg[punch.npunch][1]> nelem+1 )
01205 {
01206 fprintf(ioQQQ,"Bad ionization stage - please check Hazy.\nSorry.\n");
01207 puts( "[Stop in ParsePunch]" );
01208 cdEXIT(EXIT_FAILURE);
01209 }
01210 }
01211 else
01212 {
01213
01214 strcpy( punch.chPunch[punch.npunch], "GAMt" );
01215 }
01216
01217 }
01218 else if( nMatch("GRAI",chCard) )
01219 {
01220
01221 if( nMatch("OPAC",chCard) )
01222 {
01223
01224
01225 ChkUnits(chCard);
01226
01227 strcpy( punch.chPunch[punch.npunch], "DUSO" );
01228
01229 sprintf( chHeader,
01230 "#grain ext, abs, scat\n" );
01231 }
01232 else if( nMatch("PHYS",chCard) )
01233 {
01234
01235 strcpy( punch.chPunch[punch.npunch], "DUSP" );
01236 sprintf( chHeader,
01237 "#grain depth temp, charge, drift, frac heat, cool\n" );
01238 }
01239 else if( nMatch(" QS ",chCard) )
01240 {
01241 strcpy( punch.chPunch[punch.npunch], "DUSQ" );
01242 sprintf( chHeader,
01243 "#grain abs, scat, qs\n" );
01244 }
01245 else if( nMatch("TEMP",chCard) )
01246 {
01247
01248 strcpy( punch.chPunch[punch.npunch], "DUST" );
01249
01250 }
01251 else if( nMatch("DRIF",chCard) )
01252 {
01253
01254 strcpy( punch.chPunch[punch.npunch], "DUSV" );
01255
01256 }
01257 else if( nMatch("EXTI",chCard) )
01258 {
01259
01260 strcpy( punch.chPunch[punch.npunch], "DUSE" );
01261
01262 sprintf( chHeader,
01263 "#depth\tA_V(extended)\tA_V(point)\n" );
01264 }
01265 else if( nMatch("CHAR",chCard) )
01266 {
01267
01268 strcpy( punch.chPunch[punch.npunch], "DUSC" );
01269
01270 }
01271 else if( nMatch("HEAT",chCard) )
01272 {
01273
01274 strcpy( punch.chPunch[punch.npunch], "DUSH" );
01275
01276 }
01277 else if( nMatch("POTE",chCard) )
01278 {
01279
01280 strcpy( punch.chPunch[punch.npunch], "DUSP" );
01281
01282 }
01283 else if( nMatch("H2RA",chCard) )
01284 {
01285
01286 strcpy( punch.chPunch[punch.npunch], "DUSR" );
01287
01288 }
01289 else
01290 {
01291 fprintf( ioQQQ, "There must be a second key on this GRAIN command; The options I know about follow (required key in CAPS):\n");
01292 fprintf( ioQQQ, "OPACity, PHYSical conditions, QS , TEMPerature, DRIFt velocity, EXTInction, CHARge, HEATing, POTEntial, H2RAtes\nSorry.\n" );
01293 puts( "[Stop in ParsePunch]" );
01294 cdEXIT(EXIT_FAILURE);
01295 }
01296 }
01297
01298 else if( nMatch("GAUN",chCard) )
01299 {
01300 strcpy( punch.chPunch[punch.npunch], "GAUN" );
01301 sprintf( chHeader,
01302 "#Gaunt factors.\n" );
01303 }
01304 else if( nMatch("GRID",chCard) )
01305 {
01306 strcpy( punch.chPunch[punch.npunch], "GRID" );
01307 }
01308 else if( nMatch( "HIST" , chCard ) )
01309 {
01310
01311 if( nMatch( "PRES" , chCard ) )
01312 {
01313
01314 strcpy( punch.chPunch[punch.npunch], "HISp" );
01315 sprintf( chHeader,
01316 "#iter zon\tdensity\tpres cur\tpres corr\n" );
01317 }
01318
01319 else if( nMatch( "TEMP" , chCard ) )
01320 {
01321
01322 strcpy( punch.chPunch[punch.npunch], "HISt" );
01323 sprintf( chHeader,
01324 "#iter zon\ttemperature\theating\tcooling\n" );
01325 }
01326 }
01327
01328 else if( nMatch("HTWO",chCard) )
01329 {
01330 fprintf(ioQQQ," Sorry, this command has been replaced with the "
01331 "PUNCH H2 CREATION and PUNCH H2 DESTRUCTION commands.\n");
01332 puts( "[Stop in ParsePunch]" );
01333 cdEXIT(EXIT_FAILURE);
01334 }
01335
01336
01337 else if( nMatch("QHEA",chCard) )
01338 {
01339
01340
01341 ((void)0);
01342 }
01343
01344 else if( nMatch("HEAT",chCard) )
01345 {
01346
01347 strcpy( punch.chPunch[punch.npunch], "HEAT" );
01348
01349 sprintf( chHeader,
01350 "#depth cm\tTemp K\tHtot erg/cm3/s\tCtot erg/cm3/s\theat fracs\n" );
01351 }
01352
01353 else if( nMatch("HUMM",chCard) )
01354 {
01355 strcpy( punch.chPunch[punch.npunch], "HUMM" );
01356 sprintf( chHeader,
01357 "#input to DHs routine.\n" );
01358 }
01359
01360 else if( nMatch("HYDR",chCard) )
01361 {
01362
01363 if( nMatch("COND",chCard) )
01364 {
01365 strcpy( punch.chPunch[punch.npunch], "HYDc" );
01366 sprintf( chHeader,
01367 "#depth\tTe\tHDEN\tEDEN\tHI/H\tHII/H\tH2/H\tH2+/H\tH3+/H\tH-/H\n" );
01368
01369 }
01370
01371
01372 else if( nMatch("21 CM",chCard) ||nMatch("21CM",chCard))
01373 {
01374
01375 strcpy( punch.chPunch[punch.npunch], "21CM" );
01376 sprintf( chHeader,
01377 "#depth\tT(spin)\tT(kin)\tT(Lya/21cm)\tnLo\tnHi\tOccLya\ttau(21cm)"
01378 "\ttau(Lya)\topac(21 cm)\tn/Ts\ttau(21)\tTex(Lya)\tN(H0)/Tspin"
01379 "\tSum_F0\tSum_F1\tSum_T21\n" );
01380 }
01381
01382 else if( nMatch("IONI",chCard) )
01383 {
01384
01385 strcpy( punch.chPunch[punch.npunch], "HYDi" );
01386 sprintf( chHeader,
01387 "#hion\tzn\tgam1\tcoll ion1\tRecTot\tHRecCaB\thii/hi\tSim hii/hi"
01388 "\time_Hrecom_long(esc)\tdec2grd\texc pht\texc col\trec eff\tsec ion\n" );
01389 }
01390 else if( nMatch("POPU",chCard) )
01391 {
01392
01393 strcpy( punch.chPunch[punch.npunch], "HYDp" );
01394 sprintf( chHeader,
01395 "#depth\tHI\tHII\tHN 2s 2p\n" );
01396 }
01397 else if( nMatch("LINE",chCard) )
01398 {
01399
01400
01401 strcpy( punch.chPunch[punch.npunch], "HYDl" );
01402 sprintf( chHeader,
01403 "#nup\tnlo\tE(ryd)\ttau\n" );
01404 }
01405 else if( nMatch(" LYA",chCard) )
01406 {
01407
01408 strcpy( punch.chPunch[punch.npunch], "HYDL" );
01409 sprintf( chHeader,
01410 "#depth\tTauIn\tTauTot\tn(2p)/n(1s)\tTexc\tTe\tTex/T\tPesc\tPdes\tpump\topacity\talbedo\n" );
01411 }
01412 else
01413 {
01414 fprintf( ioQQQ, "Punch hydrogen has options: CONDitions, 21 CM, LINE, POPUlations, and IONIzation.\nSorry.\n" );
01415 puts( "[Stop in ParsePunch]" );
01416 cdEXIT(EXIT_FAILURE);
01417 }
01418 }
01419
01420 else if( nMatch("IONI",chCard) )
01421 {
01422 if( nMatch("RATE",chCard) )
01423 {
01424
01425 if( (nelem = GetElem( chCard ) ) < 0 )
01426 {
01427 fprintf( ioQQQ, "There must be an element name on the ionization rates command. Sorry.\n" );
01428 puts( "[Stop in ParsePunch]" );
01429 cdEXIT(EXIT_FAILURE);
01430 }
01431 punch.punarg[punch.npunch][0] = (float)nelem;
01432 strcpy( punch.chPunch[punch.npunch], "IONR" );
01433 sprintf( chHeader,
01434 "#%s depth\teden\tdynamics.Rate\tabund\tTotIonize\tTotRecom\tSource\t ... \n",
01435 elementnames.chElementSym[nelem]);
01436 }
01437 else
01438 {
01439
01440 strcpy( punch.chPunch[punch.npunch], "IONI" );
01441 sprintf( chHeader,
01442 "#Mean ionization distribution\n" );
01443 }
01444 }
01445
01446 else if( nMatch(" IP ",chCard) )
01447 {
01448 strcpy( punch.chPunch[punch.npunch], " IP " );
01449 sprintf( chHeader,
01450 "#ionization potentials, valence shell\n" );
01451 }
01452
01453 else if( nMatch("LEID",chCard) )
01454 {
01455 if( nMatch( "LINE" , chCard ) )
01456 {
01457
01458
01459 strcpy( punch.chPunch[punch.npunch], "LEIL" );
01460 sprintf( chHeader, "#ion\twl\tInt\trel int\n");
01461 }
01462 else
01463 {
01464
01465
01466 strcpy( punch.chPunch[punch.npunch], "LEIS" );
01467 sprintf( chHeader,
01468
01469 "#Leid depth\tA_V(extentd)\tA_V(point)\tTe\tH0\tH2\tCo\tC+\tOo\tCO\tO2\tCH\tOH\te\tHe+\tH+\tH3+\t"
01470
01471 "N(H0)\tN(H2)\tN(Co)\tN(C+)\tN(Oo)\tN(CO)\tN(O2)\tN(CH)\t(OH)\tN(e)\tN(He+)\tN(H+)\tN(H3+)\t"
01472
01473 "H2(Sol)\tH2(FrmGrn)\t"
01474
01475 "G0(DB96)\trate(CO)\trate(C)\theat\tcool\tGrnP\tGr-Gas-Cool\tGr-Gas-Heat\tCOds\tH2dH\tH2vH\tChaT\tCR H\tMgI\tSI\t"
01476 "Si\tFe\tNa\tAl\tC\tC610\tC370\tC157\tC63\tC146\n" );
01477 }
01478 }
01479
01480 else if( nMatch("LINE",chCard) && nMatch("LIST",chCard) )
01481 {
01482
01483 long int j;
01484
01485
01486
01487
01488 if( !lgSecondFilename )
01489 {
01490 fprintf(ioQQQ , "There must be a second file name between "
01491 "double quotes on the PUNCH LINE LIST command. This second"
01492 " file contains the input line list. I did not find it.\nSorry.\n");
01493 puts( "[Stop in ParsePunch]" );
01494 cdEXIT(EXIT_FAILURE);
01495 }
01496
01497
01498
01499 if( (punch.nLineList[punch.npunch] = cdGetLineList( chSecondFilename ,
01500 &punch.chLineListLabel[punch.npunch] ,
01501 &punch.wlLineList[punch.npunch] ) ) < 0 )
01502 {
01503 fprintf(ioQQQ,"DISASTER could not open PUNCH LINE LIST file %s \n",
01504 chSecondFilename );
01505 puts( "[Stop in ParsePunch]" );
01506 cdEXIT(EXIT_FAILURE);
01507 }
01508
01509
01510 strcpy( punch.chPunch[punch.npunch], "LLST" );
01511
01512
01513
01514 if( nMatch("ABSO",chCard) )
01515 {
01516 punch.punarg[punch.npunch][0] = 1;
01517 }
01518 else
01519 {
01520 punch.punarg[punch.npunch][0] = 0;
01521 }
01522
01523
01524 sprintf( chHeader, "#lineslist" );
01525 for( j=0; j<punch.nLineList[punch.npunch]; ++j )
01526 {
01527 sprintf( chTemp, "\t%s ", punch.chLineListLabel[punch.npunch][j] );
01528 strcat( chHeader, chTemp );
01529 sprt_wl( chTemp, punch.wlLineList[punch.npunch][j] );
01530 strcat( chHeader, chTemp );
01531 }
01532 strcat( chHeader, "\n" );
01533 }
01534
01535 else if( nMatch("LINE",chCard) && !nMatch("XSPE",chCard) )
01536 {
01537
01538
01539
01540 ChkUnits(chCard);
01541
01542
01543
01544 if( nMatch("STRU",chCard) ||nMatch("EMIS",chCard) )
01545 {
01546
01547
01548
01549
01550 strcpy( punch.chPunch[punch.npunch], "LINS" );
01551 sprintf( chHeader,
01552 "#Emission line structure.\n" );
01553
01554 punch_line(punch.ipPnunit[punch.npunch],"READ",false, chTemp);
01555 strcat( chHeader, chTemp );
01556 }
01557
01558 else if( nMatch(" RT ", chCard ) )
01559 {
01560
01561 strcpy( punch.chPunch[punch.npunch], "LINR" );
01562
01563
01564 Punch_Line_RT(punch.ipPnunit[punch.npunch],"READ");
01565 }
01566
01567 else if( nMatch("CUMU",chCard) )
01568 {
01569
01570
01571 strcpy( punch.chPunch[punch.npunch], "LINC" );
01572
01573 if( nMatch("RELA",chCard) )
01574 {
01575 lgEOL = true;
01576 sprintf( chHeader,
01577 "#Cumulative emission line relative intensity.\n" );
01578 }
01579 else
01580 {
01581 sprintf( chHeader,
01582 "#Cumulative emission line absolute intensity.\n" );
01583 lgEOL = false;
01584 }
01585
01586 punch_line(punch.ipPnunit[punch.npunch],"READ",lgEOL,chTemp);
01587 strcat( chHeader, chTemp );
01588 }
01589
01590 else if( nMatch("DATA",chCard) )
01591 {
01592
01593 strcpy( punch.chPunch[punch.npunch], "LIND" );
01594 sprintf( chHeader,
01595 "#Emission line data.\n" );
01596 }
01597
01598 else if( nMatch("ARRA",chCard) )
01599 {
01600
01601
01602 strcpy( punch.chPunch[punch.npunch], "LINA" );
01603 sprintf( chHeader,
01604 "#enr\tID\tI(intrinsic)\tI(emergent)\ttype\n" );
01605
01606 }
01607
01608 else if( nMatch("LABE",chCard) )
01609 {
01610
01611 strcpy( punch.chPunch[punch.npunch], "LINL" );
01612 sprintf( chHeader,
01613 "#index\tlabel\twavelength\n" );
01614 }
01615
01616 else if( nMatch("OPTI",chCard) )
01617 {
01618
01619 strcpy( punch.chPunch[punch.npunch], "LINO" );
01620 sprintf( chHeader,
01621 "#species\tenergy\topt depth\tdamp\n" );
01622
01623
01624
01625 strcpy( punch.chConPunEnr[punch.npunch],
01626 "labl" );
01627
01628
01629
01630 if( nMatch("UNIT",chCard) )
01631 ChkUnits(chCard);
01632
01633
01634 ipFFmt = 5;
01635 punch.punarg[punch.npunch][0] = (float)pow(10.,FFmtRead(chCard,&ipFFmt, INPUT_LINE_LENGTH,&lgEOL));
01636
01637 if( lgEOL )
01638 {
01639 punch.punarg[punch.npunch][0] = 0.1f;
01640 }
01641 }
01642
01643 else if( nMatch("POPU",chCard) )
01644 {
01645
01646 strcpy( punch.chPunch[punch.npunch], "LINP" );
01647 sprintf( chHeader,
01648 "#population information\n" );
01649
01650 ipFFmt = 5;
01651 punch.punarg[punch.npunch][0] = (float)pow(10.,FFmtRead(chCard,&ipFFmt, INPUT_LINE_LENGTH,&lgEOL));
01652
01653 if( lgEOL )
01654 {
01655 punch.punarg[punch.npunch][0] = 0.f;
01656 }
01657 }
01658
01659 else if( nMatch("INTE",chCard) )
01660 {
01661
01662 strcpy( punch.chPunch[punch.npunch], "LINI" );
01663 sprintf( chHeader,
01664 "#Emission line intensities per unit inner area\n" );
01665 if( nMatch("COLU",chCard) )
01666 {
01667
01668 strcpy( punch.chPunRltType, "column" );
01669 }
01670 else
01671 {
01672
01673 strcpy( punch.chPunRltType, "array " );
01674 }
01675 if( nMatch("EVER",chCard) )
01676 {
01677 ipFFmt = 3;
01678 punch.LinEvery = (long int)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
01679 punch.lgLinEvery = true;
01680 if( lgEOL )
01681 {
01682 fprintf( ioQQQ,
01683 "There must be a second number, the number of zones to print.\nSorry.\n" );
01684 puts( "[Stop in ParsePunch]" );
01685 cdEXIT(EXIT_FAILURE);
01686 }
01687 }
01688 else
01689 {
01690 punch.LinEvery = geometry.nend[0];
01691 punch.lgLinEvery = false;
01692 }
01693 }
01694 else
01695 {
01696 fprintf( ioQQQ,
01697 "This option for PUNCH LINE is something that I do not understand. Sorry.\n" );
01698 puts( "[Stop in ParsePunch]" );
01699 cdEXIT(EXIT_FAILURE);
01700 }
01701 }
01702
01703 else if( nMatch(" MAP",chCard) )
01704 {
01705 strcpy( punch.chPunch[punch.npunch], "MAP " );
01706 sprintf( chHeader,
01707 "#te, heating, cooling.\n" );
01708
01709
01710
01711
01712 i = 5;
01713 map.MapZone = (long)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
01714 if( lgEOL )
01715 {
01716 map.MapZone = 1;
01717 }
01718
01719
01720 ioMAP = punch.ipPnunit[punch.npunch];
01721
01722 if( nMatch("RANG",chCard) )
01723 {
01724 bool lgLogOn;
01725 map.RangeMap[0] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
01726 if( map.RangeMap[0] <= 10. )
01727 {
01728 map.RangeMap[0] = (float)pow(10.f,map.RangeMap[0]);
01729 lgLogOn = true;
01730 }
01731 else
01732 {
01733 lgLogOn = false;
01734 }
01735
01736 map.RangeMap[1] = (float)FFmtRead(chCard,&i,INPUT_LINE_LENGTH,&lgEOL);
01737 if( lgLogOn )
01738 map.RangeMap[1] = (float)pow(10.f,map.RangeMap[1]);
01739
01740 if( lgEOL )
01741 {
01742 fprintf( ioQQQ, "There must be a zone number, followed by two temperatures, on this line. Sorry.\n" );
01743 puts( "[Stop in ParsePunch]" );
01744 cdEXIT(EXIT_FAILURE);
01745 }
01746 }
01747 }
01748
01749 else if( nMatch("MOLE",chCard) )
01750 {
01751
01752 strcpy( punch.chPunch[punch.npunch], "MOLE" );
01753 sprintf( chHeader,
01754 "#depth\tAV(point)\tAV(extend)\tCO diss rate\tC recom rate");
01755
01756 for(i=0; i<N_H_MOLEC; ++i )
01757 {
01758 sprintf( chTemp, "\t%s", hmi.chLab[i] );
01759 strcat( chHeader, chTemp );
01760 }
01761 for(i=0; i<mole.num_comole_calc; ++i )
01762 {
01763 sprintf(chTemp, "\t%s",COmole[i]->label );
01764 strcat( chHeader, chTemp );
01765 }
01766 strcat( chHeader, "\n");
01767 }
01768
01769 else if( nMatch("OPTICAL",chCard) && nMatch("DEPTH",chCard) )
01770 {
01771
01772
01773 ChkUnits(chCard);
01774 if( nMatch("FINE",chCard) )
01775 {
01776
01777 rfield.lgPunchOpacityFine = true;
01778 strcpy( punch.chPunch[punch.npunch], "OPTf" );
01779 sprintf( chHeader,
01780 "#energy\tTau tot\topacity\n" );
01781 ipFFmt = 5;
01782
01783 if( nMatch("RANGE",chCard) )
01784 {
01785
01786 punch.punarg[punch.npunch][0] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
01787 punch.punarg[punch.npunch][1] = (float)FFmtRead(chCard,&ipFFmt,INPUT_LINE_LENGTH,&lgEOL);
01788 if( lgEOL )
01789 {
01790 fprintf(ioQQQ,"There must be two numbers, the lower and upper energy range in Ryd.\nSorry.\n");
01791 puts( "[Stop in ParsePunch]" );
01792 cdEXIT(EXIT_FAILURE);
01793 }
01794 if( punch.punarg[punch.npunch][0] >=punch.punarg[punch.npunch][1] )
01795 {
01796 fprintf(ioQQQ,"The two energies for the range must be in increasing order.\nSorry.\n");
01797 puts( "[Stop in ParsePunch]" );
01798 cdEXIT(EXIT_FAILURE);
01799 }
01800 }
01801 else
01802 {
01803
01804 punch.punarg[punch.npunch][0] = 0.;
01805 punch.punarg[punch.npunch][1] = 0.;
01806 }
01807
01808 punch.punarg[punch.npunch][2] = (float)FFmtRead(chCard,&ipFFmt,
01809 INPUT_LINE_LENGTH,&lgEOL);
01810
01811 if( lgEOL )
01812 punch.punarg[punch.npunch][2] = 10;
01813 if( punch.punarg[punch.npunch][2] < 1 )
01814 {
01815 fprintf(ioQQQ,"The number of fine opacities to skip must be > 0 \nSorry.\n");
01816 puts( "[Stop in ParsePunch]" );
01817 cdEXIT(EXIT_FAILURE);
01818 }
01819 }
01820 else
01821 {
01822
01823 strcpy( punch.chPunch[punch.npunch], "OPTc" );
01824 sprintf( chHeader,
01825 "#energy\ttotal\tabsorp\tscat\n" );
01826 }
01827
01828 }
01829 else if( nMatch(" OTS",chCard) )
01830 {
01831 strcpy( punch.chPunch[punch.npunch], " OTS" );
01832 sprintf( chHeader,
01833 "#otscon, lin, conOpac LinOpc\n" );
01834 }
01835
01836 else if( nMatch("OVER",chCard) && nMatch(" OVE",chCard) )
01837 {
01838
01839 strcpy( punch.chPunch[punch.npunch], "OVER" );
01840 sprintf( chHeader,
01841 "#depth\tTe\tHtot\thden\teden\t2H_2/H\tHI\tHII\tHeI\tHeII\tHeIII\tCO/C\tC1\tC2\tC3\tC4\tO1\tO2\tO3\tO4\tO5\tO6\tAV(point)\tAV(extend)\n" );
01842 }
01843
01844 else if( nMatch(" PDR",chCard) )
01845 {
01846 strcpy( punch.chPunch[punch.npunch], " PDR" );
01847 sprintf( chHeader,
01848 "#depth\tH colden\tTe\tHI/HDEN\tH2/HDEN\tH2*/HDEN\tCI/C\tCO/C\tH2O/O\tG0\tAV(point)\tAV(extend)\tTauV(point)\n" );
01849 }
01850
01851 else if( nMatch("PHYS",chCard) )
01852 {
01853
01854 strcpy( punch.chPunch[punch.npunch], "PHYS" );
01855 sprintf( chHeader,
01856 "#PhyC depth\tTe\tn(H)\tn(e)\tHtot\taccel\tfillfac\n" );
01857 }
01858
01859 else if( nMatch("POIN",chCard) )
01860 {
01861
01862 punch.lgPunPoint = true;
01863
01864 }
01865
01866 else if( nMatch("PRES",chCard) )
01867 {
01868
01869 strcpy( punch.chPunch[punch.npunch], "PRES" );
01870 sprintf( chHeader,
01871 "#P depth\tPcorrect\tPcurrent\tPIn+Pinteg\tPgas(r0)\tPgas\tPram\tPrad(line)\tPinteg\tV(wind km/s)\tcad(wind km/s)\tP(mag)\tV(turb km/s)\tP(turb)\tconv?\n" );
01872 }
01873
01874 else if( nMatch("RADI",chCard) )
01875 {
01876
01877 sprintf( chHeader, "#NZONE\tradius\tdepth\tdr\n" );
01878
01879 if( nMatch( "OUTE" , chCard ) )
01880 {
01881
01882 strcpy( punch.chPunch[punch.npunch], "RADO" );
01883 }
01884 else
01885 {
01886
01887 strcpy( punch.chPunch[punch.npunch], "RADI" );
01888 }
01889 }
01890
01891 else if( nMatch("RECO",chCard) )
01892 {
01893 if( nMatch("COEF",chCard) )
01894 {
01895
01896
01897
01898 punch.lgioRecom = true;
01899
01900 }
01901
01902 else if( nMatch("EFFI",chCard) )
01903 {
01904
01905 strcpy( punch.chPunch[punch.npunch], "RECE" );
01906 sprintf( chHeader,
01907 "#Recom effic H, Heo, He+\n" );
01908 }
01909
01910 else
01911 {
01912 fprintf( ioQQQ, "No option recognized on this punch recombination command\n" );
01913 fprintf( ioQQQ, "Valid options are COEFFICIENTS, AGN, and EFFICIENCY\nSorry.\n" );
01914 puts( "[Stop in ParsePunch]" );
01915 cdEXIT(EXIT_FAILURE);
01916 }
01917 }
01918
01919
01920 else if( nMatch("RESU",chCard) )
01921 {
01922 strcpy( punch.chPunch[punch.npunch], "RESU" );
01923 if( nMatch("COLU",chCard) )
01924 {
01925
01926 strcpy( punch.chPunRltType, "column" );
01927 }
01928 else
01929 {
01930
01931 strcpy( punch.chPunRltType, "array " );
01932 }
01933
01934
01935 sprintf( chHeader,
01936 "#results of calculation\n" );
01937 }
01938
01939 else if( nMatch("SECO",chCard) )
01940 {
01941
01942 strcpy( punch.chPunch[punch.npunch], "SECO" );
01943 sprintf( chHeader,
01944 "#depth\tIon(H^0)\tDiss(H_2)\tExcit(Lya)\n" );
01945 }
01946
01947 else if( nMatch("SOUR",chCard) )
01948 {
01949 if( nMatch("DEPT",chCard) )
01950 {
01951
01952 strcpy( punch.chPunch[punch.npunch], "SOUD" );
01953 sprintf( chHeader,
01954 "#continuum source function vs depth\n" );
01955 }
01956 else if( nMatch("SPEC",chCard) )
01957 {
01958
01959 strcpy( punch.chPunch[punch.npunch], "SOUS" );
01960 sprintf( chHeader,
01961 "#continuum source function\n" );
01962 }
01963 else
01964 {
01965 fprintf( ioQQQ, "A second keyword must appear on this line.\n" );
01966 fprintf( ioQQQ, "They are DEPTH and SPECTRUM.\n" );
01967 fprintf( ioQQQ, "Sorry.\n" );
01968 puts( "[Stop in ParsePunch]" );
01969 cdEXIT(EXIT_FAILURE);
01970 }
01971 }
01972
01973
01974
01975
01976 else if( nMatch("SPEC",chCard) && nMatch("TRUM",chCard) && !nMatch("XSPE",chCard) )
01977 {
01978
01979
01980 punch.lgPunContinuum = true;
01981
01982
01983 strcpy( punch.chPunch[punch.npunch], "CONN" );
01984
01985 sprintf( chHeader,
01986 "#Cont Enr\tincid nFn\ttrans\tdiff\tlines \n" );
01987
01988
01989
01990 ChkUnits(chCard);
01991
01992
01993
01994 punch.punarg[punch.npunch][0] = (float)punch.cp_npun;
01995
01996 ++punch.cp_npun;
01997
01998 if( punch.cp_npun > LIMPUN )
01999 {
02000 fprintf( ioQQQ,
02001 "The limit to the number of PUNCH options is %ld. Increase LIMPUN in punch.h if more are needed.\nSorry.\n",
02002 LIMPUN );
02003 puts( "[Stop in ParsePunch]" );
02004 cdEXIT(EXIT_FAILURE);
02005 }
02006
02007 }
02008
02009 else if( nMatch("SPEC",chCard) && nMatch("CIAL",chCard) )
02010 {
02011
02012 strcpy( punch.chPunch[punch.npunch], "SPEC" );
02013 sprintf( chHeader, "#Special.\n" );
02014 }
02015
02016 else if( nMatch("TEGR",chCard) )
02017 {
02018
02019 strcpy( punch.chPunch[punch.npunch], "TEGR" );
02020 sprintf( chHeader,
02021 "#zone, te, heat, cool.\n" );
02022 }
02023
02024 else if( nMatch("TEMP",chCard) )
02025 {
02026 strcpy( punch.chPunch[punch.npunch], "TEMP" );
02027 sprintf( chHeader,
02028 "#depth\tte\tdt/dr\td^2T/dr^2\n" );
02029 }
02030
02031 else if( nMatch("TIME",chCard) && nMatch("DEPE",chCard) )
02032 {
02033
02034 strcpy( punch.chPunch[punch.npunch], "TIMD" );
02035
02036 punch.lg_separate_iterations[punch.npunch] = false;
02037
02038 sprintf( chHeader ,
02039 "#elapsed time\ttime step \tscale cont\tn(H)\t<T>\t<H+/H rad>\t<H0/H rad>\t<H2/H rad>\t<He+/H rad>\t<CO/H>\n" );
02040 }
02041
02042 else if( nMatch("TPRE",chCard) )
02043 {
02044
02045
02046 strcpy( punch.chPunch[punch.npunch], "TPRE" );
02047 sprintf( chHeader,
02048 "#zone old temp, guess Tnew, new temp delta \n" );
02049 }
02050
02051 else if( nMatch("WIND",chCard) )
02052 {
02053 strcpy( punch.chPunch[punch.npunch], "WIND" );
02054 sprintf( chHeader,
02055 "#radius\tdepth\tvelocity\tTot accel\tLin accel\tCon accel\tforce mult\n" );
02056 if( nMatch( "TERM" , chCard ) )
02057 {
02058
02059 punch.punarg[punch.npunch][0] = 0.;
02060 }
02061 else
02062 {
02063
02064 punch.punarg[punch.npunch][0] = 1.;
02065 }
02066 }
02067
02068 else if( nMatch("XSPE",chCard) )
02069 {
02070
02071 if( !punch.lgPunLstIter[punch.npunch] )
02072 {
02073 punch.lgPunLstIter[punch.npunch] = true;
02074
02075
02076
02077
02078
02079
02080 }
02081
02082 if( nMatch("ATAB",chCard) )
02083 {
02084
02085 if( nMatch("INCI",chCard) )
02086 {
02087 if( nMatch("ATTE",chCard) )
02088 {
02089
02090 strcpy( punch.chPunch[punch.npunch], "XATT" );
02091 grid.lgOutputTypeOn[2] = true;
02092 }
02093 else if( nMatch("REFL",chCard) )
02094 {
02095
02096 strcpy( punch.chPunch[punch.npunch], "XRFI" );
02097 grid.lgOutputTypeOn[3] = true;
02098 }
02099 else
02100 {
02101
02102 strcpy( punch.chPunch[punch.npunch], "XINC" );
02103 grid.lgOutputTypeOn[1] = true;
02104 }
02105 }
02106 else if( nMatch("DIFF",chCard) )
02107 {
02108 if( nMatch("REFL",chCard) )
02109 {
02110
02111 strcpy( punch.chPunch[punch.npunch], "XDFR" );
02112 grid.lgOutputTypeOn[5] = true;
02113 }
02114 else
02115 {
02116
02117 strcpy( punch.chPunch[punch.npunch], "XDFO" );
02118 grid.lgOutputTypeOn[4] = true;
02119 }
02120 }
02121 else if( nMatch("LINE",chCard) )
02122 {
02123 if( nMatch("REFL",chCard) )
02124 {
02125
02126 strcpy( punch.chPunch[punch.npunch], "XLNR" );
02127 grid.lgOutputTypeOn[7] = true;
02128 }
02129 else
02130 {
02131
02132 strcpy( punch.chPunch[punch.npunch], "XLNO" );
02133 grid.lgOutputTypeOn[6] = true;
02134 }
02135 }
02136 else if( nMatch("SPEC",chCard) )
02137 {
02138 if( nMatch("REFL",chCard) )
02139 {
02140
02141 strcpy( punch.chPunch[punch.npunch], "XREF" );
02142 grid.lgOutputTypeOn[9] = true;
02143 }
02144 else
02145 {
02146
02147 strcpy( punch.chPunch[punch.npunch], "XTRN" );
02148 grid.lgOutputTypeOn[8] = true;
02149 }
02150 }
02151 else
02152 {
02153
02154 strcpy( punch.chPunch[punch.npunch], "XTRN" );
02155 grid.lgOutputTypeOn[8] = true;
02156 }
02157 }
02158 else if( nMatch("MTAB",chCard) )
02159 {
02160
02161 strcpy( punch.chPunch[punch.npunch], "XSPM" );
02162 grid.lgOutputTypeOn[10] = true;
02163 }
02164 else
02165 {
02166 fprintf( ioQQQ, "Support only for xspec atable and xspec mtable.\n" );
02167 cdEXIT( EXIT_FAILURE );
02168 }
02169
02170
02171
02172
02173
02174
02175 }
02176
02177
02178
02179 else if( nMatch("COLU",chCard) && nMatch("DENS",chCard) )
02180 {
02181 if( nMatch("SOME" , chCard ))
02182 {
02183
02184 strcpy( punch.chPunch[punch.npunch], "COLS" );
02185 punch_colden( chHeader , punch.ipPnunit[punch.npunch] , "READ" );
02186 }
02187 else
02188 {
02189
02190
02191 strcpy( punch.chPunch[punch.npunch], "COLU" );
02192 sprintf( chHeader,
02193 "#column densities\n" );
02194 }
02195 }
02196
02197 else
02198 {
02199 fprintf( ioQQQ,
02200 "ParsePunch cannot find a recognized keyword on this PUNCH command line.\nSorry.\n" );
02201 puts( "[Stop in ParsePunch]" );
02202 cdEXIT(EXIT_FAILURE);
02203 }
02204
02205
02206
02207 if( punch.ipPnunit[punch.npunch] == NULL )
02208 {
02209
02210
02211
02212 if( nMatch("XSPE",chCard) || nMatch("FITS",chCard) )
02213 {
02214
02215 if( (punch.ipPnunit[punch.npunch] = fopen( chFilename,"wb" ) ) == NULL )
02216 {
02217 fprintf( ioQQQ, "ParsePunch could not open punch file %s for writing.\nSorry.\n",
02218 chFilename);
02219 puts( "[Stop in ParsePunch]" );
02220 cdEXIT(EXIT_FAILURE);
02221 }
02222
02223 }
02224 else if( punch.lgPunchToSeparateFiles[punch.npunch] && optimize.lgOptimr )
02225 {
02226 char chIndex[4];
02227
02228
02229 sprintf( chIndex, "%li", MAX2( 1, optimize.nOptimiz ) );
02230
02231 strcat( chFilename, chIndex );
02232
02233 fixit();
02234
02235
02236
02237
02238
02239
02240
02241 if( (punch.ipPnunit[punch.npunch] = fopen( chFilename,"w" ) ) == NULL )
02242 {
02243 fprintf( ioQQQ, "ParsePunch could not open punch file %s for writing.\nSorry.\n",
02244 chFilename);
02245 puts( "[Stop in ParsePunch]" );
02246 cdEXIT(EXIT_FAILURE);
02247 }
02248 }
02249 else
02250 {
02251
02252 if( (punch.ipPnunit[punch.npunch] = fopen( chFilename,"w" ) ) == NULL )
02253 {
02254 fprintf( ioQQQ, "ParsePunch could not open punch file %s for writing.\nSorry.\n",
02255 chFilename);
02256 puts( "[Stop in ParsePunch]" );
02257 cdEXIT(EXIT_FAILURE);
02258 }
02259 }
02260
02261
02262
02263
02264 if( nMatch("NO BUFFER",chCard) )
02265 setbuf( punch.ipPnunit[punch.npunch] , NULL );
02266 }
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278 if( nMatch(" H2 ",chCard) )
02279 {
02280
02281 H2_ParsePunch( chCard );
02282 }
02283 else if( nMatch("CONV",chCard) && nMatch("REAS",chCard) )
02284 {
02285
02286
02287 punch.ipPunConv = punch.ipPnunit[punch.npunch];
02288 lgPunConv_noclobber = lgNoClobber[punch.npunch];
02289 punch.lgPunConv = true;
02290 fprintf( punch.ipPunConv,
02291 "# reason for continued iterations\n" );
02292
02293
02294 punch.ipPnunit[punch.npunch] = NULL;
02295 lgNoClobber[punch.npunch] = false;
02296 --punch.npunch;
02297 }
02298 else if( nMatch(" DR ",chCard) )
02299 {
02300 punch.ipDRout = punch.ipPnunit[punch.npunch];
02301
02302 punch.lgDRPLst = punch.lgPunLstIter[punch.npunch];
02303 lgDROn_noclobber = lgNoClobber[punch.npunch];
02304 fprintf( punch.ipDRout,
02305 "#zone\tdepth\tdr\tdr 2 go\treason \n" );
02306
02307
02308 punch.ipPnunit[punch.npunch] = NULL;
02309 lgNoClobber[punch.npunch] = false;
02310 --punch.npunch;
02311 }
02312 else if( nMatch("QHEA",chCard) )
02313 {
02314 gv.QHPunchFile = punch.ipPnunit[punch.npunch];
02315 gv.lgQHPunLast = punch.lgPunLstIter[punch.npunch];
02316 lgQHPunchFile_noclobber = lgNoClobber[punch.npunch];
02317 fprintf( gv.QHPunchFile,
02318 "#Probability distributions from quantum heating routine.\n" );
02319
02320
02321 punch.ipPnunit[punch.npunch] = NULL;
02322 lgNoClobber[punch.npunch] = false;
02323 --punch.npunch;
02324 }
02325 else if( nMatch("POIN",chCard) )
02326 {
02327
02328 punch.ipPoint = punch.ipPnunit[punch.npunch];
02329 lgPunPoint_noclobber = lgNoClobber[punch.npunch];
02330 punch.lgPunPoint = true;
02331 fprintf( punch.ipPoint,
02332 "#pointers. \n" );
02333
02334
02335 punch.ipPnunit[punch.npunch] = NULL;
02336 lgNoClobber[punch.npunch] = false;
02337 --punch.npunch;
02338 }
02339 else if( nMatch("RECO",chCard) && nMatch("COEF",chCard) )
02340 {
02341
02342
02343
02344
02345
02346
02347 punch.ioRecom = punch.ipPnunit[punch.npunch];
02348 lgioRecom_noclobber = lgNoClobber[punch.npunch];
02349
02350 punch.lgioRecom = true;
02351 fprintf( punch.ioRecom,
02352 "#recombination coefficients cm3 s-1 for current density and temperature\n" );
02353
02354
02355 punch.ipPnunit[punch.npunch] = NULL;
02356 lgNoClobber[punch.npunch] = false;
02357 --punch.npunch;
02358 }
02359
02360
02361 if( punch.lgPunHeader && !nMatch("ArNdY38dZ9us4N4e12SEcuQ",chHeader) )
02362 {
02363 fprintf( punch.ipPnunit[punch.npunch], "%s", chHeader );
02364 }
02365
02366
02367 ++punch.npunch;
02368
02369 DEBUG_EXIT( "ParsePunch()" );
02370 return;
02371 }
02372
02373
02374
02375 void PunchFilesInit(void)
02376 {
02377 long int i;
02378 static bool lgFIRST = true;
02379
02380 DEBUG_ENTRY( "PunchFilesInit()" );
02381
02382
02383
02384 if( lgFIRST )
02385 {
02386
02387
02388
02389
02390 bool lgNoClobberDefault = false;
02391 if( grid.lgGrid )
02392 {
02393
02394 lgNoClobberDefault = true;
02395 }
02396
02397 for( i=0; i < LIMPUN; i++ )
02398 {
02399 lgNoClobber[i] = lgNoClobberDefault;
02400 }
02401 lgPunConv_noclobber = lgNoClobberDefault;
02402 lgDROn_noclobber = lgNoClobberDefault;
02403 lgPunPoint_noclobber = lgNoClobberDefault;
02404 lgioRecom_noclobber = lgNoClobberDefault;
02405 lgQHPunchFile_noclobber = lgNoClobberDefault;
02406 lgFIRST = false;
02407 }
02408
02409 for( i=0; i < LIMPUN; i++ )
02410 {
02411 if( !lgNoClobber[i] )
02412 {
02413 punch.ipPnunit[i] = NULL;
02414 }
02415
02416 punch.cp_range_min[i] = 0.;
02417 punch.cp_range_max[i] = 0.;
02418
02419
02420 punch.cp_resolving_power[i] = 0.;
02421 }
02422
02423 if( !lgPunConv_noclobber )
02424 {
02425 punch.ipPunConv = NULL;
02426 punch.lgPunConv = false;
02427 }
02428
02429 if( !lgDROn_noclobber )
02430 {
02431 punch.ipDRout = NULL;
02432 punch.lgDROn = false;
02433 }
02434
02435 if( !lgPunPoint_noclobber )
02436 {
02437 punch.ipPoint = NULL;
02438 punch.lgPunPoint = false;
02439 }
02440
02441 if( !lgQHPunchFile_noclobber )
02442 gv.QHPunchFile = NULL;
02443
02444 if( !lgioRecom_noclobber )
02445 {
02446 punch.ioRecom = NULL;
02447 punch.lgioRecom = false;
02448 }
02449
02450 ioMAP = NULL;
02451
02452 DEBUG_EXIT( "PunchFilesInit()" );
02453 return;
02454 }
02455
02456
02457
02458 void ClosePunchFiles(void)
02459 {
02460 long int i;
02461
02462 DEBUG_ENTRY( "ClosePunchFiles()" );
02463
02464
02465
02466
02467 for( i=0; i < punch.npunch; i++ )
02468 {
02469 if( punch.ipPnunit[i] != NULL && !lgNoClobber[i] )
02470 {
02471 fclose( punch.ipPnunit[i] );
02472 punch.ipPnunit[i] = NULL;
02473 }
02474 }
02475
02476 if( punch.ipPunConv != NULL && !lgPunConv_noclobber )
02477 {
02478 fclose( punch.ipPunConv );
02479 punch.ipPunConv = NULL;
02480 punch.lgPunConv = false;
02481 }
02482 if( punch.ipDRout != NULL && !lgDROn_noclobber )
02483 {
02484 fclose( punch.ipDRout );
02485 punch.ipDRout = NULL;
02486 punch.lgDROn = false;
02487 }
02488 if( punch.ipPoint != NULL && !lgPunPoint_noclobber )
02489 {
02490 fclose( punch.ipPoint );
02491 punch.ipPoint = NULL;
02492 punch.lgPunPoint = false;
02493 }
02494 if( gv.QHPunchFile != NULL && !lgQHPunchFile_noclobber )
02495 {
02496 fclose( gv.QHPunchFile );
02497 gv.QHPunchFile = NULL;
02498 }
02499 if( punch.ioRecom != NULL && !lgioRecom_noclobber )
02500 {
02501 fclose( punch.ioRecom );
02502 punch.ioRecom = NULL;
02503 punch.lgioRecom = false;
02504 }
02505
02506 ioMAP = NULL;
02507
02508 DEBUG_EXIT( "ClosePunchFiles()" );
02509 return;
02510 }
02511
02512
02513
02514
02515
02516 static void ChkUnits( char *chCard)
02517 {
02518
02519 DEBUG_ENTRY( "ChkUnits()" );
02520
02521
02522 if( nMatch("NITS",chCard) )
02523 {
02524 if( nMatch("MICR",chCard) )
02525 {
02526
02527 strcpy( punch.chConPunEnr[punch.npunch], "micr" );
02528 }
02529 else if( nMatch(" KEV",chCard) )
02530 {
02531
02532 strcpy( punch.chConPunEnr[punch.npunch], " kev" );
02533 }
02534 else if( nMatch("CENT",chCard) || nMatch(" CM ",chCard) )
02535 {
02536
02537 strcpy( punch.chConPunEnr[punch.npunch], "cent" );
02538 }
02539 else if( nMatch(" EV ",chCard) )
02540 {
02541
02542 strcpy( punch.chConPunEnr[punch.npunch], " ev " );
02543 }
02544 else if( nMatch("ANGS",chCard) )
02545 {
02546
02547 strcpy( punch.chConPunEnr[punch.npunch], "angs" );
02548 }
02549 else if( nMatch("WAVE",chCard) )
02550 {
02551
02552 strcpy( punch.chConPunEnr[punch.npunch], "wave" );
02553 }
02554 else if( nMatch(" MHZ",chCard) )
02555 {
02556
02557 strcpy( punch.chConPunEnr[punch.npunch], " mhz" );
02558 }
02559 else if( nMatch(" RYD",chCard) )
02560 {
02561
02562
02563 strcpy( punch.chConPunEnr[punch.npunch], "ryd " );
02564 }
02565 else
02566 {
02567 fprintf( ioQQQ, "I did not recognize units on this line.\n" );
02568 fprintf( ioQQQ, "Units are keV, eV, Angstroms, Rydbergs, centimeters, and microns.\nSorry.\n" );
02569 puts( "[Stop in ParsePunch]" );
02570 cdEXIT(EXIT_FAILURE);
02571 }
02572 }
02573 else
02574 {
02575 strcpy( punch.chConPunEnr[punch.npunch], "ryd " );
02576 }
02577
02578 DEBUG_EXIT( "ChkUnits()" );
02579 return;
02580 }