11 #ifndef OOPS_ASSIMILATION_RPCGMINIMIZER_H_
12 #define OOPS_ASSIMILATION_RPCGMINIMIZER_H_
23 #include "oops/util/dot_product.h"
24 #include "oops/util/formats.h"
25 #include "oops/util/Logger.h"
74 const std::string
classname()
const override {
return "RPCGMinimizer";}
80 const int &,
const double &,
Dual_ &,
const double &)
override;
85 template<
typename MODEL,
typename OBS>
88 const int & maxiter,
const double & tolerance,
89 Dual_ & dy,
const double & sigma) {
113 std::vector<Dual_> vVEC;
114 std::vector<Dual_> wVEC;
116 vVEC.reserve(maxiter+1);
117 wVEC.reserve(maxiter+1);
119 std::vector<double> vpVEC;
120 std::vector<double> wpVEC;
125 llp = dot_product(dy, rr) + sigma*rrp;
135 double dotwr = dot_product(rr, ww) + rrp*wwp;
136 double normReduction = 1.0;
137 double dotw0r0 = dotwr;
138 double dotwr_old = 0.0;
159 Log::info() << std::endl;
160 for (
int jiter = 0; jiter < maxiter; ++jiter) {
161 Log::info() <<
"RPCG Starting Iteration " << jiter+1 << std::endl;
164 double beta = dotwr/dotwr_old;
165 Log::info() <<
"RPCG beta = " << beta << std::endl;
185 double alpha = dotwr/(dot_product(qq, tt) + qqp * ttp);
186 Log::info() <<
"RPCG alpha = " << alpha << std::endl;
189 vvp = vvp + alpha*ppp;
192 rrp = rrp - alpha*qqp;
195 for (
int iiter = 0; iiter < jiter; ++iiter) {
196 double proj = dot_product(rr, wVEC[iiter]) + rrp * wpVEC[iiter];
197 rr.
axpy(-proj, vVEC[iiter]);
198 rrp -= proj*vpVEC[iiter];
204 llp = dot_product(dy, rr) + sigma * rrp;
215 dotwr = dot_product(ww, rr) + rrp * wwp;
231 normReduction = sqrt(dotwr/dotw0r0);
233 Log::info() <<
"RPCG end of iteration " << jiter+1 <<
". Norm reduction= "
234 << util::full_precision(normReduction) << std::endl << std::endl;
236 if (normReduction < tolerance) {
237 Log::info() <<
"RPCG: Achieved required reduction in residual norm." << std::endl;
241 return normReduction;
248 #endif // OOPS_ASSIMILATION_RPCGMINIMIZER_H_