11 #ifndef OOPS_ASSIMILATION_IPCG_H_
12 #define OOPS_ASSIMILATION_IPCG_H_
17 #include "oops/util/dot_product.h"
18 #include "oops/util/formats.h"
19 #include "oops/util/Logger.h"
61 template <
typename VECTOR,
typename AMATRIX,
typename PMATRIX>
62 double IPCG(VECTOR & x,
const VECTOR & b,
63 const AMATRIX & A,
const PMATRIX & precond,
64 const int maxiter,
const double tolerance ) {
74 std::vector<VECTOR> vVEC;
75 std::vector<VECTOR> zVEC;
77 vVEC.reserve(maxiter+1);
78 zVEC.reserve(maxiter+1);
82 double xnrm2 = dot_product(x, x);
89 precond.multiply(r, s);
91 double dotRr0 = dot_product(r, r);
92 double dotSr0 = dot_product(r, s);
93 double normReduction = 1.0;
94 double rdots_old = dotSr0;
95 double rdots = dotSr0;
105 Log::info() << std::endl;
106 for (
int jiter = 0; jiter < maxiter; ++jiter) {
107 Log::info() <<
" IPCG Starting Iteration " << jiter+1 << std::endl;
114 double beta = dot_product(s, w)/rdots_old;
123 double alpha = rdots/dot_product(p, ap);
129 for (
int iiter = 0; iiter < jiter; ++iiter) {
130 double proj = dot_product(r, zVEC[iiter]);
131 r.axpy(-proj, vVEC[iiter]);
134 precond.multiply(r, s);
137 rdots = dot_product(r, s);
146 normReduction = sqrt(dot_product(r, r)/dotRr0);
147 Log::info() <<
"IPCG end of iteration " << jiter+1 <<
". Norm reduction= "
148 << util::full_precision(normReduction) << std::endl << std::endl;
150 if (normReduction < tolerance) {
151 Log::info() <<
"IPCG: Achieved required reduction in residual norm." << std::endl;
156 Log::info() <<
"IPCG: end" << std::endl;
158 return normReduction;
163 #endif // OOPS_ASSIMILATION_IPCG_H_