numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
rodasp_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
30
32
42template <concepts::problem Problem,
43 concepts::rosenbrock_equation_solver EquationSolver =
46 : public rosenbrock_formula_base<rodasp_formula<Problem, EquationSolver>,
47 Problem, EquationSolver> {
48public:
50 using base_type =
52 Problem, EquationSolver>;
53
55 using typename base_type::problem_type;
56 using typename base_type::scalar_type;
57 using typename base_type::variable_type;
58
62
63protected:
64 using base_type::coeff;
65
66public:
68 static constexpr index_type stages = 6;
69
71 static constexpr index_type order = 4;
72
78 static constexpr index_type lesser_order = 3;
79
81 static constexpr auto log_tag =
82 logging::log_tag_view("num_collect::ode::rosenbrock::rodasp_formula");
83
97 static constexpr scalar_type a21 = coeff(0.75);
98 static constexpr scalar_type a31 = coeff(8.6120400814152190e-2);
99 static constexpr scalar_type a32 = coeff(0.1238795991858478);
100 static constexpr scalar_type a41 = coeff(0.7749345355073236);
101 static constexpr scalar_type a42 = coeff(0.1492651549508680);
102 static constexpr scalar_type a43 = coeff(-0.2941996904581916);
103 static constexpr scalar_type a51 = coeff(5.308746682646142);
104 static constexpr scalar_type a52 = coeff(1.330892140037269);
105 static constexpr scalar_type a53 = coeff(-5.374137811655562);
106 static constexpr scalar_type a54 = coeff(-0.2655010110278497);
107 static constexpr scalar_type a61 = coeff(-1.764437648774483);
108 static constexpr scalar_type a62 = coeff(-0.4747565572063027);
109 static constexpr scalar_type a63 = coeff(2.369691846915802);
110 static constexpr scalar_type a64 = coeff(0.6195023590649829);
111 static constexpr scalar_type a65 = coeff(0.25);
112
113 static constexpr scalar_type b1 = coeff(0);
114 static constexpr scalar_type b2 = a21;
115 static constexpr scalar_type b3 = a31 + a32;
116 static constexpr scalar_type b4 = a41 + a42 + a43;
117 static constexpr scalar_type b5 = a51 + a52 + a53 + a54;
118 static constexpr scalar_type b6 = a61 + a62 + a63 + a64 + a65;
119
120 static constexpr scalar_type g21 = coeff(-0.75);
121 static constexpr scalar_type g31 = coeff(-0.1355124008141522);
122 static constexpr scalar_type g32 = coeff(-0.1379915991858478);
123 static constexpr scalar_type g41 = coeff(-1.2569840048950798);
124 static constexpr scalar_type g42 = coeff(-0.2501447105064236);
125 static constexpr scalar_type g43 = coeff(1.2209287154015032);
126 static constexpr scalar_type g51 = coeff(-7.073184331420625);
127 static constexpr scalar_type g52 = coeff(-1.805648697243572);
128 static constexpr scalar_type g53 = coeff(7.7438296585713635);
129 static constexpr scalar_type g54 = coeff(0.8850033700928326);
130 static constexpr scalar_type g61 = coeff(1.6840692779853665);
131 static constexpr scalar_type g62 = coeff(0.41826594361385516);
132 static constexpr scalar_type g63 = coeff(-1.8814062168730028);
133 static constexpr scalar_type g64 = coeff(-0.11378614758336392);
134 static constexpr scalar_type g65 = coeff(-0.3571428571428569);
135 static constexpr scalar_type g = coeff(0.25);
136
137 static constexpr scalar_type g1 = g;
138 static constexpr scalar_type g2 = g21 + g;
139 static constexpr scalar_type g3 = g31 + g32 + g;
140 static constexpr scalar_type g4 = g41 + g42 + g43 + g;
141 static constexpr scalar_type g5 = g51 + g52 + g53 + g54 + g;
142 static constexpr scalar_type g6 = g61 + g62 + g63 + g64 + g65 + g;
143
144 static constexpr scalar_type c1 = coeff(-8.0368370789113464e-2);
145 static constexpr scalar_type c2 = coeff(-5.6490613592447572e-2);
146 static constexpr scalar_type c3 = coeff(0.4882856300427991);
147 static constexpr scalar_type c4 = coeff(0.5057162114816189);
148 static constexpr scalar_type c5 = coeff(-0.1071428571428569);
149 static constexpr scalar_type c6 = coeff(0.25);
150
151 static constexpr scalar_type cw1 = coeff(-1.764437648774483);
152 static constexpr scalar_type cw2 = coeff(-0.4747565572063027);
153 static constexpr scalar_type cw3 = coeff(2.369691846915802);
154 static constexpr scalar_type cw4 = coeff(0.6195023590649829);
155 static constexpr scalar_type cw5 = coeff(0.25);
156
157 static constexpr scalar_type ce1 = c1 - cw1;
158 static constexpr scalar_type ce2 = c2 - cw2;
159 static constexpr scalar_type ce3 = c3 - cw3;
160 static constexpr scalar_type ce4 = c4 - cw4;
161 static constexpr scalar_type ce5 = c5 - cw5;
162 static constexpr scalar_type ce6 = c6;
164
172
174 void step(scalar_type time, scalar_type step_size,
175 const variable_type& current, variable_type& estimate) {
176 variable_type unused;
177 step_embedded(time, step_size, current, estimate, unused);
178 }
179
191 const variable_type& current, variable_type& estimate,
192 variable_type& error) {
193 equation_solver().evaluate_and_update_jacobian(
194 problem(), time, step_size, current);
195
196 // 1st stage
197 temp_rhs_ = problem().diff_coeff();
198 equation_solver().add_time_derivative_term(step_size, g1, temp_rhs_);
199 equation_solver().solve(temp_rhs_, k1_);
200
201 // 2nd stage
202 temp_var_ = g21 * k1_;
203 equation_solver().apply_jacobian(temp_var_, temp_rhs_);
204 temp_rhs_ *= step_size;
205 temp_var_ = current + step_size * (a21 * k1_);
206 problem().evaluate_on(time + b2 * step_size, temp_var_,
207 evaluation_type{.diff_coeff = true});
208 temp_rhs_ += problem().diff_coeff();
209 equation_solver().add_time_derivative_term(step_size, g2, temp_rhs_);
210 equation_solver().solve(temp_rhs_, k2_);
211
212 // 3rd stage
213 temp_var_ = g31 * k1_ + g32 * k2_;
214 equation_solver().apply_jacobian(temp_var_, temp_rhs_);
215 temp_rhs_ *= step_size;
216 temp_var_ = current + step_size * (a31 * k1_ + a32 * k2_);
217 problem().evaluate_on(time + b3 * step_size, temp_var_,
218 evaluation_type{.diff_coeff = true});
219 temp_rhs_ += problem().diff_coeff();
220 equation_solver().add_time_derivative_term(step_size, g3, temp_rhs_);
221 equation_solver().solve(temp_rhs_, k3_);
222
223 // 4th stage
224 temp_var_ = g41 * k1_ + g42 * k2_ + g43 * k3_;
225 equation_solver().apply_jacobian(temp_var_, temp_rhs_);
226 temp_rhs_ *= step_size;
227 temp_var_ = current + step_size * (a41 * k1_ + a42 * k2_ + a43 * k3_);
228 problem().evaluate_on(time + b4 * step_size, temp_var_,
229 evaluation_type{.diff_coeff = true});
230 temp_rhs_ += problem().diff_coeff();
231 equation_solver().add_time_derivative_term(step_size, g4, temp_rhs_);
232 equation_solver().solve(temp_rhs_, k4_);
233
234 // 5th stage
235 temp_var_ = g51 * k1_ + g52 * k2_ + g53 * k3_ + g54 * k4_;
236 equation_solver().apply_jacobian(temp_var_, temp_rhs_);
237 temp_rhs_ *= step_size;
238 temp_var_ = current +
239 step_size * (a51 * k1_ + a52 * k2_ + a53 * k3_ + a54 * k4_);
240 problem().evaluate_on(time + b5 * step_size, temp_var_,
241 evaluation_type{.diff_coeff = true});
242 temp_rhs_ += problem().diff_coeff();
243 equation_solver().add_time_derivative_term(step_size, g5, temp_rhs_);
244 equation_solver().solve(temp_rhs_, k5_);
245
246 // 6th stage
247 temp_var_ = g61 * k1_ + g62 * k2_ + g63 * k3_ + g64 * k4_ + g65 * k5_;
248 equation_solver().apply_jacobian(temp_var_, temp_rhs_);
249 temp_rhs_ *= step_size;
250 temp_var_ = current +
251 step_size *
252 (a61 * k1_ + a62 * k2_ + a63 * k3_ + a64 * k4_ + a65 * k5_);
253 problem().evaluate_on(time + b6 * step_size, temp_var_,
254 evaluation_type{.diff_coeff = true});
255 temp_rhs_ += problem().diff_coeff();
256 equation_solver().add_time_derivative_term(step_size, g6, temp_rhs_);
257 equation_solver().solve(temp_rhs_, k6_);
258
259 estimate = current +
260 step_size *
261 (c1 * k1_ + c2 * k2_ + c3 * k3_ + c4 * k4_ + c5 * k5_ +
262 c6 * k6_);
263 error = step_size *
264 (ce1 * k1_ + ce2 * k2_ + ce3 * k3_ + ce4 * k4_ + ce5 * k5_ +
265 ce6 * k6_);
266 }
267
268private:
281
284
287};
288
294template <concepts::problem Problem>
296
297} // namespace num_collect::ode::rosenbrock
Class of tags of logs without memory management.
Class of solvers of ODEs using embedded formulas.
Base class of formulas in ODE solvers.
auto problem() -> problem_type &
Get the problem.
Class of RODASP formula for Rosenbrock method.
static constexpr index_type order
Order of this formula.
static constexpr auto log_tag
Log tag.
static constexpr index_type lesser_order
Order of lesser coefficients of this formula.
rodasp_formula(const problem_type &problem)
Constructor.
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.
variable_type temp_var_
Temporary variable.
variable_type temp_rhs_
Temporary right-hand-side vector.
static constexpr index_type stages
Number of stages of this formula.
void step(scalar_type time, scalar_type step_size, const variable_type &current, variable_type &estimate)
Compute the next variable.
auto equation_solver() const -> const equation_solver_type &
Access the solver of equations in Rosenbrock methods.
Base class of formulas in Rosenbrock method.
typename problem_type::variable_type variable_type
Type of variables.
typename problem_type::scalar_type scalar_type
Type of scalars.
EquationSolver equation_solver_type
Type of class to solve equations in Rosenbrock methods.
auto equation_solver() const -> const equation_solver_type &
Access the solver of equations in Rosenbrock methods.
static constexpr auto coeff(T val) -> scalar_type
Convert coefficients.
Definition of default_rosenbrock_equation_solver class.
Definition of embedded_solver class.
Definition of evaluation_type enumeration.
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
typename default_rosenbrock_equation_solver< Problem >::type default_rosenbrock_equation_solver_t
Default class to solve equations in Rosenbrock methods.
Definition of problem concept.
Definition of rosenbrock_equation_solver concept.
Definition of rosenbrock_formula_base class.
Struct to specify types of evaluations.