1 /* 2 [auto_generated] 3 boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp 4 5 [begin_description] 6 Base class for all explicit first-same-as-last Runge Kutta steppers. 7 [end_description] 8 9 Copyright 2010-2013 Karsten Ahnert 10 Copyright 2010-2012 Mario Mulansky 11 Copyright 2012 Christoph Koke 12 13 Distributed under the Boost Software License, Version 1.0. 14 (See accompanying file LICENSE_1_0.txt or 15 copy at http://www.boost.org/LICENSE_1_0.txt) 16 */ 17 18 19 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED 20 #define BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED 21 22 #include <boost/utility/enable_if.hpp> 23 #include <boost/type_traits/is_same.hpp> 24 25 26 #include <boost/numeric/odeint/util/bind.hpp> 27 #include <boost/numeric/odeint/util/unwrap_reference.hpp> 28 #include <boost/numeric/odeint/util/state_wrapper.hpp> 29 #include <boost/numeric/odeint/util/is_resizeable.hpp> 30 #include <boost/numeric/odeint/util/resizer.hpp> 31 #include <boost/numeric/odeint/util/copy.hpp> 32 33 #include <boost/numeric/odeint/stepper/stepper_categories.hpp> 34 35 #include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp> 36 37 namespace boost { 38 namespace numeric { 39 namespace odeint { 40 41 /* 42 * base class for explicit stepper and error steppers with the fsal property 43 * models the stepper AND the error stepper fsal concept 44 * 45 * this class provides the following do_step overloads 46 * do_step( sys , x , t , dt ) 47 * do_step( sys , x , dxdt , t , dt ) 48 * do_step( sys , in , t , out , dt ) 49 * do_step( sys , in , dxdt_in , t , out , dxdt_out , dt ) 50 * do_step( sys , x , t , dt , xerr ) 51 * do_step( sys , x , dxdt , t , dt , xerr ) 52 * do_step( sys , in , t , out , dt , xerr ) 53 * do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr ) 54 */ 55 template< 56 class Stepper , 57 unsigned short Order , 58 unsigned short StepperOrder , 59 unsigned short ErrorOrder , 60 class State , 61 class Value , 62 class Deriv , 63 class Time , 64 class Algebra , 65 class Operations , 66 class Resizer 67 > 68 class explicit_error_stepper_fsal_base : public algebra_stepper_base< Algebra , Operations > 69 { 70 public: 71 72 typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; 73 typedef typename algebra_stepper_base_type::algebra_type algebra_type; 74 75 typedef State state_type; 76 typedef Value value_type; 77 typedef Deriv deriv_type; 78 typedef Time time_type; 79 typedef Resizer resizer_type; 80 typedef Stepper stepper_type; 81 typedef explicit_error_stepper_fsal_tag stepper_category; 82 83 #ifndef DOXYGEN_SKIP 84 typedef state_wrapper< state_type > wrapped_state_type; 85 typedef state_wrapper< deriv_type > wrapped_deriv_type; 86 typedef explicit_error_stepper_fsal_base< Stepper , Order , StepperOrder , ErrorOrder , 87 State , Value , Deriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type; 88 #endif 89 90 91 typedef unsigned short order_type; 92 static const order_type order_value = Order; 93 static const order_type stepper_order_value = StepperOrder; 94 static const order_type error_order_value = ErrorOrder; 95 explicit_error_stepper_fsal_base(const algebra_type & algebra=algebra_type ())96 explicit_error_stepper_fsal_base( const algebra_type &algebra = algebra_type() ) 97 : algebra_stepper_base_type( algebra ) , m_first_call( true ) 98 { } 99 order(void) const100 order_type order( void ) const 101 { 102 return order_value; 103 } 104 stepper_order(void) const105 order_type stepper_order( void ) const 106 { 107 return stepper_order_value; 108 } 109 error_order(void) const110 order_type error_order( void ) const 111 { 112 return error_order_value; 113 } 114 115 116 /* 117 * version 1 : do_step( sys , x , t , dt ) 118 * 119 * the two overloads are needed in order to solve the forwarding problem 120 */ 121 template< class System , class StateInOut > do_step(System system,StateInOut & x,time_type t,time_type dt)122 void do_step( System system , StateInOut &x , time_type t , time_type dt ) 123 { 124 do_step_v1( system , x , t , dt ); 125 } 126 127 /** 128 * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut. 129 */ 130 template< class System , class StateInOut > do_step(System system,const StateInOut & x,time_type t,time_type dt)131 void do_step( System system , const StateInOut &x , time_type t , time_type dt ) 132 { 133 do_step_v1( system , x , t , dt ); 134 } 135 136 137 /* 138 * version 2 : do_step( sys , x , dxdt , t , dt ) 139 * 140 * this version does not solve the forwarding problem, boost.range can not be used 141 * 142 * the disable is needed to avoid ambiguous overloads if state_type = time_type 143 */ 144 template< class System , class StateInOut , class DerivInOut > 145 typename boost::disable_if< boost::is_same< StateInOut , time_type > , void >::type do_step(System system,StateInOut & x,DerivInOut & dxdt,time_type t,time_type dt)146 do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt ) 147 { 148 m_first_call = true; 149 this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt ); 150 } 151 152 153 /* 154 * named Version 2: do_step_dxdt_impl( sys , in , dxdt , t , dt ) 155 * 156 * this version is needed when this stepper is used for initializing 157 * multistep stepper like adams-bashforth. Hence we provide an explicitely 158 * named version that is not disabled. Meant for internal use only. 159 */ 160 template< class System , class StateInOut , class DerivInOut > do_step_dxdt_impl(System system,StateInOut & x,DerivInOut & dxdt,time_type t,time_type dt)161 void do_step_dxdt_impl( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt ) 162 { 163 m_first_call = true; 164 this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt ); 165 } 166 167 /* 168 * version 3 : do_step( sys , in , t , out , dt ) 169 * 170 * this version does not solve the forwarding problem, boost.range can not 171 * be used. 172 * 173 * the disable is needed to avoid ambiguous overloads if 174 * state_type = time_type 175 */ 176 template< class System , class StateIn , class StateOut > 177 typename boost::disable_if< boost::is_same< StateIn , time_type > , void >::type do_step(System system,const StateIn & in,time_type t,StateOut & out,time_type dt)178 do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) 179 { 180 if( m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call ) 181 { 182 initialize( system , in , t ); 183 } 184 this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , m_dxdt.m_v , dt ); 185 } 186 187 188 /* 189 * version 4 : do_step( sys , in , dxdt_in , t , out , dxdt_out , dt ) 190 * 191 * this version does not solve the forwarding problem, boost.range can not be used 192 */ 193 template< class System, class StateIn, class DerivIn, class StateOut, 194 class DerivOut > do_step(System system,const StateIn & in,const DerivIn & dxdt_in,time_type t,StateOut & out,DerivOut & dxdt_out,time_type dt)195 void do_step( System system, const StateIn &in, const DerivIn &dxdt_in, 196 time_type t, StateOut &out, DerivOut &dxdt_out, time_type dt ) 197 { 198 m_first_call = true; 199 this->stepper().do_step_impl( system, in, dxdt_in, t, out, dxdt_out, 200 dt ); 201 } 202 203 204 205 206 207 /* 208 * version 5 : do_step( sys , x , t , dt , xerr ) 209 * 210 * the two overloads are needed in order to solve the forwarding problem 211 */ 212 template< class System , class StateInOut , class Err > do_step(System system,StateInOut & x,time_type t,time_type dt,Err & xerr)213 void do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr ) 214 { 215 do_step_v5( system , x , t , dt , xerr ); 216 } 217 218 /** 219 * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut. 220 */ 221 template< class System , class StateInOut , class Err > do_step(System system,const StateInOut & x,time_type t,time_type dt,Err & xerr)222 void do_step( System system , const StateInOut &x , time_type t , time_type dt , Err &xerr ) 223 { 224 do_step_v5( system , x , t , dt , xerr ); 225 } 226 227 228 /* 229 * version 6 : do_step( sys , x , dxdt , t , dt , xerr ) 230 * 231 * this version does not solve the forwarding problem, boost.range can not be used 232 * 233 * the disable is needed to avoid ambiguous overloads if state_type = time_type 234 */ 235 template< class System , class StateInOut , class DerivInOut , class Err > 236 typename boost::disable_if< boost::is_same< StateInOut , time_type > , void >::type do_step(System system,StateInOut & x,DerivInOut & dxdt,time_type t,time_type dt,Err & xerr)237 do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt , Err &xerr ) 238 { 239 m_first_call = true; 240 this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt , xerr ); 241 } 242 243 244 245 246 /* 247 * version 7 : do_step( sys , in , t , out , dt , xerr ) 248 * 249 * this version does not solve the forwarding problem, boost.range can not be used 250 */ 251 template< class System , class StateIn , class StateOut , class Err > do_step(System system,const StateIn & in,time_type t,StateOut & out,time_type dt,Err & xerr)252 void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr ) 253 { 254 if( m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call ) 255 { 256 initialize( system , in , t ); 257 } 258 this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , m_dxdt.m_v , dt , xerr ); 259 } 260 261 262 /* 263 * version 8 : do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr ) 264 * 265 * this version does not solve the forwarding problem, boost.range can not be used 266 */ 267 template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut , class Err > do_step(System system,const StateIn & in,const DerivIn & dxdt_in,time_type t,StateOut & out,DerivOut & dxdt_out,time_type dt,Err & xerr)268 void do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , 269 StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr ) 270 { 271 m_first_call = true; 272 this->stepper().do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt , xerr ); 273 } 274 275 template< class StateIn > adjust_size(const StateIn & x)276 void adjust_size( const StateIn &x ) 277 { 278 resize_impl( x ); 279 } 280 reset(void)281 void reset( void ) 282 { 283 m_first_call = true; 284 } 285 286 template< class DerivIn > initialize(const DerivIn & deriv)287 void initialize( const DerivIn &deriv ) 288 { 289 boost::numeric::odeint::copy( deriv , m_dxdt.m_v ); 290 m_first_call = false; 291 } 292 293 template< class System , class StateIn > initialize(System system,const StateIn & x,time_type t)294 void initialize( System system , const StateIn &x , time_type t ) 295 { 296 typename odeint::unwrap_reference< System >::type &sys = system; 297 sys( x , m_dxdt.m_v , t ); 298 m_first_call = false; 299 } 300 is_initialized(void) const301 bool is_initialized( void ) const 302 { 303 return ! m_first_call; 304 } 305 306 307 308 private: 309 310 template< class System , class StateInOut > do_step_v1(System system,StateInOut & x,time_type t,time_type dt)311 void do_step_v1( System system , StateInOut &x , time_type t , time_type dt ) 312 { 313 if( m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call ) 314 { 315 initialize( system , x , t ); 316 } 317 this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , m_dxdt.m_v , dt ); 318 } 319 320 template< class System , class StateInOut , class Err > do_step_v5(System system,StateInOut & x,time_type t,time_type dt,Err & xerr)321 void do_step_v5( System system , StateInOut &x , time_type t , time_type dt , Err &xerr ) 322 { 323 if( m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call ) 324 { 325 initialize( system , x , t ); 326 } 327 this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , m_dxdt.m_v , dt , xerr ); 328 } 329 330 template< class StateIn > resize_impl(const StateIn & x)331 bool resize_impl( const StateIn &x ) 332 { 333 return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() ); 334 } 335 336 stepper(void)337 stepper_type& stepper( void ) 338 { 339 return *static_cast< stepper_type* >( this ); 340 } 341 stepper(void) const342 const stepper_type& stepper( void ) const 343 { 344 return *static_cast< const stepper_type* >( this ); 345 } 346 347 348 resizer_type m_resizer; 349 bool m_first_call; 350 351 protected: 352 353 354 wrapped_deriv_type m_dxdt; 355 }; 356 357 358 /******* DOXYGEN *******/ 359 360 /** 361 * \class explicit_error_stepper_fsal_base 362 * \brief Base class for explicit steppers with error estimation and stepper fulfilling the FSAL (first-same-as-last) 363 * property. This class can be used with controlled steppers for step size control. 364 * 365 * This class serves as the base class for all explicit steppers with algebra and operations and which fulfill the FSAL 366 * property. In contrast to explicit_stepper_base it also estimates the error and can be used in a controlled stepper 367 * to provide step size control. 368 * 369 * The FSAL property means that the derivative of the system at t+dt is already used in the current step going from 370 * t to t +dt. Therefore, some more do_steps method can be introduced and the controlled steppers can explicitly make use 371 * of this property. 372 * 373 * \note This stepper provides `do_step` methods with and without error estimation. It has therefore three orders, 374 * one for the order of a step if the error is not estimated. The other two orders are the orders of the step and 375 * the error step if the error estimation is performed. 376 * 377 * explicit_error_stepper_fsal_base is used as the interface in a CRTP (currently recurring template 378 * pattern). In order to work correctly the parent class needs to have a method 379 * `do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt , xerr )`. 380 * explicit_error_stepper_fsal_base derives from algebra_stepper_base. 381 * 382 * This class can have an intrinsic state depending on the explicit usage of the `do_step` method. This means that some 383 * `do_step` methods are expected to be called in order. For example the `do_step( sys , x , t , dt , xerr )` will keep track 384 * of the derivative of `x` which is the internal state. The first call of this method is recognized such that one 385 * does not explicitly initialize the internal state, so it is safe to use this method like 386 * 387 * \code 388 * stepper_type stepper; 389 * stepper.do_step( sys , x , t , dt , xerr ); 390 * stepper.do_step( sys , x , t , dt , xerr ); 391 * stepper.do_step( sys , x , t , dt , xerr ); 392 * \endcode 393 * 394 * But it is unsafe to call this method with different system functions after each other. Do do so, one must initialize the 395 * internal state with the `initialize` method or reset the internal state with the `reset` method. 396 * 397 * explicit_error_stepper_fsal_base provides several overloaded `do_step` methods, see the list below. Only two of them are needed 398 * to fulfill the Error Stepper concept. The other ones are for convenience and for better performance. Some of them 399 * simply update the state out-of-place, while other expect that the first derivative at `t` is passed to the stepper. 400 * 401 * - `do_step( sys , x , t , dt )` - The classical `do_step` method needed to fulfill the Error Stepper concept. The 402 * state is updated in-place. A type modelling a Boost.Range can be used for x. 403 * - `do_step( sys , x , dxdt , t , dt )` - This method updates the state x and the derivative dxdt in-place. It is expected 404 * that dxdt has the value of the derivative of x at time t. 405 * - `do_step( sys , in , t , out , dt )` - This method updates the state out-of-place, hence the result of the step 406 * is stored in `out`. 407 * - `do_step( sys , in , dxdt_in , t , out , dxdt_out , dt )` - This method updates the state and the derivative 408 * out-of-place. It expects that the derivative at the point `t` is explicitly passed in `dxdt_in`. 409 * - `do_step( sys , x , t , dt , xerr )` - This `do_step` method is needed to fulfill the Error Stepper concept. The 410 * state is updated in-place and an error estimate is calculated. A type modelling a Boost.Range can be used for x. 411 * - `do_step( sys , x , dxdt , t , dt , xerr )` - This method updates the state and the derivative in-place. It is assumed 412 * that the dxdt has the value of the derivative of x at time t. An error estimate is calculated. 413 * - `do_step( sys , in , t , out , dt , xerr )` - This method updates the state out-of-place and estimates the error 414 * during the step. 415 * - `do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr )` - This methods updates the state and the derivative 416 * out-of-place and estimates the error during the step. It is assumed the dxdt_in is derivative of in at time t. 417 * 418 * \note The system is always passed as value, which might result in poor performance if it contains data. In this 419 * case it can be used with `boost::ref` or `std::ref`, for example `stepper.do_step( boost::ref( sys ) , x , t , dt );` 420 * 421 * \note The time `t` is not advanced by the stepper. This has to done manually, or by the appropriate `integrate` 422 * routines or `iterator`s. 423 * 424 * \tparam Stepper The stepper on which this class should work. It is used via CRTP, hence explicit_stepper_base 425 * provides the interface for the Stepper. 426 * \tparam Order The order of a stepper if the stepper is used without error estimation. 427 * \tparam StepperOrder The order of a step if the stepper is used with error estimation. Usually Order and StepperOrder have 428 * the same value. 429 * \tparam ErrorOrder The order of the error step if the stepper is used with error estimation. 430 * \tparam State The state type for the stepper. 431 * \tparam Value The value type for the stepper. This should be a floating point type, like float, 432 * double, or a multiprecision type. It must not necessary be the value_type of the State. For example 433 * the State can be a `vector< complex< double > >` in this case the Value must be double. 434 * The default value is double. 435 * \tparam Deriv The type representing time derivatives of the state type. It is usually the same type as the 436 * state type, only if used with Boost.Units both types differ. 437 * \tparam Time The type representing the time. Usually the same type as the value type. When Boost.Units is 438 * used, this type has usually a unit. 439 * \tparam Algebra The algebra type which must fulfill the Algebra Concept. 440 * \tparam Operations The type for the operations which must fulfill the Operations Concept. 441 * \tparam Resizer The resizer policy class. 442 */ 443 444 445 446 /** 447 * \fn explicit_error_stepper_fsal_base::explicit_error_stepper_fsal_base( const algebra_type &algebra ) 448 * \brief Constructs a explicit_stepper_fsal_base class. This constructor can be used as a default 449 * constructor if the algebra has a default constructor. 450 * \param algebra A copy of algebra is made and stored inside explicit_stepper_base. 451 */ 452 453 454 /** 455 * \fn explicit_error_stepper_fsal_base::order( void ) const 456 * \return Returns the order of the stepper if it used without error estimation. 457 */ 458 459 /** 460 * \fn explicit_error_stepper_fsal_base::stepper_order( void ) const 461 * \return Returns the order of a step if the stepper is used without error estimation. 462 */ 463 464 465 /** 466 * \fn explicit_error_stepper_fsal_base::error_order( void ) const 467 * \return Returns the order of an error step if the stepper is used without error estimation. 468 */ 469 470 /** 471 * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , time_type t , time_type dt ) 472 * \brief This method performs one step. It transforms the result in-place. 473 * 474 * \note This method uses the internal state of the stepper. 475 * 476 * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the 477 * Simple System concept. 478 * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. 479 * \param t The value of the time, at which the step should be performed. 480 * \param dt The step size. 481 */ 482 483 484 /** 485 * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt ) 486 * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other methods 487 * the derivative of x is also passed to this method. Therefore, dxdt must be evaluated initially: 488 * 489 * \code 490 * ode( x , dxdt , t ); 491 * for( ... ) 492 * { 493 * stepper.do_step( ode , x , dxdt , t , dt ); 494 * t += dt; 495 * } 496 * \endcode 497 * 498 * \note This method does NOT use the initial state, since the first derivative is explicitly passed to this method. 499 * 500 * The result is updated in place in x as well as the derivative dxdt. This method is disabled if 501 * Time and StateInOut are of the same type. In this case the method could not be distinguished from other `do_step` 502 * versions. 503 * 504 * \note This method does not solve the forwarding problem. 505 * 506 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 507 * Simple System concept. 508 * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. 509 * \param dxdt The derivative of x at t. After calling `do_step` dxdt is updated to the new value. 510 * \param t The value of the time, at which the step should be performed. 511 * \param dt The step size. 512 */ 513 514 /** 515 * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) 516 * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. 517 * This method is disabled if StateIn and Time are the same type. In this case the method can not be distinguished from 518 * other `do_step` variants. 519 * 520 * \note This method uses the internal state of the stepper. 521 * 522 * \note This method does not solve the forwarding problem. 523 * 524 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 525 * Simple System concept. 526 * \param in The state of the ODE which should be solved. in is not modified in this method 527 * \param t The value of the time, at which the step should be performed. 528 * \param out The result of the step is written in out. 529 * \param dt The step size. 530 */ 531 532 /** 533 * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt ) 534 * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. 535 * Furthermore, the derivative of x at t is passed to the stepper and updated by the stepper to its new value at 536 * t+dt. 537 * 538 * \note This method does not solve the forwarding problem. 539 * 540 * \note This method does NOT use the internal state of the stepper. 541 * 542 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 543 * Simple System concept. 544 * \param in The state of the ODE which should be solved. in is not modified in this method 545 * \param dxdt_in The derivative of x at t. 546 * \param t The value of the time, at which the step should be performed. 547 * \param out The result of the step is written in out. 548 * \param dxdt_out The updated derivative of `out` at `t+dt`. 549 * \param dt The step size. 550 */ 551 552 /** 553 * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr ) 554 * \brief The method performs one step with the stepper passed by Stepper and estimates the error. The state of the ODE 555 * is updated in-place. 556 * 557 * 558 * \note This method uses the internal state of the stepper. 559 * 560 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 561 * Simple System concept. 562 * \param x The state of the ODE which should be solved. x is updated by this method. 563 * \param t The value of the time, at which the step should be performed. 564 * \param dt The step size. 565 * \param xerr The estimation of the error is stored in xerr. 566 */ 567 568 /** 569 * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt , Err &xerr ) 570 * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other method 571 * the derivative of x is also passed to this method and updated by this method. 572 * 573 * \note This method does NOT use the internal state of the stepper. 574 * 575 * The result is updated in place in x. This method is disabled if Time and Deriv are of the same type. In this 576 * case the method could not be distinguished from other `do_step` versions. This method is disabled if StateInOut and 577 * Time are of the same type. 578 * 579 * \note This method does NOT use the internal state of the stepper. 580 * 581 * \note This method does not solve the forwarding problem. 582 * 583 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 584 * Simple System concept. 585 * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. 586 * \param dxdt The derivative of x at t. After calling `do_step` this value is updated to the new value at `t+dt`. 587 * \param t The value of the time, at which the step should be performed. 588 * \param dt The step size. 589 * \param xerr The error estimate is stored in xerr. 590 */ 591 592 593 /** 594 * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr ) 595 * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. 596 * Furthermore, the error is estimated. 597 * 598 * \note This method uses the internal state of the stepper. 599 * 600 * \note This method does not solve the forwarding problem. 601 * 602 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 603 * Simple System concept. 604 * \param in The state of the ODE which should be solved. in is not modified in this method 605 * \param t The value of the time, at which the step should be performed. 606 * \param out The result of the step is written in out. 607 * \param dt The step size. 608 * \param xerr The error estimate. 609 */ 610 611 /** 612 * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr ) 613 * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. 614 * Furthermore, the derivative of x at t is passed to the stepper and the error is estimated. 615 * 616 * \note This method does NOT use the internal state of the stepper. 617 * 618 * \note This method does not solve the forwarding problem. 619 * 620 * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the 621 * Simple System concept. 622 * \param in The state of the ODE which should be solved. in is not modified in this method 623 * \param dxdt_in The derivative of x at t. 624 * \param t The value of the time, at which the step should be performed. 625 * \param out The result of the step is written in out. 626 * \param dxdt_out The new derivative at `t+dt` is written into this variable. 627 * \param dt The step size. 628 * \param xerr The error estimate. 629 */ 630 631 /** 632 * \fn explicit_error_stepper_fsal_base::adjust_size( const StateIn &x ) 633 * \brief Adjust the size of all temporaries in the stepper manually. 634 * \param x A state from which the size of the temporaries to be resized is deduced. 635 */ 636 637 /** 638 * \fn explicit_error_stepper_fsal_base::reset( void ) 639 * \brief Resets the internal state of this stepper. After calling this method it is safe to use all 640 * `do_step` method without explicitly initializing the stepper. 641 */ 642 643 /** 644 * \fn explicit_error_stepper_fsal_base::initialize( const DerivIn &deriv ) 645 * \brief Initializes the internal state of the stepper. 646 * \param deriv The derivative of x. The next call of `do_step` expects that the derivative of `x` passed to `do_step` 647 * has the value of `deriv`. 648 */ 649 650 /** 651 * \fn explicit_error_stepper_fsal_base::initialize( System system , const StateIn &x , time_type t ) 652 * \brief Initializes the internal state of the stepper. 653 * 654 * This method is equivalent to 655 * \code 656 * Deriv dxdt; 657 * system( x , dxdt , t ); 658 * stepper.initialize( dxdt ); 659 * \endcode 660 * 661 * \param system The system function for the next calls of `do_step`. 662 * \param x The current state of the ODE. 663 * \param t The current time of the ODE. 664 */ 665 666 /** 667 * \fn explicit_error_stepper_fsal_base::is_initialized( void ) const 668 * \brief Returns if the stepper is already initialized. If the stepper is not initialized, the first 669 * call of `do_step` will initialize the state of the stepper. If the stepper is already initialized 670 * the system function can not be safely exchanged between consecutive `do_step` calls. 671 */ 672 673 } // odeint 674 } // numeric 675 } // boost 676 677 #endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED 678