Show
Ignore:
Timestamp:
06/11/08 02:41:14 (7 months ago)
Author:
gary
Message:

iso_level.cpp - use difference in ionization / recombination rates in source/sink for exchange with next resolved atoms in next lower ionization stage. At high densities excited states have very large ion/rec rates which cancel one another when level is in LTE. Using the differences is more stable fur such densities.

trivial changes in comments
ion_solver.cpp
iso.h
iso_ionize_recombine.cpp

with this change in iso_level.cpp test suite has following issues:
blr_hizqso.out: crashed
blr_n09_p20_Z20.out: crashed
limit_conserve.out: crashed
all crashes are due to radius_increment finds inconsistent populations
radius_increment.cpp at line number 152

following have asserts thrown;
may be serious, should look at:
orion_hii_pdr - molecular ions changes, esp HeH+

trivial changes;
pdr_coolbb
blr_n13_p18_Z20 - took more iterations per zone
blr_n12_p19 slight change in 1640

known problem unrelated to this:
grains_conserve

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/source/iso_level.cpp

    r2099 r2107  
    1111#include "grainvar.h" 
    1212#include "he.h" 
    13 #include "heavy.h" 
    1413#include "helike.h" 
    1514#include "hydrogenic.h" 
     
    2423#include "thirdparty.h" 
    2524#include "trace.h" 
    26 #include "yield.h" 
    2725 
    2826/* solve for level populations  */ 
     
    9088 
    9189        /* these two collision rates must be the same or we are in big trouble, 
    92          * since used interchangeably */ 
     90         * since used interchangably */ 
    9391        ASSERT( ionbal.CollIonRate_Ground[nelem][nelem-ipISO][0]< SMALLFLOAT || 
    9492                fabs( iso.ColIoniz[ipISO][nelem][0]* collider / 
     
    375373#endif 
    376374 
     375                /* derive source/sink terms for ion/rec terms coupling resolved atoms  
     376                 * to lower ionization stages */ 
    377377                if( nelem-ipISO >= 1 && ionbal.RateIonizTot[nelem][nelem-ipISO-1] > 0.) 
    378378                { 
     379                        double sum_recom =0. , sum_ioniz = 0.; 
     380                        sum_popn_ov_ion = 0.; 
     381                        /* if lower stage of ionization is itself resolved then we must 
     382                         * sum over rates between levels and its continuum, the ion we 
     383                         * are now solving */ 
     384                        if( ipISO+1<NISO ) 
     385                        { 
     386                                for( level=0; level < iso.numLevels_local[ipISO+1][nelem]; level++ ) 
     387                                { 
     388                                        sum_popn_ov_ion += StatesElem[ipISO+1][nelem][level].Pop; 
     389 
     390                                        /* sum of all ionization processes from levels to ion we 
     391                                         * now consider - use difference in ionization / recombination  
     392                                         * since at high densities each of these terms are very 
     393                                         * large but nearly cancel */ 
     394                                        double one = iso.RateCont2Level[ipISO+1][nelem][level] - 
     395                                                StatesElem[ipISO+1][nelem][level].Pop *  
     396                                                iso.RateLevel2Cont[ipISO+1][nelem][level]; 
     397 
     398                                        /* sign determines whether this is net ionization or  
     399                                         * recombination process.  Ground & metastable states have  
     400                                         * large departure coefficients so are net ionization, 
     401                                         * excited states have departure coefficients that 
     402                                         * asymptotically approach unity from below, so are net 
     403                                         * recombination */ 
     404                                        if( one > 0 ) 
     405                                                sum_recom += one; 
     406                                        else 
     407                                                sum_ioniz -= one; 
     408                                } 
     409                                ASSERT( sum_recom>=0. && sum_ioniz>=0. ); 
     410                                sum_ioniz  /= MAX2(SMALLDOUBLE , sum_popn_ov_ion); 
     411                        } 
     412                        else 
     413                        { 
     414                                /* lower stage is not resolved */ 
     415                                sum_ioniz = ionbal.RateIonizTot[nelem][nelem-ipISO-1]; 
     416                                sum_recom = ionbal.RateRecomTot[nelem][nelem-ipISO-1]; 
     417                        } 
    379418                        /* now add ionization from next lower stage */ 
    380                         source += ionbal.RateIonizTot[nelem][nelem-ipISO-1]* 
     419                        source += sum_ioniz* 
    381420                                dense.xIonDense[nelem][nelem-ipISO-1];   
    382421 
    383                         /* now add recombination to next lower stage ground */ 
    384                         sink += ionbal.RateRecomTot[nelem][nelem-ipISO-1]; 
    385                 } 
    386                  
     422                        /* now add recombination to next lower stage, units are s-1 */ 
     423                        sink += sum_recom; 
     424                } 
     425 
    387426                creation[0] += source/SDIV(dense.xIonDense[nelem][nelem+1-ipISO]); 
    388  
    389427                for( level=0; level < numlevels_local; level++ ) 
    390428                { 
     
    577615 
    578616        /* all solvers end up here */ 
    579         /* sum_popn_ov_ion will become the ratio of iso to parent 
     617 
     618        /* sum_popn_ov_ion will become the ratio of this atom to parent 
    580619         * species, create sum of level pops per ion first */ 
    581620        sum_popn_ov_ion = 0.; 
    582621 
    583         /* this is total ionization of this species referenced to the ground state */ 
     622        /* this is total ionization rate, s-1, of this species referenced to  
     623         * the total abundance */ 
    584624        ionbal.RateIonizTot[nelem][nelem-ipISO] = 0.; 
    585  
    586625        for( level=0; level < numlevels_local; level++ ) 
    587626        {