Documentation


odeSolver.inl

Go to the documentation of this file.
00001 #ifndef animal_odesolver_inl___________________________
00002 #define animal_odesolver_inl___________________________
00003 
00004 
00005 #include "odeSolver.h"
00006 #include <iostream>
00007 
00008 
00009 
00010 namespace animal
00011 {
00012 
00013 template<class P,class V,class R>
00014 OdeSolver<P,V,R>::OdeSolver()
00015     : _method( EULER )
00016     , _MMIDsteps(3)
00017     , d1(dv1,da1)
00018     , d2(dv2,da2)
00019     , d3(dv3,da3)
00020     , d4(dv4,da4)
00021     , s1(sp1,sv1)
00022     , s2(sp2,sv2)
00023     , s3(sp3,sv3)
00024 {}
00025 
00026 template<class P,class V,class R>
00027 void OdeSolver<P,V,R>::solveODE(
00028     Positions& pos,
00029     Vector& vel,
00030     Real dt
00031 )
00032 {
00033     //std::cerr<<"apply method " << _method << std::endl;
00034     if( _method == EULER ){
00035         //std::cerr<<"OdeSolver<P,V,R>::solveODE apply euler" << std::endl;
00036         euler(pos,vel,dt);
00037     }
00038     else if( _method == RK2 ){
00039         //std::cerr<<"apply rk2" << std::endl;
00040         rk2(pos,vel,dt);
00041     }
00042     else if( _method == RK4 ){
00043         //std::cerr<<"apply rk4" << std::endl;
00044         rk4(pos,vel,dt);
00045     }
00046     else if( _method == MODMID ){
00047         //std::cerr<<"apply modmid" << std::endl;
00048         modmid(pos,vel,dt,_MMIDsteps);
00049     }
00050     else if( _method == VVERLET ){
00051         //std::cerr<<"apply velocity verlet" << std::endl;
00052         velocityVerlet(pos,vel,dt);
00053     }
00054     else std::cerr <<"unknown integration method "<<_method<< std::endl;
00055 }
00056 
00057 
00058 
00059 template<class P,class V,class R>
00060 void OdeSolver<P,V,R>::setMethod( int m )
00061 {
00062     _method = m;
00063 }
00064 
00065 template<class P,class V,class R>
00066 int OdeSolver<P,V,R>::method() const
00067 {
00068     return _method;
00069 }
00070 
00071 //template<class P,class V,class R>
00072 //void OdeSolver<P,V,R>::setMMIDsteps( int n )
00073 //{
00074 //  _MMIDsteps = n;
00075 //}
00076 
00077 //template<class P,class V,class R>
00078 //int OdeSolver<P,V,R>::MMIDsteps() const
00079 //{
00080 //  return _MMIDsteps;
00081 //}
00082 
00083 template<class P,class V,class R>
00084 void OdeSolver<P,V,R>::computeDerivative(
00085     Der& d,
00086     const Sta& s,
00087     Real
00088 )
00089 {
00090             computeAccelerations( d.accelerations, s.positions, s.velocities );
00091             v_eq( d.velocities, s.velocities );
00092 
00093 }
00094 
00101 template<class P,class V,class R>
00102 void OdeSolver<P,V,R>::euler(Positions& pos, Vector& vel, Real h, Real t)
00103 {
00104     d1.resize( size(pos) );
00105     Sta states(pos,vel);
00106 //  cerr<<"OdeSolver<P,V,R>::euler: states.pos= "<< v_output(states.positions) <<endl;
00107 //  cerr<<"OdeSolver<P,V,R>::euler: states.vel= "<< v_output(states.velocities) <<endl;
00108     integrate_euler(states,h,t,d1);
00109 }
00110 
00117 template<class P,class V,class R>
00118 void OdeSolver<P,V,R>::rk2(Positions& pos, Vector& vel, Real h, Real t)
00119 {
00120     d1.resize( size(pos) );
00121     s1.resize( size(pos) );
00122     States<P,V> states(pos,vel);
00123     integrate_rk2(states,h,t,d1,s1);
00124 }
00125 
00132 template<class P,class V,class R>
00133 void OdeSolver<P,V,R>::rk4(Positions& pos, Vector& vel, Real h, Real t)
00134 {
00135     d1.resize( size(pos) );
00136     d2.resize( size(pos) );
00137     d3.resize( size(pos) );
00138     d4.resize( size(pos) );
00139     s1.resize( size(pos) );
00140     States<P,V> states(pos,vel);
00141     integrate_rk4(states,h,t,d1,d2,d3,d4,s1);
00142 }
00143 
00151 template<class P,class V,class R>
00152 void OdeSolver<P,V,R>::modmid(Positions& pos, Vector& vel, Real h, int n, Real t)
00153 {
00154     d1.resize( size(pos) );
00155     s1.resize( size(pos) );
00156     s2.resize( size(pos) );
00157     s3.resize( size(pos) );
00158     States<P,V> states(pos,vel);
00159     integrate_modmid(states,h,t,n,d1,s1,s2,s3);
00160 }
00161 
00168 template<class P, class V, class R>
00169 void OdeSolver<P, V, R>::velocityVerlet(Positions& pos, Vector& vel, Real h)
00170 {
00171     // auxiliary variable for half step velocities - need to make sure its the right size
00172     velHalf.resize(size(vel));
00173 
00174     // derivatives and states storage
00175     d1.resize(size(pos));
00176     States<P,V> states(pos, vel);
00177 
00178     integrate_VVerlet(states,h,d1);
00179 
00180 }
00181 //=======================================================================
00182 template<class P,class V,class R>
00183 void OdeSolver<P,V,R>::integrate_euler
00184 (
00185     Sta& s,
00186     Real h,
00187     Real t,
00188     Der& d
00189 )
00190 {
00191     computeDerivative(d,s,t);
00192     v_eq_euler_step(s,s,h,d);
00193 }
00194 
00195 template<class P,class V,class R>
00196 void OdeSolver<P,V,R>::integrate_rk2
00197 ( 
00198     Sta& s, 
00199     Real h, 
00200     Real t, 
00201     Der& d, 
00202     Sta& s1 
00203 )
00204 {
00205     computeDerivative(d,s,t);
00206     v_eq_euler_step(s1,s,h/2,d);
00207     computeDerivative(d,s1,t+(h/2));
00208     v_eq_euler_step(s,s,h,d);
00209 }
00210 
00211 
00212 template<class P,class V,class R>
00213 void OdeSolver<P,V,R>::integrate_rk4
00214 (
00215     Sta& s, 
00216     Real h,
00217     Real t, 
00218     Der& d1, 
00219     Der& d2, 
00220     Der& d3, 
00221     Der& d4, 
00222     Sta& s1 
00223 )
00224 {
00225     computeDerivative(d1,s,t);
00226     v_eq_euler_step(s1,s,h/2,d1);
00227     computeDerivative(d2,s1,t+(h/2));
00228     v_eq_euler_step(s1,s,h/2,d2);
00229     computeDerivative(d3,s1,t+(h/2));
00230     v_eq_euler_step(s1,s,h,d3);
00231     computeDerivative(d4,s1,t+h);
00232     
00233     // accumulate composed derivative in d2
00234     v_peq(d2,d3); // d2+d3
00235     v_teq(d2,2.);  // 2(d2+d3)
00236     v_peq(d2,d1); // d1+2(d2+d3)
00237     v_peq(d2,d4); // d1+2(d2+d3)+d4
00238     
00239     v_eq_euler_step(s,s,h/6,d2);
00240 }
00241 
00242 
00243 template<class P,class V,class R>
00244 void OdeSolver<P,V,R>::integrate_modmid
00245 ( 
00246     Sta& s, 
00247     Real h, 
00248     Real t, 
00249     int n, 
00250     Der& d1, 
00251     Sta& s1, 
00252     Sta& s2, 
00253     Sta& s3 
00254 )
00255 {
00256     Real hsub = h/n;       // h: total step to be made
00257     Real hhsub = 2.0*hsub; // hsub: substep value
00258 
00259     v_eq(s1,s);
00260 
00261     computeDerivative(d1,s,t);
00262     v_eq_euler_step(s2,s,hsub,d1); // First substep taken
00263     
00264     // take remaining substeps minus one
00265     int i;
00266     for( i=0; i<n-1; ++i )
00267     {
00268         computeDerivative(d1,s2,t+i*hsub);
00269         v_eq_euler_step(s3,s1,hhsub,d1);
00270         v_eq(s1,s2);
00271         v_eq(s2,s3);
00272     }
00273     
00274     //  Take last substep
00275     computeDerivative(d1,s2,t+i*hsub);
00276     v_eq_euler_step(s3,s1,hhsub,d1);
00277     
00278     // Take another step
00279     computeDerivative(d1,s3,t+h);
00280     v_eq_euler_step(s3,s3,hsub,d1);
00281     
00282     // result = average(s2,s3)
00283     v_peq(s2,s3);
00284     Real unDemi = 0.5;
00285     v_eq_ab( s,unDemi,s2 );
00286 }
00287 
00288 template<class P, class V, class R>
00289 void OdeSolver<P, V, R>::integrate_VVerlet(
00290     Sta& s,
00291     Real h,
00292     Der& d)
00293 {
00294     // get accelerations for this time step
00295     computeAccelerations(d.accelerations, s.positions, s.velocities);
00296 
00297     // velocity at half timestep is...
00298     v_eq(velHalf, s.velocities, h/2, d.accelerations);
00299 
00300     // the updated position at time t+Delta_t is...
00301     v_eq(s.positions, s.positions, h, velHalf);
00302 
00303     // acceleration at time t+Delta_t based on updated positions is...
00304     // note: we are using halfstep velocities to predict acceleration at update time here
00305     computeAccelerations(d.accelerations, s.positions, velHalf);
00306 
00307     // and finally, the velocity at time t+Delta_t is...
00308     v_eq(s.velocities, velHalf, h/2, d.accelerations);
00309 
00310 }
00311 
00312 }
00313 
00314 #endif
00315 

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