00001
00002
00003 #include "cddefines.h"
00004 #include "lines_service.h"
00005 #include "physconst.h"
00006 #include "taulines.h"
00007 #include "trace.h"
00008 #include "string.h"
00009 #include "thirdparty.h"
00010 #include "rfield.h"
00011 #include "atmdat.h"
00012
00013 static const bool DEBUGSTATE = false;
00014
00015 const double ENERGY_MIN_WN = 1e-10;
00016
00017 void atmdat_STOUT_readin( long intNS, char *chPrefix )
00018 {
00019 DEBUG_ENTRY( "atmdat_STOUT_readin()" );
00020
00021 long int nMolLevs;
00022 char chLine[FILENAME_PATH_LENGTH_2],
00023 chNRGFilename[FILENAME_PATH_LENGTH_2],
00024 chTPFilename[FILENAME_PATH_LENGTH_2],
00025 chCOLLFilename[FILENAME_PATH_LENGTH_2];
00026
00027 static const int MAX_NUM_LEVELS = 999;
00028
00029 dBaseSpecies[intNS].lgMolecular = false;
00030 dBaseSpecies[intNS].lgLTE = false;
00031 dBaseSpecies[intNS].lgLAMDA = false;
00032
00033 strcpy( chNRGFilename , chPrefix );
00034 strcpy( chTPFilename , chPrefix );
00035 strcpy( chCOLLFilename , chPrefix );
00036
00037
00038 strcat( chNRGFilename , ".nrg");
00039 uncaps( chNRGFilename );
00040 if(DEBUGSTATE)
00041 printf("The data file is %s \n",chNRGFilename);
00042
00043
00044 if( trace.lgTrace )
00045 fprintf( ioQQQ," atmdat_STOUT_readin opening %s:",chNRGFilename);
00046
00047 FILE *ioDATA;
00048 ioDATA = open_data( chNRGFilename, "r" );
00049 long int i = 0;
00050 bool lgEOL = false;
00051 long index = 0;
00052 double nrg = 0.0;
00053 double stwt = 0.0;
00054
00055
00056 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00057 {
00058 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of %s.\n", chNRGFilename );
00059 cdEXIT(EXIT_FAILURE);
00060 }
00061 i = 1;
00062 const long int iyr = 11, imo=10 , idy = 14;
00063 long iyrread, imoread , idyread;
00064 iyrread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00065 imoread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00066 idyread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00067
00068 if(( iyrread != iyr ) ||
00069 ( imoread != imo ) ||
00070 ( idyread != idy ) )
00071 {
00072 fprintf( ioQQQ,
00073 " PROBLEM atmdat_STOUT_readin: the version of %s is not the current version.\n", chNRGFilename );
00074 fprintf( ioQQQ,
00075 " atmdat_STOUT_readin: I expected the magic numbers %li %li %li but found %li %li %li.\n",
00076 iyr, imo , idy ,iyrread, imoread , idyread );
00077 cdEXIT(EXIT_FAILURE);
00078 }
00079
00080 nMolLevs = 0;
00081
00082 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00083 {
00084
00085 if( chLine[0] != '#' && chLine[0] != '\n' && chLine[0] != '*' )
00086 {
00087 i = 1;
00088 long n = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00089 if( n < 0 )
00090 break;
00091 nMolLevs++;
00092 }
00093 }
00094
00095
00096 if( fseek( ioDATA , 0 , SEEK_SET ) != 0 )
00097 {
00098 fprintf( ioQQQ, " atmdat_STOUT_readin could not rewind %s.\n", chNRGFilename );
00099 cdEXIT(EXIT_FAILURE);
00100 }
00101
00102 read_whole_line( chLine , (int)sizeof(chLine) , ioDATA );
00103
00104 long HighestIndexInFile = nMolLevs;
00105
00106 nMolLevs = MIN3(atmdat.nStoutMaxLevels,nMolLevs, MAX_NUM_LEVELS );
00107
00108 if( atmdat.lgStoutPrint == true)
00109 {
00110 fprintf( ioQQQ," Using STOUT model %s with %li levels of %li available.\n",
00111 dBaseSpecies[intNS].chLabel , nMolLevs , HighestIndexInFile );
00112 }
00113
00114 dBaseSpecies[intNS].numLevels_max = nMolLevs;
00115 dBaseSpecies[intNS].numLevels_local = dBaseSpecies[intNS].numLevels_max;
00116
00117
00118 dBaseStates[intNS].resize(nMolLevs);
00119
00120 dBaseSpecies[intNS].maxWN = 0.;
00121
00122
00123 ipdBaseTrans[intNS].reserve(nMolLevs);
00124 for( long ipHi = 1; ipHi < nMolLevs; ipHi++)
00125 ipdBaseTrans[intNS].reserve(ipHi,ipHi);
00126 ipdBaseTrans[intNS].alloc();
00127 dBaseTrans[intNS].resize(ipdBaseTrans[intNS].size());
00128 dBaseTrans[intNS].states() = &dBaseStates[intNS];
00129 dBaseTrans[intNS].chLabel() = "Stout";
00130
00131
00132
00133 int ndBase = 0;
00134 for( long ipHi = 1; ipHi < nMolLevs; ipHi++)
00135 {
00136 for( long ipLo = 0; ipLo < ipHi; ipLo++)
00137 {
00138 ipdBaseTrans[intNS][ipHi][ipLo] = ndBase;
00139 dBaseTrans[intNS][ndBase].Junk();
00140 dBaseTrans[intNS][ndBase].setLo(ipLo);
00141 dBaseTrans[intNS][ndBase].setHi(ipHi);
00142 ++ndBase;
00143 }
00144 }
00145
00146
00147
00148 bool lgSentinelReached = false;
00149
00150
00151 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00152 {
00153 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of the energy level file.\n");
00154 cdEXIT(EXIT_FAILURE);
00155 }
00156
00157 do
00158 {
00159 i = 1;
00160
00161
00162 if( chLine[0] == '*' )
00163 {
00164 lgSentinelReached = true;
00165 break;
00166 }
00167
00168 if( chLine[0] != '#' )
00169 {
00170
00171 if( chLine[0] == '\n')
00172 continue;
00173
00174 index = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL) -1 ;
00175
00176 if( index < 0 )
00177 {
00178 fprintf( ioQQQ, " PROBLEM An energy level index was less than 1 in file %s\n",chNRGFilename);
00179 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00180 cdEXIT(EXIT_FAILURE);
00181 }
00182
00183 nrg = (double)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00184 stwt = (double)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00185
00186 if( lgEOL )
00187 {
00188 fprintf( ioQQQ, " PROBLEM End of line reached prematurely in file %s\n",chNRGFilename);
00189 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00190 cdEXIT(EXIT_FAILURE);
00191 }
00192
00193 if( index >= nMolLevs )
00194 {
00195
00196 continue;
00197 }
00198
00199 dBaseStates[intNS][index].energy().set(nrg,"cm^-1");
00200 dBaseStates[intNS][index].g() = stwt;
00201
00202
00203 strcpy(dBaseStates[intNS][index].chLabel(), " ");
00204 strncpy(dBaseStates[intNS][index].chLabel(),dBaseSpecies[intNS].chLabel, 4);
00205 dBaseStates[intNS][index].chLabel()[4] = '\0';
00206 }
00207 }
00208 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL );
00209 if( !lgSentinelReached )
00210 {
00211 fprintf( ioQQQ, " PROBLEM End of data sentinel was not reached in file %s\n",chNRGFilename);
00212 fprintf( ioQQQ, " Check that stars (*****) appear after the last line of data and start in the first column of that line.\n");
00213 cdEXIT(EXIT_FAILURE);
00214 }
00215 fclose(ioDATA);
00216
00217 if( DEBUGSTATE )
00218 {
00219
00220 printf("DEBUG STOUT ENERGY LEVELS:\n");
00221 for( int i = 0; i< nMolLevs; i++ )
00222 {
00223 printf("DEBUG\t%i\t%11.4e\t%3.1f\n",i+1,dBaseStates[intNS][i].energy().WN(),dBaseStates[intNS][i].g());
00224 }
00225 }
00226
00227
00228 double fenergyWN = 0.;
00229 for(TransitionList::iterator tr=dBaseTrans[intNS].begin();
00230 tr!= dBaseTrans[intNS].end(); ++tr)
00231 {
00232 int ipHi = (*tr).ipHi();
00233 int ipLo = (*tr).ipLo();
00234 ASSERT(ipHi > ipLo );
00235 fenergyWN = dBaseStates[intNS][ipHi].energy().WN() - dBaseStates[intNS][ipLo].energy().WN();
00236 if( fenergyWN <= 0.)
00237 {
00238 printf("\nWARNING: The %s transition between level %i and %i has zero or negative energy.\n",
00239 dBaseStates[intNS][ipHi].chLabel(),ipLo+1,ipHi+1);
00240 printf("Check the Stout energy level data file (*.nrg) of this species for missing or duplicate energies.\n");
00241
00242 }
00243 (*tr).EnergyWN() = (realnum)MAX2(ENERGY_MIN_WN,fenergyWN);
00244 (*tr).WLAng() = (realnum)(1e+8/(*tr).EnergyWN()/RefIndex((*tr).EnergyWN()));
00245 dBaseSpecies[intNS].maxWN = MAX2(dBaseSpecies[intNS].maxWN,(*tr).EnergyWN());
00246 }
00247
00248
00249
00250
00251 strcat( chTPFilename , ".tp");
00252 uncaps( chTPFilename );
00253
00254 ioDATA = open_data( chTPFilename, "r" );
00255
00256
00257 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00258 {
00259 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of %s.\n", chTPFilename );
00260 cdEXIT(EXIT_FAILURE);
00261 }
00262 i = 1;
00263 iyrread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00264 imoread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00265 idyread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00266
00267 if(( iyrread != iyr ) ||
00268 ( imoread != imo ) ||
00269 ( idyread != idy ) )
00270 {
00271 fprintf( ioQQQ,
00272 " PROBLEM atmdat_STOUT_readin: the version of %s is not the current version.\n", chTPFilename );
00273 fprintf( ioQQQ,
00274 " atmdat_STOUT_readin: I expected the magic numbers %li %li %li but found %li %li %li.\n",
00275 iyr, imo , idy ,iyrread, imoread , idyread );
00276 cdEXIT(EXIT_FAILURE);
00277 }
00278
00279 long numtrans = 0;
00280
00281 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
00282 {
00283
00284 if( chLine[0] != '#' && chLine[0] != '\n' && chLine[0] != '*' )
00285 {
00286 i = 1;
00287 long n = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00288 if( n < 0 )
00289 break;
00290 numtrans++;
00291 }
00292 }
00293
00294 if( fseek( ioDATA , 0 , SEEK_SET ) != 0 )
00295 {
00296 fprintf( ioQQQ, " atmdat_STOUT_readin could not rewind %s.\n", chTPFilename );
00297 cdEXIT(EXIT_FAILURE);
00298 }
00299
00300 read_whole_line( chLine , (int)sizeof(chLine) , ioDATA );
00301
00302
00303
00304 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00305 {
00306 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of the transition probability file.\n");
00307 cdEXIT(EXIT_FAILURE);
00308 }
00309
00310 long ipLo = 0;
00311 long ipHi = 0;
00312 double Aul = 0.0;
00313 lgSentinelReached = false;
00314
00315 do
00316 {
00317 if( chLine[0] == '*' )
00318 {
00319 lgSentinelReached = true;
00320 break;
00321 }
00322
00323
00324 if( chLine[0] != '#' )
00325 {
00326 i = 1;
00327
00328
00329 if( chLine[0] == '\n')
00330 continue;
00331
00332
00333 if( nMatch("A",chLine) )
00334 {
00335
00336 i = 1;
00337
00338 ipLo= (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL) - 1;
00339 ipHi = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL) - 1;
00340 Aul = (double)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00341 if( lgEOL )
00342 {
00343 fprintf( ioQQQ, " PROBLEM End of line reached prematurely in file %s\n",chTPFilename);
00344 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00345 cdEXIT(EXIT_FAILURE);
00346 }
00347
00348 if( ipLo >= nMolLevs || ipHi >= nMolLevs )
00349 {
00350
00351 continue;
00352 }
00353
00354 TransitionList::iterator tr = dBaseTrans[intNS].begin()+ipdBaseTrans[intNS][ipHi][ipLo];
00355 if( (*tr).hasEmis() )
00356 {
00357 fprintf(ioQQQ," PROBLEM duplicate transition found by atmdat_STOUT_readin in %s, "
00358 "wavelength=%f\n", chTPFilename,dBaseStates[intNS][ipHi].energy().WN()
00359 - dBaseStates[intNS][ipLo].energy().WN());
00360 cdEXIT(EXIT_FAILURE);
00361 }
00362
00363 if( (*tr).EnergyWN() > ENERGY_MIN_WN )
00364 {
00365 (*tr).AddLine2Stack();
00366 (*tr).Emis().Aul() = Aul;
00367 (*tr).Emis().gf() = (realnum)GetGF((*tr).Emis().Aul(), (*tr).EnergyWN(), (*(*tr).Hi()).g());
00368 }
00369 }
00370 else
00371 {
00372 fprintf( ioQQQ, " PROBLEM File %s contains an invalid line.\n",chTPFilename);
00373 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00374 cdEXIT(EXIT_FAILURE);
00375 }
00376 }
00377 }
00378 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL );
00379 if( !lgSentinelReached )
00380 {
00381 fprintf( ioQQQ, " PROBLEM End of data sentinel was not reached in file %s\n",chTPFilename);
00382 fprintf( ioQQQ, " Check that stars (*****) appear after the last line of data and start in the first column of that line.");
00383 cdEXIT(EXIT_FAILURE);
00384 }
00385 fclose(ioDATA);
00386
00387 if( DEBUGSTATE )
00388 {
00389
00390 printf("DEBUG STOUT A's:\n");
00391 for(TransitionList::iterator tr=dBaseTrans[intNS].begin();
00392 tr!= dBaseTrans[intNS].end(); ++tr)
00393 {
00394 printf("DEBUG.STOUT.A:\t%i\t%i\t%8.2e\n",(*tr).ipLo()+1,(*tr).ipHi()+1,(*tr).Emis().Aul());
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404 strcat( chCOLLFilename , ".coll");
00405 uncaps( chCOLLFilename );
00406
00407 ioDATA = open_data( chCOLLFilename, "r" );
00408
00409
00410 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00411 {
00412 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of %s.\n", chCOLLFilename );
00413 cdEXIT(EXIT_FAILURE);
00414 }
00415 i = 1;
00416 iyrread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00417 imoread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00418 idyread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00419
00420 if(( iyrread != iyr ) ||
00421 ( imoread != imo ) ||
00422 ( idyread != idy ) )
00423 {
00424 fprintf( ioQQQ,
00425 " PROBLEM atmdat_STOUT_readin: the version of %s is not the current version.\n", chCOLLFilename );
00426 fprintf( ioQQQ,
00427 " atmdat_STOUT_readin: I expected the magic numbers %li %li %li but found %li %li %li.\n",
00428 iyr, imo , idy ,iyrread, imoread , idyread );
00429 cdEXIT(EXIT_FAILURE);
00430 }
00431
00432
00433
00434
00435
00436 if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
00437 {
00438 fprintf( ioQQQ, " atmdat_STOUT_readin could not read first line of the collision data file.\n");
00439 cdEXIT(EXIT_FAILURE);
00440 }
00441
00442
00443 StoutCollData[intNS] = (StoutColls***)MALLOC(nMolLevs *sizeof(StoutColls**));
00444 for( long ipHi=0; ipHi<nMolLevs; ipHi++ )
00445 {
00446 StoutCollData[intNS][ipHi] = (StoutColls **)MALLOC((unsigned long)(nMolLevs)*sizeof(StoutColls *));
00447 for( long ipLo=0; ipLo<nMolLevs; ipLo++ )
00448 {
00449 StoutCollData[intNS][ipHi][ipLo] =
00450 (StoutColls *)MALLOC((unsigned long)(ipNCOLLIDER)*sizeof(StoutColls ));
00451
00452 for( long k=0; k<ipNCOLLIDER; k++ )
00453 {
00454
00455 StoutCollData[intNS][ipHi][ipLo][k].ntemps = -1;
00456 StoutCollData[intNS][ipHi][ipLo][k].temps = NULL;
00457 StoutCollData[intNS][ipHi][ipLo][k].collstrs = NULL;
00458 StoutCollData[intNS][ipHi][ipLo][k].lgIsRate = false;
00459 }
00460 }
00461 }
00462
00463 ipLo = 0;
00464 ipHi = 0;
00465 int numpoints = 0;
00466 double *temps = NULL;
00467 long ipCollider = -1;
00468 lgSentinelReached = false;
00469
00470
00471 do
00472 {
00473
00474 if( chLine[0] == '*' )
00475 {
00476 lgSentinelReached = true;
00477 break;
00478 }
00479
00480
00481 if( chLine[0] != '#' )
00482 {
00483 i = 1;
00484
00485
00486 if( chLine[0] == '\n')
00487 continue;
00488
00489
00490 if( nMatch("TEMP",chLine) )
00491 {
00492 if( temps != NULL)
00493 free( temps );
00494
00495 i = 1;
00496 numpoints = (int)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00497 ASSERT( numpoints > 0 );
00498
00499 temps = (double*)MALLOC(numpoints*sizeof(double));
00500 memset( temps, 0, (unsigned long)(numpoints)*sizeof(double) );
00501 for( int j = 0; j < numpoints; j++ )
00502 {
00503 temps[j] = (double)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00504 ASSERT( temps[j] > 0 );
00505 }
00506 }
00507 else if( nMatch("CS",chLine) || nMatch("RATE",chLine) )
00508 {
00509
00510 bool isRate = false;
00511 if( nMatch("RATE", chLine) )
00512 isRate = true;
00513
00514 if( nMatch( "ELECTRON",chLine ) )
00515 {
00516 ipCollider = ipELECTRON;
00517 }
00518 else if( nMatch( "PROTON",chLine ) )
00519 {
00520 ipCollider = ipPROTON;
00521 }
00522 else
00523 {
00524 fprintf( ioQQQ, " PROBLEM atmdat_STOUT_readin: Each line of the collision data"
00525 "file must specify the collider.\n");
00526 fprintf( ioQQQ, " Possible colliders are: ELECTRON, PROTON\n");
00527 cdEXIT(EXIT_FAILURE);
00528 }
00529
00530 if( temps == NULL )
00531 {
00532 fprintf( ioQQQ, " PROBLEM atmdat_STOUT_readin: The collision "
00533 "file must specify temperatures before the collision strengths");
00534 cdEXIT(EXIT_FAILURE);
00535 }
00536
00537 i = 1;
00538 ipLo= (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL) - 1;
00539 ipHi = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL) - 1;
00540
00541 if( ipLo >= nMolLevs || ipHi >= nMolLevs )
00542 {
00543
00544 continue;
00545 }
00546
00547
00548 StoutCollData[intNS][ipHi][ipLo][ipCollider].lgIsRate = isRate;
00549
00550 StoutCollData[intNS][ipHi][ipLo][ipCollider].ntemps = numpoints;
00551 ASSERT( numpoints > 0 );
00552
00553
00554 StoutCollData[intNS][ipHi][ipLo][ipCollider].temps =
00555 (double *)MALLOC((unsigned long)(numpoints)*sizeof(double));
00556 StoutCollData[intNS][ipHi][ipLo][ipCollider].collstrs =
00557 (double *)MALLOC((unsigned long)(numpoints)*sizeof(double));
00558
00559 for( int j = 0; j < numpoints; j++ )
00560 {
00561 StoutCollData[intNS][ipHi][ipLo][ipCollider].temps[j] = temps[j];
00562 ASSERT( StoutCollData[intNS][ipHi][ipLo][ipCollider].temps[j] > 0 );
00563 StoutCollData[intNS][ipHi][ipLo][ipCollider].collstrs[j] = (double)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
00564 ASSERT( StoutCollData[intNS][ipHi][ipLo][ipCollider].collstrs[j] > 0 );
00565 }
00566 }
00567 else
00568 {
00569 fprintf( ioQQQ, " PROBLEM File %s contains an invalid line.\n",chCOLLFilename);
00570 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00571 cdEXIT(EXIT_FAILURE);
00572 }
00573
00574 if( lgEOL )
00575 {
00576 fprintf( ioQQQ, " PROBLEM End of line reached prematurely in file %s\n",chCOLLFilename);
00577 fprintf( ioQQQ, " The line being read is between the braces {%.*s}\n",int(strlen(chLine)-1),chLine);
00578 cdEXIT(EXIT_FAILURE);
00579 }
00580 }
00581 }
00582 while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL );
00583 if( !lgSentinelReached )
00584 {
00585 fprintf( ioQQQ, " PROBLEM End of data sentinel was not reached in file %s\n",chCOLLFilename);
00586 fprintf( ioQQQ, " Check that stars (*****) appear after the last line of data and start in the first column.");
00587 cdEXIT(EXIT_FAILURE);
00588 }
00589 free(temps);
00590 fclose(ioDATA);
00591
00592 return;
00593 }
00594
00595 void atmdat_CHIANTI_readin( long intNS, char *chPrefix )
00596 {
00597 DEBUG_ENTRY( "atmdat_CHIANTI_readin()" );
00598
00599 int intsplinepts,intTranType,intxs;
00600 long int nMolLevs,nMolExpLevs,nElvlcLines;
00601 FILE *ioElecCollData=NULL, *ioProtCollData=NULL;
00602 realnum fstatwt,fenergyWN,fWLAng,fenergy,feinsteina;
00603 double fScalingParam,fEnergyDiff,*xs,*spl,*spl2;
00604
00605 char chLine[FILENAME_PATH_LENGTH_2] ,
00606 chEnFilename[FILENAME_PATH_LENGTH_2],
00607 chTraFilename[FILENAME_PATH_LENGTH_2],
00608 chEleColFilename[FILENAME_PATH_LENGTH_2],
00609 chProColFilename[FILENAME_PATH_LENGTH_2];
00610
00611 realnum *dBaseStatesEnergy;
00612 long int *intNewIndex=NULL,*intOldIndex=NULL, *intExperIndex=NULL;
00613 int interror;
00614 bool lgProtonData=false,lgEneLevOrder;
00615
00616
00617 static const int MAX_NUM_LEVELS = 999;
00618
00619 dBaseSpecies[intNS].lgMolecular = false;
00620 dBaseSpecies[intNS].lgLAMDA = false;
00621 dBaseSpecies[intNS].lgLTE = false;
00622
00623 strcpy( chEnFilename , chPrefix );
00624 strcpy( chTraFilename , chPrefix );
00625 strcpy( chEleColFilename , chPrefix );
00626 strcpy( chProColFilename , chPrefix );
00627
00628
00629
00630 strcat( chEnFilename , ".elvlc");
00631 uncaps( chEnFilename );
00632 if(DEBUGSTATE)
00633 printf("The data file is %s \n",chEnFilename);
00634
00635
00636 if( trace.lgTrace )
00637 fprintf( ioQQQ," atmdat_CHIANTI_readin opening %s:",chEnFilename);
00638
00639 fstream elvlcstream;
00640 open_data(elvlcstream, chEnFilename,mode_r);
00641
00642
00643 strcat( chTraFilename , ".wgfa");
00644 uncaps( chTraFilename );
00645 if(DEBUGSTATE)
00646 printf("The data file is %s \n",chTraFilename);
00647
00648
00649 if( trace.lgTrace )
00650 fprintf( ioQQQ," atmdat_CHIANTI_readin opening %s:",chTraFilename);
00651
00652 fstream wgfastream;
00653 open_data(wgfastream, chTraFilename,mode_r);
00654
00655
00656 strcat( chEleColFilename , ".splups");
00657 uncaps( chEleColFilename );
00658 if(DEBUGSTATE)
00659 printf("The data file is %s \n",chEleColFilename);
00660
00661 if( trace.lgTrace )
00662 fprintf( ioQQQ," atmdat_CHIANTI_readin opening %s:",chEleColFilename);
00663
00664 ioElecCollData = open_data( chEleColFilename, "r" );
00665
00666
00667 strcat( chProColFilename , ".psplups");
00668 uncaps( chProColFilename );
00669 if(DEBUGSTATE)
00670 printf("The data file is %s \n",chProColFilename);
00671
00672 if( trace.lgTrace )
00673 fprintf( ioQQQ," atmdat_CHIANTI_readin opening %s:",chProColFilename);
00674
00675
00676 if( ( ioProtCollData = fopen( chProColFilename , "r" ) ) != NULL )
00677 {
00678 lgProtonData = true;
00679
00680
00681 }
00682 else
00683 {
00684 lgProtonData = false;
00685 }
00686
00687
00688
00689 const int eof_col = 5;
00690
00691 const int lvl_nrg_col=16;
00692
00693 const int lvl_skipto_nrg = 40;
00694
00695 const int lvl_eof_to_nrg = lvl_skipto_nrg - eof_col + 1;
00696 nElvlcLines = 0;
00697 nMolExpLevs = 1;
00698 lgEneLevOrder = true;
00699 if (elvlcstream.is_open())
00700 {
00701 int nj = 0;
00702 char otemp[eof_col];
00703 char exptemp[lvl_nrg_col];
00704 double tempexpenergy = 0.;
00705
00706
00707 while(nj != -1)
00708 {
00709 elvlcstream.get(otemp,eof_col);
00710 nj = atoi(otemp);
00711 if( nj == -1)
00712 break;
00713 nElvlcLines++;
00714
00715 elvlcstream.seekg(lvl_eof_to_nrg,ios::cur);
00716 elvlcstream.get(exptemp,lvl_nrg_col);
00717 tempexpenergy = (realnum) atof(exptemp);
00718 if( tempexpenergy != 0.)
00719 nMolExpLevs++;
00720
00721 elvlcstream.ignore(INT_MAX,'\n');
00722
00723 }
00724 elvlcstream.seekg(0,ios::beg);
00725 }
00726
00727 if(DEBUGSTATE)
00728 {
00729 printf("DEBUG: The file %s contains %li experimental energy levels of the %li total levels. \n",chEnFilename,nMolExpLevs,nElvlcLines);
00730 }
00731
00732
00733 if( atmdat.lgChiantiExp )
00734 {
00735 if( tolower(dBaseSpecies[intNS].chLabel[0]) == 'f' && tolower(dBaseSpecies[intNS].chLabel[1]) == 'e')
00736 {
00737
00738 nMolLevs = MIN3(nMolExpLevs, atmdat.nChiantiMaxLevelsFe, MAX_NUM_LEVELS );
00739 }
00740 else
00741 {
00742 nMolLevs = MIN3(nMolExpLevs, atmdat.nChiantiMaxLevels, MAX_NUM_LEVELS );
00743 }
00744 }
00745 else
00746 {
00747 if( tolower(dBaseSpecies[intNS].chLabel[0]) == 'f' && tolower(dBaseSpecies[intNS].chLabel[1]) == 'e')
00748 {
00749
00750 nMolLevs = MIN3(nElvlcLines, atmdat.nChiantiMaxLevelsFe,MAX_NUM_LEVELS );
00751 }
00752 else
00753 {
00754 nMolLevs = MIN3(nElvlcLines, atmdat.nChiantiMaxLevels,MAX_NUM_LEVELS );
00755 }
00756 }
00757
00758 if( nMolLevs <= 0 )
00759 {
00760 fprintf( ioQQQ, "The number of energy levels is non-positive in datafile %s.\n", chEnFilename );
00761 fprintf( ioQQQ, "The file must be corrupted.\n" );
00762 fclose( ioProtCollData );
00763 cdEXIT( EXIT_FAILURE );
00764 }
00765
00766 dBaseSpecies[intNS].numLevels_max = nMolLevs;
00767 dBaseSpecies[intNS].numLevels_local = dBaseSpecies[intNS].numLevels_max;
00768
00769 if( atmdat.lgChiantiPrint == true)
00770 {
00771 if( atmdat.lgChiantiExp )
00772 {
00773 fprintf( ioQQQ," Using CHIANTI model %s with %li experimental energy levels of %li available.\n",
00774 dBaseSpecies[intNS].chLabel , nMolLevs , nMolExpLevs );
00775 }
00776 else
00777 {
00778 fprintf( ioQQQ," Using CHIANTI model %s with %li theoretical energy levels of %li available.\n",
00779 dBaseSpecies[intNS].chLabel , nMolLevs , nElvlcLines );
00780 }
00781 }
00782
00783
00784 dBaseStatesEnergy = (realnum*)MALLOC((unsigned long)(nMolLevs)*sizeof(realnum));
00785
00786
00787 dBaseStates[intNS].resize(nMolLevs);
00788
00789
00790 ipdBaseTrans[intNS].reserve(nMolLevs);
00791 for( long ipHi = 1; ipHi < nMolLevs; ipHi++)
00792 ipdBaseTrans[intNS].reserve(ipHi,ipHi);
00793 ipdBaseTrans[intNS].alloc();
00794 dBaseTrans[intNS].resize(ipdBaseTrans[intNS].size());
00795 dBaseTrans[intNS].states() = &dBaseStates[intNS];
00796 dBaseTrans[intNS].chLabel() = "Chianti";
00797
00798 int ndBase = 0;
00799 for( long ipHi = 1; ipHi < nMolLevs; ipHi++)
00800 {
00801 for( long ipLo = 0; ipLo < ipHi; ipLo++)
00802 {
00803 ipdBaseTrans[intNS][ipHi][ipLo] = ndBase;
00804 dBaseTrans[intNS][ndBase].Junk();
00805 dBaseTrans[intNS][ndBase].setLo(ipLo);
00806 dBaseTrans[intNS][ndBase].setHi(ipHi);
00807 ++ndBase;
00808 }
00809 }
00810
00811
00812
00813
00814 const int lvl_skip_ryd = 15;
00815
00816
00817
00818
00819 long ncounter = 0;
00820
00821 if( atmdat.lgChiantiExp )
00822 {
00823
00824 intExperIndex = (long int*)MALLOC((unsigned long)(nElvlcLines)* sizeof(long int));
00825
00826
00827 for(int i = 0; i < nElvlcLines; i++)
00828 {
00829 intExperIndex[i] = -1;
00830 }
00831 }
00832
00833
00834 for( long ipLev=0; ipLev<nElvlcLines; ipLev++ )
00835 {
00836 if(elvlcstream.is_open())
00837 {
00838 char thtemp[lvl_nrg_col],obtemp[lvl_nrg_col];
00839 elvlcstream.seekg(lvl_skipto_nrg,ios::cur);
00840 elvlcstream.get(thtemp,lvl_nrg_col);
00841 fenergy = (realnum) atof(thtemp);
00842
00843 if( atmdat.lgChiantiExp )
00844 {
00845
00846
00847
00848
00849
00850
00851
00852 if( ncounter == nMolLevs)
00853 break;
00854 ASSERT( ncounter < nMolLevs );
00855
00856 if(fenergy != 0. || ipLev == 0 )
00857 {
00858 dBaseStatesEnergy[ncounter] = fenergy;
00859 intExperIndex[ipLev] = ncounter;
00860 ncounter++;
00861 }
00862 else
00863 {
00864 intExperIndex[ipLev] = -1;
00865 }
00866
00867 }
00868 else
00869 {
00870
00871 if( ipLev == nMolLevs )
00872 break;
00873
00874 elvlcstream.seekg(lvl_skip_ryd,ios::cur);
00875 elvlcstream.get(obtemp,lvl_nrg_col);
00876 if(atof(obtemp) != 0.)
00877 {
00878 fenergy = (realnum) atof(obtemp);
00879 }
00880
00881
00882 dBaseStatesEnergy[ipLev] = fenergy;
00883 }
00884
00885 elvlcstream.ignore(INT_MAX,'\n');
00886
00887 }
00888 else
00889 {
00890 fprintf( ioQQQ, " The data file %s is corrupted .\n",chEnFilename);
00891 fclose( ioProtCollData );
00892 cdEXIT(EXIT_FAILURE);
00893 }
00894 }
00895
00896 for( long ipLev=1; ipLev<nMolLevs; ipLev++ )
00897 {
00898
00899
00900 if (dBaseStatesEnergy[ipLev] < dBaseStatesEnergy[ipLev-1])
00901 {
00902 lgEneLevOrder = false;
00903 }
00904 }
00905
00906
00907 intNewIndex = (long int*)MALLOC((unsigned long)(nElvlcLines)* sizeof(long int));
00908
00909 if(lgEneLevOrder == false)
00910 {
00911
00912
00913 intOldIndex = (long int*)MALLOC((unsigned long)(nMolLevs)* sizeof(long int));
00914
00915 spsort(dBaseStatesEnergy,nMolLevs,intOldIndex,2,&interror);
00916
00917 for( long i=0; i<nMolLevs; i++ )
00918 {
00919 ASSERT( intOldIndex[i] < nMolLevs );
00920 intNewIndex[intOldIndex[i]] = i;
00921 }
00922
00923 if( nMolLevs < nElvlcLines )
00924 {
00925
00926
00927
00928
00929
00930 for( long i=nMolLevs; i<nElvlcLines; i++)
00931 {
00932 intNewIndex[i] = -1;
00933 }
00934 }
00935
00936 if(DEBUGSTATE)
00937 {
00938 for( long i=0; i<nMolLevs; i++ )
00939 {
00940 printf("The %ld value of the relation matrix is %ld \n",i,intNewIndex[i]);
00941 }
00942 for( long i=0; i<nMolLevs; i++ )
00943 {
00944 printf("The %ld value of the sorted energy array is %f \n",i,dBaseStatesEnergy[i]);
00945 }
00946 }
00947 free( intOldIndex );
00948 }
00949 else
00950 {
00951
00952 for( long i=0; i<nMolLevs; i++ )
00953 {
00954 intNewIndex[i] = i;
00955 }
00956
00957 if( nMolLevs < nElvlcLines )
00958 {
00959
00960
00961 for( long i=nMolLevs; i<nElvlcLines; i++)
00962 {
00963 intNewIndex[i] = -1;
00964 }
00965 }
00966 }
00967
00968
00969 for( long i=0; i<nMolLevs; i++ )
00970 {
00971 for( long j=i+1; j<nMolLevs; j++ )
00972 {
00973 ASSERT( intNewIndex[i] != intNewIndex[j] );
00974 }
00975 }
00976
00977
00978
00979
00980
00981 if( DEBUGSTATE && atmdat.lgChiantiExp )
00982 {
00983 printf("\n\n%s Energy Level Matrix\n",dBaseSpecies[intNS].chLabel);
00984 printf("(Original, Experimental, Sorted)\n");
00985 for( long ipLevOld=0; ipLevOld<nElvlcLines; ipLevOld++ )
00986 {
00987 if( intExperIndex[ipLevOld] != -1)
00988 printf("%li\t%li\t%li\n",ipLevOld+1,intExperIndex[ipLevOld]+1,intNewIndex[intExperIndex[ipLevOld]]+1);
00989 }
00990 printf("\n");
00991 }
00992
00993
00994 elvlcstream.seekg(0,ios::beg);
00995
00996
00997 const int lvl_skipto_statwt = 37;
00998
00999 const int lvl_statwt_col = 4;
01000
01001 for( long ipLevOld=0; ipLevOld<nElvlcLines; ipLevOld++ )
01002 {
01003 long ipLevNew = 0;
01004 if( atmdat.lgChiantiExp )
01005 {
01006
01007
01008
01009
01010 if( intExperIndex[ipLevOld] == -1 )
01011 {
01012 elvlcstream.ignore(INT_MAX,'\n');
01013 continue;
01014 }
01015 else
01016 {
01017
01018 ipLevNew = intNewIndex[intExperIndex[ipLevOld]];
01019 }
01020 }
01021 else
01022 {
01023
01024
01025
01026 if( intNewIndex[ipLevOld] == -1 )
01027 {
01028 elvlcstream.ignore(INT_MAX,'\n');
01029 continue;
01030 }
01031 else
01032 {
01033 ipLevNew = intNewIndex[ipLevOld];
01034 }
01035 }
01036
01037 char gtemp[lvl_statwt_col],thtemp[lvl_nrg_col],obtemp[lvl_nrg_col];
01038
01039
01040 strcpy(dBaseStates[intNS][ipLevNew].chLabel(), " ");
01041 strncpy(dBaseStates[intNS][ipLevNew].chLabel(),dBaseSpecies[intNS].chLabel, 4);
01042 dBaseStates[intNS][ipLevNew].chLabel()[4] = '\0';
01043
01044
01045 elvlcstream.seekg(lvl_skipto_statwt,ios::cur);
01046 elvlcstream.get(gtemp,lvl_statwt_col);
01047 fstatwt = (realnum)atof(gtemp);
01048
01049 if(fstatwt <= 0.)
01050 {
01051 fprintf( ioQQQ, " WARNING: A positive non zero value is expected for the "
01052 "statistical weight but was not found in %s"
01053 " level %li\n", chEnFilename,ipLevNew);
01054 fstatwt = 1.f;
01055
01056 }
01057 dBaseStates[intNS][ipLevNew].g() = fstatwt;
01058
01059
01060 elvlcstream.get(thtemp,lvl_nrg_col);
01061
01062 fenergy = (realnum) atof(thtemp);
01063
01064
01065
01066 if( !atmdat.lgChiantiExp )
01067 {
01068 elvlcstream.seekg(lvl_skip_ryd,ios::cur);
01069 elvlcstream.get(obtemp,lvl_nrg_col);
01070 if(atof(obtemp) != 0.)
01071 {
01072 fenergy = (realnum) atof(obtemp);
01073 }
01074 }
01075 elvlcstream.ignore(INT_MAX,'\n');
01076 dBaseStates[intNS][ipLevNew].energy().set(fenergy,"cm^-1");
01077 }
01078
01079 elvlcstream.close();
01080
01081
01082 dBaseSpecies[intNS].maxWN = 0.;
01083
01084 for(TransitionList::iterator tr=dBaseTrans[intNS].begin();
01085 tr!= dBaseTrans[intNS].end(); ++tr)
01086 {
01087 int ipHi = (*tr).ipHi();
01088 int ipLo = (*tr).ipLo();
01089 fenergyWN = (realnum)MAX2( ENERGY_MIN_WN , dBaseStates[intNS][ipHi].energy().WN() - dBaseStates[intNS][ipLo].energy().WN() );
01090
01091 (*tr).EnergyWN() = fenergyWN;
01092 (*tr).WLAng() = (realnum)(1e+8/fenergyWN/RefIndex(fenergyWN));
01093 dBaseSpecies[intNS].maxWN = MAX2(dBaseSpecies[intNS].maxWN,fenergyWN);
01094 }
01095
01096 if(DEBUGSTATE)
01097 {
01098
01099
01100 printf("\n%s Stored Energy Levels\n",dBaseSpecies[intNS].chLabel);
01101 printf("(Index,Energy in WN, Statistical Weight)\n");
01102 for( long ipLo = 0; ipLo < nMolLevs; ipLo++ )
01103 {
01104 printf("%li\t%e\t%.1f\n",ipLo+1,dBaseStates[intNS][ipLo].energy().WN(),dBaseStates[intNS][ipLo].g());
01105 }
01106 }
01107
01108
01109
01110
01111
01112
01113 long wgfarows = -1;
01114 if (wgfastream.is_open())
01115 {
01116 int nj = 0;
01117 char otemp[eof_col];
01118 while(nj != -1)
01119 {
01120 wgfastream.get(otemp,eof_col);
01121 wgfastream.ignore(INT_MAX,'\n');
01122 nj = atoi(otemp);
01123 wgfarows++;
01124 }
01125 wgfastream.seekg(0,ios::beg);
01126 }
01127 else
01128 fprintf( ioQQQ, " The data file %s is corrupted .\n",chTraFilename);
01129
01130
01131 const int line_index_col = 6;
01132
01133 const int line_nrg_to_eina =15;
01134
01135 const int line_eina_col = 16;
01136 char lvltemp[line_index_col];
01137
01138 if (wgfastream.is_open())
01139 {
01140 for (long i = 0;i<wgfarows;i++)
01141 {
01142 wgfastream.get(lvltemp,line_index_col);
01143 long ipLo = atoi(lvltemp)-1;
01144 wgfastream.get(lvltemp,line_index_col);
01145 long ipHi = atoi(lvltemp)-1;
01146
01147 if( atmdat.lgChiantiExp )
01148 {
01149
01150
01151
01152 if( intExperIndex[ipLo] == - 1 || intExperIndex[ipHi] == -1 )
01153 {
01154 wgfastream.ignore(INT_MAX,'\n');
01155 continue;
01156 }
01157 else
01158 {
01159 ipLo = intNewIndex[intExperIndex[ipLo]];
01160 ipHi = intNewIndex[intExperIndex[ipHi]];
01161 }
01162 }
01163 else
01164 {
01165
01166
01167
01168 if( intNewIndex[ipLo] == - 1 || intNewIndex[ipHi] == -1 )
01169 {
01170 wgfastream.ignore(INT_MAX,'\n');
01171 continue;
01172 }
01173 else
01174 {
01175 ipLo = intNewIndex[ipLo];
01176 ipHi = intNewIndex[ipHi];
01177 }
01178 }
01179
01180 if( ipLo >= nMolLevs || ipHi >= nMolLevs )
01181 {
01182
01183 wgfastream.ignore(INT_MAX,'\n');
01184 continue;
01185 }
01186
01187 if( ipHi == ipLo )
01188 {
01189 fprintf( ioQQQ," WARNING: Upper level = lower for a radiative transition in %s. Ignoring.\n", chTraFilename );
01190 wgfastream.ignore(INT_MAX,'\n');
01191 continue;
01192 }
01193
01194
01195 ASSERT( ipHi != ipLo );
01196 ASSERT(ipHi >= 0);
01197 ASSERT(ipLo >= 0);
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 char trantemp[lvl_nrg_col];
01212 wgfastream.get(trantemp,lvl_nrg_col);
01213 fWLAng = (realnum)atof(trantemp);
01214
01215
01216
01217
01218
01219 if( atmdat.lgChiantiExp )
01220 {
01221
01222
01223
01224
01225
01226
01227 if( ipHi < ipLo )
01228 {
01229 if( strcmp(dBaseSpecies[intNS].chLabel,"Fe 3") == 0)
01230 {
01231 long ipLoTemp = ipLo;
01232 long ipHiTemp = ipHi;
01233 ipHi = max( ipHiTemp, ipLoTemp );
01234 ipLo = min( ipHiTemp, ipLoTemp );
01235 if( atmdat.lgChiantiPrint )
01236 {
01237 fprintf( ioQQQ," WARNING: Swapped level indices for species %6s, indices %3li %3li with wavelength %e \n",
01238 dBaseSpecies[intNS].chLabel, ipLoTemp, ipHiTemp,fWLAng );
01239 }
01240 }
01241 else if( atmdat.lgChiantiPrint )
01242 {
01243 fprintf( ioQQQ," WARNING: Upper and Lower Indices are reversed.Species: %6s, Indices: %3li %3li Wavelength: %e \n",
01244 dBaseSpecies[intNS].chLabel, ipLo+1, ipHi+1,fWLAng );
01245 }
01246 }
01247
01248 if( fWLAng < 0.)
01249 {
01250
01251 wgfastream.ignore(INT_MAX,'\n');
01252 if( atmdat.lgChiantiPrint )
01253 {
01254 fprintf(ioQQQ,"WARNING: Skipping Transition %li to %li of %s.\n",ipLo+1,ipHi+1,dBaseSpecies[intNS].chLabel);
01255 }
01256 continue;
01257 }
01258
01259 }
01260 else
01261 {
01262
01263 if( ipHi < ipLo )
01264 {
01265 long ipLoTemp = ipLo;
01266 long ipHiTemp = ipHi;
01267 ipHi = max( ipHiTemp, ipLoTemp );
01268 ipLo = min( ipHiTemp, ipLoTemp );
01269 fprintf( ioQQQ," WARNING: Swapped level indices for species %6s, indices %3li %3li with wavelength %e \n",
01270 dBaseSpecies[intNS].chLabel, ipLoTemp, ipHiTemp,fWLAng );
01271 }
01272 }
01273
01274
01275
01276
01277 if( !atmdat.lgChiantiExp && fWLAng <= 0. )
01278 {
01279
01280
01281 fWLAng = (realnum)(1e8/
01282 (dBaseStates[intNS][ipHi].energy().WN() - dBaseStates[intNS][ipLo].energy().WN()));
01283 }
01284
01285 wgfastream.seekg(line_nrg_to_eina,ios::cur);
01286 wgfastream.get(trantemp,line_eina_col);
01287 feinsteina = (realnum)atof(trantemp);
01288 if( feinsteina < 1e-20 )
01289 {
01290 static bool notPrintedYet = true;
01291 if( notPrintedYet && atmdat.lgChiantiPrint)
01292 {
01293 fprintf( ioQQQ," WARNING: Radiative rate(s) equal to zero in %s.\n", chTraFilename );
01294 notPrintedYet = false;
01295 }
01296 wgfastream.ignore(INT_MAX,'\n');
01297 continue;
01298 }
01299
01300 fixit();
01301
01302 wgfastream.getline(chLine,INT_MAX);
01303 TransitionList::iterator tr = dBaseTrans[intNS].begin()+ipdBaseTrans[intNS][ipHi][ipLo];
01304 if( nMatch("auto", chLine) )
01305 {
01306 if( (*tr).hasEmis() )
01307 {
01308 (*tr).Emis().AutoIonizFrac() =
01309 feinsteina/((*tr).Emis().Aul() + feinsteina);
01310 ASSERT( (*tr).Emis().AutoIonizFrac() >= 0. );
01311 ASSERT( (*tr).Emis().AutoIonizFrac() <= 1. );
01312 }
01313 continue;
01314 }
01315
01316 if( (*tr).hasEmis() )
01317 {
01318 fprintf(ioQQQ," PROBLEM duplicate transition found by atmdat_chianti in %s, "
01319 "wavelength=%f\n", chTraFilename,fWLAng);
01320 fclose( ioProtCollData );
01321 cdEXIT(EXIT_FAILURE);
01322 }
01323 (*tr).AddLine2Stack();
01324 (*tr).Emis().Aul() = feinsteina;
01325 (*tr).WLAng() = fWLAng;
01326
01327 fenergyWN = (realnum)(1e+8/fWLAng);
01328
01329
01330
01331 (*tr).EnergyWN() = fenergyWN;
01332 (*tr).WLAng() = (realnum)(1e+8/fenergyWN/RefIndex(fenergyWN));
01333 (*tr).Emis().gf() = (realnum)GetGF((*tr).Emis().Aul(), (*tr).EnergyWN(), (*(*tr).Hi()).g());
01334
01335 if(DEBUGSTATE)
01336 {
01337 fprintf( ioQQQ, "The lower level is %ld \n",ipLo);
01338 fprintf( ioQQQ, "The upper level is %ld \n",ipHi);
01339 fprintf( ioQQQ, "The Einstein A is %f \n",(*tr).Emis().Aul());
01340 fprintf( ioQQQ, "The wavelength of the transition is %f \n",(*tr).WLAng() );
01341 }
01342 }
01343 }
01344 else fprintf( ioQQQ, " The data file %s is corrupted .\n",chTraFilename);
01345 wgfastream.close();
01346
01347
01348 AtmolCollSplines[intNS] = (CollSplinesArray***)MALLOC(nMolLevs *sizeof(CollSplinesArray**));
01349 for( long ipHi=0; ipHi<nMolLevs; ipHi++ )
01350 {
01351 AtmolCollSplines[intNS][ipHi] = (CollSplinesArray **)MALLOC((unsigned long)(nMolLevs)*sizeof(CollSplinesArray *));
01352 for( long ipLo=0; ipLo<nMolLevs; ipLo++ )
01353 {
01354 AtmolCollSplines[intNS][ipHi][ipLo] =
01355 (CollSplinesArray *)MALLOC((unsigned long)(ipNCOLLIDER)*sizeof(CollSplinesArray ));
01356
01357 for( long k=0; k<ipNCOLLIDER; k++ )
01358 {
01359
01360 AtmolCollSplines[intNS][ipHi][ipLo][k].collspline = NULL;
01361 AtmolCollSplines[intNS][ipHi][ipLo][k].SplineSecDer = NULL;
01362 AtmolCollSplines[intNS][ipHi][ipLo][k].nSplinePts = -1;
01363 AtmolCollSplines[intNS][ipHi][ipLo][k].intTranType = -1;
01364 AtmolCollSplines[intNS][ipHi][ipLo][k].EnergyDiff = BIGDOUBLE;
01365 AtmolCollSplines[intNS][ipHi][ipLo][k].ScalingParam = BIGDOUBLE;
01366 }
01367 }
01368 }
01369
01370
01371
01372
01373
01374
01375 for( long ipCollider=0; ipCollider<=1; ipCollider++ )
01376 {
01377 char chFilename[FILENAME_PATH_LENGTH_2];
01378
01379 if( ipCollider == ipELECTRON )
01380 {
01381 strcpy( chFilename, chEleColFilename );
01382 }
01383 else if( ipCollider == ipPROTON )
01384 {
01385 if( !lgProtonData )
01386 break;
01387 fprintf( ioQQQ," WARNING: Chianti proton collision data have different format than electron data files!\n" );
01388 strcpy( chFilename, chProColFilename );
01389 }
01390 else
01391 TotalInsanity();
01392
01393
01394 strcpy(chLine,"A");
01395
01396 fstream splupsstream;
01397 open_data(splupsstream, chFilename,mode_r);
01398
01399
01400 const int cs_eof_col = 4;
01401
01402 const int cs_index_col = 4;
01403
01404 const int cs_trantype_col = 4;
01405
01406
01407 const int cs_values_col = 11;
01408
01409 if (splupsstream.is_open())
01410 {
01411 int nj = 0;
01412
01413 long splupslines = -1;
01414 char otemp[cs_eof_col];
01415 while(nj != -1)
01416 {
01417 splupsstream.get(otemp,cs_eof_col);
01418 splupsstream.ignore(INT_MAX,'\n');
01419 nj = atoi(otemp);
01420 splupslines++;
01421 }
01422 splupsstream.seekg(0,ios::beg);
01423
01424 for (int m = 0;m<splupslines;m++)
01425 {
01426 if( ipCollider == ipELECTRON )
01427 {
01428 splupsstream.seekg(6,ios::cur);
01429 }
01430
01431
01432 splupsstream.get(otemp,cs_index_col);
01433 long ipLo = atoi(otemp)-1;
01434 splupsstream.get(otemp,cs_index_col);
01435 long ipHi = atoi(otemp)-1;
01436
01437
01438
01439
01440 if( atmdat.lgChiantiExp )
01441 {
01442 if( intExperIndex[ipLo] == - 1 || intExperIndex[ipHi] == -1 )
01443 {
01444 splupsstream.ignore(INT_MAX,'\n');
01445 continue;
01446 }
01447 else
01448 {
01449 ipLo = intNewIndex[intExperIndex[ipLo]];
01450 ipHi = intNewIndex[intExperIndex[ipHi]];
01451 }
01452
01453 }
01454 else
01455 {
01456
01457
01458
01459 if( intNewIndex[ipLo] == - 1 || intNewIndex[ipHi] == -1 )
01460 {
01461 splupsstream.ignore(INT_MAX,'\n');
01462 continue;
01463 }
01464 else
01465 {
01466 ipLo = intNewIndex[ipLo];
01467 ipHi = intNewIndex[ipHi];
01468 }
01469 }
01470
01471 if( ipLo >= nMolLevs || ipHi >= nMolLevs )
01472 {
01473
01474 splupsstream.ignore(INT_MAX,'\n');
01475 continue;
01476 }
01477
01478 ASSERT( ipLo < nMolLevs );
01479 ASSERT( ipHi < nMolLevs );
01480
01481 splupsstream.get(otemp,cs_trantype_col);
01482 intTranType = atoi(otemp);
01483 char qtemp[cs_values_col];
01484 splupsstream.get(qtemp,cs_values_col);
01485
01486 splupsstream.get(qtemp,cs_values_col);
01487 fEnergyDiff = atof(qtemp);
01488
01489 splupsstream.get(qtemp,cs_values_col);
01490 fScalingParam = atof(qtemp);
01491
01492 ASSERT( ipLo < nMolLevs );
01493 ASSERT( ipHi < nMolLevs );
01494 ASSERT( AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline == NULL );
01495 ASSERT( AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].SplineSecDer == NULL );
01496
01497 const int CHIANTI_SPLINE_MAX=9, CHIANTI_SPLINE_MIN=5;
01498 STATIC_ASSERT(CHIANTI_SPLINE_MAX > CHIANTI_SPLINE_MIN);
01499
01500
01501 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline =
01502 (double *)MALLOC((unsigned long)(CHIANTI_SPLINE_MAX)*sizeof(double));
01503 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].SplineSecDer =
01504 (double *)MALLOC((unsigned long)(CHIANTI_SPLINE_MAX)*sizeof(double));
01505
01506
01507 for( intsplinepts=0; intsplinepts<=CHIANTI_SPLINE_MAX; intsplinepts++ )
01508 {
01509
01510 char p = splupsstream.peek();
01511 if( p == '\n' )
01512 {
01513
01514
01515 if( (intsplinepts != CHIANTI_SPLINE_MAX) && (intsplinepts != CHIANTI_SPLINE_MIN) )
01516 {
01517 static bool notPrintedYet = true;
01518 if( notPrintedYet )
01519 {
01520 fprintf( ioQQQ, " WARNING: Wrong number of spline points in %s.\n", chFilename);
01521 notPrintedYet = false;
01522 }
01523 for( long j=intsplinepts-1; j<CHIANTI_SPLINE_MAX; j++ )
01524 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline[j] = 0.;
01525 }
01526 else
01527 break;
01528 }
01529 else
01530 {
01531 if( intsplinepts >= CHIANTI_SPLINE_MAX )
01532 {
01533 fprintf( ioQQQ, " WARNING: More spline points than expected in %s, indices %3li %3li. Ignoring extras.\n", chFilename, ipHi, ipLo );
01534 break;
01535 }
01536 ASSERT( intsplinepts < CHIANTI_SPLINE_MAX );
01537 double temp;
01538
01539 splupsstream.get(qtemp,cs_values_col);
01540 temp = atof(qtemp);
01541 if(temp < 0)
01542 {
01543 temp = 0.;
01544 }
01545 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline[intsplinepts] = temp;
01546 }
01547
01548 }
01549
01550 ASSERT( (intsplinepts == CHIANTI_SPLINE_MAX) || (intsplinepts == CHIANTI_SPLINE_MIN) );
01551
01552
01553 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].nSplinePts = intsplinepts;
01554
01555 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].intTranType = intTranType;
01556
01557 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].EnergyDiff = fEnergyDiff;
01558
01559 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].ScalingParam = fScalingParam;
01560
01561
01562
01563 xs = (double *)MALLOC((unsigned long)intsplinepts*sizeof(double));
01564 spl = (double *)MALLOC((unsigned long)intsplinepts*sizeof(double));
01565 spl2 = (double *)MALLOC((unsigned long)intsplinepts*sizeof(double));
01566
01567
01568 if(intsplinepts == CHIANTI_SPLINE_MIN)
01569 {
01570 for(intxs=0;intxs<CHIANTI_SPLINE_MIN;intxs++)
01571 {
01572 xs[intxs] = 0.25*intxs;
01573 spl[intxs] = AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline[intxs];
01574 }
01575 }
01576 else if(intsplinepts == CHIANTI_SPLINE_MAX)
01577 {
01578 for(intxs=0;intxs<CHIANTI_SPLINE_MAX;intxs++)
01579 {
01580 xs[intxs] = 0.125*intxs;
01581 spl[intxs] = AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].collspline[intxs];
01582 }
01583 }
01584 else
01585 TotalInsanity();
01586
01587 spline(xs, spl,intsplinepts,2e31,2e31,spl2);
01588
01589
01590 for( long i=0; i<intsplinepts; i++)
01591 {
01592 AtmolCollSplines[intNS][ipHi][ipLo][ipCollider].SplineSecDer[i] = spl2[i];
01593 }
01594
01595 free( xs );
01596 free( spl );
01597 free( spl2 );
01598 splupsstream.ignore(INT_MAX,'\n');
01599 }
01600 splupsstream.close();
01601 }
01602 }
01603
01604
01605 free( dBaseStatesEnergy );
01606 free( intNewIndex );
01607 if( atmdat.lgChiantiExp)
01608 {
01609 free( intExperIndex );
01610 }
01611
01612
01613 fclose( ioElecCollData );
01614 if( lgProtonData )
01615 fclose( ioProtCollData );
01616
01617 return;
01618 }