31void iso_level(
const long int ipISO,
const long int nelem,
double &renorm)
45 double HighestPColOut = 0.;
47 valarray<int32> ipiv(numlevels_local);
85 fprintf(
ioQQQ,
" iso_level iso=%2ld nelem=%2ld simple II/I=%10.2e so not doing equilibrium, doing %s.\n",
92 for(
long n=1; n < numlevels_local; n++ )
102 creation(numlevels_local),
103 error(numlevels_local),
104 work(numlevels_local),
105 Save_creation(numlevels_local);
108 for( level=0; level < numlevels_local; level++ )
111 creation[level] = sp->
fb[level].RateCont2Level *
dense.
xIonDense[nelem][nelem+1-ipISO];
114 double ctsource=0.0, ctsink=0.0, ctrec=0.0;
162 z.
alloc(numlevels_local,numlevels_local);
164 vector<double> Boltzmann(numlevels_local-1);
165 for (
unsigned lev = 0; lev < Boltzmann.size(); ++lev)
166 Boltzmann[lev] = 1.0;
171 long SpinUsed[
NISO] = {2,1};
178 fprintf(
ioQQQ,
" iso_level iso=%2ld nelem=%2ld doing regular matrix inversion, %s\n",
186 for( level=0; level < numlevels_local; level++ )
190 z[level][level] += sp->
fb[level].RateLevel2Cont;
194 sp->
qTot2S = sp->
fb[level].ColIoniz;
200 double arg = (StElm[level].energy().K()-StElm[level-1].energy().K()) /
203 double bstep =
sexp( arg );
204 for ( ipLo = 0; ipLo < level; ++ipLo )
205 Boltzmann[ipLo] *= bstep;
209 for( ipLo=0; ipLo < level; ipLo++ )
224 coll_down *= sp->
ex[level][ipLo].ErrorFactor[
IPCOLLIS];
225 RadDecay *= sp->
ex[level][ipLo].ErrorFactor[
IPRAD];
226 pump *= sp->
ex[level][ipLo].ErrorFactor[
IPRAD];
229 double coll_up = coll_down *
230 (double)StElm[level].
g()/
231 (double)StElm[ipLo].
g()*
234 z[ipLo][ipLo] += coll_up + pump ;
235 z[ipLo][level] -= coll_up + pump ;
237 double pump_down = pump *
238 (double)StElm[ipLo].
g()/
239 (double)StElm[level].
g();
241 z[level][level] += RadDecay + pump_down + coll_down;
242 z[level][ipLo] -= RadDecay + pump_down + coll_down;
244 if( level == indexNmaxP )
246 HighestPColOut += coll_down;
248 if( ipLo == indexNmaxP )
250 HighestPColOut += coll_up;
254 if( (level == 1) && (ipLo==0) )
258 if( (ipLo == 1) && (ipISO==
ipH_LIKE || StElm[level].S()==1) )
270 if( HighestPColOut < 1./sp->st[indexNmaxP].lifetime() )
278 for( vector<two_photon>::iterator tnu = sp->
TwoNu.begin(); tnu != sp->
TwoNu.end(); ++tnu )
286 z[tnu->ipHi][tnu->ipLo] -= tnu->AulTotal;
287 z[tnu->ipHi][tnu->ipHi] += tnu->AulTotal;
293 for( vector<two_photon>::iterator tnu = sp->
TwoNu.begin(); tnu != sp->
TwoNu.end(); ++tnu )
299 z[tnu->ipHi][tnu->ipLo] -= tnu->induc_dn;
300 z[tnu->ipHi][tnu->ipHi] += tnu->induc_dn;
303 z[tnu->ipLo][tnu->ipHi] -= tnu->induc_up;
304 z[tnu->ipLo][tnu->ipLo] += tnu->induc_up;
311 if( ion!=nelem-ipISO )
346 for( level=0; level < numlevels_local; level++ )
363 if( ion_from == nelem-1-ipISO )
371 for( level=0; level < numlevels_local; level++ )
373 z[level][level] +=
sink;
381 for ( level = 0; level < numlevels_local; level++ )
383 partfun += sp->
st[level].Boltzmann()*sp->
st[level].g();
386 for( level=0; level < numlevels_local; level++ )
388 creation[level] +=
source*
389 sp->
st[level].Boltzmann()*sp->
st[level].g();
390 z[level][level] +=
sink;
393 creation[0] += ctsource;
400 for( level=1; level < numlevels_local; level++ )
402 double RateUp , RateDown;
405 RateDown = RateUp * (double)sp->
st[
ipH1s].g() /
406 (double)sp->
st[level].g();
412 z[level][
ipH1s] -= RateDown;
415 z[
ipH1s][level] -= RateUp;
417 z[level][level] += RateDown;
429 for( ipLo=0; ipLo < numlevels_local; ipLo++ )
430 Save_creation[ipLo] = creation[ipLo];
434 const long numlevels_print = numlevels_local;
435 fprintf(
ioQQQ,
" pop level others => (iso_level)\n" );
436 for(
long n=0; n < numlevels_print; n++ )
439 for(
long j=0; j < numlevels_print; j++ )
441 fprintf(
ioQQQ,
"\t%.9e", z[j][n] );
443 fprintf(
ioQQQ,
"\n" );
445 fprintf(
ioQQQ,
" recomb ct %.2e co %.2e hectr %.2e hctr %.2e\n",
450 fprintf(
ioQQQ,
" recomb ");
451 for(
long n=0; n < numlevels_print; n++ )
453 fprintf(
ioQQQ,
"\t%.9e", creation[n] );
455 fprintf(
ioQQQ,
"\n" );
461 z.
data(),numlevels_local,&ipiv[0],&nerror);
464 &creation[0],numlevels_local,&nerror);
468 fprintf(
ioQQQ,
" iso_level: dgetrs finds singular or ill-conditioned matrix\n" );
474 for( level=
ipH1s; level < numlevels_local; level++ )
476 double qn = 0., qx = 0.;
478 for(
long n=
ipH1s; n < numlevels_local; n++ )
480 double q = SaveZ[n][level]*creation[n];
496 error[level] = (error[level] - Save_creation[level])/qx;
508 for( level=
ipH1s; level < numlevels_local; level++ )
511 abserror = fabs( error[level]);
513 if( abserror > BigError )
522 if( BigError > FLT_EPSILON )
525 fprintf(
ioQQQ,
" PROBLEM" );
528 " iso_level zone %.2f - largest residual in iso=%li %s nelem=%li matrix inversion is %g "
529 "level was %li Search?%c \n",
544 for ( level = 0; level < numlevels_local; level++ )
546 partfun += sp->
st[level].Boltzmann()*sp->
st[level].g();
549 for ( level = 0; level < numlevels_local; level++ )
551 creation[level] = sp->
st[level].Boltzmann()*sp->
st[level].g()*scale;
555 for( level = numlevels_local-1; level > 0; --level )
558 if( creation[level] < 0. )
567 for( level = 1; level < numlevels_local; ++level )
568 creation[level] = 0.;
575 for( level=0; level < numlevels_local; level++ )
577 ASSERT( creation[level] >= 0. );
578 sp->
st[level].Pop() = creation[level];
583 "PROBLEM non-positive level pop for iso = %li, nelem = "
584 "%li = %s, level=%li val=%.3e nTotalIoniz %li\n",
589 sp->
st[level].Pop() ,
595 for( level=numlevels_local; level < sp->
numLevels_max; level++ )
597 sp->
st[level].Pop() = 0.;
606 double TotalPopExcited = 0.;
608 for( level=1; level < numlevels_local; level++ )
609 TotalPopExcited += sp->
st[level].Pop();
610 ASSERT( TotalPopExcited >= 0. );
611 double TotalPop = TotalPopExcited + sp->
st[0].Pop();
620 for( level=0; level < numlevels_local; level++ )
621 sp->
st[level].Pop() *=
641 " DISASTER iso_level finds negative ion fraction for iso=%2ld nelem=%2ld "\
642 "%s using solver %s, IonFrac=%.3e simple=%.3e TE=%.3e ZONE=%4ld\n",
652 fprintf(
ioQQQ,
" level pop are:\n" );
653 for( i=0; i < numlevels_local; i++ )
656 if( (i!=0) && !(i%10) ) fprintf(
ioQQQ,
"\n" );
658 fprintf(
ioQQQ,
"\n" );
664 for( ipHi=1; ipHi<numlevels_local; ++ipHi )
666 for( ipLo=0; ipLo<ipHi; ++ipLo )
673 sp->
st[ipLo].Pop() - sp->
st[ipHi].Pop()*
674 sp->
st[ipLo].g()/sp->
st[ipHi].g();
692 double TotalPop = 0.;
694 for(
long level=0; level < numlevels_local; level++ )
699 sp->
st[level].Pop() * sp->
fb[level].RateLevel2Cont;
700 TotalPop += sp->
st[level].Pop();
705 fprintf(
ioQQQ,
"DISASTER RateIonizTot for Z=%li, ion %li is larger than BIGDOUBLE. This is a big problem.",
706 nelem+1, nelem-ipISO);
729 ratio = rateOutOf2TripS /
sys_float sexp(sys_float x)
bool fp_equal(sys_float x, sys_float y, int n=3)
sys_float SDIV(sys_float x)
#define DEBUG_ENTRY(funcname)
realnum rate_lu_nontherm() const
realnum ColUL(const ColliderList &colls) const
realnum & Pelec_esc() const
realnum GrainChTrRate[LIMELM][LIMELM+1][LIMELM+1]
CollisionProxy Coll() const
EmissionList::reference Emis() const
double *** CollIonRate_Ground
double RateIonizTot(long nelem, long ion)
multi_arr< extra_tr, 2 > ex
TransitionProxy trans(const long ipHi, const long ipLo)
long int n_HighestResolved_local
vector< two_photon > TwoNu
multi_arr< long, 3 > QuantumNumbers2Index
bool lgCritDensLMix[NISO]
realnum *** xMoleChTrRate
t_elementnames elementnames
t_iso_sp iso_sp[NISO][LIMELM]
void iso_renorm(long nelem, long ipISO, double &renorm)
#define KILL_BELOW_PLASMA(E_)
void iso_level(const long int ipISO, const long int nelem, double &renorm)
void iso_set_ion_rates(long ipISO, long nelem)
molezone * findspecieslocal(const char buf[])
double CharExcRecTo[NCX][LIMELM][LIMELM+1]
double CharExcIonOf[NCX][LIMELM][LIMELM+1]
double CharExcRecTotal[NCX]
double CharExcIonTotal[NCX]
long int IonLow[LIMELM+1]
long int IonHigh[LIMELM+1]
double xIonDense[LIMELM][LIMELM+1]
char chElementSym[LIMELM][CHARS_ELEMENT_SYM]
char chElementNameShort[LIMELM][CHARS_ELEMENT_NAME_SHORT]
char chElementName[LIMELM][CHARS_ELEMENT_NAME]
double frac_he0dest_23S_photo
bool lgIsoTraceFull[NISO]
long int ipIsoTrace[NISO]
void getrs_wrapper(char trans, long N, long nrhs, double *A, long lda, int32 *ipiv, double *B, long ldb, int32 *info)
void getrf_wrapper(long M, long N, double *A, long lda, int32 *ipiv, int32 *info)