42 if( !
exists( SpeciesCurrent ) )
46 fprintf(
ioQQQ,
" PROBLEM dBase_solve did not find molecular species %li\n",ipSpecies);
67 for(
long ipSpecies=0; ipSpecies<
nSpecies; ipSpecies++ )
73 for(
long ipSpecies=0; ipSpecies<
nSpecies; ipSpecies++ )
81 for(
long ipHi = 1; ipHi <
dBaseSpecies[ipSpecies].numLevels_max; ipHi++ )
88 (*tr).Emis().xIntensity() = 0.;
89 (*tr).Emis().xObsIntensity() = 0.;
90 (*tr).Coll().col_str() = 0.;
91 (*tr).Coll().cool() = 0.;
92 (*tr).Coll().heat() = 0.;
105 for(
long ipSpecies=0; ipSpecies<
nSpecies; ipSpecies++ )
114 int ipHi = (*tr).ipHi();
118 (*tr).Coll().rate_coef_ul_set()[k] = 0.f;
127 int ipHi = (*tr).ipHi();
130 for(
long intCollNo=0; intCollNo<
ipNCOLLIDER; intCollNo++)
133 (*tr).Coll().rate_coef_ul_set()[intCollNo] =
136 tr->Coll().is_gbar() = 0;
145 if ((*tr).ipHi() >=
dBaseSpecies[ipSpecies].numLevels_local)
147 for(
long intCollNo=0; intCollNo<
ipNCOLLIDER; intCollNo++)
149 (*tr).Coll().rate_coef_ul_set()[intCollNo] =
152 tr->Coll().is_gbar() = 0;
161 if ((*tr).ipHi() >=
dBaseSpecies[ipSpecies].numLevels_local)
163 for(
long intCollNo=0; intCollNo<
ipNCOLLIDER; intCollNo++)
165 (*tr).Coll().rate_coef_ul_set()[intCollNo] =
168 tr->Coll().is_gbar() = 0;
178 int ipHi = (*tr).ipHi();
230 for(
long intCollNo=0; intCollNo<
ipNCOLLIDER; intCollNo++)
240 if( (*tr).Coll().rate_coef_ul_set()[
ipELECTRON] == 0. )
252 (*tr).Coll().is_gbar() = 1;
259 if( tr->Coll().col_str() == -FLT_MAX && tr->Coll().rate_coef_ul()[
ipELECTRON] > 0.0 )
278 static bool lgFirstPass =
true;
279 static long maxNumLevels = 1;
280 static double *g, *ex, *pops, *
depart, *source, *sink;
281 static double **AulEscp, **AulDest, **AulPump, **CollRate;
285 for(
long ipSpecies=0; ipSpecies<
nSpecies; ipSpecies++ )
288 g = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
289 ex = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
290 pops = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
291 depart = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
292 source = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
293 sink = (
double *)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double));
295 AulEscp = (
double **)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double *));
296 AulDest = (
double **)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double *));
297 AulPump = (
double **)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double *));
298 CollRate = (
double **)
MALLOC( (
unsigned long)(maxNumLevels)*
sizeof(
double *));
300 AulEscp[0] = (
double *)
MALLOC( (
unsigned long)(maxNumLevels*maxNumLevels)*
sizeof(
double));
301 AulDest[0] = (
double *)
MALLOC( (
unsigned long)(maxNumLevels*maxNumLevels)*
sizeof(
double));
302 AulPump[0] = (
double *)
MALLOC( (
unsigned long)(maxNumLevels*maxNumLevels)*
sizeof(
double));
303 CollRate[0] = (
double *)
MALLOC( (
unsigned long)(maxNumLevels*maxNumLevels)*
sizeof(
double));
304 for(
long j=1; j< maxNumLevels; j++ )
306 AulEscp[j]=AulEscp[j-1]+maxNumLevels;
307 AulDest[j]=AulDest[j-1]+maxNumLevels;
308 AulPump[j]=AulPump[j-1]+maxNumLevels;
309 CollRate[j]=CollRate[j-1]+maxNumLevels;
316 memset( g, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
317 memset( ex, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
318 memset( pops, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
319 memset( depart, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
320 memset( source, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
321 memset( sink, 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
322 for(
long j=0; j< maxNumLevels; j++ )
324 memset( AulEscp[j], 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
325 memset( AulDest[j], 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
326 memset( AulPump[j], 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
327 memset( CollRate[j], 0, (
unsigned long)(maxNumLevels)*
sizeof(
double) );
332 double totalHeating = 0.;
333 for(
long ipSpecies=0; ipSpecies<
nSpecies; ipSpecies++ )
352 for(
long ipLo = 0; ipLo <
dBaseSpecies[ipSpecies].numLevels_local; ipLo++ )
358 ex[ipLo] =
dBaseStates[ipSpecies][ipLo].energy().WN() -
371 for(
long ipHi= 0; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ipHi++)
373 for(
long ipLo= 0; ipLo<
dBaseSpecies[ipSpecies].numLevels_local; ipLo++)
375 AulEscp[ipHi][ipLo] = 0.;
378 for(
long ipHi= 0; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ipHi++)
380 for(
long ipLo= 0; ipLo<
dBaseSpecies[ipSpecies].numLevels_local; ipLo++)
382 AulDest[ipHi][ipLo] = 0.;
385 for(
long ipLo= 0; ipLo<
dBaseSpecies[ipSpecies].numLevels_local; ipLo++)
387 for(
long ipHi= 0; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ipHi++)
389 AulPump[ipLo][ipHi] = 0.;
393 const bool isO1 = ( strcmp( spName,
"O 1" ) == 0 ),
394 isO3 = (strcmp(spName,
"O 3") == 0),
395 isCa2 = (strcmp(spName,
"Ca 2") == 0),
396 isN1 = (strcmp(spName,
"N 1") == 0),
397 isMg2 = (strcmp(spName,
"Mg 2") == 0);
402 int ipHi = (*tr).ipHi();
403 if (ipHi >=
dBaseSpecies[ipSpecies].numLevels_local || (*tr).ipCont() <= 0)
405 int ipLo = (*tr).ipLo();
406 AulEscp[ipHi][ipLo] = (*tr).Emis().Aul()*(*tr).Emis().Pesc_total();
407 AulDest[ipHi][ipLo] = (*tr).Emis().Aul()*(*tr).Emis().Pdest();
408 AulPump[ipLo][ipHi] = (*tr).Emis().pump();
409 AulPump[ipHi][ipLo] = AulPump[ipLo][ipHi]*g[ipLo]/g[ipHi];
412 double xtraExRate = 0.;
413 double xtraDxRate = 0.;
418 static const double lo1_nrg = 0.;
419 static const double lo2_nrg = 158.265;
420 static const double lo3_nrg = 226.977;
422 static const double hi1_nrg = 97488.378;
423 static const double hi2_nrg = 97488.448;
424 static const double hi3_nrg = 97488.538;
426 if( (
fp_equal( tr->Lo()->energy().WN(),lo1_nrg ) ||
427 fp_equal( tr->Lo()->energy().WN(),lo2_nrg ) ||
428 fp_equal( tr->Lo()->energy().WN(),lo3_nrg ) ) &&
429 (
fp_equal( tr->Hi()->energy().WN(),hi1_nrg ) ||
430 fp_equal( tr->Hi()->energy().WN(),hi2_nrg ) ||
431 fp_equal( tr->Hi()->energy().WN(),hi3_nrg ) ) )
437 if( tr->ipHi() == 3 )
443 if( tr->ipHi() == 3 )
449 if( tr->ipLo() == 0 && tr->ipHi() < 5 )
455 if( tr->ipLo() == 0 && (tr->ipHi() == 1 || tr->ipHi() == 2) )
461 if( tr->ipLo() == 0 && (tr->ipHi() == 4 || tr->ipHi() == 5) )
464 else if( strcmp(spName,
"Fe 2") == 0 )
469 AulPump[ipLo][ipHi] += xtraExRate;
470 AulPump[ipHi][ipLo] += xtraDxRate;
477 int ipHi = (*tr).ipHi();
486 for(
long ipHi= 0; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ipHi++)
488 for(
long ipLo= 0; ipLo<
dBaseSpecies[ipSpecies].numLevels_local; ipLo++)
490 CollRate[ipHi][ipLo] = 0.;
498 int ipHi = (*tr).ipHi();
501 int ipLo = (*tr).ipLo();
502 CollRate[ipHi][ipLo] = (*tr).Coll().ColUL( colld );
505 for(
int ipHi=1; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ++ipHi)
506 arg[ipHi] = -(ex[ipHi]-ex[ipHi-1])*T1CM /
phycon.
te;
508 for (
int ipLo=0; ipLo<
dBaseSpecies[ipSpecies].numLevels_local-1; ++ipLo)
510 double boltz_over_glo=1./ g[ipLo];
511 for (
int ipHi=ipLo+1; ipHi<
dBaseSpecies[ipSpecies].numLevels_local; ++ipHi)
513 boltz_over_glo *= bstep[ipHi];
514 CollRate[ipLo][ipHi] = CollRate[ipHi][ipLo] * g[ipHi] * boltz_over_glo;
532 if( (*tr).ipCont() > 0 )
534 int ipHi = (*tr).ipHi();
537 int ipLo = (*tr).ipLo();
538 (*tr).Coll().rate_lu_nontherm_set() = sfac *
539 ((*tr).Emis().gf()/(*tr).EnergyWN());
541 CollRate[ipLo][ipHi] += (*tr).Coll().rate_lu_nontherm();
542 CollRate[ipHi][ipLo] += (*tr).Coll().rate_lu_nontherm() * g[ipLo] / g[ipHi];
548 enum {DEBUG_LOC=
false};
549 if( DEBUG_LOC && (
nzone>110) )
559 int ipLo = tr->ipLo();
560 int ipHi = tr->ipHi();
561 if( ipLo == 39 && ipHi == 139 )
566 if( ipLo == 36 && ipHi == 133 )
577 double grnd_excit = 0.0;
578 double cooltl, coolder;
580 bool lgZeroPop, lgDeBug =
false;
644 [(*(*
dBaseTrans[ipSpecies].begin()).Lo()).IonStg()-1]
652 fprintf(
ioQQQ,
" dBase_solve fixup: negative pops set to zero during search phase, continuing.\n");
655 fprintf(
ioQQQ,
" PROBLEM in dBase_solve, atom_levelN returned negative population .\n");
661 while( (pops[
dBaseSpecies[ipSpecies].numLevels_local-1]<=0 ) &&
665 for(
long j=0;j<
dBaseSpecies[ipSpecies].numLevels_local; j++ )
668 dBaseStates[ipSpecies][j].DepartCoef() = depart[j];
681 tr != dBaseTrans[ipSpecies].end(); ++tr)
683 int ipHi = (*tr).ipHi();
686 int ipLo = (*tr).ipLo();
687 (*tr).Coll().cool() =
max(Cool[ipHi][ipLo],0.);
688 (*tr).Coll().heat() =
max(-Cool[ipHi][ipLo],0.);
690 if ( (*tr).ipCont() > 0 )
693 (*tr).Emis().PopOpc() = (*(*tr).Lo()).Pop() - (*(*tr).Hi()).Pop()*
694 (*(*tr).Lo()).g()/(*(*tr).Hi()).g();
699 if( CollRate[ipLo][ipHi]+AulPump[ipLo][ipHi] > 0. )
701 (*tr).Emis().ColOvTot() = CollRate[ipLo][ipHi]/
702 (CollRate[ipLo][ipHi]+AulPump[ipLo][ipHi]);
705 (*tr).Emis().ColOvTot() = 0.;
727 tr->Lo()->Pop()*exRate -
728 tr->Hi()->Pop()*dxRate);
747 tr != dBaseTrans[ipSpecies].end(); ++tr)
749 int ipHi = (*tr).ipHi();
766 enum {DEBUG_LOC=
false};
770 fprintf(
ioQQQ,
" Departure coefficients for species %li\n", ipSpecies );
771 for(
long j=0; j<
dBaseSpecies[ipSpecies].numLevels_local; j++ )
773 fprintf(
ioQQQ,
" level %li \t Depar Coef %e\n", j, depart[j] );
805 for(
int j = 0; j < n; j ++)
807 ASSERT( x[j] > 0. && y[j] > 0.);
812 double fupsilon = 0.;
817 else if( ftemp > x[n-1] )
823 fupsilon =
linint(&x[0],&y[0],n,ftemp);
834 tr.
Coll().
col_str() = (rate * (*tr.
Hi()).g()*sqrt(ftemp))/COLL_CONST;
843 rate = (COLL_CONST*fupsilon)/((*tr.
Hi()).g()*sqrt(ftemp));
848 fprintf(
ioQQQ,
"PROBLEM: Stout data format does not support using collision strengths with "
849 "non-electron colliders.\n");
876 rate = (COLL_CONST*fupsilon)/((*tr.
Hi()).g()*sqrt(ftemp));
884 double CHIANTI_Upsilon(
long ipSpecies,
long ipCollider,
long ipHi,
long ipLo,
double ftemp)
886 double fdeltae,fscalingparam,fkte,fxt,fsups,fups;
887 int intxs,inttype,intsplinepts;
891 if(
AtmolCollSplines[ipSpecies][ipHi][ipLo][ipCollider].collspline == NULL )
896 intsplinepts =
AtmolCollSplines[ipSpecies][ipHi][ipLo][ipCollider].nSplinePts;
899 fscalingparam =
AtmolCollSplines[ipSpecies][ipHi][ipLo][ipCollider].ScalingParam;
901 fkte = ftemp/fdeltae/1.57888e5;
907 if( inttype ==1 || inttype==4 )
909 fxt = 1-(log(fscalingparam)/(log(fkte+fscalingparam)));
911 else if(inttype == 2 || inttype == 3||inttype == 5 || inttype == 6)
913 fxt = fkte/(fkte+fscalingparam);
921 for(intxs=0;intxs<intsplinepts;intxs++)
923 double coeff = (double)1/(intsplinepts-1);
924 xs[intxs] = coeff*intxs;
927 printf(
"The xs and spl values are %f and %f \n",xs[intxs],spl[intxs]);
932 const bool SPLINE_INTERP=
false;
935 fsups =
linint( xs, spl, intsplinepts, fxt);
946 for(intxs=0;intxs<intsplinepts;intxs++)
948 printf(
"The %d value of 2nd derivative is %f \n",intxs+1,spl2[intxs]);
953 splint(xs,spl,spl2,intsplinepts,fxt,&fsups);
959 fups = fsups*log(fkte+EE);
961 else if(inttype == 2)
965 else if(inttype == 3)
967 fups = fsups/(fkte+1.0) ;
969 else if(inttype == 4)
971 fups = fsups*log(fkte+fscalingparam) ;
973 else if(inttype == 5)
977 else if(inttype == 6)
979 fups =
exp10(fsups) ;
988 fprintf(
ioQQQ,
" WARNING: Negative upsilon in species %s, collider %li, indices %4li %4li, Te = %e.\n",
989 dBaseSpecies[ipSpecies].chLabel, ipCollider, ipHi, ipLo, ftemp );
1012 fixit(
"ticket #78 refers");
1033 " P8446 finds Lbeta, OI widths=%10.2e%10.2e and esc prob=%10.2e%10.2e esAB=%10.2e\n",
1042 xoi = opacoi/(opacoi + opaclb);
1043 xlb = opaclb/(opacoi + opaclb);
1053 " P8446 opac Lb, OI=%10.2e%10.2e X Lb, OI=%10.2e%10.2e FLb, OI=%10.2e%10.2e\n",
1054 opaclb, opacoi, xlb, xoi, flb, foi );
1064 xtraDxRate += (
realnum)(aoi*(1. - (1. - foi)*(1. - esoi) - xoi*(1. - esab)*foi));
1086 PhotoRate5 = 1.7e-18*hlgam;
1087 PhotoRate4 = 8.4e-19*hlgam;
1088 PhotoRate3 = 7.0e-18*hlgam;
1089 PhotoRate2 = 4.8e-18*hlgam;
1091 if( tr.
ipHi() + 1 == 2)
1093 xtraDxRate += PhotoRate2;
1095 else if( tr.
ipHi() + 1 == 3 )
1097 xtraDxRate += PhotoRate3;
1099 else if( tr.
ipHi() + 1 == 4 )
1101 xtraDxRate += PhotoRate4;
1103 else if( tr.
ipHi() + 1 == 5 )
1105 xtraDxRate += PhotoRate5;
1133 double EnerLyaProf1 = 82259.0 - de*2.0;
1134 double EnerLyaProf2 = 82259.0 - de;
1135 double EnerLyaProf3 = 82259.0 + de;
1136 double EnerLyaProf4 = 82259.0 + de*2.0;
1138 double PhotOccNumLyaCenter = 0.;
1144 PhotOccNumLyaCenter =
1166 if( EnergyWN >= EnerLyaProf1 && EnergyWN <= EnerLyaProf4 && taux > 1 )
1183 double PhotOccNum_at_nu = 0.,
1185 if( EnergyWN < EnerLyaProf2 )
1188 PhotOccNum_at_nu = PhotOccNumLyaCenter*(EnergyWN - EnerLyaProf1)/ de;
1190 else if( EnergyWN < EnerLyaProf3 )
1193 PhotOccNum_at_nu = PhotOccNumLyaCenter;
1198 PhotOccNum_at_nu = PhotOccNumLyaCenter*(EnerLyaProf4 - EnergyWN)/de;
1211 PumpRate = FeIILineWidthHz * PhotOccNum_at_nu * tr.
Emis().
Aul()*
1212 powi(82259.0f/EnergyWN,3);
1215 PumpRate = tr.
Emis().
Aul()* PhotOccNum_at_nu;
1218 xtraDxRate += PumpRate;
1221 xtraExRate += PumpRate * (*tr.
Hi()).g()/(*tr.
Lo()).g();
void CoolAdd(const char *chLabel, realnum lambda, double cool)
void DumpLine(const TransitionProxy &t)
vector< StoutCollArray > StoutCollData
NORETURN void TotalInsanity(void)
double depart(const genericState &gs)
STATIC void setXtraRatesO1(const TransitionProxy &tr, double &xtraExRate, double &xtraDxRate)
void set_xIntensity(const TransitionProxy &t)
double CHIANTI_Upsilon(long, long, long, long, double)
molezone * findspecieslocal(const char buf[])
STATIC double LeidenCollRate(long, long, const TransitionProxy &, double)
multi_arr< CollRateCoeffArray, 2 > AtmolCollRateCoeff
static const bool DEBUGSTATE
void splint(const double xa[], const double ya[], const double y2a[], long int n, double x, double *y)
double * rate_coef_ul_set() const
double ** ExcitationGround
t_iso_sp iso_sp[NISO][LIMELM]
void vexp(const double x[], double y[], long nlo, long nhi)
double xIonDense[LIMELM][LIMELM+1]
bool fp_equal(sys_float x, sys_float y, int n=3)
ColliderList colliders(dense)
realnum & EnergyWN() const
double energy(const genericState &gs)
EmissionList::reference Emis() const
STATIC void setXtraRatesFe2(const TransitionProxy &tr, double &xtraExRate, double &xtraDxRate)
STATIC void setXtraRatesCa2(const TransitionProxy &tr, double &xtraDxRate)
double InterpCollRate(const CollRateCoeffArray &rate_table, const long &ipHi, const long &ipLo, const double &ftemp)
qList::iterator Hi() const
double powi(double, long int)
static realnum dBaseAbund(long ipSpecies)
realnum GetDopplerWidth(realnum massAMU)
bool exists(const molecule *m)
vector< multi_arr< CollSplinesArray, 3 > > AtmolCollSplines
TransitionProxy trans(const long ipHi, const long ipLo)
void setHeating(long nelem, long ion, double heating)
realnum AtomicWeight[LIMELM]
qList::iterator Lo() const
void EmLineZero(EmissionList::reference t)
realnum Pesc_total() const
STATIC double StoutCollRate(long ipSpecies, long ipCollider, const TransitionProxy &, double ftemp)
realnum & col_str() const
CollisionProxy Coll() const
vector< vector< long > > ipSpecIon
#define DEBUG_ENTRY(funcname)
double linint(const double x[], const double y[], long n, double xval)
vector< qList > dBaseStates
double elementcool[LIMELM+1]
const double * rate_coef_ul() const
vector< species > dBaseSpecies
int fprintf(const Output &stream, const char *format,...)
STATIC double ChiantiCollRate(long ipSpecies, long ipCollider, const TransitionProxy &, double ftemp)
t_secondaries secondaries
void CollisionZero(const CollisionProxy &t)
vector< TransitionList > dBaseTrans
void dBaseUpdateCollCoeffs(void)
void MakeCS(const TransitionProxy &t)