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