numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
esdirk45_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
39template <concepts::problem Problem,
40 concepts::update_equation_solver FormulaSolver =
41 inexact_newton_update_equation_solver<Problem>>
43 : public implicit_formula_base<esdirk45_formula<Problem, FormulaSolver>,
44 Problem, FormulaSolver> {
45public:
48
50 using base_type =
52 FormulaSolver>;
53
54 using typename base_type::problem_type;
55 using typename base_type::scalar_type;
56 using typename base_type::variable_type;
57
58 static_assert(!problem_type::allowed_evaluations.mass,
59 "Mass matrix is not supported.");
60
63
64protected:
65 using base_type::coeff;
67
68public:
70 static constexpr index_type stages = 6;
71
73 static constexpr index_type order = 5;
74
76 static constexpr index_type lesser_order = 4;
77
79 static constexpr auto log_tag = logging::log_tag_view(
80 "num_collect::ode::runge_kutta::esdirk45_formula");
81
93 static constexpr scalar_type ad = coeff(1, 4); // diagonal coefficient
94 static constexpr scalar_type a21 = coeff(1, 4);
95 static constexpr scalar_type a31 = coeff(1, 16);
96 static constexpr scalar_type a32 = coeff(-1, 16);
97 static constexpr scalar_type a41 = coeff(-7, 36);
98 static constexpr scalar_type a42 = coeff(-4, 9);
99 static constexpr scalar_type a43 = coeff(8, 9);
100 static constexpr scalar_type a51 = coeff(-5, 48);
101 static constexpr scalar_type a52 = coeff(-257, 768);
102 static constexpr scalar_type a53 = coeff(5, 6);
103 static constexpr scalar_type a54 = coeff(27, 256);
104 static constexpr scalar_type a61 = coeff(1, 4);
105 static constexpr scalar_type a62 = coeff(2, 3);
106 static constexpr scalar_type a63 = coeff(-1, 3);
107 static constexpr scalar_type a64 = coeff(1, 2);
108 static constexpr scalar_type a65 = coeff(-1, 3);
109
110 // b1 = 0
111 static constexpr scalar_type b2 = coeff(1, 2);
112 static constexpr scalar_type b3 = coeff(1, 4);
113 static constexpr scalar_type b4 = coeff(1, 2);
114 static constexpr scalar_type b5 = coeff(3, 4);
115 static constexpr scalar_type b6 = coeff(1);
116
117 static constexpr scalar_type c1 = a61;
118 static constexpr scalar_type c2 = a62;
119 static constexpr scalar_type c3 = a63;
120 static constexpr scalar_type c4 = a64;
121 static constexpr scalar_type c5 = a65;
122 static constexpr scalar_type c6 = ad;
123
124 static constexpr scalar_type cw1 = coeff(7, 90);
125 static constexpr scalar_type cw2 = coeff(3, 20);
126 static constexpr scalar_type cw3 = coeff(16, 45);
127 static constexpr scalar_type cw4 = coeff(-1, 60);
128 static constexpr scalar_type cw5 = coeff(16, 45);
129 static constexpr scalar_type cw6 = coeff(7, 90);
130
131 static constexpr scalar_type ce1 = c1 - cw1;
132 static constexpr scalar_type ce2 = c2 - cw2;
133 static constexpr scalar_type ce3 = c3 - cw3;
134 static constexpr scalar_type ce4 = c4 - cw4;
135 static constexpr scalar_type ce5 = c5 - cw5;
136 static constexpr scalar_type ce6 = c6 - cw6;
138
140 void step(scalar_type time, scalar_type step_size,
141 const variable_type& current, variable_type& estimate) {
142 formula_solver().update_jacobian(
143 problem(), time, step_size, current, ad);
144
145 problem().evaluate_on(
146 time, current, evaluation_type{.diff_coeff = true});
147 k1_ = problem().diff_coeff();
148
149 z2_ = step_size * ad * k1_;
150 formula_solver().init(
151 time + b2 * step_size, step_size * a21 * k1_, z2_);
152 formula_solver().solve();
153 k2_ = (z2_ - formula_solver().solution_offset()) / (step_size * ad);
154
155 z3_ = z2_;
156 formula_solver().init(
157 time + b3 * step_size, step_size * (a31 * k1_ + a32 * k2_), z3_);
158 formula_solver().solve();
159 k3_ = (z3_ - formula_solver().solution_offset()) / (step_size * ad);
160
161 z4_ = z3_;
162 formula_solver().init(time + b4 * step_size,
163 step_size * (a41 * k1_ + a42 * k2_ + a43 * k3_), z4_);
164 formula_solver().solve();
165 k4_ = (z4_ - formula_solver().solution_offset()) / (step_size * ad);
166
167 z5_ = z4_;
168 formula_solver().init(time + b5 * step_size,
169 step_size * (a51 * k1_ + a52 * k2_ + a53 * k3_ + a54 * k4_), z5_);
170 formula_solver().solve();
171 k5_ = (z5_ - formula_solver().solution_offset()) / (step_size * ad);
172
173 z6_ = z5_;
174 formula_solver().init(time + b6 * step_size,
175 step_size *
176 (a61 * k1_ + a62 * k2_ + a63 * k3_ + a64 * k4_ + a65 * k5_),
177 z6_);
178 formula_solver().solve();
179
180 estimate = current + z6_;
181 }
182
194 const variable_type& current, variable_type& estimate,
195 variable_type& error) {
196 step(time, step_size, current, estimate);
197 k6_ = (z6_ - formula_solver().solution_offset()) / (step_size * ad);
198
199 error = step_size *
200 (ce1 * k1_ + ce2 * k2_ + ce3 * k3_ + ce4 * k4_ + ce5 * k5_ +
201 ce6 * k6_);
202 }
203
204private:
222};
223
229template <concepts::problem Problem>
231
232} // 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.
auto problem() -> problem_type &
Get the problem.
static constexpr auto coeff(T val) -> scalar_type
Convert coefficients.
Class of ESDIRK45c formula in jorgensen2018.
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 formula_solver() -> formula_solver_type &
Get solver of formula.
static constexpr index_type order
Order 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.
static constexpr index_type lesser_order
Order of lesser coefficients of this formula.
typename problem_type::variable_type variable_type
Type of variables.
typename problem_type::scalar_type scalar_type
Type of scalars.
auto formula_solver() -> formula_solver_type &
Get solver of formula.
Definition of embedded_solver class.
Definition of evaluation_type enumeration.
Definition of implicit_formula_base class.
Definition of index_type type.
Definition of inexact_newton_update_equation_solver class.
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.
Definition of update_equation_solver concept.