00001
00002
00003
00004
00005
00006 #include "cddefines.h"
00007 #include "taulines.h"
00008 #include "atomfeii.h"
00009 #include "dense.h"
00010 #include "conv.h"
00011 #include "atoms.h"
00012 #include "rfield.h"
00013 #include "wind.h"
00014 #include "iso.h"
00015 #include "h2.h"
00016 #include "opacity.h"
00017 #include "trace.h"
00018 #include "lines_service.h"
00019 #include "atmdat.h"
00020 #include "hydrogenic.h"
00021 #include "rt.h"
00022
00023 void RT_line_all(
00024
00025
00026 bool lgDoEsc ,
00027
00028 bool lgUpdateFineOpac )
00029 {
00030 long int i,
00031 ion,
00032 ipISO,
00033 nelem;
00034 long ipHi , ipLo;
00035 double factor,
00036 coloi;
00037 double SaveLyaPesc[NISO][LIMELM] ,
00038 SaveLyaPdest[NISO][LIMELM];
00039
00040 bool lgRT_update = lgUpdateFineOpac || lgDoEsc || conv.lgIonStageTrimed;
00041
00042 DEBUG_ENTRY( "RT_line_all()" );
00043
00044 if( trace.lgTrace )
00045 fprintf( ioQQQ, " RT_line_all called\n" );
00046
00047
00048 if( !rfield.lgDoLineTrans && conv.nPres2Ioniz )
00049 {
00050 return;
00051 }
00052
00053
00054
00055 rfield.lgFine_opac_update = lgUpdateFineOpac;
00056 if( rfield.lgFine_opac_update )
00057 {
00058
00059 memset(rfield.fine_opac_zone , 0 , (unsigned long)rfield.nfine*sizeof(realnum) );
00060
00061
00062
00063
00064
00065
00066 realnum dWind = wind.windv - wind.windv0;
00067
00068
00069 rfield.ipFineConVelShift = -(long int)(dWind / rfield.fine_opac_velocity_width+0.5);
00070 }
00071
00072 # if 0
00073
00074
00075
00076 {
00077 #include "doppvel.h"
00078 double dTau , aa;
00079 ipISO = 0; nelem = 0;ipLo = 0;
00080 ipHi = 23;
00081 dTau = Transitions[ipISO][nelem][ipHi][ipLo].Emis->PopOpc *
00082 Transitions[ipISO][nelem][ipHi][ipLo].Emis->opacity /
00083 DoppVel.doppler[nelem] + opac.opacity_abs[Transitions[ipISO][nelem][ipHi][ipLo].ipCont-1];
00084 dTau *= radius.drad_x_fillfac_mean;
00085 aa = log(1. + dTau ) / SDIV(dTau);
00086 fprintf(ioQQQ,"DEBUG dTau\t%.2f\t%.5e\t%.5e\t%.5e\n",fnzone,dTau,
00087 radius.drad_x_fillfac_mean,
00088 aa);
00089 }
00090 # endif
00091
00092
00093 RT_stark();
00094
00095
00096
00097 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00098 {
00099
00100 for( nelem=ipISO; nelem<LIMELM; ++nelem )
00101 {
00102
00103
00104 ion = nelem+1-ipISO;
00105
00106
00107 if( !dense.lgElmtOn[nelem] )
00108 continue;
00109
00110 if( ion <=dense.IonHigh[nelem] )
00111 {
00112
00113
00114
00115
00116
00117 if( ipISO<=nelem )
00118 {
00119 SaveLyaPesc[ipISO][nelem] = Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc;
00120 SaveLyaPdest[ipISO][nelem] = Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pdest;
00121 }
00122
00123
00124 if( dense.xIonDense[nelem][ion] > 1e-30 )
00125 {
00126 factor = dense.xIonDense[nelem][ion];
00127 }
00128 else
00129 {
00130
00131
00132 factor = 1.;
00133 }
00134
00135
00136 for( ipHi=1; ipHi < iso.numLevels_local[ipISO][nelem]; ++ipHi )
00137 {
00138 for( ipLo=0; ipLo < ipHi; ++ipLo )
00139 {
00140
00141
00142 if( Transitions[ipISO][nelem][ipHi][ipLo].ipCont < 0 )
00143 continue;
00144
00145 double SavePopOpc = Transitions[ipISO][nelem][ipHi][ipLo].Emis->PopOpc;
00146
00147 Transitions[ipISO][nelem][ipHi][ipLo].Emis->PopOpc *= factor;
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 RT_line_one(&Transitions[ipISO][nelem][ipHi][ipLo] , lgDoEsc , lgUpdateFineOpac,true);
00158
00159
00160 {
00161
00162 enum {DEBUG_LOC=false};
00163 if( DEBUG_LOC && nelem==1&& ipLo==0 )
00164 {
00165 fprintf(ioQQQ,"DEBUG pdest\t%3li\t%.2f\t%.3e\n",
00166 ipHi ,
00167 fnzone,
00168 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pdest);
00169 }
00170 }
00171
00172
00173 Transitions[ipISO][nelem][ipHi][ipLo].Emis->PopOpc = SavePopOpc;
00174 }
00175 }
00176
00177 if( ipISO > 0 && lgDoEsc )
00178 {
00179
00180
00181 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc *=
00182 opac.ExpmTau[Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].ipCont-1];
00183 }
00184
00185
00186 atmdat_2phot_rate(ipISO , nelem);
00187
00188
00189
00190 if( opac.lgCaseB_no_pdest )
00191 {
00192 ipLo = 0;
00193
00194 for( ipHi=ipLo+1; ipHi < iso.numLevels_max[ipISO][nelem]; ++ipHi )
00195 {
00196 if( Transitions[ipISO][nelem][ipHi][ipLo].ipCont <= 0 )
00197 continue;
00198
00199
00200 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pdest = SMALLFLOAT;
00201 }
00202 }
00203
00204 ipLo = 0;
00205
00206
00207
00208 if( dense.xIonDense[nelem][ion] > 1e-30 && lgUpdateFineOpac )
00209 {
00210
00211 factor = StatesElem[ipISO][nelem][0].Pop * dense.xIonDense[nelem][ion];
00212 for( ipHi=StatesElem[ipISO][nelem][iso.numLevels_max[ipISO][nelem]-1].n; ipHi < iso.nLyman[ipISO]; ipHi++ )
00213 {
00214
00215 ExtraLymanLines[ipISO][nelem][ipHi].Emis->PopOpc = factor;
00216 ExtraLymanLines[ipISO][nelem][ipHi].Lo->Pop =
00217 StatesElem[ipISO][nelem][ipLo].Pop;
00218
00219
00220 RT_line_one(&ExtraLymanLines[ipISO][nelem][ipHi] , lgDoEsc , lgUpdateFineOpac,true);
00221
00222
00223 ExtraLymanLines[ipISO][nelem][ipHi].Emis->PopOpc =
00224 StatesElem[ipISO][nelem][0].Pop;
00225 }
00226 }
00227
00228 }
00229 }
00230 }
00231
00232
00233
00234 for( ipISO=0; ipISO<NISO; ipISO++ )
00235 {
00236 for( nelem=ipISO; nelem<LIMELM; nelem++ )
00237 {
00238 if( nelem < 2 || dense.lgElmtOn[nelem] )
00239 {
00240
00241
00242
00243 if( lgTauGood( &Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0] ) )
00244 {
00245 if( lgDoEsc )
00246 {
00247 for( ipHi=1; ipHi < iso.numLevels_max[ipISO][nelem]; ipHi++ )
00248 {
00249 for( ipLo=0; ipLo < ipHi; ipLo++ )
00250 {
00251 if( Transitions[ipISO][nelem][ipHi][ipLo].ipCont <= 0 )
00252 continue;
00253
00254
00255
00256 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pesc<1. )
00257 {
00258 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pesc = MIN2(1.f,
00259 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pesc+
00260 (realnum)iso.pestrk[ipISO][nelem][ipLo][ipHi]);
00261 }
00262 }
00263 }
00264 }
00265
00266 else if( Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc < 1. )
00267 {
00268 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc = MIN2(1.f,
00269 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc+
00270 (realnum)iso.pestrk[ipISO][nelem][0][iso.nLyaLevel[ipISO]]);
00271 }
00272 }
00273 }
00274 }
00275 }
00276
00277
00278
00279
00280 if( lgTauGood( &Transitions[ipH_LIKE][ipHYDROGEN][iso.nLyaLevel[ipH_LIKE]][0] ) )
00281 {
00282
00283 atom_oi_calc(&coloi);
00284
00285 Transitions[ipH_LIKE][ipHYDROGEN][ipH3p][ipH1s].Emis->Pesc = (realnum)(atoms.pmph31/
00286 Transitions[ipH_LIKE][ipHYDROGEN][ipH3p][ipH1s].Emis->Aul);
00287
00288 if( trace.lgTrace && trace.lgIsoTraceFull[ipH_LIKE] )
00289 {
00290 fprintf( ioQQQ, " RT_line_all calls P8446 who found pmph31=%10.2e\n",
00291 atoms.pmph31 );
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 t_fe2ovr_la::Inst().atoms_fe2ovr();
00302
00303
00304
00305
00306
00307
00308 Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->Pdest += hydro.dstfe2lya;
00309 }
00310
00311
00312 if( nzone > 1 )
00313 {
00314 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00315 {
00316
00317 for( nelem=ipISO; nelem<LIMELM; ++nelem )
00318 {
00319 ion = nelem+1-ipISO;
00320 if( ion <=dense.IonHigh[nelem] && ipISO<=nelem )
00321 {
00322
00323
00324 if( Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->iRedisFun==ipLY_A &&
00325 lgTauGood( &Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0] ) )
00326 {
00327
00328
00329
00330
00331 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pdest =
00332 ((realnum)SaveLyaPdest[ipISO][nelem] +
00333 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pdest) / 2.f;
00334 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc =
00335 ((realnum)SaveLyaPesc[ipISO][nelem] +
00336 Transitions[ipISO][nelem][iso.nLyaLevel[ipISO]][0].Emis->Pesc) / 2.f;
00337
00338 }
00339 }
00340 }
00341 }
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 if( !hydro.lgLymanPumping )
00351 {
00352 ipISO = ipH_LIKE;
00353 nelem = ipHYDROGEN;
00354 ipLo = 0;
00355 for( ipHi=ipLo+1; ipHi < iso.numLevels_max[ipISO][nelem]; ++ipHi )
00356 {
00357
00358
00359 Transitions[ipISO][nelem][ipHi][ipLo].Emis->pump = 0.;
00360 }
00361 }
00362
00363 {
00364
00365
00366 enum {DEBUG_LOC=false};
00367
00368 if( DEBUG_LOC && nzone>433 )
00369 {
00370
00371 DumpLine(&Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][0] );
00372 }
00373 }
00374
00375
00376 for( i=1; i <= nLevel1; i++ )
00377 {
00378 RT_line_one(&TauLines[i] , lgDoEsc , lgUpdateFineOpac,true);
00379 }
00380
00381 for( i=0; i < nCORotate; i++ )
00382 {
00383 RT_line_one(&C12O16Rotate[i] , lgDoEsc , lgUpdateFineOpac,true);
00384 RT_line_one(&C13O16Rotate[i] , lgDoEsc , lgUpdateFineOpac,true);
00385 }
00386 for( i=0; i < nHFLines; i++ )
00387 {
00388 RT_line_one(&HFLines[i] , lgDoEsc , lgUpdateFineOpac,true);
00389 }
00390
00391 for( i=0; i < linesAdded2; i++)
00392 {
00393 RT_line_one(atmolEmis[i].tran , lgDoEsc , lgUpdateFineOpac,true);
00394 }
00395
00396 if( lgRT_update )
00397 {
00398 for( i=0; i < nUTA; i++ )
00399 {
00400
00401
00402 if( UTALines[i].Emis->Aul > 0. )
00403 {
00404
00405 UTALines[i].Emis->PopOpc = dense.xIonDense[UTALines[i].Hi->nelem-1][UTALines[i].Hi->IonStg-1];
00406 UTALines[i].Lo->Pop = dense.xIonDense[UTALines[i].Hi->nelem-1][UTALines[i].Hi->IonStg-1];
00407 UTALines[i].Hi->Pop = 0.;
00408 RT_line_one(&UTALines[i] , lgDoEsc , lgUpdateFineOpac,true);
00409 }
00410 }
00411 }
00412
00413
00414 for( ipISO=ipHE_LIKE; ipISO<NISO; ++ipISO )
00415 {
00416
00417 for( nelem=ipISO; nelem<LIMELM; ++nelem )
00418 {
00419 if( dense.lgElmtOn[nelem] )
00420 {
00421 for( ipLo=1; ipLo < (iso.numLevels_local[ipISO][nelem]-1); ++ipLo )
00422 {
00423 RT_line_one(&SatelliteLines[ipISO][nelem][ipLo], lgDoEsc, lgUpdateFineOpac, true);
00424 }
00425 }
00426 }
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 for( i=0; i < nWindLine; i++ )
00438 {
00439
00440
00441 if( TauLine2[i].Hi->IonStg < TauLine2[i].Hi->nelem+1-NISO )
00442 {
00443 RT_line_one(&TauLine2[i] , lgDoEsc , lgUpdateFineOpac,true);
00444 }
00445 }
00446
00447
00448 H2_RTMake( lgDoEsc , lgUpdateFineOpac);
00449
00450
00451 FeII_RT_Make( lgDoEsc , lgUpdateFineOpac);
00452 return;
00453 }