00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "cddefines.h"
00012 #include "taulines.h"
00013 #include "opacity.h"
00014 #include "dense.h"
00015 #include "iso.h"
00016 #include "hmi.h"
00017 #include "h2.h"
00018 #include "rfield.h"
00019 #include "conv.h"
00020 #include "rt.h"
00021 #include "mole_co_atom.h"
00022 #include "atomfeii.h"
00023 #include "heavy.h"
00024 #include "he.h"
00025 #include "trace.h"
00026
00027
00028 static int nOTS_Line_type = -1;
00029 static int nOTS1=-1 , nOTS2=-1;
00030
00031 STATIC void RT_OTS_AddCont(
00032
00033 realnum ots,
00034
00035 long int ip);
00036
00037
00038
00039 void RT_OTS(void)
00040 {
00041 long int
00042 ipla,
00043 ipISO ,
00044 nelem,
00045 n;
00046 realnum
00047 difflya,
00048 esc,
00049 ots;
00050
00051
00052
00053 # define BOWEN 0.5f
00054 long int ipHi,
00055 ipLo;
00056
00057 double bwnfac;
00058 double ots660;
00059 realnum cont_phot_destroyed;
00060 double save_lya_dest,
00061 save_he2lya_dest;
00062
00063 double save_he2rec_dest;
00064
00065
00066
00067
00068
00069 DEBUG_ENTRY( "RT_OTS()" );
00070
00071
00072
00073
00074
00075
00076 nOTS_Line_type = 0;
00077 nelem = ipHELIUM;
00078 if( dense.lgElmtOn[nelem] )
00079 {
00080
00081
00082 bwnfac = BOWEN * MAX2(0.f,1.f- Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Pesc -
00083 Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Pelec_esc );
00084
00085
00086
00087 ots660 = Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Aul*
00088 StatesElem[ipH_LIKE][nelem][ipH2p].Pop*dense.xIonDense[nelem][nelem+1]*
00089
00090 Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Pdest *BOWEN*2.0;
00091
00092
00093 if( ots660 > SMALLFLOAT )
00094 RT_OTS_AddLine(ots660 , he.ip660 );
00095
00096
00097
00098 Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Pdest *= (realnum)bwnfac;
00099 ASSERT( Transitions[ipH_LIKE][nelem][ipH2p][ipH1s].Emis->Pdest >= 0. );
00100 {
00101
00102
00103
00104 enum {DEBUG_LOC=false};
00105
00106 if( DEBUG_LOC )
00107 {
00108 fprintf(ioQQQ,"DEBUG HeII Bowen nzone %li bwnfac:%.2e bwnfac esc:%.2e ots660 %.2e\n",
00109 nzone,
00110 bwnfac ,
00111 bwnfac/BOWEN ,
00112 ots660 );
00113 }
00114 }
00115 }
00116
00117 else
00118 {
00119 bwnfac = 1.;
00120 }
00121
00122
00123 save_lya_dest = Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->Pdest;
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->Pdest *= rfield.lgLyaOTS;
00137
00138
00139 save_he2lya_dest = Transitions[ipH_LIKE][ipHELIUM][ipH2p][ipH1s].Emis->Pdest;
00140 Transitions[ipH_LIKE][ipHELIUM][ipH2p][ipH1s].Emis->Pdest *= rfield.lgHeIIOTS;
00141
00142
00143 save_he2rec_dest = iso.RadRecomb[ipH_LIKE][ipHELIUM][ipH1s][ipRecRad];
00144 iso.RadRecomb[ipH_LIKE][ipHELIUM][ipH1s][ipRecRad] *= rfield.lgHeIIOTS;
00145
00146 nOTS_Line_type = 1;
00147
00148
00149
00150
00151 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00152 {
00153 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00154 {
00155 nOTS1 = ipISO;
00156 nOTS2 = nelem;
00157
00161 if( (dense.IonHigh[nelem] >= nelem+1-ipISO ) )
00162 {
00163
00164
00165
00166
00167 for( ipHi=1; ipHi < iso.numLevels_local[ipISO][nelem]; ipHi++ )
00168 {
00169 for( ipLo=0; ipLo < ipHi; ipLo++ )
00170 {
00171
00172
00173
00174 if( Transitions[ipISO][nelem][ipHi][ipLo].ipCont < 1 ||
00175 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pdest<= DEST0 )
00176 continue;
00177
00178
00179 Transitions[ipISO][nelem][ipHi][ipLo].Emis->ots =
00180 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Aul*
00181 StatesElem[ipISO][nelem][ipHi].Pop*dense.xIonDense[nelem][nelem+1-ipISO]*
00182 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pdest;
00183
00184 ASSERT( Transitions[ipISO][nelem][ipHi][ipLo].Emis->ots >= 0. );
00185
00186
00187
00188
00189
00190
00191
00192 if( Transitions[ipISO][nelem][ipHi][ipLo].Emis->ots > SMALLFLOAT )
00193 RT_OTS_AddLine(Transitions[ipISO][nelem][ipHi][ipLo].Emis->ots,
00194 Transitions[ipISO][nelem][ipHi][ipLo].ipCont );
00195 }
00196 }
00197 {
00198
00199
00200
00201 enum {DEBUG_LOC=false};
00202
00203 if( DEBUG_LOC )
00204 {
00205 long ip;
00206 if( ipISO==0 && nelem==0 && nzone>500 )
00207 {
00208 ipHi = 2;
00209 ipLo = 0;
00210 ip = Transitions[ipISO][nelem][ipHi][ipLo].ipCont;
00211 fprintf(ioQQQ,"DEBUG hlyaots\t%.2f\tEdenTrue\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
00212 fnzone,
00213 dense.EdenTrue ,
00214 Transitions[ipISO][nelem][ipHi][ipLo].Emis->ots,
00215 opac.opacity_abs[ip-1],
00216 StatesElem[ipISO][nelem][ipHi].Pop*dense.xIonDense[nelem][nelem+1-ipISO],
00217 StatesElem[ipISO][nelem][ipHi].Pop,
00218 dense.xIonDense[nelem][nelem+1-ipISO],
00219 Transitions[ipISO][nelem][ipHi][ipLo].Emis->Pdest,
00220 rfield.otslinNew[ip-1],
00221 rfield.otslin[ip-1]);
00222 }
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 for( n=0; n < iso.numLevels_local[ipISO][nelem]; n++ )
00235 {
00236 cont_phot_destroyed = (realnum)(iso.RadRecomb[ipISO][nelem][n][ipRecRad]*
00237 (1. - iso.RadRecomb[ipISO][nelem][n][ipRecEsc])*dense.eden*
00238 dense.xIonDense[nelem][nelem+1-ipISO]);
00239 ASSERT( cont_phot_destroyed >= 0. );
00240
00241
00242 RT_OTS_AddCont(cont_phot_destroyed,iso.ipIsoLevNIonCon[ipISO][nelem][n]);
00243
00244 {
00245
00246 enum {DEBUG_LOC=false};
00247
00248 if( DEBUG_LOC && nzone > 400 && nelem==0 && n==2 )
00249 {
00250 long ip = iso.ipIsoLevNIonCon[ipISO][nelem][n]-1;
00251 fprintf(ioQQQ,"hotsdebugg\t%.3f\t%li\th con ots\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
00252 fnzone,
00253 n ,
00254 StatesElem[ipISO][ipHYDROGEN][2].Pop*dense.xIonDense[ipHYDROGEN][1],
00255 cont_phot_destroyed,
00256 cont_phot_destroyed/opac.opacity_abs[ip],
00257 rfield.otsconNew[ip] ,
00258 rfield.otscon[ip] ,
00259 opac.opacity_abs[ip] ,
00260 hmi.Hmolec[ipMHm] ,
00261 hmi.HMinus_photo_rate);
00262 }
00263 }
00264 }
00265 }
00266 }
00267 }
00268
00269 {
00270
00271 enum {DEBUG_LOC=false};
00272
00273 if( DEBUG_LOC )
00274 {
00275 nelem = 0;
00276 fprintf(ioQQQ,"hotsdebugg %li \t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
00277 nzone,
00278 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][0]-1],
00279 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][1]-1],
00280 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][3]-1],
00281 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][4]-1],
00282 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][5]-1],
00283 rfield.otsconNew[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][6]-1],
00284 opac.opacity_abs[iso.ipIsoLevNIonCon[ipH_LIKE][nelem][6]-1]);
00285 }
00286 }
00287
00288
00289 Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->Pdest = (realnum)save_lya_dest;
00290 Transitions[ipH_LIKE][ipHELIUM][ipH2p][ipH1s].Emis->Pdest = (realnum)save_he2lya_dest;
00291 iso.RadRecomb[ipH_LIKE][ipHELIUM][ipH1s][ipRecRad] = save_he2rec_dest;
00292
00293 nelem = ipHELIUM;
00294 if( dense.lgElmtOn[nelem] && bwnfac > 0. )
00295 {
00296
00297 Transitions[ipH_LIKE][ipHELIUM][ipH2p][ipH1s].Emis->Pdest /= (realnum)bwnfac;
00298 }
00299
00300 if( trace.lgTrace )
00301 {
00302 fprintf(ioQQQ," RT_OTS Pdest %.2e ots rate %.2e in otslinNew %.2e con opac %.2e\n",
00303 Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->Pdest , Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].Emis->ots ,
00304 rfield.otslinNew[Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].ipCont-1] ,
00305 opac.opacity_abs[Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].ipCont-1]
00306 );
00307 }
00308
00309 nOTS_Line_type = 2;
00310
00311 for( nelem=NISO; nelem < LIMELM; nelem++ )
00312 {
00313 long int ion;
00314
00315
00316 for( ion=0; ion < nelem+1-NISO; ion++ )
00317 {
00318 if( dense.xIonDense[nelem][ion+1] > 0. )
00319 {
00320 nOTS1 = nelem;
00321 nOTS2 = ion;
00322
00323 ipla = Heavy.ipLyHeavy[nelem][ion];
00324 ASSERT( ipla>0 );
00325 esc = opac.ExpmTau[ipla-1];
00326
00327 difflya = Heavy.xLyaHeavy[nelem][ion]*dense.xIonDense[nelem][ion+1];
00328
00329
00330 ots = difflya*MAX2(0.f,1.f-esc);
00331
00332
00333 ASSERT( ots >= 0.);
00334
00335
00336
00337
00338 if( ots > SMALLFLOAT )
00339 RT_OTS_AddLine(ots,ipla);
00340
00341
00342 ipla = Heavy.ipBalHeavy[nelem][ion];
00343 esc = opac.ExpmTau[ipla-1];
00344
00345 difflya = Heavy.xLyaHeavy[nelem][ion]*dense.xIonDense[nelem][ion+1];
00346
00347
00348 ots = difflya*MAX2(0.f,1.f-esc);
00349 ASSERT( ots >= 0.);
00350
00351
00352 if( ots > SMALLFLOAT )
00353 RT_OTS_AddLine(ots,ipla);
00354 }
00355 }
00356 }
00357
00358 nOTS_Line_type = 3;
00359
00360 FeII_OTS();
00361
00362 nOTS_Line_type = 4;
00363
00364 # if 0
00365 {
00366 # include "lines_service.h"
00367 if( nzone>290 ) DumpLine( &TauLines[74] );
00368 }
00369 # endif
00370
00371
00372 for( nOTS1=1; nOTS1 < nLevel1; nOTS1++ )
00373 {
00374
00375 TauLines[nOTS1].Emis->ots = TauLines[nOTS1].Hi->Pop * TauLines[nOTS1].Emis->Aul * TauLines[nOTS1].Emis->Pdest;
00376
00377
00378
00379 if( TauLines[nOTS1].Emis->ots > SMALLFLOAT )
00380 RT_OTS_AddLine( TauLines[nOTS1].Emis->ots , TauLines[nOTS1].ipCont);
00381 }
00382
00383 nOTS_Line_type = 5;
00384
00385 for( nOTS1=0; nOTS1 < nWindLine; nOTS1++ )
00386 {
00387 if( TauLine2[nOTS1].Hi->IonStg < TauLine2[nOTS1].Hi->nelem+1-NISO )
00388 {
00389 TauLine2[nOTS1].Emis->ots = TauLine2[nOTS1].Hi->Pop * TauLine2[nOTS1].Emis->Aul * TauLine2[nOTS1].Emis->Pdest;
00390 if( TauLine2[nOTS1].Emis->ots > SMALLFLOAT )
00391 RT_OTS_AddLine( TauLine2[nOTS1].Emis->ots , TauLine2[nOTS1].ipCont);
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400 nOTS_Line_type = 6;
00401 CO_OTS();
00402
00403
00404 nOTS_Line_type = 7;
00405 H2_RT_OTS();
00406
00407 return;
00408 }
00409
00410
00411
00412 void RT_OTS_AddLine(double ots,
00413
00414 long int ip )
00415 {
00416
00417 DEBUG_ENTRY( "RT_OTS_AddLine()" );
00418
00419
00420
00421
00422
00423 if( ip==0 || ip > rfield.nflux )
00424 {
00425 return;
00426 }
00427
00428
00429 ASSERT( ots >= 0. );
00430
00431 ASSERT( ip > 0 );
00432
00433
00434
00435
00436 if( opac.opacity_abs[ip-1] > 0. )
00437 {
00438 rfield.otslinNew[ip-1] += (realnum)(ots/opac.opacity_abs[ip-1]);
00439 }
00440
00441 {
00442
00443 enum {DEBUG_LOC=false};
00444
00445 if( DEBUG_LOC && ip== 2363 )
00446 {
00447 fprintf(ioQQQ,"DEBUG ots, opc, otsr %.3e\t%.3e\t%.3e\t",
00448 ots ,
00449 opac.opacity_abs[ip-1],
00450 ots/opac.opacity_abs[ip-1] );
00451 fprintf(ioQQQ,"iteration %li type %i %i %i \n",
00452 iteration,
00453 nOTS_Line_type,
00454 nOTS1,nOTS2 );
00455 }
00456 }
00457 return;
00458 }
00459
00460
00461
00462
00463 STATIC void RT_OTS_AddCont(
00464
00465 realnum ots,
00466
00467 long int ip)
00468 {
00469
00470 DEBUG_ENTRY( "RT_OTS_AddCont()" );
00471
00472
00473
00474
00475
00476
00477
00478 if( ip > rfield.nflux )
00479 {
00480 return;
00481 }
00482
00483 ASSERT( ip> 0 );
00484 ASSERT( ots >= 0. );
00485 ASSERT( ip <= rfield.nupper );
00486
00487
00488
00489
00490 if( opac.opacity_abs[ip-1] > 0. )
00491 {
00492 rfield.otsconNew[ip-1] += (realnum)(ots/opac.opacity_abs[ip-1]);
00493
00494
00495
00496 }
00497 return;
00498 }
00499
00500 #if 0
00501
00502 STATIC bool lgLyaOTS_oscil( realnum ots_new )
00503 {
00504 static realnum old , older;
00505 bool lgReturn = false;
00506
00507 if( !conv.nTotalIoniz || conv.lgSearch )
00508 {
00509
00510 old = 0.;
00511 older = 0.;
00512 }
00513
00514
00515 if( conv.nPres2Ioniz>1 && (ots_new-old) * (old-older) < 0.)
00516 lgReturn = true;
00517
00518 older = old;
00519 old = ots_new;
00520 return( lgReturn );
00521 }
00522
00523
00524 if( lgLyaOTS_oscil( rfield.otslinNew[Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].ipCont-1] ) )
00525 {
00526 fprintf(ioQQQ,"DEBUG lya ots %.2f %.3e\n",
00527 fnzone,
00528 rfield.otslinNew[Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].ipCont-1] );
00529 }
00530 #endif
00531
00532
00533
00534 void RT_OTS_Update(
00535
00536 double *SumOTS ,
00537
00538
00539
00540 double BigFrac)
00541 {
00542 long int i;
00543
00544 static bool lgNeedSpace=true;
00545 static double *old_OTS_line_x_opac , *old_OTS_cont_x_opac;
00546 realnum FacBig , FacSml;
00547
00548 DEBUG_ENTRY( "RT_OTS_Update()" );
00549
00550 if( BigFrac <= 0. )
00551 BigFrac = 10.;
00552 FacBig = (realnum)(1. + BigFrac);
00553 FacSml = 1.f/FacBig;
00554
00555
00556 if( lgNeedSpace )
00557 {
00558 old_OTS_line_x_opac = (double*)MALLOC((size_t)((unsigned)rfield.nupper*sizeof(double)) );
00559 old_OTS_cont_x_opac = (double*)MALLOC((size_t)((unsigned)rfield.nupper*sizeof(double)) );
00560 }
00561 lgNeedSpace = false;
00562
00563 *SumOTS = 0.;
00564
00565
00566 if( rfield.lgKillOTSLine )
00567 {
00568 for( i=0; i < rfield.nflux; i++ )
00569 {
00570 rfield.otslinNew[i] = 0.;
00571 }
00572 }
00573
00574
00575 if( nzone==0 )
00576 {
00577 for( i=0; i < rfield.nflux; i++ )
00578 {
00579 old_OTS_line_x_opac[i] = rfield.otslinNew[i] * opac.opacity_abs[i];
00580 old_OTS_cont_x_opac[i] = rfield.otsconNew[i] * opac.opacity_abs[i];
00581 }
00582 }
00583
00584
00585 *SumOTS = 0.;
00586
00587 for( i=0; i < rfield.nflux; ++i )
00588 {
00589 double OTS_line_x_opac = rfield.otslinNew[i] * opac.opacity_abs[i];
00590 double OTS_cont_x_opac = rfield.otsconNew[i] * opac.opacity_abs[i];
00591 double CurrentInverseOpacity = 1./MAX2( SMALLDOUBLE , opac.opacity_abs[i] );
00592
00593
00594 if( OTS_line_x_opac > old_OTS_line_x_opac[i]*FacBig )
00595 {
00596 rfield.otslin[i] = rfield.otslin[i]*FacBig;
00597 }
00598 else if( OTS_line_x_opac < old_OTS_line_x_opac[i]*FacSml )
00599 {
00600 rfield.otslin[i] = rfield.otslin[i]*FacSml;
00601 }
00602 else
00603 {
00604 rfield.otslin[i] = rfield.otslinNew[i];
00605 }
00606
00607
00608 if( OTS_cont_x_opac > old_OTS_cont_x_opac[i]*FacBig )
00609 {
00610 rfield.otscon[i] = rfield.otscon[i]*FacBig;
00611 }
00612 else if( OTS_cont_x_opac < old_OTS_cont_x_opac[i]*FacSml )
00613 {
00614 rfield.otscon[i] = rfield.otscon[i]*FacSml;
00615 }
00616 else
00617 {
00618 rfield.otscon[i] = rfield.otsconNew[i];
00619 }
00620
00621
00622 rfield.otsconNew[i] = 0.;
00623
00624
00625 rfield.otslinNew[i] = 0.;
00626
00627
00628 old_OTS_line_x_opac[i] = rfield.otslin[i] * opac.opacity_abs[i];
00629 old_OTS_cont_x_opac[i] = rfield.otscon[i] * opac.opacity_abs[i];
00630
00631
00632
00633 rfield.ConOTS_local_OTS_rate[i] = (realnum)((double)rfield.ConOTS_local_photons[i]*CurrentInverseOpacity);
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 *SumOTS += (rfield.otscon[i] + rfield.otslin[i])*opac.opacity_abs[i];
00644
00645 rfield.SummedDif[i] = rfield.otscon[i] + rfield.otslin[i] + rfield.outlin_noplot[i]+
00646 rfield.ConInterOut[i]*rfield.lgOutOnly + rfield.outlin[i] +
00647 rfield.ConOTS_local_OTS_rate[i];
00648
00649 rfield.SummedCon[i] = rfield.flux[i] + rfield.SummedDif[i];
00650 rfield.SummedOcc[i] = rfield.SummedCon[i]*rfield.convoc[i];
00651
00652 }
00653
00654
00655
00656
00657 rfield.flux_accum[rfield.nflux-1] = 0;
00658 for( i=1; i < rfield.nflux; i++ )
00659 {
00660 rfield.flux_accum[rfield.nflux-i-1] = rfield.flux_accum[rfield.nflux-i] +
00661 rfield.SummedCon[rfield.nflux-i-1];
00662 }
00663
00664 ASSERT( rfield.flux_accum[0]> 0. );
00665
00666
00667
00668 ASSERT(rfield.ipPlasma>0 );
00669
00670
00671 for( i=0; i < rfield.ipPlasma-1; i++ )
00672 {
00673 rfield.otscon[i] = 0.;
00674 rfield.ConOTS_local_OTS_rate[i] = 0.;
00675 rfield.ConOTS_local_photons[i] = 0.;
00676 rfield.otslin[i] = 0.;
00677 rfield.SummedDif[i] = 0.;
00678 rfield.OccNumbBremsCont[i] = 0.;
00679 rfield.SummedCon[i] = 0.;
00680 rfield.SummedOcc[i] = 0.;
00681 rfield.ConInterOut[i] = 0.;
00682 }
00683
00684
00685 if( rfield.ipEnergyBremsThin > 0 )
00686 {
00687 for( i=rfield.ipPlasma-1; i < rfield.nflux; i++ )
00688 {
00689
00690
00691
00692
00693 realnum factor = MIN2(1.f,rfield.anu2[MAX2(0,rfield.ipEnergyBremsThin-1)] / rfield.anu2[i]);
00694
00695
00696 rfield.OccNumbBremsCont[i] = (realnum)(1./(1./SDIV(rfield.ContBoltz[i]) - 1.)) * factor;
00697 }
00698 }
00699 return;
00700
00701 # if 0
00702 OTSOld = 0.;
00703 OTSNew = 0.;
00704 BigOTSNew = 0.;
00705
00706 for( i=0; i < rfield.nflux; i++ )
00707 {
00708 OTSOld += rfield.otscon[i] + rfield.otslin[i];
00709 OTSNew += rfield.otsconNew[i] + rfield.otslinNew[i];
00710 if( BigOTSNew < rfield.otsconNew[i] + rfield.otslinNew[i] )
00711 {
00712 BigOTSNew = rfield.otsconNew[i] + rfield.otslinNew[i];
00713 }
00714 }
00715
00716
00717
00718 if( BigFrac == 0. || conv.lgSearch || OTSOld < SMALLFLOAT )
00719 {
00720
00721
00722 FracOld = 0.;
00723 }
00724 else
00725 {
00726 if( OTSNew > OTSOld )
00727 {
00728 chng = fabs(1. - OTSOld/SDIV(OTSNew) );
00729 }
00730 else
00731 {
00732 chng = fabs(1. - OTSNew/SDIV(OTSOld) );
00733 }
00734
00735 if( chng < BigFrac )
00736 {
00737
00738 FracOld = 0.;
00739 }
00740 else
00741 {
00742
00743 FracOld = (1. - BigFrac / chng);
00744 ASSERT( FracOld >= 0. );
00745 FracOld = MIN2( 0.25 , FracOld );
00746 }
00747 }
00748
00749
00750 FracNew = 1. - FracOld;
00751 fprintf(ioQQQ," DEBUG FracNew\t%.2e\n", FracNew);
00752
00753
00754 changeOTS = 0.;
00755
00756
00757 for( i=0; i < rfield.nflux; i++ )
00758 {
00759
00760 double CurrentInverseOpacity = 1./MAX2( SMALLDOUBLE , opac.opacity_abs[i] );
00761
00762
00763 if( fabs( rfield.otscon[i]+rfield.otslin[i]-rfield.otsconNew[i]-rfield.otslinNew[i])> changeOTS)
00764 {
00765 changeOTS =
00766 fabs( rfield.otscon[i]+rfield.otslin[i]-rfield.otsconNew[i]-rfield.otslinNew[i]);
00767 }
00768
00769
00770
00771
00772 if( BigFrac > 0. && conv.nTotalIoniz > 0 )
00773 {
00774
00775
00776
00777
00778
00779 rfield.otscon[i] = (realnum)((rfield.otscon[i]*FracOld +rfield.otsconNew[i]*FracNew));
00780
00781
00782
00783
00784 rfield.ConOTS_local_OTS_rate[i] = (realnum)(rfield.ConOTS_local_photons[i]*CurrentInverseOpacity);
00785
00786
00787 rfield.otslin[i] = (realnum)((rfield.otslin[i]*FracOld + rfield.otslinNew[i]*FracNew));
00788 }
00789
00790
00791 rfield.otsconNew[i] = 0.;
00792
00793
00794 rfield.otslinNew[i] = 0.;
00795
00796
00797 *SumOTS += (rfield.otscon[i] + rfield.otslin[i])*opac.opacity_abs[i];
00798 {
00799
00800
00801 enum {DEBUG_LOC=false};
00802
00803 if( DEBUG_LOC && (nzone==378) )
00804 {
00805 if( conv.nPres2Ioniz > 3 )
00806 cdEXIT( EXIT_FAILURE );
00807 fprintf(ioQQQ,"rtotsbugggg\t%li\t%.3e\t%.3e\t%.3e\t%.3e\n",
00808 conv.nPres2Ioniz,
00809 rfield.anu[i],
00810 opac.opacity_abs[i],
00811 rfield.otscon[i],
00812 rfield.otslin[i]);
00813 }
00814 }
00815
00816
00817
00818 rfield.SummedDif[i] = rfield.otscon[i] + rfield.otslin[i] + rfield.outlin_noplot[i]+
00819 rfield.ConInterOut[i]*rfield.lgOutOnly + rfield.outlin[i] +
00820 rfield.ConOTS_local_OTS_rate[i];
00821
00822 rfield.SummedCon[i] = rfield.flux[i] + rfield.SummedDif[i];
00823 rfield.SummedOcc[i] = rfield.SummedCon[i]*rfield.convoc[i];
00824 }
00825
00826 ASSERT(*SumOTS >= 0. );
00827
00828
00829
00830 rfield.flux_accum[rfield.nflux-1] = 0;
00831 for( i=1; i < rfield.nflux; i++ )
00832 {
00833 rfield.flux_accum[rfield.nflux-i-1] = rfield.flux_accum[rfield.nflux-i] +
00834 rfield.SummedCon[rfield.nflux-i-1];
00835 }
00836
00837 ASSERT( rfield.flux_accum[0]> 0. );
00838
00839
00840
00841 ASSERT(rfield.ipPlasma>0 );
00842
00843
00844 for( i=0; i < rfield.ipPlasma-1; i++ )
00845 {
00846 rfield.otscon[i] = 0.;
00847 rfield.ConOTS_local_OTS_rate[i] = 0.;
00848 rfield.ConOTS_local_photons[i] = 0.;
00849 rfield.otslin[i] = 0.;
00850 rfield.SummedDif[i] = 0.;
00851 rfield.OccNumbBremsCont[i] = 0.;
00852 rfield.SummedCon[i] = 0.;
00853 rfield.SummedOcc[i] = 0.;
00854 rfield.ConInterOut[i] = 0.;
00855 }
00856
00857
00858 if( rfield.ipEnergyBremsThin > 0 )
00859 {
00860 for( i=rfield.ipPlasma-1; i < rfield.nflux; i++ )
00861 {
00862
00863
00864
00865
00866 realnum factor = MIN2(1.f,rfield.anu2[MAX2(0,rfield.ipEnergyBremsThin-1)] / rfield.anu2[i]);
00867
00868
00869 rfield.OccNumbBremsCont[i] = (realnum)(1./(1./SDIV(rfield.ContBoltz[i]) - 1.)) * factor;
00870 }
00871 }
00872
00873 {
00874
00875
00876 enum {DEBUG_LOC=false};
00877
00878 if( DEBUG_LOC && (nzone>0) )
00879 {
00880 double BigOTS;
00881 int ipOTS=0;
00882 BigOTS = -1.;
00883
00884
00885 for( i=0; i < rfield.nflux; i++ )
00886 {
00887 if( (rfield.otscon[i] + rfield.otslin[i])*opac.opacity_abs[i] > BigOTS )
00888 {
00889 BigOTS = (rfield.otscon[i] + rfield.otslin[i])*opac.opacity_abs[i];
00890 ipOTS = (int)i;
00891 }
00892 }
00893 fprintf(ioQQQ,
00894 " sumcontinuunots zone %li SumOTS %.2e %.2eRyd opc:%.2e OTS%.2e lin%.2e con:%.2e %s %s cell%i FracNew %.2f \n",
00895 nzone,
00896 *SumOTS,
00897 rfield.anu[ipOTS] ,
00898 opac.opacity_abs[ipOTS],
00899 BigOTS ,
00900 rfield.otslin[ipOTS],
00901 rfield.otscon[ipOTS] ,
00902
00903 rfield.chLineLabel[ipOTS] ,
00904
00905 rfield.chContLabel[ipOTS] ,
00906 ipOTS,
00907 FracNew);
00908 }
00909 }
00910 return;
00911 # endif
00912 }
00913
00914
00915
00916
00917
00918 void RT_OTS_Zero( void )
00919 {
00920 long int i;
00921
00922 DEBUG_ENTRY( "RT_OTS_Zero()" );
00923
00924
00925
00926 for( i=0; i <= rfield.nflux; i++ )
00927 {
00928 rfield.SummedDif[i] = 0.;
00929
00930 rfield.otscon[i] = 0.;
00931 rfield.otslin[i] = 0.;
00932 rfield.otslinNew[i] = 0.;
00933 rfield.otsconNew[i] = 0.;
00934
00935 rfield.trans_coef_zone[i] = 1.f;
00936 rfield.trans_coef_total[i] = 1.f;
00937
00938 rfield.ConInterOut[i] = 0.;
00939 rfield.outlin[i] = 0.;
00940 rfield.outlin_noplot[i] = 0.;
00941 rfield.SummedDif[i] = 0.;
00942
00943 rfield.SummedCon[i] = rfield.flux[i];
00944 rfield.SummedOcc[i] = rfield.SummedCon[i]*rfield.convoc[i];
00945 rfield.ConOTS_local_photons[i] = 0.;
00946 rfield.ConOTS_local_OTS_rate[i] = 0.;
00947 }
00948 return;
00949 }
00950
00951
00952
00953
00954 void RT_OTS_ChkSum(long int ipPnt)
00955 {
00956 static long int nInsane=0;
00957 long int i;
00958 double phisig;
00959 # define LIM_INSAME_PRT 30
00960
00961 DEBUG_ENTRY( "RT_OTS_ChkSum()" );
00962
00963
00964
00965
00966 for( i=rfield.ipEnergyBremsThin; i < rfield.nflux; i++ )
00967 {
00968 phisig = rfield.otscon[i] + rfield.otslin[i] + rfield.ConInterOut[i]*rfield.lgOutOnly +
00969 rfield.outlin[i]+
00970 rfield.outlin_noplot[i]+
00971 rfield.ConOTS_local_OTS_rate[i];
00972
00973
00974 if( phisig > 0. && rfield.SummedDif[i]> 0.)
00975 {
00976 if( fabs(rfield.SummedDif[i]/phisig-1.) > 1e-3 )
00977 {
00978 ++nInsane;
00979
00980
00981 if( nInsane < LIM_INSAME_PRT )
00982 {
00983 fprintf( ioQQQ, " PROBLEM RT_OTS_ChkSum insane SummedDif at energy %.5e error= %.2e i=%4ld\n",
00984 rfield.anu[i], rfield.SummedDif[i]/phisig - 1., i );
00985 fprintf( ioQQQ, " SummedDif, sum are%11.4e%11.4e\n",
00986 rfield.SummedDif[i], phisig );
00987 fprintf( ioQQQ, " otscon otslin ConInterOut outlin are%11.4e%11.4e%11.4e%11.4e\n",
00988 rfield.otscon[i], rfield.otslin[i]+rfield.outlin_noplot[i], rfield.ConInterOut[i],
00989 rfield.outlin[i]+rfield.outlin_noplot[i] );
00990 fprintf( ioQQQ, " line continuum here are %4.4s %4.4s\n",
00991 rfield.chLineLabel[i], rfield.chContLabel[i] );
00992 }
00993 }
00994 }
00995
00996 phisig += rfield.flux[i];
00997
00998
00999 if( phisig > 0. && rfield.SummedDif[i]> 0. )
01000 {
01001 if( fabs(rfield.SummedCon[i]/phisig-1.) > 1e-3 )
01002 {
01003 ++nInsane;
01004
01005
01006 if( nInsane < LIM_INSAME_PRT )
01007 {
01008 fprintf( ioQQQ, " PROBLEM RT_OTS_ChkSum %3ld, insane SummedCon at energy %.5e error=%.2e i=%ld\n",
01009 ipPnt, rfield.anu[i], rfield.SummedCon[i]/phisig - 1., i );
01010 fprintf( ioQQQ, " SummedCon, sum are %.4e %.4e\n",
01011 rfield.SummedCon[i], phisig );
01012 fprintf( ioQQQ, " otscon otslin ConInterOut outlin flux are%.4e %.4e %.4e %.4e %.4e\n",
01013 rfield.otscon[i], rfield.otslin[i]+rfield.outlin_noplot[i], rfield.ConInterOut[i],
01014 rfield.outlin[i]+rfield.outlin_noplot[i], rfield.flux[i] );
01015 fprintf( ioQQQ, " line continuum here are %s %s\n",
01016 rfield.chLineLabel[i], rfield.chContLabel[i]
01017 );
01018 }
01019 }
01020 }
01021 }
01022
01023 if( nInsane > 0 )
01024 {
01025 fprintf( ioQQQ, " PROBLEM RT_OTS_ChkSum too much insanity to continue.\n");
01026
01027 TotalInsanity();
01028 }
01029 return;
01030 }
01031
01032
01033
01034
01035 void RT_OTS_PrtRate(
01036
01037 double weak ,
01038
01039 int chFlag )
01040 {
01041 long int i;
01042
01043 DEBUG_ENTRY( "RT_OTS_PrtRate()" );
01044
01045
01046 ASSERT( chFlag=='l' || chFlag=='c' || chFlag=='b' );
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 if( chFlag == 'c' || chFlag == 'b' )
01061 {
01062 fprintf( ioQQQ, " DEBUG OTSCON array, anu, otscon, opac, OTS*opac limit:%.2e zone:%.2f IonConv?%c\n",
01063 weak,fnzone ,TorF(conv.lgConvIoniz) );
01064
01065 for( i=0; i < rfield.nupper; i++ )
01066 {
01067 if( rfield.otscon[i]*opac.opacity_abs[i] > weak )
01068 {
01069 fprintf( ioQQQ, " %4ld%12.4e%12.4e%12.4e%12.4e %s \n",
01070 i,
01071 rfield.anu[i],
01072 rfield.otscon[i],
01073 opac.opacity_abs[i],
01074 rfield.otscon[i]*opac.opacity_abs[i],
01075 rfield.chContLabel[i]);
01076
01077 }
01078 }
01079 }
01080
01081
01082
01083
01084 if( chFlag == 'l' || chFlag == 'b' )
01085 {
01086 fprintf( ioQQQ, " DEBUG OTSLIN array, anu, otslin, opac, OTS*opac Lab nLine limit:%.2e zone:%.2f IonConv?%c\n",
01087 weak,fnzone,TorF(conv.lgConvIoniz) );
01088
01089 for( i=0; i < rfield.nupper; i++ )
01090 {
01091 if( rfield.otslin[i]*opac.opacity_abs[i] > weak )
01092 {
01093 fprintf( ioQQQ, " %4ld%12.4e%12.4e%12.4e%12.4e %s %3li\n",
01094 i,
01095 rfield.anu[i],
01096 rfield.otslin[i],
01097 opac.opacity_abs[i],
01098 rfield.otslin[i]*opac.opacity_abs[i],
01099 rfield.chLineLabel[i] ,
01100 rfield.line_count[i] );
01101 }
01102 }
01103 }
01104 return;
01105 }