1#ifndef TATOOINE_ODE_BOOST_CONTROLLED_RUNGE_KUTTA_WITH_DOMAIN_CHECK_H
2#define TATOOINE_ODE_BOOST_CONTROLLED_RUNGE_KUTTA_WITH_DOMAIN_CHECK_H
4#include <boost/config.hpp>
5#include <boost/numeric/odeint/algebra/default_operations.hpp>
6#include <boost/numeric/odeint/algebra/range_algebra.hpp>
7#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
8#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
9#include <boost/numeric/odeint/util/bind.hpp>
10#include <boost/numeric/odeint/util/copy.hpp>
11#include <boost/numeric/odeint/util/is_resizeable.hpp>
12#include <boost/numeric/odeint/util/resizer.hpp>
13#include <boost/numeric/odeint/util/state_wrapper.hpp>
14#include <boost/numeric/odeint/util/unwrap_reference.hpp>
15#include <boost/type_traits/is_same.hpp>
16#include <boost/utility/enable_if.hpp>
21template <
typename Value,
typename Algebra = ::boost::numeric::odeint::range_algebra,
22 typename Operations = ::boost::numeric::odeint::default_operations>
35 template <
typename State,
typename Deriv,
typename Err,
typename Time>
41 template <
typename State,
typename Deriv,
typename Err,
typename Time>
43 const Deriv &dxdt_old, Err &x_err, Time dt)
const {
46 x_err, x_old, dxdt_old,
47 typename operations_type::template rel_error<value_type>(
51 x_err,
typename operations_type::template maximum<value_type>(),
64template <
typename ErrorStepper,
65 typename ErrorChecker =
67 typename ErrorStepper::algebra_type,
68 typename ErrorStepper::operations_type>,
69 typename Resizer =
typename ErrorStepper::resizer_type,
70 typename ErrorStepperCategory =
typename ErrorStepper::stepper_category>
93template <
typename ErrorStepper,
typename ErrorChecker,
typename Resizer>
95 ErrorStepper, ErrorChecker, Resizer,
96 ::boost::numeric::odeint::explicit_error_stepper_tag> {
115 explicit_error_stepper_tag>;
126 : m_stepper(stepper), m_error_checker(error_checker) {}
149 template <
typename System,
typename StateInOut>
152 return try_step_v1(system, x, t, dt);
173 template <
typename System,
typename StateInOut>
174 controlled_step_result
try_step(System system,
const StateInOut &x,
176 return try_step_v1(system, x, t, dt);
202 template <
typename System,
typename StateInOut,
typename DerivIn>
203 controlled_step_result
try_step(System system, StateInOut &x,
206 m_xnew_resizer.adjust_size(
208 &controlled_runge_kutta_with_domain_check::template resize_m_xnew_impl<StateInOut>,
209 detail::ref(*
this), detail::_1));
210 controlled_step_result res = try_step(system, x, dxdt, t, m_xnew.m_v, dt);
211 if (res == success) {
212 boost::numeric::odeint::copy(m_xnew.m_v, x);
245 template <
typename System,
typename StateIn,
typename StateOut>
246 typename boost::disable_if<boost::is_same<StateIn, time_type>,
247 controlled_step_result>::type
250 typename odeint::unwrap_reference<System>::type &sys = system;
251 m_dxdt_resizer.adjust_size(
253 &controlled_runge_kutta_with_domain_check::template resize_m_dxdt_impl<StateIn>,
254 detail::ref(*
this), detail::_1));
255 sys(in, m_dxdt.m_v, t);
256 return try_step(system, in, m_dxdt.m_v, t, out, dt);
282 template <
typename System,
typename StateIn,
typename DerivIn,
typename StateOut>
283 controlled_step_result
try_step(System system,
const StateIn &in,
286 BOOST_USING_STD_MIN();
287 BOOST_USING_STD_MAX();
290 m_xerr_resizer.adjust_size(
292 &controlled_runge_kutta_with_domain_check::template resize_m_xerr_impl<StateIn>,
293 detail::ref(*
this), detail::_1));
296 m_stepper.do_step(system, in, dxdt, t, out, dt, m_xerr.m_v);
299 m_error_checker.error(m_stepper.algebra(), in, dxdt, m_xerr.m_v, dt);
301 if (m_max_rel_error > 1.0) {
304 dt *=
max BOOST_PREVENT_MACRO_SUBSTITUTION(
307 static_cast<value_type>(-1) / (m_stepper.error_order() - 1)),
311 if (m_max_rel_error < 0.5) {
313 m_max_rel_error =
max BOOST_PREVENT_MACRO_SUBSTITUTION(
314 pow(5.0, -m_stepper.stepper_order()), m_max_rel_error);
320 static_cast<value_type>(-1) / m_stepper.stepper_order());
341 template <
typename StateType>
343 resize_m_xerr_impl(x);
344 resize_m_dxdt_impl(x);
345 resize_m_xnew_impl(x);
346 m_stepper.adjust_size(x);
362 template <
typename System,
typename StateInOut>
365 typename odeint::unwrap_reference<System>::type &sys = system;
366 m_dxdt_resizer.adjust_size(
368 &controlled_runge_kutta_with_domain_check::template resize_m_dxdt_impl<StateInOut>,
369 detail::ref(*
this), detail::_1));
370 sys(x, m_dxdt.m_v, t);
371 return try_step(system, x, m_dxdt.m_v, t, dt);
374 template <
typename StateIn>
376 return adjust_size_by_resizeability(
377 m_xerr, x,
typename is_resizeable<state_type>::type());
380 template <
typename StateIn>
382 return adjust_size_by_resizeability(
383 m_dxdt, x,
typename is_resizeable<deriv_type>::type());
386 template <
typename StateIn>
388 return adjust_size_by_resizeability(
389 m_xnew, x,
typename is_resizeable<state_type>::type());
425template <
typename ErrorStepper,
typename ErrorChecker,
typename Resizer>
427 explicit_error_stepper_fsal_tag> {
446 explicit_error_stepper_tag>;
457 : m_stepper(stepper),
458 m_error_checker(error_checker),
459 m_first_call(true) {}
482 template <
typename System,
typename StateInOut>
485 return try_step_v1(system, x, t, dt);
506 template <
typename System,
typename StateInOut>
507 controlled_step_result
try_step(System system,
const StateInOut &x,
509 return try_step_v1(system, x, t, dt);
539 template <
typename System,
typename StateIn,
typename StateOut>
540 typename boost::disable_if<boost::is_same<StateIn, time_type>,
541 controlled_step_result>::type
544 if (m_dxdt_resizer.adjust_size(
547 &controlled_runge_kutta_with_domain_check::template resize_m_dxdt_impl<StateIn>,
548 detail::ref(*
this), detail::_1)) ||
550 initialize(system, in, t);
552 return try_step(system, in, m_dxdt.m_v, t, out, dt);
578 template <
typename System,
typename StateInOut,
typename DerivInOut>
579 controlled_step_result
try_step(System system, StateInOut &x,
582 m_xnew_resizer.adjust_size(
584 &controlled_runge_kutta_with_domain_check::template resize_m_xnew_impl<StateInOut>,
585 detail::ref(*
this), detail::_1));
586 m_dxdt_new_resizer.adjust_size(
588 detail::bind(&controlled_runge_kutta_with_domain_check::template resize_m_dxdt_new_impl<
590 detail::ref(*
this), detail::_1));
591 controlled_step_result res =
592 try_step(system, x, dxdt, t, m_xnew.m_v, m_dxdtnew.m_v, dt);
593 if (res == success) {
594 boost::numeric::odeint::copy(m_xnew.m_v, x);
595 boost::numeric::odeint::copy(m_dxdtnew.m_v, dxdt);
623 template <
typename System,
typename StateIn,
typename DerivIn,
typename StateOut,
625 controlled_step_result
try_step(System system,
const StateIn &in,
627 StateOut &out, DerivOut &dxdt_out,
629 BOOST_USING_STD_MIN();
630 BOOST_USING_STD_MAX();
634 m_xerr_resizer.adjust_size(
636 &controlled_runge_kutta_with_domain_check::template resize_m_xerr_impl<StateIn>,
637 detail::ref(*
this), detail::_1));
641 m_stepper.do_step(system, in, dxdt_in, t, out, dxdt_out, dt, m_xerr.m_v);
646 m_error_checker.error(m_stepper.algebra(), in, dxdt_in, m_xerr.m_v, dt);
648 if (max_rel_err > 1.0) {
651 dt *=
max BOOST_PREVENT_MACRO_SUBSTITUTION(
655 static_cast<value_type>(-1) / (m_stepper.error_order() - 1))),
660 if (max_rel_err < 0.5) {
663 max_rel_err =
max BOOST_PREVENT_MACRO_SUBSTITUTION(
664 pow(5.0, -m_stepper.stepper_order()), max_rel_err);
669 static_cast<value_type>(-1) / m_stepper.stepper_order()));
681 void reset(
void) { m_first_call =
true; }
689 template <
typename DerivIn>
691 boost::numeric::odeint::copy(deriv, m_dxdt.m_v);
692 m_first_call =
false;
703 template <
typename System,
typename StateIn>
705 typename odeint::unwrap_reference<System>::type &sys = system;
706 sys(x, m_dxdt.m_v, t);
707 m_first_call =
false;
722 template <
typename StateType>
724 resize_m_xerr_impl(x);
725 resize_m_dxdt_impl(x);
726 resize_m_dxdt_new_impl(x);
727 resize_m_xnew_impl(x);
743 template <
typename StateIn>
745 return adjust_size_by_resizeability(
746 m_xerr, x,
typename is_resizeable<state_type>::type());
749 template <
typename StateIn>
751 return adjust_size_by_resizeability(
752 m_dxdt, x,
typename is_resizeable<deriv_type>::type());
755 template <
typename StateIn>
757 return adjust_size_by_resizeability(
758 m_dxdtnew, x,
typename is_resizeable<deriv_type>::type());
761 template <
typename StateIn>
763 return adjust_size_by_resizeability(
764 m_xnew, x,
typename is_resizeable<state_type>::type());
767 template <
typename System,
typename StateInOut>
770 if (m_dxdt_resizer.adjust_size(
772 detail::bind(&controlled_runge_kutta_with_domain_check::template resize_m_dxdt_impl<
774 detail::ref(*
this), detail::_1)) ||
776 initialize(system, x, t);
778 return try_step(system, x, m_dxdt.m_v, t, dt);
controlled_step_result try_step(System system, StateInOut &x, time_type &t, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:150
typename stepper_type::value_type value_type
Definition: controller_runge_kutta_with_domain_check.h:100
typename stepper_type::deriv_type deriv_type
Definition: controller_runge_kutta_with_domain_check.h:101
controlled_step_result try_step(System system, const StateInOut &x, time_type &t, time_type &dt)
Tries to perform one step. Solves the forwarding problem and allows for using boost range as state_ty...
Definition: controller_runge_kutta_with_domain_check.h:174
typename stepper_type::time_type time_type
Definition: controller_runge_kutta_with_domain_check.h:102
typename stepper_type::wrapped_state_type wrapped_state_type
Definition: controller_runge_kutta_with_domain_check.h:110
bool resize_m_xerr_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:375
controlled_runge_kutta_with_domain_check(const error_checker_type &error_checker=error_checker_type(), const stepper_type &stepper=stepper_type())
Constructs the controlled Runge-Kutta stepper.
Definition: controller_runge_kutta_with_domain_check.h:123
typename stepper_type::operations_type operations_type
Definition: controller_runge_kutta_with_domain_check.h:104
typename stepper_type::algebra_type algebra_type
Definition: controller_runge_kutta_with_domain_check.h:103
bool resize_m_dxdt_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:381
wrapped_state_type m_xnew
Definition: controller_runge_kutta_with_domain_check.h:401
typename stepper_type::state_type state_type
Definition: controller_runge_kutta_with_domain_check.h:99
bool resize_m_xnew_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:387
error_checker_type m_error_checker
Definition: controller_runge_kutta_with_domain_check.h:393
resizer_type m_xnew_resizer
Definition: controller_runge_kutta_with_domain_check.h:397
ErrorStepper stepper_type
Definition: controller_runge_kutta_with_domain_check.h:98
value_type last_error(void) const
Returns the error of the last step.
Definition: controller_runge_kutta_with_domain_check.h:334
ErrorChecker error_checker_type
Definition: controller_runge_kutta_with_domain_check.h:106
resizer_type m_dxdt_resizer
Definition: controller_runge_kutta_with_domain_check.h:395
controlled_step_result try_step(System system, const StateIn &in, const DerivIn &dxdt, time_type &t, StateOut &out, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:283
value_type m_max_rel_error
Definition: controller_runge_kutta_with_domain_check.h:402
stepper_type & stepper(void)
Returns the instance of the underlying stepper.
Definition: controller_runge_kutta_with_domain_check.h:353
stepper_type m_stepper
Definition: controller_runge_kutta_with_domain_check.h:392
controlled_step_result try_step(System system, StateInOut &x, const DerivIn &dxdt, time_type &t, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:203
typename stepper_type::wrapped_deriv_type wrapped_deriv_type
Definition: controller_runge_kutta_with_domain_check.h:111
Resizer resizer_type
Definition: controller_runge_kutta_with_domain_check.h:105
const stepper_type & stepper(void) const
Returns the instance of the underlying stepper.
Definition: controller_runge_kutta_with_domain_check.h:359
void adjust_size(const StateType &x)
Adjust the size of all temporaries in the stepper manually.
Definition: controller_runge_kutta_with_domain_check.h:342
boost::disable_if< boost::is_same< StateIn, time_type >, controlled_step_result >::type try_step(System system, const StateIn &in, time_type &t, StateOut &out, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:248
controlled_step_result try_step_v1(System system, StateInOut &x, time_type &t, time_type &dt)
Definition: controller_runge_kutta_with_domain_check.h:363
wrapped_deriv_type m_dxdt
Definition: controller_runge_kutta_with_domain_check.h:399
wrapped_state_type m_xerr
Definition: controller_runge_kutta_with_domain_check.h:400
resizer_type m_xerr_resizer
Definition: controller_runge_kutta_with_domain_check.h:396
explicit_controlled_stepper_tag stepper_category
Definition: controller_runge_kutta_with_domain_check.h:107
resizer_type m_dxdt_resizer
Definition: controller_runge_kutta_with_domain_check.h:784
bool m_first_call
Definition: controller_runge_kutta_with_domain_check.h:793
resizer_type m_xerr_resizer
Definition: controller_runge_kutta_with_domain_check.h:785
wrapped_deriv_type m_dxdt
Definition: controller_runge_kutta_with_domain_check.h:789
typename stepper_type::operations_type operations_type
Definition: controller_runge_kutta_with_domain_check.h:435
void adjust_size(const StateType &x)
Adjust the size of all temporaries in the stepper manually.
Definition: controller_runge_kutta_with_domain_check.h:723
typename stepper_type::wrapped_state_type wrapped_state_type
Definition: controller_runge_kutta_with_domain_check.h:441
wrapped_state_type m_xnew
Definition: controller_runge_kutta_with_domain_check.h:791
explicit_controlled_stepper_fsal_tag stepper_category
Definition: controller_runge_kutta_with_domain_check.h:438
stepper_type & stepper(void)
Returns the instance of the underlying stepper.
Definition: controller_runge_kutta_with_domain_check.h:734
bool resize_m_xnew_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:762
resizer_type m_dxdt_new_resizer
Definition: controller_runge_kutta_with_domain_check.h:787
controlled_step_result try_step(System system, const StateInOut &x, time_type &t, time_type &dt)
Tries to perform one step. Solves the forwarding problem and allows for using boost range as state_ty...
Definition: controller_runge_kutta_with_domain_check.h:507
wrapped_deriv_type m_dxdtnew
Definition: controller_runge_kutta_with_domain_check.h:792
bool is_initialized(void) const
Returns true if the stepper has been initialized, false otherwise.
Definition: controller_runge_kutta_with_domain_check.h:715
ErrorChecker error_checker_type
Definition: controller_runge_kutta_with_domain_check.h:437
controlled_step_result try_step(System system, const StateIn &in, const DerivIn &dxdt_in, time_type &t, StateOut &out, DerivOut &dxdt_out, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:625
wrapped_state_type m_xerr
Definition: controller_runge_kutta_with_domain_check.h:790
bool resize_m_xerr_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:744
typename stepper_type::state_type state_type
Definition: controller_runge_kutta_with_domain_check.h:430
typename stepper_type::deriv_type deriv_type
Definition: controller_runge_kutta_with_domain_check.h:432
Resizer resizer_type
Definition: controller_runge_kutta_with_domain_check.h:436
void initialize(const DerivIn &deriv)
Initializes the internal state storing an internal copy of the derivative.
Definition: controller_runge_kutta_with_domain_check.h:690
void initialize(System system, const StateIn &x, time_type t)
Initializes the internal state storing an internal copy of the derivative.
Definition: controller_runge_kutta_with_domain_check.h:704
controlled_step_result try_step_v1(System system, StateInOut &x, time_type &t, time_type &dt)
Definition: controller_runge_kutta_with_domain_check.h:768
controlled_step_result try_step(System system, StateInOut &x, DerivInOut &dxdt, time_type &t, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:579
resizer_type m_xnew_resizer
Definition: controller_runge_kutta_with_domain_check.h:786
error_checker_type m_error_checker
Definition: controller_runge_kutta_with_domain_check.h:782
controlled_step_result try_step(System system, StateInOut &x, time_type &t, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:483
typename stepper_type::time_type time_type
Definition: controller_runge_kutta_with_domain_check.h:433
const stepper_type & stepper(void) const
Returns the instance of the underlying stepper.
Definition: controller_runge_kutta_with_domain_check.h:740
boost::disable_if< boost::is_same< StateIn, time_type >, controlled_step_result >::type try_step(System system, const StateIn &in, time_type &t, StateOut &out, time_type &dt)
Tries to perform one step.
Definition: controller_runge_kutta_with_domain_check.h:542
typename stepper_type::algebra_type algebra_type
Definition: controller_runge_kutta_with_domain_check.h:434
bool resize_m_dxdt_new_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:756
bool resize_m_dxdt_impl(const StateIn &x)
Definition: controller_runge_kutta_with_domain_check.h:750
typename stepper_type::wrapped_deriv_type wrapped_deriv_type
Definition: controller_runge_kutta_with_domain_check.h:442
void reset(void)
Resets the internal state of the underlying FSAL stepper.
Definition: controller_runge_kutta_with_domain_check.h:681
typename stepper_type::value_type value_type
Definition: controller_runge_kutta_with_domain_check.h:431
controlled_runge_kutta_with_domain_check(const error_checker_type &error_checker=error_checker_type(), const stepper_type &stepper=stepper_type())
Constructs the controlled Runge-Kutta stepper.
Definition: controller_runge_kutta_with_domain_check.h:454
stepper_type m_stepper
Definition: controller_runge_kutta_with_domain_check.h:781
ErrorStepper stepper_type
Definition: controller_runge_kutta_with_domain_check.h:429
error stepper category dispatcher
Definition: controller_runge_kutta_with_domain_check.h:71
The default error checker to be used with Runge-Kutta error steppers.
Definition: controller_runge_kutta_with_domain_check.h:23
value_type m_a_x
Definition: controller_runge_kutta_with_domain_check.h:59
Value value_type
Definition: controller_runge_kutta_with_domain_check.h:25
value_type error(algebra_type &algebra, const State &x_old, const Deriv &dxdt_old, Err &x_err, Time dt) const
Definition: controller_runge_kutta_with_domain_check.h:42
value_type m_eps_abs
Definition: controller_runge_kutta_with_domain_check.h:57
value_type error(const State &x_old, const Deriv &dxdt_old, Err &x_err, Time dt) const
Definition: controller_runge_kutta_with_domain_check.h:36
default_error_checker(value_type eps_abs=static_cast< value_type >(1.0e-6), value_type eps_rel=static_cast< value_type >(1.0e-6), value_type a_x=static_cast< value_type >(1), value_type a_dxdt=static_cast< value_type >(1))
Definition: controller_runge_kutta_with_domain_check.h:29
value_type m_a_dxdt
Definition: controller_runge_kutta_with_domain_check.h:60
Operations operations_type
Definition: controller_runge_kutta_with_domain_check.h:27
Algebra algebra_type
Definition: controller_runge_kutta_with_domain_check.h:26
value_type m_eps_rel
Definition: controller_runge_kutta_with_domain_check.h:58
Definition: controller_runge_kutta_with_domain_check.h:19
constexpr auto pow(arithmetic auto const x)
Definition: math.h:30
constexpr auto max(A &&a, B &&b)
Definition: math.h:20