00001 #ifndef ANIMAL_INTEGRATOR_HPP
00002 #define ANIMAL_INTEGRATOR_HPP
00003
00004 #include <animal/linear.h>
00005 #include <animal/vectorVec.h>
00006
00007
00008 namespace animal {
00009
00012 template<class FS, class IS, class D, class Real>
00013 inline void v_eq_euler_step( FS& final, const IS& initial, Real h, const D& derivative )
00014 {
00015
00016 v_eq(final.positions, initial.positions, h, derivative.velocities );
00017 v_eq(final.velocities, initial.velocities, h, derivative.accelerations );
00018 }
00019
00028 template<class State, class Deriv, class Derivator, class Real>
00029 inline void integrate_euler( State& s, Real h, Derivator* eq_deriv, Real t, Deriv& d )
00030 {
00031 (*eq_deriv)(d,s,t);
00032 v_eq_euler_step(s,s,h,d);
00033 }
00034
00044 template<class State, class Deriv, class Derivator, class StateAux, class Real>
00045 inline void integrate_rk2( State& s, Real h, Derivator* eq_deriv, Real t, Deriv& d, StateAux& s1 )
00046 {
00047 (*eq_deriv)(d,s,t);
00048 v_eq_euler_step(s1,s,h/2,d);
00049 (*eq_deriv)(d,s1,t+(h/2));
00050 v_eq_euler_step(s,s,h,d);
00051 }
00052
00053
00066 template<class State, class Deriv, class Derivator, class StateAux, class Real>
00067 inline void integrate_rk4( State& s, Real h, Derivator* eq_deriv, Real t, Deriv& d1, Deriv& d2, Deriv& d3, Deriv& d4, StateAux& s1 )
00068 {
00069 (*eq_deriv)(d1,s,t);
00070 v_eq_euler_step(s1,s,h/2,d1);
00071 (*eq_deriv)(d2,s1,t+(h/2));
00072 v_eq_euler_step(s1,s,h/2,d2);
00073 (*eq_deriv)(d3,s1,t+(h/2));
00074 v_eq_euler_step(s1,s,h,d3);
00075 (*eq_deriv)(d4,s1,t+h);
00076
00077
00078 v_peq(d2,d3);
00079 v_teq(d2,2.);
00080 v_peq(d2,d1);
00081 v_peq(d2,d4);
00082
00083 v_eq_euler_step(s,s,h/6,d2);
00084 }
00085
00086
00099 template<class State, class Deriv, class Derivator, class StateAux, class Real>
00100 inline void integrate_modmid( State& s, Real h, Derivator *eq_deriv, Real t, int n, Deriv& d1, StateAux& s1, StateAux& s2, StateAux& s3 )
00101 {
00102 Real hsub = h/n;
00103 Real hhsub = 2.0*hsub;
00104
00105 v_eq(s1,s);
00106
00107 (*eq_deriv)(d1,s,t);
00108 v_eq_euler_step(s2,s,hsub,d1);
00109
00110
00111 int i;
00112 for( i=0; i<n-1; ++i )
00113 {
00114 (*eq_deriv)(d1,s2,t+i*hsub);
00115 v_eq_euler_step(s3,s1,hhsub,d1);
00116 v_eq(s1,s2);
00117 v_eq(s2,s3);
00118 }
00119
00120
00121 (*eq_deriv)(d1,s2,t+i*hsub);
00122 v_eq_euler_step(s3,s1,hhsub,d1);
00123
00124
00125 (*eq_deriv)(d1,s3,t+h);
00126 v_eq_euler_step(s3,s3,hsub,d1);
00127
00128
00129 v_peq(s2,s3);
00130 Real unDemi = 0.5;
00131 v_eq_ab( s,unDemi,s2 );
00132 }
00133
00134
00144
00145 template<class State, class Deriv, class Derivator, class Real>
00146 class ExplicitIntegrator
00147 {
00149 Derivator* eq_deriv;
00150 public:
00152 ExplicitIntegrator( Derivator* d=0 )
00153 : eq_deriv(d)
00154 {}
00155
00161 template<class States>
00162 void euler(States& s, Real h, Real t=0)
00163 {
00164 assert(eq_deriv);
00165 d1.resize( size(s) );
00166 integrate_euler(s,h,eq_deriv,t,d1);
00167 }
00168
00174 template<class States>
00175 void rk2(States& s, Real h, Real t=0)
00176 {
00177 assert(eq_deriv);
00178 d1.resize( size(s) );
00179 s1.resize( size(s) );
00180 integrate_rk2(s,h,eq_deriv,t,d1,s1);
00181 }
00182
00188 template<class States>
00189 void rk4(States& s, Real h, Real t=0)
00190 {
00191 assert(eq_deriv);
00192 d1.resize( size(s) );
00193 d2.resize( size(s) );
00194 d3.resize( size(s) );
00195 d4.resize( size(s) );
00196 s1.resize( size(s) );
00197 integrate_rk4(s,h,eq_deriv,t,d1,d2,d3,d4,s1);
00198 }
00199
00206 template<class States>
00207 void modmid(States& s, Real h, int n, Real t=0)
00208 {
00209 assert(eq_deriv);
00210 d1.resize( size(s) );
00211 s1.resize( size(s) );
00212 s2.resize( size(s) );
00213 s3.resize( size(s) );
00214 integrate_modmid(s,h,eq_deriv,t,n,d1,s1,s2,s3);
00215 }
00216
00217 protected:
00218 animal::vector<Deriv> d1;
00219 animal::vector<Deriv> d2;
00220 animal::vector<Deriv> d3;
00221 animal::vector<Deriv> d4;
00222 animal::vector<State> s1;
00223 animal::vector<State> s2;
00224 animal::vector<State> s3;
00225 };
00226
00227
00228
00229
00230
00231
00232
00233
00234
00236 template<class Poss, class Vels>
00237 struct States {
00238 Poss& positions;
00239 Vels& velocities;
00240
00242 States( Poss& pos, Vels& vel )
00243 : positions(pos)
00244 , velocities(vel)
00245 {}
00246
00248 void resize( int s ){
00249 velocities.resize(s);
00250 positions.resize(s);
00251 }
00252 };
00253
00255 template<class P,class V> inline
00256 void v_eq(States<P,V>& s, const States<P,V>& t ){
00257 v_eq(s.positions,t.positions);
00258 v_eq(s.velocities,t.velocities);
00259 }
00260
00262 template<class P,class V> inline
00263 void v_peq(States<P,V>& s, const States<P,V>& t ){
00264 v_peq(s.positions,t.positions);
00265 v_peq(s.velocities,t.velocities);
00266 }
00267
00269 template<class P,class V,class Real> inline
00270 void v_eq_ab(States<P,V>& s, const Real& a, const States<P,V>& b ){
00271 v_eq_ab(s.positions,a,b.positions);
00272 v_eq_ab(s.velocities,a,b.velocities);
00273 }
00274
00276 template<class Vels,class Accs>
00277 struct Derivs {
00278 Accs& accelerations;
00279 Vels& velocities;
00280
00282 Derivs( Vels& vel, Accs& acc )
00283 : accelerations(acc)
00284 , velocities(vel)
00285 {}
00286
00288 void resize( int s ){
00289 velocities.resize(s);
00290 accelerations.resize(s);
00291 }
00292 };
00293
00295 template<class V,class A> inline
00296 void v_peq( Derivs<V,A>& d, const Derivs<V,A>& e ){
00297 v_peq(d.velocities,e.velocities);
00298 v_peq(d.accelerations,e.accelerations);
00299 }
00300
00302 template<class V,class A,class Real> inline
00303 void v_teq( Derivs<V,A>& d, const Real& e ){
00304 v_teq(d.velocities,e);
00305 v_teq(d.accelerations,e);
00306 }
00307
00308
00318 template<class Position, class Velocity, class ComputeAcceleration, class Real, class Acceleration=Velocity>
00319 class ExplicitIntegrator2
00320 {
00322 typedef animal::VectorVec<Position> Positions;
00323
00325 typedef animal::VectorVec<Velocity> Velocities;
00326
00328 typedef animal::VectorVec<Acceleration> Accelerations;
00329
00330
00332 struct Derivator {
00334 ComputeAcceleration& computeAcceleration;
00335
00337 Derivator(ComputeAcceleration& compAcc)
00338 : computeAcceleration(compAcc)
00339 {}
00340
00342 template<class P,class V,class A>
00343 void operator() (Derivs<V,A>& deriv, const States<P,V>& state, Real )
00344 {
00345 computeAcceleration( deriv.accelerations, state.positions, state.velocities );
00346 v_eq( deriv.velocities, state.velocities );
00347 }
00348 };
00349
00351 Derivator eq_deriv;
00352 public:
00354 ExplicitIntegrator2( ComputeAcceleration& d )
00355 : eq_deriv(d)
00356 , d1(dv1,da1)
00357 , d2(dv2,da2)
00358 , d3(dv3,da3)
00359 , d4(dv4,da4)
00360 , s1(sp1,sv1)
00361 , s2(sp2,sv2)
00362 , s3(sp3,sv3)
00363 {}
00364
00371 template< class P, class V >
00372 void euler(P& pos, V& vel, Real h, Real t=0)
00373 {
00374 d1.resize( size(pos) );
00375 States<P,V> states(pos,vel);
00376
00377
00378 integrate_euler(states,h,&eq_deriv,t,d1);
00379 }
00380
00387 template<class P, class V>
00388 void rk2(P& pos, V& vel, Real h, Real t=0)
00389 {
00390 d1.resize( size(pos) );
00391 s1.resize( size(pos) );
00392 States<P,V> states(pos,vel);
00393 integrate_rk2(states,h,&eq_deriv,t,d1,s1);
00394 }
00395
00402 template<class P, class V>
00403 void rk4(P& pos, V& vel, Real h, Real t=0)
00404 {
00405 d1.resize( size(pos) );
00406 d2.resize( size(pos) );
00407 d3.resize( size(pos) );
00408 d4.resize( size(pos) );
00409 s1.resize( size(pos) );
00410 States<P,V> states(pos,vel);
00411 integrate_rk4(states,h,&eq_deriv,t,d1,d2,d3,d4,s1);
00412 }
00413
00421 template<class P, class V>
00422 void modmid(P& pos, V& vel, Real h, int n, Real t=0)
00423 {
00424 d1.resize( size(pos) );
00425 s1.resize( size(pos) );
00426 s2.resize( size(pos) );
00427 s3.resize( size(pos) );
00428 States<P,V> states(pos,vel);
00429 integrate_modmid(states,h,&eq_deriv,t,n,d1,s1,s2,s3);
00430 }
00431
00432 protected:
00433
00434 typedef Derivs<Velocities,Accelerations> Der;
00435
00436 Velocities dv1;
00437 Accelerations da1;
00438 Der d1;
00439
00440 Velocities dv2;
00441 Accelerations da2;
00442 Der d2;
00443
00444 Velocities dv3;
00445 Accelerations da3;
00446 Der d3;
00447
00448 Velocities dv4;
00449 Accelerations da4;
00450 Der d4;
00451
00452
00453 typedef States<Positions,Velocities> Sta;
00454
00455 Positions sp1;
00456 Velocities sv1;
00457 Sta s1;
00458
00459 Positions sp2;
00460 Velocities sv2;
00461 Sta s2;
00462
00463 Positions sp3;
00464 Velocities sv3;
00465 Sta s3;
00466
00467 };
00468
00469
00470 }
00471
00472
00473
00474 #endif