00001
00002
00003
00004
00005
00006 #include "cddefines.h"
00007 #include "atmdat.h"
00008 #include "dense.h"
00009 #include "elementnames.h"
00010 #include "helike.h"
00011 #include "helike_einsta.h"
00012 #include "hydro_bauman.h"
00013 #include "hydrogenic.h"
00014 #include "hydroeinsta.h"
00015 #include "iso.h"
00016 #include "lines_service.h"
00017 #include "opacity.h"
00018 #include "phycon.h"
00019 #include "physconst.h"
00020 #include "secondaries.h"
00021 #include "taulines.h"
00022 #include "thirdparty.h"
00023
00024
00025 STATIC void iso_zero(void);
00026
00027
00028 STATIC void iso_allocate(void);
00029
00030
00031 STATIC void iso_assign_quantum_numbers(void);
00032
00033 STATIC void FillExtraLymanLine( transition *t, long ipISO, long nelem, long nHi );
00034
00035
00036 STATIC double iso_state_lifetime( long ipISO, long nelem, long n, long l );
00037
00038 STATIC void iso_satellite( void );
00039
00040 char chL[21]={'S','P','D','F','G','H','I','K','L','M','N','O','Q','R','T','U','V','W','X','Y','Z'};
00041
00042 void iso_create(void)
00043 {
00044 long int ipHi,
00045 ipLo,
00046 ipISO,
00047 nelem;
00048
00049 static int nCalled = 0;
00050
00051 double HIonPoten;
00052
00053 DEBUG_ENTRY( "iso_create()" );
00054
00055
00056 if( nCalled > 0 )
00057 {
00058 iso_zero();
00059 return;
00060 }
00061
00062
00063 ++nCalled;
00064
00065
00066 iso.stat_ion[ipH_LIKE] = 1.f;
00067 iso.stat_ion[ipHE_LIKE] = 2.f;
00068
00069
00070
00071 iso_allocate();
00072
00073
00074 iso_assign_quantum_numbers();
00075
00076
00077 TransitionJunk( &TauDummy );
00078 TauDummy.Hi = AddState2Stack();
00079 TauDummy.Lo = AddState2Stack();
00080 TauDummy.Emis = AddLine2Stack( true );
00081
00082
00083
00084
00085 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00086 {
00087
00088 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00089 {
00090
00091 if( nelem < 2 || dense.lgElmtOn[nelem] )
00092 {
00093
00094
00095
00096 HIonPoten = t_ADfA::Inst().ph1(0,0,nelem,0)/EVRYD* 0.9998787;
00097 ASSERT(HIonPoten > 0.);
00098
00099
00100 for( ipHi=0; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00101 {
00102 double EnergyWN, EnergyRyd;
00103
00104 if( ipISO == ipH_LIKE )
00105 {
00106 EnergyRyd = HIonPoten/POW2((double)N_(ipHi));
00107 }
00108 else if( ipISO == ipHE_LIKE )
00109 {
00110 EnergyRyd = helike_energy( nelem, ipHi ) * WAVNRYD;
00111 }
00112 else
00113 {
00114
00115 TotalInsanity();
00116 }
00117
00118
00119 ASSERT(EnergyRyd >= 0.);
00120
00121 iso.xIsoLevNIonRyd[ipISO][nelem][ipHi] = EnergyRyd;
00122
00123
00124 for( ipLo=0; ipLo < ipHi; ipLo++ )
00125 {
00126 EnergyWN = RYD_INF * (iso.xIsoLevNIonRyd[ipISO][nelem][ipLo] -
00127 iso.xIsoLevNIonRyd[ipISO][nelem][ipHi]);
00128
00129
00130
00131 if( EnergyWN==0 && ipISO==ipHE_LIKE )
00132 EnergyWN = 0.0001;
00133
00134 if( EnergyWN < 0. )
00135 EnergyWN = -1.0 * EnergyWN;
00136
00137
00138 Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN = (realnum)EnergyWN;
00139 Transitions[ipISO][nelem][ipHi][ipLo].EnergyErg = (realnum)(EnergyWN*WAVNRYD*EN1RYD);
00140 Transitions[ipISO][nelem][ipHi][ipLo].EnergyK = (realnum)(EnergyWN*WAVNRYD*TE1RYD );
00141
00142 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN >= 0.);
00143 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].EnergyErg >= 0.);
00144 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].EnergyK >= 0.);
00145
00147 if( N_(ipLo)==N_(ipHi) && ipISO==ipH_LIKE )
00148 {
00149 Transitions[ipISO][nelem][ipHi][ipLo].WLAng = 0.;
00150 }
00151 else
00152 {
00153
00154 Transitions[ipISO][nelem][ipHi][ipLo].WLAng =
00155 (realnum)(1.0e8/
00156 Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN/
00157 RefIndex( Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN));
00158 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].WLAng > 0.);
00159 }
00160
00161 }
00162 }
00163
00164
00165 for( ipHi=2; ipHi < iso.nLyman[ipISO]; ipHi++ )
00166 {
00167 FillExtraLymanLine( &ExtraLymanLines[ipISO][nelem][ipHi], ipISO, nelem, ipHi );
00168 }
00169 }
00170 }
00171 }
00172
00173
00174
00175
00176
00177 iso_recomb_malloc();
00178 iso_recomb_setup( ipH_LIKE );
00179 iso_recomb_setup( ipHE_LIKE );
00180 iso_recomb_auxiliary_free();
00181
00182
00183 HeCollidSetup();
00184
00185
00186
00187
00188 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00189 {
00190 if( ipISO == ipH_LIKE )
00191 {
00192
00193 }
00194 else if( ipISO == ipHE_LIKE )
00195 {
00196
00197 HelikeTransProbSetup();
00198 }
00199 else
00200 {
00201 TotalInsanity();
00202 }
00203
00204 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00205 {
00206
00207 if( nelem < 2 || dense.lgElmtOn[nelem] )
00208 {
00209 for( ipLo=ipH1s; ipLo < (iso.numLevels_max[ipISO][nelem] - 1); ipLo++ )
00210 {
00211 for( ipHi=ipLo + 1; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00212 {
00213 realnum Aul;
00214
00215
00216 if( ipISO == ipH_LIKE )
00217 {
00218 Aul = hydro_transprob( nelem, ipHi, ipLo );
00219 }
00220 else if( ipISO == ipHE_LIKE )
00221 {
00222 Aul = helike_transprob(nelem, ipHi, ipLo);
00223 }
00224 else
00225 {
00226 TotalInsanity();
00227 }
00228
00229 if( Aul <= iso.SmallA )
00230 Transitions[ipISO][nelem][ipHi][ipLo].Emis = AddLine2Stack( false );
00231 else
00232 Transitions[ipISO][nelem][ipHi][ipLo].Emis = AddLine2Stack( true );
00233
00234 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul = Aul;
00235
00236 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul > 0.);
00237
00238 if( ipLo == 0 && ipHi == iso.nLyaLevel[ipISO] )
00239 {
00240
00241 Transitions[ipISO][nelem][ipHi][ipLo].Emis->iRedisFun = iso.ipLyaRedist[ipISO];
00242 }
00243 else if( ipLo == 0 )
00244 {
00245
00246
00247 Transitions[ipISO][nelem][ipHi][ipLo].Emis->iRedisFun = iso.ipResoRedist[ipISO];
00248 }
00249 else
00250 {
00251
00252
00253 Transitions[ipISO][nelem][ipHi][ipLo].Emis->iRedisFun = iso.ipSubRedist[ipISO];
00254 }
00255
00256 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA ||
00257 Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN <= 0.)
00258 {
00259 Transitions[ipISO][nelem][ipHi][ipLo].Emis->gf = 0.;
00260 Transitions[ipISO][nelem][ipHi][ipLo].Emis->opacity = 0.;
00261 }
00262 else
00263 {
00264 Transitions[ipISO][nelem][ipHi][ipLo].Emis->gf =
00265 (realnum)(GetGF(Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul,
00266 Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN,
00267 Transitions[ipISO][nelem][ipHi][ipLo].Hi->g));
00268 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].Emis->gf > 0.);
00269
00270
00271 Transitions[ipISO][nelem][ipHi][ipLo].Emis->opacity =
00272 (realnum)(abscf(Transitions[ipISO][nelem][ipHi][ipLo].Emis->gf,
00273 Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN,
00274 Transitions[ipISO][nelem][ipHi][ipLo].Lo->g));
00275 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].Emis->opacity > 0.);
00276 }
00277 }
00278 }
00279 }
00280 }
00281 }
00282
00283
00284
00285
00286 if( iso.lgFSM[ipHE_LIKE] )
00287 {
00288
00289 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00290 {
00291
00292 if( nelem < 2 || dense.lgElmtOn[nelem] )
00293 {
00294 for( ipHi=ipHe2s3S; ipHi<iso.numLevels_max[ipHE_LIKE][nelem]; ipHi++ )
00295 {
00296 for( ipLo=ipHe1s1S; ipLo<ipHi; ipLo++ )
00297 {
00298 DoFSMixing( nelem, ipLo, ipHi );
00299 }
00300 }
00301 }
00302 }
00303 }
00304
00305
00306 Transitions[ipH_LIKE][ipHELIUM][ipH3s][ipH2s].WLAng = 1640.f;
00307 Transitions[ipH_LIKE][ipHELIUM][ipH3s][ipH2p].WLAng = 1640.f;
00308 if( iso.n_HighestResolved_max[ipH_LIKE][ipHELIUM] >=3 )
00309 {
00310 Transitions[ipH_LIKE][ipHELIUM][ipH3p][ipH2s].WLAng = 1640.f;
00311 Transitions[ipH_LIKE][ipHELIUM][ipH3p][ipH2p].WLAng = 1640.f;
00312 Transitions[ipH_LIKE][ipHELIUM][ipH3d][ipH2s].WLAng = 1640.f;
00313 Transitions[ipH_LIKE][ipHELIUM][ipH3d][ipH2p].WLAng = 1640.f;
00314 }
00315
00316
00317
00318
00319 for( ipISO=ipH_LIKE; ipISO<NISO; ipISO++ )
00320 {
00321 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00322 {
00323
00324 if( nelem < 2 || dense.lgElmtOn[nelem] )
00325 {
00326
00327 StatesElem[ipISO][nelem][0].lifetime = -FLT_MAX;
00328
00329 for( ipHi=1; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00330 {
00331 StatesElem[ipISO][nelem][ipHi].lifetime = SMALLFLOAT;
00332
00333 for( ipLo=0; ipLo < ipHi; ipLo++ )
00334 {
00335 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA )
00336 continue;
00337
00338 StatesElem[ipISO][nelem][ipHi].lifetime += Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul;
00339 }
00340
00341
00342 StatesElem[ipISO][nelem][ipHi].lifetime = 1./StatesElem[ipISO][nelem][ipHi].lifetime;
00343
00344 for( ipLo=0; ipLo < ipHi; ipLo++ )
00345 {
00346 if( Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN <= 0. )
00347 continue;
00348
00349 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA )
00350 continue;
00351
00352 Transitions[ipISO][nelem][ipHi][ipLo].Emis->dampXvel = (realnum)(
00353 (1.f/StatesElem[ipISO][nelem][ipHi].lifetime)/
00354 PI4/Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN);
00355
00356 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].Emis->dampXvel> 0.);
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363
00364
00365
00366 for( ipISO=ipH_LIKE; ipISO<NISO; ipISO++ )
00367 {
00368
00369 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00370 {
00371
00372 if( nelem < 2 || dense.lgElmtOn[nelem] )
00373 {
00374
00375 ASSERT( ipISO <= ipHE_LIKE );
00376
00377
00378 Transitions[ipISO][nelem][1+ipISO][0].Emis->TauTot = 0.;
00379
00380
00381
00382 Transitions[ipISO][nelem][1+ipISO][0].Emis->opacity /= 1e4f;
00383
00384
00385 Transitions[ipISO][nelem][1+ipISO][0].WLAng = 0.;
00386 }
00387 }
00388 }
00389
00390
00391
00392 iso_zero();
00393
00394
00395 for( ipISO=ipH_LIKE; ipISO<NISO; ipISO++ )
00396 {
00397 for( nelem = ipISO; nelem < LIMELM; nelem++ )
00398 {
00399
00400 if( nelem == ipISO || dense.lgElmtOn[nelem] )
00401 {
00402
00403 iso_cascade( ipISO, nelem);
00404 }
00405 }
00406 }
00407
00408 iso_satellite();
00409
00410 iso_satellite_update();
00411
00412
00413
00414
00415
00416 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00417 {
00418 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00419 {
00420 if( nelem < 2 || dense.lgElmtOn[nelem] )
00421 {
00422 for( ipLo=ipH1s; ipLo < (iso.numLevels_max[ipISO][nelem] - 1); ipLo++ )
00423 {
00424 for( ipHi= ipLo + 1; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00425 {
00426 long nHi = StatesElem[ipISO][nelem][ipHi].n;
00427 long nLo = StatesElem[ipISO][nelem][ipLo].n;
00428
00429 iso.strkar[ipISO][nelem][ipLo][ipHi] = (realnum)pow((realnum)( nLo * nHi ),(realnum)1.2f);
00430 iso.pestrk[ipISO][nelem][ipLo][ipHi] = 0.;
00431 }
00432 }
00433 }
00434 }
00435 }
00436
00437 return;
00438 }
00439
00440
00441 STATIC void iso_zero(void)
00442 {
00443 long int i,
00444 ipHi,
00445 ipISO,
00446 ipLo,
00447 nelem;
00448
00449 DEBUG_ENTRY( "iso_zero()" );
00450
00451 fixit();
00452
00453
00454 hydro.HLineWidth = 0.;
00455
00456
00457
00458
00459 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00460 {
00461 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00462 {
00463 if( nelem < 2 || dense.lgElmtOn[nelem] )
00464 {
00465 for( ipHi=0; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00466 {
00467 StatesElem[ipISO][nelem][ipHi].Pop = 0.;
00468
00469 iso.PopLTE[ipISO][nelem][ipHi] = 0.;
00470 iso.ColIoniz[ipISO][nelem][ipHi] = 0.;
00471 iso.gamnc[ipISO][nelem][ipHi] = -DBL_MAX;
00472 iso.RecomInducRate[ipISO][nelem][ipHi] = -DBL_MAX;
00473 iso.DepartCoef[ipISO][nelem][ipHi] = -DBL_MAX;
00474 iso.RateLevel2Cont[ipISO][nelem][ipHi] = 0.;
00475 iso.RateCont2Level[ipISO][nelem][ipHi] = 0.;
00476 iso.ConOpacRatio[ipISO][nelem][ipHi] = 1.f;
00477 iso.RadRecomb[ipISO][nelem][ipHi][ipRecRad] = 0.;
00478 iso.RadRecomb[ipISO][nelem][ipHi][ipRecNetEsc] = 1.;
00479 iso.RadRecomb[ipISO][nelem][ipHi][ipRecEsc] = 1.;
00480 iso.DielecRecomb[ipISO][nelem][ipHi] = 0.;
00481 }
00482 }
00483 }
00484 }
00485
00486
00487
00488 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][0] = 1e-5f;
00489 iso.ConOpacRatio[ipH_LIKE][ipHELIUM][0] = 1e-5f;
00490 iso.ConOpacRatio[ipHE_LIKE][ipHELIUM][0] = 1e-5f;
00491
00492
00493
00494 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00495 {
00496 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00497 {
00498
00499 iso.numLevels_local[ipISO][nelem] = iso.numLevels_max[ipISO][nelem];
00500
00501
00502 if( nelem < 2 || dense.lgElmtOn[nelem] )
00503 {
00504 for( ipHi=1; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00505 {
00506 TransitionZero( &SatelliteLines[ipISO][nelem][ipHi] );
00507
00508 for( ipLo=0; ipLo < ipHi; ipLo++ )
00509 {
00510 TransitionZero( &Transitions[ipISO][nelem][ipHi][ipLo] );
00511 }
00512 }
00513
00514 for( ipHi=2; ipHi < iso.nLyman[ipISO]; ipHi++ )
00515 {
00516 TransitionZero( &ExtraLymanLines[ipISO][nelem][ipHi] );
00517 }
00518 }
00519 }
00520 }
00521
00522
00523 for( i=0; i <= nLevel1; i++ )
00524 {
00525 TransitionZero( &TauLines[i] );
00526 }
00527
00528
00529
00530
00531 TransitionZero( &TauDummy );
00532
00533 for( i=0; i < nUTA; i++ )
00534 {
00535
00536 double hsave = UTALines[i].Coll.heat;
00537 TransitionZero( &UTALines[i] );
00538 UTALines[i].Coll.heat = hsave;
00539 }
00540
00541 for( i=0; i < nWindLine; i++ )
00542 {
00543 TransitionZero( &TauLine2[i] );
00544 }
00545
00546 for( i=0; i < nHFLines; i++ )
00547 {
00548 TransitionZero( &HFLines[i] );
00549 }
00550
00551
00552 for( i=0; i <linesAdded2; i++)
00553 {
00554 TransitionZero( atmolEmis[i].tran );
00555 }
00556
00557 for( i=0; i < nCORotate; i++ )
00558 {
00559 TransitionZero( &C12O16Rotate[i] );
00560 TransitionZero( &C13O16Rotate[i] );
00561 }
00562 return;
00563 }
00564
00565 STATIC void iso_allocate(void)
00566 {
00567 long int
00568 ipISO,
00569 nelem,
00570 n,
00571 i,
00572 i1,
00573 j,
00574 ipHi,
00575 ipLo;
00576
00577 DEBUG_ENTRY( "iso_allocate()" );
00578
00579 iso.strkar.reserve( NISO );
00580 iso.ipOpac.reserve( NISO );
00581 iso.RadRecomb.reserve( NISO );
00582 iso.DielecRecombVsTemp.reserve( NISO );
00583 iso.Boltzmann.reserve( NISO );
00584 iso.QuantumNumbers2Index.reserve( NISO );
00585 iso.BranchRatio.reserve( NISO );
00586 iso.CascadeProb.reserve( NISO );
00587 iso.CachedAs.reserve( NISO );
00588
00589
00590 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00591 {
00592 iso.strkar.reserve( ipISO, LIMELM );
00593 iso.ipOpac.reserve( ipISO, LIMELM );
00594 iso.RadRecomb.reserve( ipISO, LIMELM );
00595 iso.DielecRecombVsTemp.reserve( ipISO, LIMELM );
00596 iso.Boltzmann.reserve( ipISO, LIMELM );
00597 iso.QuantumNumbers2Index.reserve( ipISO, LIMELM );
00598 iso.BranchRatio.reserve( ipISO, LIMELM );
00599 iso.CascadeProb.reserve( ipISO, LIMELM );
00600 iso.CachedAs.reserve( ipISO, LIMELM );
00601
00602 for( nelem=ipISO; nelem < LIMELM; ++nelem )
00603 {
00604
00605 if( nelem < 2 || dense.lgElmtOn[nelem] )
00606 {
00607 iso.numLevels_malloc[ipISO][nelem] = iso.numLevels_max[ipISO][nelem];
00608
00609
00610 ASSERT( iso.numLevels_max[ipISO][nelem] > 0 );
00611
00612 iso.nLyman_malloc[ipISO] = iso.nLyman[ipISO];
00613
00614 iso.strkar.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00615 iso.ipOpac.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00616 iso.RadRecomb.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00617 iso.DielecRecombVsTemp.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00618 iso.Boltzmann.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00619
00620 iso.CachedAs.reserve( ipISO, nelem, MAX2(1, iso.nCollapsed_max[ipISO][nelem]) );
00621
00622 for( i = 0; i < iso.nCollapsed_max[ipISO][nelem]; ++i )
00623 {
00624 iso.CachedAs.reserve( ipISO, nelem, i, iso.numLevels_max[ipISO][nelem] - iso.nCollapsed_max[ipISO][nelem] );
00625 for( i1 = 0; i1 < iso.numLevels_max[ipISO][nelem] - iso.nCollapsed_max[ipISO][nelem]; ++i1 )
00626 {
00627
00628 iso.CachedAs.reserve( ipISO, nelem, i, i1, 2 );
00629 }
00630 }
00631
00632 iso.QuantumNumbers2Index.reserve( ipISO, nelem, iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] + 1 );
00633
00634
00635 for( i = 1; i <= (iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]); ++i )
00636 {
00637
00638 iso.QuantumNumbers2Index.reserve( ipISO, nelem, i, i );
00639
00640 for( i1 = 0; i1 < i; ++i1 )
00641 {
00642
00643 ASSERT( NISO == 2 );
00644
00645
00646 iso.QuantumNumbers2Index.reserve( ipISO, nelem, i, i1, 4 );
00647 }
00648 }
00649
00650 for( n=0; n < iso.numLevels_max[ipISO][nelem]; ++n )
00651 {
00652 iso.RadRecomb.reserve( ipISO, nelem, n, 3 );
00653
00654
00655
00656 if( n > 0 )
00657 iso.Boltzmann.reserve( ipISO, nelem, n, n );
00658
00659
00660 iso.DielecRecombVsTemp.reserve( ipISO, nelem, n, NUM_DR_TEMPS );
00661 }
00662
00663
00664 iso.CascadeProb.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00665 iso.BranchRatio.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem]+1 );
00666
00667 for( i = 1; i < iso.numLevels_max[ipISO][nelem]; i++ )
00668 iso.BranchRatio.reserve( ipISO, nelem, i, i+1 );
00669
00670
00671 for( i = 0; i < iso.numLevels_max[ipISO][nelem]; ++i )
00672 {
00673 iso.strkar.reserve( ipISO, nelem, i, iso.numLevels_max[ipISO][nelem] );
00674 iso.CascadeProb.reserve( ipISO, nelem, i, i+1 );
00675 }
00676 }
00677 }
00678 }
00679
00680 iso.strkar.alloc();
00681 iso.pestrk.alloc( iso.strkar.clone() );
00682 iso.ipOpac.alloc();
00683 secondaries.Hx12.alloc( iso.ipOpac.clone() );
00684 iso.ipIsoLevNIonCon.alloc( iso.ipOpac.clone() );
00685 iso.xIsoLevNIonRyd.alloc( iso.ipOpac.clone() );
00686 iso.DielecRecomb.alloc( iso.ipOpac.clone() );
00687 iso.DepartCoef.alloc( iso.ipOpac.clone() );
00688 iso.RateLevel2Cont.alloc( iso.ipOpac.clone() );
00689 iso.RateCont2Level.alloc( iso.ipOpac.clone() );
00690 iso.ConOpacRatio.alloc( iso.ipOpac.clone() );
00691 iso.gamnc.alloc( iso.ipOpac.clone() );
00692 iso.RecomInducRate.alloc( iso.ipOpac.clone() );
00693 iso.RecomInducCool_Coef.alloc( iso.ipOpac.clone() );
00694 iso.PhotoHeat.alloc( iso.ipOpac.clone() );
00695 iso.PopLTE.alloc( iso.ipOpac.clone() );
00696 iso.ColIoniz.alloc( iso.ipOpac.clone() );
00697 iso.RadEffec.alloc( iso.ipOpac.clone() );
00698 iso.RadRecomb.alloc();
00699 iso.Boltzmann.alloc();
00700 iso.DielecRecombVsTemp.alloc();
00701 iso.CachedAs.alloc();
00702 iso.QuantumNumbers2Index.alloc();
00703 iso.BranchRatio.alloc();
00704 iso.CascadeProb.alloc();
00705
00706 iso.bnl_effective.alloc( iso.QuantumNumbers2Index.clone() );
00707
00708 iso.DielecRecombVsTemp.zero();
00709 iso.QuantumNumbers2Index.invalidate();
00710 iso.bnl_effective.invalidate();
00711 iso.BranchRatio.invalidate();
00712 iso.CascadeProb.invalidate();
00713
00714 StatesElem.reserve( NISO );
00715 Transitions.reserve( NISO );
00716 ExtraLymanLines.reserve( NISO );
00717
00718 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00719 {
00720 StatesElem.reserve( ipISO, LIMELM );
00721 Transitions.reserve( ipISO, LIMELM );
00722 ExtraLymanLines.reserve( ipISO, LIMELM );
00723
00724 for( nelem=ipISO; nelem < LIMELM; ++nelem )
00725 {
00726
00727 if( nelem < 2 || dense.lgElmtOn[nelem] )
00728 {
00729 ASSERT( iso.numLevels_max[ipISO][nelem] > 0 );
00730
00731 StatesElem.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00732 Transitions.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00733 ExtraLymanLines.reserve( ipISO, nelem, iso.nLyman[ipISO] );
00734
00735 for( ipHi=1; ipHi<iso.numLevels_max[ipISO][nelem]; ipHi++ )
00736 Transitions.reserve( ipISO, nelem, ipHi, ipHi );
00737 }
00738 }
00739 }
00740
00741 StatesElem.alloc();
00742 SatelliteLines.alloc( StatesElem.clone() );
00743 Transitions.alloc();
00744 ExtraLymanLines.alloc();
00745
00746 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00747 {
00748 for( nelem=ipISO; nelem < LIMELM; ++nelem )
00749 {
00750
00751 if( nelem < 2 || dense.lgElmtOn[nelem] )
00752 {
00753 for( ipLo=0; ipLo<iso.numLevels_max[ipISO][nelem]; ipLo++ )
00754 {
00755
00756
00757 TransitionJunk( &SatelliteLines[ipISO][nelem][ipLo] );
00758 SatelliteLines[ipISO][nelem][ipLo].Hi = AddState2Stack();
00759 SatelliteLines[ipISO][nelem][ipLo].Lo = &StatesElem[ipISO][nelem][ipLo];
00760 SatelliteLines[ipISO][nelem][ipLo].Emis = AddLine2Stack( true );
00761 }
00762
00763 for( ipHi=1; ipHi<iso.numLevels_max[ipISO][nelem]; ipHi++ )
00764 {
00765 for( ipLo=0; ipLo < ipHi; ipLo++ )
00766 {
00767
00768 TransitionJunk( &Transitions[ipISO][nelem][ipHi][ipLo] );
00769 Transitions[ipISO][nelem][ipHi][ipLo].Hi = &StatesElem[ipISO][nelem][ipHi];
00770 Transitions[ipISO][nelem][ipHi][ipLo].Lo = &StatesElem[ipISO][nelem][ipLo];
00771 }
00772 }
00773
00774
00775 for( ipHi=2; ipHi < iso.nLyman[ipISO]; ipHi++ )
00776 {
00777 TransitionJunk( &ExtraLymanLines[ipISO][nelem][ipHi] );
00778 ExtraLymanLines[ipISO][nelem][ipHi].Hi = AddState2Stack();
00779
00780 ExtraLymanLines[ipISO][nelem][ipHi].Lo = &StatesElem[ipISO][nelem][0];
00781 ExtraLymanLines[ipISO][nelem][ipHi].Emis = AddLine2Stack( true );
00782 }
00783 }
00784 }
00785 }
00786
00787
00788 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00789 {
00790 static bool lgNotSetYet = true;
00791
00792 if( iso.lgRandErrGen[ipISO] && lgNotSetYet )
00793 {
00794 iso.Error.reserve( NISO );
00795 iso.SigmaCascadeProb.reserve( NISO );
00796 lgNotSetYet = false;
00797 }
00798
00799 if( iso.lgRandErrGen[ipISO] )
00800 {
00801 ASSERT( !lgNotSetYet );
00802 iso.Error.reserve( ipISO, LIMELM );
00803 iso.SigmaCascadeProb.reserve( ipISO, LIMELM );
00804
00805 for( nelem=ipISO; nelem < LIMELM; ++nelem )
00806 {
00807 if( nelem == ipHELIUM || dense.lgElmtOn[nelem] )
00808 {
00809
00810 iso.Error.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem]+1 );
00811
00812 for( i = 1; i< iso.numLevels_max[ipISO][nelem] + 1; i++ )
00813 {
00814 iso.Error.reserve( ipISO, nelem, i, i+1 );
00815
00816 for( j = 0; j<i+1; j++ )
00817 iso.Error.reserve( ipISO, nelem, i, j, 3 );
00818 }
00819
00820
00821
00822 iso.SigmaCascadeProb.reserve( ipISO, nelem, iso.numLevels_max[ipISO][nelem] );
00823 for( i=0; i < iso.numLevels_max[ipISO][nelem]; i++ )
00824
00825 iso.SigmaCascadeProb.reserve( ipISO, nelem, i, i+1 );
00826 }
00827 }
00828 }
00829 }
00830
00831 iso.Error.alloc();
00832 iso.ErrorFactor.alloc( iso.Error.clone() );
00833 iso.SigmaAtot.alloc( iso.ipOpac.clone() );
00834 iso.SigmaRadEffec.alloc( iso.RadEffec.clone() );
00835 iso.SigmaCascadeProb.alloc();
00836
00837 iso.Error.invalidate();
00838 iso.ErrorFactor.invalidate();
00839
00840 return;
00841 }
00842
00843 STATIC void iso_assign_quantum_numbers(void)
00844 {
00845 long int
00846 ipISO,
00847 ipLo,
00848 level,
00849 nelem,
00850 i,
00851 in,
00852 il,
00853 is,
00854 ij;
00855
00856 DEBUG_ENTRY( "iso_assign_quantum_numbers()" );
00857
00858 ipISO = ipH_LIKE;
00859 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00860 {
00861
00862 if( nelem == ipHELIUM || dense.lgElmtOn[nelem] )
00863 {
00864 i = 0;
00865
00866
00867 is = 2;
00868
00869
00870
00871 for( in = 1L; in <= iso.n_HighestResolved_max[ipISO][nelem]; ++in )
00872 {
00873 for( il = 0L; il < in; ++il )
00874 {
00875 StatesElem[ipISO][nelem][i].n = in;
00876 StatesElem[ipISO][nelem][i].S = is;
00877 StatesElem[ipISO][nelem][i].l = il;
00878 StatesElem[ipISO][nelem][i].j = -1;
00879 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = i;
00880 ++i;
00881 }
00882 }
00883
00884 in = iso.n_HighestResolved_max[ipISO][nelem] + 1;
00885 for( level = i; level< iso.numLevels_max[ipISO][nelem]; ++level)
00886 {
00887 StatesElem[ipISO][nelem][level].n = in;
00888 StatesElem[ipISO][nelem][level].S = -LONG_MAX;
00889 StatesElem[ipISO][nelem][level].l = -LONG_MAX;
00890 StatesElem[ipISO][nelem][level].j = -1;
00891
00892 for( il = 0; il < in; ++il )
00893 {
00894 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = level;
00895 }
00896 ++in;
00897 }
00898 --in;
00899
00900
00901 ASSERT( i <= iso.numLevels_max[ipISO][nelem] );
00902
00903
00904 ASSERT( (in > 0) && (in < (iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] + 1) ) );
00905
00906
00907 for( in = 2L; in <= iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]; ++in )
00908 {
00909 for( il = 0L; il < in; ++il )
00910 {
00911 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].n == in );
00912 if( in <= iso.n_HighestResolved_max[ipISO][nelem] )
00913 {
00914
00915
00916 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].l == il );
00917 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].S == is );
00918 }
00919 }
00920 }
00921 }
00922 }
00923
00924
00925 ipISO = ipHE_LIKE;
00926 for( nelem=ipHELIUM; nelem < LIMELM; nelem++ )
00927 {
00928
00929 if( nelem == ipHELIUM || dense.lgElmtOn[nelem] )
00930 {
00931 i = 0;
00932
00933
00934
00935 for( in = 1L; in <= iso.n_HighestResolved_max[ipISO][nelem]; ++in )
00936 {
00937 for( il = 0L; il < in; ++il )
00938 {
00939 for( is = 3L; is >= 1L; is -= 2 )
00940 {
00941
00942
00943
00944 if( (il == 1L) && (is == 1L) )
00945 continue;
00946
00947 if( (in == 1L) && (is == 3L) )
00948 continue;
00949
00950
00951 if( is == 1 )
00952 {
00953 StatesElem[ipISO][nelem][i].n = in;
00954 StatesElem[ipISO][nelem][i].S = is;
00955 StatesElem[ipISO][nelem][i].l = il;
00956
00957 StatesElem[ipISO][nelem][i].j = il;
00958 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = i;
00959 ++i;
00960 }
00961
00962 else if( (in == 2) && (il == 1) && (is == 3) )
00963 {
00964 ij = 0;
00965 do
00966 {
00967 StatesElem[ipISO][nelem][i].n = in;
00968 StatesElem[ipISO][nelem][i].S = is;
00969 StatesElem[ipISO][nelem][i].l = il;
00970 StatesElem[ipISO][nelem][i].j = ij;
00971 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = i;
00972 ++i;
00973 ++ij;
00974
00975 } while ( ij < 3 );
00976 }
00977 else
00978 {
00979 StatesElem[ipISO][nelem][i].n = in;
00980 StatesElem[ipISO][nelem][i].S = is;
00981 StatesElem[ipISO][nelem][i].l = il;
00982 StatesElem[ipISO][nelem][i].j = -1L;
00983 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = i;
00984 ++i;
00985 }
00986 }
00987 }
00988
00989 if( in > 1L )
00990 {
00991 StatesElem[ipISO][nelem][i].n = in;
00992 StatesElem[ipISO][nelem][i].S = 1L;
00993 StatesElem[ipISO][nelem][i].l = 1L;
00994 StatesElem[ipISO][nelem][i].j = 1L;
00995 iso.QuantumNumbers2Index[ipISO][nelem][in][1][1] = i;
00996 ++i;
00997 }
00998 }
00999
01000 in = iso.n_HighestResolved_max[ipISO][nelem] + 1;
01001 for( level = i; level< iso.numLevels_max[ipISO][nelem]; ++level)
01002 {
01003 StatesElem[ipISO][nelem][level].n = in;
01004 StatesElem[ipISO][nelem][level].S = -LONG_MAX;
01005 StatesElem[ipISO][nelem][level].l = -LONG_MAX;
01006 StatesElem[ipISO][nelem][level].j = -1;
01007
01008 for( il = 0; il < in; ++il )
01009 {
01010 for( is = 1; is <= 3; is += 2 )
01011 {
01012 iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] = level;
01013 }
01014 }
01015 ++in;
01016 }
01017 --in;
01018
01019
01020 ASSERT( i <= iso.numLevels_max[ipISO][nelem] );
01021
01022
01023 ASSERT( (in > 0) && (in < (iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] + 1) ) );
01024
01025
01026 for( in = 2L; in <= iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]; ++in )
01027 {
01028 for( il = 0L; il < in; ++il )
01029 {
01030 for( is = 3L; is >= 1; is -= 2 )
01031 {
01032
01033 if( (in == 1L) && (is == 3L) )
01034 continue;
01035
01036 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].n == in );
01037 if( in <= iso.n_HighestResolved_max[ipISO][nelem] )
01038 {
01039
01040
01041 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].l == il );
01042 ASSERT( StatesElem[ipISO][nelem][ iso.QuantumNumbers2Index[ipISO][nelem][in][il][is] ].S == is );
01043 }
01044 }
01045 }
01046 }
01047 }
01048 }
01049
01050 for( ipISO=ipH_LIKE; ipISO<NISO; ipISO++ )
01051 {
01052 for( nelem=ipISO; nelem < LIMELM; nelem++ )
01053 {
01054
01055 if( nelem < 2 || dense.lgElmtOn[nelem] )
01056 {
01057 for( ipLo=ipH1s; ipLo < iso.numLevels_max[ipISO][nelem]; ipLo++ )
01058 {
01059 StatesElem[ipISO][nelem][ipLo].nelem = (int)(nelem+1);
01060 StatesElem[ipISO][nelem][ipLo].IonStg = (int)(nelem+1-ipISO);
01061
01062 if( StatesElem[ipISO][nelem][ipLo].j >= 0 )
01063 {
01064 StatesElem[ipISO][nelem][ipLo].g = 2.f*StatesElem[ipISO][nelem][ipLo].j+1.f;
01065 }
01066 else if( StatesElem[ipISO][nelem][ipLo].l >= 0 )
01067 {
01068 StatesElem[ipISO][nelem][ipLo].g = (2.f*StatesElem[ipISO][nelem][ipLo].l+1.f) *
01069 StatesElem[ipISO][nelem][ipLo].S;
01070 }
01071 else
01072 {
01073 if( ipISO == ipH_LIKE )
01074 StatesElem[ipISO][nelem][ipLo].g = 2.f*(realnum)POW2( StatesElem[ipISO][nelem][ipLo].n );
01075 else if( ipISO == ipHE_LIKE )
01076 StatesElem[ipISO][nelem][ipLo].g = 4.f*(realnum)POW2( StatesElem[ipISO][nelem][ipLo].n );
01077 else
01078 {
01079
01080 TotalInsanity();
01081 }
01082 }
01083 char chConfiguration[11] = " ";
01084 long nCharactersWritten = 0;
01085
01086
01087 if( StatesElem[ipISO][nelem][ipLo].n > iso.n_HighestResolved_max[ipISO][nelem] )
01088 {
01089 nCharactersWritten = sprintf( chConfiguration, "n=%3li",
01090 StatesElem[ipISO][nelem][ipLo].n );
01091 }
01092 else if( StatesElem[ipISO][nelem][ipLo].j > 0 )
01093 {
01094 nCharactersWritten = sprintf( chConfiguration, "%3li^%2li%c_%li",
01095 StatesElem[ipISO][nelem][ipLo].n,
01096 StatesElem[ipISO][nelem][ipLo].S,
01097 chL[ MIN2( 20, StatesElem[ipISO][nelem][ipLo].l ) ],
01098 StatesElem[ipISO][nelem][ipLo].j );
01099 }
01100 else
01101 {
01102 nCharactersWritten = sprintf( chConfiguration, "%3li^%2li%c",
01103 StatesElem[ipISO][nelem][ipLo].n,
01104 StatesElem[ipISO][nelem][ipLo].S,
01105 chL[ MIN2( 20, StatesElem[ipISO][nelem][ipLo].l) ] );
01106 }
01107
01108 ASSERT( nCharactersWritten <= 10 );
01109 chConfiguration[10] = '\0';
01110
01111 strncpy( StatesElem[ipISO][nelem][ipLo].chConfig, chConfiguration, 10 );
01112 }
01113 }
01114 }
01115 }
01116 return;
01117 }
01118
01119 #if defined(__ICC) && defined(__i386)
01120 #pragma optimization_level 1
01121 #endif
01122 STATIC void FillExtraLymanLine( transition *t, long ipISO, long nelem, long nHi )
01123 {
01124 double Enerwn, Aul;
01125
01126 DEBUG_ENTRY( "FillExtraLymanLine()" );
01127
01128
01129 t->Hi->nelem = (int)(nelem+1);
01130 t->Hi->IonStg = (int)(nelem+1-ipISO);
01131
01132
01133 t->Hi->g = StatesElem[ipISO][nelem][iso.nLyaLevel[ipISO]].g;
01134
01135
01136 Enerwn = iso.xIsoLevNIonRyd[ipISO][nelem][0] * RYD_INF * ( 1. - 1./POW2((double)nHi) );
01137
01138
01139 t->EnergyWN = (realnum)(Enerwn);
01140 t->EnergyErg = (realnum)(Enerwn * WAVNRYD * EN1RYD);
01141 t->EnergyK = (realnum)(Enerwn * WAVNRYD * TE1RYD);
01142 t->WLAng = (realnum)(1.0e8/ Enerwn/ RefIndex(Enerwn));
01143
01144 if( ipISO == ipH_LIKE )
01145 {
01146 Aul = H_Einstein_A( nHi, 1, 1, 0, nelem+1 );
01147 }
01148 else
01149 {
01150 if( nelem == ipHELIUM )
01151 {
01152
01153 Aul = (1.508e10) / pow((double)nHi,2.975);
01154 }
01155 else
01156 {
01157
01158
01159
01160
01161 Aul = 1.375E10 * pow((double)nelem, 3.9) / pow((double)nHi,3.1);
01162 }
01163 }
01164
01165 t->Emis->Aul = (realnum)Aul;
01166
01167 t->Hi->lifetime = iso_state_lifetime( ipISO, nelem, nHi, 1 );
01168
01169 t->Emis->dampXvel = (realnum)( 1.f / t->Hi->lifetime / PI4 / t->EnergyWN );
01170
01171 t->Emis->iRedisFun = iso.ipResoRedist[ipISO];
01172
01173 t->Emis->gf = (realnum)(GetGF(t->Emis->Aul, t->EnergyWN, t->Hi->g));
01174
01175
01176 t->Emis->opacity = (realnum)(abscf(t->Emis->gf, t->EnergyWN, t->Lo->g));
01177
01178
01179 t->ipCont = INT_MIN;
01180 t->Emis->ipFine = INT_MIN;
01181
01182 {
01183
01184
01185
01186 enum {DEBUG_LOC=false};
01187 if( DEBUG_LOC )
01188 {
01189 fprintf(ioQQQ,"%li\t%li\t%.2e\t%.2e\n",
01190 nelem+1,
01191 nHi,
01192 t->Emis->Aul ,
01193 t->Emis->opacity
01194 );
01195 }
01196 }
01197 return;
01198 }
01199
01200
01201 STATIC double iso_state_lifetime( long ipISO, long nelem, long n, long l )
01202 {
01203
01204
01205 double tau, t0, eps2;
01206
01207 double m = ELECTRON_MASS;
01208
01209 double M = (double)dense.AtomicWeight[nelem] * ATOMIC_MASS_UNIT;
01210 double mu = (m*M)/(M+m);
01211 long z = 1;
01212 long Z = nelem + 1 - ipISO;
01213
01214 DEBUG_ENTRY( "iso_state_lifetime()" );
01215
01216 eps2 = 1. - ( l*l + l + 8./47. - (l+1.)/69./n ) / POW2( (double)n );
01217
01218 t0 = 3. * H_BAR * pow( (double)n, 5.) /
01219 ( 2. * POW4( (double)( z * Z ) ) * pow( FINE_STRUCTURE, 5. ) * mu * POW2( SPEEDLIGHT ) ) *
01220 POW2( (m + M)/(Z*m + z*M) );
01221
01222 tau = t0 * ( 1. - eps2 ) /
01223 ( 1. + 19./88.*( (1./eps2 - 1.) * log( 1. - eps2 ) + 1. -
01224 0.5 * eps2 - 0.025 * eps2 * eps2 ) );
01225
01226 if( ipISO == ipHE_LIKE )
01227 {
01228
01229 tau /= 3.;
01230
01231 tau *= 1.1722 * pow( (double)nelem, 0.1 );
01232 }
01233
01234
01235 ASSERT( ipISO <= ipHE_LIKE );
01236 ASSERT( tau > 0. );
01237
01238 return tau;
01239 }
01240
01241
01242 void iso_cascade( long ipISO, long nelem )
01243 {
01244
01245
01246 double *SumAPerN;
01247
01248 long int i, j, ipLo, ipHi;
01249
01250 DEBUG_ENTRY( "iso_cascade()" );
01251
01252 SumAPerN = ((double*)MALLOC( (size_t)(iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] + 1 )*sizeof(double )));
01253 memset( SumAPerN, 0, (iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] + 1 )*sizeof(double ) );
01254
01255
01256 iso.CascadeProb[ipISO][nelem][0][0] = 1.;
01257 if( iso.lgRandErrGen[ipISO] )
01258 {
01259 iso.SigmaAtot[ipISO][nelem][0] = 0.;
01260 iso.SigmaCascadeProb[ipISO][nelem][0][0] = 0.;
01261 }
01262
01263
01264
01265
01266 for( ipHi=1; ipHi<iso.numLevels_max[ipISO][nelem]; ipHi++ )
01267 {
01268 double SumAs = 0.;
01269
01275
01276 iso.CascadeProb[ipISO][nelem][ipHi][ipHi] = 1.;
01277 iso.CascadeProb[ipISO][nelem][ipHi][0] = 0.;
01278 iso.BranchRatio[ipISO][nelem][ipHi][0] = 0.;
01279
01280 if( iso.lgRandErrGen[ipISO] )
01281 {
01282 iso.SigmaAtot[ipISO][nelem][ipHi] = 0.;
01283 iso.SigmaCascadeProb[ipISO][nelem][ipHi][ipHi] = 0.;
01284 }
01285
01286 long ipLoStart = 0;
01287 if( opac.lgCaseB && L_(ipHi)==1 && (ipISO==ipH_LIKE || S_(ipHi)==1) )
01288 ipLoStart = 1;
01289
01290 for( ipLo=ipLoStart; ipLo<ipHi; ipLo++ )
01291 {
01292 SumAs += Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul;
01293 }
01294
01295 for( ipLo=ipLoStart; ipLo<ipHi; ipLo++ )
01296 {
01297 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA )
01298 {
01299 iso.CascadeProb[ipISO][nelem][ipHi][ipLo] = 0.;
01300 iso.BranchRatio[ipISO][nelem][ipHi][ipLo] = 0.;
01301 continue;
01302 }
01303
01304 iso.CascadeProb[ipISO][nelem][ipHi][ipLo] = 0.;
01305 iso.BranchRatio[ipISO][nelem][ipHi][ipLo] =
01306 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul / SumAs;
01307
01308 ASSERT( iso.BranchRatio[ipISO][nelem][ipHi][ipLo] <= 1.0000001 );
01309
01310 SumAPerN[N_(ipHi)] += Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul;
01311
01312
01313
01314
01315 ASSERT( Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN > 0. ||
01316 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA );
01317
01318 if( iso.lgRandErrGen[ipISO] )
01319 {
01320 ASSERT( iso.Error[ipISO][nelem][ipHi][ipLo][IPRAD] >= 0. );
01321
01322 iso.SigmaAtot[ipISO][nelem][ipHi] +=
01323 pow( iso.Error[ipISO][nelem][ipHi][ipLo][IPRAD] *
01324 (double)Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul, 2. );
01325 }
01326 }
01327
01328 if( iso.lgRandErrGen[ipISO] )
01329 {
01330
01331 iso.SigmaAtot[ipISO][nelem][ipHi] = sqrt( iso.SigmaAtot[ipISO][nelem][ipHi] );
01332 }
01333
01334
01335 for( ipLo=0; ipLo<ipHi; ipLo++ )
01336 {
01337 double SigmaA, SigmaCul = 0.;
01338
01339 for( i=ipLo; i<ipHi; i++ )
01340 {
01341 iso.CascadeProb[ipISO][nelem][ipHi][ipLo] += iso.BranchRatio[ipISO][nelem][ipHi][i] * iso.CascadeProb[ipISO][nelem][i][ipLo];
01342 if( iso.lgRandErrGen[ipISO] )
01343 {
01344 if( Transitions[ipISO][nelem][ipHi][i].Emis->Aul > iso.SmallA )
01345 {
01346
01347 SigmaA = iso.Error[ipISO][nelem][ipHi][i][IPRAD] *
01348 Transitions[ipISO][nelem][ipHi][i].Emis->Aul;
01349 SigmaCul +=
01350 pow(SigmaA*iso.CascadeProb[ipISO][nelem][i][ipLo]*StatesElem[ipISO][nelem][ipHi].lifetime, 2.) +
01351 pow(iso.SigmaAtot[ipISO][nelem][ipHi]*iso.BranchRatio[ipISO][nelem][ipHi][i]*iso.CascadeProb[ipISO][nelem][i][ipLo]*StatesElem[ipISO][nelem][ipHi].lifetime, 2.) +
01352 pow(iso.SigmaCascadeProb[ipISO][nelem][i][ipLo]*iso.BranchRatio[ipISO][nelem][ipHi][i], 2.);
01353 }
01354 }
01355 }
01356 if( iso.lgRandErrGen[ipISO] )
01357 {
01358 SigmaCul = sqrt(SigmaCul);
01359 iso.SigmaCascadeProb[ipISO][nelem][ipHi][ipLo] = SigmaCul;
01360 }
01361 }
01362 }
01363
01364
01365
01366
01367 {
01368 enum {DEBUG_LOC=false};
01369
01370 if( DEBUG_LOC && (nelem == ipHELIUM) && (ipISO==ipHE_LIKE) )
01371 {
01372
01373 long int hi_l,hi_s;
01374 double Bm;
01375
01376
01377
01378 hi_s = -100000;
01379 hi_l = -100000;
01380 ipLo = -100000;
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390 ASSERT( hi_l != StatesElem[ipISO][nelem][ipLo].l );
01391
01392 fprintf(ioQQQ,"Bm(n,%ld,%ld;%ld)\n",hi_l,hi_s,ipLo);
01393 fprintf(ioQQQ,"m\t2\t\t3\t\t4\t\t5\t\t6\n");
01394
01395 for( ipHi=ipHe2p3P2; ipHi<iso.numLevels_max[ipISO][nelem]-iso.nCollapsed_max[ipISO][nelem]; ipHi++ )
01396 {
01397
01398 if( (StatesElem[ipISO][nelem][ipHi].l == 1) && (StatesElem[ipISO][nelem][ipHi].S == 3) )
01399 {
01400 fprintf(ioQQQ,"\n%ld\t",StatesElem[ipISO][nelem][ipHi].n);
01401 j = 0;
01402 Bm = 0;
01403 for( i = ipLo; i<=ipHi; i++)
01404 {
01405 if( (StatesElem[ipISO][nelem][i].l == hi_l) && (StatesElem[ipISO][nelem][i].S == hi_s) )
01406 {
01407 if( (ipLo == ipHe2p3P0) && (i > ipHe2p3P2) )
01408 {
01409 Bm += iso.CascadeProb[ipISO][nelem][ipHi][i] * ( iso.BranchRatio[ipISO][nelem][i][ipHe2p3P0] +
01410 iso.BranchRatio[ipISO][nelem][i][ipHe2p3P1] + iso.BranchRatio[ipISO][nelem][i][ipHe2p3P2] );
01411 }
01412 else
01413 Bm += iso.CascadeProb[ipISO][nelem][ipHi][i] * iso.BranchRatio[ipISO][nelem][i][ipLo];
01414
01415 if( (i == ipHe2p3P0) || (i == ipHe2p3P1) || (i == ipHe2p3P2) )
01416 {
01417 j++;
01418 if(j == 3)
01419 {
01420 fprintf(ioQQQ,"%2.4e\t",Bm);
01421 Bm = 0;
01422 }
01423 }
01424 else
01425 {
01426 fprintf(ioQQQ,"%2.4e\t",Bm);
01427 Bm = 0;
01428 }
01429 }
01430 }
01431 }
01432 }
01433 fprintf(ioQQQ,"\n\n");
01434 }
01435 }
01436
01437
01438
01439
01440
01441 for( i=2; i < iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem] - 1; ++i)
01442 {
01443
01444 ASSERT( (SumAPerN[i] > SumAPerN[i+1]) || opac.lgCaseB || (i==iso.n_HighestResolved_max[ipISO][nelem]+1) );
01445 }
01446
01447 {
01448 enum {DEBUG_LOC=false};
01449 if( DEBUG_LOC )
01450 {
01451 for( i = 2; i<= (iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]); ++i)
01452 {
01453 fprintf(ioQQQ,"n %ld\t lifetime %.4e\n", i, 1./SumAPerN[i]);
01454 }
01455 }
01456 }
01457
01458 free( SumAPerN );
01459
01460 return;
01461 }
01462
01464
01465
01466 STATIC void iso_satellite( void )
01467 {
01468 long i, ipISO, nelem;
01469
01470 DEBUG_ENTRY( "iso_satellite()" );
01471
01472 for( ipISO = ipHE_LIKE; ipISO < NISO; ipISO++ )
01473 {
01474 for( nelem = ipISO; nelem < LIMELM; nelem++ )
01475 {
01476 if( !iso.lgDielRecom[ipISO] )
01477 continue;
01478
01479
01480 if( nelem == ipISO || dense.lgElmtOn[nelem] )
01481 {
01482 for( i=0; i<iso.numLevels_max[ipISO][nelem]; i++ )
01483 {
01484 char chLab[5]=" ";
01485
01486 TransitionZero( &SatelliteLines[ipISO][nelem][i] );
01487
01488
01489
01490
01491
01492 SatelliteLines[ipISO][nelem][i].WLAng = (realnum)(RYDLAM/
01493 ((iso.xIsoLevNIonRyd[ipISO-1][nelem][0] - iso.xIsoLevNIonRyd[ipISO-1][nelem][1]) -
01494 (iso.xIsoLevNIonRyd[ipISO][nelem][1]- iso.xIsoLevNIonRyd[ipISO][nelem][i])) );
01495
01496 SatelliteLines[ipISO][nelem][i].EnergyWN = 1.e8f /
01497 SatelliteLines[ipISO][nelem][i].WLAng;
01498
01499 SatelliteLines[ipISO][nelem][i].EnergyErg = (realnum)ERG1CM *
01500 SatelliteLines[ipISO][nelem][i].EnergyWN;
01501
01502 SatelliteLines[ipISO][nelem][i].EnergyK = (realnum)T1CM *
01503 SatelliteLines[ipISO][nelem][i].EnergyWN;
01504
01505
01506 sprintf( chLab, "%2s%2ld",elementnames.chElementSym[nelem], nelem+1-ipISO );
01507
01508 SatelliteLines[ipISO][nelem][i].Emis->iRedisFun = ipCRDW;
01509
01510 SatelliteLines[ipISO][nelem][i].Hi->nelem = nelem + 1;
01511 SatelliteLines[ipISO][nelem][i].Hi->IonStg = nelem + 1 - ipISO;
01512 fixit();
01513 SatelliteLines[ipISO][nelem][i].Hi->g = 2.f;
01514 SatelliteLines[ipISO][nelem][i].Lo->g = StatesElem[ipISO][nelem][i].g;
01515 SatelliteLines[ipISO][nelem][i].Emis->PopOpc =
01516 SatelliteLines[ipISO][nelem][i].Lo->Pop;
01517 }
01518 }
01519 }
01520 }
01521
01522 return;
01523 }
01524
01525 void iso_satellite_update( void )
01526 {
01527 double ConBoltz, LTE_pop=SMALLFLOAT+FLT_EPSILON, factor1, ConvLTEPOP;
01528 long i, ipISO, nelem;
01529 double dr_rate;
01530
01531 DEBUG_ENTRY( "iso_satellite()" );
01532
01533 for( ipISO = ipHE_LIKE; ipISO < NISO; ipISO++ )
01534 {
01535 for( nelem = ipISO; nelem < LIMELM; nelem++ )
01536 {
01537 if( !iso.lgDielRecom[ipISO] )
01538 continue;
01539
01540
01541 if( nelem == ipISO || dense.lgElmtOn[nelem] )
01542 {
01543 for( i=0; i<iso.numLevels_max[ipISO][nelem]; i++ )
01544 {
01545 dr_rate = MAX2( iso.SmallA, iso.DielecRecomb[ipISO][nelem][i] );
01546
01547 SatelliteLines[ipISO][nelem][i].Emis->phots =
01548 dr_rate * dense.eden * dense.xIonDense[nelem][nelem+1-ipISO];
01549
01550 SatelliteLines[ipISO][nelem][i].Emis->xIntensity =
01551 SatelliteLines[ipISO][nelem][i].Emis->phots *
01552 ERG1CM * SatelliteLines[ipISO][nelem][i].EnergyWN;
01553
01554
01555
01556
01557 factor1 = HION_LTE_POP*dense.AtomicWeight[nelem]/
01558 (dense.AtomicWeight[nelem]+ELECTRON_MASS/ATOMIC_MASS_UNIT);
01559
01560
01561 ConvLTEPOP = pow(factor1,1.5)/(2.*iso.stat_ion[ipISO])/phycon.te32;
01562
01563
01564
01565
01566 ConBoltz = dsexp(iso.xIsoLevNIonRyd[ipISO-1][nelem][1]/phycon.te_ryd);
01567
01568 if( ConBoltz >= SMALLDOUBLE )
01569 {
01570
01571
01572
01573
01574 LTE_pop = SatelliteLines[ipISO][nelem][i].Hi->g * ConBoltz * ConvLTEPOP;
01575 }
01576
01577 LTE_pop = max( LTE_pop, 1e-30f );
01578
01579
01580 SatelliteLines[ipISO][nelem][i].Emis->Aul = (realnum)(dr_rate/LTE_pop);
01581 SatelliteLines[ipISO][nelem][i].Emis->Aul =
01582 max( iso.SmallA, SatelliteLines[ipISO][nelem][i].Emis->Aul );
01583
01584 SatelliteLines[ipISO][nelem][i].Emis->gf = (realnum)GetGF(
01585 SatelliteLines[ipISO][nelem][i].Emis->Aul,
01586 SatelliteLines[ipISO][nelem][i].EnergyWN,
01587 SatelliteLines[ipISO][nelem][i].Hi->g);
01588
01589 SatelliteLines[ipISO][nelem][i].Emis->gf =
01590 max( 1e-20f, SatelliteLines[ipISO][nelem][i].Emis->gf );
01591
01592 SatelliteLines[ipISO][nelem][i].Emis->PopOpc =
01593 SatelliteLines[ipISO][nelem][i].Lo->Pop -
01594 LTE_pop * SatelliteLines[ipISO][nelem][i].Lo->g/SatelliteLines[ipISO][nelem][i].Hi->g;
01595
01596 SatelliteLines[ipISO][nelem][i].Emis->opacity =
01597 (realnum)(abscf(SatelliteLines[ipISO][nelem][i].Emis->gf,
01598 SatelliteLines[ipISO][nelem][i].EnergyWN,
01599 SatelliteLines[ipISO][nelem][i].Lo->g));
01600
01601
01602 double lifetime = 1e-10;
01603
01604 SatelliteLines[ipISO][nelem][i].Emis->dampXvel = (realnum)(
01605 (1.f/lifetime)/PI4/SatelliteLines[ipISO][nelem][i].EnergyWN);
01606 }
01607 }
01608 }
01609 }
01610
01611 return;
01612 }
01613
01614 long iso_get_total_num_levels( long ipISO, long nmaxResolved, long numCollapsed )
01615 {
01616 DEBUG_ENTRY( "iso_get_total_num_levels()" );
01617
01618 long tot_num_levels;
01619
01620
01621
01622
01623 if( ipISO == ipH_LIKE )
01624 {
01625 tot_num_levels = (long)( nmaxResolved * 0.5 *( nmaxResolved + 1 ) ) + numCollapsed;
01626 }
01627 else if( ipISO == ipHE_LIKE )
01628 {
01629 tot_num_levels = nmaxResolved*nmaxResolved + nmaxResolved + 1 + numCollapsed;
01630 }
01631 else
01632 TotalInsanity();
01633
01634 return tot_num_levels;
01635 }
01636
01637 void iso_update_num_levels( long ipISO, long nelem )
01638 {
01639 DEBUG_ENTRY( "iso_update_num_levels()" );
01640
01641
01642 ASSERT( iso.n_HighestResolved_max[ipISO][nelem] >= 3 );
01643
01644 iso.numLevels_max[ipISO][nelem] =
01645 iso_get_total_num_levels( ipISO, iso.n_HighestResolved_max[ipISO][nelem], iso.nCollapsed_max[ipISO][nelem] );
01646
01647 if( iso.numLevels_max[ipISO][nelem] > iso.numLevels_malloc[ipISO][nelem] )
01648 {
01649 fprintf( ioQQQ, "The number of levels for ipISO %li, nelem %li, has been increased since the initial coreload.\n",
01650 ipISO, nelem );
01651 fprintf( ioQQQ, "This cannot be done.\n" );
01652 cdEXIT(EXIT_FAILURE);
01653 }
01654
01655
01656 iso.numLevels_local[ipISO][nelem] = iso.numLevels_max[ipISO][nelem];
01657 iso.nCollapsed_local[ipISO][nelem] = iso.nCollapsed_max[ipISO][nelem];
01658 iso.n_HighestResolved_local[ipISO][nelem] = iso.n_HighestResolved_max[ipISO][nelem];
01659
01660
01661 iso.numPrintLevels[ipISO][nelem] = iso.numLevels_max[ipISO][nelem] - iso.nCollapsed_max[ipISO][nelem];
01662
01663
01664
01665
01666 max_num_levels = MAX2( max_num_levels, iso.numLevels_max[ipISO][nelem]);
01667
01668 return;
01669 }
01670
01671 void iso_collapsed_bnl_set( long ipISO, long nelem )
01672 {
01673
01674 DEBUG_ENTRY( "iso_collapsed_bnl_set()" );
01675
01676 double bnl_array[4][3][4][10] = {
01677 {
01678
01679 {
01680 {6.13E-01, 2.56E-01, 1.51E-01, 2.74E-01, 3.98E-01, 4.98E-01, 5.71E-01, 6.33E-01, 7.28E-01, 9.59E-01},
01681 {1.31E+00, 5.17E-01, 2.76E-01, 4.47E-01, 5.87E-01, 6.82E-01, 7.44E-01, 8.05E-01, 9.30E-01, 1.27E+00},
01682 {1.94E+00, 7.32E-01, 3.63E-01, 5.48E-01, 6.83E-01, 7.66E-01, 8.19E-01, 8.80E-01, 1.02E+00, 1.43E+00},
01683 {2.53E+00, 9.15E-01, 4.28E-01, 6.16E-01, 7.42E-01, 8.13E-01, 8.60E-01, 9.22E-01, 1.08E+00, 1.56E+00}
01684 },
01685 {
01686 {5.63E-01, 2.65E-01, 1.55E-01, 2.76E-01, 3.91E-01, 4.75E-01, 5.24E-01, 5.45E-01, 5.51E-01, 5.53E-01},
01687 {1.21E+00, 5.30E-01, 2.81E-01, 4.48E-01, 5.80E-01, 6.62E-01, 7.05E-01, 7.24E-01, 7.36E-01, 7.46E-01},
01688 {1.81E+00, 7.46E-01, 3.68E-01, 5.49E-01, 6.78E-01, 7.51E-01, 7.88E-01, 8.09E-01, 8.26E-01, 8.43E-01},
01689 {2.38E+00, 9.27E-01, 4.33E-01, 6.17E-01, 7.38E-01, 8.05E-01, 8.40E-01, 8.65E-01, 8.92E-01, 9.22E-01}
01690 },
01691 {
01692 {2.97E-01, 2.76E-01, 2.41E-01, 3.04E-01, 3.66E-01, 4.10E-01, 4.35E-01, 4.48E-01, 4.52E-01, 4.53E-01},
01693 {5.63E-01, 5.04E-01, 3.92E-01, 4.67E-01, 5.39E-01, 5.85E-01, 6.10E-01, 6.20E-01, 6.23E-01, 6.23E-01},
01694 {7.93E-01, 6.90E-01, 4.94E-01, 5.65E-01, 6.36E-01, 6.79E-01, 7.00E-01, 7.09E-01, 7.11E-01, 7.11E-01},
01695 {1.04E+00, 8.66E-01, 5.62E-01, 6.31E-01, 7.01E-01, 7.43E-01, 7.63E-01, 7.71E-01, 7.73E-01, 7.73E-01}
01696 }
01697 },
01698 {
01699
01700 {
01701 {6.70E-02, 2.93E-02, 1.94E-02, 4.20E-02, 7.40E-02, 1.12E-01, 1.51E-01, 1.86E-01, 2.26E-01, 3.84E-01},
01702 {2.39E-01, 1.03E-01, 6.52E-02, 1.31E-01, 2.11E-01, 2.91E-01, 3.61E-01, 4.17E-01, 4.85E-01, 8.00E-01},
01703 {4.26E-01, 1.80E-01, 1.10E-01, 2.09E-01, 3.18E-01, 4.15E-01, 4.93E-01, 5.54E-01, 6.34E-01, 1.04E+00},
01704 {6.11E-01, 2.55E-01, 1.51E-01, 2.74E-01, 3.99E-01, 5.02E-01, 5.80E-01, 6.41E-01, 7.30E-01, 1.21E+00}
01705 },
01706 {
01707 {6.79E-02, 3.00E-02, 2.00E-02, 4.30E-02, 7.48E-02, 1.11E-01, 1.44E-01, 1.70E-01, 1.87E-01, 1.96E-01},
01708 {2.40E-01, 1.04E-01, 6.62E-02, 1.32E-01, 2.11E-01, 2.87E-01, 3.51E-01, 3.98E-01, 4.32E-01, 4.58E-01},
01709 {4.26E-01, 1.81E-01, 1.11E-01, 2.10E-01, 3.17E-01, 4.12E-01, 4.89E-01, 5.53E-01, 6.14E-01, 6.84E-01},
01710 {6.12E-01, 2.55E-01, 1.51E-01, 2.73E-01, 3.97E-01, 4.98E-01, 5.77E-01, 6.51E-01, 7.82E-01, 1.18E+00}
01711 },
01712 {
01713 {4.98E-02, 3.47E-02, 2.31E-02, 4.54E-02, 7.14E-02, 9.37E-02, 1.08E-01, 1.13E-01, 1.13E-01, 1.11E-01},
01714 {1.75E-01, 1.16E-01, 7.36E-02, 1.36E-01, 2.01E-01, 2.50E-01, 2.76E-01, 2.84E-01, 2.81E-01, 2.77E-01},
01715 {3.38E-01, 1.97E-01, 1.18E-01, 2.13E-01, 3.06E-01, 3.72E-01, 4.06E-01, 4.15E-01, 4.10E-01, 4.04E-01},
01716 {6.01E-01, 2.60E-01, 1.53E-01, 2.76E-01, 3.95E-01, 4.87E-01, 5.45E-01, 5.76E-01, 5.93E-01, 6.05E-01}
01717 }
01718 },
01719 {
01720
01721 {
01722 {1.77E-01, 3.59E-01, 1.54E-01, 2.75E-01, 3.98E-01, 4.94E-01, 5.51E-01, 5.68E-01, 5.46E-01, 4.97E-01},
01723 {4.09E-01, 7.23E-01, 2.83E-01, 4.48E-01, 5.89E-01, 6.78E-01, 7.22E-01, 7.30E-01, 7.07E-01, 6.65E-01},
01724 {6.40E-01, 1.02E+00, 3.74E-01, 5.49E-01, 6.85E-01, 7.63E-01, 7.98E-01, 8.03E-01, 7.84E-01, 7.53E-01},
01725 {8.70E-01, 1.28E+00, 4.42E-01, 6.17E-01, 7.44E-01, 8.13E-01, 8.42E-01, 8.46E-01, 8.34E-01, 8.13E-01}
01726 },
01727 {
01728 {1.78E-01, 3.62E-01, 1.55E-01, 2.73E-01, 3.91E-01, 4.73E-01, 5.10E-01, 5.04E-01, 4.70E-01, 4.32E-01},
01729 {4.08E-01, 7.26E-01, 2.83E-01, 4.45E-01, 5.79E-01, 6.54E-01, 6.78E-01, 6.64E-01, 6.30E-01, 5.98E-01},
01730 {6.37E-01, 1.03E+00, 3.73E-01, 5.46E-01, 6.75E-01, 7.40E-01, 7.57E-01, 7.43E-01, 7.15E-01, 6.92E-01},
01731 {8.65E-01, 1.28E+00, 4.41E-01, 6.14E-01, 7.35E-01, 7.92E-01, 8.05E-01, 7.95E-01, 7.74E-01, 7.59E-01}
01732 },
01733 {
01734 {2.07E-01, 3.73E-01, 1.73E-01, 2.85E-01, 4.03E-01, 4.76E-01, 5.06E-01, 5.03E-01, 4.84E-01, 4.63E-01},
01735 {4.32E-01, 7.13E-01, 3.06E-01, 4.54E-01, 5.81E-01, 6.44E-01, 6.59E-01, 6.49E-01, 6.28E-01, 6.11E-01},
01736 {6.40E-01, 9.85E-01, 3.98E-01, 5.53E-01, 6.74E-01, 7.27E-01, 7.36E-01, 7.26E-01, 7.10E-01, 6.98E-01},
01737 {8.38E-01, 1.21E+00, 4.67E-01, 6.20E-01, 7.34E-01, 7.79E-01, 7.87E-01, 7.79E-01, 7.69E-01, 7.63E-01}
01738 }
01739 },
01740 {
01741
01742 {
01743 {9.31E-02, 3.96E-01, 1.36E-01, 2.74E-01, 3.99E-01, 4.95E-01, 5.52E-01, 5.70E-01, 5.48E-01, 4.96E-01},
01744 {2.25E-01, 8.46E-01, 2.49E-01, 4.46E-01, 5.89E-01, 6.79E-01, 7.23E-01, 7.31E-01, 7.08E-01, 6.64E-01},
01745 {3.59E-01, 1.24E+00, 3.30E-01, 5.47E-01, 6.85E-01, 7.63E-01, 7.98E-01, 8.04E-01, 7.85E-01, 7.53E-01},
01746 {4.93E-01, 1.60E+00, 3.91E-01, 6.15E-01, 7.44E-01, 8.13E-01, 8.42E-01, 8.47E-01, 8.35E-01, 8.12E-01}
01747 },
01748 {
01749 {9.32E-02, 3.99E-01, 1.35E-01, 2.72E-01, 3.91E-01, 4.75E-01, 5.14E-01, 5.09E-01, 4.73E-01, 4.31E-01},
01750 {2.25E-01, 8.49E-01, 2.49E-01, 4.44E-01, 5.79E-01, 6.56E-01, 6.81E-01, 6.68E-01, 6.31E-01, 5.96E-01},
01751 {3.58E-01, 1.25E+00, 3.29E-01, 5.44E-01, 6.76E-01, 7.42E-01, 7.60E-01, 7.46E-01, 7.16E-01, 6.91E-01},
01752 {4.92E-01, 1.60E+00, 3.90E-01, 6.12E-01, 7.36E-01, 7.93E-01, 8.07E-01, 7.97E-01, 7.74E-01, 7.58E-01}
01753 },
01754 {
01755 {1.13E-01, 4.21E-01, 1.47E-01, 2.83E-01, 4.04E-01, 4.80E-01, 5.13E-01, 5.12E-01, 4.93E-01, 4.71E-01},
01756 {2.52E-01, 8.56E-01, 2.61E-01, 4.50E-01, 5.82E-01, 6.48E-01, 6.66E-01, 6.56E-01, 6.35E-01, 6.16E-01},
01757 {3.85E-01, 1.23E+00, 3.41E-01, 5.49E-01, 6.75E-01, 7.30E-01, 7.41E-01, 7.31E-01, 7.15E-01, 7.02E-01},
01758 {5.14E-01, 1.56E+00, 4.01E-01, 6.15E-01, 7.34E-01, 7.82E-01, 7.90E-01, 7.83E-01, 7.72E-01, 7.65E-01}
01759 }
01760 }
01761 };
01762
01763 double temps[4] = {5000., 10000., 15000., 20000. };
01764 double log_dens[3] = {2., 4., 6.};
01765 long ipTe, ipDens;
01766
01767 ASSERT( nelem <= 1 );
01768
01769
01770 ipTe = hunt_bisect( temps, 4, phycon.te );
01771 ipDens = hunt_bisect( log_dens, 3, log10(dense.eden) );
01772
01773 ASSERT( (ipTe >=0) && (ipTe < 3) );
01774 ASSERT( (ipDens >=0) && (ipDens < 2) );
01775
01776 for( long nHi=iso.n_HighestResolved_max[ipISO][nelem]+1; nHi<=iso.n_HighestResolved_max[ipISO][nelem]+iso.nCollapsed_max[ipISO][nelem]; nHi++ )
01777 {
01778 for( long lHi=0; lHi<nHi; lHi++ )
01779 {
01780 for( long sHi=1; sHi<4; sHi++ )
01781 {
01782 if( ipISO == ipH_LIKE && sHi != 2 )
01783 continue;
01784 else if( ipISO == ipHE_LIKE && sHi != 1 && sHi != 3 )
01785 continue;
01786
01787 double bnl_at_lo_den, bnl_at_hi_den, bnl;
01788 double bnl_max, bnl_min, temp, dens;
01789
01790 long ipL = MIN2(9,lHi);
01791 long ip1;
01792
01793 if( nelem==ipHYDROGEN )
01794 ip1 = 0;
01795 else if( nelem==ipHELIUM )
01796 {
01797 if( ipISO==ipH_LIKE )
01798 ip1 = 1;
01799 else if( ipISO==ipHE_LIKE )
01800 {
01801 if( sHi==1 )
01802 ip1 = 2;
01803 else if( sHi==3 )
01804 ip1 = 3;
01805 else
01806 TotalInsanity();
01807 }
01808 else
01809 TotalInsanity();
01810 }
01811 else
01812 TotalInsanity();
01813
01814 temp = MAX2( temps[0], phycon.te );
01815 temp = MIN2( temps[3], temp );
01816
01817 dens = MAX2( log_dens[0], log10(dense.eden) );
01818 dens = MIN2( log_dens[2], dens );
01819
01820
01821
01822
01823
01824 if( temp < temps[0] && dens < log_dens[0] )
01825 bnl = bnl_array[ip1][0][0][ipL];
01826 else if( temp < temps[0] && dens >= log_dens[2] )
01827 bnl = bnl_array[ip1][2][0][ipL];
01828 else if( temp >= temps[3] && dens < log_dens[0] )
01829 bnl = bnl_array[ip1][0][3][ipL];
01830 else if( temp >= temps[3] && dens >= log_dens[2] )
01831 bnl = bnl_array[ip1][2][3][ipL];
01832 else
01833 {
01834 bnl_at_lo_den = ( temp - temps[ipTe]) / (temps[ipTe+1] - temps[ipTe]) *
01835 (bnl_array[ip1][ipDens][ipTe+1][ipL] - bnl_array[ip1][ipDens][ipTe][ipL]) + bnl_array[ip1][ipDens][ipTe][ipL];
01836
01837 bnl_at_hi_den = ( temp - temps[ipTe]) / (temps[ipTe+1] - temps[ipTe]) *
01838 (bnl_array[ip1][ipDens+1][ipTe+1][ipL] - bnl_array[ip1][ipDens+1][ipTe][ipL]) + bnl_array[ip1][ipDens+1][ipTe][ipL];
01839
01840 bnl = ( dens - log_dens[ipDens]) / (log_dens[ipDens+1] - log_dens[ipDens]) *
01841 (bnl_at_hi_den - bnl_at_lo_den) + bnl_at_lo_den;
01842 }
01843
01845 {
01846 bnl_max = MAX4( bnl_array[ip1][ipDens][ipTe+1][ipL], bnl_array[ip1][ipDens+1][ipTe+1][ipL],
01847 bnl_array[ip1][ipDens][ipTe][ipL], bnl_array[ip1][ipDens+1][ipTe][ipL] );
01848 ASSERT( bnl <= bnl_max );
01849
01850 bnl_min = MIN4( bnl_array[ip1][ipDens][ipTe+1][ipL], bnl_array[ip1][ipDens+1][ipTe+1][ipL],
01851 bnl_array[ip1][ipDens][ipTe][ipL], bnl_array[ip1][ipDens+1][ipTe][ipL] );
01852 ASSERT( bnl >= bnl_min );
01853 }
01854
01855 iso.bnl_effective[ipISO][nelem][nHi][lHi][sHi] = bnl;
01856
01857 ASSERT( iso.bnl_effective[ipISO][nelem][nHi][lHi][sHi] > 0. );
01858 }
01859 }
01860 }
01861
01862 return;
01863 }
01864
01865
01866 void iso_collapsed_bnl_print( long ipISO, long nelem )
01867 {
01868 DEBUG_ENTRY( "iso_collapsed_bnl_print()" );
01869
01870 for( long is = 1; is<=3; ++is)
01871 {
01872 if( ipISO == ipH_LIKE && is != 2 )
01873 continue;
01874 else if( ipISO == ipHE_LIKE && is != 1 && is != 3 )
01875 continue;
01876
01877 char chSpin[3][9]= {"singlets", "doublets", "triplets"};
01878
01879
01880 fprintf(ioQQQ," %s %s %s bnl\n",
01881 iso.chISO[ipISO],
01882 elementnames.chElementSym[nelem],
01883 chSpin[is-1]);
01884
01885
01886 fprintf(ioQQQ," n\\l=> ");
01887 for( long i =0; i < iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]; ++i)
01888 {
01889 fprintf(ioQQQ,"%2ld ",i);
01890 }
01891 fprintf(ioQQQ,"\n");
01892
01893
01894 for( long in = 1; in <= iso.n_HighestResolved_max[ipISO][nelem] + iso.nCollapsed_max[ipISO][nelem]; ++in)
01895 {
01896 if( is==3 && in==1 )
01897 continue;
01898
01899 fprintf(ioQQQ," %2ld ",in);
01900
01901 for( long il = 0; il < in; ++il)
01902 {
01903 fprintf( ioQQQ, "%9.3e ", iso.bnl_effective[ipISO][nelem][in][il][is] );
01904 }
01905 fprintf(ioQQQ,"\n");
01906 }
01907 }
01908
01909 return;
01910 }
01911
01912 void iso_collapsed_Aul_update( long ipISO, long nelem )
01913 {
01914 DEBUG_ENTRY( "iso_collapsed_Aul_update()" );
01915
01916 long ipFirstCollapsed = iso.numLevels_max[ipISO][nelem] - iso.nCollapsed_max[ipISO][nelem];
01917
01918 for( long ipLo=0; ipLo<ipFirstCollapsed; ipLo++ )
01919 {
01920 long spin = StatesElem[ipISO][nelem][ipLo].S;
01921
01922
01923 for( long nHi=iso.n_HighestResolved_max[ipISO][nelem]+1; nHi<=iso.n_HighestResolved_max[ipISO][nelem]+iso.nCollapsed_max[ipISO][nelem]; nHi++ )
01924 {
01925 realnum Auls[2] = {
01926 iso.CachedAs[ipISO][nelem][ nHi-iso.n_HighestResolved_max[ipISO][nelem]-1 ][ ipLo ][0],
01927 iso.CachedAs[ipISO][nelem][ nHi-iso.n_HighestResolved_max[ipISO][nelem]-1 ][ ipLo ][1] };
01928
01929 realnum EffectiveAul =
01930 Auls[0]*spin*(2.f*(L_(ipLo)+1.f)+1.f)*(realnum)iso.bnl_effective[ipISO][nelem][nHi][ L_(ipLo)+1 ][spin];
01931
01932
01933
01934 if( L_(ipLo) > 0 )
01935 {
01936 EffectiveAul +=
01937 Auls[1]*spin*(2.f*(L_(ipLo)-1.f)+1.f)*(realnum)iso.bnl_effective[ipISO][nelem][nHi][ L_(ipLo)-1 ][spin];
01938 }
01939
01940 if( ipISO==ipH_LIKE )
01941 EffectiveAul /= (2.f*nHi*nHi);
01942 else if( ipISO==ipHE_LIKE )
01943 EffectiveAul /= (4.f*nHi*nHi);
01944 else
01945 TotalInsanity();
01946
01947 long ipHi = iso.QuantumNumbers2Index[ipISO][nelem][nHi][ L_(ipLo)+1 ][spin];
01948
01949
01950 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul = EffectiveAul;
01951
01952 ASSERT( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul > 0. );
01953 }
01954 }
01955
01956 return;
01957 }
01958
01959 void iso_collapsed_lifetimes_update( long ipISO, long nelem )
01960 {
01961 DEBUG_ENTRY( "iso_collapsed_Aul_update()" );
01962
01963 for( long ipHi=iso.numLevels_max[ipISO][nelem]- iso.nCollapsed_max[ipISO][nelem]; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
01964 {
01965 StatesElem[ipISO][nelem][ipHi].lifetime = SMALLFLOAT;
01966
01967 for( long ipLo=0; ipLo < ipHi; ipLo++ )
01968 {
01969 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA )
01970 continue;
01971
01972 StatesElem[ipISO][nelem][ipHi].lifetime += Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul;
01973 }
01974
01975
01976 StatesElem[ipISO][nelem][ipHi].lifetime = 1./StatesElem[ipISO][nelem][ipHi].lifetime;
01977
01978 for( long ipLo=0; ipLo < ipHi; ipLo++ )
01979 {
01980 if( Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN <= 0. )
01981 continue;
01982
01983 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul <= iso.SmallA )
01984 continue;
01985
01986 Transitions[ipISO][nelem][ipHi][ipLo].Emis->dampXvel = (realnum)(
01987 (1.f/StatesElem[ipISO][nelem][ipHi].lifetime)/
01988 PI4/Transitions[ipISO][nelem][ipHi][ipLo].EnergyWN);
01989
01990 ASSERT(Transitions[ipISO][nelem][ipHi][ipLo].Emis->dampXvel> 0.);
01991 }
01992 }
01993
01994 return;
01995 }
01996
01997 #if 0
01998 STATIC void Prt_AGN_table( void )
01999 {
02000
02001 multi_arr<char,2> chLevel(max_num_levels,10);
02002
02003
02004 for( long ipLo=0; ipLo < iso.numLevels_max[ipISO][ipISO]-iso.nCollapsed_max[ipISO][ipISO]; ++ipLo )
02005 {
02006 long nelem = ipISO;
02007 sprintf( &chLevel.front(ipLo) , "%li %li%c", N_(ipLo), S_(ipLo), chL[MIN2(20,L_(ipLo))] );
02008 }
02009
02010
02011
02012 {
02013
02014 enum {AGN=false};
02015 if( AGN )
02016 {
02017 # define NTEMP 6
02018 double te[NTEMP]={6000.,8000.,10000.,15000.,20000.,25000. };
02019 double telog[NTEMP] ,
02020 cs ,
02021 ratecoef;
02022 long nelem = ipHELIUM;
02023 fprintf( ioQQQ,"trans");
02024 for( long i=0; i < NTEMP; ++i )
02025 {
02026 telog[i] = log10( te[i] );
02027 fprintf( ioQQQ,"\t%.3e",te[i]);
02028 }
02029 for( long i=0; i < NTEMP; ++i )
02030 {
02031 fprintf( ioQQQ,"\t%.3e",te[i]);
02032 }
02033 fprintf(ioQQQ,"\n");
02034
02035 for( long ipHi=ipHe2s3S; ipHi< iso.numLevels_max[ipHE_LIKE][ipHELIUM]; ++ipHi )
02036 {
02037 for( long ipLo=ipHe1s1S; ipLo < ipHi; ++ipLo )
02038 {
02039
02040
02041
02042 if( N_(ipHi) == N_(ipLo) )
02043 continue;
02044
02045
02046 fprintf( ioQQQ,"%s - %s",
02047 &chLevel.front(ipLo) , &chLevel.front(ipHi) );
02048
02049
02050 for( long i=0; i < NTEMP; ++i )
02051 {
02052 phycon.alogte = telog[i];
02053
02054 cs = HeCSInterp( nelem , ipHi , ipLo, ipELECTRON );
02055 fprintf(ioQQQ,"\t%.2e", cs );
02056 }
02057
02058
02059 for( long i=0; i < NTEMP; ++i )
02060 {
02061 phycon.alogte = telog[i];
02062 phycon.te = pow(10.,telog[i] );
02063 tfidle(false);
02064 cs = HeCSInterp( nelem , ipHi , ipLo, ipELECTRON );
02065
02066 ratecoef = cs/sqrt(phycon.te)*COLL_CONST/StatesElem[ipHE_LIKE][nelem][ipLo].g *
02067 sexp( Transitions[ipHE_LIKE][nelem][ipHi][ipLo].EnergyK / phycon.te );
02068 fprintf(ioQQQ,"\t%.2e", ratecoef );
02069 }
02070 fprintf(ioQQQ,"\n");
02071 }
02072 }
02073 cdEXIT(EXIT_FAILURE);
02074 }
02075 }
02076
02077 return;
02078 }
02079 #endif