numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
avf3_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
26#include "num_collect/constants/one.h" // IWYU pragma: keep
27#include "num_collect/constants/zero.h" // IWYU pragma: keep
36
37namespace num_collect::ode::avf {
38
45template <concepts::differentiable_problem Problem>
47public:
49 using problem_type = Problem;
50
52 using variable_type = typename problem_type::variable_type;
53
55 using scalar_type = typename problem_type::scalar_type;
56
58 using jacobian_type = typename problem_type::jacobian_type;
59
61 static constexpr index_type stages = 1;
62
64 static constexpr index_type order = 3;
65
67 static constexpr auto log_tag =
68 logging::log_tag_view("num_collect::ode::avf::avf3_formula");
69
77
86 void step(scalar_type time, scalar_type step_size,
87 const variable_type& current, variable_type& estimate) {
88 const auto dim = current.size();
89
90 problem().evaluate_on(time, current,
91 evaluation_type{.diff_coeff = true, .jacobian = true});
92 static constexpr scalar_type coeff_jacobi =
93 -static_cast<scalar_type>(1) / static_cast<scalar_type>(12);
94 const jacobian_type coeff = step_size *
95 (jacobian_type::Identity(dim, dim) +
96 coeff_jacobi * step_size * step_size * problem().jacobian() *
97 problem().jacobian());
98
99 estimate = current + coeff * problem().diff_coeff();
100
101 integrand_.time(time);
102 integrand_.prev_var(current);
103 variable_type prev_estimate;
104 constexpr index_type max_loops = 10000;
105 for (index_type i = 0; i < max_loops; ++i) {
106 integrand_.next_var(estimate);
107 prev_estimate = estimate;
108 estimate = current +
109 coeff *
112 if (norm(estimate - prev_estimate) < tol_residual_norm_) {
113 return;
114 }
115 }
116 }
117
123 [[nodiscard]] auto problem() -> problem_type& {
124 return integrand_.problem();
125 }
126
132 [[nodiscard]] auto problem() const -> const problem_type& {
133 return integrand_.problem();
134 }
135
142 NUM_COLLECT_PRECONDITION(val > static_cast<scalar_type>(0),
143 "Tolerance of residual norm must be a positive value.");
144 tol_residual_norm_ = val;
145 }
146
147private:
150
152 static constexpr index_type integrator_degree = 5;
153
157
159 static constexpr auto default_tol_residual_norm =
160 static_cast<scalar_type>(1e-8);
161
164};
165
172template <concepts::differentiable_problem Problem>
174
181template <concepts::differentiable_problem Problem>
183
184} // namespace num_collect::ode::avf
Definition of avf_integrand class.
Class to perform numerical integration with Gauss-Legendre formula.
Class of tags of logs without memory management.
Class of 3rd order average vector field (AVF) method quispel2008.
static constexpr index_type integrator_degree
Degree of integrator.
auto problem() -> problem_type &
Get the problem.
typename problem_type::scalar_type scalar_type
Type of scalars.
static constexpr index_type stages
Number of stages of this formula.
impl::avf_integrand< problem_type > integrand_
Integrand.
Problem problem_type
Type of problem.
typename problem_type::jacobian_type jacobian_type
Type of Jacobian.
scalar_type tol_residual_norm_
Tolerance of residual norm.
integration::gauss_legendre_integrator< variable_type(scalar_type)> integrator_
Integrator.
avf3_formula(const problem_type &problem=problem_type())
Constructor.
static constexpr index_type order
Order of this formula.
typename problem_type::variable_type variable_type
Type of variables.
auto problem() const -> const problem_type &
Get the problem.
static constexpr auto log_tag
Log tag.
void tol_residual_norm(scalar_type val)
Set tolerance of residual norm.
static constexpr auto default_tol_residual_norm
Default tolerance of residual norm.
void step(scalar_type time, scalar_type step_size, const variable_type &current, variable_type &estimate)
Compute the next variable.
Class of integrand for average vector field (AVF) method quispel2008.
void time(scalar_type val)
Set time.
void prev_var(const variable_type &var)
Set the previous variable.
void next_var(const variable_type &var)
Set the next variable.
auto problem() -> problem_type &
Get the problem.
Class of solvers of ODEs using embedded formulas.
Class of simple solver of ODEs.
Definition of differentiable_problem concept.
Definition of evaluation_type enumeration.
Definition of exceptions.
Definition of legendre_roots function.
Definition of index_type type.
Definition of log_tag_view class.
Definition of macros for logging.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
auto norm(const Matrix &matrix)
Calculate norm of a matrix.
Definition norm.h:39
constexpr T zero
Value 0.
Definition zero.h:30
constexpr T one
Value 1.
Definition one.h:30
Namespace of average vector field (AVF) method.
Definition of non_embedded_formula_wrapper class.
Definition of norm class.
Definition of one.
Definition of NUM_COLLECT_PRECONDITION macro.
#define NUM_COLLECT_PRECONDITION(CONDITION,...)
Check whether a precondition is satisfied and throw an exception if not.
Definition of simple_solver class.
Struct to specify types of evaluations.
Definition of zero.