| 1 | Index: conv_temp_eden_ioniz.cpp |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- conv_temp_eden_ioniz.cpp (revision 3610) |
|---|
| 4 | +++ conv_temp_eden_ioniz.cpp (working copy) |
|---|
| 5 | @@ -96,7 +96,6 @@ |
|---|
| 6 | // here starts the standard solver for variable temperature |
|---|
| 7 | iter_track TeTrack; |
|---|
| 8 | double t1=0, error1=0, t2, error2; |
|---|
| 9 | - bool lgHighTeSearch = false; |
|---|
| 10 | |
|---|
| 11 | t2 = phycon.te; |
|---|
| 12 | error2 = CoolHeatError( t2 ); |
|---|
| 13 | @@ -105,103 +104,43 @@ |
|---|
| 14 | { |
|---|
| 15 | const int DEF_ITER = 10; |
|---|
| 16 | const double DEF_FACTOR = 0.02; |
|---|
| 17 | - double step, factor = DEF_FACTOR; |
|---|
| 18 | + const double BIG_FACTOR = 0.05; |
|---|
| 19 | + double step, factor; |
|---|
| 20 | |
|---|
| 21 | TeTrack.clear(); |
|---|
| 22 | |
|---|
| 23 | - // set up an initial guess for the bracket |
|---|
| 24 | - // t2 was already initialized outside the main loop, or is copied from the |
|---|
| 25 | - // previous iteration. don't record this evaluation, it may be poorly converged |
|---|
| 26 | - for( int i=0; i < 2 && !lgAbort; ++i ) |
|---|
| 27 | - { |
|---|
| 28 | - t1 = t2; |
|---|
| 29 | - error1 = error2; |
|---|
| 30 | + t1 = t2; |
|---|
| 31 | + error1 = error2; |
|---|
| 32 | |
|---|
| 33 | - // the factor 1.2 creates 20% safety margin |
|---|
| 34 | - step = safe_div( -1.2*error1, conv.dCmHdT, 0. ); |
|---|
| 35 | - step = sign( min( abs(step), factor*t1 ), step ); |
|---|
| 36 | - t2 = t1 + step; |
|---|
| 37 | - error2 = CoolHeatError( t2 ); |
|---|
| 38 | - TeTrack.add( t2, error2 ); |
|---|
| 39 | - } |
|---|
| 40 | + step = abs(safe_div( 2.*error1, conv.dCmHdT, 0. )); |
|---|
| 41 | |
|---|
| 42 | - int j = 0; |
|---|
| 43 | - |
|---|
| 44 | - // now hunt until we have bracketed the solution |
|---|
| 45 | - while( error1*error2 > 0. && j++ < 2*DEF_ITER && !lgAbort ) |
|---|
| 46 | - { |
|---|
| 47 | - t1 = t2; |
|---|
| 48 | - error1 = error2; |
|---|
| 49 | - double deriv = TeTrack.deriv(7); |
|---|
| 50 | - // the factor 1.2 creates 20% safety margin |
|---|
| 51 | - step = safe_div( -1.2*error1, deriv, 0. ); |
|---|
| 52 | - step = sign( min( abs(step), factor*t1 ), step ); |
|---|
| 53 | - t2 = t1 + step; |
|---|
| 54 | - error2 = CoolHeatError( t2 ); |
|---|
| 55 | - TeTrack.add( t2, error2 ); |
|---|
| 56 | - } |
|---|
| 57 | - |
|---|
| 58 | - if( trace.nTrConvg >= 2 && error1*error2 > 0. && !lgAbort ) |
|---|
| 59 | - { |
|---|
| 60 | - fprintf( ioQQQ, " ConvTempEdenIoniz: bracket1 fails t1: %e %e t2: %e %e\n", |
|---|
| 61 | - t1, error1, t2, error2 ); |
|---|
| 62 | - TeTrack.print_history(); |
|---|
| 63 | - } |
|---|
| 64 | - |
|---|
| 65 | - // If we reach this point without having bracketed the solution this means |
|---|
| 66 | - // that searching using the derivate doesn't work... This typically happens |
|---|
| 67 | - // when the heating and cooling curve no longer intersect, which implies |
|---|
| 68 | - // that C-H vs Te now has a local maximum, but doesn't change sign any more. |
|---|
| 69 | - // Hence we have reached a thermal front and we need to take a discontinuous |
|---|
| 70 | - // step up or down. In the first while loop we search upwards, in the second |
|---|
| 71 | - // downwards. |
|---|
| 72 | - |
|---|
| 73 | - int nUP = 2; |
|---|
| 74 | - |
|---|
| 75 | - if( error2 < 0. && !lgHighTeSearch && !lgAbort ) |
|---|
| 76 | - { |
|---|
| 77 | - lgHighTeSearch = true; |
|---|
| 78 | - nUP = 25; |
|---|
| 79 | - } |
|---|
| 80 | - |
|---|
| 81 | - // hunting using the derivative failed, so first start hunting upwards |
|---|
| 82 | + // set up a bracket for the temperature solution |
|---|
| 83 | + // t2 was already initialized outside the main loop, or is copied from the |
|---|
| 84 | + // previous iteration. don't record this evaluation, it may be poorly converged |
|---|
| 85 | // |
|---|
| 86 | - // guard against overrunning the maximum temperature limit of the code |
|---|
| 87 | - // so that we are guaranteed to get a chance to hunt downwards |
|---|
| 88 | - while( error1*error2 > 0. && j++ < (2+nUP)*DEF_ITER && !lgAbort && |
|---|
| 89 | - t2*(1.+factor) <= 0.99999*phycon.TEMP_LIMIT_HIGH ) |
|---|
| 90 | + // if we have reached a thermal front (which happens when the heating and |
|---|
| 91 | + // cooling curves no longer intersect near the solution from the previous |
|---|
| 92 | + // call to ConvTempEdenIoniz()) we may need to make a big adjustment to the |
|---|
| 93 | + // temperature. since we are only allowed to take baby steps, we should allow |
|---|
| 94 | + // for a large number of iterations here. |
|---|
| 95 | + for( int i=0; error1*error2 > 0. && i < 250 && !lgAbort; ++i ) |
|---|
| 96 | { |
|---|
| 97 | t1 = t2; |
|---|
| 98 | error1 = error2; |
|---|
| 99 | - if( lgHighTeSearch && t2 > 4000. ) |
|---|
| 100 | - factor = 0.05; |
|---|
| 101 | - t2 = t1*(1.+factor); |
|---|
| 102 | - error2 = CoolHeatError( t2 ); |
|---|
| 103 | - TeTrack.add( t2, error2 ); |
|---|
| 104 | - } |
|---|
| 105 | |
|---|
| 106 | - // hunting upwards failed, so start hunting downwards |
|---|
| 107 | - // we may need to take a big plunge downwards, so # of iter should be big |
|---|
| 108 | - // |
|---|
| 109 | - // don't guard against dropping below the minimum temperature limit of the |
|---|
| 110 | - // code so that we get an abort if the solver has completely lost the solution. |
|---|
| 111 | - // this is a serious condition that needs to be investigated... |
|---|
| 112 | - while( error1*error2 > 0. && j++ < (2+2*nUP+9)*DEF_ITER && !lgAbort ) |
|---|
| 113 | - { |
|---|
| 114 | - t1 = t2; |
|---|
| 115 | - error1 = error2; |
|---|
| 116 | - if( lgHighTeSearch && t2 <= 4000. ) |
|---|
| 117 | - factor = DEF_FACTOR; |
|---|
| 118 | - t2 = t1*(1.-factor); |
|---|
| 119 | + factor = ( t1 > 4000. ) ? BIG_FACTOR : DEF_FACTOR; |
|---|
| 120 | + step = min(step,factor*t1); |
|---|
| 121 | + t2 = t1 + sign( step, -error1 ); |
|---|
| 122 | error2 = CoolHeatError( t2 ); |
|---|
| 123 | TeTrack.add( t2, error2 ); |
|---|
| 124 | + step *= 2.; |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | factor = DEF_FACTOR; |
|---|
| 128 | |
|---|
| 129 | if( trace.nTrConvg >= 2 && error1*error2 > 0. && !lgAbort ) |
|---|
| 130 | { |
|---|
| 131 | - fprintf( ioQQQ, " ConvTempEdenIoniz: bracket2 fails t1: %e %e t2: %e %e\n", |
|---|
| 132 | + fprintf( ioQQQ, " ConvTempEdenIoniz: bracket fails t1: %e %e t2: %e %e\n", |
|---|
| 133 | t1, error1, t2, error2 ); |
|---|
| 134 | TeTrack.print_history(); |
|---|
| 135 | } |
|---|