11 #ifndef OOPS_ASSIMILATION_GMRESR_H_ 12 #define OOPS_ASSIMILATION_GMRESR_H_ 17 #include "oops/util/dot_product.h" 18 #include "oops/util/formats.h" 19 #include "oops/util/Logger.h" 62 template <
typename VECTOR,
typename AMATRIX,
typename PMATRIX>
64 const AMATRIX & A,
const PMATRIX & precond,
65 const int maxiter,
const double tolerance) {
66 const double stagthresh = 1.0e-3;
67 const double smallres = 1.0e-6;
69 std::vector<VECTOR> cvecs;
70 std::vector<VECTOR> zvecs;
78 double normReduction = 1.0;
79 double rrnorm = sqrt(dot_product(rr, rr));
80 double cdotr = rrnorm;
81 const double rrnorm0 = rrnorm;
83 if (rrnorm > smallres) {
85 for (
int jiter = 0; jiter < maxiter; ++jiter) {
86 Log::info() <<
" GMRESR Starting Iteration " << jiter+1 << std::endl;
89 if (std::abs(cdotr) < stagthresh*rrnorm) {
90 Log::info() <<
"GMRESR stagnated. Doing an LSQR step." << std::endl;
93 precond.multiply(rr, zz);
98 for (
int jj = 0; jj < jiter; ++jj) {
99 double alpha = -dot_product(cvecs[jj],
cc);
101 zz.axpy(
alpha, zvecs[jj]);
104 double ccnorm = sqrt(dot_product(
cc,
cc));
106 cvecs[jiter] *= 1.0/ccnorm;
108 zvecs[jiter] *= 1.0/ccnorm;
110 cdotr = dot_product(cvecs[jiter], rr);
111 rr.axpy(-cdotr, cvecs[jiter]);
112 xx.axpy(cdotr, zvecs[jiter]);
114 rrnorm = sqrt(dot_product(rr, rr));
115 normReduction = rrnorm/rrnorm0;
116 Log::info() <<
"GMRESR end of iteration " << jiter+1 <<
". Norm reduction= " 117 << util::full_precision(normReduction) << std::endl << std::endl;
120 Log::info() <<
"GMRESR: Achieved required reduction in residual norm." << std::endl;
126 return normReduction;
131 #endif // OOPS_ASSIMILATION_GMRESR_H_ double GMRESR(VECTOR &xx, const VECTOR &bb, const AMATRIX &A, const PMATRIX &precond, const int maxiter, const double tolerance)
real, dimension(:,:), allocatable, private bb
The namespace for the main oops code.
subroutine, public info(self)
real(fp), parameter, public tolerance