59 static double OHIIoHI,
66 const double BigRadius = 1e30;
78 fprintf(
ioQQQ,
" radius_next called\n" );
81 bool lgFirstCall = (
nzone == 0 );
83 multimap<double,string> drChoice;
87 if( !lgFirstCall && OHIIoHI > 1e-15 &&
94 double x = 1. - atomic_frac/OHIIoHI;
95 if( atomic_frac > 0.05 && atomic_frac < 0.9 )
112 double SaveOHIIoHI = OHIIoHI;
115 oss <<
"change in H ionization old=" << scientific << setprecision(3);
116 oss << SaveOHIIoHI <<
" new=" << OHIIoHI;
117 drChoice.insert( pair<const double,string>( drHion, oss.str() ) );
134 oss <<
"H maser dTauMase=" << scientific << setprecision(2) <<
rt.
dTauMase <<
" ";
136 drChoice.insert( pair<const double,string>( drHMase, oss.str() ) );
142 double change_heavy_frac_big = -1.;
143 double frac_change_heavy_frac_big = -1.;
144 const realnum CHANGE_ION_HEAV = 0.2f;
145 const realnum CHANGE_ION_HHE = 0.15f;
148 long ichange_heavy_nelem = -1L;
149 long ichange_heavy_ion = -1L;
150 double dr_change_heavy = BigRadius;
162 change = CHANGE_ION_HHE;
170 change = CHANGE_ION_HEAV;
173 for(
int ion=0; ion<=nelem+1; ++ion )
177 if( abundnew > frac_limit && abundold > frac_limit )
184 double change_heavy_frac = fabs(abundnew-abundold)/
MIN2(abundold,abundnew);
186 if( (change_heavy_frac > change) && (change_heavy_frac > change_heavy_frac_big) &&
189 ((abundnew-abundold)>0.) &&
190 ((abundold-abundolder)>0.) &&
191 ((abundolder-abundoldest)>0.) )
193 ichange_heavy_nelem = nelem;
194 ichange_heavy_ion = ion;
195 change_heavy_frac_big = change_heavy_frac;
196 frac_change_heavy_frac_big = abundnew;
204 dr_change_heavy =
radius.
drad *
MAX2(0.25, change / change_heavy_frac );
214 if(ichange_heavy_nelem>=0)
217 oss <<
" ion (C scale) " << ichange_heavy_ion <<
" rel change " << scientific << setprecision(2);
218 oss << change_heavy_frac_big <<
" ion frac " << frac_change_heavy_frac_big;
223 dr_change_heavy = BigRadius;
225 drChoice.insert( pair<const double,string>( dr_change_heavy, oss.str() ) );
237 drChoice.insert( pair<const double,string>( drLeiden_hack,
"Leiden hack" ) );
241 static double extin_mag_V_point_old = -1.;
244 const double extin_mag_V_limit = 20.+0.01*extin_mag_V_point_old;
250 oss <<
"change in V mag extinction; current=" << scientific << setprecision(3) <<
252 oss << fixed <<
" delta=" << dExtin;
253 drChoice.insert( pair<const double,string>( drExtintion, oss.str() ) );
286 oss <<
"change in heating; current=" << scientific << setprecision(3) <<
thermal.
htot;
287 oss << fixed <<
" delta=" << dHdStep;
288 drChoice.insert( pair<const double,string>( drdHdStep, oss.str() ) );
306 drChoice.insert( pair<const double,string>( drConPres,
"change in con accel" ) );
317 ASSERT( drGravPres > 0. );
318 drChoice.insert( pair<const double,string>( drGravPres,
"change in gravitational pressure" ) );
324 double dTdStep = FLT_MAX;
338 if( dTdStep*OlddTdStep > 0. )
345 double absdt = fabs(dTdStep);
348 oss <<
"change in temperature; current=" << scientific << setprecision(3) <<
phycon.
te;
349 oss << fixed <<
" dT/T=" << dTdStep;
350 drChoice.insert( pair<const double,string>( drdTdStep, oss.str() ) );
353 OlddTdStep = dTdStep;
363 double freqm = 0., opacm = 0.;
374 oss <<
"cont inter nu=" << scientific << setprecision(2) << freqm <<
" opac=" << opacm;
375 drChoice.insert( pair<const double,string>( drInter, oss.str() ) );
387 double dVelRelative = fabs(
wind.
windv-OldWindVelocity)/
390 const double WIND_CHNG_VELOCITY_RELATIVE = 0.01;
396 if( dVelRelative > WIND_CHNG_VELOCITY_RELATIVE &&
nzone>1 )
399 double factor = WIND_CHNG_VELOCITY_RELATIVE / dVelRelative;
401 factor =
MAX2(0.8 , factor );
418 oss <<
"Wind, dVelRelative=" << scientific << setprecision(3);
419 oss << dVelRelative <<
" windv=" <<
wind.
windv;
420 drChoice.insert( pair<const double,string>( winddr, oss.str() ) );
425 const double DNGLOB = 0.10;
432 fprintf(
ioQQQ,
" Globule distance is negative, internal overflow has occured, sorry.\n" );
433 fprintf(
ioQQQ,
" This is routine radius_next, GLBDST is%10.2e\n",
440 double GlobDr = ( fac2/factor > 1. + DNGLOB ) ?
radius.
drad*DNGLOB/(fac2/factor - 1.) : BigRadius;
444 drChoice.insert( pair<const double,string>( GlobDr, oss.str() ) );
468 fprintf(
ioQQQ,
" dlw insanity in radius_next\n" );
474 oss <<
"spec den law, new old den " << scientific << setprecision(2);
476 drChoice.insert( pair<const double,string>( drTab, oss.str() ) );
491 else if( dnew/DNGLOB > 1.0 )
501 drChoice.insert( pair<const double,string>( SpecDr, oss.str() ) );
510 double grfreqm = 0., gropacm = 0.;
516 oss <<
"grain heating nu=" << scientific << setprecision(2) << grfreqm <<
" opac=" << gropacm;
517 drChoice.insert( pair<const double,string>( DrGrainHeat, oss.str() ) );
542 double drLineHeat = ( TauDTau > 0. ) ?
MAX2(1.,TauInwd)*0.4/TauDTau : BigRadius;
544 oss <<
"level " << level <<
" line heating, " <<
chLineLbl(t) <<
" TauIn " << scientific;
545 oss << setprecision(2) << TauInwd <<
" " << t.
Emis().
pump() <<
" " << t.
Emis().
Pesc();
546 drChoice.insert( pair<const double,string>( drLineHeat, oss.str() ) );
552 Old_H2_heat_cool = 0.;
559 double dH2_heat_cool = fabs( H2_heat_cool - Old_H2_heat_cool );
560 if( H2_heat_cool > 0.1 && Old_H2_heat_cool>0. && dH2_heat_cool>
SMALLFLOAT )
566 oss <<
"change in H2 heating/cooling, d(c,h)/H " << scientific << setprecision(2);
567 oss << dH2_heat_cool;
568 drChoice.insert( pair<const double,string>( drH2_heat_cool, oss.str() ) );
576 int mole_dr_change = -1;
609 dH2_abund =
SDIV(dH2_abund);
612 oss <<
"change in H2 abundance, d(H2)/H " << scientific << setprecision(2) << dH2_abund;
613 drChoice.insert( pair<const double,string>( drH2_abund, oss.str() ) );
618 double max_change = 0.0;
633 for( molecule::nAtomsMap::iterator atom=
mole_global.
list[i]->nAtom.begin();
636 long int nelem = atom->first->el->Z-1;
661 if(
abund > abund_limit )
664 double relative_change =
667 if (relative_change > max_change)
669 max_change = relative_change;
675 if( mole_dr_change >= 0 )
679 oss <<
"change in molecular abundance, old=" << scientific << setprecision(2);
681 oss <<
" mole=" << mole_dr_change <<
"=" <<
mole_global.
list[mole_dr_change]->label;
682 drChoice.insert( pair<const double,string>( dr_mole_abund, oss.str() ) );
688 drChoice.insert( pair<const double,string>( (*diatom)->H2_DR(),
"change in big H2 Solomon rate line opt depth" ) );
698 drChoice.insert( pair<const double,string>( drmax,
"DRMAX" ) );
702 double recom_dr_last_iter = BigRadius;
706 static long int nzone_recom = -1;
723 drChoice.insert( pair<const double,string>( recom_dr_last_iter,
724 "previous iteration recom logic" ) );
737 double dEfrac = fabs(Efrac_old-Efrac_new) / Efrac_new;
767 oss <<
"change in elec den, rel chng: " << scientific << setprecision(3) << dEfrac;
768 oss <<
" cur=" << Efrac_new <<
" old=" << Efrac_old;
769 drChoice.insert( pair<const double,string>( drEfrac, oss.str() ) );
777 drChoice.insert( pair<const double,string>(
radius.
depth/10.,
"relative depth" ) );
782 double thickness_total = BigRadius;
783 double DepthToGo = BigRadius;
787 DepthToGo =
MIN2(DepthToGo ,
796 DepthToGo =
MIN2(DepthToGo ,
805 DepthToGo =
MIN2(DepthToGo ,
814 DepthToGo =
MIN2(DepthToGo ,
823 DepthToGo =
MIN2(DepthToGo ,
832 DepthToGo =
MIN2(DepthToGo ,
840 DepthToGo =
MIN2(DepthToGo ,
849 DepthToGo =
MIN2(DepthToGo ,
858 DepthToGo =
MIN2(DepthToGo ,
862 if( DepthToGo <= 0. )
866 if( DepthToGo < BigRadius )
868 double depth_min =
MIN2( DepthToGo , thickness_total/100. );
869 DepthToGo =
MAX2( DepthToGo / 10. , depth_min );
875 double drThickness =
MIN2( thickness_total/10. , DepthToGo );
876 drChoice.insert( pair<const double,string>( drThickness,
"depth to go" ) );
882 double AV_to_go = BigRadius;
885 double SAFETY = 1. + 10.*DBL_EPSILON;
894 AV_to_go =
MIN2( ave , avp );
903 AV_to_go = BigRadius;
906 drChoice.insert( pair<const double,string>( AV_to_go,
"A_V to go" ) );
911 drChoice.insert( pair<const double,string>( drSphere,
"sphericity" ) );
919 drChoice.insert( pair<const double,string>( dRTaue,
"optical depth to electron scattering" ) );
928 drChoice.insert( pair<const double,string>( drFluc,
"density fluctuations" ) );
936 drChoice.insert( pair<const double,string>( drStart,
"capped to old DR in first zone" ) );
940 drChoice.insert( pair<const double,string>( rfacmax*
radius.
sdrmax,
"sdrmax" ) );
964 drChoice.insert( pair<const double,string>( drThermalFront,
"thermal front logic" ) );
968 ASSERT( drChoice.size() > 0 );
971 if( drChoice.begin()->first <= 0. )
973 multimap<double,string>::const_iterator ptr = drChoice.begin();
974 fprintf(
ioQQQ,
" radius_next finds insane drNext: %.2e\n", ptr->first );
975 fprintf(
ioQQQ,
" all drs follow:\n" );
976 while( ptr != drChoice.end() )
978 fprintf(
ioQQQ,
" %.2e %s\n", ptr->first, ptr->second.c_str() );
996 drChoice.insert( pair<const double,string>( rfacmin*
radius.
sdrmin,
"sdrmin" ) );
1016 drChoice.begin()->first != DepthToGo &&
1018 drChoice.begin()->first != AV_to_go )
1040 "\n DISASTER PROBLEM radius_next finds dr too small and aborts. "
1041 "This is zone %ld iteration %ld. The thickness was %.2e\n",
1046 " If this simulation seems reasonable you can override this limit "
1047 "with the command SET DRMIN %.2e\n\n",
1056 const double Z = 1.0001;
1063 drChoice.insert( pair<const double,string>( drOuterRadius,
"outer radius" ) );
1069 if( drChoice.begin()->second.find(
"H maser" ) != string::npos )
1089 fprintf(
ioQQQ,
" radius_next chooses next drad drNext=%.4e; this drad was %.4e\n",
1109 Rate_max_nonIonizing;
1118 Rate_max_nonIonizing = 0.;
1119 Freq_nonIonizing = 0.;
1120 Opac_nonIonizing = 0.;
1174 for( i=iplow; i < limit; i++ )
1206 if( Rate_max_nonIonizing < 1e-30 && Opac_Hion >
SMALLFLOAT )
1214 else if( Opac_Hion > Opac_nonIonizing && Rate_max_Hion/
SDIV(Rate_max_nonIonizing) > 1e-10 && Opac_Hion >
SMALLFLOAT )
1223 *opacm = Opac_nonIonizing;
1224 *freqm = Freq_nonIonizing;
1235 double fluxGrainPeak = -1.;
1236 long int ipGrainPeak = -1;
1237 long int ipGrainPeak2 = -1;
1251 ASSERT( fluxGrainPeak>=0. && ipGrainPeak >=0 );
1264 if( fluxGrainPeak > 0. )
1276 ASSERT( ipGrainPeak2>=0 );
1293 enum {DEBUG_LOC=
false};
1296 fprintf(
ioQQQ,
"conratedebug \t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\t%.2e\n",
1297 Rate_max_nonIonizing,Freq_nonIonizing,Opac_nonIonizing,
1298 Rate_max_Hion,FreqH ,Opac_Hion,*freqm,*opacm
1309 ASSERT( *opacm >= 0. && *freqm >= 0. );
NORETURN void TotalInsanity(void)
sys_float SDIV(sys_float x)
#define DEBUG_ENTRY(funcname)
realnum & opacity() const
realnum & dampXvel() const
vector< realnum > GrainEmission
CollisionProxy Coll() const
EmissionList::reference Emis() const
valarray< class molezone > species
double dense_tabden(double r0, double depth)
double dense_fabden(double radius, double depth)
double dense_parametric_wind(double rad)
t_elementnames elementnames
static const double SAFETY
vector< diatomics * > diatoms
vector< diatomics * >::iterator diatom_iter
t_iso_sp iso_sp[NISO][LIMELM]
const TransitionProxy FndLineHt(long int *level)
t_mole_global mole_global
molezone * findspecieslocal(const char buf[])
STATIC void GrainRateDr(double *grfreqm, double *gropacm)
STATIC void ContRate(double *freqm, double *opacm)
bool lgStatic(void) const
realnum AccelTotalOutward
long int ipHeavy[LIMELM][LIMELM]
double xIonDense[LIMELM][LIMELM+1]
realnum gas_phase[LIMELM]
bool lgTimeDependentStatic
char chElementName[LIMELM][CHARS_ELEMENT_NAME]
double extin_mag_V_extended
long int ipEnergyBremsThin
double opac_mag_V_extended
long int nzonePreviousIteration
double heating[LIMELM][LIMELM]
bool lgTemperatureConstant
double sound_speed_isothermal
char * chLineLbl(const TransitionProxy &t)