00001
00002
00003
00004
00005 #include "cddefines.h"
00006 #include "physconst.h"
00007 #include "iso.h"
00008 #include "grainvar.h"
00009 #include "ca.h"
00010 #include "rfield.h"
00011 #include "oxy.h"
00012 #include "mole.h"
00013 #include "dense.h"
00014 #include "atoms.h"
00015 #include "conv.h"
00016 #include "ionbal.h"
00017 #include "trace.h"
00018 #include "hmi.h"
00019 #include "phycon.h"
00020 #include "opacity.h"
00021
00022 void OpacityAddTotal(void)
00023 {
00024 long int i,
00025 ion,
00026 ipHi,
00027 ipISO,
00028 ipop,
00029 limit,
00030 low,
00031 nelem,
00032 n;
00033 double DepartCoefInv ,
00034 fac,
00035 sum;
00036 realnum SaveOxygen1 ,
00037 SaveCarbon1;
00038
00039 DEBUG_ENTRY( "OpacityAddTotal()" );
00040
00041
00042
00043 OpacityZero();
00044
00045
00046
00047
00048 for( i=0; i < rfield.nflux; i++ )
00049 {
00050
00051 opac.opacity_sct[i] += opac.OpacStack[i-1+opac.iopcom]*
00052 dense.eden;
00053 }
00054
00055
00056
00057
00058 for( nelem=ipHYDROGEN; nelem<LIMELM; ++nelem )
00059 {
00060 if( dense.lgElmtOn[nelem] )
00061 {
00062 for( ion=0; ion<nelem+1; ++ion )
00063 {
00064 realnum factor = dense.xIonDense[nelem][ion];
00065
00066
00067
00068 if( nelem==ipHYDROGEN )
00069 factor += hmi.H2_total*2.f;
00070 if( factor > 0. )
00071 {
00072
00073 long loop_min = ionbal.ipCompRecoil[nelem][ion]-1;
00074 long loop_max = rfield.nflux;
00075
00076
00077 factor *= ionbal.nCompRecoilElec[nelem-ion];
00078 for( i=loop_min; i < loop_max; i++ )
00079 {
00080
00081 opac.opacity_abs[i] += opac.OpacStack[i-1+opac.iopcom]*factor;
00082 }
00083 }
00084 }
00085 }
00086 }
00087
00088
00089
00091 sum = dense.gas_phase[ipHYDROGEN] + 4.*dense.gas_phase[ipHELIUM];
00092 OpacityAdd1Subshell(opac.ioppr,opac.ippr,rfield.nflux,(realnum)sum,'s');
00093
00094
00095
00096
00097
00098
00099 static double *TotBremsAllIons;
00100 static bool lgFirstTime=true;
00101 double BremsThisEner,bfac, bhfac,sumion[LIMELM+1];
00102 long int ion_lo , ion_hi;
00103
00104 if( lgFirstTime )
00105 {
00106
00107 TotBremsAllIons = (double *)MALLOC((unsigned long)rfield.nupper*sizeof(double));
00108 lgFirstTime = false;
00109 }
00110 bfac = (dense.eden/1e20)/phycon.sqrte/1e10;
00111
00112
00113 sumion[0] = 0.;
00114 for(ion=1; ion<=LIMELM; ++ion )
00115 {
00116 sumion[ion] = 0.;
00117 for( nelem=ipHELIUM; nelem < LIMELM; ++nelem )
00118 {
00119 if( dense.lgElmtOn[nelem] && ion<=nelem+1 )
00120 {
00121 sumion[ion] += dense.xIonDense[nelem][ion];
00122 }
00123 }
00124
00125 sumion[ion] *= POW2((double)ion)*bfac;
00126 }
00127
00128
00129
00130
00131 ion_lo = 1;
00132 while( sumion[ion_lo]==0 && ion_lo<LIMELM-1 )
00133 ++ion_lo;
00134 ion_hi = LIMELM;
00135 while( sumion[ion_hi]==0 && ion_hi>0 )
00136 --ion_hi;
00137
00138 bhfac = bfac*(dense.xIonDense[ipHYDROGEN][1]+hmi.Hmolec[ipMH2p]+hmi.Hmolec[ipMH3p]);
00139 for( i=0; i < rfield.nflux; i++ )
00140 {
00141
00142 nelem = ipHYDROGEN;
00143 ion = 1;
00144
00145
00146
00147 BremsThisEner = bhfac * rfield.gff[ion][i]*
00148 (1.+opac.OpacStack[i-1+opac.iphmra]*StatesElem[ipH_LIKE][ipHYDROGEN][ipH1s].Pop);
00149
00150
00151
00152
00153
00154
00155
00156
00157 for(ion=ion_lo; ion<=ion_hi; ++ion )
00158 {
00159 BremsThisEner += sumion[ion]*rfield.gff[ion][i];
00160 }
00161 TotBremsAllIons[i] = BremsThisEner;
00162
00163
00164 if( rfield.ContBoltz[i] < 0.995 )
00165 {
00166 TotBremsAllIons[i] *= opac.OpacStack[i-1+opac.ipBrems]*
00167 (1. - rfield.ContBoltz[i]);
00168 }
00169 else
00170 {
00171 TotBremsAllIons[i] *= opac.OpacStack[i-1+opac.ipBrems]*
00172 rfield.anu[i]*TE1RYD/phycon.te;
00173 }
00174 opac.FreeFreeOpacity[i] = TotBremsAllIons[i];
00175
00176
00177
00178 opac.opacity_abs[i] += opac.FreeFreeOpacity[i];
00179 }
00180
00181
00182
00183 if( hmi.hmidep > SMALLFLOAT )
00184 {
00185 DepartCoefInv = 1./hmi.hmidep;
00186 }
00187 else
00188 {
00189
00190
00191 DepartCoefInv = 1.;
00192 }
00193
00194 limit = iso.ipIsoLevNIonCon[ipHE_LIKE][ipHELIUM][0];
00195 if(limit > rfield.nflux)
00196 limit = rfield.nflux;
00197
00198 for( i=hmi.iphmin-1; i < limit; i++ )
00199 {
00200 double factor;
00201 factor = 1. - rfield.ContBoltz[i]*DepartCoefInv;
00202 if(factor > 0)
00203 opac.opacity_abs[i] += opac.OpacStack[i-hmi.iphmin+opac.iphmop]*
00204 hmi.Hmolec[ipMHm]*factor;
00205 }
00206
00207
00208 limit = opac.ih2pnt[1];
00209 if(limit > rfield.nflux)
00210 limit = rfield.nflux;
00211 for( i=opac.ih2pnt[0]-1; i < limit; i++ )
00212 {
00213 opac.opacity_abs[i] += hmi.Hmolec[ipMH2p]*opac.OpacStack[i-opac.ih2pnt[0]+opac.ih2pof];
00214 }
00215
00216
00217 if( dense.xIonDense[ipHYDROGEN][1] <= 0. )
00218 {
00219 fac = dense.xIonDense[ipHYDROGEN][0];
00220 }
00221 else
00222 {
00223 fac = dense.xIonDense[ipHYDROGEN][1]*StatesElem[ipH_LIKE][ipHYDROGEN][ipH1s].Pop;
00224 }
00225
00226
00227 limit = iso.ipIsoLevNIonCon[ipH_LIKE][ipHYDROGEN][ipH1s];
00228 if(limit > rfield.nflux)
00229 limit = rfield.nflux;
00230 for( i=0; i < limit; i++ )
00231 {
00232 opac.opacity_sct[i] += (fac*opac.OpacStack[i-1+opac.ipRayScat]);
00233 }
00234
00235
00236 if( iso.DepartCoef[ipH_LIKE][ipHYDROGEN][ipH1s] > 1e-30 && !conv.lgSearch )
00237 {
00238 realnum factor;
00239 factor = (realnum)(rfield.ContBoltz[iso.ipIsoLevNIonCon[ipH_LIKE][ipHYDROGEN][ipH1s]-1]/iso.DepartCoef[ipH_LIKE][ipHYDROGEN][ipH1s]);
00240 if(opac.stimax[0] < factor)
00241 opac.stimax[0] = factor;
00242 }
00243
00244 if( iso.DepartCoef[ipH_LIKE][ipHYDROGEN][ipH2p] > 1e-30 && !conv.lgSearch )
00245 {
00246 realnum factor;
00247 factor = (realnum)(rfield.ContBoltz[iso.ipIsoLevNIonCon[ipH_LIKE][ipHYDROGEN][ipH2p]-1]/iso.DepartCoef[ipH_LIKE][ipHYDROGEN][ipH2p]);
00248 if(opac.stimax[1] < factor)
00249 opac.stimax[1] = factor;
00250 }
00251
00252 # if 0
00253
00254 if( !conv.lgSearch )
00255 {
00256 if( Transitions[ipH_LIKE][ipHYDROGEN][ipH2p][ipH1s].PopOpc < 0. )
00257 {
00258 hydro.lgHLyaMased = true;
00259 }
00260 }
00261 # endif
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 low = opac.ipH2_photo_thresh;
00272 ipHi = rfield.nupper;
00273 ipop = opac.ipH2_photo_opac_offset;
00274
00275
00276
00277
00278 OpacityAdd1Subshell( ipop , low , ipHi , hmi.H2_total , 's' );
00279
00280
00281
00282
00283
00284
00285 SaveOxygen1 = dense.xIonDense[ipOXYGEN][0];
00286 SaveCarbon1 = dense.xIonDense[ipCARBON][0];
00287 dense.xIonDense[ipOXYGEN][0] += findspecies("CO")->hevmol + findspecies("H2Ogrn")->hevmol;
00288 dense.xIonDense[ipCARBON][0] += findspecies("CO")->hevmol;
00289
00290
00291
00292 for( nelem=ipHYDROGEN; nelem < LIMELM; nelem++ )
00293 {
00294
00295 if( dense.lgElmtOn[nelem] )
00296 {
00297 OpacityAdd1Element(nelem);
00298 }
00299 }
00300
00301
00302 dense.xIonDense[ipOXYGEN][0] = SaveOxygen1;
00303 dense.xIonDense[ipCARBON][0] = SaveCarbon1;
00304
00305
00306
00307
00308
00309 OpacityAdd1Subshell(opac.in1[2],opac.in1[0],opac.in1[1],
00310 dense.xIonDense[ipNITROGEN][0]*atoms.p2nit , 'v' );
00311
00312
00313
00314 OpacityAdd1Subshell(opac.ipo1exc[2],opac.ipo1exc[0],opac.ipo1exc[1],
00315 dense.xIonDense[ipOXYGEN][0]*oxy.poiexc,'v');
00316
00317
00318 OpacityAdd1Subshell(opac.ipo3exc[2],opac.ipo3exc[0],opac.ipo3exc[1],
00319 dense.xIonDense[ipOXYGEN][2]*oxy.poiii2,'v');
00320
00321 OpacityAdd1Subshell(opac.ipo3exc3[2],opac.ipo3exc3[0],opac.ipo3exc3[1],
00322 dense.xIonDense[ipOXYGEN][2]*oxy.poiii3,'v');
00323
00324
00325
00326 OpacityAdd1Subshell(opac.ipOpMgEx,opac.ipmgex,iso.ipIsoLevNIonCon[ipH_LIKE][ipHYDROGEN][ipH1s],
00327 dense.xIonDense[ipMAGNESIUM][1]* atoms.popmg2,'v');
00328
00329
00330
00331 OpacityAdd1Subshell(opac.ica2op,opac.ica2ex[0],opac.ica2ex[1],
00332 ca.popca2ex,'v');
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 for( ipISO=ipH_LIKE; ipISO<NISO; ++ipISO )
00345 {
00346 for( nelem=ipISO; nelem < LIMELM; nelem++ )
00347 {
00348
00349 if( dense.lgElmtOn[nelem] )
00350 {
00351
00352 if( nzone < 1 )
00353 {
00354
00355 for( n=0; n < iso.numLevels_local[ipISO][nelem]; n++ )
00356 {
00357 if(iso.ipIsoLevNIonCon[ipISO][nelem][n] < rfield.nflux )
00358 {
00359
00360
00361
00362
00363 if( opac.opacity_abs[iso.ipIsoLevNIonCon[ipISO][nelem][n]-1] > 0. )
00364 {
00365
00366
00367 long int ip = iso.ipIsoLevNIonCon[ipISO][nelem][n];
00368 double t2 = csphot(
00369 ip ,
00370 ip ,
00371 iso.ipOpac[ipISO][nelem][n] );
00372
00373 iso.ConOpacRatio[ipISO][nelem][n] = 1.f-(realnum)(
00374 (StatesElem[ipISO][nelem][n].Pop*dense.xIonDense[nelem][nelem+1-ipISO]*t2)/
00375 opac.opacity_abs[ip-1]);
00376 }
00377 else
00378 {
00379 iso.ConOpacRatio[ipISO][nelem][n] = 0.;
00380 }
00381 }
00382 }
00383 }
00384
00385
00386 for( n=0; n < iso.numLevels_local[ipISO][nelem]; n++ )
00387 {
00388
00389 if(iso.ipIsoLevNIonCon[ipISO][nelem][n] < rfield.nflux )
00390 {
00391
00392
00393
00394
00395 if( opac.opacity_abs[iso.ipIsoLevNIonCon[ipISO][nelem][n]-1] > 0. )
00396 {
00397
00398 if( iso.DepartCoef[ipISO][nelem][n] > 1e-30 && (!conv.lgSearch ) )
00399 {
00400
00401 fac = 1./iso.DepartCoef[ipISO][nelem][n];
00402 }
00403 else if( conv.lgSearch )
00404 {
00405
00406
00407 fac = 0.;
00408 }
00409 else
00410 {
00411 fac = 1.;
00412 }
00413
00416
00417
00418
00419
00420
00421 if( opac.opacity_abs[iso.ipIsoLevNIonCon[ipISO][nelem][n]-1] > 0. )
00422 {
00423
00424 long int ip = iso.ipIsoLevNIonCon[ipISO][nelem][n];
00425
00426 double t2 = csphot(
00427 ip ,
00428 ip ,
00429 iso.ipOpac[ipISO][nelem][n] );
00430
00431 double opacity_this_species =
00432 StatesElem[ipISO][nelem][n].Pop*dense.xIonDense[nelem][nelem+1-ipISO]*t2*
00433 (1. - fac*rfield.ContBoltz[ip-1]);
00434
00435 double opacity_fraction = 1. - opacity_this_species / opac.opacity_abs[ip-1];
00436 if(opacity_fraction < 0)
00437 opacity_fraction = 0.;
00438
00439
00440 iso.ConOpacRatio[ipISO][nelem][n] = (realnum)(
00441 iso.ConOpacRatio[ipISO][nelem][n]* 0.75 + 0.25*opacity_fraction );
00442
00443 if(iso.ConOpacRatio[ipISO][nelem][n] < 0.)
00444 iso.ConOpacRatio[ipISO][nelem][n] = 0.;
00445 }
00446 else
00447 {
00448 iso.ConOpacRatio[ipISO][nelem][n] = 0.;
00449 }
00450 }
00451 else
00452 {
00453 iso.ConOpacRatio[ipISO][nelem][n] = 0.;
00454 }
00455 }
00456 else
00457 {
00458 iso.ConOpacRatio[ipISO][nelem][n] = 0.;
00459 }
00460 }
00461 }
00462 }
00463 }
00464
00465
00466 if( gv.lgDustOn )
00467 {
00468
00469
00470 for( i=0; i < rfield.nflux; i++ )
00471 {
00472
00473 opac.opacity_sct[i] += gv.dstsc[i]*dense.gas_phase[ipHYDROGEN];
00474 opac.opacity_abs[i] += gv.dstab[i]*dense.gas_phase[ipHYDROGEN];
00475 }
00476 }
00477
00478
00479 for( i=0; i < rfield.nflux; i++ )
00480 {
00481
00482 opac.opacity_abs[i] += opac.OpacStatic[i];
00483
00484
00485 }
00486
00487
00488 for( i=0; i < rfield.nflux; i++ )
00489 {
00490 opac.albedo[i] = opac.opacity_sct[i]/
00491 (opac.opacity_sct[i] + opac.opacity_abs[i]);
00492 }
00493
00494
00495 if( conv.lgSearch )
00496 OpacityZeroOld();
00497
00498 if( trace.lgTrace )
00499 {
00500 fprintf( ioQQQ, " OpacityAddTotal returns; grd rec eff (opac) for Hn=1,4%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e%10.2e HeI,II:%10.2e%10.2e\n",
00501 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH1s],
00502 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH2s],
00503 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH2p],
00504 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH3s],
00505 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH3p],
00506 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH3d],
00507 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH4s],
00508 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH4p],
00509 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH4d],
00510 iso.ConOpacRatio[ipH_LIKE][ipHYDROGEN][ipH4f],
00511 iso.ConOpacRatio[ipHE_LIKE][ipHELIUM][ipHe1s1S],
00512 iso.ConOpacRatio[ipH_LIKE][ipHELIUM][ipH1s] );
00513 }
00514 {
00515
00516
00517 enum {DEBUG_LOC=false};
00518
00519 if( DEBUG_LOC && (nzone>=378) )
00520 {
00521 if( nzone > 380 )
00522 cdEXIT( EXIT_FAILURE );
00523 for( i=0; i<rfield.nflux; ++i )
00524 {
00525 fprintf(ioQQQ,"rtotsbugggg\t%li\t%.3e\t%.3e\t%.3e\t%.3e\n",
00526 conv.nPres2Ioniz,
00527 rfield.anu[i],
00528 opac.opacity_abs[i],
00529 rfield.otscon[i],
00530 rfield.otslin[i]);
00531 }
00532 }
00533 }
00534 return;
00535 }