11 #ifndef OOPS_ASSIMILATION_DRPCGMINIMIZER_H_
12 #define OOPS_ASSIMILATION_DRPCGMINIMIZER_H_
18 #include "eckit/config/Configuration.h"
25 #include "oops/util/dot_product.h"
26 #include "oops/util/formats.h"
27 #include "oops/util/Logger.h"
85 const std::string
classname()
const override {
return "DRPCGMinimizer";}
91 const double,
const double,
const int,
const double)
override;
98 template<
typename MODEL,
typename OBS>
105 template<
typename MODEL,
typename OBS>
108 const double costJ0Jb,
const double costJ0JoJc,
109 const int maxiter,
const double tolerance) {
123 std::vector<CtrlInc_> vvecs;
124 std::vector<CtrlInc_> zvecs;
125 std::vector<double> scals;
127 vvecs.reserve(maxiter+1);
128 zvecs.reserve(maxiter+1);
129 scals.reserve(maxiter+1);
132 const double costJ0 = costJ0Jb + costJ0JoJc;
138 Log::info() <<
"normr0 " << dot_product(rr, rr) << std::endl;
141 lmp_.multiply(rr, pr);
149 double dotRr0 = dot_product(rr, zz);
150 double normReduction = 1.0;
151 double rdots = dotRr0;
152 double rdots_old = 0.0;
156 scals.push_back(1.0/dotRr0);
158 Log::info() << std::endl;
159 for (
int jiter = 0; jiter < maxiter; ++jiter) {
160 Log::info() <<
" DRPCG Starting Iteration " << jiter+1 << std::endl;
164 double beta = rdots/rdots_old;
180 double rho = dot_product(pp, qq);
181 double alpha = rdots/rho;
192 double costJ = costJ0 - 0.5 * dot_product(dx, r0);
194 double costJb = costJ0Jb + 0.5 * dot_product(dx, dxh);
196 double costJoJc = costJ - costJb;
199 for (
int jj = 0; jj < jiter; ++jj) {
200 double proj = scals[jj] * dot_product(rr, zvecs[jj]);
201 rr.
axpy(-proj, vvecs[jj]);
205 lmp_.multiply(rr, pr);
211 rdots = dot_product(rr, zz);
213 Log::info() <<
"rdots " << rdots <<
" iteration " << jiter << std::endl;
216 normReduction = sqrt(rdots/dotRr0);
218 Log::info() <<
"DRPCG end of iteration " << jiter+1 << std::endl
219 <<
" Norm reduction (" << std::setw(2) << jiter+1 <<
") = "
220 << util::full_precision(normReduction) << std::endl
221 <<
" Quadratic cost function: J (" << std::setw(2) << jiter+1 <<
") = "
222 << util::full_precision(costJ) << std::endl
223 <<
" Quadratic cost function: Jb (" << std::setw(2) << jiter+1 <<
") = "
224 << util::full_precision(costJb) << std::endl
225 <<
" Quadratic cost function: JoJc(" << std::setw(2) << jiter+1 <<
") = "
226 << util::full_precision(costJoJc) << std::endl << std::endl;
229 lmp_.push(pp, hh, qq, rho);
231 if (normReduction < tolerance) {
232 Log::info() <<
"DRPCG: Achieved required reduction in residual norm." << std::endl;
238 scals.push_back(1.0/rdots);
244 return normReduction;
251 #endif // OOPS_ASSIMILATION_DRPCGMINIMIZER_H_