Ticket #111: patch2

File patch2, 4.8 kB (added by peter, 2 years ago)

updated patch wrt r3610

Line 
1Index: 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                        }