Documentation


explicit_solver.h

Go to the documentation of this file.
00001 #ifndef ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H
00002 #define ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H
00003 
00004 #include <animal/integration/solver.h>
00005 
00006 
00007 
00008 namespace animal { namespace integration {
00009 
00010 // ------------------------------------------------------------
00011 //  
00012 //  Euler class.
00022 //  
00023 // ------------------------------------------------------------
00024 
00025 template 
00026 <
00027     class DerivativeF,
00028     class StepF,
00029     class TraitsT
00030 >
00031 
00032 struct Euler : public Solver< DerivativeF, StepF, TraitsT >
00033 {
00034   
00035 //  typedef DerivativeF Derivative;   ///< derivative functor
00036 //  typedef StepF Step;               ///< basic step functor
00037 //  typedef TraitsT Traits;           ///< traits
00038 
00040   typedef TraitsT                     Traits;
00041 
00043   typedef typename Traits::Real       Real;
00044 
00046   typedef typename Traits::State      State;
00047 
00049   typedef typename Traits::CopyState      CopyState;
00050 
00052   typedef typename Traits::Derivative Derivative;
00053 
00055   typedef typename Traits::SizeType   SizeType;
00056 
00057 
00058     
00063 
00067   Euler
00068     (
00069         const DerivativeF& df = DerivativeF(), 
00070         const StepF& sf = StepF(),
00071         const TraitsT& tr = Traits()
00072     )
00073   : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00074     {}
00075     
00077     virtual ~Euler(){}
00078     
00080     
00081 
00086 
00095     void doStep
00096     (
00097           const State& initial_S,
00098           State& final_S,
00099           const Derivative& initial_D,
00100           const Real, // t
00101             const Real h
00102     )
00103   {
00104     applyStep( initial_S, final_S, initial_D, h );
00105   }
00106     
00108   
00109 
00110 protected:
00111 
00114 
00116   void setSize( const SizeType ){}
00117     
00119 
00120 }; // struct Euler
00121 
00122 
00123 
00124 // ------------------------------------------------------
00125 //  
00126 //  Runge_Kutta_2 class.
00137 //  
00138 // ------------------------------------------------------
00139 
00140 template 
00141 <
00142   class DerivativeF,
00143   class StepF,
00144   class TraitsT
00145 >
00146 
00147 struct Runge_Kutta_2 : public Solver< DerivativeF,StepF,TraitsT >
00148 {
00149 
00151   typedef TraitsT                     Traits;
00152 
00154   typedef typename Traits::Real       Real;
00155 
00157   typedef typename Traits::State      State;
00158 
00160   typedef typename Traits::CopyState      CopyState;
00161 
00163   typedef typename Traits::Derivative Derivative;
00164 
00166   typedef typename Traits::SizeType   SizeType;
00167 
00168 
00173 
00177   Runge_Kutta_2
00178     (
00179         const DerivativeF& df = DerivativeF(), 
00180         const StepF& sf = StepF(),
00181         const Traits& tr = Traits()
00182     )
00183   : Solver< DerivativeF,StepF,TraitsT >( df, sf, tr )
00184   {}
00185     
00187     virtual ~Runge_Kutta_2(){}
00188     
00190   
00191 
00196 
00205   void doStep
00206     (
00207         const State& initial_S,
00208         State& final_S,
00209         const Derivative& D,
00210         const Real t, 
00211         const Real h
00212     )
00213   {
00214     Real h_2 = 0.5*h;
00215 
00216     applyStep(initial_S, tmp_S, D, h_2);
00217 
00218     writeDerivative( tmp_S, D1, (t + h_2) );
00219     applyStep( initial_S, final_S, D1, h );
00220   }
00221     
00223   
00224 protected:
00225 
00228 
00230   CopyState tmp_S;
00231   
00233   void setSize( const SizeType size )
00234   {
00235         traits.resize( tmp_S, size );
00236   }
00237     
00239   
00240 }; // class Runge_Kutta_2
00241 
00242 
00243 //  /** Apply a second-order Runge-Kutta integration step
00244 //      \param finalState The final state
00245 //      \param initialState The initial state
00246 //      \param doDerivate A functor which computes a derivative given a state
00247 //      \param h The time step
00248 //      \param derivative An auxiliary value to store a derivative
00249 //      \param doStep A functor which applies a basic Euler step
00250 //  */
00251 //  template< class FS, class IS, class DR, class DV, class S>
00252 //  void rk2Step( FS& finalState, const IS& initialState, DR& doDerivate, double h, DV& derivative, S& doStep )
00253 //  {
00254 //      doDerivate( derivative, initialState );
00255 //      doStep( finalState, initialState, derivative, h/2 );  // half step
00256 //      doDerivate( derivative, finalState );                 // derivative there
00257 //      doStep( finalState, initialState, derivative, h );
00258 //  }
00259 
00260 
00261 
00262 // -------------------------------------------------------
00263 //  
00264 //  Runge_Kutta_4 class.
00274 //  
00275 // -------------------------------------------------------
00276 
00277 template 
00278 <
00279   class DerivativeF,
00280   class StepF,
00281   class TraitsT
00282 >
00283 
00284 struct Runge_Kutta_4 : public Solver< DerivativeF,StepF,TraitsT >
00285 {
00286   
00288   typedef TraitsT                     Traits;
00289 
00291   typedef typename Traits::Real       Real;
00292 
00294   typedef typename Traits::State      State;
00295 
00297   typedef typename Traits::CopyState      CopyState;
00298 
00300   typedef typename Traits::Derivative Derivative;
00301 
00303   typedef typename Traits::SizeType   SizeType;
00304 
00305 
00310 
00314   Runge_Kutta_4
00315     (
00316         const DerivativeF& df = DerivativeF(), 
00317         const StepF& sf = StepF(),
00318         const Traits& tr = Traits()
00319     )
00320   : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00321   {}
00322     
00324     virtual ~Runge_Kutta_4(){}
00325     
00327   
00328 
00329   
00334 
00342   void doStep
00343     (
00344         const State& initial_S,
00345         State& final_S,
00346         const Derivative& initial_D,
00347         const Real t, 
00348         const Real h
00349     )
00350   {
00351         Real h_2 = 0.5*h;
00352 
00353         applyStep(initial_S, tmp_S, initial_D, h_2);
00354 
00355         writeDerivative ( tmp_S, D2, (t + h_2) );
00356         applyStep( initial_S, tmp_S, D2, h_2 );
00357 
00358         writeDerivative ( tmp_S, D3, (t + h_2) );
00359         applyStep( initial_S, tmp_S, D3, h );
00360 
00361         writeDerivative ( tmp_S, D4, (t + h) );
00362         
00363         // weighted sum of derivatives: final_D = initial_D + 2*(D2+d3) + D4
00364         traits.rk4Step( initial_D, D2, D3, D4, final_D );
00365 
00366         applyStep(initial_S, final_S, final_D, h/6 );
00367 
00368   }
00369 
00371   
00372 protected:
00373 
00376 
00378   CopyState tmp_S;
00379   
00381   Derivative D2, D3, D4;
00382   
00384   Derivative final_D;
00385 
00387   void setSize(const SizeType size)
00388   {
00389         traits.resize( tmp_S,  size );
00390         traits.resize( D2, size );
00391         traits.resize( D3, size );
00392         traits.resize( D4, size );
00393         traits.resize( final_D, size );
00394   }
00395     
00397 
00398 }; // class Runge_Kutta_4
00399 
00400 
00401 
00402 // --------------------------------------
00403 //  
00404 //  Modified_Midpoint class.
00415 //  
00416 // --------------------------------------
00417 
00418 template 
00419 <
00420   int N,
00421   class DerivativeF,
00422   class StepF,
00423   class TraitsT
00424 >
00425 
00426 struct Modified_Midpoint : public Solver< DerivativeF, StepF, TraitsT >
00427 {
00428   
00429   
00431   typedef TraitsT                     Traits;
00432 
00434   typedef typename Traits::Real       Real;
00435 
00437   typedef typename Traits::State      State;
00438 
00440   typedef typename Traits::CopyState      CopyState;
00441 
00443   typedef typename Traits::Derivative Derivative;
00444 
00446   typedef typename Traits::SizeType   SizeType;
00447 
00448 
00453 
00457   Modified_Midpoint
00458     (
00459         const DerivativeF& df = DerivativeF(), 
00460         const StepF& sf = StepF(),
00461         const Traits& tr = Traits()
00462     )
00463   : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00464   {}
00465     
00467   
00472 
00480   void doStep
00481     (
00482         const State& initial_S,
00483         State& final_S,
00484         const Derivative& initial_D,
00485         const Real t, 
00486         const Real h
00487     )
00488   {
00489 
00490     Real hsub = h/N;       // h: total step to be made
00491     Real hhsub = 2.0*hsub; // hsub: substep value
00492 
00493     traits.copy( initial_S, S1 );
00494 
00495     applyStep( S1, S2, initial_D, hsub ); // First substep taken
00496 
00497     // Take remaining substeps minus one
00498     for( int m = 1; m < (N - 1); m++ )
00499         {
00500             writeDerivative( S2, D1, (t + m*hsub) );
00501             applyStep(S1, S3, D1, hhsub);
00502             S1 = S2;
00503             S2 = S3;
00504         }
00505 
00506     // Take last substep
00507     writeDerivative( S2, D1, (t + (N - 1)*hsub) );
00508     applyStep( S1, S3, D1, hhsub );
00509 
00510     // Take full step
00511     writeDerivative( S3, D1, (t + h) );
00512     applyStep( S3, S3, D1, hsub );
00513         traits.average( S2, S3, final_S );
00514         
00515 //          cout<<" performed modified_midpoint with N = " << N << endl;
00516 
00517   }
00518     
00520 
00521   
00522 protected:
00523 
00526 
00528   CopyState S1, S2, S3;
00529   
00531   void setSize( const SizeType size )
00532   {
00533         traits.resize( S1, size );
00534         traits.resize( S2, size );
00535         traits.resize( S3, size );
00536   }
00537     
00539   
00540 }; // class Modified_Midpoint
00541 
00542 
00543 
00544 // --------------------------------------
00545 //  
00546 //  Modified_Midpoint_V class.
00556 //  
00557 // --------------------------------------
00558 
00559 template 
00560 <
00561   class NStepF,
00562   class DerivativeF,
00563   class StepF,
00564   class TraitsT
00565 >
00566 
00567 struct Modified_Midpoint_V : public Solver< DerivativeF, StepF, TraitsT >
00568 {
00569   
00571   typedef TraitsT                     Traits;
00572 
00574   typedef typename Traits::Real       Real;
00575 
00577   typedef typename Traits::State      State;
00578 
00580   typedef typename Traits::CopyState      CopyState;
00581 
00583   typedef typename Traits::Derivative Derivative;
00584 
00586   typedef typename Traits::SizeType   SizeType;
00587 
00588 
00589   NStepF nstep;  
00590   
00595 
00599   Modified_Midpoint_V
00600     (
00601         const NStepF& nsf = NStepF(),
00602         const DerivativeF& df = DerivativeF(), 
00603         const StepF& sf = StepF(),
00604         const Traits& tr = Traits()
00605     )
00606   : Solver< DerivativeF, StepF, TraitsT >( df, sf, tr )
00607     , nstep(nsf)
00608   {}
00609     
00611     virtual ~Modified_Midpoint_V(){}
00612     
00614   
00619 
00628   void doStep
00629     (
00630         const State& initial_S,
00631         State& final_S,
00632         const Derivative& initial_D,
00633         const Real t, 
00634         const Real h
00635     )
00636   {
00637     unsigned int N = nstep( initial_S, t );
00638 
00639     Real hsub = h/N;       // h: total step to be made
00640     Real hhsub = 2.0*hsub; // hsub: substep value
00641 
00642     S1 = initial_S;
00643 
00644     applyStep( S1, S2, initial_D, hsub ); // First substep taken
00645 
00646     // Take remaining substeps minus one
00647     for( unsigned int m = 1; m < (N - 1); m++ )
00648         {
00649             writeDerivative( S2, D1, (t + m*hsub) );
00650             applyStep(S1, S3, D1, hhsub);
00651             S1 = S2;
00652             S2 = S3;
00653         }
00654 
00655     // Take last substep
00656     writeDerivative( S2, D1, (t + (N - 1)*hsub) );
00657     applyStep( S1, S3, D1, hhsub );
00658 
00659     // Take full step
00660     writeDerivative( S3, D1, (t + h) );
00661     applyStep( S3, S3, D1, hsub );
00662         traits.average( S2, S3, final_S );
00663         
00664 //          cout<<" performed modified_midpoint with N = " << N << endl;
00665 
00666   }
00667     
00669 
00670   
00671 protected:
00672 
00675 
00677   State S1, S2, S3;
00678   
00680   void setSize( const SizeType size )
00681   {
00682         traits.resize( S1, size );
00683         traits.resize( S2, size );
00684         traits.resize( S3, size );
00685   }
00686     
00688   
00689 }; // class Modified_Midpoint
00690 
00691 
00692 
00693 
00694 
00695 
00699 template <class TraitsT>
00700 
00701 struct NStep_Function
00702 {
00703   typedef typename TraitsT::Real     Real;     
00704   typedef typename TraitsT::State    State;    
00705   typedef typename TraitsT::Numerics Numerics; 
00706   
00708   unsigned int operator()
00709     (
00710         const State& S,
00711         const Real t
00712     ) 
00713     const;
00714     
00715 };
00716 
00717 } // end namespace integration
00718 } // end namespace animal
00719 
00720 
00721 
00722 #endif // ANIMAL_INTEGRATION_EXPLICIT_SOLVER_H

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