numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
ark54_esdirk_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<ark54_esdirk_formula<Problem, FormulaSolver>,
44 Problem, FormulaSolver> {
45public:
48
50 using base_type =
52 Problem, 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 = 8;
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::ark54_esdirk_formula");
81
93 static constexpr scalar_type ad = coeff(41, 200); // diagonal coefficient
94 static constexpr scalar_type a21 = ad;
95 static constexpr scalar_type a31 = coeff(41, 400);
96 static constexpr scalar_type a32 = coeff(-567603406766, 11931857230679);
97 static constexpr scalar_type a41 = coeff(683785636431, 9252920307686);
98 // a42 = 0
99 static constexpr scalar_type a43 = coeff(-110385047103, 1367015193373);
100 static constexpr scalar_type a51 = coeff(3016520224154, 10081342136671);
101 // a52 = 0
102 static constexpr scalar_type a53 = coeff(30586259806659, 12414158314087);
103 static constexpr scalar_type a54 = coeff(-22760509404356, 11113319521817);
104 static constexpr scalar_type a61 = coeff(218866479029, 1489978393911);
105 // a62 = 0
106 static constexpr scalar_type a63 = coeff(638256894668, 5436446318841);
107 static constexpr scalar_type a64 = coeff(-1179710474555, 5321154724896);
108 static constexpr scalar_type a65 = coeff(-60928119172, 8023461067671);
109 static constexpr scalar_type a71 = coeff(1020004230633, 5715676835656);
110 // a72 = 0
111 static constexpr scalar_type a73 = coeff(25762820946817, 25263940353407);
112 static constexpr scalar_type a74 = coeff(-2161375909145, 9755907335909);
113 static constexpr scalar_type a75 = coeff(-211217309593, 5846859502534);
114 static constexpr scalar_type a76 = coeff(-4269925059573, 7827059040749);
115 static constexpr scalar_type a81 = coeff(-872700587467, 9133579230613);
116 // a82 = 0
117 // a83 = 0
118 static constexpr scalar_type a84 = coeff(22348218063261, 9555858737531);
119 static constexpr scalar_type a85 = coeff(-1143369518992, 8141816002931);
120 static constexpr scalar_type a86 = coeff(-39379526789629, 19018526304540);
121 static constexpr scalar_type a87 = coeff(32727382324388, 42900044865799);
122
123 // b1 = 0
124 static constexpr scalar_type b2 = coeff(41, 100);
125 static constexpr scalar_type b3 = coeff(2935347310677, 11292855782101);
126 static constexpr scalar_type b4 = coeff(1426016391358, 7196633302097);
127 static constexpr scalar_type b5 = coeff(92, 100);
128 static constexpr scalar_type b6 = coeff(24, 100);
129 static constexpr scalar_type b7 = coeff(3, 5);
130 static constexpr scalar_type b8 = coeff(1);
131
132 static constexpr scalar_type c1 = a81;
133 // c2 = 0
134 // c3 = 0
135 static constexpr scalar_type c4 = a84;
136 static constexpr scalar_type c5 = a85;
137 static constexpr scalar_type c6 = a86;
138 static constexpr scalar_type c7 = a87;
139 static constexpr scalar_type c8 = ad;
140
141 static constexpr scalar_type cw1 = coeff(-975461918565, 9796059967033);
142 // cw2 = 0
143 // cw3 = 0
144 static constexpr scalar_type cw4 = coeff(78070527104295, 32432590147079);
145 static constexpr scalar_type cw5 = coeff(-548382580838, 3424219808633);
146 static constexpr scalar_type cw6 = coeff(-33438840321285, 15594753105479);
147 static constexpr scalar_type cw7 = coeff(3629800801594, 4656183773603);
148 static constexpr scalar_type cw8 = coeff(4035322873751, 18575991585200);
149
150 static constexpr scalar_type ce1 = c1 - cw1;
151 // ce2 = 0
152 // ce3 = 0
153 static constexpr scalar_type ce4 = c4 - cw4;
154 static constexpr scalar_type ce5 = c5 - cw5;
155 static constexpr scalar_type ce6 = c6 - cw6;
156 static constexpr scalar_type ce7 = c7 - cw7;
157 static constexpr scalar_type ce8 = c8 - cw8;
159
161 void step(scalar_type time, scalar_type step_size,
162 const variable_type& current, variable_type& estimate) {
163 formula_solver().update_jacobian(
164 problem(), time, step_size, current, ad);
165
166 problem().evaluate_on(
167 time, current, evaluation_type{.diff_coeff = true});
168 k1_ = problem().diff_coeff();
169
170 z2_ = step_size * ad * k1_;
171 formula_solver().init(
172 time + b2 * step_size, step_size * a21 * k1_, z2_);
173 formula_solver().solve();
174 k2_ = (z2_ - formula_solver().solution_offset()) / (step_size * ad);
175
176 z3_ = z2_;
177 formula_solver().init(
178 time + b3 * step_size, step_size * (a31 * k1_ + a32 * k2_), z3_);
179 formula_solver().solve();
180 k3_ = (z3_ - formula_solver().solution_offset()) / (step_size * ad);
181
182 z4_ = z3_;
183 formula_solver().init(
184 time + b4 * step_size, step_size * (a41 * k1_ + a43 * k3_), z4_);
185 formula_solver().solve();
186 k4_ = (z4_ - formula_solver().solution_offset()) / (step_size * ad);
187
188 z5_ = z4_;
189 formula_solver().init(time + b5 * step_size,
190 step_size * (a51 * k1_ + a53 * k3_ + a54 * k4_), z5_);
191 formula_solver().solve();
192 k5_ = (z5_ - formula_solver().solution_offset()) / (step_size * ad);
193
194 z6_ = z5_;
195 formula_solver().init(time + b6 * step_size,
196 step_size * (a61 * k1_ + a63 * k3_ + a64 * k4_ + a65 * k5_), z6_);
197 formula_solver().solve();
198 k6_ = (z6_ - formula_solver().solution_offset()) / (step_size * ad);
199
200 z7_ = z6_;
201 formula_solver().init(time + b7 * step_size,
202 step_size *
203 (a71 * k1_ + a73 * k3_ + a74 * k4_ + a75 * k5_ + a76 * k6_),
204 z7_);
205 formula_solver().solve();
206 k7_ = (z7_ - formula_solver().solution_offset()) / (step_size * ad);
207
208 z8_ = z7_;
209 formula_solver().init(time + b8 * step_size,
210 step_size *
211 (a81 * k1_ + a84 * k4_ + a85 * k5_ + a86 * k6_ + a87 * k7_),
212 z8_);
213 formula_solver().solve();
214
215 estimate = current + z8_;
216 }
217
229 const variable_type& current, variable_type& estimate,
230 variable_type& error) {
231 step(time, step_size, current, estimate);
232 k8_ = (z8_ - formula_solver().solution_offset()) / (step_size * ad);
233
234 error = step_size *
235 (ce1 * k1_ + ce4 * k4_ + ce5 * k5_ + ce6 * k6_ + ce7 * k7_ +
236 ce8 * k8_);
237 }
238
239private:
261};
262
269template <concepts::problem Problem>
271
272} // 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 ARK5(4)8L[2]SA-ESDIRK formula in kennedy2003 .
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.
auto formula_solver() -> formula_solver_type &
Get solver of formula.
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.
static constexpr index_type order
Order 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.