numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
ark43_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<ark43_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 = 6;
71
73 static constexpr index_type order = 4;
74
76 static constexpr index_type lesser_order = 3;
77
79 static constexpr auto log_tag = logging::log_tag_view(
80 "num_collect::ode::runge_kutta::ark43_esdirk_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(8611, 62500);
96 static constexpr scalar_type a32 = coeff(-1743, 31250);
97 static constexpr scalar_type a41 = coeff(5012029, 34652500);
98 static constexpr scalar_type a42 = coeff(-654441, 2922500);
99 static constexpr scalar_type a43 = coeff(174375, 388108);
100 static constexpr scalar_type a51 = coeff(15267082809, 155376265600);
101 static constexpr scalar_type a52 = coeff(-71443401, 120774400);
102 static constexpr scalar_type a53 = coeff(730878875, 902184768);
103 static constexpr scalar_type a54 = coeff(2285395, 8070912);
104 static constexpr scalar_type a61 = coeff(82889, 524892);
105 // a62 = 0
106 static constexpr scalar_type a63 = coeff(15625, 83664);
107 static constexpr scalar_type a64 = coeff(69875, 102672);
108 static constexpr scalar_type a65 = coeff(-2260, 8211);
109
110 // b1 = 0
111 static constexpr scalar_type b2 = coeff(1, 2);
112 static constexpr scalar_type b3 = coeff(83, 250);
113 static constexpr scalar_type b4 = coeff(31, 50);
114 static constexpr scalar_type b5 = coeff(17, 20);
115 static constexpr scalar_type b6 = coeff(1);
116
117 static constexpr scalar_type c1 = a61;
118 // c2 = 0
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(4586570599, 29645900160);
125 // cw2 = 0
126 static constexpr scalar_type cw3 = coeff(178811875, 945068544);
127 static constexpr scalar_type cw4 = coeff(814220225, 1159782912);
128 static constexpr scalar_type cw5 = coeff(-3700637, 11593932);
129 static constexpr scalar_type cw6 = coeff(61727, 225920);
130
131 static constexpr scalar_type ce1 = c1 - cw1;
132 // ce2 = 0
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 * (a61 * k1_ + a63 * k3_ + a64 * k4_ + a65 * k5_), z6_);
176 formula_solver().solve();
177
178 estimate = current + z6_;
179 }
180
192 const variable_type& current, variable_type& estimate,
193 variable_type& error) {
194 step(time, step_size, current, estimate);
195 k6_ = (z6_ - formula_solver().solution_offset()) / (step_size * ad);
196
197 error = step_size *
198 (ce1 * k1_ + ce3 * k3_ + ce4 * k4_ + ce5 * k5_ + ce6 * k6_);
199 }
200
201private:
219};
220
227template <concepts::problem Problem>
229
230} // 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 ARK4(3)6L[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.
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.
auto formula_solver() -> formula_solver_type &
Get solver of formula.
static constexpr index_type lesser_order
Order of lesser coefficients of this formula.
static constexpr index_type stages
Number of stages 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.