00001
00002
00003
00004 #include "cddefines.h"
00005 #include "physconst.h"
00006 #include "geometry.h"
00007 #include "input.h"
00008 #include "prt.h"
00009 #include "atomfeii.h"
00010 #include "mole.h"
00011 #include "rt.h"
00012 #include "phycon.h"
00013 #include "optimize.h"
00014 #include "hcmap.h"
00015 #include "hmi.h"
00016 #include "dense.h"
00017 #include "h2.h"
00018 #include "iterations.h"
00019 #include "conv.h"
00020 #include "secondaries.h"
00021 #include "rfield.h"
00022 #include "ionbal.h"
00023 #include "numderiv.h"
00024 #include "dynamics.h"
00025 #include "iso.h"
00026 #include "predcont.h"
00027 #include "save.h"
00028 #include "stopcalc.h"
00029 #include "opacity.h"
00030 #include "hydrogenic.h"
00031 #include "peimbt.h"
00032 #include "radius.h"
00033 #include "atmdat.h"
00034 #include "continuum.h"
00035 #include "grains.h"
00036 #include "grainvar.h"
00037 #include "parser.h"
00038 #include "lines.h"
00039 #include "monitor_results.h"
00040 #include "thirdparty.h"
00041
00042 void ParseSet(Parser &p)
00043 {
00044 long int ip;
00045 char chString_quotes_lowercase[INPUT_LINE_LENGTH];
00046 bool lgQuotesFound;
00047
00048 DEBUG_ENTRY( "ParseSet()" );
00049
00050
00051
00052
00053 lgQuotesFound = true;
00054 if( p.GetQuote( chString_quotes_lowercase , false ) )
00055 lgQuotesFound = false;
00056
00057
00058 if( p.nMatch("ASSE") && p.nMatch("ABOR") )
00059 {
00060
00061
00062 cpu.setAssertAbort( true );
00063 }
00064
00065 else if( p.nMatch("MONI") &&p.nMatch("SCIE") )
00066 {
00067
00068
00069 lgPrtSciNot = true;
00070 }
00071
00072 else if( p.nMatch("ATOM") && p.nMatch( "DATA") )
00073 {
00074
00075 long int nelem , ion;
00076 bool UNUSED lgAs=false;
00077 bool lgCS=false , lgDR=false;
00078 const char *chMole;
00079
00080
00081 if( p.nMatch( " AS " ) )
00082 lgAs = true;
00083
00084 else if( p.nMatch( " DR " ) )
00085 lgDR = true;
00086
00087 else if( p.nMatch( " CS " ) )
00088 lgCS = true;
00089 else
00090 {
00091
00092 fprintf( ioQQQ, " One of the keywords AS DR or CS must appear to change"
00093 " the transition probabilities, dielectronic recombination rate,"
00094 " or collision strength.\n Sorry.\n" );
00095 cdEXIT(EXIT_FAILURE);
00096 }
00097
00098
00099 if( p.nMatch(" ION") )
00100 {
00101
00102
00103 if( (nelem = p.GetElem())<0 )
00104 {
00105 fprintf( ioQQQ, " An element name must appear on this line\n Sorry.\n" );
00106 cdEXIT(EXIT_FAILURE);
00107 }
00108
00109
00110 ion = (long int)p.FFmtRead();
00111 if( !p.lgEOL() && (ion< 1 || ion>nelem+1) )
00112 {
00113 fprintf( ioQQQ, " The ionization stage is not valid\n Sorry.\n" );
00114 cdEXIT(EXIT_FAILURE);
00115 }
00116
00117
00118 if( nelem==ipSULPHUR && lgDR )
00119 {
00120
00121
00122
00123
00124
00125 if( p.nMatch( " MIX" ) )
00126
00127 ionbal.nDR_S_guess = 0;
00128 else if( p.nMatch( "PURE" ) )
00129
00130 ionbal.nDR_S_guess = 1;
00131 else if( p.nMatch( "SCAL" ) )
00132 {
00133
00134 ionbal.nDR_S_guess = 2;
00135 ionbal.DR_S_scale[0] = (realnum)p.FFmtRead();
00136 if( p.lgEOL() )
00137 p.NoNumb("sulphur scale");
00138 for( ion=1; ion<5; ++ion )
00139 {
00140
00141
00142 ionbal.DR_S_scale[ion] = (realnum)p.FFmtRead();
00143 if( p.lgEOL() )
00144 ionbal.DR_S_scale[ion] = ionbal.DR_S_scale[ion-1];
00145 }
00146 }
00147 else
00148 {
00149
00150 fprintf(
00151 ioQQQ, " One of the keywords MIX, PURE, or SCALe must"
00152 "appear on the set atomic physics sulphur dr command.\n"
00153 "Sorry.\n" );
00154 cdEXIT(EXIT_FAILURE);
00155 }
00156 }
00157 else
00158 {
00159 fprintf( ioQQQ, " None of the valid set atomic data atoms/ions were found\n Sorry.\n" );
00160 cdEXIT(EXIT_FAILURE);
00161 }
00162 }
00163 else
00164 {
00165
00166 if( p.nMatch(" H2 ") )
00167 {
00168
00169 chMole = "H2";
00170 }
00171 else
00172 {
00173
00174 fprintf( ioQQQ, " No molecule was on this SET ATOMIC DATA command.\n Sorry.\n" );
00175 fprintf( ioQQQ, " Use SET ATOMIC DATA ION to change an ion.\n Sorry.\n" );
00176 cdEXIT(EXIT_FAILURE);
00177 }
00178
00179 if( strcmp( chMole , "H2" )==0 )
00180 {
00181 if( p.nMatch(" H " ) && lgCS )
00182 {
00183
00184 ion = (long int)p.FFmtRead();
00185 if( ion!=2 )
00186 TotalInsanity();
00187 long int nYear = (long)p.FFmtRead();
00188 if( p.lgEOL() )
00189 p.NoNumb("collison data set (year)");
00190 if( nYear == 1999 )
00191
00192
00193
00194 h2.lgH2_H_coll_07 = false;
00195 else if( nYear == 2007 )
00196
00197
00198
00199 h2.lgH2_H_coll_07 = true;
00200 else
00201 {
00202
00203 fprintf(ioQQQ," the SET ATOMIC DATA MOLECULE H2"
00204 " H CS command must have year 1999 or 2007.\n" );
00205 cdEXIT(EXIT_FAILURE);
00206 }
00207 }
00208 else if( p.nMatch(" HE " ) && lgCS )
00209 {
00210
00211 if( p.nMatch("ORNL" ) )
00212 {
00213
00214
00215 mole.lgH2_He_ORNL = true;
00216 }
00217 else if( p.nMatch( "BOUR") )
00218 {
00219
00220
00221
00222 mole.lgH2_He_ORNL = false;
00223 }
00224 else
00225 {
00226
00227 fprintf(ioQQQ," the SET ATOMIC DATA MOLECULE H2"
00228 "He CS command must have ORNL or Le BOURlot.\n" );
00229 cdEXIT(EXIT_FAILURE);
00230 }
00231 }
00232 }
00233 else
00234 TotalInsanity();
00235 }
00236 }
00237
00238 else if( p.nMatch(" CHA") && !p.nMatch( "HO ") )
00239 {
00240
00241
00242 atmdat.HCTAlex = p.FFmtRead();
00243 if( p.lgEOL() )
00244 {
00245 p.NoNumb("minimum charge transfer rate");
00246 }
00247 if( atmdat.HCTAlex < 0. )
00248 {
00249 atmdat.HCTAlex = pow(10.,atmdat.HCTAlex);
00250 }
00251 }
00252
00253 else if( p.nMatch("CHEM") && !p.nMatch( "HO ") )
00254 {
00255
00256 if( p.nMatch("FEDE") )
00257 {
00258 if( p.nMatch( " ON " ) )
00259 {
00260
00261
00262 co.lgFederman = true;
00263 }
00264 else if( p.nMatch( " OFF" ) )
00265 {
00266 co.lgFederman = false;
00267 }
00268 else
00269 {
00270
00271 co.lgFederman = true;
00272 }
00273 }
00274
00275 else if( p.nMatch(" NON") && p.nMatch( "EQUI"))
00276 {
00277
00278
00279
00280
00281
00282 co.lgNonEquilChem = true;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 if( p.nMatch("NEUT") )
00293 {
00294 if( p.nMatch( " ON " ) )
00295 {
00296
00297
00298 co.lgNeutrals = true;
00299 }
00300 else if( p.nMatch( " OFF" ) )
00301 {
00302 co.lgNeutrals = false;
00303 }
00304 else
00305 {
00306
00307 co.lgNeutrals = true;
00308 }
00309 }
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 else if( p.nMatch("PROT") && p.nMatch( "ELIM") )
00327 {
00328 if( p.nMatch( " ON " ) )
00329 {
00330
00331
00332 co.lgProtElim = true;
00333 }
00334 else if( p.nMatch( " OFF" ) )
00335 {
00336 co.lgProtElim = false;
00337 }
00338 else
00339 {
00340
00341 co.lgProtElim = true;
00342 }
00343 }
00344
00345 else
00346 {
00347
00348 fprintf( ioQQQ, " There should have been an option on this SET CHEMISTRY command.\n" );
00349 fprintf( ioQQQ, " consult Hazy to find valid options.\n Sorry.\n" );
00350 cdEXIT(EXIT_FAILURE);
00351 }
00352 }
00353
00354
00355 else if( p.nMatch("COLL") && p.nMatch("STRE") && p.nMatch("AVER") )
00356 {
00357 if( p.nMatch(" OFF") )
00358 {
00359 iso.lgCollStrenThermAver = false;
00360 }
00361 else
00362 {
00363
00364 iso.lgCollStrenThermAver = true;
00365 }
00366 }
00367
00368 else if( p.nMatch("COVE") )
00369 {
00370 iterations.lgConverge_set = true;
00371
00372 if( p.nMatch("FAST") )
00373 {
00374 iterations.lim_zone = 1;
00375 iterations.lim_iter = 0;
00376 }
00377 else
00378 {
00379 iterations.lim_zone = 10;
00380 iterations.lim_iter = 1;
00381 }
00382 }
00383
00384 else if( p.nMatch("CSUP") )
00385 {
00386
00387 secondaries.SetCsupra = (realnum)p.FFmtRead();
00388 secondaries.lgCSetOn = true;
00389 if( p.lgEOL() )
00390 {
00391 p.NoNumb("secondary ionization rate");
00392 }
00393 secondaries.SetCsupra = (realnum)pow((realnum)10.f,secondaries.SetCsupra);
00394 }
00395
00396 else if( p.nMatch(" D/H") )
00397 {
00398
00399 hydro.D2H_ratio = p.FFmtRead();
00400 if( hydro.D2H_ratio <= 0. || p.nMatch( " LOG") )
00401 {
00402 hydro.D2H_ratio = pow(10.,hydro.D2H_ratio);
00403 }
00404 if( p.lgEOL() )
00405 {
00406 p.NoNumb("D to H ratio");
00407 }
00408 }
00409
00410 else if( p.nMatch( " HO " ) && p.nMatch( "CHAR" ) )
00411 {
00412
00413
00414 if( p.nMatch( "CHEM" ) )
00415 {
00416
00417 ionbal.lgHO_ct_chem = true;
00418 }
00419 else if( p.nMatch( "IONI" ) )
00420 {
00421
00422 ionbal.lgHO_ct_chem = false;
00423 }
00424 else
00425 {
00426 fprintf( ioQQQ, " I did not recognize a subkey on this SET OH CHARge transfer line.\n" );
00427 fprintf( ioQQQ, " Valid keys are CHEMistry and IONIzation.\n" );
00428 cdEXIT(EXIT_FAILURE);
00429 }
00430 }
00431
00432 else if( p.nMatch("12C1") )
00433 {
00434
00435
00436 co.C12_C13_isotope_ratio = (realnum)p.FFmtRead();
00437 co.C12_C13_isotope_ratio = (realnum)p.FFmtRead();
00438
00439
00440 co.C12_C13_isotope_ratio = (realnum)p.FFmtRead();
00441 if( p.lgEOL() )
00442 p.NoNumb("12C to 13C abundance ratio");
00443
00444 if( co.C12_C13_isotope_ratio <= 0. || p.nMatch( " LOG") )
00445 co.C12_C13_isotope_ratio = (realnum)pow((realnum)10.f,co.C12_C13_isotope_ratio);
00446 }
00447
00448
00449 else if( p.nMatch("DYNA") )
00450 {
00451
00452 if( p.nMatch("ADVE") && p.nMatch("LENG") )
00453 {
00454
00455 dynamics.AdvecLengthInit = p.FFmtRead();
00456 if( p.lgEOL() )
00457 p.NoNumb("advection length");
00458
00459
00460 if( p.nMatch("FRAC") )
00461 {
00462
00463 if( dynamics.AdvecLengthInit <= 0. )
00464 dynamics.AdvecLengthInit = pow(10.,dynamics.AdvecLengthInit);
00465
00466
00467 dynamics.AdvecLengthInit *= -1.;
00468 }
00469 else
00470 {
00471
00472
00473 dynamics.AdvecLengthInit = pow(10.,dynamics.AdvecLengthInit);
00474 }
00475 }
00476 else if( p.nMatch("PRES") && p.nMatch("MODE") )
00477 {
00478 dynamics.lgSetPresMode = true;
00479 if( p.nMatch("SUBS") )
00480 {
00481
00482 strcpy( dynamics.chPresMode , "subsonic" );
00483 }
00484 else if( p.nMatch("SUPE") )
00485 {
00486
00487 strcpy( dynamics.chPresMode , "supersonic" );
00488 }
00489 else if( p.nMatch("STRO") )
00490 {
00491
00492 strcpy( dynamics.chPresMode , "strongd" );
00493 }
00494 else if( p.nMatch("ORIG") )
00495 {
00496
00497 strcpy( dynamics.chPresMode , "original" );
00498 }
00499 }
00500 else if( p.nMatch("ANTI") && p.nMatch("DEPT") )
00501 {
00502 dynamics.lgSetPresMode = true;
00503 strcpy( dynamics.chPresMode , "antishock" );
00504
00505
00506 dynamics.ShockDepth = p.FFmtRead();
00507 if( p.lgEOL() )
00508 p.NoNumb("antishock depth");
00509 dynamics.ShockDepth = pow( 10., dynamics.ShockDepth );
00510 }
00511 else if( p.nMatch("ANTI") && p.nMatch("MACH") )
00512 {
00513 dynamics.lgSetPresMode = true;
00514 strcpy( dynamics.chPresMode , "antishock-by-mach" );
00515
00516
00517 dynamics.ShockMach = p.FFmtRead();
00518 if( p.lgEOL() )
00519 p.NoNumb("antishock-by-mach");
00520 }
00521 else if( p.nMatch("RELA") )
00522 {
00523
00524
00525 dynamics.n_initial_relax = (long int)p.FFmtRead();
00526 if( p.lgEOL() )
00527 p.NoNumb("relaxation cycles before start of dynamics");
00528 else if( dynamics.n_initial_relax < 2 )
00529 {
00530 fprintf(ioQQQ," First iteration to relax dynamics must be > 1."
00531 "It was %li. Sorry.\n",
00532 dynamics.n_initial_relax );
00533 cdEXIT(EXIT_FAILURE);
00534 }
00535 }
00536 else if( p.nMatch("SHOC") && p.nMatch("DEPT") )
00537 {
00538 dynamics.lgSetPresMode = true;
00539 strcpy( dynamics.chPresMode , "shock" );
00540
00541
00542 dynamics.ShockDepth = p.FFmtRead();
00543 if( p.lgEOL() )
00544 p.NoNumb("shock depth");
00545 dynamics.ShockDepth = pow( 10., dynamics.ShockDepth );
00546 }
00547 else if( p.nMatch("POPU") && p.nMatch("EQUI") )
00548 {
00549
00550
00551 dynamics.lgEquilibrium = true;
00552 }
00553 else
00554 {
00555
00556 fprintf( ioQQQ, " There should have been an option on this SET DYNAMICS command.\n" );
00557 fprintf( ioQQQ, " consult Hazy to find valid options.\n Sorry.\n" );
00558 cdEXIT(EXIT_FAILURE);
00559 }
00560 }
00561
00562 else if( p.nMatch("DIDZ") )
00563 {
00564
00565
00566
00567 radius.drChange = (realnum)p.FFmtRead();
00568 if( radius.drChange <= 0. )
00569 {
00570 radius.drChange = (realnum)pow((realnum)10.f,radius.drChange);
00571 }
00572 if( p.lgEOL() )
00573 {
00574 p.NoNumb("largest optical depth allowed in zone");
00575 }
00576 }
00577
00578
00579 else if( p.nMatch("EDEN") )
00580 {
00581
00582
00583 if( p.nMatch("CONV") || p.nMatch("ERRO") )
00584 {
00585
00586
00587 conv.EdenErrorAllowed = p.FFmtRead();
00588 if( p.lgEOL() )
00589 {
00590 p.NoNumb("electron density error allowed");
00591 }
00592
00593 if( conv.EdenErrorAllowed < 0. )
00594 {
00595 conv.EdenErrorAllowed = pow(10.,conv.EdenErrorAllowed);
00596 }
00597 }
00598 else
00599 {
00600
00601
00602 dense.EdenSet = (realnum)pow(10.,p.FFmtRead());
00603 if( p.lgEOL() )
00604 {
00605 p.NoNumb("electron density");
00606 }
00607
00608
00609 phycon.lgPhysOK = false;
00610 }
00611 }
00612
00613 else if( p.nMatch("FINE") && p.nMatch("CONT") )
00614 {
00615
00616
00617
00618
00619
00620 if( (rfield.fine_opac_nelem = p.GetElem())<0 )
00621 {
00622 fprintf( ioQQQ, " An element name must appear on this line\n Sorry.\n" );
00623 cdEXIT(EXIT_FAILURE);
00624 }
00625
00626
00627 rfield.fine_opac_nresolv = (long int)p.FFmtRead();
00628 if( rfield.fine_opac_nresolv< 1 )
00629 {
00630 fprintf( ioQQQ, " The number of resolution elements within FWHM of line must appear\n Sorry.\n" );
00631 cdEXIT(EXIT_FAILURE);
00632 }
00633
00634
00635
00636 if( !p.lgEOL() )
00637 {
00638 realnum lower_limit = (realnum)p.FFmtRead();
00639 if( lower_limit < 0 )
00640 lower_limit = pow((realnum)10.f, lower_limit);
00641
00642 if( lower_limit > 0.2f )
00643 fprintf( ioQQQ, " The fine continuum lower limit is quite high (%f Ryd). Please check.\n", lower_limit );
00644
00645
00646 rfield.fine_ener_lo = MAX2( rfield.emm, lower_limit );
00647
00648 if( !p.lgEOL() )
00649 {
00650 realnum upper_limit = (realnum)p.FFmtRead();
00651 if( upper_limit < 0 )
00652 upper_limit = pow((realnum)10.f, upper_limit);
00653
00654 if( upper_limit < 10.f )
00655 fprintf( ioQQQ, " The fine continuum upper limit is quite low (%f Ryd). Please check.\n", upper_limit );
00656
00657
00658 rfield.fine_ener_hi = MIN2( rfield.egamry, upper_limit );
00659 }
00660 }
00661 }
00662
00663
00664 else if( p.nMatch("GRAI") && !p.nMatch(" H2 ") )
00665 {
00666 if( p.nMatch("HEAT") )
00667 {
00668
00669 gv.GrainHeatScaleFactor = (realnum)p.FFmtRead();
00670
00671 phycon.lgPhysOK = false;
00672 if( p.lgEOL() )
00673 {
00674 p.NoNumb("grain heating");
00675 }
00676 }
00677 else
00678 {
00679 fprintf( ioQQQ, " A keyword must appear on the SET GRAIN line - options are HEAT \n Sorry.\n" );
00680 cdEXIT(EXIT_FAILURE);
00681 }
00682 }
00683
00684
00685
00686 else if( p.nMatch("LEID") && p.nMatch("HACK") )
00687 {
00688 if( p.nMatch( "H2* " ) && p.nMatch( " OFF" ) )
00689 {
00690
00691 hmi.lgLeiden_Keep_ipMH2s = false;
00692
00693 phycon.lgPhysOK = false;
00694 }
00695 else if( p.nMatch( "CR " ) && p.nMatch( " OFF" ) )
00696 {
00697
00698 hmi.lgLeidenCRHack = false;
00699
00700 }
00701 else if( p.nMatch("RATE") && p.nMatch("UMIS"))
00702 {
00703
00704
00705
00706 co.lgUMISTrates = false;
00707 }
00708 }
00709
00710
00711 else if( p.nMatch("LAMD") )
00712 {
00713 if( p.nMatch(" OFF") )
00714 atmdat.lgLamdaOn = false;
00715 else if( p.nMatch(" ON ") )
00716 {
00717 atmdat.lgLamdaOn = true;
00718 fprintf( ioQQQ, " The version of LAMDA distributed with this version of Cloudy is as accessed on Feb. 9, 2010.\n");
00719 fprintf( ioQQQ, " Publications using LAMDA results should refer to Schoeier et al 2005, A&A 432, 369-379.\n");
00720 }
00721 else
00722 {
00723
00724 fprintf( ioQQQ, " There should have been an option on this SET LAMDA command.\n" );
00725 fprintf( ioQQQ, " consult Hazy to find valid options.\n Sorry.\n" );
00726 cdEXIT(EXIT_FAILURE);
00727 }
00728 }
00729
00730
00731 else if( p.nMatch(" H2 ") )
00732 {
00733 ip = (long int)p.FFmtRead();
00734 if( ip != 2 )
00735 {
00736 fprintf( ioQQQ, " The first number on this line must be the 2 in H2\n Sorry.\n" );
00737 cdEXIT(EXIT_FAILURE);
00738 }
00739
00740
00741 if( p.nMatch("SOLO") || ( p.nMatch("SMAL")&&p.nMatch("MODE") ) )
00742 {
00743 if( p.nMatch("SOLO") )
00744 {
00745
00746 fprintf(ioQQQ,"PROBLEM - *set H2 Solomon* has been changed to *set H2 small model*."\
00747 " This is OK for now but it may not work in a future version.\n");
00748 }
00749 if( p.nMatch("TH85") )
00750 {
00751
00752 hmi.chH2_small_model_type = 'T';
00753 }
00754 else if( p.nMatch( " BHT" ) )
00755 {
00756
00757
00758
00759 hmi.chH2_small_model_type = 'H';
00760 }
00761 else if( p.nMatch( "BD96" ) )
00762 {
00763
00764
00765
00766 hmi.chH2_small_model_type = 'B';
00767 }
00768 else if( p.nMatch( "ELWE" ) )
00769 {
00770
00771
00772
00773 hmi.chH2_small_model_type = 'E';
00774 }
00775 else
00776 {
00777 fprintf( ioQQQ, " One of the keywords TH85, _BHT, BD96 or ELWErt must appear.\n Sorry.\n" );
00778 cdEXIT(EXIT_FAILURE);
00779 }
00780 }
00781
00782
00783
00784 if( p.nMatch("GRAI") && p.nMatch("FORM") && p.nMatch("PUMP") )
00785 {
00786 if( p.nMatch( "DB96" ) )
00787 {
00788
00789 hmi.chGrainFormPump = 'D';
00790 }
00791 else if( p.nMatch( "TAKA" ) )
00792 {
00793
00794
00795 hmi.chGrainFormPump = 'T';
00796 }
00797 else if( p.nMatch( "THER" ) )
00798 {
00799
00800
00801 hmi.chGrainFormPump = 't';
00802 }
00803 else
00804 {
00805 fprintf( ioQQQ, " The grain form pump option is wrong.\n Sorry.\n" );
00806 cdEXIT(EXIT_FAILURE);
00807 }
00808 }
00809
00810
00811 else if( p.nMatch("JURA") )
00812 {
00813 if( p.nMatch("TH85") )
00814 {
00815
00816 hmi.chJura = 'T';
00817 }
00818 else if( p.nMatch( "CT02" ) )
00819 {
00820
00821 hmi.chJura = 'C';
00822 }
00823 else if( p.nMatch( "SN99" ) )
00824 {
00825
00826 hmi.chJura = 'S';
00827 }
00828 else if( p.nMatch( "RATE" ) )
00829 {
00830
00831
00832
00833
00834 hmi.chJura = 'F';
00835 hmi.rate_h2_form_grains_set = pow(10.,p.FFmtRead() );
00836 if( p.lgEOL() )
00837 {
00838
00839
00840 hmi.rate_h2_form_grains_set = 3e-17;
00841 }
00842 }
00843 else if( p.nMatch( "SCAL" ) )
00844 {
00845
00846 hmi.ScaleJura = (realnum)p.FFmtRead();
00847
00848 if( p.nMatch( " LOG" ) || hmi.ScaleJura < 0. )
00849 {
00850 hmi.ScaleJura = (realnum)pow( 10., (double)hmi.ScaleJura );
00851 }
00852 if( p.lgEOL() )
00853 p.NoNumb("scale for Jura rate");
00854
00855
00856 if( optimize.lgVarOn )
00857 {
00858 optimize.nvarxt[optimize.nparm] = 1;
00859 strcpy( optimize.chVarFmt[optimize.nparm], "SET H2 JURA SCALE %f LOG" );
00860
00861
00862 optimize.nvfpnt[optimize.nparm] = input.nRead;
00863
00864
00865 optimize.vparm[0][optimize.nparm] = (realnum)log10(hmi.ScaleJura);
00866 optimize.vincr[optimize.nparm] = 0.3f;
00867
00868 ++optimize.nparm;
00869 }
00870 }
00871 else
00872 {
00873 fprintf( ioQQQ, " The Jura rate option is wrong.\n Sorry.\n" );
00874 cdEXIT(EXIT_FAILURE);
00875 }
00876 }
00877
00878
00879 else if( p.nMatch(" TAD") )
00880 {
00881 hmi.Tad = (realnum)p.FFmtRead();
00882 if( p.lgEOL() )
00883 p.NoNumb("temperature for binding energy");
00884
00885 if( hmi.Tad <=10. && !p.nMatch("LINE") )
00886 hmi.Tad = (realnum)pow((realnum)10.f,hmi.Tad);
00887 }
00888
00889 else if( p.nMatch("FRAC") )
00890 {
00891
00892
00893
00894
00895 hmi.H2_frac_abund_set = p.FFmtRead();
00896 if( p.lgEOL() )
00897 p.NoNumb("H2 fractional abundance");
00898
00899
00900 if( hmi.H2_frac_abund_set <= 0. )
00901 hmi.H2_frac_abund_set = pow(10., hmi.H2_frac_abund_set);
00902
00903
00904 hmi.H2_frac_abund_set = MIN2(0.49999 , hmi.H2_frac_abund_set );
00905 }
00906
00907 else if( p.nMatch("FORM") && p.nMatch("SCAL") )
00908 {
00909
00910
00911
00912
00913
00914 hmi.H2_formation_scale = p.FFmtRead();
00915 if( p.lgEOL() )
00916 p.NoNumb("H2 formation scale");
00917
00918
00919 if( hmi.H2_formation_scale <= 0. )
00920 hmi.H2_formation_scale = pow(10., hmi.H2_frac_abund_set);
00921 }
00922
00923 }
00924
00925
00926
00927
00928 else if( p.nMatch("HCOR") )
00929 {
00930 dense.HCorrFac = (realnum)p.FFmtRead();
00931 if( p.lgEOL() )
00932 p.NoNumb("scale for H0 correction to e- collision rate");
00933 }
00934
00935 else if( p.nMatch(" PAH") )
00936 {
00937
00938 if( lgQuotesFound )
00939 {
00940
00941 gv.chPAH_abundance = chString_quotes_lowercase;
00942 }
00943 else if( p.nMatch("CONS" ) )
00944 {
00945
00946 gv.chPAH_abundance = "CON";
00947 }
00948 else if( p.nMatch("BAKE") )
00949 {
00950
00951
00952 gv.lgBakesPAH_heat = true;
00953
00954 phycon.lgPhysOK = false;
00955 }
00956 else
00957 {
00958 fprintf( ioQQQ, " a string, or one of the keywords BAKES, or CONStant must appear.\n Sorry." );
00959 cdEXIT(EXIT_FAILURE);
00960 }
00961 }
00962
00963 else if( p.nMatch("PRES") && p.nMatch("IONI") )
00964 {
00965
00966
00967 conv.limPres2Ioniz = (long)p.FFmtRead();
00968 if( p.lgEOL() )
00969 {
00970 p.NoNumb("number of calls from pressure to ion solver");
00971 }
00972 else if( conv.limPres2Ioniz <= 0 )
00973 {
00974 fprintf( ioQQQ, " The limit must be greater than zero.\n Sorry." );
00975 cdEXIT(EXIT_FAILURE);
00976 }
00977 }
00978
00979 else if( p.nMatch("PRES") )
00980 {
00981
00982 if( p.nMatch("CONV") )
00983 {
00984
00985
00986 conv.PressureErrorAllowed = (realnum)p.FFmtRead();
00987 if( p.lgEOL() )
00988 p.NoNumb("pressure convergence tolerance");
00989
00990 if( conv.PressureErrorAllowed < 0. )
00991 conv.PressureErrorAllowed = (realnum)pow((realnum)10.f,conv.PressureErrorAllowed);
00992 }
00993
00994 else
00995 {
00996
00997
00998 fprintf( ioQQQ, " I didn\'t recognize a key on this SET PRESSURE line.\n" );
00999 fprintf( ioQQQ, " The ones I know about are: CONVergence.\n" );
01000 cdEXIT(EXIT_FAILURE);
01001 }
01002 }
01003 else if( p.nMatch("RECOMBIN") )
01004 {
01005
01006 if( p.nMatch("DIELECTR") )
01007 {
01008 if( p.nMatch("KLUD") )
01009 {
01010
01011 if( p.nMatch(" OFF") )
01012 {
01013 ionbal.lg_guess_coef = false;
01014 }
01015
01016 else if( p.nMatch("NOISE") )
01017 {
01018 ionbal.guess_noise = (realnum)p.FFmtRead();
01019 if( p.lgEOL() )
01020 ionbal.guess_noise = 2.;
01021
01022
01023 init_genrand( (unsigned)time( NULL ) );
01024 }
01025 else
01026 {
01027 fprintf( ioQQQ, " key OFF or NOISE must appear.\n" );
01028 cdEXIT(EXIT_FAILURE);
01029 }
01030 }
01031
01032 else if( p.nMatch("BURG") )
01033 {
01034
01035 if( p.nMatch(" ON ") )
01036 {
01037
01038 ionbal.lgSupDie[0] = true;
01039 }
01040 else if( p.nMatch(" OFF") )
01041 {
01042
01043 ionbal.lgSupDie[0] = false;
01044 }
01045 else
01046 {
01047 fprintf( ioQQQ, " flag ON or OFF must appear.\n" );
01048 cdEXIT(EXIT_FAILURE);
01049 }
01050 }
01051
01052 else if( p.nMatch("NUSS") )
01053 {
01054
01055 if( p.nMatch(" ON ") )
01056 {
01057
01058 ionbal.lgSupDie[1] = true;
01059 }
01060 else if( p.nMatch(" OFF") )
01061 {
01062
01063 ionbal.lgSupDie[1] = false;
01064 }
01065 else
01066 {
01067 fprintf( ioQQQ, " flag ON or OFF must appear.\n" );
01068 cdEXIT(EXIT_FAILURE);
01069 }
01070 }
01071
01072 else if( p.nMatch("BADN") )
01073 {
01074
01075 if( p.nMatch(" OFF") )
01076 {
01077 ionbal.lgDR_recom_Badnell_use = false;
01078 }
01079 else
01080 {
01081 ionbal.lgDR_recom_Badnell_use = true;
01082 }
01083
01084
01085 if( p.nMatch("PRIN") )
01086 ionbal.lgRecom_Badnell_print = true;
01087 }
01088 else
01089 {
01090 fprintf( ioQQQ, " key KLUDge, BURGess, NUSSbaumer, or BADNell must appear.\n" );
01091 cdEXIT(EXIT_FAILURE);
01092 }
01093 }
01094
01095 else if( p.nMatch("RADIATIV") )
01096 {
01097 if( p.nMatch("BADN" ) )
01098 {
01099
01100 if( p.nMatch( " OFF" ) )
01101 {
01102 ionbal.lgRR_recom_Badnell_use = false;
01103 }
01104 else
01105 {
01106 ionbal.lgRR_recom_Badnell_use = true;
01107 }
01108
01109
01110 if( p.nMatch("PRIN" ) )
01111 ionbal.lgRecom_Badnell_print = true;
01112 }
01113 else
01114 {
01115 fprintf( ioQQQ, " key BADNell must appear.\n" );
01116 cdEXIT(EXIT_FAILURE);
01117 }
01118 }
01119 else
01120 {
01121 fprintf( ioQQQ, " key RADIATIve or DIELECTRonic must appear on set recombination command.\n" );
01122 cdEXIT(EXIT_FAILURE);
01123 }
01124 }
01125
01126 else if( p.nMatch("SPEC") )
01127 {
01128 fprintf( ioQQQ, " This command is no longer supported. The saved continuum now always has the same resolution as the native continuum of the calculation.\n" );
01129 cdEXIT( EXIT_FAILURE );
01130 }
01131
01132 else if( p.nMatch(" DR ") )
01133 {
01134
01135
01136 radius.sdrmax = p.FFmtRead();
01137 if( !p.nMatch("LINE") )
01138 {
01139
01140 radius.sdrmax = pow( 10. , radius.sdrmax );
01141 }
01142 if( p.lgEOL() )
01143 {
01144 p.NoNumb("zone thickness");
01145 }
01146
01147 radius.lgSdrmaxRel = p.nMatch("RELA");
01148
01149
01150 radius.sdrmin = radius.sdrmax;
01151 radius.lgSdrminRel = radius.lgSdrmaxRel;
01152 if( !radius.lgSdrmaxRel && radius.sdrmax < DEPTH_OFFSET*1e4 )
01153 {
01154 fprintf( ioQQQ, "\n Thicknesses less than about %.0e will NOT give accurate results. If tricking the code\n",
01155 DEPTH_OFFSET*1e4 );
01156 fprintf( ioQQQ, " into computing emissivities instead of intensities, try to instead use a thickness of unity,\n" );
01157 fprintf( ioQQQ, " and then multiply (divide) the results by the necessary thickness (product of densities).\n\n" );
01158 cdEXIT(EXIT_FAILURE);
01159 }
01160 if( radius.lgSdrmaxRel && ( radius.sdrmax <= 0. || radius.sdrmax >= 1. ) )
01161 {
01162 fprintf( ioQQQ, " When using a relative dr, a fraction between 0 and 1 must be entered. Found: %g\n",
01163 radius.sdrmax );
01164 cdEXIT(EXIT_FAILURE);
01165 }
01166 }
01167
01168 else if( p.nMatch("DRMA") )
01169 {
01170
01171 radius.sdrmax = p.FFmtRead();
01172 if( p.lgEOL() )
01173 p.NoNumb("maximum zone thickness");
01174
01175 if( ( radius.sdrmax < 38. || p.nMatch(" LOG") ) && !p.nMatch("LINE") )
01176 radius.sdrmax = pow(10.,radius.sdrmax);
01177
01178
01179 radius.lgSdrmaxRel = p.nMatch("RELA");
01180 if( radius.lgSdrmaxRel && ( radius.sdrmax <= 0. || radius.sdrmax >= 1. ) )
01181 {
01182 fprintf( ioQQQ, " When using a relative drmax, a fraction between 0 and 1 must be entered. Found: %g\n",
01183 radius.sdrmax );
01184 cdEXIT(EXIT_FAILURE);
01185 }
01186 }
01187
01188 else if( p.nMatch("DRMI") )
01189 {
01190
01191 radius.sdrmin = p.FFmtRead();
01192 if( p.lgEOL() )
01193 p.NoNumb("minimum zone thickness");
01194
01195 if( ( radius.sdrmin < 38. || p.nMatch(" LOG") ) && !p.nMatch("LINE") )
01196 radius.sdrmin = pow(10.,radius.sdrmin);
01197
01198
01199 radius.lgSdrminRel = p.nMatch("RELA");
01200 radius.lgSMinON = true;
01201 if( radius.lgSdrminRel && ( radius.sdrmin <= 0. || radius.sdrmin >= 1. ) )
01202 {
01203 fprintf( ioQQQ, " When using a relative drmin, a fraction between 0 and 1 must be entered. Found: %g\n",
01204 radius.sdrmin );
01205 cdEXIT(EXIT_FAILURE);
01206 }
01207 }
01208
01209 else if( p.nMatch("FLXF") )
01210 {
01211
01212 rfield.FluxFaint = (realnum)p.FFmtRead();
01213 if( p.lgEOL() )
01214 {
01215 p.NoNumb("faintest continuum flux to consider");
01216 }
01217 if( rfield.FluxFaint < 0. )
01218 {
01219 rfield.FluxFaint = (realnum)pow((realnum)10.f,rfield.FluxFaint);
01220 }
01221 }
01222
01223 else if( p.nMatch("LINE") && p.nMatch("PREC") )
01224 {
01225
01226
01227 LineSave.sig_figs = (int)p.FFmtRead();
01228 if( p.lgEOL() )
01229 {
01230 p.NoNumb("line precision");
01231 }
01232 else if( LineSave.sig_figs > 6 )
01233 {
01234 fprintf( ioQQQ, " set line precision currently only works for up to 6 significant figures.\n" );
01235 cdEXIT(EXIT_FAILURE);
01236 }
01237
01238
01239 }
01240
01241
01242 else if( p.nMatch("NFNU") )
01243 {
01244 if( p.nMatch(" ADD") )
01245 {
01246
01247 double energy = p.FFmtRead();
01248 if( p.lgEOL() )
01249 p.NoNumb("energy");
01250 t_PredCont::Inst().add( energy, p.StandardEnergyUnit() );
01251 }
01252 else
01253 {
01254
01255
01256
01257
01258 prt.lgSourceReflected = p.nMatch("INCIDENT R") || p.nMatch("INCIDENT_R");
01259
01260 prt.lgSourceTransmitted = p.nMatch("INCIDENT_T") || p.nMatch("INCIDENT T");
01261
01262 prt.lgDiffuseInward = p.nMatch("DIFFUSE_I") || p.nMatch("DIFFUSE I");
01263
01264 prt.lgDiffuseOutward = p.nMatch("DIFFUSE_O") || p.nMatch("DIFFUSE O");
01265
01266
01267 if( ! ( prt.lgSourceReflected || prt.lgSourceTransmitted ||
01268 prt.lgDiffuseInward || prt.lgDiffuseOutward ) )
01269 {
01270 fprintf( ioQQQ, " set nFnu expects one or more of the following keywords:\n" );
01271 fprintf( ioQQQ, " INCIDENT_REFLECTED, INCIDENT_TRANSMITTED, "
01272 "DIFFUSE_INWARD, DIFFUSE_OUTWARD\n" );
01273 cdEXIT(EXIT_FAILURE);
01274 }
01275 }
01276
01277
01278 prt.lgPrnDiff = true;
01279 }
01280
01281 else if( p.nMatch("IND2") )
01282 {
01283 if( p.nMatch(" ON ") )
01284 {
01285
01286 iso.lgInd2nu_On = true;
01287 }
01288 else if( p.nMatch(" OFF") )
01289 {
01290 iso.lgInd2nu_On = false;
01291 }
01292 else
01293 {
01294 fprintf( ioQQQ, " set ind2 needs either ON or OFF.\n" );
01295 cdEXIT(EXIT_FAILURE);
01296 }
01297 }
01298
01299 else if( p.nMatch("TEMP") )
01300 {
01301
01302 if( p.nMatch("FLOO") )
01303 {
01304 StopCalc.TeFloor = (realnum)p.FFmtRead();
01305 if( p.lgEOL() )
01306 p.NoNumb("temperature floor");
01307
01308
01309 if( p.nMatch(" LOG") || (StopCalc.TeFloor <= 10. && !p.nMatch("LINE")) )
01310 StopCalc.TeFloor = (realnum)pow(10.,StopCalc.TeFloor);
01311
01312 if( StopCalc.TeFloor < phycon.TEMP_LIMIT_LOW )
01313 {
01314 fprintf( ioQQQ, " TE < %gK, reset to %gK.\n",
01315 phycon.TEMP_LIMIT_LOW, 1.0001*phycon.TEMP_LIMIT_LOW );
01316 StopCalc.TeFloor = realnum(1.0001*phycon.TEMP_LIMIT_LOW);
01317 }
01318
01319 if( StopCalc.TeFloor > phycon.TEMP_LIMIT_HIGH )
01320 {
01321 fprintf( ioQQQ, " TE > %gK. Cloudy cannot handle this. Bailing out.\n",
01322 phycon.TEMP_LIMIT_HIGH );
01323 cdEXIT(EXIT_FAILURE);
01324 }
01325
01326
01327 if( optimize.lgVarOn )
01328 {
01329 optimize.nvarxt[optimize.nparm] = 1;
01330 strcpy( optimize.chVarFmt[optimize.nparm], "SET TEMPERATURE FLOOR %f LOG" );
01331
01332
01333 optimize.nvfpnt[optimize.nparm] = input.nRead;
01334
01335
01336 optimize.vparm[0][optimize.nparm] = (realnum)log10(StopCalc.TeFloor);
01337 optimize.varang[optimize.nparm][0] = (realnum)log10(1.00001*phycon.TEMP_LIMIT_LOW);
01338 optimize.varang[optimize.nparm][1] = (realnum)log10(0.99999*phycon.TEMP_LIMIT_HIGH);
01339 optimize.vincr[optimize.nparm] = 0.3f;
01340
01341 ++optimize.nparm;
01342 }
01343 }
01344
01345 else if( p.nMatch("CONV") || p.nMatch("TOLE") )
01346 {
01347
01348 conv.HeatCoolRelErrorAllowed = (realnum)p.FFmtRead();
01349 if( p.lgEOL() )
01350 {
01351 p.NoNumb("heating cooling tolerance");
01352 }
01353 if( conv.HeatCoolRelErrorAllowed <= 0. )
01354 {
01355 conv.HeatCoolRelErrorAllowed = (realnum)pow((realnum)10.f,conv.HeatCoolRelErrorAllowed);
01356 }
01357 }
01358
01359 else
01360 {
01361 fprintf( ioQQQ, "\nI did not recognize a keyword on this SET TEMPERATURE command.\n");
01362 p.PrintLine(ioQQQ);
01363 fprintf( ioQQQ, "The keywords are FLOOr and CONVergence.\n" );
01364 cdEXIT(EXIT_FAILURE);
01365 }
01366 }
01367
01368 else if( p.nMatch("TEST") )
01369 {
01370
01371 lgTestCodeEnabled = true;
01372 }
01373
01374 else if( p.nMatch("TRIM") )
01375 {
01376
01377
01378
01379 if( p.nMatch("UPPE") )
01380 {
01381
01382 double save = ionbal.trimhi;
01383 ionbal.trimhi = pow(10.,p.FFmtRead());
01384 if( p.lgEOL() && p.nMatch(" OFF") )
01385 {
01386
01387 p.setEOL(false);
01388 ionbal.lgTrimhiOn = false;
01389
01390 ionbal.trimhi = save;
01391 }
01392 }
01393
01394 else if( p.nMatch("LOWE") )
01395 {
01396
01397 ionbal.trimlo = pow(10.,p.FFmtRead());
01398 }
01399
01400
01401 else if( p.nMatch("SMAL") || p.nMatch(" OFF") )
01402 {
01403
01404 ionbal.trimlo = SMALLFLOAT;
01405 ionbal.trimhi = SMALLFLOAT;
01406 p.setEOL(false);
01407 }
01408
01409 else
01410 {
01411
01412 ionbal.trimhi = pow(10.,p.FFmtRead());
01413
01414
01415 ionbal.trimlo = ionbal.trimhi;
01416 }
01417
01418 if( p.lgEOL() )
01419 {
01420 p.NoNumb("trimming parameter");
01421 }
01422
01423 if( ionbal.trimlo >= 1. || ionbal.trimhi >= 1. )
01424 {
01425 fprintf( ioQQQ, " number must be negative since log\n" );
01426 cdEXIT(EXIT_FAILURE);
01427 }
01428 }
01429
01430 else if( p.nMatch("SKIP") )
01431 {
01432
01433 save.ncSaveSkip = (long)p.FFmtRead();
01434 if( p.lgEOL() )
01435 {
01436 p.NoNumb("number of points to skip in save");
01437 }
01438 }
01439
01440 else if( p.nMatch(" UTA") )
01441 {
01442
01443
01444 if( p.nMatch("GU06" ) )
01445 {
01446 if( p.nMatch(" OFF" ) )
01447 {
01448
01449 ionbal.lgInnerShell_Gu06 = false;
01450 }
01451 else
01452 {
01453
01454
01455
01456 ionbal.lgInnerShell_Gu06 = true;
01457 }
01458 }
01459 else if( p.nMatch("KISI" ) )
01460 {
01461 if( p.nMatch(" OFF" ) )
01462 {
01463
01464 ionbal.lgInnerShell_Kisielius = false;
01465 }
01466 else
01467 {
01468
01469 ionbal.lgInnerShell_Kisielius = true;
01470 }
01471 }
01472 }
01473
01474 else if( p.nMatch("WEAKH") )
01475 {
01476
01477 save.WeakHeatCool = (realnum)p.FFmtRead();
01478
01479 if( p.lgEOL() )
01480 {
01481 p.NoNumb("threshold on save heating and cooling");
01482 }
01483
01484 if( save.WeakHeatCool < 0. )
01485 {
01486 save.WeakHeatCool = (realnum)pow((realnum)10.f,save.WeakHeatCool);
01487 }
01488 }
01489
01490 else if( p.nMatch("KSHE") )
01491 {
01492
01493 continuum.EnergyKshell = (realnum)p.FFmtRead();
01494 if( p.lgEOL() )
01495 {
01496 p.NoNumb("k-shell ionization opacity limit");
01497 }
01498
01499 if( continuum.EnergyKshell == 0. )
01500 {
01501
01502 continuum.EnergyKshell = rfield.egamry;
01503 }
01504
01505 else if( continuum.EnergyKshell < 194. )
01506 {
01507 fprintf( ioQQQ, " k-shell energy must be greater than 194 Ryd\n" );
01508 cdEXIT(EXIT_FAILURE);
01509 }
01510 }
01511
01512 else if( p.nMatch("NCHR") )
01513 {
01514
01515 double val = p.FFmtRead();
01516
01517 if( p.lgEOL() )
01518 {
01519 p.NoNumb("number of charge states");
01520 }
01521 else
01522 {
01523 long nChrg = nint(val);
01524 if( nChrg < 2 || nChrg > NCHS )
01525 {
01526 fprintf( ioQQQ, " illegal value for number of charge states: %ld\n", nChrg );
01527 fprintf( ioQQQ, " choose a value between 2 and %d\n", NCHS );
01528 fprintf( ioQQQ, " or increase NCHS in grainvar.h and recompile\n" );
01529 cdEXIT(EXIT_FAILURE);
01530 }
01531 else
01532 {
01533 SetNChrgStates(nChrg);
01534 }
01535 }
01536 }
01537
01538 else if( p.nMatch("NEGO") )
01539 {
01540
01541 opac.lgNegOpacIO = true;
01542 }
01543
01544 else if( p.nMatch("NEND") )
01545 {
01546
01547
01548
01549
01550 if( geometry.lgEndDflt )
01551 {
01552
01553 geometry.nEndDflt = (long)p.FFmtRead();
01554 geometry.lgEndDflt = false;
01555 if( p.lgEOL() )
01556 p.NoNumb("limit to zone number");
01557
01558
01559 for( long i=0; i < iterations.iter_malloc; i++ )
01560 geometry.nend[i] = geometry.nEndDflt;
01561
01562 if( geometry.nEndDflt>2000 )
01563 fprintf(ioQQQ,"CAUTION - it will take a lot of memory to save"
01564 " results for %li zones. Is this many zones really necessary?\n",
01565 geometry.nEndDflt );
01566 }
01567 }
01568
01569 else if( p.nMatch("TSQD") )
01570 {
01571
01572
01573 peimbt.tsqden = (realnum)p.FFmtRead();
01574
01575 if( p.lgEOL() )
01576 {
01577 p.NoNumb("highest density in t^2 section of printout");
01578 }
01579 peimbt.tsqden = (realnum)pow((realnum)10.f,peimbt.tsqden);
01580 }
01581
01582 else if( p.nMatch("NMAP") )
01583 {
01584
01585 hcmap.nMapStep = (long)p.FFmtRead();
01586 if( p.lgEOL() )
01587 {
01588 p.NoNumb("steps in heating-cooling map");
01589 }
01590 }
01591
01592 else if( p.nMatch("NUME") && p.nMatch("DERI") )
01593 {
01594
01595 NumDeriv.lgNumDeriv = true;
01596 }
01597
01598 else if( p.nMatch("PATH") )
01599 {
01600 fprintf( ioQQQ, " The SET PATH command is no longer supported.\n" );
01601 fprintf( ioQQQ, " Please set the correct path in the file path.h.\n" );
01602 fprintf( ioQQQ, " Or set the environment variable CLOUDY_DATA_PATH.\n Sorry.\n" );
01603 cdEXIT(EXIT_FAILURE);
01604 }
01605
01606 else if( p.nMatch("PHFI") )
01607 {
01608
01609 ip = (long)p.FFmtRead();
01610 if( p.lgEOL() )
01611 {
01612 p.NoNumb("version of PHFIT");
01613 }
01614
01615 if( ip == 1995 )
01616 {
01617
01618 t_ADfA::Inst().set_version( PHFIT95 );
01619 }
01620 else if( ip == 1996 )
01621 {
01622
01623 t_ADfA::Inst().set_version( PHFIT96 );
01624 }
01625 else
01626 {
01627 fprintf( ioQQQ, " Two possible values are 1995 and 1996.\n" );
01628 cdEXIT(EXIT_FAILURE);
01629 }
01630 }
01631
01632
01633 else if( p.nMatch("PUNC") || p.nMatch("SAVE") )
01634 {
01635 if( p.nMatch("HASH") )
01636 {
01637
01638 if( !lgQuotesFound )
01639 {
01640 fprintf( ioQQQ, " I didn\'t recognize a key on this SET SAVE HASH line.\n" );
01641 cdEXIT(EXIT_FAILURE);
01642 }
01643
01644
01645
01646
01647
01648
01649 if( strcmp( chString_quotes_lowercase, "return" ) == 0 )
01650 {
01651
01652 sprintf(save.chHashString , "\n" );
01653 }
01654 else if( strcmp( chString_quotes_lowercase, "time" ) == 0 )
01655 {
01656
01657 sprintf( save.chHashString, "TIME_DEP" );
01658 }
01659 else
01660 {
01661
01662 strcpy( save.chHashString, chString_quotes_lowercase );
01663 }
01664 }
01665
01666 else if( ( p.nMatch("LINE") && p.nMatch("WIDT") ) || p.nMatch("RESO") ||
01667 p.nMatch("LWID"))
01668 {
01669
01670 if( p.nMatch(" C ") )
01671 {
01672 fprintf( ioQQQ, " the keyword C is no longer necessary since"
01673 " energy conservation is now supported by default.\n" );
01674 cdEXIT(EXIT_FAILURE);
01675 }
01676 else if( p.nMatch("SUPP") )
01677
01678 save.Resolution = realnum(0.);
01679 else
01680 {
01681 double number = p.FFmtRead();
01682 if( p.lgEOL() )
01683 p.NoNumb("line width or resolution");
01684 if( number <= 0. )
01685 {
01686 fprintf( ioQQQ, " line width or resolution must be greater than zero.\n" );
01687 cdEXIT(EXIT_FAILURE);
01688 }
01689
01690 if( p.nMatch("RESO") )
01691
01692 save.Resolution = realnum(number);
01693 else
01694
01695 save.Resolution = realnum(SPEEDLIGHT/(number*1.e5));
01696 }
01697
01698
01699
01700 if( p.nMatch("ABSO") )
01701 save.ResolutionAbs = save.Resolution;
01702 }
01703
01704 else if( p.nMatch("PREF") )
01705 {
01706
01707 save.chFilenamePrefix = chString_quotes_lowercase;
01708 }
01709
01710 else if( p.nMatch("FLUS") )
01711 {
01712
01713 save.lgFLUSH = true;
01714 }
01715
01716 else
01717 {
01718 fprintf( ioQQQ, " There should have been an option on this command.\n" );
01719 fprintf( ioQQQ, " Valid options for SET SAVE are summarized in Hazy 1 "
01720 "Miscellaneous commands.\n" );
01721 fprintf( ioQQQ, " The SET PUNCHLWIDTH command is now SET SAVE LINE WIDTH.\n" );
01722 cdEXIT(EXIT_FAILURE);
01723 }
01724 }
01725
01726
01727 else if( p.nMatch("CONT" ) )
01728 {
01729 if( p.nMatch("FEII" ) || p.nMatch("FE I" ) )
01730 {
01731
01732
01733 FeII.feconwlLo = (realnum)p.FFmtRead();
01734 FeII.feconwlHi = (realnum)p.FFmtRead();
01735 FeII.nfe2con = (long)p.FFmtRead();
01736 if( p.lgEOL() )
01737 {
01738 fprintf(ioQQQ, "PROBLEM The set FeII continuum command must have"
01739 " three numbers, the lower and upper wavelength range in Angstroms"
01740 " and the number of bins to divide this into.\n");
01741 cdEXIT(EXIT_FAILURE);
01742 }
01743
01744 if( FeII.feconwlLo >= FeII.feconwlHi )
01745 {
01746 fprintf(ioQQQ, "PROBLEM The first two numbers on the set "
01747 "FeII continuum command must be the lower and upper "
01748 "wavelength range in Angstroms and the first must be less "
01749 "than the second.\n");
01750 cdEXIT(EXIT_FAILURE);
01751 }
01752 if( FeII.nfe2con < 2 )
01753 {
01754 fprintf(ioQQQ, "PROBLEM The third number on the set FeII continuum "
01755 "command must be the number of bins to divide the range into and"
01756 " it must be greater than 1.\n");
01757 cdEXIT(EXIT_FAILURE);
01758 }
01759
01760 }
01761
01762 else if( p.nMatch("RESO" ) )
01763 {
01764
01765
01766 continuum.ResolutionScaleFactor = p.FFmtRead();
01767 if( p.lgEOL() )
01768 {
01769 p.NoNumb("continuum resolution scale");
01770 }
01771
01772 if( continuum.ResolutionScaleFactor <= 0. )
01773 continuum.ResolutionScaleFactor = pow(10.,continuum.ResolutionScaleFactor);
01774 }
01775
01776 else if( p.nMatch("SHIE" ) )
01777 {
01778
01779
01780
01781
01782
01783
01784 if( p.nMatch("PESC" ) )
01785 {
01786
01787 rt.nLineContShield = LINE_CONT_SHIELD_PESC;
01788 }
01789 else if( p.nMatch("FEDE" ) )
01790 {
01791
01792
01793
01794
01795 rt.nLineContShield = LINE_CONT_SHIELD_FEDERMAN;
01796 }
01797 else if( p.nMatch("FERL" ) )
01798 {
01799 rt.nLineContShield = LINE_CONT_SHIELD_FERLAND;
01800 }
01801 else if( p.nMatch("NONE" ) )
01802 {
01803
01804 rt.nLineContShield = 0;
01805 }
01806 else
01807 {
01808 fprintf( ioQQQ, " I didn\'t recognize a key on this SET CONTINUUM SHIELDing line.\n" );
01809 fprintf( ioQQQ, " The ones I know about are: PESC, FEDErman, & FERLand.\n" );
01810 cdEXIT(EXIT_FAILURE);
01811 }
01812 }
01813
01814 else
01815 {
01816 fprintf( ioQQQ, " I didn\'t recognize a key on this SET CONTINUUM line.\n" );
01817 fprintf( ioQQQ, " The ones I know about are: RESOlution and SHIEld.\n" );
01818 cdEXIT(EXIT_FAILURE);
01819 }
01820 }
01821
01822 else
01823 {
01824 fprintf( ioQQQ, " I didn\'t recognize a key on this SET command.\n" );
01825 cdEXIT(EXIT_FAILURE);
01826 }
01827
01828 return;
01829 }