numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
sdirk4_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
40template <concepts::problem Problem,
41 concepts::update_equation_solver FormulaSolver =
42 inexact_newton_update_equation_solver<Problem>>
44 : public implicit_formula_base<sdirk4_formula<Problem, FormulaSolver>,
45 Problem, FormulaSolver> {
46public:
49
51 using base_type =
53 FormulaSolver>;
54
55 using typename base_type::problem_type;
56 using typename base_type::scalar_type;
57 using typename base_type::variable_type;
58
59 static_assert(!problem_type::allowed_evaluations.mass,
60 "Mass matrix is not supported.");
61
64
65protected:
66 using base_type::coeff;
68
69public:
71 static constexpr index_type stages = 5;
72
74 static constexpr index_type order = 4;
75
77 static constexpr index_type lesser_order = 3;
78
80 static constexpr auto log_tag =
81 logging::log_tag_view("num_collect::ode::runge_kutta::sdirk4_formula");
82
94 static constexpr scalar_type ad = coeff(1, 4); // diagonal coefficient
95 static constexpr scalar_type a21 = coeff(1, 2);
96 static constexpr scalar_type a31 = coeff(17, 50);
97 static constexpr scalar_type a32 = coeff(-1, 25);
98 static constexpr scalar_type a41 = coeff(371, 1360);
99 static constexpr scalar_type a42 = coeff(-137, 2720);
100 static constexpr scalar_type a43 = coeff(15, 544);
101 static constexpr scalar_type a51 = coeff(25, 24);
102 static constexpr scalar_type a52 = coeff(-49, 48);
103 static constexpr scalar_type a53 = coeff(125, 16);
104 static constexpr scalar_type a54 = coeff(-85, 12);
105
106 static constexpr scalar_type b1 = coeff(1, 4);
107 static constexpr scalar_type b2 = coeff(3, 4);
108 static constexpr scalar_type b3 = coeff(11, 20);
109 static constexpr scalar_type b4 = coeff(1, 2);
110 static constexpr scalar_type b5 = coeff(1);
111
112 static constexpr scalar_type c1 = a51;
113 static constexpr scalar_type c2 = a52;
114 static constexpr scalar_type c3 = a53;
115 static constexpr scalar_type c4 = a54;
116 static constexpr scalar_type c5 = ad;
117
118 static constexpr scalar_type cw1 = coeff(59, 48);
119 static constexpr scalar_type cw2 = coeff(-17, 96);
120 static constexpr scalar_type cw3 = coeff(225, 32);
121 static constexpr scalar_type cw4 = coeff(-85, 12);
122 static constexpr scalar_type cw5 = coeff(0);
123
124 static constexpr scalar_type ce1 = c1 - cw1;
125 static constexpr scalar_type ce2 = c2 - cw2;
126 static constexpr scalar_type ce3 = c3 - cw3;
127 // ce4 = 0
128 static constexpr scalar_type ce5 = c5 - cw5;
130
132 void step(scalar_type time, scalar_type step_size,
133 const variable_type& current, variable_type& estimate) {
134 formula_solver().update_jacobian(
135 problem(), time, step_size, current, ad);
136
137 z1_ = step_size * ad * problem().diff_coeff();
139 formula_solver().init(time + b1 * step_size,
140 variable_type::Zero(current.size()), z1_);
141 } else {
142 formula_solver().init(
143 time + b1 * step_size, static_cast<variable_type>(0), z1_);
144 }
145 formula_solver().solve();
146 k1_ = z1_ / (step_size * ad);
147
148 z2_ = z1_;
149 formula_solver().init(
150 time + b2 * step_size, step_size * a21 * k1_, z2_);
151 formula_solver().solve();
152 k2_ = (z2_ - formula_solver().solution_offset()) / (step_size * ad);
153
154 z3_ = z2_;
155 formula_solver().init(
156 time + b3 * step_size, step_size * (a31 * k1_ + a32 * k2_), z3_);
157 formula_solver().solve();
158 k3_ = (z3_ - formula_solver().solution_offset()) / (step_size * ad);
159
160 z4_ = z3_;
161 formula_solver().init(time + b4 * step_size,
162 step_size * (a41 * k1_ + a42 * k2_ + a43 * k3_), z4_);
163 formula_solver().solve();
164 k4_ = (z4_ - formula_solver().solution_offset()) / (step_size * ad);
165
166 z5_ = z4_;
167 formula_solver().init(time + b5 * step_size,
168 step_size * (a51 * k1_ + a52 * k2_ + a53 * k3_ + a54 * k4_), z5_);
169 formula_solver().solve();
170
171 estimate = current + z5_;
172 }
173
185 const variable_type& current, variable_type& estimate,
186 variable_type& error) {
187 step(time, step_size, current, estimate);
188 k5_ = (z5_ - formula_solver().solution_offset()) / (step_size * ad);
189
190 error = step_size * (ce1 * k1_ + ce2 * k2_ + ce3 * k3_ + ce5 * k5_);
191 }
192
193private:
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.
Base class of formulas in ODE solvers.
auto problem() -> problem_type &
Get the problem.
static constexpr auto coeff(T val) -> scalar_type
Convert coefficients.
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.
Class of 4th order SDIRK (singly diagonally implicit Runge-Kutta) formula in hairer1991.
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.
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.
auto formula_solver() -> formula_solver_type &
Get solver of formula.
static constexpr index_type lesser_order
Order of lesser coefficients 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 stages
Number of stages of this formula.
Concept of Eigen's dense vectors with real scalars.
Definition of embedded_solver class.
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.
Definition of real_scalar_dense_vector concept.
Definition of update_equation_solver concept.