numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
implicit_problem_wrapper.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 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 */
21#pragma once
22
23#include <type_traits>
24#include <utility> // IWYU pragma: keep
25
26#include <Eigen/LU>
27
33
34namespace num_collect::ode {
35
41template <concepts::single_variate_problem Problem>
42 requires concepts::mass_problem<Problem>
44public:
46 using variable_type = typename Problem::variable_type;
47
49 using scalar_type = typename Problem::scalar_type;
50
52 static constexpr auto allowed_evaluations =
53 num_collect::ode::evaluation_type{.diff_coeff = true};
54
61 : problem_(std::move(problem)) {}
62
69 void evaluate_on(const scalar_type& time, const variable_type& variable,
70 evaluation_type /*evaluations*/) {
71 problem_.evaluate_on(
72 time, variable, evaluation_type{.diff_coeff = true, .mass = true});
73 diff_coeff_ = problem_.diff_coeff() / problem_.mass();
74 }
75
81 [[nodiscard]] auto diff_coeff() const noexcept -> const variable_type& {
82 return diff_coeff_;
83 }
84
85private:
87 Problem problem_;
88
91};
92
99template <concepts::multi_variate_problem Problem,
100 base::concepts::eigen_solver_of<typename Problem::mass_type,
101 typename Problem::variable_type>
102 LinearEquationSolver = Eigen::PartialPivLU<typename Problem::mass_type>>
103 requires concepts::mass_problem<Problem>
105public:
107 using variable_type = typename Problem::variable_type;
108
110 using scalar_type = typename Problem::scalar_type;
111
113 static constexpr auto allowed_evaluations =
114 num_collect::ode::evaluation_type{.diff_coeff = true};
115
122 : problem_(std::move(problem)) {}
123
130 void evaluate_on(const scalar_type& time, const variable_type& variable,
131 evaluation_type /*evaluations*/) {
132 problem_.evaluate_on(
133 time, variable, evaluation_type{.diff_coeff = true, .mass = true});
134 solver_.compute(problem_.mass());
135 diff_coeff_ = solver_.solve(problem_.diff_coeff());
136 }
137
143 [[nodiscard]] auto diff_coeff() const noexcept -> const variable_type& {
144 return diff_coeff_;
145 }
146
147private:
149 Problem problem_;
150
153
155 LinearEquationSolver solver_{};
156};
157
165template <concepts::single_variate_problem Problem>
166 requires concepts::mass_problem<Problem>
167[[nodiscard]] auto wrap_implicit_problem(Problem&& problem)
170 std::forward<Problem>(problem));
171}
172
173#ifndef NUM_COLLECT_DOCUMENTATION
174// This function causes errors in Doxygen.
175
183template <concepts::multi_variate_problem Problem>
184 requires concepts::mass_problem<Problem>
185[[nodiscard]] auto wrap_implicit_problem(Problem&& problem)
186 -> multi_variate_implicit_problem_wrapper<std::decay_t<Problem>> {
187 return multi_variate_implicit_problem_wrapper<std::decay_t<Problem>>(
188 std::forward<Problem>(problem));
189}
190#endif
191
192} // namespace num_collect::ode
Class to wrap implicit problems to use as explicit problems.
void evaluate_on(const scalar_type &time, const variable_type &variable, evaluation_type)
Evaluate on a (time, variable) pair.
auto diff_coeff() const noexcept -> const variable_type &
Get the differential coefficient.
LinearEquationSolver solver_
Solver of linear equations.
typename Problem::scalar_type scalar_type
Type of scalars.
typename Problem::variable_type variable_type
Type of variables.
static constexpr auto allowed_evaluations
Allowed evaluations.
Class to wrap implicit problems to use as explicit problems.
auto diff_coeff() const noexcept -> const variable_type &
Get the differential coefficient.
typename Problem::variable_type variable_type
Type of variables.
static constexpr auto allowed_evaluations
Allowed evaluations.
typename Problem::scalar_type scalar_type
Type of scalars.
void evaluate_on(const scalar_type &time, const variable_type &variable, evaluation_type)
Evaluate on a (time, variable) pair.
Concept of Eigen's solvers of linear equations.
Definition of eigen_solver_of concept.
Definition of evaluation_type enumeration.
Definition of mass_problem concept.
Definition of multi_variate_problem concept.
Namespace of solvers of ordinary differential equations (ODE).
auto wrap_implicit_problem(Problem &&problem) -> single_variate_implicit_problem_wrapper< std::decay_t< Problem > >
Wrap an implicit problem to use as an explicit problem.
STL namespace.
Definition of single_variate_problem concept.
Struct to specify types of evaluations.