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.
formula_base(const problem_type &problem=problem_type())
Class of DOPRI5 formula using coefficients in hairer1991.
static constexpr index_type order
Order of this formula.
static constexpr auto coeff(T val) -> scalar_type
Convert coefficients.
formula_base< dopri5_formula< Problem >, Problem > base_type
Type of base class.
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.
auto problem() -> problem_type &
Get the problem.
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.
embedded_solver< dopri5_formula< Problem > > dopri5_solver
Class of solver using DOPRI5 formula with coefficients in hairer1991.
Definition of problem concept.
Struct to specify types of evaluations.