Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:53

0001 /*
0002  [auto_generated]
0003   boost/numeric/odeint/iterator/detail/times_iterator_impl.hpp
0004 
0005   [begin_description]
0006   tba.
0007   [end_description]
0008 
0009   Copyright 2009-2013 Karsten Ahnert
0010   Copyright 2009-2013 Mario Mulansky
0011 
0012   Distributed under the Boost Software License, Version 1.0.
0013   (See accompanying file LICENSE_1_0.txt or
0014   copy at http://www.boost.org/LICENSE_1_0.txt)
0015 */
0016 
0017 
0018 #ifndef BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED
0019 #define BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED
0020 
0021 #include <boost/utility/enable_if.hpp>
0022 #include <boost/type_traits/is_same.hpp>
0023 #include <boost/throw_exception.hpp>
0024 
0025 #include <boost/numeric/odeint/util/unit_helper.hpp>
0026 #include <boost/numeric/odeint/util/copy.hpp>
0027 #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
0028 #include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>
0029 
0030 
0031 namespace boost {
0032 namespace numeric {
0033 namespace odeint {
0034 
0035 
0036     template< class Iterator , class Stepper , class System , class State , class TimeIterator ,
0037               typename Tag , typename StepperTag >
0038     class times_iterator_impl;
0039 
0040     /*
0041      * Specilization for basic steppers
0042      */
0043     /**
0044      * \brief ODE Iterator with constant step size.
0045      *
0046      * Implements an ODE iterator with observer calls at predefined times.
0047      * Uses controlled steppers. times_iterator is a model of single-pass iterator.
0048      *
0049      * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time.
0050      *
0051      * \tparam Stepper The stepper type which should be used during the iteration.
0052      * \tparam System The type of the system function (ODE) which should be solved.
0053      */
0054     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0055     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , stepper_tag >
0056         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0057     {
0058     private:
0059 
0060 
0061         typedef Stepper stepper_type;
0062         typedef System system_type;
0063         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0064         typedef State state_type;
0065         typedef TimeIterator time_iterator_type;
0066         typedef typename traits::time_type< stepper_type >::type time_type;
0067         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0068         #ifndef DOXYGEN_SKIP
0069         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0070         #endif
0071 
0072     public:
0073 
0074         /**
0075          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0076          *
0077          * \param stepper The stepper to use during the iteration.
0078          * \param sys The system function (ODE) to solve.
0079          * \param s The initial state. adaptive_iterator stores a reference of s and changes its value during the iteration.
0080          * \param t_start Iterator to the begin of a sequence of time values.
0081          * \param t_end Iterator to the begin of a sequence of time values.
0082          * \param dt The (initial) time step.
0083          */
0084         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0085                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0086             : base_type( stepper , sys , *t_start , dt ) ,
0087               m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0088         {
0089             if( t_start == t_end )
0090                 this->m_at_end = true;
0091         }
0092 
0093         /**
0094          * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
0095          *
0096          * \param stepper The stepper to use during the iteration.
0097          * \param sys The system function (ODE) to solve.
0098          * \param s The initial state. adaptive_iterator store a reference of s and changes its value during the iteration.
0099          */
0100         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0101             : base_type( stepper , sys ) , m_state( &s ) { }
0102 
0103     protected:
0104 
0105         friend class boost::iterator_core_access;
0106 
0107         void increment()
0108         {
0109             unwrapped_stepper_type &stepper = this->m_stepper;
0110             if( ++m_t_start != m_t_end )
0111             {
0112                 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0113                 {
0114                     const time_type current_dt = detail::min_abs( this->m_dt , static_cast<time_type>(*m_t_start) - this->m_t );
0115                     stepper.do_step( this->m_system , *( this->m_state ) , this->m_t , current_dt );
0116                     this->m_t += current_dt;
0117                 }
0118 
0119             } else {
0120                 this->m_at_end = true;
0121             }
0122          }
0123 
0124     public:
0125         const state_type& get_state() const
0126         {
0127             return *m_state;
0128         }
0129 
0130     private:
0131         time_iterator_type m_t_start;
0132         time_iterator_type m_t_end;
0133         state_type* m_state;
0134     };
0135 
0136 
0137 
0138     /*
0139      * Specilization for controlled steppers
0140      */
0141     /**
0142      * \brief ODE Iterator with adaptive step size control. The value type of this iterator is the state type of the stepper.
0143      *
0144      * Implements an ODE iterator with observer calls at predefined times.
0145      * Uses controlled steppers. times_iterator is a model of single-pass iterator.
0146      *
0147      * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time.
0148      *
0149      * \tparam Stepper The stepper type which should be used during the iteration.
0150      * \tparam System The type of the system function (ODE) which should be solved.
0151      */
0152     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0153     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , controlled_stepper_tag >
0154         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0155     {
0156     private:
0157 
0158 
0159         typedef Stepper stepper_type;
0160         typedef System system_type;
0161         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0162         typedef State state_type;
0163         typedef TimeIterator time_iterator_type;
0164         typedef typename traits::time_type< stepper_type >::type time_type;
0165         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0166         #ifndef DOXYGEN_SKIP
0167         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0168         #endif
0169 
0170     public:
0171 
0172         /**
0173          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0174          *
0175          * \param stepper The stepper to use during the iteration.
0176          * \param sys The system function (ODE) to solve.
0177          * \param s The initial state. adaptive_iterator stores a reference of s and changes its value during the iteration.
0178          * \param t_start Iterator to the begin of a sequence of time values.
0179          * \param t_end Iterator to the begin of a sequence of time values.
0180          * \param dt The (initial) time step.
0181          */
0182         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0183                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0184             : base_type( stepper , sys , *t_start , dt ) ,
0185               m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0186         {
0187             if( t_start == t_end )
0188                 this->m_at_end = true;
0189         }
0190 
0191         /**
0192          * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
0193          *
0194          * \param stepper The stepper to use during the iteration.
0195          * \param sys The system function (ODE) to solve.
0196          * \param s The initial state. adaptive_iterator store a reference of s and changes its value during the iteration.
0197          */
0198         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0199             : base_type( stepper , sys ) , m_state( &s ) { }
0200 
0201     protected:
0202 
0203         friend class boost::iterator_core_access;
0204 
0205         void increment()
0206         {
0207             if( ++m_t_start != m_t_end )
0208             {
0209                 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0210                 {
0211                     if( detail::less_with_sign( static_cast<time_type>(*m_t_start) - this->m_t , this->m_dt , this->m_dt ) )
0212                     {
0213                         // we want to end exactly at the time point
0214                         time_type current_dt = static_cast<time_type>(*m_t_start) - this->m_t;
0215                         step_loop( current_dt );
0216                     } else {
0217                         step_loop( this->m_dt );
0218                     }
0219                 }
0220 
0221             } else {
0222                 this->m_at_end = true;
0223             }
0224         }
0225 
0226     private:
0227         void step_loop( time_type &dt )
0228         {
0229             unwrapped_stepper_type &stepper = this->m_stepper;
0230             const size_t max_attempts = 1000;
0231             size_t trials = 0;
0232             controlled_step_result res = success;
0233             do
0234             {
0235                 res = stepper.try_step( this->m_system , *( this->m_state ) , this->m_t , dt );
0236                 ++trials;
0237             }
0238             while( ( res == fail ) && ( trials < max_attempts ) );
0239             if( trials == max_attempts )
0240             {
0241                 BOOST_THROW_EXCEPTION( std::overflow_error( "Adaptive iterator : Maximal number of iterations reached. A step size could not be found." ) );
0242             }
0243         }
0244 
0245     public:
0246         const state_type& get_state() const
0247         {
0248             return *m_state;
0249         }
0250 
0251 
0252     private:
0253         time_iterator_type m_t_start;
0254         time_iterator_type m_t_end;
0255         state_type* m_state;
0256     };
0257 
0258 
0259     /*
0260      * Specilization for dense outputer steppers
0261      */
0262     /**
0263      * \brief ODE Iterator with step size control and dense output.
0264      * Implements an ODE iterator with adaptive step size control. Uses dense-output steppers.
0265      * times_iterator is a model of single-pass iterator.
0266      *
0267      * \tparam Stepper The stepper type which should be used during the iteration.
0268      * \tparam System The type of the system function (ODE) which should be solved.
0269      */
0270     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0271     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , dense_output_stepper_tag >
0272         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0273     {
0274     private:
0275 
0276 
0277         typedef Stepper stepper_type;
0278         typedef System system_type;
0279         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0280         typedef State state_type;
0281         typedef TimeIterator time_iterator_type;
0282         typedef typename traits::time_type< stepper_type >::type time_type;
0283         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0284         #ifndef DOXYGEN_SKIP
0285         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0286         #endif
0287 
0288 
0289    public:
0290 
0291 
0292         /**
0293          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0294          *
0295          * \param stepper The stepper to use during the iteration.
0296          * \param sys The system function (ODE) to solve.
0297          * \param s The initial state.
0298          * \param t_start Iterator to the begin of a sequence of time values.
0299          * \param t_end Iterator to the begin of a sequence of time values.
0300          * \param dt The (initial) time step.
0301          */
0302         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0303                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0304             : base_type( stepper , sys , *t_start , dt ) ,
0305               m_t_start( t_start ) , m_t_end( t_end ) , m_final_time( *(t_end-1) ) ,
0306               m_state( &s )
0307         {
0308             if( t_start != t_end )
0309             {
0310                 unwrapped_stepper_type &st = this->m_stepper;
0311                 st.initialize( *( this->m_state ) , this->m_t , this->m_dt );
0312             } else {
0313                 this->m_at_end = true;
0314             }
0315         }
0316 
0317         /**
0318          * \brief Constructs a times_iterator. This constructor should be used to construct the end iterator.
0319          *
0320          * \param stepper The stepper to use during the iteration.
0321          * \param sys The system function (ODE) to solve.
0322          * \param s The initial state.
0323          */
0324         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0325             : base_type( stepper , sys ) , m_state( &s ) { }
0326 
0327     protected:
0328 
0329         friend class boost::iterator_core_access;
0330 
0331         void increment()
0332         {
0333             unwrapped_stepper_type &st = this->m_stepper;
0334             if( ++m_t_start != m_t_end )
0335             {
0336                 this->m_t = static_cast<time_type>(*m_t_start);
0337                 while( detail::less_with_sign( st.current_time() , this->m_t , this->m_dt ) )
0338                 {
0339                     // make sure we don't go beyond the last point
0340                     if( detail::less_with_sign( m_final_time-st.current_time() , st.current_time_step() , st.current_time_step() ) )
0341                     {
0342                         st.initialize( st.current_state() , st.current_time() , m_final_time-st.current_time() );
0343                     }
0344                     st.do_step( this->m_system );
0345                 }
0346                 st.calc_state( this->m_t , *( this->m_state ) );
0347             } else {
0348                 this->m_at_end = true;
0349             }
0350         }
0351 
0352     public:
0353         const state_type& get_state() const
0354         {
0355             return *m_state;
0356         }
0357 
0358 
0359     private:
0360         time_iterator_type m_t_start;
0361         time_iterator_type m_t_end;
0362         time_type m_final_time;
0363         state_type* m_state;
0364     };
0365 
0366 } // namespace odeint
0367 } // namespace numeric
0368 } // namespace boost
0369 
0370 
0371 #endif // BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED