24 using state_type =
typename base_type::state_type;
25 using time_type =
typename base_type::time_type;
26 using value_type =
typename base_type::value_type;
27 using system_function =
typename base_type::system_function;
30 time_type rtol =
static_cast<time_type
>(1e-6),
31 time_type atol =
static_cast<time_type
>(1e-9))
32 :
base_type(std::move(sys), rtol, atol) {}
34 void step(state_type& state, time_type dt)
override {
35 adaptive_step(state, dt);
38 time_type adaptive_step(state_type& state, time_type dt)
override {
39 const int max_attempts = 10;
40 time_type current_dt = dt;
42 for (
int attempt = 0; attempt < max_attempts; ++attempt) {
46 rk23_step(state, y_new, error, current_dt);
49 time_type err_norm = this->error_norm(error, y_new);
51 if (err_norm <= 1.0) {
54 this->advance_time(current_dt);
57 time_type next_dt = this->suggest_step_size(current_dt, err_norm, 3);
58 return std::max<time_type>(this->dt_min_, std::min<time_type>(this->dt_max_, next_dt));
61 current_dt *= std::max<time_type>(this->safety_factor_ * std::pow(err_norm, -1.0/3.0),
62 static_cast<time_type
>(0.1));
63 current_dt = std::max<time_type>(current_dt, this->dt_min_);
67 throw std::runtime_error(
"RK23: Maximum number of step size reductions exceeded");
71 void rk23_step(
const state_type& y, state_type& y_new, state_type& error, time_type dt) {
84 time_type t = this->current_time_;
90 for (std::size_t i = 0; i < y.size(); ++i) {
91 auto y_it = y.begin();
92 auto k1_it = k1.begin();
93 auto temp_it = temp.begin();
94 temp_it[i] = y_it[i] + dt * k1_it[i] /
static_cast<time_type
>(2);
96 this->sys_(t + dt /
static_cast<time_type
>(2), temp, k2);
99 for (std::size_t i = 0; i < y.size(); ++i) {
100 auto y_it = y.begin();
101 auto k2_it = k2.begin();
102 auto temp_it = temp.begin();
103 temp_it[i] = y_it[i] +
static_cast<time_type
>(3) * dt * k2_it[i] /
static_cast<time_type
>(4);
105 this->sys_(t +
static_cast<time_type
>(3) * dt /
static_cast<time_type
>(4), temp, k3);
108 for (std::size_t i = 0; i < y.size(); ++i) {
109 auto y_it = y.begin();
110 auto k1_it = k1.begin();
111 auto k2_it = k2.begin();
112 auto k3_it = k3.begin();
113 auto y_new_it = y_new.begin();
115 y_new_it[i] = y_it[i] + dt * (
static_cast<time_type
>(2) * k1_it[i] /
static_cast<time_type
>(9) +
116 k2_it[i] /
static_cast<time_type
>(3) +
117 static_cast<time_type
>(4) * k3_it[i] /
static_cast<time_type
>(9));
121 this->sys_(t + dt, y_new, k4);
124 for (std::size_t i = 0; i < y.size(); ++i) {
125 auto k1_it = k1.begin();
126 auto k2_it = k2.begin();
127 auto k3_it = k3.begin();
128 auto k4_it = k4.begin();
129 auto error_it = error.begin();
131 error_it[i] = dt * (
static_cast<time_type
>(5) * k1_it[i] /
static_cast<time_type
>(72) -
132 k2_it[i] /
static_cast<time_type
>(12) -
133 k3_it[i] /
static_cast<time_type
>(9) +
134 k4_it[i] /
static_cast<time_type
>(8));