71 #ifndef GMM_KRYLOV_GMRES_H
72 #define GMM_KRYLOV_GMRES_H
88 template <
typename Mat,
typename Vec,
typename VecB,
typename Precond,
90 void gmres(
const Mat &A, Vec &x,
const VecB &b,
const Precond &M,
91 int restart,
iteration &outer, Basis& KS) {
93 typedef typename linalg_traits<Vec>::value_type T;
94 typedef typename number_traits<T>::magnitude_type R;
96 std::vector<T> w(vect_size(x)), r(vect_size(x)), u(vect_size(x));
97 std::vector<T> c_rot(restart+1), s_rot(restart+1), s(restart+1);
98 gmm::dense_matrix<T> H(restart+1, restart);
100 double t_ref, t_prec = MPI_Wtime(), t_tot = 0;
101 static double tmult_tot = 0.0;
103 cout <<
"GMRES " << endl;
107 if (outer.get_rhsnorm() == 0.0) {
clear(x);
return; }
109 mult(A, scaled(x, T(-1)), b, w);
115 inner.reduce_noisy();
116 inner.set_maxiter(restart);
117 inner.set_name(
"GMRes inner");
119 while (! outer.finished(beta)) {
121 gmm::copy(gmm::scaled(r, R(1)/beta), KS[0]);
125 size_type i = 0; inner.init();
130 orthogonalize(KS, mat_col(H, i), i);
133 gmm::scale(KS[i+1], T(1) / a);
134 for (size_type k = 0; k < i; ++k)
135 Apply_Givens_rotation_left(H(k,i), H(k+1,i), c_rot[k], s_rot[k]);
137 Givens_rotation(H(i,i), H(i+1,i), c_rot[i], s_rot[i]);
138 Apply_Givens_rotation_left(H(i,i), H(i+1,i), c_rot[i], s_rot[i]);
139 Apply_Givens_rotation_left(s[i], s[i+1], c_rot[i], s_rot[i]);
141 ++inner, ++outer, ++i;
142 }
while (! inner.finished(gmm::abs(s[i])));
144 upper_tri_solve(H, s, i,
false);
145 combine(KS, s, x, i);
146 mult(A, gmm::scaled(x, T(-1)), b, w);
149 if (
int(inner.get_iteration()) < restart -1 || beta_old <= beta)
150 ++blocked;
else blocked = 0;
152 if (outer.get_noisy()) cout <<
"Gmres is blocked, exiting\n";
156 t_tot = MPI_Wtime() - t_ref;
157 cout <<
"temps GMRES : " << t_tot << endl;
163 template <
typename Mat,
typename Vec,
typename VecB,
typename Precond >
164 void gmres(
const Mat &A, Vec &x,
const VecB &b,
165 const Precond &M,
int restart, iteration& outer) {
166 typedef typename linalg_traits<Vec>::value_type T;
167 modified_gram_schmidt<T> orth(restart, vect_size(x));
168 gmres(A, x, b, M, restart, outer, orth);