29         const long int ipISO, 
const long int nelem);
 
   32 void iso_level( 
const long int ipISO, 
const long int nelem, 
double &renorm,
 
   47         double HighestPColOut = 0.;
 
   49         static vector<int32> ipiv;
 
   50         ipiv.resize(numlevels_local); 
 
   52         double source=0., sink=0.;
 
   53         static vector<double> PopPerN;
 
   88                         fprintf( 
ioQQQ, 
"     iso_level iso=%2ld nelem=%2ld simple II/I=%10.2e so not doing equilibrium, doing %s.\n", 
 
   95                 for( 
long n=1; n < numlevels_local; n++ )
 
  104                 static vector<double> creation, error, work, Save_creation;
 
  105                 creation.resize(numlevels_local);
 
  106                 error.resize(numlevels_local);
 
  107                 work.resize(numlevels_local);
 
  108                 Save_creation.resize(numlevels_local);
 
  111                 for( level=0; level < numlevels_local; level++ )
 
  114                         creation[level] = sp->
fb[level].RateCont2Level * 
dense.
xIonDense[nelem][nelem+1-ipISO];
 
  117                 double ctsource=0.0, ctsink=0.0, ctrec=0.0;
 
  165                 z.
alloc(numlevels_local,numlevels_local);
 
  171                 long SpinUsed[
NISO] = {2,1};
 
  178                         fprintf( 
ioQQQ, 
"     iso_level iso=%2ld nelem=%2ld doing regular matrix inversion, %s\n", 
 
  184                 static vector<double> Boltzmann_overg;
 
  185                 Boltzmann_overg.resize(numlevels_local-1);
 
  186                 for (
unsigned lev = 0; lev < Boltzmann_overg.size(); ++lev)
 
  187                         Boltzmann_overg[lev] = 1.0/(
double)StElm[lev].g();
 
  192                 static vector<double> coll_down, RadDecay, pump;
 
  193                 coll_down.resize(numlevels_local);
 
  194                 RadDecay.resize(numlevels_local);
 
  195                 pump.resize(numlevels_local);
 
  198                 for( level=1; level < numlevels_local; level++ )
 
  200                         fixit(
"Wouldn't need to mask this out if levels were in order");
 
  203                 vexp( arg.ptr0(), bstep.
ptr0(), 1, numlevels_local );
 
  207                 enum { DEBUG_RATES = 
false };
 
  210                         fprintf( stdout, 
"# ipISO\tnelem\tlevel\tcollDown\tcollIonz\tradRecom\tRadDecay\n" );
 
  213                 for( level=0; level < numlevels_local; level++ )
 
  215                         double coll_down_total = 0.;
 
  219                         z[level][level] += sp->
fb[level].RateLevel2Cont;
 
  223                                 for ( ipLo = 0; ipLo < level; ++ipLo )
 
  224                                         Boltzmann_overg[ipLo] *= bstep[level];
 
  228                         for( ipLo=0; ipLo < level; ipLo++ )
 
  233                                         coll_down_total += coll_down[ipLo];
 
  251                                 for( ipLo=0; ipLo < level; ipLo++ )
 
  253                                         coll_down[ipLo] *= sp->
ex[level][ipLo].ErrorFactor[
IPCOLLIS];
 
  254                                         RadDecay[ipLo] *= sp->
ex[level][ipLo].ErrorFactor[
IPRAD];
 
  255                                         pump[ipLo] *= sp->
ex[level][ipLo].ErrorFactor[
IPRAD];
 
  259                         double glev = (double)StElm[level].g(), rglev = 1.0/glev;
 
  260                         for( ipLo=0; ipLo < level; ipLo++ )
 
  262                                 double coll_up = coll_down[ipLo] * glev *
 
  263                                         Boltzmann_overg[ipLo];
 
  265                                 z[ipLo][ipLo] += coll_up + pump[ipLo] ;
 
  266                                 z[ipLo][level] -= coll_up + pump[ipLo] ;
 
  268                                 double pump_down = pump[ipLo] *
 
  269                                         (double)StElm[ipLo].g() * rglev;
 
  271                                 z[level][level] += RadDecay[ipLo] + pump_down + coll_down[ipLo];
 
  272                                 z[level][ipLo] -= RadDecay[ipLo] + pump_down + coll_down[ipLo];
 
  273                                 if( level == indexNmaxP )
 
  275                                         HighestPColOut += coll_down[ipLo];
 
  277                                 if( ipLo == indexNmaxP )
 
  279                                         HighestPColOut += coll_up;
 
  283                                 if( (level == 1) && (ipLo==0) )
 
  287                                 if( (ipLo == 1) && (ipISO==
ipH_LIKE || StElm[level].S()==1) )
 
  305                                         1. / 
iso_sp[ipISO][nelem].
st[level].lifetime() );
 
  317                         if( HighestPColOut < 1./sp->st[indexNmaxP].lifetime() )
 
  325                 for( vector<two_photon>::iterator tnu = sp->
TwoNu.begin(); tnu != sp->
TwoNu.end(); ++tnu )
 
  331                         fixit(
"need Pesc or the equivalent to multiply AulTotal?");
 
  333                         z[tnu->ipHi][tnu->ipLo] -= tnu->AulTotal;
 
  334                         z[tnu->ipHi][tnu->ipHi] += tnu->AulTotal; 
 
  340                         for( vector<two_photon>::iterator tnu = sp->
TwoNu.begin(); tnu != sp->
TwoNu.end(); ++tnu )
 
  346                                 z[tnu->ipHi][tnu->ipLo] -= tnu->induc_dn;
 
  347                                 z[tnu->ipHi][tnu->ipHi] += tnu->induc_dn;
 
  350                                 z[tnu->ipLo][tnu->ipHi] -= tnu->induc_up;
 
  351                                 z[tnu->ipLo][tnu->ipLo] += tnu->induc_up;
 
  358                         if( ion!=nelem-ipISO )
 
  373                 sink += 
mole.
sink[nelem][nelem-ipISO];
 
  395                         for( level=0; level < numlevels_local; level++ )
 
  412                         if( ion_from == nelem-1-ipISO )
 
  423                         creation[0] += source;
 
  436                         for ( level = 0; level < numlevels_local; level++ )
 
  441                         for( level=0; level < numlevels_local; level++ )
 
  443                                 creation[level] += source*
 
  445                                 z[level][level] += sink;
 
  448                 creation[0] += ctsource;
 
  455                         for( level=1; level < numlevels_local; level++ )
 
  457                                 double RateUp , RateDown;
 
  460                                 RateDown = RateUp * (double)sp->
st[
ipH1s].g() /
 
  461                                         (double)sp->
st[level].g();
 
  467                                 z[level][
ipH1s] -= RateDown;
 
  470                                 z[
ipH1s][level] -= RateUp;
 
  472                                 z[level][level] += RateDown;  
 
  484                 for( ipLo=0; ipLo < numlevels_local; ipLo++ )
 
  485                         Save_creation[ipLo] = creation[ipLo];
 
  489                         const long numlevels_print = numlevels_local;
 
  491                         for( 
long n=0; n < numlevels_print; n++ )
 
  494                                 for( 
long j=0; j < numlevels_print; j++ )
 
  500                         fprintf(
ioQQQ,
" recomb ct %.2e co %.2e hectr %.2e hctr %.2e\n",
 
  506                         for( 
long n=0; n < numlevels_print; n++ )
 
  516                         valarray<double> c( 
get_ptr(creation), creation.size() );
 
  523                                                   z.
data(),numlevels_local,&ipiv[0],&nerror);
 
  526                                                   &creation[0],numlevels_local,&nerror);
 
  530                         fprintf( 
ioQQQ, 
" iso_level: dgetrs finds singular or ill-conditioned matrix\n" );
 
  536                 for( level=
ipH1s; level < numlevels_local; level++ )
 
  538                         double qn = 0., qx = 0.;
 
  540                         for( 
long n=
ipH1s; n < numlevels_local; n++ )
 
  542                                 double q = SaveZ[n][level]*creation[n];
 
  558                                 error[level] = (error[level] - Save_creation[level])/qx;
 
  570                 for( level=
ipH1s; level < numlevels_local; level++ )
 
  573                         abserror = fabs( error[level]);
 
  575                         if( abserror > BigError )
 
  584                 if( BigError > FLT_EPSILON ) 
 
  590                                 " iso_level zone %.2f - largest residual in iso=%li %s nelem=%li matrix inversion is %g " 
  591                                 "level was %li Search?%c \n", 
 
  606                         for ( level = 0; level < numlevels_local; level++ )
 
  611                         for ( level = 0; level < numlevels_local; level++ )
 
  613                                 creation[level] = sp->
st[level].
Boltzmann()*sp->
st[level].g()*scale;
 
  617                 for( level = numlevels_local-1; level > 0; --level )
 
  620                         if( creation[level] < 0. )
 
  629                         for( level = 1; level < numlevels_local; ++level )
 
  630                                 creation[level] = 0.;
 
  637                 for( level=0; level < numlevels_local; level++ )
 
  639                         ASSERT( creation[level] >= 0. );
 
  640                         sp->
st[level].Pop() = creation[level];
 
  645                                         "PROBLEM non-positive level pop for iso = %li, nelem = " 
  646                                         "%li = %s, level=%li val=%.3e nTotalIoniz %li\n", 
 
  651                                         sp->
st[level].Pop() ,
 
  657                 for( level=numlevels_local; level < sp->
numLevels_max; level++ )
 
  659                         sp->
st[level].Pop() = 0.;
 
  668                 double TotalPopExcited = 0.;
 
  670                 for( level=1; level < numlevels_local; level++ )
 
  671                         TotalPopExcited += sp->
st[level].Pop();
 
  672                 ASSERT( TotalPopExcited >= 0. );
 
  673                 double TotalPop = TotalPopExcited + sp->
st[0].Pop();
 
  682                                         for( level=0; level < numlevels_local; level++ )
 
  683                                                 sp->
st[level].Pop() *=
 
  703                         " DISASTER iso_level finds negative ion fraction for iso=%2ld nelem=%2ld " 
  704                         "%s using solver %s, IonFrac=%.3e simple=%.3e TE=%.3e ZONE=%4ld\n", 
 
  715                 for( i=0; i < numlevels_local; i++ )
 
  726         for( ipHi=1; ipHi<numlevels_local; ++ipHi )
 
  728                 for( ipLo=0; ipLo<ipHi; ++ipLo )
 
  735                                 sp->
st[ipLo].Pop() - sp->
st[ipHi].Pop()*
 
  736                                 sp->
st[ipLo].g()/sp->
st[ipHi].g();
 
  745         for( ipHi=numlevels_local; ipHi < sp->
numLevels_max; ++ipHi )
 
  747                 for( ipLo=0; ipLo<ipHi; ++ipLo )
 
  774         const long int ipISO, 
const long int nelem)
 
  782         for( 
long n=2; n <= nMax; ++n )
 
  792                 for( 
long ipLo=0; ipLo < ipHi; ++ipLo )
 
  795                         MultOpacs[ sp->
st[ipHi].n() ][ sp->
st[ipLo].n() ] += tr.
Emis().
PopOpc() *
 
  803                 for( 
long ipLo=0; ipLo < ipHi; ++ipLo )
 
  818         double TotalPop = 0.;
 
  820         for( 
long level=0; level < numlevels_local; level++ )
 
  825                         sp->
