Documentation


explicit_stepper.h

Go to the documentation of this file.
00001 #ifndef ANIMAL_INTEGRATION_EXPLICIT_STEPPER_H
00002 #define ANIMAL_INTEGRATION_EXPLICIT_STEPPER_H
00003 
00004 #include <animal/integration/stepper.h>
00005 
00006 
00007 
00008 namespace animal { namespace integration {
00009 
00010 // -------------------------------------------------------------
00011 //  
00012 //  Step_Doubling class.
00030 //  
00031 // -------------------------------------------------------------
00032 
00033 template <
00034   class SolverF,
00035   class HSmallerF,
00036   class HLargerF,
00037   class IsDifferentF >
00038 
00039 struct Step_Doubling
00040   : public Stepper_Function<SolverF,HSmallerF,HLargerF,IsDifferentF>
00041 {
00042   State initial_S_copy;  
00043   State final_S_eval;    
00044   
00046   Derivative initial_D;
00047   
00048   unsigned int ngood;  
00049   unsigned int nbad;   
00050   
00052   Step_Doubling()
00053     {}
00054   
00056   Step_Doubling
00057     (
00058         const SolverF& slf,
00059         const HSmallerF& hsf, 
00060         const HLargerF& hlf,
00061         const IsDifferentF& isdf
00062     )
00063   : Stepper_Function
00064         <
00065             SolverF,
00066             HSmallerF,
00067             HLargerF,
00068             IsDifferentF
00069         >(slf, hsf, hlf, isdf),
00070     initial_S_copy( slf.curr_size ),
00071     final_S_eval( slf.curr_size ),
00072     initial_D( slf.curr_size ),
00073     ngood(0), nbad(0)
00074     {}
00075   
00077   void resize(const typename Derivative::sizeype size)
00078     {
00079       solve.resize(size);
00080       
00081       Derivative initial_S_copy(size);
00082       Derivative final_S_eval(size);
00083       Derivative initial_D(size);
00084     }
00085   
00088   void operator()(const Model& M,
00089           State& S,
00090           const Real t,
00091           const Real htry, Real& hdid, Real& hnext)
00092     {
00093       initial_S_copy = S;
00094       operator()(M, initial_S_copy, S, t, htry, hdid, hnext);
00095     }
00096   void operator()(const Model& M,
00097           const State& initial_S,
00098           State& final_S,
00099           const Real t,
00100           const Real htry, Real& hdid, Real& hnext)
00101     {
00102       bool divide_step = true;
00103       
00104       Real h = htry; // Stepsize to be attempted (initial trial value)
00105       Real h_2;
00106       
00107       // Derivative first evaluation
00108       solve.writeDerivative(M, initial_S, initial_D, t);
00109       
00110       while ( divide_step )
00111     {
00112       hdid = h; // Stepsize that was actually accomplished
00113       h_2 = 0.5*h;
00114       
00115       // Take a full step
00116       solve(M, initial_S, final_S_eval, initial_D, t, h);
00117       
00118         // Take two half steps
00119         solve(M, initial_S, final_S, initial_D, t, h_2);
00120         solve(M, final_S, (t + h_2), h_2);
00121 
00122         if ( isDifferent(M, final_S_eval, final_S, t) )
00123       {
00124           h = hsmaller(M, initial_S, t, h);
00125 #if DEBUG
00126           nbad++;
00127 #endif
00128       }
00129       else
00130         {
00131           divide_step = false;
00132           h = hlarger(M, initial_S, t, h);
00133 #if DEBUG
00134           ngood++;
00135 #endif
00136         }
00137     }
00138       
00139       hnext = h; // Estimated next stepsize
00140     }
00142   
00143 }; // struct Step_Doubling
00144 
00145 
00146 
00147 // -------------------------------------------------------------
00148 //  
00149 //  Step_Back_And_Forth class.
00164 //  
00165 // -------------------------------------------------------------
00166 
00167 template <
00168   class SolverF,
00169   class HSmallerF,
00170   class HLargerF,
00171   class IsDifferentF >
00172 
00173 struct Step_Back_And_Forth
00174   : public Step_Doubling<SolverF,HSmallerF,HLargerF,IsDifferentF>
00175 {
00177   Step_Back_And_Forth(const SolverF& slf,
00178               const HSmallerF& hsf, const HLargerF& hlf,
00179               const IsDifferentF& isdf)
00180   : Step_Doubling<SolverF,HSmallerF,HLargerF,IsDifferentF>(slf, hsf, hlf, isdf)
00181     {}
00182   
00185   void operator()(const Model& M,
00186           State& S,
00187           const Real t,
00188           const Real htry, Real& hdid, Real& hnext)
00189     {
00190       initial_S_copy = S;
00191       operator()(M, initial_S_copy, S, t, htry, hdid, hnext);
00192     }
00193   void operator()(const Model& M,
00194           const State& initial_S,
00195           State& final_S,
00196           const Real t,
00197           const Real htry, Real& hdid, Real& hnext)
00198     {
00199       bool divide_step = true;
00200       
00201       Real h = htry; // Stepsize to be attempted (initial trial value)
00202       
00203       // Derivative first evaluation
00204       solve.writeDerivative(M, initial_S, initial_D, t);
00205       
00206       while ( divide_step )
00207     {
00208       hdid = h; // Stepsize that was actually accomplished
00209           
00210           // Take a step
00211           solve(M, initial_S, final_S, initial_D, t, h);
00212           
00213           if ( isDifferent(M, initial_S, final_S, t) )
00214         {
00215           h = hsmaller(M, initial_S, t, h);
00216 #if DEBUG
00217           nbad++;
00218 #endif
00219         }
00220       else
00221         {
00222           divide_step = false;
00223           h = hlarger(M, initial_S, t, h);
00224 #if DEBUG
00225           ngood++;
00226 #endif
00227         }
00228     }
00229       
00230       hnext = h; // Estimated next stepsize
00231     }
00233   
00234 }; // struct Step_Back_And_Forth
00235 
00236 } } // namespace animal { namespace integration {
00237 
00238 
00239 
00240 #endif // ANIMAL_INTEGRATION_EXPLICIT_STEPPER_H

Generated on Thu Dec 23 13:52:24 2004 by doxygen 1.3.6