11 #ifndef OOPS_ASSIMILATION_PCG_H_
12 #define OOPS_ASSIMILATION_PCG_H_
18 #include "oops/util/dot_product.h"
19 #include "oops/util/formats.h"
20 #include "oops/util/Logger.h"
63 template <
typename VECTOR,
typename AMATRIX,
typename PMATRIX>
64 double PCG(VECTOR & x,
const VECTOR & b,
65 const AMATRIX & A,
const PMATRIX & precond,
66 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, s);
92 double normReduction = 1.0;
93 double rdots = dotRr0;
94 double rdots_old = 0.0;
104 Log::info() << std::endl;
105 for (
int jiter = 0; jiter < maxiter; ++jiter) {
106 Log::info() <<
" PCG Starting Iteration " << jiter+1 << std::endl;
111 double beta = dot_product(s, r)/rdots_old;
112 Log::info() <<
"PCG beta = " << beta << std::endl;
120 double alpha = rdots/dot_product(p, ap);
126 for (
int iiter = 0; iiter < jiter; ++iiter) {
127 double proj = dot_product(r, zVEC[iiter]);
128 r.axpy(-proj, vVEC[iiter]);
131 precond.multiply(r, s);
134 rdots = dot_product(r, s);
143 normReduction = sqrt(rdots/dotRr0);
145 Log::info() <<
"PCG end of iteration " << jiter+1 << std::endl;
148 if (normReduction < tolerance) {
149 Log::info() <<
"PCG: Achieved required reduction in residual norm." << std::endl;
154 Log::info() <<
"PCG: end" << std::endl;
156 return normReduction;
The namespace for the main oops code.
double PCG(VECTOR &x, const VECTOR &b, const AMATRIX &A, const PMATRIX &precond, const int maxiter, const double tolerance)
void printNormReduction(int iteration, const double &grad, const double &norm)