6 #include <Eigen/Sparse> 15 template <
class T,
class Preconditioner = Eigen::DiagonalPreconditioner<
double>>
16 int Gmres(
const T&
A,
const Eigen::VectorXd&
rhs, Eigen::VectorXd& x,
const int maxNumRestarts,
const double tolerance,
17 const int krylovDimension)
20 using MatrixType = Eigen::MatrixXd;
21 using VectorType = Eigen::VectorXd;
23 const int n = A.rows();
26 MatrixType H = MatrixType::Zero(krylovDimension + 1, krylovDimension);
29 MatrixType V = MatrixType::Zero(n, krylovDimension + 1);
32 std::vector<Eigen::JacobiRotation<double>> Givens(krylovDimension + 1);
34 VectorType e1 = VectorType::Zero(n);
38 Preconditioner precond(A);
41 VectorType r = precond.solve(rhs - A * x);
42 double rNorm = r.norm();
43 double rhsNorm = rhs.norm();
51 while (rNorm > tolerance * rhsNorm and numRestarts < maxNumRestarts)
58 VectorType
s = rNorm * e1;
61 for (
int i = 0; i < krylovDimension; ++i)
63 VectorType w = precond.solve(A * V.col(i));
65 for (
int iRow = 0; iRow < i + 1; ++iRow)
67 H(iRow, i) = w.transpose() * V.col(iRow);
68 w = w - H(iRow, i) * V.col(iRow);
71 H(i + 1, i) = w.norm();
72 V.col(i + 1) = w / H(i + 1, i);
76 for (
int iRow = 0; iRow < i; ++iRow)
78 H.col(i).applyOnTheLeft(iRow, iRow + 1, Givens[iRow].adjoint());
82 Givens[i].makeGivens(H(i, i), H(i + 1, i));
86 H.col(i).applyOnTheLeft(i, i + 1, Givens[i].adjoint());
89 s.applyOnTheLeft(i, i + 1, Givens[i].adjoint());
93 if (rNorm < tolerance * rhsNorm)
95 VectorType y = s.head(i + 1);
96 H.topLeftCorner(i + 1, i + 1).triangularView<Eigen::Upper>().solveInPlace(y);
97 x = x + V.block(0, 0, n, i + 1) * y;
104 VectorType y = s.head(krylovDimension);
105 H.topLeftCorner(krylovDimension, krylovDimension).triangularView<Eigen::Upper>().solveInPlace(y);
106 x = x + V.block(0, 0, n, krylovDimension) * y;
109 r = precond.solve(rhs - A * x);
constexpr double tolerance
Definition: NewtonRaphsonBenchmark.cpp:11
s
Definition: WaveFieldSynthesis.py:99
Definition: Exception.h:6
rhs
Definition: SparseDirectSolverMKLDSS.py:46
int Gmres(const T &A, const Eigen::VectorXd &rhs, Eigen::VectorXd &x, const int maxNumRestarts, const double tolerance, const int krylovDimension)
Generalized minimal residual method.
Definition: Gmres.h:16
const Eigen::MatrixBase< OtherDerived > abs() const
elementwise absolute value of the matrix
Definition: MatrixBaseAddons.h:17
int A
Definition: TimeIntegrationResultForce.py:7