00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _ARK4_H_
00012 #define _ARK4_H_
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 class dXConcept;
00027
00028
00029
00030 class XConcept
00031 {
00032
00033 void define(const XConcept& a_state);
00034
00035
00036 void copy(const XConcept& a_state);
00037
00038
00039 void increment(const dXConcept& a_increment, Real a_factor = 1.);
00040
00041 ~XConcept() {};
00042 };
00043
00044
00045
00046 class dXConcept
00047 {
00048
00049 void define(const XConcept& a_state);
00050
00051
00052 void init(const XConcept& a_state);
00053
00054
00055 void increment(const dXConcept& a_increment, Real a_factor = 1.);
00056
00057 ~dXConcept() {};
00058 };
00059
00060
00061
00062 class FEConcept
00063 {
00064
00065 void define(const XConcept& a_state, Real a_dt);
00066
00067
00068 void resetDt(Real a_dt);
00069
00070
00071 void operator()(dXConcept& a_result, Real a_time, const XConcept& a_state);
00072
00073 ~FEConcept() {};
00074 };
00075
00076
00077
00078 class FIConcept
00079 {
00080
00081 void define(const XConcept& a_state, Real a_dt, Real a_gamma);
00082
00083
00084 void resetDt(Real a_dt);
00085
00086
00087 void operator()(dXConcept& a_result, Real a_time, const XConcept& a_state);
00088
00089
00090 void solve(XConcept& a_soln, const dXConcept& a_rhs, Real a_time);
00091
00092 ~FIConcept() {};
00093 };
00094
00095 template <class X, class FI, class FE, class dX>
00096 class ARK4
00097 {
00098 public:
00099
00100 ARK4<X, FI, FE, dX>() { m_isDefined = false; }
00101
00102
00103 void define(const X& a_state, Real a_dt);
00104
00105
00106 void advance(Real a_time, X& a_state);
00107
00108
00109 void resetDt(Real a_dt);
00110
00111 bool isDefined() const { return m_isDefined; }
00112
00113
00114 static const int s_nStages = 6;
00115 static const Real s_gamma;
00116 static const Real s_aE[s_nStages][s_nStages];
00117 static const Real s_aI[s_nStages][s_nStages];
00118 static const Real s_b[s_nStages];
00119 static const Real s_c[s_nStages];
00120
00121 protected:
00122
00123 bool m_isDefined;
00124 Real m_dt;
00125 X m_phi[s_nStages];
00126 dX m_kE[s_nStages-1];
00127 dX m_kI[s_nStages-1];
00128 dX m_kEfinal;
00129 dX m_rhs;
00130 FI m_fI;
00131 FE m_fE;
00132
00133 private:
00134
00135
00136 static ARK4<XConcept, FIConcept, FEConcept, dXConcept> testConcept;
00137 };
00138
00139
00140
00141 template <class X, class FI, class FE, class dX>
00142 void ARK4<X, FI, FE, dX>::define(const X& a_state, Real a_dt)
00143 {
00144 m_dt = a_dt;
00145
00146 for (int stage = 0; stage < s_nStages; stage++)
00147 {
00148 m_phi[stage].define(a_state);
00149 }
00150
00151 for (int stage = 0; stage < s_nStages-1; stage++)
00152 {
00153 m_kE[stage].define(a_state);
00154 m_kI[stage].define(a_state);
00155 }
00156 m_kEfinal.define(a_state);
00157 m_rhs.define(a_state);
00158
00159 m_fI.define(a_state, m_dt, s_gamma);
00160
00161 m_fE.define(a_state, m_dt);
00162 m_isDefined = true;
00163 }
00164
00165
00166
00167
00168 template <class X, class FI, class FE, class dX>
00169 void ARK4<X, FI, FE, dX>::resetDt(Real a_dt)
00170 {
00171 CH_assert(isDefined());
00172
00173
00174 Real reltol = 1e-10;
00175 if (Abs(m_dt - a_dt) > m_dt*reltol)
00176 {
00177 m_dt = a_dt;
00178 m_fI.resetDt(m_dt);
00179 m_fE.resetDt(m_dt);
00180 }
00181 }
00182
00183
00184
00185
00186 template <class X, class FI, class FE, class dX>
00187 void ARK4<X, FI, FE, dX>::advance(Real a_time, X& a_state)
00188 {
00189 CH_assert(isDefined());
00190
00191 Real t[s_nStages];
00192 for (int stage = 0; stage < s_nStages; stage++)
00193 {
00194 t[stage] = a_time + s_c[stage] * m_dt;
00195 }
00196
00197
00198 m_phi[0].copy(a_state);
00199 for (int stage = 1; stage < s_nStages; stage++)
00200 {
00201 m_fE(m_kE[stage-1], t[stage-1], m_phi[stage-1]);
00202 m_fI(m_kI[stage-1], t[stage-1], m_phi[stage-1]);
00203
00204
00205
00206
00207 m_rhs.init(a_state);
00208 for (int j = 0; j < stage; j++)
00209 {
00210 m_rhs.increment(m_kE[j], s_aE[stage][j]);
00211 m_rhs.increment(m_kI[j], s_aI[stage][j]);
00212 }
00213
00214
00215 m_phi[stage].define(a_state);
00216 m_fI.solve(m_phi[stage], m_rhs, t[stage]);
00217 }
00218
00219
00220
00221
00222
00223
00224 const int stageFinal = s_nStages-1;
00225 Real tFinal = t[stageFinal];
00226
00227 m_fE(m_kEfinal, tFinal, m_phi[stageFinal]);
00228 a_state.copy(m_phi[stageFinal]);
00229 for (int j = 0; j < s_nStages-1; j++)
00230 {
00231 a_state.increment(m_kE[j], s_b[j] - s_aE[stageFinal][j]);
00232 }
00233
00234 a_state.increment(m_kEfinal, s_b[stageFinal] );
00235 }
00236
00237 template<class X, class FI, class FE, class dX>
00238 const Real ARK4<X, FI, FE, dX>::s_gamma = 0.25;
00239
00240
00241 template<class X, class FI, class FE, class dX>
00242 const Real ARK4<X, FI, FE, dX>::s_c[] = { 0.0, 0.5, 0.332, 0.62, 0.85, 1.0 };
00243
00244
00245 template<class X, class FI, class FE, class dX>
00246 const Real ARK4<X, FI, FE, dX>::s_aE[][ARK4<X, FI, FE, dX>::s_nStages] = {
00247 {0., 0., 0., 0., 0., 0.},
00248 {0.5, 0., 0., 0., 0., 0.},
00249 {0.221776, 0.110224, 0., 0., 0., 0.},
00250 {-0.04884659515311857, -0.17772065232640102, 0.8465672474795197, 0., 0., 0.},
00251 {-0.15541685842491548, -0.3567050098221991, 1.0587258798684427, 0.30339598837867193, 0., 0.},
00252 { 0.2014243506726763, 0.008742057842904185, 0.15993995707168115, 0.4038290605220775, 0.22606457389066084, 0.}
00253 };
00254
00255 template<class X, class FI, class FE, class dX>
00256 const Real ARK4<X, FI, FE, dX>::s_aI[][ARK4<X, FI, FE, dX>::s_nStages] = {
00257 {0., 0., 0., 0., 0., 0.},
00258 {0.25, 0.25, 0., 0., 0., 0.},
00259 {0.137776, -0.055776, 0.25, 0., 0., 0.},
00260 {0.14463686602698217, -0.22393190761334475, 0.4492950415863626, 0.25, 0., 0.},
00261 {0.09825878328356477, -0.5915442428196704, 0.8101210538282996, 0.283164405707806, 0.25, 0.},
00262 {0.15791629516167136, 0., 0.18675894052400077, 0.6805652953093346, -0.27524053099500667, 0.25}
00263 };
00264
00265 template<class X, class FI, class FE, class dX>
00266 const Real ARK4<X, FI, FE, dX>::s_b[] =
00267 {0.15791629516167136, 0., 0.18675894052400077, 0.6805652953093346, -0.27524053099500667, 0.25};
00268
00269 #endif