00001
00002
00003
00004
00005
00006
00007 #include "cddefines.h"
00008 #include "physconst.h"
00009 #include "taulines.h"
00010 #include "thermal.h"
00011 #include "yield.h"
00012 #include "ipoint.h"
00013 #include "ionbal.h"
00014 #include "cddrive.h"
00015 #include "iterations.h"
00016 #include "trace.h"
00017 #include "dense.h"
00018 #include "prt.h"
00019 #include "rt.h"
00020 #include "coolheavy.h"
00021 #include "rfield.h"
00022 #include "phycon.h"
00023 #include "elementnames.h"
00024 #include "iso.h"
00025 #include "hyperfine.h"
00026 #include "hydrogenic.h"
00027 #include "lines_service.h"
00028 #include "atmdat.h"
00029 #include "lines.h"
00030 #include "radius.h"
00031
00032 STATIC void Drive_cdLine( void );
00033
00034 void lines(void)
00035 {
00036 char chLabel[5];
00037 long int i,
00038 ipnt,
00039 nelem;
00040 double BigstExtra,
00041 ExtraCool,
00042 f2, sum;
00043
00044 DEBUG_ENTRY( "lines()" );
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 if( trace.lgTrace )
00066 {
00067 fprintf( ioQQQ, " lines called\n" );
00068 }
00069
00070
00071 if( trace.lgDrv_cdLine && LineSave.ipass > 0 )
00072 Drive_cdLine();
00073
00074
00075
00076 thermal.power += thermal.htot*radius.dVeffAper;
00077
00078
00079 fixit();
00080
00081 thermal.FreeFreeTotHeat += thermal.heating[0][11]*radius.dVeffAper;
00082
00083
00084 rfield.comtot += rfield.cmheat*radius.dVeffAper;
00085 thermal.totcol += thermal.ctot*radius.dVeffAper;
00086
00087
00088 for( nelem=0; nelem<LIMELM; ++nelem )
00089 {
00090 hydro.cintot += iso_sp[ipH_LIKE][nelem].RecomInducCool_Rate*radius.dVeffAper;
00091 }
00092
00093
00094 LineSave.nsum = 0;
00095 LineSave.nComment = 0;
00096
00097
00098
00099
00100 rt.fracin = 0.5;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 PntForLine(0.,"FILL",&i);
00117
00118
00119
00120
00121 t_ADfA::Inst().rec_lines(phycon.te,LineSave.RecCoefCNO);
00122
00123
00124 PutExtra(0.);
00125
00126
00127 linadd(0.f,0,"zero",'i' , "null placeholder");
00128
00129
00130
00131
00132 linadd( 1.e-10 , 1 , "Unit" , 'i' , "unit integration placeholder");
00133 static long int ipOneAng=-1;
00134 if( LineSave.ipass<0 )
00135 ipOneAng = ipoint( RYDLAM );
00136 lindst( 1.e-10 , 1. , "UntD" , ipOneAng , 'i' , false,"unit integration placeholder");
00137
00138
00139 lines_general();
00140
00141
00142 lines_continuum();
00143
00144
00145 lines_grains();
00146
00147
00148 for( long nelem=ipHYDROGEN; nelem < LIMELM; ++nelem )
00149 iso_satellite_update(nelem);
00150
00151
00152 lines_hydro();
00153
00154
00155 lines_helium();
00156
00157 #if 0
00158
00159
00160
00161 if( iteration > 1 )
00162 {
00163 fprintf( ioQQQ,"ipHi\tipLo\tnu\tlu\tsu\tnl\tll\tsl\tWL\tintens\n" );
00164 for( long ipHi=5; ipHi<= iso_sp[ipHE_LIKE][ipHELIUM].numLevels_local - iso_sp[ipHE_LIKE][ipHELIUM].nCollapsed_local; ipHi++ )
00165 {
00166 for( long ipLo=0; ipLo<ipHi; ipLo++ )
00167 {
00168 if( iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).ipCont() > 0 )
00169 {
00170 double relint, absint;
00171
00172 if( cdLine("He 1",
00173 iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng(),
00174 &relint, &absint ) )
00175 {
00176
00177
00178 if( iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng() < 1.1E4 &&
00179 iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng() > 3.59E3 &&
00180 ipLo!=3 && ipLo!=4 && relint >= 0.0009 )
00181 {
00182 fprintf( ioQQQ,"%li\t%li\t%li\t%li\t%li\t%li\t%li\t%li\t%e\t%e\n",
00183 ipHi,
00184 ipLo,
00185 iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].n(),
00186 iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].l(),
00187 iso_sp[ipHE_LIKE][ipHELIUM].st[ipHi].S(),
00188 iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].n(),
00189 iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].l(),
00190 iso_sp[ipHE_LIKE][ipHELIUM].st[ipLo].S(),
00191 iso_sp[ipHE_LIKE][ipHELIUM].trans(ipHi,ipLo).WLAng(),
00192 relint );
00193 }
00194 }
00195 }
00196 }
00197 }
00198 }
00199 #endif
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 i = StuffComment( "database lines" );
00212 linadd( 0., (realnum)i , "####", 'i' ,
00213 "database lines ");
00214 for (int ipSpecies=0; ipSpecies < nSpecies; ++ipSpecies)
00215 {
00216 for( EmissionList::iterator em=dBaseTrans[ipSpecies].Emis().begin();
00217 em != dBaseTrans[ipSpecies].Emis().end(); ++em)
00218 {
00219
00220 if( (*em).Tran().ipCont() > 0)
00221 {
00222 PutLine((*em).Tran(), "lines from third-party databases", (*(*em).Tran().Hi()).chLabel());
00223 }
00224 }
00225 }
00226
00227
00228 lines_lv1_li_ne();
00229
00230
00231 lines_lv1_na_ar();
00232
00233
00234 lines_lv1_k_zn();
00235
00236
00237 sum = PrtLineSum();
00238
00239
00240 if( LineSave.ipass > 0 )
00241 {
00242 LineSv[LineSave.nsum].SumLine[0] = 0.;
00243 LineSv[LineSave.nsum].SumLine[1] = 0.;
00244 }
00245
00246 linadd(sum/radius.dVeffAper,0,"Stoy",'i' ,
00247 "Stoy method energy sum ");
00248
00249
00250 i = StuffComment( "recombination" );
00251 linadd( 0., (realnum)i , "####", 'i' ,
00252 "recombination lines");
00253
00254
00255
00256
00257
00258 for( i=0; i < 471; i++ )
00259 {
00260
00261
00262 if( LineSave.ipass <= 0 )
00263 {
00264
00265 strcpy( chLabel, elementnames.chElementSym[(long)(LineSave.RecCoefCNO[0][i])-1] );
00266 strcat( chLabel, elementnames.chIonStage[(long)(LineSave.RecCoefCNO[0][i]-
00267 LineSave.RecCoefCNO[1][i]+1.01)-1] );
00268 }
00269 else
00270 chLabel[0] = ' ';
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 if( dense.eden < 1e8 )
00282 {
00283 nelem = (long)LineSave.RecCoefCNO[0][i]-1;
00284 long int ion = (long)(LineSave.RecCoefCNO[0][i]-LineSave.RecCoefCNO[1][i]+2)-1;
00285 f2 = LineSave.RecCoefCNO[3][i]*dense.eden*
00286 dense.xIonDense[nelem][ion];
00287
00288
00289 f2 = f2*1.99e-8/LineSave.RecCoefCNO[2][i];
00290 }
00291 else
00292 {
00293 f2 = 0.;
00294 }
00295
00296 PntForLine(LineSave.RecCoefCNO[2][i],chLabel,&ipnt);
00297 lindst(f2,LineSave.RecCoefCNO[2][i],chLabel,ipnt, 'r',true ,
00298 "recombination line");
00299 }
00300
00301
00302 i = StuffComment( "level2 lines" );
00303 linadd( 0., (realnum)i , "####", 'i' ,
00304 "level2 lines");
00305
00306
00307
00308 ExtraCool = 0.;
00309 BigstExtra = 0.;
00310 for( i=0; i < nWindLine; i++ )
00311 {
00312 if( (*TauLine2[i].Hi()).IonStg() < (*TauLine2[i].Hi()).nelem()+1-NISO )
00313 {
00314 PutLine(TauLine2[i],"level 2 line");
00315 if( TauLine2[i].Coll().cool() > BigstExtra )
00316 {
00317 BigstExtra = TauLine2[i].Coll().cool();
00318 thermal.ipMaxExtra = i+1;
00319 }
00320 ExtraCool += TauLine2[i].Coll().cool();
00321 }
00322 }
00323
00324 thermal.GBarMax = MAX2(thermal.GBarMax,(realnum)(ExtraCool/thermal.ctot));
00325
00326
00327 i = StuffComment( "hyperfine structure" );
00328 linadd( 0., (realnum)i , "####", 'i' ,
00329 "hyperfine structure lines ");
00330
00331
00332 linadd( hyperfine.cooling_total, 0., "hfin", 'i' ,
00333 "total cooling all hyperfine structure lines ");
00334
00335
00336 hyperfine.cooling_max = (realnum)MAX2(hyperfine.cooling_max,hyperfine.cooling_total/thermal.ctot);
00337
00338
00339 for( i=0; i < nHFLines; i++ )
00340 {
00341 PutLine(HFLines[i],
00342 "hyperfine structure line");
00343 }
00344
00345
00346 i = StuffComment( "inner shell" );
00347 linadd( 0., (realnum)i , "####", 'i' ,
00348 "inner shell lines");
00349
00350
00351 for( i=0; i < t_yield::Inst().nlines(); ++i )
00352 {
00353 double xInten =
00354
00355 dense.xIonDense[t_yield::Inst().nelem(i)][t_yield::Inst().ion(i)] *
00356
00357 ionbal.PhotoRate_Shell[t_yield::Inst().nelem(i)][t_yield::Inst().ion(i)][t_yield::Inst().nshell(i)][0]*
00358
00359 t_yield::Inst().yield(i) *
00360
00361 t_yield::Inst().energy(i) * EN1RYD;
00362
00363
00364 if( LineSave.ipass == 0 )
00365 {
00366
00367 strcpy( chLabel , elementnames.chElementSym[t_yield::Inst().nelem(i)] );
00368 strcat( chLabel , elementnames.chIonStage[t_yield::Inst().ion_emit(i)] );
00369 # if 0
00370
00371 if( t_yield::Inst().ion(i) == 0 && t_yield::Inst().nelem()(i) == ipIRON )
00372 fprintf(ioQQQ,"DEBUGyeild\t%s\t%.3f\t%.3e\n",
00373
00374 chLabel , t_yield::Inst().energy()(i)*EVRYD, t_yield::Inst().yield(i) );
00375 # endif
00376 }
00377
00378
00379 lindst(
00380
00381 xInten,
00382
00383 (realnum)RYDLAM / t_yield::Inst().energy(i),
00384
00385 chLabel ,
00386
00387 t_yield::Inst().ipoint(i),
00388
00389 'r',
00390
00391 true ,
00392 "inner shell line");
00393 }
00394
00395
00396
00397 {
00398 static long nLineSave=-1 , ndLineSave=-1;
00399 if( LineSave.ipass == 0 )
00400 {
00401 nLineSave = LineSave.nsum;
00402 ndLineSave = LineSave.nsum;
00403 }
00404 else if( LineSave.ipass > 0 )
00405 {
00406
00407 if( nLineSave<= 0 || ndLineSave < 0 )
00408 TotalInsanity();
00409
00410
00411
00412
00413 if( nLineSave != LineSave.nsum )
00414 {
00415 fprintf( ioQQQ, "DISASTER number of lines in LineSave.nsum changed between pass 0 and 1 - this is impossible\n" );
00416 fprintf( ioQQQ, "DISASTER LineSave.nsum is %li and nLineSave is %li\n",
00417 LineSave.nsum ,
00418 nLineSave);
00419 ShowMe();
00420 cdEXIT(EXIT_FAILURE);
00421 }
00422 if( ndLineSave != LineSave.nsum )
00423 {
00424 fprintf( ioQQQ, "DISASTER number of lines in LineSave.nsum changed between pass 0 and 1 - this is impossible\n" );
00425 fprintf( ioQQQ, "DISASTER LineSave.nsum is %li and ndLineSave is %li\n",
00426 LineSave.nsum ,
00427 ndLineSave);
00428 ShowMe();
00429 cdEXIT(EXIT_FAILURE);
00430 }
00431 }
00432 }
00433
00434
00435 lines_molecules();
00436
00437 if( trace.lgTrace )
00438 {
00439 fprintf( ioQQQ, " lines returns\n" );
00440 }
00441 return;
00442 }
00443
00444
00445 STATIC void Drive_cdLine( void )
00446 {
00447 long int j;
00448 bool lgMustPrintHeader = true;
00449 double absval , rel;
00450
00451 DEBUG_ENTRY( "Drive_cdLine()" );
00452
00453 for( j=1; j < LineSave.nsum; j++ )
00454 {
00455 if( cdLine( LineSv[j].chALab , LineSv[j].wavelength , &absval , &rel ) <= 0 )
00456 {
00457
00458 if( lgMustPrintHeader )
00459 {
00460 fprintf(ioQQQ,"n\tlab\twl\n");
00461 lgMustPrintHeader = false;
00462 }
00463
00464 fprintf(ioQQQ,"%li\t%s\t%f\n", j, LineSv[j].chALab , LineSv[j].wavelength );
00465 }
00466 }
00467 fprintf( ioQQQ, " Thanks for checking on the cdLine routine!\n" );
00468 cdEXIT(EXIT_FAILURE);
00469 }
00470