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
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;
00105 Real h_2;
00106
00107
00108 solve.writeDerivative(M, initial_S, initial_D, t);
00109
00110 while ( divide_step )
00111 {
00112 hdid = h;
00113 h_2 = 0.5*h;
00114
00115
00116 solve(M, initial_S, final_S_eval, initial_D, t, h);
00117
00118
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;
00140 }
00142
00143 };
00144
00145
00146
00147
00148
00149
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;
00202
00203
00204 solve.writeDerivative(M, initial_S, initial_D, t);
00205
00206 while ( divide_step )
00207 {
00208 hdid = h;
00209
00210
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;
00231 }
00233
00234 };
00235
00236 } }
00237
00238
00239
00240 #endif // ANIMAL_INTEGRATION_EXPLICIT_STEPPER_H