st[level].Pop() * sp->
fb[level].RateLevel2Cont;
 
  826                 TotalPop += sp->
st[level].Pop();
 
  831                 fprintf( 
ioQQQ, 
"DISASTER RateIonizTot for Z=%li, ion %li is larger than BIGDOUBLE.  This is a big problem.",
 
  832                                         nelem+1, nelem-ipISO);
 
  855                         ratio = rateOutOf2TripS /
 
realnum & opacity() const 
void getrs_wrapper(char trans, long N, long nrhs, double *A, long lda, int32 *ipiv, double *B, long ldb, int32 *info)
bool lgIsoTraceFull[NISO]
void prtRates(const long nlevels_local, const multi_arr< double, 2, C_TYPE > &a, valarray< double > &b)
long int IonHigh[LIMELM+1]
bool lgTimeDependentStatic
long int ipIsoTrace[NISO]
molezone * findspecieslocal(const char buf[])
t_elementnames elementnames
t_iso_sp iso_sp[NISO][LIMELM]
void vexp(const double x[], double y[], long nlo, long nhi)
double xIonDense[LIMELM][LIMELM+1]
long int n_HighestResolved_local
double CharExcRecTotal[NCX]
double CharExcIonTotal[NCX]
bool fp_equal(sys_float x, sys_float y, int n=3)
void iso_multiplet_opacities(void)
ColliderList colliders(dense)
vector< two_photon > TwoNu
long int n_HighestResolved_max
long int IonLow[LIMELM+1]
void getrf_wrapper(long M, long N, double *A, long lda, int32 *ipiv, int32 *info)
double energy(const genericState &gs)
double frac_he0dest_23S_photo
EmissionList::reference Emis() const 
realnum rate_lu_nontherm() const 
realnum *** xMoleChTrRate
realnum GetDopplerWidth(realnum massAMU)
char chElementNameShort[LIMELM][CHARS_ELEMENT_NAME_SHORT]
multi_arr< long, 3 > QuantumNumbers2Index
bool lgCritDensLMix[NISO]
TransitionProxy trans(const long ipHi, const long ipLo)
char chElementSym[LIMELM][CHARS_ELEMENT_SYM]
double *** CollIonRate_Ground
realnum AtomicWeight[LIMELM]
multi_arr< extra_tr, 2 > ex
STATIC void iso_multiplet_opacities_one(const long int ipISO, const long int nelem)
void reserve(size_type i1)
CollisionProxy Coll() const 
double & mult_opac() const 
#define DEBUG_ENTRY(funcname)
void iso_renorm(long nelem, long ipISO, double &renorm)
double RateIonizTot(long nelem, long ion) const 
int fprintf(const Output &stream, const char *format,...)
sys_float SDIV(sys_float x)
char chElementName[LIMELM][CHARS_ELEMENT_NAME]
double CharExcIonOf[NCX][LIMELM][LIMELM+1]
realnum GrainChTrRate[LIMELM][LIMELM+1][LIMELM+1]
double CharExcRecTo[NCX][LIMELM][LIMELM+1]
void iso_set_ion_rates(long ipISO, long nelem)
double ColUL(const ColliderList &colls) const 
void iso_level(const long ipISO, const long nelem, double &renorm, bool lgPrtMatrix)