74 multimap<double,drChoiceItem>
m_map;
77 void insert(
double val,
const string& str,
bool* flag = NULL)
106 static double OHIIoHI,
110 OldWindVelocity = 0.,
113 const double BigRadius = 1e30;
128 bool lgFirstCall = (
nzone == 0 );
134 if( !lgFirstCall && OHIIoHI > 1e-15 &&
141 double x = fabs(1. - atomic_frac/OHIIoHI);
142 if( atomic_frac > 0.05 && atomic_frac < 0.9 )
155 double SaveOHIIoHI = OHIIoHI;
158 oss <<
"change in H ionization old=" << scientific << setprecision(3);
159 oss << SaveOHIIoHI <<
" new=" << OHIIoHI;
160 drChoice.
insert( drHion, oss.str() );
182 oss <<
"H maser dTauMase=" << scientific << setprecision(2) <<
rt.
dTauMase <<
" ";
190 double change_heavy_frac_big = -1.;
191 double frac_change_heavy_frac_big = -1.;
192 const realnum CHANGE_ION_HEAV = 0.2f;
193 const realnum CHANGE_ION_HHE = 0.15f;
196 long ichange_heavy_nelem = -1L;
197 long ichange_heavy_ion = -1L;
198 double dr_change_heavy = BigRadius;
210 change = CHANGE_ION_HHE;
218 change = CHANGE_ION_HEAV;
221 for(
int ion=0; ion<=nelem+1; ++ion )
225 if( abundnew > frac_limit && abundold > frac_limit )
232 double change_heavy_frac = fabs(abundnew-abundold)/
MIN2(abundold,abundnew);
234 if( (change_heavy_frac > change) && (change_heavy_frac > change_heavy_frac_big) &&
237 ((abundnew-abundold)>0.) &&
238 ((abundold-abundolder)>0.) &&
239 ((abundolder-abundoldest)>0.) )
241 ichange_heavy_nelem = nelem;
242 ichange_heavy_ion = ion;
243 change_heavy_frac_big = change_heavy_frac;
244 frac_change_heavy_frac_big = abundnew;
252 dr_change_heavy =
radius.
drad *
MAX2(0.25, change / change_heavy_frac );
262 if(ichange_heavy_nelem>=0)
265 oss <<
" ion (C scale) " << ichange_heavy_ion <<
" rel change " << scientific << setprecision(2);
266 oss << change_heavy_frac_big <<
" ion frac " << frac_change_heavy_frac_big;
271 dr_change_heavy = BigRadius;
273 drChoice.
insert( dr_change_heavy, oss.str() );
285 drChoice.
insert( drLeiden_hack,
"Leiden hack" );
289 static double extin_mag_V_point_old = -1.;
292 const double extin_mag_V_limit = 20.+0.01*extin_mag_V_point_old;
298 oss <<
"change in V mag extinction; current=" << scientific << setprecision(3) <<
300 oss << fixed <<
" delta=" << dExtin;
301 drChoice.
insert( drExtintion, oss.str() );
334 oss <<
"change in heating; current=" << scientific << setprecision(3) <<
thermal.
htot;
335 oss << fixed <<
" delta=" << dHdStep;
336 drChoice.
insert( drdHdStep, oss.str() );
354 drChoice.
insert( drConPres,
"change in con accel" );
365 ASSERT( drGravPres > 0. );
366 drChoice.
insert( drGravPres,
"change in gravitational pressure" );
372 double dTdStep = FLT_MAX;
386 if( dTdStep*OlddTdStep > 0. )
393 double absdt = fabs(dTdStep);
396 oss <<
"change in temperature; current=" << scientific << setprecision(3) <<
phycon.
te;
397 oss << fixed <<
" dT/T=" << dTdStep;
398 drChoice.
insert( drdTdStep, oss.str() );
401 OlddTdStep = dTdStep;
411 double freqm = 0., opacm = 0.;
422 oss <<
"cont inter nu=" << scientific << setprecision(2) << freqm <<
" opac=" << opacm;
423 drChoice.
insert( drInter, oss.str() );
435 double dVelRelative = fabs(
wind.
windv-OldWindVelocity)/
438 const double WIND_CHNG_VELOCITY_RELATIVE = 0.01;
444 if( dVelRelative > WIND_CHNG_VELOCITY_RELATIVE &&
nzone>1 )
447 double factor = WIND_CHNG_VELOCITY_RELATIVE / dVelRelative;
449 factor =
MAX2(0.8 , factor );
466 oss <<
"Wind, dVelRelative=" << scientific << setprecision(3);
467 oss << dVelRelative <<
" windv=" <<
wind.
windv;
468 drChoice.
insert( winddr, oss.str() );
473 const double DNGLOB = 0.10;
480 fprintf(
ioQQQ,
" Globule distance is negative, internal overflow has occured, sorry.\n" );
481 fprintf(
ioQQQ,
" This is routine radius_next, GLBDST is%10.2e\n",
488 double GlobDr = ( fac2/factor > 1. + DNGLOB ) ?
radius.
drad*DNGLOB/(fac2/factor - 1.) : BigRadius;
492 drChoice.
insert( GlobDr, oss.str() );
522 oss <<
"spec den law, new old den " << scientific << setprecision(2);
524 drChoice.
insert( drTab, oss.str() );
539 else if( dnew/DNGLOB > 1.0 )
549 drChoice.
insert( SpecDr, oss.str() );
558 double grfreqm = 0., gropacm = 0.;
564 oss <<
"grain heating nu=" << scientific << setprecision(2) << grfreqm <<
" opac=" << gropacm;
565 drChoice.
insert( DrGrainHeat, oss.str() );
584 fixit(
"all other line stacks need to be included here.");
590 double drLineHeat = ( TauDTau > 0. ) ?
MAX2(1.,TauInwd)*0.4/TauDTau : BigRadius;
592 oss <<
"level " << level <<
" line heating, " <<
chLineLbl(t) <<
" TauIn " << scientific;
593 oss << setprecision(2) << TauInwd <<
" " << t.
Emis().
pump() <<
" " << t.
Emis().
Pesc();
594 drChoice.
insert( drLineHeat, oss.str() );
600 Old_H2_heat_cool = 0.;
607 double dH2_heat_cool = fabs( H2_heat_cool - Old_H2_heat_cool );
608 if( H2_heat_cool > 0.1 && Old_H2_heat_cool>0. && dH2_heat_cool>
SMALLFLOAT )
614 oss <<
"change in H2 heating/cooling, d(c,h)/H " << scientific << setprecision(2);
615 oss << dH2_heat_cool;
616 drChoice.
insert( drH2_heat_cool, oss.str() );
654 dH2_abund =
SDIV(dH2_abund);
657 oss <<
"change in H2 abundance, d(H2)/H " << scientific << setprecision(2) << dH2_abund;
658 drChoice.
insert( drH2_abund, oss.str() );
662 int mole_dr_change = -1;
667 double max_change = 0.0;
682 for( molecule::nNucsMap::iterator atom=
mole_global.
list[i]->nNuclide.begin();
685 long int nelem = atom->first->el->Z-1;
710 if( abund > abund_limit )
713 double relative_change =
716 if (relative_change > max_change)
718 max_change = relative_change;
724 if( mole_dr_change >= 0 )
728 oss <<
"change in abundance species=" <<
mole_global.
list[mole_dr_change]->label <<
", ";
729 oss << scientific << setprecision(2);
731 drChoice.
insert( dr_mole_abund, oss.str() );
737 drChoice.
insert( (*diatom)->H2_DR(),
"change in big H2 Solomon rate line opt depth" );
747 drChoice.
insert( drmax,
"DRMAX" );
751 double recom_dr_last_iter = BigRadius;
755 static long int nzone_recom = -1;
772 drChoice.
insert( recom_dr_last_iter,
773 "previous iteration recom logic" );
786 double dEfrac = fabs(Efrac_old-Efrac_new) / Efrac_new;
816 oss <<
"change in elec den, rel chng: " << scientific << setprecision(3) << dEfrac;
817 oss <<
" cur=" << Efrac_new <<
" old=" << Efrac_old;
818 drChoice.
insert( drEfrac, oss.str() );
831 double thickness_total = BigRadius;
832 double DepthToGo = BigRadius;
836 DepthToGo =
MIN2(DepthToGo ,
845 DepthToGo =
MIN2(DepthToGo ,
854 DepthToGo =
MIN2(DepthToGo ,
863 DepthToGo =
MIN2(DepthToGo ,
872 DepthToGo =
MIN2(DepthToGo ,
881 DepthToGo =
MIN2(DepthToGo ,
890 static bool lgMustFind=
true;
897 DepthToGo =
MIN2(DepthToGo ,
905 DepthToGo =
MIN2(DepthToGo ,
914 DepthToGo =
MIN2(DepthToGo ,
923 DepthToGo =
MIN2(DepthToGo ,
927 if( DepthToGo <= 0. )
931 if( DepthToGo < BigRadius )
933 double depth_min =
MIN2( DepthToGo , thickness_total/100. );
934 DepthToGo =
MAX2( DepthToGo / 10. , depth_min );
940 double drThickness =
MIN2( thickness_total/10. , DepthToGo );
941 drChoice.
insert( drThickness,
"depth to go" );
947 double AV_to_go = BigRadius;
950 double SAFETY = 1. + 10.*DBL_EPSILON;
959 AV_to_go =
MIN2( ave , avp );
968 AV_to_go = BigRadius;
971 drChoice.
insert( AV_to_go,
"A_V to go" );
976 drChoice.
insert( drSphere,
"sphericity" );
984 drChoice.
insert( dRTaue,
"optical depth to electron scattering" );
993 drChoice.
insert( drFluc,
"density fluctuations" );
1001 drChoice.
insert( drStart,
"capped to old DR in first zone" );
1029 drChoice.
insert( drThermalFront,
"thermal front logic" );
1036 if( drChoice.
begin()->first <= 0. )
1039 fprintf(
ioQQQ,
" radius_next finds insane drNext: %.2e\n", ptr->first );
1041 while( ptr != drChoice.
end() )
1043 fprintf(
ioQQQ,
" %.2e %s\n", ptr->first, ptr->second.c_str() );
1083 drChoice.
begin()->first != DepthToGo &&
1085 drChoice.
begin()->first != AV_to_go )
1087 fixit(
"drMinimum does not get reevaluated in each iteration,"
1088 " so time-dependent solutions just use the first drad and Hden."
1089 " Re-eval here for now to keep this minimum from blowing." );
1112 "\n DISASTER PROBLEM radius_next finds dr too small and aborts. "
1113 "This is zone %ld iteration %ld. The thickness was %.2e\n",
1118 " If this simulation seems reasonable you can override this limit "
1119 "with the command SET DRMIN %.2e\n\n",
1128 const double Z = 1.0001;
1135 drChoice.
insert( drOuterRadius,
"outer radius" );
1141 drChoice.
insert( drHz,
"c over H(z)" );
1148 drChoice.
begin()->second.select( );
1165 fprintf(
ioQQQ,
" radius_next chooses next drad drNext=%.4e; this drad was %.4e\n",
1185 Rate_max_nonIonizing;
1194 Rate_max_nonIonizing = 0.;
1195 Freq_nonIonizing = 0.;
1196 Opac_nonIonizing = 0.;
1250 for( i=iplow; i < limit; i++ )
1282 if( Rate_max_nonIonizing < 1e-30 && Opac_Hion >
SMALLFLOAT )
1290 else if( Opac_Hion > Opac_nonIonizing && Rate_max_Hion/
SDIV(Rate_max_nonIonizing) > 1e-10 && Opac_Hion > SMALLFLOAT )
1299 *opacm = Opac_nonIonizing;
1300 *freqm = Freq_nonIonizing;
1311 double fluxGrainPeak = -1.;
1312 long int ipGrainPeak = -1;
1313 long int ipGrainPeak2 = -1;
1327 ASSERT( fluxGrainPeak>=0. && ipGrainPeak >=0 );
1340 if( fluxGrainPeak > 0. )
1352 ASSERT( ipGrainPeak2>=0 );
1369 enum {DEBUG_LOC=
false};
1372 fprintf(
ioQQQ,
"conratedebug \t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
1373 Rate_max_nonIonizing,Freq_nonIonizing,Opac_nonIonizing,
1374 Rate_max_Hion,FreqH ,Opac_Hion,*freqm,*opacm
1385 ASSERT( *opacm >= 0. && *freqm >= 0. );
multimap< double, drChoiceItem >::const_iterator const_iterator
t_mole_global mole_global
realnum & opacity() const
string chLineLbl(const TransitionProxy &t)
long int ipEnergyBremsThin
NORETURN void TotalInsanity(void)
double widflx(size_t i) const
multimap< double, drChoiceItem > m_map
const char * c_str() const
bool lgTimeDependentStatic
STATIC void ContRate(double *freqm, double *opacm)
bool lgTemperatureConstant
vector< double > StopThickness
molezone * findspecieslocal(const char buf[])
double anu(size_t i) const
molezone * findspecieslocal_validate(const char buf[])
t_elementnames elementnames
t_iso_sp iso_sp[NISO][LIMELM]
long int nflux_with_check
double xIonDense[LIMELM][LIMELM+1]
const_iterator end() const
double sound_speed_isothermal
vector< realnum > GrainEmission
double & VoigtLineCen() const
realnum & dampXvel() const
EmissionList::reference Emis() const
const_iterator begin() const
const TransitionProxy FndLineHt(long int *level)
valarray< class molezone > species
realnum AccelTotalOutward
vector< diatomics * > diatoms
double tabval(double r0, double depth) const
void insert(double val, const string &str, bool *flag=NULL)
sys_float safe_div(sys_float x, sys_float y, sys_float res_0by0)
double column(const genericState &gs)
double heating(long nelem, long ion)
realnum gas_phase[LIMELM]
STATIC void GrainRateDr(double *grfreqm, double *gropacm)
static const double SAFETY
double extin_mag_V_extended
double opac_mag_V_extended
CollisionProxy Coll() const
#define DEBUG_ENTRY(funcname)
int fprintf(const Output &stream, const char *format,...)
double dense_fabden(double radius, double depth)
realnum GetHubbleFactor(realnum z)
sys_float SDIV(sys_float x)
double dense_parametric_wind(double rad)
bool lgStatic(void) const
drChoiceItem(const string &str, bool *flag)
char chElementName[LIMELM][CHARS_ELEMENT_NAME]
long int nzonePreviousIteration
vector< diatomics * >::iterator diatom_iter
long int ipHeavy[LIMELM][LIMELM]