00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "cddefines.h"
00035 #include "physconst.h"
00036 #include "phycon.h"
00037 #include "lines.h"
00038 #include "radius.h"
00039 #include "geometry.h"
00040 #include "elementnames.h"
00041 #include "rt.h"
00042 #include "dense.h"
00043 #include "rfield.h"
00044 #include "opacity.h"
00045 #include "ipoint.h"
00046 #include "iso.h"
00047 #include "taulines.h"
00048 #include "hydrogenic.h"
00049 #include "lines_service.h"
00050
00051
00052 void outline( transition *t )
00053 {
00054 long int ip = t->ipCont-1;
00055 double xInWrd = t->Emis->phots*t->Emis->FracInwd;
00056
00057 DEBUG_ENTRY( "outline()" );
00058
00059 ASSERT( t->Emis->phots >= 0. );
00060 ASSERT( t->Emis->FracInwd >= 0. );
00061 ASSERT( radius.BeamInIn >= 0. );
00062 ASSERT( radius.BeamInOut >= 0. );
00063
00064
00065 rfield.reflin[ip] += (realnum)(xInWrd*radius.BeamInIn);
00066
00067
00068 rfield.outlin[ip] += (realnum)(xInWrd*radius.BeamInOut*opac.tmn[ip]*
00069 t->Emis->ColOvTot);
00070
00071
00073 rfield.outlin[ip] += (realnum)(t->Emis->phots*
00074 (1. - t->Emis->FracInwd)*radius.BeamOutOut* t->Emis->ColOvTot);
00075 return;
00076 }
00077
00078
00079 double emit_frac( transition *t )
00080 {
00081 DEBUG_ENTRY( "emit_frac()" );
00082
00083 ASSERT( t->ipCont > 0 );
00084
00085
00086
00087 double deexcit_loss = t->Coll.cs * dense.cdsqte + t->Emis->Aul*t->Emis->Pdest;
00088
00089 double rad_deexcit = t->Emis->Aul*(t->Emis->Pelec_esc + t->Emis->Pesc);
00090 return rad_deexcit/(deexcit_loss + rad_deexcit);
00091 }
00092
00093
00094
00095 void DumpLine(transition * t)
00096 {
00097 char chLbl[11];
00098
00099 DEBUG_ENTRY( "DumpLine()" );
00100
00101 ASSERT( t->ipCont > 0 );
00102
00103
00104 strcpy( chLbl, chLineLbl(t) );
00105
00106 fprintf( ioQQQ,
00107 " %10.10s Te%.2e eden%.1e CS%.2e Aul%.1e Tex%.2e cool%.1e het%.1e conopc%.1e albdo%.2e\n",
00108 chLbl,
00109 phycon.te,
00110 dense.eden,
00111 t->Coll.cs,
00112 t->Emis->Aul,
00113 TexcLine(t),
00114 t->Coll.cool,
00115 t->Coll.heat ,
00116 opac.opacity_abs[t->ipCont-1],
00117 opac.albedo[t->ipCont-1]);
00118
00119 fprintf( ioQQQ,
00120 " Tin%.1e Tout%.1e Esc%.1e eEsc%.1e DesP%.1e Pump%.1e OTS%.1e PopL,U %.1e %.1e PopOpc%.1e\n",
00121 t->Emis->TauIn,
00122 t->Emis->TauTot,
00123 t->Emis->Pesc,
00124 t->Emis->Pelec_esc,
00125 t->Emis->Pdest,
00126 t->Emis->pump,
00127 t->Emis->ots,
00128 t->Lo->Pop,
00129 t->Hi->Pop ,
00130 t->Emis->PopOpc );
00131 return;
00132 }
00133
00134
00135
00136 double OccupationNumberLine( transition * t )
00137 {
00138 double OccupationNumberLine_v;
00139
00140 DEBUG_ENTRY( "OccupationNumberLine()" );
00141
00142 ASSERT( t->ipCont > 0 );
00143
00144
00145 if( t->Lo->Pop > SMALLFLOAT )
00146 {
00147
00148 double PopLo_corr = t->Lo->Pop / t->Lo->g - t->Hi->Pop / t->Hi->g;
00149 OccupationNumberLine_v = ( t->Hi->Pop / t->Hi->g )/SDIV(PopLo_corr ) *
00150 (1. - t->Emis->Pesc);
00151 }
00152 else
00153 {
00154 OccupationNumberLine_v = 0.;
00155 }
00156 return( OccupationNumberLine_v );
00157 }
00158
00159
00160 double TexcLine(transition * t)
00161 {
00162 double TexcLine_v;
00163
00164 DEBUG_ENTRY( "TexcLine()" );
00165
00166
00167
00168 if( t->Hi->Pop * t->Lo->Pop > 0. )
00169 {
00170 TexcLine_v = ( t->Hi->Pop / t->Hi->g )/( t->Lo->Pop / t->Lo->g );
00171 TexcLine_v = log(TexcLine_v);
00172
00173 if( fabs(TexcLine_v) > SMALLFLOAT )
00174 {
00175 TexcLine_v = - t->EnergyK / TexcLine_v;
00176 }
00177 }
00178 else
00179 {
00180 TexcLine_v = 0.;
00181 }
00182 return( TexcLine_v );
00183 }
00184
00185
00186 double eina(double gf,
00187 double enercm,
00188 double gup)
00189 {
00190 double eina_v;
00191
00192 DEBUG_ENTRY( "eina()" );
00193
00194
00195
00196
00197
00198 eina_v = (gf/gup)*TRANS_PROB_CONST*POW2(enercm);
00199 return( eina_v );
00200 }
00201
00202
00203 double GetGF(double trans_prob,
00204 double enercm,
00205 double gup)
00206 {
00207 double GetGF_v;
00208
00209 DEBUG_ENTRY( "GetGF()" );
00210
00211 ASSERT( enercm > 0. );
00212 ASSERT( trans_prob > 0. );
00213 ASSERT( gup > 0.);
00214
00215
00216
00217
00218
00219 GetGF_v = trans_prob*gup/TRANS_PROB_CONST/POW2(enercm);
00220 return( GetGF_v );
00221 }
00222
00223
00224 double abscf(double gf,
00225 double enercm,
00226 double gl)
00227 {
00228 double abscf_v;
00229
00230 DEBUG_ENTRY( "abscf()" );
00231
00232 ASSERT(gl > 0. && enercm > 0. && gf > 0. );
00233
00234
00235
00236
00237 abscf_v = 1.4974e-6*(gf/gl)*(1e4/enercm);
00238 return( abscf_v );
00239 }
00240
00241
00242 void chIonLbl(char *chIonLbl_v , transition * t )
00243 {
00244
00245
00246 DEBUG_ENTRY( "chIonLbl()" );
00247
00248
00249
00250
00251
00252 if( t->Hi->nelem < 0 )
00253 {
00254
00255 strcpy( chIonLbl_v, "Dumy" );
00256 }
00257 else if( t->Hi->nelem-1 >= LIMELM )
00258 {
00259
00260
00261
00262 strcpy( chIonLbl_v , elementnames.chElementNameShort[t->Hi->nelem-1] );
00263
00264
00265
00266 }
00267
00268 else
00269 {
00270 ASSERT( t->Hi->nelem >= 1 );
00271
00272
00273 strcpy( chIonLbl_v , elementnames.chElementSym[t->Hi->nelem -1] );
00274
00275
00276 strcat( chIonLbl_v, elementnames.chIonStage[t->Hi->IonStg-1]);
00277 }
00278
00279 return;
00280 }
00281
00282
00283
00284
00285 char* chLineLbl(transition * t )
00286 {
00287 static char chLineLbl_v[11];
00288
00289 DEBUG_ENTRY( "chLineLbl()" );
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 if( t->WLAng > (realnum)INT_MAX )
00301 {
00302 sprintf( chLineLbl_v, "%2.2s%2.2s%5i%c",
00303 elementnames.chElementSym[t->Hi->nelem -1],
00304 elementnames.chIonStage[t->Hi->IonStg-1],
00305 (int)(t->WLAng/1e8), 'c' );
00306 }
00307 else if( t->WLAng > 9999999. )
00308 {
00309
00310 sprintf( chLineLbl_v, "%2.2s%2.2s%5.2f%c",
00311 elementnames.chElementSym[t->Hi->nelem -1],
00312 elementnames.chIonStage[t->Hi->IonStg-1],
00313 t->WLAng/1e8, 'c' );
00314 }
00315 else if( t->WLAng > 999999. )
00316 {
00317
00318 sprintf( chLineLbl_v, "%2.2s%2.2s%5i%c",
00319 elementnames.chElementSym[t->Hi->nelem -1],
00320 elementnames.chIonStage[t->Hi->IonStg-1],
00321 (int)(t->WLAng/1e4), 'm' );
00322 }
00323 else if( t->WLAng > 99999. )
00324 {
00325
00326 sprintf( chLineLbl_v, "%2.2s%2.2s%5.1f%c",
00327 elementnames.chElementSym[t->Hi->nelem -1],
00328 elementnames.chIonStage[t->Hi->IonStg-1],
00329 t->WLAng/1e4, 'm' );
00330 }
00331 else if( t->WLAng > 9999. )
00332 {
00333 sprintf( chLineLbl_v, "%2.2s%2.2s%5.2f%c",
00334 elementnames.chElementSym[ t->Hi->nelem -1],
00335 elementnames.chIonStage[t->Hi->IonStg-1],
00336 t->WLAng/1e4, 'm' );
00337 }
00338 else if( t->WLAng >= 100. )
00339 {
00340 sprintf( chLineLbl_v, "%2.2s%2.2s%5i%c",
00341 elementnames.chElementSym[ t->Hi->nelem -1],
00342 elementnames.chIonStage[t->Hi->IonStg-1],
00343 (int)t->WLAng, 'A' );
00344 }
00345
00346
00347 else if( t->WLAng >= 10. )
00348 {
00349 sprintf( chLineLbl_v, "%2.2s%2.2s%5.1f%c",
00350 elementnames.chElementSym[ t->Hi->nelem -1],
00351 elementnames.chIonStage[t->Hi->IonStg-1],
00352 t->WLAng, 'A' );
00353 }
00354 else
00355 {
00356 sprintf( chLineLbl_v, "%2.2s%2.2s%5.2f%c",
00357 elementnames.chElementSym[ t->Hi->nelem -1],
00358 elementnames.chIonStage[t->Hi->IonStg-1],
00359 t->WLAng, 'A' );
00360 }
00361
00362
00363 ASSERT( chLineLbl_v[10]==0 );
00364 return( chLineLbl_v );
00365 }
00366
00367
00368
00369 double RefIndex(double EnergyWN )
00370 {
00371 double RefIndex_v,
00372 WaveMic,
00373 xl,
00374 xn;
00375
00376 DEBUG_ENTRY( "RefIndex()" );
00377
00378 ASSERT( EnergyWN > 0. );
00379
00380
00381 WaveMic = 1.e4/EnergyWN;
00382
00383
00384 if( WaveMic > 0.2 )
00385 {
00386
00387
00388 xl = 1.0/WaveMic/WaveMic;
00389
00390
00391
00392 xn = 255.4/(41. - xl);
00393 xn += 29498.1/(146. - xl);
00394 xn += 64.328;
00395 RefIndex_v = xn/1.e6 + 1.;
00396 }
00397 else
00398 {
00399 RefIndex_v = 1.;
00400 }
00401 ASSERT( RefIndex_v > 0. );
00402 return( RefIndex_v );
00403 }
00404
00405
00406 void PutCS(double cs,
00407 transition * t)
00408 {
00409
00410 DEBUG_ENTRY( "PutCS()" );
00411
00412
00413
00414 ASSERT( cs >= 0. );
00415
00416 t->Coll.cs = (realnum)cs;
00417 return;
00418 }
00419
00420
00421
00422
00423
00424
00425 realnum WavlenErrorGet( realnum wavelength )
00426 {
00427 double a;
00428 realnum errorwave;
00429
00430 DEBUG_ENTRY( "WavlenErrorGet()" );
00431
00432 ASSERT( LineSave.sig_figs <= 6 );
00433
00434 if( wavelength > 0. )
00435 {
00436
00437 a = log10( wavelength+FLT_EPSILON);
00438 a = floor(a);
00439 }
00440 else
00441 {
00442
00443
00444 a = 0.;
00445 }
00446
00447 errorwave = 5.f * (realnum)pow( 10., a - (double)LineSave.sig_figs );
00448 return errorwave;
00449 }
00450
00451
00452 void linadd(
00453 double xInten,
00454 realnum wavelength,
00455 const char *chLab,
00456 char chInfo,
00457
00458 const char *chComment )
00459 {
00460 DEBUG_ENTRY( "linadd()" );
00461
00462
00463
00464
00465
00466
00467
00468 if( LineSave.ipass > 0 )
00469 {
00470
00471
00472 LineSv[LineSave.nsum].sumlin[0] += xInten*radius.dVeff;
00473
00474 LineSv[LineSave.nsum].emslin[0] = xInten;
00475
00476
00477 if( wavelength > 0 )
00478 {
00479
00480
00481
00482 LineSv[LineSave.nsum].emslin[1] = LineSv[LineSave.nsum].emslin[0];
00483 LineSv[LineSave.nsum].sumlin[1] = LineSv[LineSave.nsum].sumlin[0];
00484 }
00485 }
00486
00487 else if( LineSave.ipass == 0 )
00488 {
00489
00490
00491
00492 ASSERT( (chInfo == 'c') || (chInfo == 'h') || (chInfo == 'i') || (chInfo == 'r' ) );
00493
00494
00495 LineSv[LineSave.nsum].chSumTyp = (char)chInfo;
00496
00497
00498 LineSv[LineSave.nsum].sumlin[0] = 0.;
00499 LineSv[LineSave.nsum].emslin[0] = 0.;
00500 LineSv[LineSave.nsum].wavelength = wavelength;
00501 LineSv[LineSave.nsum].sumlin[1] = 0.;
00502 LineSv[LineSave.nsum].emslin[1] = 0.;
00503 LineSv[LineSave.nsum].chComment = chComment;
00504
00505
00506 ASSERT( strlen( chLab )<5 );
00507 strcpy( LineSv[LineSave.nsum].chALab, chLab );
00508 }
00509
00510
00511 ++LineSave.nsum;
00512
00513
00514
00515 return;
00516 }
00517
00518
00519
00520 static double EnergyRyd;
00521
00522
00523 double emergent_line(
00524
00525 double emissivity_in ,
00526
00527 double emissivity_out ,
00528
00529 long int ipCont )
00530 {
00531
00532 double emergent_in , emergent_out;
00533 long int i = ipCont-1;
00534
00535 DEBUG_ENTRY( "emergent_line()" );
00536
00537 ASSERT( i >= 0 && i < rfield.nupper-1 );
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 if( iteration == 1 )
00549 {
00550
00551
00552 emergent_in = emissivity_in*opac.E2TauAbsFace[i];
00553 emergent_out = emissivity_out;
00554 }
00555 else
00556 {
00557 if( geometry.lgSphere )
00558 {
00559
00560
00561
00562 emergent_in = emissivity_in * opac.E2TauAbsFace[i] *opac.E2TauAbsTotal[i];
00563
00564
00565 emergent_out = emissivity_out * opac.E2TauAbsOut[i];
00566 }
00567 else
00568 {
00569
00570
00571
00572 double reflected = emissivity_out * opac.albedo[i] * (1.-opac.E2TauAbsOut[i]);
00573
00574 emergent_in = (emissivity_in + reflected) * opac.E2TauAbsFace[i];
00575
00576 emergent_out = (emissivity_out - reflected) * opac.E2TauAbsOut[i];
00577 }
00578 }
00579
00580 return( (emergent_in + emergent_out) );
00581 }
00582
00583
00584 void lindst(
00585 double xInten,
00586 realnum wavelength,
00587 const char *chLab,
00588 long int ipnt,
00589 char chInfo,
00590 bool lgOutToo,
00591 const char *chComment )
00592 {
00593 double saveemis;
00594 DEBUG_ENTRY( "lindst()" );
00595
00596
00597
00598 if( LineSave.ipass > 0 && xInten > 0. )
00599 {
00600
00601
00602 LineSv[LineSave.nsum].emslin[0] = xInten;
00603
00604 LineSv[LineSave.nsum].sumlin[0] += xInten*radius.dVeff;
00605
00606
00607
00608
00609
00610
00611
00612 if( lgOutToo )
00613 {
00614 rfield.outlin[ipnt-1] += (realnum)(xInten/(rfield.anu[ipnt-1]*EN1RYD)*
00615 radius.dVolOutwrd*opac.ExpZone[ipnt-1]);
00616 rfield.reflin[ipnt-1] += (realnum)(xInten/(rfield.anu[ipnt-1]*EN1RYD)*
00617 radius.dVolReflec);
00618 }
00619
00620 if( ipnt <= rfield.nflux )
00621 {
00622
00623
00624 saveemis = emergent_line(
00625 xInten*rt.fracin , xInten*(1.-rt.fracin) , ipnt );
00626 LineSv[LineSave.nsum].emslin[1] = saveemis;
00627 LineSv[LineSave.nsum].sumlin[1] += saveemis*radius.dVeff;
00628 }
00629 }
00630 else if( LineSave.ipass == 0 )
00631 {
00632 ASSERT( ipnt > 0 );
00633
00634
00635
00636
00637 ASSERT( (chInfo == 'c') || (chInfo == 'h') || (chInfo == 'i') || (chInfo == 'r' ) );
00638 LineSv[LineSave.nsum].chSumTyp = (char)chInfo;
00639
00640 LineSv[LineSave.nsum].sumlin[0] = 0.;
00641 LineSv[LineSave.nsum].emslin[0] = 0.;
00642 LineSv[LineSave.nsum].wavelength = wavelength;
00643 LineSv[LineSave.nsum].emslin[1] = 0.;
00644 LineSv[LineSave.nsum].sumlin[1] = 0.;
00645 LineSv[LineSave.nsum].chComment = chComment;
00646
00647
00648
00649 ASSERT( strlen( chLab )<5 );
00650 strcpy( LineSv[LineSave.nsum].chALab, chLab );
00651 }
00652
00653
00654 ++LineSave.nsum;
00655
00656 EnergyRyd = 0.;
00657 return;
00658 }
00659
00660
00661 void PntForLine(
00662
00663 double wavelength,
00664
00665 const char *chLabel,
00666
00667
00668 long int *ipnt)
00669 {
00670
00671
00672
00673
00674
00675 # define MAXFORLIN 1000
00676 static long int ipForLin[MAXFORLIN]={0};
00677
00678
00679 static long int nForLin;
00680
00681 DEBUG_ENTRY( "PntForLine()" );
00682
00683
00684 ASSERT( wavelength >= 0. );
00685
00686 if( wavelength == 0. )
00687 {
00688
00689 nForLin = 0;
00690
00691 EnergyRyd = 0.;
00692 }
00693 else
00694 {
00695
00696 if( LineSave.ipass > 0 )
00697 {
00698
00699 *ipnt = ipForLin[nForLin];
00700 }
00701 else if( LineSave.ipass == 0 )
00702 {
00703
00704 if( nForLin >= MAXFORLIN )
00705 {
00706 fprintf( ioQQQ, "PROBLEM %5ld lines is too many for PntForLine.\n",
00707 nForLin );
00708 fprintf( ioQQQ, " Increase the value of maxForLine everywhere in the code.\n" );
00709 cdEXIT(EXIT_FAILURE);
00710 }
00711
00712
00713 EnergyRyd = RYDLAM/wavelength;
00714 ipForLin[nForLin] = ipLineEnergy(EnergyRyd,chLabel , 0);
00715 *ipnt = ipForLin[nForLin];
00716 }
00717 else
00718 {
00719
00720 *ipnt = 0;
00721 }
00722 ++nForLin;
00723 }
00724 return;
00725 }
00726
00727 static realnum ExtraInten;
00728
00729
00730 void PutLine(transition * t, const char *chComment, const char *chLabelTemp)
00731 {
00732 char chLabel[5];
00733 realnum wl;
00734 double xIntensity,
00735 other,
00736 xIntensity_in;
00737
00738 DEBUG_ENTRY( "PutLine()" );
00739
00740
00741
00742 ASSERT( t->ipCont > 0. );
00743
00744 strcpy( chLabel, chLabelTemp );
00745 chLabel[4] = '\0';
00746
00747
00748
00749 if( LineSave.ipass == 0 )
00750 {
00751
00752 wl = t->WLAng;
00753
00754 xIntensity = 0.;
00755 }
00756 else
00757 {
00758
00759
00760
00761 chLabel[0] = '\n';
00762 wl = 0.;
00763
00764
00765 xIntensity = t->Emis->xIntensity + ExtraInten;
00766 }
00767
00768
00769
00770
00771
00772
00773 ExtraInten = 0.;
00774
00775
00776 rt.fracin = t->Emis->FracInwd;
00777 lindst(xIntensity,
00778 wl,
00779 chLabel,
00780 t->ipCont,
00781
00782 'i',
00783
00784 false,
00785 chComment);
00786 rt.fracin = 0.5;
00787
00788
00789
00790 xIntensity_in = xIntensity*t->Emis->FracInwd;
00791 linadd(xIntensity_in,wl,"Inwd",'i',chComment);
00792
00793
00794 other = t->Coll.cool;
00795 linadd(other,wl,"Coll",'i',chComment);
00796
00797
00798 other = t->Emis->PopOpc * t->Emis->pump * (1.-t->Emis->ColOvTot) * t->EnergyErg;
00799 linadd(other,wl,"Pump",'i',chComment);
00800
00801
00802 other = t->Coll.heat;
00803 linadd(other,wl,"Heat",'i',chComment);
00804 return;
00805 }
00806
00807
00808 void PutLine(transition * t,
00809 const char *chComment)
00810 {
00811 char chLabel[5];
00812 realnum wl;
00813 double xIntensity,
00814 other,
00815 xIntensity_in;
00816
00817 DEBUG_ENTRY( "PutLine()" );
00818
00819
00820
00821 ASSERT( t->ipCont > 0. );
00822
00823
00824
00825 if( LineSave.ipass == 0 )
00826 {
00827
00828
00829 chIonLbl(chLabel, t);
00830
00831
00832 wl = t->WLAng;
00833
00834 xIntensity = 0.;
00835 }
00836 else
00837 {
00838
00839
00840
00841 chLabel[0] = '\n';
00842 wl = 0.;
00843
00844
00845 xIntensity = t->Emis->xIntensity + ExtraInten;
00846 }
00847
00848
00849
00850
00851
00852
00853 ExtraInten = 0.;
00854
00855
00856 rt.fracin = t->Emis->FracInwd;
00857 lindst(xIntensity,
00858 wl,
00859 chLabel,
00860 t->ipCont,
00861
00862 'i',
00863
00864 false,
00865 chComment);
00866 rt.fracin = 0.5;
00867
00868
00869
00870 xIntensity_in = xIntensity*t->Emis->FracInwd;
00871 linadd(xIntensity_in,wl,"Inwd",'i',chComment);
00872
00873
00874 other = t->Coll.cool;
00875 linadd(other,wl,"Coll",'i',chComment);
00876
00877
00878 other = t->Emis->PopOpc * t->Emis->pump * (1.-t->Emis->ColOvTot) * t->EnergyErg;
00879 linadd(other,wl,"Pump",'i',chComment);
00880
00881
00882 other = t->Coll.heat;
00883 linadd(other,wl,"Heat",'i',chComment);
00884 return;
00885 }
00886
00887
00888
00889 void PutExtra(double Extra)
00890 {
00891
00892 DEBUG_ENTRY( "PutExtra()" );
00893
00894 ExtraInten = (realnum)Extra;
00895 return;
00896 }
00897
00898 void TransitionJunk( transition *t )
00899 {
00900
00901 DEBUG_ENTRY( "TransitionJunk()" );
00902
00903
00904 t->WLAng = -FLT_MAX;
00905
00906
00907 t->EnergyK = -FLT_MAX;
00908
00909 t->EnergyErg = -FLT_MAX;
00910
00911 t->EnergyWN = -FLT_MAX;
00912
00913
00914
00915 t->ipCont = -10000;
00916
00917 CollisionJunk( &t->Coll );
00918
00919
00920
00921 t->Emis = &DummyEmis;
00922
00923 t->Lo = NULL;
00924 t->Hi = NULL;
00925 return;
00926 }
00927
00928
00929
00930 void EmLineJunk( emission *t )
00931 {
00932
00933 DEBUG_ENTRY( "EmLineJunk()" );
00934
00935
00936 t->TauCon = -FLT_MAX;
00937
00938
00939 t->TauIn = -FLT_MAX;
00940 t->TauTot = -FLT_MAX;
00941
00942
00943 t->iRedisFun = INT_MIN;
00944
00945
00946 t->ipFine = -10000;
00947
00948
00949 t->FracInwd = -FLT_MAX;
00950
00951
00952 t->pump = -FLT_MAX;
00953
00954
00955 t->xIntensity = -FLT_MAX;
00956
00957
00958 t->phots = -FLT_MAX;
00959
00960
00961 t->gf = -FLT_MAX;
00962
00963
00964 t->Pesc = -FLT_MAX;
00965 t->Pdest = -FLT_MAX;
00966 t->Pelec_esc = -FLT_MAX;
00967
00968
00969 t->dampXvel = -FLT_MAX;
00970 t->damp = -FLT_MAX;
00971
00972
00973 t->ColOvTot = -FLT_MAX;
00974
00975
00976 t->opacity = -FLT_MAX;
00977
00978 t->PopOpc = -FLT_MAX;
00979
00980
00981 t->Aul = -FLT_MAX;
00982
00983
00984 t->ots = -FLT_MAX;
00985 return;
00986 }
00987
00988
00989 void CollisionJunk( collision * t )
00990 {
00991
00992 DEBUG_ENTRY( "CollisionJunk()" );
00993
00995 t->ColUL = -FLT_MAX;
00996
00997
00998 t->cool = -FLT_MAX;
00999 t->heat = -FLT_MAX;
01000
01001
01002 t->cs = -FLT_MAX;
01003 for( long i=0; i<ipNCOLLIDER; i++ )
01004 t->csi[i] = -FLT_MAX;
01005 return;
01006 }
01007
01008
01009 void StateJunk( quantumState * t )
01010 {
01011
01012 DEBUG_ENTRY( "StateJunk()" );
01013
01014
01015
01017 t->g = -FLT_MAX;
01018
01020 t->Pop = -FLT_MAX;
01021
01023 t->IonStg = -10000;
01024
01026 t->nelem = -10000;
01027 return;
01028 }
01029
01030
01031 void TransitionZero( transition *t )
01032 {
01033
01034 DEBUG_ENTRY( "TransitionZero()" );
01035
01036 CollisionZero( &t->Coll );
01037
01038 StateZero( t->Lo );
01039 StateZero( t->Hi );
01040 EmLineZero( t->Emis );
01041
01042 return;
01043 }
01044
01045
01046 void EmLineZero( emission * t )
01047 {
01048
01049 DEBUG_ENTRY( "EmLineZero()" );
01050
01051
01052
01053 t->TauCon = opac.taumin;
01054
01055
01056
01057 t->TauIn = opac.taumin;
01058
01059
01060 t->TauTot = 1e20f;
01061
01062
01063
01064 t->FracInwd = 1.;
01065
01066
01067 t->pump = 0.;
01068
01069
01070 t->xIntensity = 0.;
01071
01072
01073 t->phots = 0.;
01074
01075
01076
01077 t->Pesc = 1.;
01078 t->Pdest = 0.;
01079 t->Pelec_esc = 0.;
01080
01081
01082 t->ColOvTot = 0.;
01083
01084
01085 t->PopOpc = 0.;
01086
01087
01088 t->ots = 0.;
01089 return;
01090 }
01091
01092
01093 void CollisionZero( collision * t )
01094 {
01095
01096 DEBUG_ENTRY( "CollisionZero()" );
01097
01098
01099 t->cool = 0.;
01100 t->heat = 0.;
01101 return;
01102 }
01103
01104
01105 void StateZero( quantumState * t )
01106 {
01107
01108 DEBUG_ENTRY( "StateZero()" );
01109
01111 t->Pop = 0.;
01112 return;
01113 }
01114
01115
01116 void LineConvRate2CS( transition* t , realnum rate )
01117 {
01118
01119 DEBUG_ENTRY( "LineConvRate2CS()" );
01120
01121
01122
01123
01124 t->Coll.cs = rate * t->Hi->g / (realnum)dense.cdsqte;
01125
01126
01127
01128 ASSERT( t->Coll.cs >= 0. );
01129 return;
01130 }
01131
01132
01133 double ConvRate2CS( realnum gHi , realnum rate )
01134 {
01135
01136 double cs;
01137
01138 DEBUG_ENTRY( "ConvRate2CS()" );
01139
01140
01141
01142
01143 cs = rate * gHi / dense.cdsqte;
01144
01145
01146
01147 ASSERT( cs >= 0. );
01148 return cs;
01149 }
01150
01151
01152 bool lgTauGood( transition * t)
01153 {
01154 bool lgGoodTau;
01155
01156 DEBUG_ENTRY( "lgTauGood()" );
01157
01158 if( (t->Emis->TauTot*0.9 - t->Emis->TauIn < 0. && t->Emis->TauIn > 0.) &&
01159 ! fp_equal( t->Emis->TauTot, opac.taumin ) )
01160 {
01161
01162 lgGoodTau = false;
01163 }
01164 else
01165 {
01166 lgGoodTau = true;
01167 }
01168 return lgGoodTau;
01169 }
01170
01171
01172 STATIC void gbar0(double ex,
01173 realnum *g)
01174 {
01175 double a,
01176 b,
01177 c,
01178 d,
01179 y;
01180
01181 DEBUG_ENTRY( "gbar0()" );
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 y = ex/phycon.te;
01197 if( y < 0.01 )
01198 {
01199 *g = (realnum)(0.29*(log(1.0+1.0/y) - 0.4/POW2(y + 1.0))/exp(y));
01200 }
01201 else
01202 {
01203 if( y > 10.0 )
01204 {
01205 *g = (realnum)(0.066/sqrt(y));
01206 }
01207 else
01208 {
01209 a = 1.5819068e-02;
01210 b = 1.3018207e00;
01211 c = 2.6896230e-03;
01212 d = 2.5486007e00;
01213 d = log(y/c)/d;
01214 *g = (realnum)(a + b*exp(-0.5*POW2(d)));
01215 }
01216 }
01217 return;
01218 }
01219
01220
01221 STATIC void gbar1(double ex,
01222 realnum *g)
01223 {
01224 double y;
01225
01226 DEBUG_ENTRY( "gbar1()" );
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 y = ex/phycon.te;
01242 *g = (realnum)(0.6 + 0.28*(log(1.0+1.0/y) - 0.4/POW2(y + 1.0)));
01243 return;
01244 }
01245
01246
01247 void MakeCS(transition * t)
01248 {
01249 long int ion;
01250 double Abun,
01251 cs;
01252 realnum
01253 gbar;
01254
01255 DEBUG_ENTRY( "MakeCS()" );
01256
01257
01258
01259
01260 ion = t->Hi->IonStg;
01261
01262 Abun = dense.xIonDense[ t->Hi->nelem -1 ][ ion-1 ];
01263 if( Abun <= 0. )
01264 {
01265 gbar = 1.;
01266 }
01267 else
01268 {
01269
01270 if( ion == 1 )
01271 {
01272
01273 gbar0(t->EnergyK,&gbar);
01274 }
01275 else
01276 {
01277
01278 gbar1(t->EnergyK,&gbar);
01279 }
01280 }
01281
01282
01283 cs = gbar*(14.5104/WAVNRYD)*t->Emis->gf/t->EnergyWN;
01284
01285
01286 t->Coll.cs = (realnum)cs;
01287 return;
01288 }
01289
01290
01291 double totlin(
01292
01293
01294
01295
01296 int chInfo)
01297 {
01298 long int i;
01299 double totlin_v;
01300
01301 DEBUG_ENTRY( "totlin()" );
01302
01303
01304
01305
01306
01307
01308 if( (chInfo != 'i' && chInfo != 'r') && chInfo != 'c' )
01309 {
01310 fprintf( ioQQQ, " TOTLIN does not understand chInfo=%c\n",
01311 chInfo );
01312 cdEXIT(EXIT_FAILURE);
01313 }
01314
01315
01316
01317 totlin_v = 0.;
01318 for( i=0; i < LineSave.nsum; i++ )
01319 {
01320 if( LineSv[i].chSumTyp == chInfo )
01321 {
01322 totlin_v += LineSv[i].sumlin[0];
01323 }
01324 }
01325 return( totlin_v );
01326 }
01327
01328
01329
01330 void FndLineHt(long int *level,
01331
01332 long int *ipStrong,
01333 double *Strong)
01334 {
01335 long int i;
01336
01337 DEBUG_ENTRY( "FndLineHt()" );
01338
01339 *Strong = 0.;
01340 *level = 0;
01341
01342
01343 for( i=1; i <= nLevel1; i++ )
01344 {
01345
01346 if( TauLines[i].Coll.heat > *Strong )
01347 {
01348 *ipStrong = i;
01349 *level = 1;
01350 *Strong = TauLines[i].Coll.heat;
01351 }
01352 }
01353
01354
01355 for( i=0; i < nWindLine; i++ )
01356 {
01357 if( TauLine2[i].Hi->IonStg < TauLine2[i].Hi->nelem+1-NISO )
01358 {
01359
01360 if( TauLine2[i].Coll.heat > *Strong )
01361 {
01362 *ipStrong = i;
01363 *level = 2;
01364 *Strong = TauLine2[i].Coll.heat;
01365 }
01366 }
01367 }
01368
01369
01370 for( i=0; i < nCORotate; i++ )
01371 {
01372
01373 if( C12O16Rotate[i].Coll.heat > *Strong )
01374 {
01375 *ipStrong = i;
01376 *level = 3;
01377 *Strong = C12O16Rotate[i].Coll.heat;
01378 }
01379 }
01380 for( i=0; i < nCORotate; i++ )
01381 {
01382
01383 if( C13O16Rotate[i].Coll.heat > *Strong )
01384 {
01385 *ipStrong = i;
01386 *level = 4;
01387 *Strong = C13O16Rotate[i].Coll.heat;
01388 }
01389 }
01390
01391
01392 for( i=0; i < nHFLines; i++ )
01393 {
01394
01395 if( HFLines[i].Coll.heat > *Strong )
01396 {
01397 *ipStrong = i;
01398 *level = 5;
01399 *Strong = HFLines[i].Coll.heat;
01400 }
01401 }
01402
01403
01404 for( i=0; i <linesAdded2; i++)
01405 {
01406
01407 if( atmolEmis[i].tran->Coll.heat > *Strong )
01408 {
01409 *ipStrong = i;
01410 *level = 6;
01411 *Strong = atmolEmis[i].tran->Coll.heat;
01412 }
01413 }
01414 return;
01415 }
01416
01417 quantumState *AddState2Stack( void )
01418 {
01419 DEBUG_ENTRY( "AddState2Stack()" );
01420
01421 ASSERT( !lgStatesAdded );
01422
01423 currentState = new quantumState;
01424
01425 StateJunk( currentState );
01426
01427 if( statesAdded == 0 )
01428 {
01429 GenericStates = currentState;
01430 GenericStates->next = NULL;
01431 lastState = GenericStates;
01432 }
01433 else
01434 {
01435 StateZero( currentState );
01436 lastState->next = currentState;
01437 lastState = lastState->next;
01438 }
01439
01440 statesAdded++;
01441
01442 return currentState;
01443 }
01444
01445 emission *AddLine2Stack( bool lgRadiativeTrans )
01446 {
01447 DEBUG_ENTRY( "AddLine2Stack()" );
01448
01449 if( !lgRadiativeTrans )
01450 {
01451 return &DummyEmis;
01452 }
01453 else
01454 {
01455 ASSERT( lgLinesAdded == false );
01456
01457 currentLine = new emission;
01458
01459 EmLineJunk( currentLine );
01460
01461 if( linesAdded == 0 )
01462 {
01463 GenericLines = currentLine;
01464 GenericLines->next = NULL;
01465 lastLine = GenericLines;
01466 }
01467 else
01468 {
01469
01470
01471
01472
01473 EmLineZero( currentLine );
01474
01475 lastLine->next = currentLine;
01476 lastLine = lastLine->next;
01477 }
01478
01479 linesAdded++;
01480 return currentLine;
01481 }
01482 }