numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
dopri5_formula.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
28
30
36template <concepts::problem Problem>
37class dopri5_formula : public formula_base<dopri5_formula<Problem>, Problem> {
38public:
41
42 using typename base_type::problem_type;
43 using typename base_type::scalar_type;
44 using typename base_type::variable_type;
45
46 static_assert(!problem_type::allowed_evaluations.mass,
47 "Mass matrix is not supported.");
48
49 using base_type::base_type;
51
52protected:
53 using base_type::coeff;
54
55public:
57 static constexpr index_type stages = 7;
58
60 static constexpr index_type order = 5;
61
63 static constexpr auto log_tag =
64 logging::log_tag_view("num_collect::ode::runge_kutta::dopri5_formula");
65
67 static constexpr index_type lesser_order = 4;
68
80 static constexpr scalar_type a21 = coeff(1, 5);
81 static constexpr scalar_type a31 = coeff(3, 40);
82 static constexpr scalar_type a32 = coeff(9, 40);
83 static constexpr scalar_type a41 = coeff(44, 45);
84 static constexpr scalar_type a42 = coeff(-56, 15);
85 static constexpr scalar_type a43 = coeff(32, 9);
86 static constexpr scalar_type a51 = coeff(19372, 6561);
87 static constexpr scalar_type a52 = coeff(-25360, 2187);
88 static constexpr scalar_type a53 = coeff(64448, 6561);
89 static constexpr scalar_type a54 = coeff(-212, 729);
90 static constexpr scalar_type a61 = coeff(9017, 3168);
91 static constexpr scalar_type a62 = coeff(-355, 33);
92 static constexpr scalar_type a63 = coeff(46732, 5247);
93 static constexpr scalar_type a64 = coeff(49, 176);
94 static constexpr scalar_type a65 = coeff(-5103, 18656);
95 static constexpr scalar_type a71 = coeff(35, 384);
96 static constexpr scalar_type a72 = coeff(0);
97 static constexpr scalar_type a73 = coeff(500, 1113);
98 static constexpr scalar_type a74 = coeff(125, 192);
99 static constexpr scalar_type a75 = coeff(-2187, 6784);
100 static constexpr scalar_type a76 = coeff(11, 84);
101
102 static constexpr scalar_type b2 = coeff(1, 5);
103 static constexpr scalar_type b3 = coeff(3, 10);
104 static constexpr scalar_type b4 = coeff(4, 5);
105 static constexpr scalar_type b5 = coeff(8, 9);
106 static constexpr scalar_type b6 = coeff(1);
107 static constexpr scalar_type b7 = coeff(1);
108
109 static constexpr scalar_type c1 = a71;
110 // c2 = 0
111 static constexpr scalar_type c3 = a73;
112 static constexpr scalar_type c4 = a74;
113 static constexpr scalar_type c5 = a75;
114 static constexpr scalar_type c6 = a76;
115 // c7 = 0
116
117 static constexpr scalar_type cw1 = coeff(5179, 57600);
118 // c22 = 0
119 static constexpr scalar_type cw3 = coeff(7571, 16695);
120 static constexpr scalar_type cw4 = coeff(393, 640);
121 static constexpr scalar_type cw5 = coeff(-92097, 339200);
122 static constexpr scalar_type cw6 = coeff(187, 2100);
123 static constexpr scalar_type cw7 = coeff(1, 40);
124
125 static constexpr scalar_type ce1 = c1 - cw1;
126 // ce2 = 0
127 static constexpr scalar_type ce3 = c3 - cw3;
128 static constexpr scalar_type ce4 = c4 - cw4;
129 static constexpr scalar_type ce5 = c5 - cw5;
130 static constexpr scalar_type ce6 = c6 - cw6;
131 static constexpr scalar_type ce7 = -cw7;
133
135 void step(scalar_type time, scalar_type step_size,
136 const variable_type& current, variable_type& estimate) {
137 constexpr auto evaluations = evaluation_type{.diff_coeff = true};
138
139 problem().evaluate_on(time, current, evaluations);
140 k1_ = problem().diff_coeff();
141
142 problem().evaluate_on(time + b2 * step_size,
143 current + step_size * a21 * k1_, evaluations);
144 k2_ = problem().diff_coeff();
145
146 problem().evaluate_on(time + b3 * step_size,
147 current + step_size * (a31 * k1_ + a32 * k2_), evaluations);
148 k3_ = problem().diff_coeff();
149
150 problem().evaluate_on(time + b4 * step_size,
151 current + step_size * (a41 * k1_ + a42 * k2_ + a43 * k3_),
152 evaluations);
153 k4_ = problem().diff_coeff();
154
155 problem().evaluate_on(time + b5 * step_size,
156 current +
157 step_size * (a51 * k1_ + a52 * k2_ + a53 * k3_ + a54 * k4_),
158 evaluations);
159 k5_ = problem().diff_coeff();
160
161 problem().evaluate_on(time + b6 * step_size,
162 current +
163 step_size *
164 (a61 * k1_ + a62 * k2_ + a63 * k3_ + a64 * k4_ + a65 * k5_),
165 evaluations);
166 k6_ = problem().diff_coeff();
167
168 estimate = current +
169 step_size * (c1 * k1_ + c3 * k3_ + c4 * k4_ + c5 * k5_ + c6 * k6_);
170 }
171
183 const variable_type& current, variable_type& estimate,
184 variable_type& error) {
185 step(time, step_size, current, estimate);
186
187 constexpr auto evaluations = evaluation_type{.diff_coeff = true};
188 problem().evaluate_on(time + b7 * step_size, estimate, evaluations);
189 k7_ = problem().diff_coeff();
190
191 error = step_size *
192 (ce1 * k1_ + ce3 * k3_ + ce4 * k4_ + ce5 * k5_ + ce6 * k6_ +
193 ce7 * k7_);
194 }
195
196private:
210};
211
218template <concepts::problem Problem>
220
221} // namespace num_collect::ode::runge_kutta
Class of tags of logs without memory management.
Class of solvers of ODEs using embedded formulas.
Base class of formulas in ODE solvers.
Class of DOPRI5 formula using coefficients in hairer1991.
static constexpr index_type order
Order of this formula.
void step(scalar_type time, scalar_type step_size, const variable_type &current, variable_type &estimate)
Compute the next variable.
static constexpr index_type stages
Number of stages of this formula.
static constexpr index_type lesser_order
Order of lesser coefficients of this formula.
void step_embedded(scalar_type time, scalar_type step_size, const variable_type &current, variable_type &estimate, variable_type &error)
Compute the next variable and weak estimate of it with embedded formula.
Definition of embedded_solver class.
Definition of evaluation_type enumeration.
Definition of formula_base class.
Definition of index_type type.
Definition of log_tag_view class.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Namespace of Runge-Kutta method.
Definition of problem concept.
Struct to specify types of evaluations.
bool diff_coeff
Differential coefficient.