00001 
00002 
00003 
00004 
00005 #include "cddefines.h"
00006 #include "physconst.h"
00007 #include "taulines.h"
00008 #include "mewecoef.h"
00009 #include "iterations.h"
00010 #include "heavy.h"
00011 #include "mole.h"
00012 #include "yield.h"
00013 #include "trace.h"
00014 #include "lines.h"
00015 #include "lines_service.h"
00016 #include "ionbal.h"
00017 #include "struc.h"
00018 #include "geometry.h"
00019 #include "dynamics.h"
00020 #include "elementnames.h"
00021 #include "hyperfine.h"
00022 #include "atmdat.h"
00023 
00024 
00025 
00026 #define INTBIG 2000000000
00027 
00028 
00029 
00030 
00031 
00032 
00033 long 
00034    ipT1656=INTBIG,    ipT9830=INTBIG,  
00035    ipT8727=INTBIG,    ipT1335=INTBIG,  ipT1909=INTBIG,
00036         ipT977=INTBIG,    ipT1550=INTBIG,  ipT1548=INTBIG, ipT386=INTBIG, 
00037         ipT310=INTBIG,    ipc31175=INTBIG, ipT291=INTBIG,  ipT280=INTBIG,
00038         ipT274=INTBIG,    ipT270=INTBIG,   ipT312=INTBIG,  ipT610=INTBIG, 
00039         ipT370=INTBIG,    ipT157=INTBIG,   ipT1085=INTBIG, 
00040         ipT990=INTBIG,    ipT1486=INTBIG,  ipT765=INTBIG,  ipT1243=INTBIG, 
00041         ipT1239=INTBIG,   ipT374g=INTBIG,  ipT374x=INTBIG, ipT1200=INTBIG,
00042         ipT2140=INTBIG,   ipT671=INTBIG,   ipT315=INTBIG,  ipT324=INTBIG, 
00043         ipT333=INTBIG,    ipT209=INTBIG,   ipT122=INTBIG,  ipT205=INTBIG,
00044         ipT57=INTBIG,     ipT6300=INTBIG,  ipT6363=INTBIG, ipT5577=INTBIG, 
00045         ipT834=INTBIG,    ipT1661=INTBIG,  ipT1666=INTBIG, ipT835=INTBIG,
00046         ipT789=INTBIG,    ipT630=INTBIG,   ipT1304=INTBIG, ipSi10_606=INTBIG,
00047         ipT1039=INTBIG,   ipT8446=INTBIG,  ipT4368=INTBIG, ipTOI13=INTBIG,
00048         ipTOI11=INTBIG,   ipTOI29=INTBIG,  ipTOI46=INTBIG, ipTO1025=INTBIG, 
00049         ipT304=INTBIG,    ipT1214=INTBIG,  ipT150=INTBIG,  ipT146=INTBIG,
00050         ipT63=INTBIG,     ipTO88=INTBIG,   ipT52=INTBIG,   ipT26=INTBIG, 
00051         ipT1032=INTBIG,   ipT1037=INTBIG,  ipF0229=INTBIG, ipF0267=INTBIG,
00052         ipF444=INTBIG,    ipF425=INTBIG,   ipT770=INTBIG, ipT780=INTBIG, 
00053         ipxNe0676=INTBIG, ipT895=INTBIG,   ipT88=INTBIG, ipTNe13=INTBIG,
00054         ipTNe36=INTBIG,   ipTNe16=INTBIG,  ipTNe14=INTBIG, ipTNe24=INTBIG, 
00055         ipT5895=INTBIG,   ipfsNa373=INTBIG,ipfsNa490=INTBIG, ipfsNa421=INTBIG,
00056         ipxNa6143=INTBIG, ipxNa6862=INTBIG,ipxNa0746=INTBIG, ipMgI2853=INTBIG, 
00057         ipMgI2026=INTBIG, ipT2796=INTBIG,  ipT2804=INTBIG,
00058         ipT705=INTBIG,    ipT4561=INTBIG,  ipxMg51325=INTBIG, ipxMg52417=INTBIG, 
00059         ipxMg52855=INTBIG,ipxMg71190=INTBIG, ipxMg72261=INTBIG,
00060         ipxMg72569=INTBIG,ipxMg08303=INTBIG, ipTMg610=INTBIG, ipTMg625=INTBIG, 
00061         ipT58=INTBIG,     ipTMg4=INTBIG, ipTMg14=INTBIG, ipTMg6=INTBIG,
00062         ipfsMg790=INTBIG, ipfsMg755=INTBIG, ipAlI3957=INTBIG, ipAlI3090=INTBIG, 
00063         ipT1855=INTBIG,   ipT1863=INTBIG, ipT2670=INTBIG,
00064         ipAl529=INTBIG,   ipAl6366=INTBIG, ipAl6912=INTBIG, ipAl8575=INTBIG, 
00065         ipAl8370=INTBIG,  ipAl09204=INTBIG, ipT639=INTBIG,
00066         ipTAl550=INTBIG,  ipTAl568=INTBIG, ipTAl48=INTBIG, ipSii2518=INTBIG, 
00067         ipSii2215=INTBIG, ipT1808=INTBIG,
00068         ipT1207=INTBIG,   ipT1895=INTBIG, ipT1394=INTBIG, ipT1403=INTBIG, 
00069         ipT1527=INTBIG,   ipT1305=INTBIG, ipT1260=INTBIG, ipSi619=INTBIG,
00070         ipSi10143=INTBIG, ipTSi499=INTBIG, ipTSi521=INTBIG, ipTSi41=INTBIG, 
00071         ipTSi35=INTBIG,   ipTSi25=INTBIG, ipTSi65=INTBIG,
00072         ipTSi3=INTBIG,    ipTSi4=INTBIG, ipP0260=INTBIG, ipP0233=INTBIG, 
00073         ipP0318=INTBIG,   ipP713=INTBIG, ipP848=INTBIG, ipP817=INTBIG,
00074         ipP1027=INTBIG,   ipP1018=INTBIG, ipT1256=INTBIG, ipT1194=INTBIG, 
00075         ipTS1720=INTBIG,  ipT1198=INTBIG, ipT786=INTBIG,
00076         ipT933=INTBIG,    ipT944=INTBIG, ipfsS810=INTBIG, ipfsS912=INTBIG, 
00077         ipfsS938=INTBIG,  ipfsS1119=INTBIG, ipfsS1114=INTBIG, ipfsS1207=INTBIG,
00078         ipTSu418=INTBIG,  ipTSu446=INTBIG, ipTSu30=INTBIG, ipTS19=INTBIG, 
00079         ipTS34=INTBIG,    ipTS11=INTBIG, ipfsCl214=INTBIG, ipfsCl233=INTBIG,
00080         ipCl04203=INTBIG, ipCl04117=INTBIG, ipCl973=INTBIG, ipCl1030=INTBIG, 
00081         ipCl1092=INTBIG,  ipT354=INTBIG, ipT389=INTBIG, ipT25=INTBIG,
00082         ipTAr7=INTBIG,    ipTAr9=INTBIG, ipTAr22=INTBIG, ipTAr13=INTBIG, 
00083         ipTAr8=INTBIG,    ipAr06453=INTBIG, ipAr1055=INTBIG, ipAr1126=INTBIG,
00084         ipAr1178=INTBIG,  ipKI7745=INTBIG, ipxK03462=INTBIG, ipxK04598=INTBIG, 
00085         ipxK04154=INTBIG, ipxK06882=INTBIG, ipxK06557=INTBIG,
00086         ipxK07319=INTBIG, ipxK11425=INTBIG, ipCaI4228=INTBIG, ipT3934=INTBIG, 
00087         ipT3969=INTBIG,   ipT8498=INTBIG, ipT8542=INTBIG,
00088         ipT8662=INTBIG,   ipT7291=INTBIG, ipT7324=INTBIG, ipTCa302=INTBIG, 
00089         ipTCa345=INTBIG,  ipTCa19=INTBIG, ipTCa3=INTBIG, ipTCa12=INTBIG,
00090         ipTCa4=INTBIG,    ipCa0741=INTBIG, ipCa0761=INTBIG, ipCa08232=INTBIG, 
00091         ipCa12333=INTBIG, ipSc05231=INTBIG, ipSc13264=INTBIG,
00092         ipTi06172=INTBIG, ipTi14212=INTBIG, ipVa07130=INTBIG, ipVa15172=INTBIG, 
00093         ipCr08101=INTBIG, ipCr16141=INTBIG, ipxMn0979=INTBIG,
00094         ipxMn1712=INTBIG, ipFeI3884=INTBIG, ipFeI3729=INTBIG, ipFeI3457=INTBIG, 
00095         ipFeI3021=INTBIG, ipFeI2966=INTBIG, ipTuv3=INTBIG,
00096         ipTr48=INTBIG,    ipTFe16=INTBIG, ipTFe26=INTBIG, ipTFe34=INTBIG, 
00097         ipTFe35=INTBIG,   ipTFe46=INTBIG, ipTFe56=INTBIG, ipT1122=INTBIG,
00098         ipFe0795=INTBIG,  ipFe0778=INTBIG, ipT245=INTBIG, ipT352=INTBIG, 
00099         ipFe106375=INTBIG,ipT353=INTBIG, 
00100         ipT347=INTBIG,    ipT192=INTBIG, ipT255=INTBIG, ipT11=INTBIG, 
00101         ipT191=INTBIG,     ipFe18975=INTBIG, ipTFe23=INTBIG,
00102         ipTFe13=INTBIG,   ipCo11527=INTBIG, ipxNi1242=INTBIG;
00103 long    ipS4_1405=INTBIG,ipS4_1398=INTBIG,ipS4_1424=INTBIG,ipS4_1417=INTBIG,ipS4_1407=INTBIG,
00104                 ipO4_1400=INTBIG,ipO4_1397=INTBIG,ipO4_1407=INTBIG,ipO4_1405=INTBIG,ipO4_1401=INTBIG,
00105                 ipN3_1749=INTBIG,ipN3_1747=INTBIG,ipN3_1754=INTBIG,ipN3_1752=INTBIG,ipN3_1751=INTBIG,
00106                 ipC2_2325=INTBIG,ipC2_2324=INTBIG,ipC2_2329=INTBIG,ipC2_2328=INTBIG,ipC2_2327=INTBIG,
00107                 ipSi2_2334=INTBIG,ipSi2_2329=INTBIG,ipSi2_2350=INTBIG,ipSi2_2344=INTBIG,ipSi2_2336=INTBIG,
00108                 ipFe22_247=INTBIG,ipFe22_217=INTBIG,ipFe22_348=INTBIG,ipFe22_292=INTBIG,
00109                 ipFe22_253=INTBIG,ipFe22_846=INTBIG,ipTFe20_721=INTBIG,ipTFe20_578=INTBIG , ipZn04363=INTBIG,
00110                 ipS12_520=INTBIG,ipS1_25m=INTBIG,ipS1_56m=INTBIG,ipCl1_11m=INTBIG,
00111                 ipFe1_24m=INTBIG,ipFe1_35m=INTBIG,ipFe1_54m=INTBIG,ipFe1_111m=INTBIG,
00112                 ipNi1_7m=INTBIG ,ipNi1_11m=INTBIG,ipSi1_130m=INTBIG,ipSi1_68m=INTBIG;
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 #include "atomfeii.h"
00126 
00127 void atmdat_readin(void)
00128 {
00129         long int i, 
00130           iCase ,
00131           ion, 
00132           ipDens ,
00133           ipISO ,
00134           ipTemp ,
00135           j, 
00136           J,
00137           ig0, 
00138           ig1, 
00139           imax, 
00140           nelem, 
00141           nelec, 
00142           magic1, 
00143           magic2,
00144           mol ,
00145 
00146           nUTA_Romas,
00147           nFeIonRomas[ipIRON],
00148 
00149           nUTA_Behar ,
00150           nFeIonBehar[ipIRON],
00151 
00152           nUTA_Gu06,
00153           nFeIonGu[ipIRON];
00154         double
00155           WLloRomas[ipIRON],
00156           WLhiRomas[ipIRON],
00157           WLloBehar[ipIRON],
00158           WLhiBehar[ipIRON],
00159           WLloGu[ipIRON],
00160           WLhiGu[ipIRON];
00161 
00162         char cha;
00163         char chS2[3];
00164 
00165         long ipZ;
00166         bool lgEOL;
00167 
00168         FILE *ioDATA, *ioROMAS , *ioBEHAR=NULL;
00169         FILE *ioGU06=NULL;
00170         char chLine[FILENAME_PATH_LENGTH_2] , 
00171                 chFilename[FILENAME_PATH_LENGTH_2];
00172 
00173         static bool lgFirstCall = true;
00174 
00175         DEBUG_ENTRY( "atmdat_readin()" );
00176 
00177         
00178         if( !lgFirstCall )
00179         { 
00180                 
00181                 bool lgTooBig = false;
00182                 for( j=0; j < iterations.iter_malloc; j++ )
00183                 {
00184                         if( geometry.nend[j]>=struc.nzlim )
00185                                 lgTooBig = true;
00186                 }
00187                 if( lgTooBig )
00188                 {
00189                         fprintf(ioQQQ," This is the second or later calculation in a grid.\n");
00190                         fprintf(ioQQQ," The number of zones has been increased beyond what it was on the first calculation.\n");
00191                         fprintf(ioQQQ," This can\'t be done since space has already been allocated.\n");
00192                         fprintf(ioQQQ," Have the first calculation do the largest number of zones so that an increase is not needed.\n");
00193                         fprintf(ioQQQ," Sorry.\n");
00194                         cdEXIT(EXIT_FAILURE);
00195                 }
00196                 return;
00197         }
00198 
00199         lgFirstCall = false; 
00200 
00201         
00202 
00203         if( !mole.num_comole_calc )
00204         {
00205                 
00206                 TotalInsanity();
00207         }
00208 
00209         
00210         
00211         
00212         for( j=0; j < iterations.iter_malloc; j++ )
00213         {
00214                 struc.nzlim = MAX2( struc.nzlim , geometry.nend[j] );
00215         }
00216 
00217         
00218         ++struc.nzlim;
00219 
00220         struc.coolstr = ((double*)MALLOC( (size_t)(struc.nzlim)*sizeof(double )));
00221 
00222         struc.heatstr = ((double*)MALLOC( (size_t)(struc.nzlim)*sizeof(double )));
00223 
00224         struc.testr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00225 
00226         struc.volstr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00227 
00228         struc.drad_x_fillfac = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00229 
00230         struc.histr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00231 
00232         struc.hiistr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00233 
00234         struc.ednstr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00235 
00236         struc.o3str = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00237 
00238         struc.pressure = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00239 
00240         struc.windv = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00241 
00242         struc.AccelTot = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00243 
00244         struc.AccelGravity = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00245 
00246         struc.pres_radiation_lines_curr = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00247 
00248         struc.GasPressure = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00249 
00250         struc.hden = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00251 
00252         struc.DenParticles = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00253 
00254         struc.DenMass = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00255 
00256         struc.drad = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00257 
00258         struc.depth = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00259 
00260         struc.depth_last = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00261 
00262         struc.drad_last = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00263 
00264         struc.xLyman_depth = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00265 
00266         struc.H2_molec = ((realnum**)MALLOC( (size_t)(N_H_MOLEC)*sizeof(realnum* )));
00267 
00268         struc.CO_molec = ((realnum**)MALLOC( (size_t)(mole.num_comole_calc)*sizeof(realnum* )));
00269 
00270         for(mol=0;mol<N_H_MOLEC;mol++)
00271         {
00272                 struc.H2_molec[mol] = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00273         }
00274 
00275         for(mol=0;mol<mole.num_comole_calc;mol++)
00276         {
00277                 struc.CO_molec[mol] = ((realnum*)MALLOC( (size_t)(struc.nzlim)*sizeof(realnum )));
00278         }
00279 
00280         
00281         struc.gas_phase = (realnum **)MALLOC(sizeof(realnum *)*(unsigned)LIMELM );
00282         
00283         for( ipZ=0; ipZ< LIMELM;++ipZ )
00284         {
00285                 struc.gas_phase[ipZ] = 
00286                         (realnum*)MALLOC(sizeof(realnum)*(unsigned)(struc.nzlim) );
00287         }
00288 
00289         
00290         struc.xIonDense = (realnum ***)MALLOC(sizeof(realnum **)*(unsigned)(LIMELM+3) );
00291 
00292         for( ipZ=0; ipZ< (LIMELM+3);++ipZ )
00293         {
00294                 
00295                 struc.xIonDense[ipZ] = 
00296                         (realnum**)MALLOC(sizeof(realnum*)*(unsigned)(LIMELM+1) );
00297                 
00298                 for( ion=0; ion < (LIMELM+1); ++ion )
00299                 {
00300                         struc.xIonDense[ipZ][ion] = 
00301                                 (realnum*)MALLOC(sizeof(realnum)*(unsigned)(struc.nzlim) );
00302                 }
00303         }
00304 
00305         
00306         for( i=0; i < struc.nzlim; i++ )
00307         {
00308                 struc.testr[i] = 0.;
00309                 struc.volstr[i] = 0.;
00310                 struc.drad_x_fillfac[i] = 0.;
00311                 struc.histr[i] = 0.;
00312                 struc.hiistr[i] = 0.;
00313                 struc.ednstr[i] = 0.;
00314                 struc.o3str[i] = 0.;
00315                 struc.heatstr[i] = 0.;
00316                 struc.coolstr[i] = 0.;
00317                 struc.pressure[i] = 0.;
00318                 struc.pres_radiation_lines_curr[i] = 0.;
00319                 struc.GasPressure[i] = 0.;
00320                 struc.DenParticles[i] = 0.;
00321                 struc.depth[i] = 0.;
00322                 for(mol=0;mol<N_H_MOLEC;mol++)
00323                 {
00324                         struc.H2_molec[mol][i] = 0.;
00325                 }
00326                 for(mol=0;mol<mole.num_comole_calc;mol++)
00327                 {
00328                         struc.CO_molec[mol][i] = 0.;
00329                 }
00330         }
00331 
00332         
00333         DynaCreateArrays( );
00334 
00335         
00336 
00337 
00338 
00339 
00340 
00341         if( trace.lgTrace )
00342                 fprintf( ioQQQ," atmdat_readin opening level1.dat:");
00343 
00344         ioDATA = open_data( "level1.dat", "r" );
00345 
00346         
00347         if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00348         {
00349                 fprintf( ioQQQ, " atmdat_readin could not read first line of level1.dat.\n");
00350                 cdEXIT(EXIT_FAILURE);
00351         }
00352 
00353         
00354 
00355         nLevel1 = 0;
00356         while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00357         {
00358                 
00359 
00360                 if( chLine[0] != '#')
00361                         ++nLevel1;
00362         }
00363 
00364         
00365         TauLines = (transition *)MALLOC( (size_t)(nLevel1+1)*sizeof(transition ) );
00366 
00367         for( i=0; i<nLevel1+1; i++ )
00368         {
00369                 TransitionJunk( &TauLines[i] );
00370                 TauLines[i].Hi = AddState2Stack();
00371                 TauLines[i].Lo = AddState2Stack();
00372                 TauLines[i].Emis = AddLine2Stack( true );
00373         }
00374 
00375         
00376         if( fseek( ioDATA , 0 , SEEK_SET ) != 0 )
00377         {
00378                 fprintf( ioQQQ, " atmdat_readin could not rewind level1.dat.\n");
00379                 cdEXIT(EXIT_FAILURE);
00380         }
00381 
00382         
00383         if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00384         {
00385                 fprintf( ioQQQ, " atmdat_readin could not read first line of level1.dat.\n");
00386                 cdEXIT(EXIT_FAILURE);
00387         }
00388         i = 1;
00389         
00390         nelem = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00391         nelec = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00392         ion = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00393 
00394         
00395 
00396         if( ( nelem != 8 ) || ( nelec != 12 ) || ( ion != 20 ) )
00397         {
00398                 fprintf( ioQQQ, 
00399                         " atmdat_readin: the version of level1.dat is not the current version.\n" );
00400                 fprintf( ioQQQ, 
00401                         " Please obtain the current version from the Cloudy web site.\n" );
00402                 fprintf( ioQQQ, 
00403                         " I expected to find the number 04 11 5 and got %li %li %li instead.\n" ,
00404                         nelem , nelec , ion );
00405                 fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
00406                 cdEXIT(EXIT_FAILURE);
00407         }
00408 
00409         
00410 
00411         i = 1;
00412         while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00413         {
00414                 if( i >= (nLevel1+1) )
00415                 {
00416                         fprintf(ioQQQ," version conflict.\n");
00417                 }
00418                 
00419                 if( chLine[0] != '#')
00420                 {
00421                         
00422 
00423 
00424                         
00425 
00426 
00427 
00428                         
00429 
00430 
00431 
00432 
00433                         
00434                         strncpy( chS2 , chLine , 2);
00435                         chS2[2] = 0;
00436 
00437                         ipZ = 0;
00438                         for( j=0; j<LIMELM; ++j)
00439                         {
00440                                 if( strcmp( elementnames.chElementSym[j], chS2 ) == 0 )
00441                                 {
00442                                         
00443                                         ipZ = j + 1;
00444                                         break;
00445                                 }
00446                         }
00447 
00448                         
00449                         if( ipZ == 0 )
00450                         {
00451                                 fprintf( ioQQQ, 
00452                                         " atmdat_readin could not identify chem symbol on this level 1line:\n");
00453                                 fprintf( ioQQQ, "%s\n", chLine );
00454                                 fprintf( ioQQQ, "looking for this string==%2s==\n",chS2 );
00455                                 cdEXIT(EXIT_FAILURE);
00456                         }
00457 
00458                         
00459                         TauLines[i].Hi->nelem = (int)ipZ;
00460                         
00461 
00462                         j = 1;
00463                         TauLines[i].Hi->IonStg = (int)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00464                         if( lgEOL )
00465                         {
00466                                 fprintf( ioQQQ, " There should have been a number on this level1 line 1.   Sorry.\n" );
00467                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00468                                 cdEXIT(EXIT_FAILURE);
00469                         }
00470 
00471                         TauLines[i].Lo->nelem = TauLines[i].Hi->nelem;
00472                         TauLines[i].Lo->IonStg = TauLines[i].Hi->IonStg;
00473 
00474                         TauLines[i].WLAng = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00475                         if( lgEOL )
00476                         {
00477                                 fprintf( ioQQQ, " There should have been a number on this level1 line 2.   Sorry.\n" );
00478                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00479                                 cdEXIT(EXIT_FAILURE);
00480                         }
00481                         
00482                         TauLines[i].EnergyWN = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00483                         if( lgEOL )
00484                         {
00485                                 fprintf( ioQQQ, " There should have been a number on this level1 line 3.   Sorry.\n" );
00486                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00487                                 cdEXIT(EXIT_FAILURE);
00488                         }
00489                         
00490                         TauLines[i].Lo->g = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00491                         if( lgEOL )
00492                         {
00493                                 fprintf( ioQQQ, " There should have been a number on this level1 line 4.   Sorry.\n" );
00494                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00495                                 cdEXIT(EXIT_FAILURE);
00496                         }
00497                         
00498                         TauLines[i].Hi->g = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00499                         if( lgEOL )
00500                         {
00501                                 fprintf( ioQQQ, " There should have been a number on this level1 line 5.   Sorry.\n" );
00502                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00503                                 cdEXIT(EXIT_FAILURE);
00504                         }
00505                         
00506 
00507                         
00508                         TauLines[i].Emis->gf = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00509                         if( lgEOL )
00510                         {
00511                                 fprintf( ioQQQ, " There should have been a number on this level1 line 6.   Sorry.\n" );
00512                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00513                                 cdEXIT(EXIT_FAILURE);
00514                         }
00515                         
00516                         if( TauLines[i].Emis->gf < 0. )
00517                                 TauLines[i].Emis->gf = (realnum)pow((realnum)10.f,TauLines[i].Emis->gf);
00518 
00519                         
00520                         TauLines[i].Emis->Aul = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00521                         if( lgEOL )
00522                         {
00523                                 fprintf( ioQQQ, " There should have been a number on this level1 line 7.   Sorry.\n" );
00524                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00525                                 cdEXIT(EXIT_FAILURE);
00526                         }
00527                         if( TauLines[i].Emis->Aul < 0. )
00528                                 TauLines[i].Emis->Aul = (realnum)pow((realnum)10.f,TauLines[i].Emis->Aul);
00529                         
00530 
00531                         TauLines[i].Emis->iRedisFun = (int)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00532                         if( lgEOL )
00533                         {
00534                                 fprintf( ioQQQ, " There should have been a number on this level1 line 8.   Sorry.\n" );
00535                                 fprintf( ioQQQ, "string==%s==\n" ,chLine );
00536                                 cdEXIT(EXIT_FAILURE);
00537                         }
00538                         
00539 
00540                         
00541                         TauLines[i].Coll.cs = (realnum)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00542 
00543                         
00544                         ++i;
00545                 }
00546         }
00547 
00548         
00549         fclose(ioDATA);
00550 
00551         
00552 
00553 
00554 
00555 
00556 
00557         
00558 
00559 
00560 
00561         if( nWindLine > 0 )
00562         {
00563                 
00564                 
00565 
00566                 
00567                 TauLine2 = ((transition *)MALLOC( (size_t)nWindLine*sizeof(transition )));
00568                 cs1_flag_lev2 = ((realnum *)MALLOC( (size_t)nWindLine*sizeof(realnum )));
00569 
00570                 
00571                 for( i=0; i< nWindLine; ++i )
00572                 {
00573                         
00574 
00575                         TransitionJunk( &TauLine2[i] );
00576 
00577                         TauLine2[i].Hi = AddState2Stack();
00578                         TauLine2[i].Lo = AddState2Stack();
00579                         TauLine2[i].Emis = AddLine2Stack( true );
00580                 }
00581 
00582                 if( trace.lgTrace )
00583                         fprintf( ioQQQ," atmdat_readin opening level2.dat:");
00584 
00585                 ioDATA = open_data( "level2.dat", "r" );
00586 
00587                 
00588                 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00589                 {
00590                         fprintf( ioQQQ, " level2.dat error getting magic number\n" );
00591                         cdEXIT(EXIT_FAILURE);
00592                 }
00593 
00594                 
00595                 i = 1;
00596                 nelem = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00597                 nelec = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00598                 ion = (long)FFmtRead(chLine,&i,INPUT_LINE_LENGTH,&lgEOL);
00599 
00600                 
00601 
00602 
00603                 if( lgEOL || ( nelem != 6 ) || ( nelec != 8 ) || ( ion != 10 ) )
00604                 {
00605                         fprintf( ioQQQ, 
00606                                 " atmdat_readin: the version of level2.dat is not the current version.\n" );
00607                         fprintf( ioQQQ, 
00608                                 " I expected to find the number 06 08 10 and got %li %li %li instead.\n" ,
00609                                 nelem , nelec , ion );
00610                         fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
00611                         fprintf( ioQQQ, "Please obtain the correct version.\n");
00612                         cdEXIT(EXIT_FAILURE);
00613                 }
00614 
00615                 
00616                 i = 0;
00617                 while( i < nWindLine )
00618                 {
00619                         
00620                         double tt[7];
00621                         if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00622                         {
00623                                 fprintf( ioQQQ, " level2.dat error getting line  %li\n", i );
00624                                 cdEXIT(EXIT_FAILURE);
00625                         }
00626                         
00627                         if( chLine[0]!='#' )
00628                         {
00629                                 
00630                                 sscanf( chLine , "%lf %lf %lf %lf %lf %lf %lf " , 
00631                                         &tt[0] ,
00632                                         &tt[1] ,
00633                                         &tt[2] ,
00634                                         &tt[3] ,
00635                                         &tt[4] ,
00636                                         &tt[5] ,
00637                                         &tt[6] );
00638                                 
00639 
00640                                 TauLine2[i].Hi->nelem = (int)tt[0];
00641                                 TauLine2[i].Hi->IonStg = (int)tt[1];
00642                                 TauLine2[i].Lo->g = (realnum)tt[2];
00643                                 TauLine2[i].Hi->g = (realnum)tt[3];
00644                                 TauLine2[i].Emis->gf = (realnum)tt[4];
00645                                 TauLine2[i].EnergyWN = (realnum)tt[5];
00646                                 cs1_flag_lev2[i] = (realnum)tt[6];
00647                                 ++i;
00648                         }
00649                 }
00650                 
00651                 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00652                 {
00653                         fprintf( ioQQQ, " level2.dat error getting last magic number\n" );
00654                         cdEXIT(EXIT_FAILURE);
00655                 }
00656                 sscanf( chLine , "%ld" , &magic2 );
00657                 if( 999 != magic2 )
00658                 {
00659                         fprintf( ioQQQ, " level2.dat ends will wrong magic number=%ld \n", 
00660                           magic2 );
00661                         cdEXIT(EXIT_FAILURE);
00662                 }
00663                 fclose( ioDATA );
00664                 if( trace.lgTrace )
00665                         fprintf( ioQQQ," OK \n");
00666 
00667                 
00668         }
00669 
00670         
00671 
00672 
00673 
00674 
00675 
00676 
00677 
00678         
00679         nUTA = 0;
00680         nUTA_Gu06 = 0;
00681         nUTA_Behar = 0;
00682         nUTA_Romas = 0;
00683         
00684 
00685 
00686         if( ionbal.lgInnerShell_Gu06 )
00687         {
00688                 if( trace.lgTrace )
00689                         fprintf( ioQQQ," atmdat_readin opening UTA_Gu06.dat:");
00690 
00691                 ioGU06 = open_data( "UTA_Gu06.dat", "r" );
00692 
00693                 
00694                 while( read_whole_line( chLine , (int)sizeof(chLine) , ioGU06 ) != NULL )
00695                 {
00696                         
00697 
00698                         if( chLine[0] != '#')
00699                                 ++nUTA_Gu06;
00700                 }
00701                 
00702                 ASSERT( nUTA_Gu06 > 0 );
00703                 --nUTA_Gu06;
00704 
00705                 
00706                 if( fseek( ioGU06 , 0 , SEEK_SET ) != 0 )
00707                 {
00708                         fprintf( ioQQQ, " atmdat_readin could not rewind UTA_Gu06.dat.\n");
00709                         cdEXIT(EXIT_FAILURE);
00710                 }
00711 
00712                 
00713 
00714                 
00715                 while( read_whole_line( chLine , (int)sizeof(chLine) , ioGU06 ) != NULL )
00716                 {
00717                         
00718 
00719                         if( chLine[0] != '#')
00720                                 break;
00721                 }
00722                 
00723                 j = 1;
00724                 nelem = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00725                 nelec = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00726                 ion = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00727 
00728                 
00729 
00730                 if( ( nelem != 2007 ) || ( nelec != 1 ) || ( ion != 23 ) )
00731                 {
00732                         fprintf( ioQQQ, 
00733                                 " atmdat_readin: the version of UTA_Gu06.dat is not the current version.\n" );
00734                         fprintf( ioQQQ, 
00735                                 " I expected to find the number 2007 1 23 and got %li %li %li instead.\n" ,
00736                                 nelem , nelec , ion );
00737                         fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
00738                         cdEXIT(EXIT_FAILURE);
00739                 }
00740         }
00741         else
00742         {
00743                 
00744                 
00745 
00746 
00747 
00748 
00749                 if( trace.lgTrace )
00750                         fprintf( ioQQQ," atmdat_readin opening UTA_Behar.dat:");
00751 
00752                 ioBEHAR = open_data( "UTA_Behar.dat", "r" );
00753 
00754                 
00755 
00756                 if( read_whole_line( chLine , (int)sizeof(chLine) , ioBEHAR ) == NULL )
00757                 {
00758                         fprintf( ioQQQ, " atmdat_readin could not read first line of UTA_Behar.dat.\n");
00759                         cdEXIT(EXIT_FAILURE);
00760                 }
00761 
00762                 j = 1;
00763                 
00764                 nelem = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00765                 nelec = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00766                 ion = (long)FFmtRead(chLine,&j,INPUT_LINE_LENGTH,&lgEOL);
00767 
00768                 
00769 
00770                 
00771 
00772                 if( ( nelem != 2002 ) || ( nelec != 10 ) || ( ion != 22 ) )
00773                 {
00774                         fprintf( ioQQQ, 
00775                                 " atmdat_readin: the version of UTA_Behar.dat is not the current version.\n" );
00776                         fprintf( ioQQQ, 
00777                                 " I expected to find the number 2002 10 22 and got %li %li %li instead.\n" ,
00778                                 nelem , nelec , ion );
00779                         fprintf( ioQQQ, "Here is the line image:\n==%s==\n", chLine );
00780                         cdEXIT(EXIT_FAILURE);
00781                 }
00782         }
00783 
00784         if( trace.lgTrace )
00785                 fprintf( ioQQQ," atmdat_readin UTA data files open OK\n");
00786 
00787         
00788 
00789         nUTA_Behar = 0;
00790 
00791         
00792         for( ipISO=ipLI_LIKE; ipISO<=ipF_LIKE; ++ipISO )
00793         {
00794                 for( nelem=ipISO; nelem<LIMELM; ++nelem )
00795                 {
00796                         ++nUTA_Behar;
00797                 }
00798         }
00799 
00800         if( !ionbal.lgInnerShell_Gu06 )
00801         {
00802                 
00803 
00804                 while( read_whole_line( chLine , (int)sizeof(chLine) , ioBEHAR ) != NULL )
00805                 {
00806                         
00807 
00808                         if( chLine[0] != '#')
00809                                 ++nUTA_Behar;
00810                 }
00811                 
00812                 if( fseek( ioBEHAR , 0 , SEEK_SET ) != 0 )
00813                 {
00814                         fprintf( ioQQQ, " atmdat_readin could not rewind UTA_Behar.dat.\n");
00815                         cdEXIT(EXIT_FAILURE);
00816                 }
00817                 
00818                 if( read_whole_line( chLine , (int)sizeof(chLine) , ioBEHAR ) == NULL )
00819                 {
00820                         fprintf( ioQQQ, " atmdat_readin could not read first line of UTA_Behar.dat.\n");
00821                         cdEXIT(EXIT_FAILURE);
00822                 }
00823         }
00824 
00825         
00826 
00827 
00828 
00829         if( trace.lgTrace )
00830                 fprintf( ioQQQ," atmdat_readin opening UTA_Kisielius.dat:");
00831 
00832         ioROMAS = open_data( "UTA_Kisielius.dat", "r" );
00833 
00834         nUTA_Romas = 0;
00835         while( read_whole_line( chLine , (int)sizeof(chLine) , ioROMAS ) != NULL )
00836         {
00837                 
00838 
00839                 if( chLine[0] != '#')
00840                 {
00841                         ++nUTA_Romas;
00842                 }
00843         }
00844 
00845         
00846 
00847         UTALines = (transition *)MALLOC( (size_t)(nUTA_Behar+nUTA_Romas+nUTA_Gu06)*sizeof(transition) );
00848 
00849         for( i=0; i<nUTA_Behar+nUTA_Romas+nUTA_Gu06; i++ )
00850         {
00851                 TransitionJunk( &UTALines[i] );
00852                 UTALines[i].Hi = AddState2Stack();
00853                 UTALines[i].Lo = AddState2Stack();
00854                 UTALines[i].Emis = AddLine2Stack( true );
00855         }
00856 
00857         
00858         for( ion=0; ion<ipIRON; ++ion )
00859         {
00860                 nFeIonRomas[ion] = 0;
00861                 WLloRomas[ion] = 1e10;
00862                 WLhiRomas[ion] = 0.;
00863 
00864                 nFeIonBehar[ion] = 0;
00865                 WLloBehar[ion] = 1e10;
00866                 WLhiBehar[ion] = 0.;
00867 
00868                 nFeIonGu[ion] = 0;
00869                 WLloGu[ion] = 1e10;
00870                 WLhiGu[ion] = 0.;
00871         }
00872 
00873         
00874         i = 0;
00875         
00876         if( fseek( ioROMAS , 0 , SEEK_SET ) != 0 )
00877         {
00878                 fprintf( ioQQQ, " atmdat_readin could not rewind UTA_Kisielius.dat.\n");
00879                 cdEXIT(EXIT_FAILURE);
00880         }
00881 
00882         i = 0;
00883         
00884 
00885         for( ipISO=ipLI_LIKE; ipISO<=ipF_LIKE; ++ipISO )
00886         {
00887                 for( nelem=ipISO; nelem<LIMELM; ++nelem )
00888                 {
00889                         double f1;
00890                         double sum_spon_auto;
00891 #                       define N 7
00892 
00893                         double alam[N]={ 1.859035 , 4.692138 ,  10.324543 , 19.294364 ,
00894                                 40.401292  ,  44.442754 , 72.959719 };
00895                         double blam[N]={-9.7855968,-11.159739, -12.914931 , -14.987272,
00896                                 -18.853446 , -19.271781 ,-23.828388 };
00897                         double clam[N]={ 8.2874628, 8.3043002,  8.3164038 ,  8.3269937,
00898                                 8.4312895  , 8.3730893  , 8.493802 };
00899                         
00900 
00901                         double aA[N] = {1.9067 , 1.8715 ,  2.1033, 2.2815 ,
00902                                 1.9511 , 1.9966 ,  2.0852};
00903                         double bA[N] = {8.4538 , 8.5528, 7.616, 6.9247 ,
00904                                 7.9479, 7.9777 , 7.8349 };
00905 
00906                         double aDep[N] = {29.54 , 12.07 , 24.23 , 7.35 , 7.37 , 11.14 , 11.99 };
00907                         double bDep[N] = {-14.853 , -7.606 , -7.844 ,  9.987 , 10.503 , 8.541 , 8.865 };
00908 
00909                         
00910                         
00911                         UTALines[i].Hi->nelem = nelem+1;
00912                         ion = nelem + 1 - ipISO;
00913                         UTALines[i].Hi->IonStg = ion;
00914 
00915                         
00917                         UTALines[i].Hi->g = 4.f;
00918                         UTALines[i].Lo->g = 2.f;
00919 
00920                         f1 = alam[ipISO-2]*1e-4 + blam[ipISO-2]*1e-4*(nelem+1) + 
00921                                 clam[ipISO-2]*1e-4*POW2(nelem+1.);
00922                         f1 = (1./f1);
00923                         UTALines[i].WLAng = (realnum)f1;
00924                         UTALines[i].EnergyWN = (realnum)(1e8/f1);
00925                         UTALines[i].EnergyErg = (realnum)(ERG1CM)*UTALines[i].EnergyWN;
00926 
00927                         f1 = aA[ipISO-2]*log((double)(nelem+1)) + bA[ipISO-2];  
00928 
00929                         UTALines[i].Emis->Aul = (realnum)pow(10., f1 );
00930                         
00931                         UTALines[i].Emis->gf = 
00932                                 (realnum)(UTALines[i].Emis->Aul*UTALines[i].Hi->g*
00933                                 1.4992e-8*POW2(1e4/UTALines[i].EnergyWN));
00934 
00935                         UTALines[i].Emis->iRedisFun = 1;
00936 
00937                         
00938                         f1 = log((double)(nelem+1));
00939                         f1 = POW2( f1 );
00940                         sum_spon_auto = aDep[ipISO-2]*1e-2*f1 + bDep[ipISO-2]*1e-1;
00941 
00942                         if( ipISO == ipBE_LIKE )
00943                         {
00944                                 sum_spon_auto = exp( sum_spon_auto );
00945                                 sum_spon_auto = pow(10., sum_spon_auto )*1e13;
00946                         }
00947                         else if( ipISO <= ipF_LIKE )
00948                         {
00949                                 sum_spon_auto = pow(10., sum_spon_auto )*1e13;
00950                         }
00951                         else
00952                                 TotalInsanity();
00953 
00954                         
00955 
00956                         
00957 
00958                         
00959                         UTALines[i].Coll.cs = (realnum)MIN2(0., UTALines[i].Emis->Aul / sum_spon_auto - 1. );
00960 
00961                         
00962 #                       if 0
00963                         fprintf(ioQQQ," %2s%2li\t%.4f\t%.3e\t%.3e\t%.3e\n",
00964                                 elementnames.chElementSym[nelem], 
00965                                 ion, 
00966                                 UTALines[i].WLAng ,
00967                                 UTALines[i].Emis->Aul ,
00968                                 sum_spon_auto , 
00969                                 -UTALines[i].cs);
00970 #                       endif
00971 
00972                         
00973                         ++i;
00974 #                       undef N
00975                 }
00976         }
00977 
00978         
00979         if( ionbal.lgInnerShell_Gu06 )
00980         {
00981                 ioDATA = ioGU06;
00982                 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00983                 {
00984                         
00985                         if( chLine[0] != '#')
00986                         {
00987                                 long int i2;
00988                                 double WLAng, Aul, oscill , Aauto;
00989 
00990                                 sscanf( chLine ,"%4li%5li%8lf%13le%12le",
00991                                         &ion,&i2,&WLAng,&Aul,&Aauto);
00992                                 sscanf( &chLine[54] ,"%13le", &oscill);
00993 
00994                                 
00995                                 UTALines[i].Hi->nelem = ipIRON+1;
00996 
00997                                 
00998                                 ASSERT( ion >= 0 && ion < ipIRON );
00999                                 
01000 
01001                                 UTALines[i].Hi->IonStg = ion;
01002 
01003                                 
01004 
01005 
01006                                 UTALines[i].Hi->g = 1.f;
01007                                 UTALines[i].Lo->g = 1.f;
01008 
01009                                 
01010                                 UTALines[i].WLAng = (realnum)WLAng;
01011 
01012                                 
01013                                 ++nFeIonGu[ion-1];
01014                                 WLloGu[ion-1] = MIN2( WLAng , WLloGu[ion-1] );
01015                                 WLhiGu[ion-1] = MAX2( WLAng , WLloGu[ion-1] );
01016 
01017                                 
01018                                 UTALines[i].EnergyWN = (realnum)(1e8/WLAng);
01019                                 UTALines[i].EnergyErg = (realnum)(ERG1CM)*UTALines[i].EnergyWN;
01020 
01021                                 
01022 
01023                                 UTALines[i].Emis->Aul = (realnum)Aul;
01024 
01025                                 
01026 
01027 
01028 
01029                                 double frac_ioniz = Aauto/(Aul + Aauto);
01030                                 ASSERT( frac_ioniz >=0. &&  frac_ioniz <=1. );
01031                                 UTALines[i].Coll.cs = -(realnum)frac_ioniz;
01032 
01033                                 
01034                                 UTALines[i].Emis->gf = UTALines[i].Lo->g * (realnum)oscill;
01035 
01036                                 
01037 
01038 
01039 
01040                                 UTALines[i].Emis->Aul = (realnum)eina(UTALines[i].Emis->gf,
01041                                         UTALines[i].EnergyWN,UTALines[i].Hi->g);
01042 
01043                                 UTALines[i].Emis->iRedisFun = 1;
01044                                 {
01045                                         
01046                                         
01047                                         enum {DEBUG_LOC=false};
01048                                         
01049                                         if( DEBUG_LOC && UTALines[i].Hi->nelem==ipIRON+1 && UTALines[i].Hi->IonStg==9)
01050                                         {
01051                                                 fprintf(ioQQQ,"DEBUG Gu UTA\t%li\t%.3f\t%.3e\t%.3e\t%.3e\n",
01052                                                         ion , WLAng,Aul , 
01053                                                         eina(UTALines[i].Emis->gf,
01054                                                         UTALines[i].EnergyWN,UTALines[i].Hi->g),
01055                                                         Aauto );
01056                                         }
01057                                 }
01058 
01059                                 
01060                                 ++i;
01061                         }
01062                 }
01063         }
01064         else
01065         {
01066                 
01067                 nUTA_Gu06 = 0;
01068 
01069                 
01070                 
01071                 ioDATA = ioBEHAR;
01072                 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
01073                 {
01074                         
01075                         if( chLine[0] != '#')
01076                         {
01077                                 long int i1, i2, i3;
01078                                 double f1, f2, oscill;
01079                                 double frac_relax;
01080 
01081                                 sscanf( chLine ,"%li\t%li\t%li\t%lf\t%le\t%le\t%le",
01082                                         &i1,&i2,&i3,&f1,&f2,&frac_relax,&oscill );
01083 
01084                                 
01085                                 UTALines[i].Hi->nelem = ipIRON+1;
01086 
01087                                 
01088                                 ASSERT( i1 >= 0 && i1 < ipIRON );
01089                                 
01090 
01091                                 UTALines[i].Hi->IonStg = i1 + 1;
01092 
01093                                 
01094                                 if( i2>0 && i3>0 )
01095                                 {
01096                                         UTALines[i].Hi->g = (realnum)i2;
01097                                         UTALines[i].Lo->g = (realnum)i3;
01098                                 }
01099                                 else
01100                                 {
01101                                         
01102 
01103                                         UTALines[i].Hi->g = 1.f;
01104                                         UTALines[i].Lo->g = 1.f;
01105                                 }
01106 
01107                                 
01108                                 UTALines[i].WLAng = (realnum)f1;
01109 
01110                                 
01111                                 ++nFeIonBehar[i1];
01112                                 WLloBehar[i1] = MIN2( f1 , WLloBehar[i1] );
01113                                 WLhiBehar[i1] = MAX2( f1 , WLhiBehar[i1] );
01114 
01115                                 
01116                                 UTALines[i].EnergyWN = (realnum)(1e8/f1);
01117                                 UTALines[i].EnergyErg = (realnum)(ERG1CM)*UTALines[i].EnergyWN;
01118 
01119                                 
01120 
01121                                 UTALines[i].Emis->Aul = (realnum)f2;
01122 
01123                                 
01124 
01125                                 UTALines[i].Emis->gf = UTALines[i].Lo->g * (realnum)oscill;
01126 
01127                                 UTALines[i].Emis->iRedisFun = 1;
01128 
01129                                 
01130 
01131                                 
01132                                 ASSERT( frac_relax >=0. &&  frac_relax <=1. );
01133                                 UTALines[i].Coll.cs = (realnum)(frac_relax-1.);
01134 #                               if 0
01135                                 fprintf(ioQQQ,"data set %li line %li %2s%2li\t%.4f\t%.3e\t%.3e\n",
01136                                         nDataSet,
01137                                         i,
01138                                         elementnames.chElementSym[UTALines[i].Hi->nelem-1], 
01139                                         UTALines[i].Hi->IonStg, 
01140                                         UTALines[i].WLAng ,
01141                                         UTALines[i].Emis->Aul ,
01142                                         -UTALines[i].cs);
01143 #                               endif
01144 
01145                                 
01146                                 ++i;
01147                         }
01148                 }
01149         }
01150 
01151         
01152 
01153 
01154 
01155 
01156         ioDATA = ioROMAS;
01157         while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
01158         {
01159                 
01160                 if( chLine[0] != '#')
01161                 {
01162                         long int i1, i2, i3;
01163                         double f1, f2, oscill;
01164                         double frac_relax;
01165 
01166                         sscanf( chLine ,"%li\t%li\t%li\t%lf\t%le\t%le\t%le",
01167                                 &i1,&i2,&i3,&f1,&f2,&frac_relax,&oscill );
01168 
01169                         
01170                         UTALines[i].Hi->nelem = ipIRON+1;
01171 
01172                         
01173                         ASSERT( i1 >= 0 && i1 < ipIRON );
01174                         
01175 
01176                         UTALines[i].Hi->IonStg = i1 + 1;
01177 
01178                         
01179                         if( i2>0 && i3>0 )
01180                         {
01181                                 UTALines[i].Hi->g = (realnum)i2;
01182                                 UTALines[i].Lo->g = (realnum)i3;
01183                         }
01184                         else
01185                         {
01186                                 
01187 
01188                                 UTALines[i].Hi->g = 1.f;
01189                                 UTALines[i].Lo->g = 1.f;
01190                         }
01191 
01192                         
01193                         UTALines[i].WLAng = (realnum)f1;
01194 
01195                         
01196                         ++nFeIonRomas[i1];
01197                         WLloRomas[i1] = MIN2( f1 , WLloRomas[i1] );
01198                         WLhiRomas[i1] = MAX2( f1 , WLhiRomas[i1] );
01199 
01200                         UTALines[i].EnergyWN = (realnum)(1e8/f1);
01201                         UTALines[i].EnergyErg = (realnum)(ERG1CM)*UTALines[i].EnergyWN;
01202 
01203                         
01204 
01205                         UTALines[i].Emis->Aul = (realnum)f2;
01206                         
01207                         
01208 
01209                         UTALines[i].Emis->gf = UTALines[i].Lo->g * (realnum)oscill;
01210 
01211                         UTALines[i].Emis->iRedisFun = 1;
01212 
01213                         
01214 
01215                         
01216                         ASSERT( frac_relax >=0. &&  frac_relax <=1. );
01217                         UTALines[i].Coll.cs = (realnum)(frac_relax-1.);
01218 
01219                         
01220                         ++i;
01221                 }
01222         }
01223 
01224         
01225         ASSERT( i == (nUTA_Behar+nUTA_Romas+nUTA_Gu06) );
01226 
01227         if( trace.lgTrace )
01228         {
01229                 fprintf(ioQQQ , "summary of UTA data sets read in\nion numb     WLlo    WLhi\n");
01230                 fprintf(ioQQQ , "Behar 01 total lines %li\n" , nUTA_Behar );
01231                 for( ion=0; ion<ipIRON;++ion )
01232                 {
01233                         if( nFeIonBehar[ion] )
01234                         {
01235                                 fprintf(ioQQQ, "%3li %6li %7.3f %7.3f \n", 
01236                                         ion,
01237                                         nFeIonBehar[ion],
01238                                         WLloBehar[ion],
01239                                         WLhiBehar[ion]);
01240                         }
01241                 }
01242 
01243                 fprintf(ioQQQ , "Gu 06 total lines %li\n" , nUTA_Gu06 );
01244                 for( ion=0; ion<ipIRON;++ion )
01245                 {
01246                         if( nFeIonGu[ion] )
01247                         {
01248                                 fprintf(ioQQQ, "%3li %6li %7.3f %7.3f \n", 
01249                                         ion,
01250                                         nFeIonGu[ion],
01251                                         WLloGu[ion],
01252                                         WLhiGu[ion]);
01253                         }
01254                 }
01255 
01256                 fprintf(ioQQQ , "Romas Kisielius 03 total lines %li\n", nUTA_Romas );
01257                 for( ion=0; ion<ipIRON;++ion )
01258                 {
01259                         if( nFeIonRomas[ion] )
01260                         {
01261                                 fprintf(ioQQQ, "%3li %6li %7.3f %7.3f \n", 
01262                                         ion,
01263                                         nFeIonRomas[ion],
01264                                         WLloRomas[ion],
01265                                         WLhiRomas[ion] );
01266                         }
01267                 }
01268         }
01269 
01270         
01271 
01272 
01273         
01274 
01275 
01276         if( ionbal.lgInnerShell_Kisielius )
01277         {
01278                 for( i=0; i<nUTA_Behar+nUTA_Gu06; ++i )
01279                 {
01280                         if( UTALines[i].Hi->nelem-1 == ipIRON )
01281                         {
01282                                 
01283 
01284 
01285 
01286                                 ASSERT( UTALines[i].Hi->IonStg-1< ipIRON );
01287                                 if( nFeIonRomas[UTALines[i].Hi->IonStg-1] )
01288                                 {
01289                                         UTALines[i].Emis->Aul = -1.;
01290                                 }
01291                         }
01292                 }
01293                 
01294                 nUTA = nUTA_Behar + nUTA_Gu06 + nUTA_Romas;
01295         }
01296         else
01297         {
01298                 
01299 
01300 
01301                 nUTA = nUTA_Behar + nUTA_Gu06;
01302         }
01303 
01304         
01305         fclose(ioROMAS);
01306         if( ionbal.lgInnerShell_Gu06 )
01307                 fclose(ioGU06);
01308         else
01309                 fclose(ioBEHAR);
01310 
01311         
01312 
01313         
01314         ASSERT( nCORotate > 0);
01315         C12O16Rotate = (transition *)MALLOC( (size_t)nCORotate*sizeof(transition) );
01316         C13O16Rotate = (transition *)MALLOC( (size_t)nCORotate*sizeof(transition) );
01317 
01318         
01319         lgCORotateMalloc = true;
01320 
01321         
01322         for( J=0; J< nCORotate; ++J )
01323         {
01324                 TransitionJunk( &C12O16Rotate[J] );
01325                 C12O16Rotate[J].Hi = AddState2Stack();
01326                 C12O16Rotate[J].Lo = AddState2Stack();
01327                 C12O16Rotate[J].Emis = AddLine2Stack( true );
01328 
01329                 TransitionJunk( &C13O16Rotate[J] );
01330                 C13O16Rotate[J].Hi = AddState2Stack();
01331                 C13O16Rotate[J].Lo = AddState2Stack();
01332                 C13O16Rotate[J].Emis = AddLine2Stack( true );
01333         }
01334 
01335         
01336 
01337         HyperfineCreate();
01338 
01339         
01340         
01341 
01342         
01343         lines_setup();
01344 
01345         
01346         
01347 
01348 
01349         
01350 
01351         if( trace.lgTrace )
01352                 fprintf( ioQQQ," atmdat_readin opening mewe_gbar.dat:");
01353 
01354         ioDATA = open_data( "mewe_gbar.dat", "r" );
01355 
01356         
01357         if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
01358         {
01359                 fprintf( ioQQQ, " mewe_gbar.dat error getting magic number\n" );
01360                 cdEXIT(EXIT_FAILURE);
01361         }
01362         
01363         sscanf( chLine , "%ld" , &magic1 );
01364         if( magic1 != 9101 )
01365         {
01366                 fprintf( ioQQQ, " mewe_gbar.dat starts with wrong magic number=%ld \n", 
01367                   magic1 );
01368                 cdEXIT(EXIT_FAILURE);
01369         }
01370 
01371         
01372         for( i=1; i < 210; i++ )
01373         {
01374                 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
01375                 {
01376                         fprintf( ioQQQ, " mewe_gbar.dat error getting line  %li\n", i );
01377                         cdEXIT(EXIT_FAILURE);
01378                 }
01379                 
01380                 double help[4];
01381                 sscanf( chLine, "%lf %lf %lf %lf ", &help[0], &help[1], &help[2], &help[3] );
01382                 for( int l=0; l < 4; ++l )
01383                         MeweCoef.g[i][l] = (realnum)help[l];
01384         }
01385 
01386         
01387         if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
01388         {
01389                 fprintf( ioQQQ, " mewe_gbar.dat error getting last magic number\n" );
01390                 cdEXIT(EXIT_FAILURE);
01391         }
01392 
01393         sscanf( chLine , "%ld" , &magic2 );
01394 
01395         if( magic1 != magic2 )
01396         {
01397                 fprintf( ioQQQ, " mewe_gbar.dat ends will wrong magic number=%ld \n", 
01398                   magic2 );
01399                 cdEXIT(EXIT_FAILURE);
01400         }
01401 
01402         fclose( ioDATA );
01403 
01404         if( trace.lgTrace )
01405                 fprintf( ioQQQ," OK \n");
01406 
01407          
01408 
01409 
01410         for( nelem=0; nelem < LIMELM; nelem++ )
01411                 for( ion=0; ion < LIMELM; ion++ )
01412                         Heavy.nsShells[nelem][ion] = LONG_MAX;
01413 
01414         
01415 
01416 
01417 
01418         for( nelem=2; nelem < LIMELM; nelem++ )
01419         {
01420                 
01421                 for( ion=0; ion <= nelem; ion++ )
01422                 {
01423                         
01424                         nelec = nelem - ion + 1;
01425                         
01426 
01427                         
01428 
01429 
01430 
01431 
01432                         atmdat_outer_shell(nelem+1,nelec,&imax,&ig0,&ig1);
01433 
01434                         ASSERT( imax > 0 && imax <= 10 );
01435 
01436                         
01437 
01438                         Heavy.nsShells[nelem][ion] = imax;
01439                 }
01440         }
01441 
01442         
01443 
01444 
01445 
01446 
01447 
01448         t_yield::Inst().init_yield();
01449 
01450         
01451 
01452 
01453 
01454 
01455 
01456 
01457         
01458         
01459 
01460         for( ipZ=0; ipZ<HS_NZ; ++ipZ )
01461         {
01462                 
01463                 if( ipZ>1 && ipZ<5 ) continue;
01464 
01465                 for( iCase=0; iCase<2; ++iCase )
01466                 {
01467                         
01468                         
01469                         
01470 
01471 
01472                         sprintf( chFilename, "HS_e%ld%c.dat", ipZ+1, ( iCase == 0 ) ? 'a' : 'b' );
01473 
01474                         if( trace.lgTrace )
01475                                 fprintf( ioQQQ," atmdat_readin opening Hummer Storey emission file %s:",chFilename);
01476 
01477                         
01478                         ioDATA = open_data( chFilename, "r" );
01479 
01480                         if( trace.lgTrace )
01481                         {
01482                                 fprintf( ioQQQ," OK\n");
01483                         }
01484 
01485                         
01486                         i = fscanf( ioDATA, "%li %li ", 
01487                                 &atmdat.ntemp[iCase][ipZ], &atmdat.nDensity[iCase][ipZ] );
01488 
01489                         
01490 
01491                         assert (atmdat.ntemp[iCase][ipZ] >0 && atmdat.ntemp[iCase][ipZ] <= NHSDIM );
01492                         assert (atmdat.nDensity[iCase][ipZ] > 0 && atmdat.nDensity[iCase][ipZ] <= NHSDIM);
01493 
01494                         
01495                         for( ipTemp=0; ipTemp < atmdat.ntemp[iCase][ipZ]; ipTemp++ )
01496                         {
01497                                 for( ipDens=0; ipDens < atmdat.nDensity[iCase][ipZ]; ipDens++ )
01498                                 {
01499                                         long int junk, junk2 , ne;
01500                                         fscanf( ioDATA, " %lf %li %lf %c %li %ld ", 
01501                                                 &atmdat.Density[iCase][ipZ][ipDens], &junk , 
01502                                                 &atmdat.ElecTemp[iCase][ipZ][ipTemp], &cha , &junk2 , 
01503                                                 &atmdat.ncut[iCase][ipZ] );
01504 
01505                                         ne = atmdat.ncut[iCase][ipZ]*(atmdat.ncut[iCase][ipZ] - 1)/2;
01506                                         ASSERT( ne<=NLINEHS );
01507                                         for( j=0; j < ne; j++ )
01508                                         {
01509                                                 fscanf( ioDATA, "%lf ", &atmdat.Emiss[iCase][ipZ][ipTemp][ipDens][j] );
01510                                         }
01511                                 }
01512                         }
01513 
01514                         
01515                         fclose(ioDATA); 
01516 #                       if 0
01517                         
01518                         for( ipDens=0; ipDens<atmdat.nDensity[iCase][ipZ]; ipDens++ )
01519                         {
01520                                 fprintf(ioQQQ," %e,", atmdat.Density[iCase][ipZ][ipDens]);
01521                         }
01522                         fprintf(ioQQQ,"\n");
01523                         for( ipTemp=0; ipTemp<atmdat.ntemp[iCase][ipZ]; ipTemp++ )
01524                         {
01525                                 fprintf(ioQQQ," %e,", atmdat.ElecTemp[iCase][ipZ][ipTemp]);
01526                         }
01527                         fprintf(ioQQQ,"\n");
01528 #                       endif
01529                 }
01530         }
01531 
01532         
01533 
01534 
01535         
01536         
01537         FeIICreate();
01538         return;
01539 }
01540 
01541 t_yield::t_yield()
01542 {
01543          
01544 
01545 
01546         for( int nelem=0; nelem < LIMELM; nelem++ )
01547         {
01548                 for( int ion=0; ion < LIMELM; ion++ )
01549                 {
01550                         for( int ns=0; ns < 7; ns++ )
01551                         {
01552                                 n_elec_eject[nelem][ion][ns] = LONG_MAX;
01553                                 for( int nelec=0; nelec < 10; nelec++ )
01554                                 {
01555                                         frac_elec_eject[nelem][ion][ns][nelec] = FLT_MAX;
01556                                 }
01557                         }
01558                 }
01559         }
01560 
01561         lgKillAuger = false;
01562 }
01563 
01564 void t_yield::init_yield()
01565 {
01566         char chLine[FILENAME_PATH_LENGTH_2];
01567         const char* chFilename;
01568 
01569         
01570         double temp[15];
01571 
01572         DEBUG_ENTRY( "init_yield()" );
01573 
01574         
01575 
01576 
01577 
01578 
01579 
01580         
01581 
01582 
01583         ASSERT( Heavy.nsShells[2][0] > 0 );
01584 
01585         
01586         n_elec_eject[ipHYDROGEN][0][0] = 1;
01587         n_elec_eject[ipHELIUM][0][0] = 1;
01588         n_elec_eject[ipHELIUM][1][0] = 1;
01589 
01590         frac_elec_eject[ipHYDROGEN][0][0][0] = 1;
01591         frac_elec_eject[ipHELIUM][0][0][0] = 1;
01592         frac_elec_eject[ipHELIUM][1][0][0] = 1;
01593 
01594         
01595 
01596         chFilename = "mewe_nelectron.dat";
01597 
01598         if( trace.lgTrace )
01599                 fprintf( ioQQQ, " init_yield opening %s:", chFilename );
01600 
01601         FILE *ioDATA;
01602 
01603         
01604         ioDATA = open_data( chFilename, "r" );
01605 
01606         
01607 
01608 
01609 
01610         for( int nelem=2; nelem < LIMELM; nelem++ )
01611         {
01612                 
01613                 for( int ion=0; ion <= nelem; ion++ )
01614                 {
01615                         for( int ns=0; ns < Heavy.nsShells[nelem][ion]; ns++ )
01616                         {
01617                                 char ch1 = '#';
01618                                 
01619                                 while( ch1 == '#' || ch1 == '*' )
01620                                 {
01621                                         if( read_whole_line( chLine, (int)sizeof(chLine), ioDATA ) == NULL )
01622                                         {
01623                                                 fprintf( ioQQQ, " %s error getting line %i\n", chFilename, ns );
01624                                                 cdEXIT(EXIT_FAILURE);
01625                                         }
01626                                         ch1 = chLine[0];
01627                                 }
01628                                 
01629                                 sscanf( chLine, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", 
01630                                         &temp[0], &temp[1], &temp[2], &temp[3], &temp[4],
01631                                         &temp[5], &temp[6], &temp[7], &temp[8], &temp[9],
01632                                         &temp[10],&temp[11],&temp[12],&temp[13],&temp[14] );
01633                                 n_elec_eject[nelem][ion][ns] = (long int)temp[3];
01634 
01635                                 ASSERT( n_elec_eject[nelem][ion][ns] >= 0 && n_elec_eject[nelem][ion][ns] < 11 );
01636 
01637                                 
01638                                 for( int j=0; j < 10; j++ )
01639                                 {
01640                                         frac_elec_eject[nelem][ion][ns][j] = (realnum)temp[j+4];
01641                                         ASSERT( frac_elec_eject[nelem][ion][ns][j] >= 0. );
01642                                 }
01643                         }
01644                 }
01645                 
01646                 
01647         }
01648 
01649         fclose( ioDATA );
01650 
01651         if( trace.lgTrace )
01652         {
01653                 
01654                 if( lgKillAuger )
01655                         fprintf( ioQQQ, " Auger yields will be killed.\n");
01656                 fprintf( ioQQQ, " OK\n");
01657         }
01658 
01659         
01660 
01661         chFilename = "mewe_fluor.dat";
01662 
01663         if( trace.lgTrace )
01664                 fprintf( ioQQQ, " init_yield opening %s:", chFilename );
01665 
01666         
01667         ioDATA = open_data( chFilename, "r" );
01668 
01669         
01670 
01671 
01672         do 
01673         {
01674                 if( read_whole_line( chLine, (int)sizeof(chLine), ioDATA ) == NULL )
01675                 {
01676                         fprintf( ioQQQ, " %s error getting line %i\n", chFilename, 0 );
01677                         cdEXIT(EXIT_FAILURE);
01678                 }
01679         }
01680         while( chLine[0] == '#' );
01681 
01682         bool lgEOL = false;
01683 
01684         nfl_lines = 0;
01685         do
01686         {
01687                 const int NKM = 10;
01688                 int nDima[NKM] = { 0, 1, 2, 2, 3, 4, 4, 5, 5, 6 };
01689                 int nAuger;
01690 
01691                 if( nfl_lines >= MEWE_FLUOR )
01692                         TotalInsanity();
01693 
01694                 
01695                 sscanf( chLine, "%lf %lf %lf %lf %lf %lf %lf", 
01696                         &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], 
01697                         &temp[5], &temp[6] );
01698 
01699                 
01700                 nfl_nelem[nfl_lines] = (int)temp[0]-1;
01701                 ASSERT( nfl_nelem[nfl_lines] >= 0 && nfl_nelem[nfl_lines] < LIMELM );
01702 
01703                 
01704                 nfl_ion[nfl_lines] = (int)temp[1]-1;
01705                 ASSERT( nfl_ion[nfl_lines] >= 0 && nfl_ion[nfl_lines] <= nfl_nelem[nfl_lines]+1 );
01706 
01707                 
01708                 nfl_nshell[nfl_lines] = nDima[(long)temp[2]-1];
01709                 ASSERT( nfl_nshell[nfl_lines] >= 0 && 
01710                         
01711                         nfl_nshell[nfl_lines] < Heavy.nsShells[nfl_nelem[nfl_lines]][nfl_ion[nfl_lines]]-1 );
01712 
01713                 
01714                 nAuger = (int)temp[3];
01715                 
01716                 nfl_ion_emit[nfl_lines] = nfl_ion[nfl_lines] + nAuger + 1;
01717                 
01718                 ASSERT( nfl_ion_emit[nfl_lines] > 0 && nfl_ion_emit[nfl_lines] <= nfl_nelem[nfl_lines]+1);
01719 
01720                 
01721                 nfl_nLine[nfl_lines] = (int)temp[4];
01722 
01723                 
01724                 fl_energy[nfl_lines] = (realnum)temp[5] / (realnum)EVRYD;
01725                 ASSERT( fl_energy[nfl_lines] > 0. );
01726 
01727                 
01728                 fl_yield[nfl_lines] = (realnum)temp[6];
01729                 
01730                 ASSERT( fl_yield[nfl_lines] >= 0 );
01731 
01732                 ++nfl_lines;
01733 
01734                 do
01735                 {
01736                         if( read_whole_line( chLine, (int)sizeof(chLine), ioDATA ) == NULL )
01737                                 lgEOL = true;
01738                 } 
01739                 while( chLine[0]=='#' && !lgEOL );
01740         } 
01741         while( !lgEOL );
01742 
01743         fclose( ioDATA );
01744 }