Documentation


integrator.h

Go to the documentation of this file.
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     //v_eq(final,initial,h,derivative);
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     // accumulate composed derivative in d2
00078     v_peq(d2,d3); // d2+d3
00079     v_teq(d2,2.);  // 2(d2+d3)
00080     v_peq(d2,d1); // d1+2(d2+d3)
00081     v_peq(d2,d4); // d1+2(d2+d3)+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;       // h: total step to be made
00103     Real hhsub = 2.0*hsub; // hsub: substep value
00104 
00105     v_eq(s1,s);
00106 
00107     (*eq_deriv)(d1,s,t);
00108     v_eq_euler_step(s2,s,hsub,d1); // First substep taken
00109     
00110     // take remaining substeps minus one
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     //  Take last substep
00121     (*eq_deriv)(d1,s2,t+i*hsub);
00122     v_eq_euler_step(s3,s1,hhsub,d1);
00123     
00124     // Take another step
00125     (*eq_deriv)(d1,s3,t+h);
00126     v_eq_euler_step(s3,s3,hsub,d1);
00127     
00128     // result = average(s2,s3)
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 // Special case of ExplicitIntegrator for second-degree systems
00233 // e.g. (position, velocity) -> (velocity,acceleration)
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 /*time not used*/)
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         //cerr<<"integrator2::euler: states.pos= "<< v_output(states.positions) <<endl;
00377         //cerr<<"integrator2::euler: states.vel= "<< v_output(states.velocities) <<endl;
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 } // end namespace animal
00471 
00472 
00473 
00474 #endif 

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