Warning, file /include/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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/throw_exception.hpp>
0022
0023 #include <boost/numeric/odeint/util/unit_helper.hpp>
0024 #include <boost/numeric/odeint/util/copy.hpp>
0025 #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
0026 #include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>
0027
0028
0029 namespace boost {
0030 namespace numeric {
0031 namespace odeint {
0032
0033
0034 template< class Iterator , class Stepper , class System , class State , class TimeIterator ,
0035 typename Tag , typename StepperTag >
0036 class times_iterator_impl;
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0053 class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , stepper_tag >
0054 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0055 {
0056 private:
0057
0058
0059 typedef Stepper stepper_type;
0060 typedef System system_type;
0061 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0062 typedef State state_type;
0063 typedef TimeIterator time_iterator_type;
0064 typedef typename traits::time_type< stepper_type >::type time_type;
0065 typedef typename traits::value_type< stepper_type >::type ode_value_type;
0066 #ifndef DOXYGEN_SKIP
0067 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0068 #endif
0069
0070 public:
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0083 time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0084 : base_type( stepper , sys , *t_start , dt ) ,
0085 m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0086 {
0087 if( t_start == t_end )
0088 this->m_at_end = true;
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0099 : base_type( stepper , sys ) , m_state( &s ) { }
0100
0101 protected:
0102
0103 friend class boost::iterator_core_access;
0104
0105 void increment()
0106 {
0107 unwrapped_stepper_type &stepper = this->m_stepper;
0108 if( ++m_t_start != m_t_end )
0109 {
0110 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0111 {
0112 const time_type current_dt = detail::min_abs( this->m_dt , static_cast<time_type>(*m_t_start) - this->m_t );
0113 stepper.do_step( this->m_system , *( this->m_state ) , this->m_t , current_dt );
0114 this->m_t += current_dt;
0115 }
0116
0117 } else {
0118 this->m_at_end = true;
0119 }
0120 }
0121
0122 public:
0123 const state_type& get_state() const
0124 {
0125 return *m_state;
0126 }
0127
0128 private:
0129 time_iterator_type m_t_start;
0130 time_iterator_type m_t_end;
0131 state_type* m_state;
0132 };
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0151 class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , controlled_stepper_tag >
0152 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0153 {
0154 private:
0155
0156
0157 typedef Stepper stepper_type;
0158 typedef System system_type;
0159 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0160 typedef State state_type;
0161 typedef TimeIterator time_iterator_type;
0162 typedef typename traits::time_type< stepper_type >::type time_type;
0163 typedef typename traits::value_type< stepper_type >::type ode_value_type;
0164 #ifndef DOXYGEN_SKIP
0165 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0166 #endif
0167
0168 public:
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0181 time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0182 : base_type( stepper , sys , *t_start , dt ) ,
0183 m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0184 {
0185 if( t_start == t_end )
0186 this->m_at_end = true;
0187 }
0188
0189
0190
0191
0192
0193
0194
0195
0196 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0197 : base_type( stepper , sys ) , m_state( &s ) { }
0198
0199 protected:
0200
0201 friend class boost::iterator_core_access;
0202
0203 void increment()
0204 {
0205 if( ++m_t_start != m_t_end )
0206 {
0207 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0208 {
0209 if( detail::less_with_sign( static_cast<time_type>(*m_t_start) - this->m_t , this->m_dt , this->m_dt ) )
0210 {
0211
0212 time_type current_dt = static_cast<time_type>(*m_t_start) - this->m_t;
0213 step_loop( current_dt );
0214 } else {
0215 step_loop( this->m_dt );
0216 }
0217 }
0218
0219 } else {
0220 this->m_at_end = true;
0221 }
0222 }
0223
0224 private:
0225 void step_loop( time_type &dt )
0226 {
0227 unwrapped_stepper_type &stepper = this->m_stepper;
0228 const size_t max_attempts = 1000;
0229 size_t trials = 0;
0230 controlled_step_result res = success;
0231 do
0232 {
0233 res = stepper.try_step( this->m_system , *( this->m_state ) , this->m_t , dt );
0234 ++trials;
0235 }
0236 while( ( res == fail ) && ( trials < max_attempts ) );
0237 if( trials == max_attempts )
0238 {
0239 BOOST_THROW_EXCEPTION( std::overflow_error( "Adaptive iterator : Maximal number of iterations reached. A step size could not be found." ) );
0240 }
0241 }
0242
0243 public:
0244 const state_type& get_state() const
0245 {
0246 return *m_state;
0247 }
0248
0249
0250 private:
0251 time_iterator_type m_t_start;
0252 time_iterator_type m_t_end;
0253 state_type* m_state;
0254 };
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0269 class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , dense_output_stepper_tag >
0270 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0271 {
0272 private:
0273
0274
0275 typedef Stepper stepper_type;
0276 typedef System system_type;
0277 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0278 typedef State state_type;
0279 typedef TimeIterator time_iterator_type;
0280 typedef typename traits::time_type< stepper_type >::type time_type;
0281 typedef typename traits::value_type< stepper_type >::type ode_value_type;
0282 #ifndef DOXYGEN_SKIP
0283 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0284 #endif
0285
0286
0287 public:
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0301 time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0302 : base_type( stepper , sys , *t_start , dt ) ,
0303 m_t_start( t_start ) , m_t_end( t_end ) , m_final_time( *(t_end-1) ) ,
0304 m_state( &s )
0305 {
0306 if( t_start != t_end )
0307 {
0308 unwrapped_stepper_type &st = this->m_stepper;
0309 st.initialize( *( this->m_state ) , this->m_t , this->m_dt );
0310 } else {
0311 this->m_at_end = true;
0312 }
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322 times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0323 : base_type( stepper , sys ) , m_state( &s ) { }
0324
0325 protected:
0326
0327 friend class boost::iterator_core_access;
0328
0329 void increment()
0330 {
0331 unwrapped_stepper_type &st = this->m_stepper;
0332 if( ++m_t_start != m_t_end )
0333 {
0334 this->m_t = static_cast<time_type>(*m_t_start);
0335 while( detail::less_with_sign( st.current_time() , this->m_t , this->m_dt ) )
0336 {
0337
0338 if( detail::less_with_sign( m_final_time-st.current_time() , st.current_time_step() , st.current_time_step() ) )
0339 {
0340 st.initialize( st.current_state() , st.current_time() , m_final_time-st.current_time() );
0341 }
0342 st.do_step( this->m_system );
0343 }
0344 st.calc_state( this->m_t , *( this->m_state ) );
0345 } else {
0346 this->m_at_end = true;
0347 }
0348 }
0349
0350 public:
0351 const state_type& get_state() const
0352 {
0353 return *m_state;
0354 }
0355
0356
0357 private:
0358 time_iterator_type m_t_start;
0359 time_iterator_type m_t_end;
0360 time_type m_final_time;
0361 state_type* m_state;
0362 };
0363
0364 }
0365 }
0366 }
0367
0368
0369 #endif