1#ifndef CGMRES__MATRIXFREE_GMRES_HPP_
2#define CGMRES__MATRIXFREE_GMRES_HPP_
17template <
typename LinearProblem,
int _kmax>
20 static constexpr int dim = LinearProblem::dim;
21 static constexpr int kmax = std::min(
dim, _kmax);
30 static_assert(
dim > 0);
31 static_assert(
kmax > 0);
37 template <
typename... LinearProblemArgs>
38 int solve(LinearProblem& linear_problem,
39 LinearProblemArgs... linear_problem_args,
42 givens_c_vec_.setZero();
43 givens_s_vec_.setZero();
46 linear_problem.eval_b(linear_problem_args..., linear_problem_solution, b_vec_);
47 g_vec_.coeffRef(0) = b_vec_.template lpNorm<2>();
48 basis_mat_.col(0) = b_vec_ / g_vec_.coeff(0);
52 linear_problem.eval_Ax(linear_problem_args..., basis_mat_.col(k),
54 for (
int j=0; j<=k; ++j) {
55 hessenberg_mat_.coeffRef(k, j) = basis_mat_.col(k+1).dot(basis_mat_.col(j));
56 basis_mat_.col(k+1).noalias() -= hessenberg_mat_.coeff(k, j) * basis_mat_.col(j);
58 hessenberg_mat_.coeffRef(k, k+1) = basis_mat_.col(k+1).template lpNorm<2>();
59 if (std::abs(hessenberg_mat_.coeff(k, k+1)) < std::numeric_limits<double>::epsilon()) {
63 basis_mat_.col(k+1).array() /= hessenberg_mat_.coeff(k, k+1);
66 for (
int j=0; j<k; ++j) {
67 givensRotation(hessenberg_mat_.row(k), j);
69 const Scalar nu = std::sqrt(hessenberg_mat_.coeff(k, k)*hessenberg_mat_.coeff(k, k)
70 +hessenberg_mat_.coeff(k, k+1)*hessenberg_mat_.coeff(k, k+1));
72 givens_c_vec_.coeffRef(k) = hessenberg_mat_.coeff(k, k) / nu;
73 givens_s_vec_.coeffRef(k) = - hessenberg_mat_.coeff(k, k+1) / nu;
74 hessenberg_mat_.coeffRef(k, k) = givens_c_vec_.coeff(k) * hessenberg_mat_.coeff(k, k)
75 - givens_s_vec_.coeff(k) * hessenberg_mat_.coeff(k, k+1);
76 hessenberg_mat_.coeffRef(k, k+1) = 0.0;
77 givensRotation(g_vec_, k);
80 throw std::runtime_error(
"Lose orthogonality of the basis of the Krylov subspace");
84 for (
int i=k-1; i>=0; --i) {
85 Scalar tmp = g_vec_.coeff(i);
86 for (
int j=i+1; j<k; ++j) {
87 tmp -= hessenberg_mat_.coeff(j, i) * givens_c_vec_.coeff(j);
89 givens_c_vec_.coeffRef(i) = tmp / hessenberg_mat_.coeff(i, i);
91 for (
int i=0; i<
dim; ++i) {
93 for (
int j=0; j<k; ++j) {
94 tmp += basis_mat_.coeff(i, j) * givens_c_vec_.coeff(j);
96 linear_problem_solution.coeffRef(i) += tmp;
101 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
109 template <
typename VectorType>
111 const int i_column)
const {
112 const Scalar tmp1 = givens_c_vec_.coeff(i_column) * column_vec.coeff(i_column)
113 - givens_s_vec_.coeff(i_column) * column_vec.coeff(i_column+1);
114 const Scalar tmp2 = givens_s_vec_.coeff(i_column) * column_vec.coeff(i_column)
115 + givens_c_vec_.coeff(i_column) * column_vec.coeff(i_column+1);
Definition: matrixfree_gmres.hpp:18
static constexpr int kmax
Definition: matrixfree_gmres.hpp:21
MatrixFreeGMRES()
Definition: matrixfree_gmres.hpp:23
int solve(LinearProblem &linear_problem, LinearProblemArgs... linear_problem_args, Vector< dim > &linear_problem_solution)
Definition: matrixfree_gmres.hpp:38
static constexpr int dim
Definition: matrixfree_gmres.hpp:20
~MatrixFreeGMRES()=default
#define CGMRES_EIGEN_CONST_CAST(TYPE, OBJ)
Definition: macros.hpp:7
Definition: continuation_gmres.hpp:11
Eigen::Matrix< Scalar, rows, cols > Matrix
Alias of Eigen::Matrix.
Definition: types.hpp:17
Eigen::Matrix< Scalar, size, 1 > Vector
Alias of Eigen::Vector.
Definition: types.hpp:23
double Scalar
Alias of double.
Definition: types.hpp:11
Eigen::MatrixBase< MatrixType > MatrixBase
Alias of Eigen::MatrixBase.
Definition: types.hpp:29