Changeset 2112 for branches/newmole

Show
Ignore:
Timestamp:
06/17/08 17:10:09 (7 months ago)
Author:
rjrw
Message:

Merged from trunk r2088:2111

Location:
branches/newmole/source
Files:
16 modified

Legend:

Unmodified
Added
Removed
  • branches/newmole/source/atmdat_adfa.cpp

    r1830 r2112  
    236236        ASSERT( !lgErr ); 
    237237 
     238        /*refer HI      cs      Anderson, H., Ballance, C.P., Badnell, N.R.,  
     239         *refercon      & Summers, H.P  2000, J Phys B, 33, 1255 */ 
    238240        const static char chFile8[] = "h_coll_str.dat"; 
    239241 
  • branches/newmole/source/cddefines.h

    r1942 r2112  
    6969typedef float realnum; 
    7070#endif 
     71 
     72//Compile-time assertion after Alexandrescu 
     73template<bool> struct StaticAssertFailed; 
     74template<> struct StaticAssertFailed<true> {}; 
     75#define STATIC_ASSERT(x) (StaticAssertFailed< (x) == true >()) 
    7176 
    7277typedef float sys_float; 
     
    13381343 
    13391344/* Explicit instantiations for debugging purposes */ 
    1340 INSTANTIATE_MULTI_ARR( quantumState, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
    1341 INSTANTIATE_MULTI_ARR( transition, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
     1345INSTANTIATE_MULTI_ARR( quantumState, lgBOUNDSCHECKVAL ); 
     1346INSTANTIATE_MULTI_ARR( transition, lgBOUNDSCHECKVAL ); 
    13421347 
    13431348 
  • branches/newmole/source/container_classes.h

    r2023 r2112  
    3232//! basic_pntr - base class for generalization of normal pointers that enables bounds checking 
    3333//! it comes with the full set of operators that you would expect for a random access pointer 
    34 template<class T, int d, mem_layout ALLOC, bool lgBC> 
     34template<class T, bool lgBC> 
    3535class basic_pntr 
    3636{ 
     
    126126 
    127127//! pntr - interface class to replace normal pointers 
    128 template<class T, int d, mem_layout ALLOC, bool lgBC> 
    129 class pntr : public basic_pntr<T,d,ALLOC,lgBC> 
     128template<class T, bool lgBC> 
     129class pntr : public basic_pntr<T,lgBC> 
    130130{ 
    131131public: 
    132132        // constructors are not inherited, so define them again 
    133         pntr( T* p0 ) : basic_pntr<T,d,ALLOC,lgBC>( p0 ) {} 
    134         pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,d,ALLOC,lgBC>( p0, p1, p2 ) {} 
     133        pntr( T* p0 ) : basic_pntr<T,lgBC>( p0 ) {} 
     134        pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,lgBC>( p0, p1, p2 ) {} 
    135135        pntr() {} 
    136136        // the increment / decrement operators need to be recast... 
    137137        // otherwise expressions like p = ++q would be illegal for iterators... 
    138         pntr& operator++ () { return static_cast<pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator++()); } 
     138        pntr& operator++ () { return static_cast<pntr&>(basic_pntr<T,lgBC>::operator++()); } 
    139139        const pntr operator++ (int) { pntr t = *this; ++(*this); return t; } 
    140         pntr& operator-- () { return static_cast<pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator--()); } 
     140        pntr& operator-- () { return static_cast<pntr&>(basic_pntr<T,lgBC>::operator--()); } 
    141141        const pntr operator-- (int) { pntr t = *this; --(*this); return t; } 
    142142        // define p+n, p-n, p-q 
     
    147147 
    148148// this defines n+p 
    149 template<class T, int d, mem_layout ALLOC, bool lgBC> 
    150 inline const pntr<T,d,ALLOC,lgBC> operator+ ( const ptrdiff_t n, const pntr<T,d,ALLOC,lgBC>& t ) 
    151 { 
    152         pntr<T,d,ALLOC,lgBC> s = t; 
     149template<class T, bool lgBC> 
     150inline const pntr<T,lgBC> operator+ ( const ptrdiff_t n, const pntr<T,lgBC>& t ) 
     151{ 
     152        pntr<T,lgBC> s = t; 
    153153        s += n; 
    154154        return s; 
     
    156156 
    157157//! const_pntr - same as pntr, except that it replaces const pointers rather than normal pointers 
    158 template<class T, int d, mem_layout ALLOC, bool lgBC> 
    159 class const_pntr : public basic_pntr<T,d,ALLOC,lgBC> 
     158template<class T, bool lgBC> 
     159class const_pntr : public basic_pntr<T,lgBC> 
    160160{ 
    161161public: 
    162162        // constructors are not inherited, so define them again 
    163         const_pntr( T* p0 ) : basic_pntr<T,d,ALLOC,lgBC>( p0 ) {} 
    164         const_pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,d,ALLOC,lgBC>( p0, p1, p2 ) {} 
     163        const_pntr( T* p0 ) : basic_pntr<T,lgBC>( p0 ) {} 
     164        const_pntr( T* p0, T* p1, T* p2 ) : basic_pntr<T,lgBC>( p0, p1, p2 ) {} 
    165165        const_pntr() {} 
    166166        // make sure we can assign a pntr to a const_pntr by creating an implicit conversion to const_pntr 
    167         const_pntr( const pntr<T,d,ALLOC,lgBC>& t ) : basic_pntr<T,d,ALLOC,lgBC>( t ) {} 
     167        const_pntr( const pntr<T,lgBC>& t ) : basic_pntr<T,lgBC>( t ) {} 
    168168        // the increment / decrement operators need to be recast... 
    169169        // otherwise expressions like *p++ = 1. would be legal for const_iterators... 
    170         const_pntr& operator++ () { return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator++()); } 
     170        const_pntr& operator++ () { return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator++()); } 
    171171        const const_pntr operator++ (int) { const_pntr t = *this; ++(*this); return t; } 
    172         const_pntr& operator-- () { return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator--()); } 
     172        const_pntr& operator-- () { return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator--()); } 
    173173        const const_pntr operator-- (int) { const_pntr t = *this; --(*this); return t; } 
    174174        const_pntr& operator+= ( const ptrdiff_t n ) 
    175175        { 
    176                 return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator+=(n)); 
     176                return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator+=(n)); 
    177177        } 
    178178        const_pntr& operator-= ( const ptrdiff_t n ) 
    179179        { 
    180                 return static_cast<const_pntr&>(basic_pntr<T,d,ALLOC,lgBC>::operator-=(n)); 
     180                return static_cast<const_pntr&>(basic_pntr<T,lgBC>::operator-=(n)); 
    181181        } 
    182182        // the dereference operators need to be recast... 
    183         const T& operator* () const { return static_cast<const T&>(basic_pntr<T,d,ALLOC,lgBC>::operator*()); } 
    184         const T* operator-> () const { return static_cast<const T*>(basic_pntr<T,d,ALLOC,lgBC>::operator->()); } 
     183        const T& operator* () const { return static_cast<const T&>(basic_pntr<T,lgBC>::operator*()); } 
     184        const T* operator-> () const { return static_cast<const T*>(basic_pntr<T,lgBC>::operator->()); } 
    185185        const T& operator[] ( const ptrdiff_t n ) const 
    186186        { 
    187                 return static_cast<const T&>(basic_pntr<T,d,ALLOC,lgBC>::operator[](n)); 
     187                return static_cast<const T&>(basic_pntr<T,lgBC>::operator[](n)); 
    188188        } 
    189189        // define p+n, p-n, p-q 
     
    194194 
    195195// this defines n+p 
    196 template<class T, int d, mem_layout ALLOC, bool lgBC> 
    197 inline const const_pntr<T,d,ALLOC,lgBC> operator+ ( const ptrdiff_t n, const const_pntr<T,d,ALLOC,lgBC>& t ) 
    198 { 
    199         const_pntr<T,d,ALLOC,lgBC> s = t; 
     196template<class T, bool lgBC> 
     197inline const const_pntr<T,lgBC> operator+ ( const ptrdiff_t n, const const_pntr<T,lgBC>& t ) 
     198{ 
     199        const_pntr<T,lgBC> s = t; 
    200200        s += n; 
    201201        return s; 
     
    275275//! multi_geom - this class maintains all the geometry information for multi_arr 
    276276//! keeping it separate makes it easy to clone the information from one multi_arr to another 
    277 template<int d,mem_layout ALLOC=MEM_LAYOUT_VAL,bool lgBC=lgBOUNDSCHECKVAL> 
     277template<int d,mem_layout ALLOC=MEM_LAYOUT_VAL> 
    278278class multi_geom 
    279279{ 
     
    382382#       pragma warning( disable : 4127 ) 
    383383#endif 
     384 
     385                STATIC_ASSERT ( ALLOC == C_TYPE || ALLOC == ARPA_TYPE ); 
     386 
    384387                if( ALLOC == ARPA_TYPE ) 
    385388                { 
     
    403406                { 
    404407                        TotalInsanity(); 
    405                 }                
     408                } 
    406409        } 
    407410 
     
    902905{ 
    903906        // ancillary data describing the memory layout of the multi_arr 
    904         multi_geom<d,ALLOC,lgBC> p_g; 
     907        multi_geom<d,ALLOC> p_g; 
    905908        T** p_psl[d-1];     // pointer arrays for ARPA structure 
    906909        valarray<T> p_dsl;  // this contains the actual data 
     
    921924        typedef size_t       size_type; 
    922925        typedef ptrdiff_t    difference_type; 
    923         typedef pntr<T,d,ALLOC,lgBC>       iterator; 
    924         typedef const_pntr<T,d,ALLOC,lgBC> const_iterator; 
     926        typedef pntr<T,lgBC>       iterator; 
     927        typedef const_pntr<T,lgBC> const_iterator; 
    925928 
    926929private: 
     
    951954                p_clear1(); 
    952955        } 
    953         multi_arr(const multi_geom<d,ALLOC,lgBC>& g) 
     956        multi_arr(const multi_geom<d,ALLOC>& g) 
    954957        { 
    955958                p_clear1(); 
     
    10261029#       pragma warning( disable : 4127 ) 
    10271030#endif 
     1031                STATIC_ASSERT ( ALLOC == C_TYPE || ALLOC == ARPA_TYPE ); 
     1032 
    10281033                if( ALLOC == ARPA_TYPE ) 
    10291034                { 
     
    10641069        } 
    10651070        // clone the geometry from another multi_arr 
    1066         void alloc(const multi_geom<d,ALLOC,lgBC>& g) 
     1071        void alloc(const multi_geom<d,ALLOC>& g) 
    10671072        { 
    10681073                if( &g != &p_g ) 
     
    16471652        } 
    16481653 
    1649         const multi_geom<d,ALLOC,lgBC>& clone() const 
     1654        const multi_geom<d,ALLOC>& clone() const 
    16501655        { 
    16511656                return p_g; 
     
    17191724 
    17201725// on Mac systems these instantiations need to be extern in order to avoid duplicate symbols 
    1721 #define INSTANTIATE_MULTI_ARR( TYPE, LAYOUT, BC ) \ 
    1722 INST_EXTERN template class pntr<TYPE,2,LAYOUT,BC>; \ 
    1723 INST_EXTERN template class pntr<TYPE,3,LAYOUT,BC>; \ 
    1724 INST_EXTERN template class pntr<TYPE,4,LAYOUT,BC>; \ 
    1725 INST_EXTERN template class pntr<TYPE,5,LAYOUT,BC>; \ 
    1726 INST_EXTERN template class pntr<TYPE,6,LAYOUT,BC>; \ 
    1727 INST_EXTERN template class const_pntr<TYPE,2,LAYOUT,BC>; \ 
    1728 INST_EXTERN template class const_pntr<TYPE,3,LAYOUT,BC>; \ 
    1729 INST_EXTERN template class const_pntr<TYPE,4,LAYOUT,BC>; \ 
    1730 INST_EXTERN template class const_pntr<TYPE,5,LAYOUT,BC>; \ 
    1731 INST_EXTERN template class const_pntr<TYPE,6,LAYOUT,BC> 
    1732  
    1733 INSTANTIATE_MULTI_ARR( bool, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
    1734 INSTANTIATE_MULTI_ARR( long, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
    1735 INSTANTIATE_MULTI_ARR( realnum, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
    1736 INSTANTIATE_MULTI_ARR( double, MEM_LAYOUT_VAL, lgBOUNDSCHECKVAL ); 
    1737 INSTANTIATE_MULTI_ARR( double, C_TYPE, lgBOUNDSCHECKVAL ); 
     1726#define INSTANTIATE_MULTI_ARR( TYPE, BC ) \ 
     1727INST_EXTERN template class pntr<TYPE,BC>; \ 
     1728INST_EXTERN template class const_pntr<TYPE,BC>; 
     1729 
     1730INSTANTIATE_MULTI_ARR( bool, lgBOUNDSCHECKVAL ); 
     1731INSTANTIATE_MULTI_ARR( long, lgBOUNDSCHECKVAL ); 
     1732INSTANTIATE_MULTI_ARR( realnum,lgBOUNDSCHECKVAL ); 
     1733INSTANTIATE_MULTI_ARR( double, lgBOUNDSCHECKVAL ); 
    17381734 
    17391735 
     
    17581754        typedef long         size_type; 
    17591755        typedef ptrdiff_t    difference_type; 
    1760         typedef pntr<T,1,FLX_TYPE,lgBC>       iterator; 
    1761         typedef const_pntr<T,1,FLX_TYPE,lgBC> const_iterator; 
     1756        typedef pntr<T,lgBC>       iterator; 
     1757        typedef const_pntr<T,lgBC> const_iterator; 
    17621758 
    17631759private: 
  • branches/newmole/source/grains.cpp

    r2079 r2112  
    3333inline double ASINH(double x) 
    3434{ 
    35         if( abs(x) <= 2.3e-4 ) 
    36                 return x - pow3(x)/6.; 
    37         else if( abs(x) <= 8.e-3 ) 
     35        if( abs(x) <= 8.e-3 ) 
    3836                return ((0.075*pow2(x) - 1./6.)*pow2(x) + 1.)*x; 
    3937        else if( abs(x) <= 1./sqrt(DBL_EPSILON) ) 
     
    4745        { 
    4846                if( x < 0. ) 
    49                         return -log(-2.*x); 
     47                        return -(log(-x)+LN_TWO); 
    5048                else 
    51                         return log(2.*x); 
     49                        return log(x)+LN_TWO; 
    5250        } 
    5351} 
     
    145143                return 1.e-7; 
    146144        else 
    147                 return 3.e-6*pow((double)gv.bin[nd]->dustp[0],-0.85)*pow(e*EVRYD*1.e-3,1.5); 
     145                return 3.e-6*gv.bin[nd]->eec*sqrt(pow3(e*EVRYD*1.e-3)); 
    148146} 
    149147         
     
    192190STATIC void UpdatePot2(long,long); 
    193191/* Helper function to calculate primary and secondary yields and the average electron energy at infinity */ 
    194 STATIC void Yfunc(long,long,double,double,double,double,double,/*@out@*/double*,/*@out@*/double*, 
     192inline void Yfunc(long,long,double,double,double,double,double,/*@out@*/double*,/*@out@*/double*, 
    195193                  /*@out@*/double*,/*@out@*/double*); 
    196194/* This calculates the y0 function for band electrons (Sect. 4.1.3/4.1.4 of WDB06) */ 
     
    203201STATIC double y1psa(long,long,double); 
    204202/* This calculates the y2 function for primary and Auger electrons (Eq. 8 of WDB06) */ 
    205 STATIC double y2pa(double,double,long,double*); 
     203inline double y2pa(double,double,long,double*); 
    206204/* This calculates the y2 function for secondary electrons (Eq. 20-21 of WDB06) */ 
    207 STATIC double y2s(double,double,long,double*); 
     205inline double y2s(double,double,long,double*); 
    208206/* find highest ionization stage with non-zero population */ 
    209207STATIC long HighestIonStage(void); 
     
    32163214        } 
    32173215 
     3216        double GrainPot = chrg2pot(Zg,nd); 
     3217 
    32183218        if( nfill > ipLo ) 
    32193219        { 
     
    32413241                        /* calculate yield for band structure */ 
    32423242                        Ehi = Ehi_band = anu[i] - ThresInfVal - Emin; 
    3243                         Wcorr = ThresInfVal + Emin - chrg2pot(Zg,nd); 
     3243                        Wcorr = ThresInfVal + Emin - GrainPot; 
    32443244                        Eel = anu[i] - DustWorkFcn; 
    32453245                        yzero = y0b( nd, nz, i ); 
     
    32523252 
    32533253                        /* add in yields for inner shell ionization */ 
    3254                         for( ns=1; ns < gv.bin[nd]->nShells; ns++ ) 
     3254                        unsigned long nsmax = gv.bin[nd]->nShells; 
     3255                        for( ns=1; ns < nsmax; ns++ ) 
    32553256                        { 
    32563257                                sptr = gv.bin[nd]->sd[ns]; 
     
    32683269 
    32693270                                /* add in Auger yields */ 
    3270                                 for( n=0; n < sptr->nData; n++ ) 
     3271                                long nmax = sptr->nData; 
     3272                                for( n=0; n < nmax; n++ ) 
    32713273                                { 
    32723274                                        double max = sptr->AvNr[n]*sptr->p[i]; 
    3273                                         Ehi = sptr->Ener[n] - chrg2pot(Zg,nd); 
     3275                                        Ehi = sptr->Ener[n] - GrainPot; 
    32743276                                        Eel = sptr->Ener[n]; 
    32753277                                        Yfunc(nd,nz,sptr->y01A[n][i],max,Elo,Ehi,Eel,&Yp1,&Ys1,&Ehp,&Ehs); 
     
    34323434 
    34333435/* Helper function to calculate primary and secondary yields and the average electron energy at infinity */ 
    3434 STATIC void Yfunc(long nd, 
     3436inline void Yfunc(long nd, 
    34353437                  long nz, 
    34363438                  double y01, 
     
    34723474                /* this is Eq. 18 of WDB06 */ 
    34733475                /* Eel may be negative near threshold -> set yield to zero */ 
    3474                 f3 = max(Eel,0.)/(eps*elec_esc_length(Eel,nd)*(1./gv.bin[nd]->AvRadius + 1.e7)); 
     3476                f3 = max(Eel,0.)/(eps*elec_esc_length(Eel,nd)*gv.bin[nd]->eyc); 
    34753477                *Ys = y2sec*f3*min(y01,maxval); 
    34763478        } 
     
    36143616 
    36153617/* This calculates the y2 function for primary and Auger electrons (Eq. 8 of WDB06) */ 
    3616 STATIC double y2pa(double Elo, 
     3618inline double y2pa(double Elo, 
    36173619                   double Ehi, 
    36183620                   long Zg, 
     
    36583660 
    36593661/* This calculates the y2 function for secondary electrons (Eqs. 20-21 of WDB06) */ 
    3660 STATIC double y2s(double Elo, 
     3662inline double y2s(double Elo, 
    36613663                  double Ehi, 
    36623664                  long Zg, 
     
    37133715                                { 
    37143716                                        N0 = alpha*(1./sqR0 - 1./sqRh); 
    3715                                         E0 = alpha*ETILDE*(ASINH(x) + ASINH(yl) - yh/sqRh); 
     3717                                        E0 = alpha*ETILDE*(ASINH(x*sqR0 + yl*sqRh) - yh/sqRh); 
    37163718                                } 
    37173719                        } 
  • branches/newmole/source/grains_mie.cpp

    r1918 r2112  
    10881088        mie_next_data(chFile,io2,chLine,&dl); 
    10891089        mie_read_realnum(chFile,chLine,&gv.bin[nd]->dustp[0],true,dl); 
     1090        /* constant needed in the evaluation of the electron escape length */ 
     1091        gv.bin[nd]->eec = pow((double)gv.bin[nd]->dustp[0],-0.85); 
    10901092 
    10911093        /* molecular weight of grain molecule (amu) */ 
     
    11081110        mie_next_data(chFile,io2,chLine,&dl); 
    11091111        mie_read_realnum(chFile,chLine,&gv.bin[nd]->AvRadius,true,dl); 
     1112        gv.bin[nd]->eyc = 1./gv.bin[nd]->AvRadius + 1.e7; 
    11101113 
    11111114        /* average grain area <4pi*a^2> for entire size distr (cm^2) */ 
     
    12791282                                        gv.bin[nd2]->dustp[j] = gv.bin[nd]->dustp[j]; 
    12801283                                } 
     1284                                gv.bin[nd2]->eec = gv.bin[nd]->eec; 
     1285                                gv.bin[nd2]->eyc = gv.bin[nd]->eyc; 
    12811286                                gv.bin[nd2]->DustWorkFcn = gv.bin[nd]->DustWorkFcn; 
    12821287                                gv.bin[nd2]->BandGap = gv.bin[nd]->BandGap; 
  • branches/newmole/source/grains_qheat.cpp

    r2023 r2112  
    622622        if( trace.lgTrace && trace.lgDustBug ) 
    623623        { 
    624                 fprintf( ioQQQ, "   grain heating: %.4e, integral %.4e, total rate %.4e\n", 
    625                          gv.bin[nd]->GrainHeat,integral,Phi[0]); 
     624                double Rate2 = 0.; 
     625                for( int nz=0; nz < gv.bin[nd]->nChrg; nz++ ) 
     626                        Rate2 += gv.bin[nd]->chrg[nz]->FracPop*gv.bin[nd]->chrg[nz]->HeatingRate2; 
     627 
     628                fprintf( ioQQQ, "   grain heating: %.4e, integral %.4e, total rate %.4e lgNegRate %c\n", 
     629                         gv.bin[nd]->GrainHeat,integral,Phi[0],TorF(lgNegRate)); 
    626630                fprintf( ioQQQ, "   av grain temp %.4e av grain enthalpy (Ryd) %.4e\n", 
    627631                         gv.bin[nd]->tedust,Umax); 
    628632                fprintf( ioQQQ, "   fwhm^2/(4ln2*c2/c0): %.4e fwhm (Ryd) %.4e fwhm/Umax %.4e\n", 
    629633                         NumEvents,fwhm,FwhmRatio ); 
    630                 fprintf( ioQQQ, "   lgQHTooWide %d\n", gv.bin[nd]->lgQHTooWide ); 
     634                fprintf( ioQQQ, "   HeatingRate1 %.4e HeatingRate2 %.4e lgQHTooWide %c\n", 
     635                         gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3, Rate2*gv.bin[nd]->cnv_H_pCM3, 
     636                         TorF(gv.bin[nd]->lgQHTooWide) ); 
    631637        } 
    632638 
     
    911917         * energies, the reshuffling for higher energies is done in the next loop 
    912918         * phiTilde has units events/H/s/cell at default depletion */ 
     919 
     920        double NegHeatingRate = 0.; 
    913921 
    914922        for( nz=0; nz < gv.bin[nd]->nChrg; nz++ ) 
     
    983991                *check += gptr->FracPop*check1*EN1RYD*gv.bin[nd]->cnv_H_pCM3; 
    984992 
     993                sum += gptr->FracPop*check1*EN1RYD*gv.bin[nd]->cnv_H_pCM3; 
     994 
    985995                if( DEBUG_LOC ) 
    986996                { 
     
    9901000                                integral += phiTilde[i]*gv.bin[nd]->cnv_H_pCM3*rfield.anu[i]*EN1RYD; 
    9911001                        } 
    992                         sum += gptr->FracPop*check1*EN1RYD*gv.bin[nd]->cnv_H_pCM3; 
    9931002                        dprintf( ioQQQ, " integral test 1: integral %.6e %.6e\n", integral, sum ); 
    9941003                } 
     
    10071016 
    10081017                /* >>chng 03 nov 06, check for extremely low HeatingRate and save CPU time, pah_crash.in, PvH */ 
    1009                 if( fabs(gptr->HeatingRate2*gv.bin[nd]->cnv_H_pCM3) > 0.05*CONSERV_TOL*gv.bin[nd]->GrainHeat )  
     1018                if( gptr->HeatingRate2*gv.bin[nd]->cnv_H_pCM3 > 0.05*CONSERV_TOL*gv.bin[nd]->GrainHeat )  
    10101019                { 
    10111020                        double *RateArr,Sum,ESum,DSum,Delta,E_av2,Corr; 
     
    10761085                        } 
    10771086 
     1087                        sum += gptr->FracPop*gptr->HeatingRate2*gv.bin[nd]->cnv_H_pCM3; 
     1088 
    10781089                        if( DEBUG_LOC ) 
    10791090                        { 
     
    10831094                                        integral += phiTilde[i]*gv.bin[nd]->cnv_H_pCM3*rfield.anu[i]*EN1RYD; 
    10841095                                } 
    1085                                 sum += gptr->FracPop*gptr->HeatingRate2*gv.bin[nd]->cnv_H_pCM3; 
    10861096                                dprintf( ioQQQ, " integral test 2: integral %.6e %.6e\n", integral, sum ); 
    10871097                        } 
    10881098 
    10891099                        free( RateArr ); 
     1100                } 
     1101                else 
     1102                { 
     1103                        NegHeatingRate += gptr->FracPop*gptr->HeatingRate2*gv.bin[nd]->cnv_H_pCM3; 
    10901104                } 
    10911105        } 
     
    11091123 
    11101124        /* >>chng 03 nov 06, check for extremely low HeatingRate and save CPU time, PvH */ 
    1111         if( fabs(gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3) > 0.05*CONSERV_TOL*gv.bin[nd]->GrainHeat ) 
     1125        if( gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3 > 0.05*CONSERV_TOL*gv.bin[nd]->GrainHeat ) 
    11121126        { 
    11131127                /* limits for Taylor expansion of (1+x)*exp(-x) */ 
     
    11531167                        ylo = yhi; 
    11541168                } 
    1155         } 
    1156  
    1157         if( DEBUG_LOC ) 
    1158         { 
    1159                 double integral = 0.; 
     1169 
     1170                sum += gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3; 
     1171 
     1172                if( DEBUG_LOC ) 
     1173                { 
     1174                        double integral = 0.; 
     1175                        for( i=0; i < gv.bin[nd]->qnflux; i++ ) 
     1176                        { 
     1177                                integral += phiTilde[i]*gv.bin[nd]->cnv_H_pCM3*rfield.anu[i]*EN1RYD; 
     1178                        } 
     1179                        dprintf( ioQQQ, " integral test 3: integral %.6e %.6e\n", integral, sum ); 
     1180                } 
     1181        } 
     1182        else 
     1183        { 
     1184                NegHeatingRate += gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3; 
     1185        } 
     1186 
     1187        /* here we account for the negative heating rates, we simply do that by scaling the entire 
     1188         * phiTilde array down by a constant factor such that the total amount of energy is conserved 
     1189         * This treatment assures that phiTilde never goes negative, which avoids problems further on */ 
     1190        if( NegHeatingRate < 0. ) 
     1191        { 
     1192                double scale_fac = (sum+NegHeatingRate)/sum; 
    11601193                for( i=0; i < gv.bin[nd]->qnflux; i++ ) 
    1161                 { 
    1162                         integral += phiTilde[i]*gv.bin[nd]->cnv_H_pCM3*rfield.anu[i]*EN1RYD; 
    1163                 } 
    1164                 sum += gv.bin[nd]->HeatingRate1*gv.bin[nd]->cnv_H_pCM3; 
    1165                 dprintf( ioQQQ, " integral test 3: integral %.6e %.6e\n", integral, sum ); 
    1166         } 
     1194                        phiTilde[i] *= scale_fac; 
     1195 
     1196                sum += NegHeatingRate; 
     1197 
     1198                if( DEBUG_LOC ) 
     1199                { 
     1200                        double integral = 0.; 
     1201                        for( i=0; i < gv.bin[nd]->qnflux; i++ ) 
     1202                        { 
     1203                                integral += phiTilde[i]*gv.bin[nd]->cnv_H_pCM3*rfield.anu[i]*EN1RYD; 
     1204                        } 
     1205