numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
lu_rosenbrock_equation_solver.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
22#include <optional>
23
24#include <Eigen/Core> // IWYU pragma: keep
25#include <Eigen/LU>
26
32
34
40template <concepts::multi_variate_differentiable_problem Problem>
42public:
44 using problem_type = Problem;
45
47 using variable_type = typename problem_type::variable_type;
48
50 using scalar_type = typename problem_type::scalar_type;
51
53 using jacobian_type = typename problem_type::jacobian_type;
54
56 using lu_solver_type = Eigen::PartialPivLU<jacobian_type>;
57
59 static constexpr bool use_time_derivative =
61
64
72 const scalar_type& inverted_jacobian_coeff)
73 : inverted_jacobian_coeff_(inverted_jacobian_coeff) {}
74
84 const scalar_type& time, const scalar_type& step_size,
85 const variable_type& variable) {
86 problem.evaluate_on(time, variable,
87 evaluation_type{.diff_coeff = true,
88 .jacobian = true,
89 .time_derivative = use_time_derivative,
90 .mass = use_mass});
91 jacobian_ = problem.jacobian();
92 if constexpr (use_time_derivative) {
93 time_derivative_ = problem.time_derivative();
94 }
95
96 const index_type variable_size = variable.size();
97 if constexpr (use_mass) {
98 lu_.compute(problem.mass() -
100 } else {
101 lu_.compute(jacobian_type::Identity(variable_size, variable_size) -
102 step_size * inverted_jacobian_coeff_ * jacobian_);
103 }
104
105 // TODO: Check that condition number is not so large.
106 }
107
114 void apply_jacobian(const variable_type& target, variable_type& result) {
115 result = jacobian_ * target;
116 }
117
126 const scalar_type& coeff, variable_type& target) {
127 if constexpr (use_time_derivative) {
128 if (time_derivative_) {
129 target += step_size * coeff * (*time_derivative_);
130 }
131 }
132 }
133
140 void solve(const variable_type& rhs, variable_type& result) {
141 result = lu_.solve(rhs);
142 }
143
144private:
147
149 std::optional<variable_type> time_derivative_{};
150
153
156};
157
158} // namespace num_collect::ode::rosenbrock
Class to solve equations in Rosenbrock methods using LU decomposition.
typename problem_type::scalar_type scalar_type
Type of scalars.
void evaluate_and_update_jacobian(problem_type &problem, const scalar_type &time, const scalar_type &step_size, const variable_type &variable)
Update Jacobian matrix and internal parameters.
lu_rosenbrock_equation_solver(const scalar_type &inverted_jacobian_coeff)
Constructor.
scalar_type inverted_jacobian_coeff_
Coefficient multiplied to Jacobian matrices in inverted matrices.
typename problem_type::jacobian_type jacobian_type
Type of Jacobians.
static constexpr bool use_time_derivative
Whether to use partial derivative with respect to time.
void add_time_derivative_term(const scalar_type &step_size, const scalar_type &coeff, variable_type &target)
Add a term of partial derivative with respect to time.
Eigen::PartialPivLU< jacobian_type > lu_solver_type
Type of the LU solver.
std::optional< variable_type > time_derivative_
Partial derivative with respect to time.
void apply_jacobian(const variable_type &target, variable_type &result)
Multiply Jacobian matrix to a vector.
typename problem_type::variable_type variable_type
Type of variables.
void solve(const variable_type &rhs, variable_type &result)
Solve a linear equation.
Concept of problems of ordinary differential equations with mass.
Concept of problems of ordinary differential equations differentiable by time variable.
Definition of evaluation_type enumeration.
Definition of index_type type.
Definition of mass_problem concept.
Definition of multi_variate_differentiable_problem concept.
std::ptrdiff_t index_type
Type of indices in this library.
Definition index_type.h:33
Struct to specify types of evaluations.
Definition of time_differentiable_problem concept.