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>
105 template<
typename MODEL>
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;
128 const double costJ0 = costJ0Jb + costJ0JoJc;
134 Log::info() <<
"normr0 " << dot_product(rr, rr) << std::endl;
137 lmp_.multiply(rr,
pr);
145 double dotRr0 = dot_product(rr, zz);
146 double normReduction = 1.0;
147 double rdots = dotRr0;
148 double rdots_old = 0.0;
152 scals.push_back(1.0/dotRr0);
155 for (
int jiter = 0; jiter < maxiter; ++jiter) {
156 Log::info() <<
" DRPCG Starting Iteration " << jiter+1 << std::endl;
160 double beta = rdots/rdots_old;
177 double rho = dot_product(pp, qq);
189 double costJ = costJ0 - 0.5 * dot_product(dx,
r0);
191 double costJb = costJ0Jb + 0.5 * dot_product(dx, dxh);
193 double costJoJc = costJ - costJb;
196 for (
int jj = 0; jj < jiter; ++jj) {
197 double proj = scals[jj] * dot_product(rr, zvecs[jj]);
198 rr.
axpy(-proj, vvecs[jj]);
202 lmp_.multiply(rr,
pr);
208 rdots = dot_product(rr, zz);
210 Log::info() <<
"rdots " << rdots <<
" iteration " << jiter << std::endl;
213 normReduction = sqrt(rdots/dotRr0);
215 Log::info() <<
"DRPCG end of iteration " << jiter+1 << std::endl
216 <<
" Norm reduction (" << std::setw(2) << jiter+1 <<
") = " 217 << util::full_precision(normReduction) << std::endl
218 <<
" Quadratic cost function: J (" << std::setw(2) << jiter+1 <<
") = " 219 << util::full_precision(costJ) << std::endl
220 <<
" Quadratic cost function: Jb (" << std::setw(2) << jiter+1 <<
") = " 221 << util::full_precision(costJb) << std::endl
222 <<
" Quadratic cost function: JoJc(" << std::setw(2) << jiter+1 <<
") = " 223 << util::full_precision(costJoJc) << std::endl << std::endl;
226 lmp_.push(pp, hh, qq,
rho);
229 Log::info() <<
"DRPCG: Achieved required reduction in residual norm." << std::endl;
235 scals.push_back(1.0/rdots);
241 return normReduction;
248 #endif // OOPS_ASSIMILATION_DRPCGMINIMIZER_H_
double solve(CtrlInc_ &, CtrlInc_ &, CtrlInc_ &, const Bmat_ &, const HtRinvH_ &, const double, const double, const int, const double) override
real(double_kind), dimension(numint), parameter pr
CostFunction< MODEL > CostFct_
DRPCGMinimizer(const eckit::Configuration &, const CostFct_ &)
HtRinvHMatrix< MODEL > HtRinvH_
const std::string classname() const override
ControlIncrement< MODEL > CtrlInc_
The namespace for the main oops code.
QNewtonLMP< CtrlInc_, Bmat_ > lmp_
void multiply(const CtrlInc_ &dx, CtrlInc_ &dz) const
subroutine, public info(self)
real(fp), parameter, public tolerance
DR (Derber and Rosati) Minimizers.
void axpy(const double, const ControlIncrement &)
void multiply(const CtrlInc_ &x, CtrlInc_ &bx) const