11 #ifndef OOPS_ASSIMILATION_DRIPCGMINIMIZER_H_
12 #define OOPS_ASSIMILATION_DRIPCGMINIMIZER_H_
24 #include "oops/util/dot_product.h"
25 #include "oops/util/formats.h"
26 #include "oops/util/Logger.h"
80 const std::string
classname()
const override {
return "DRIPCGMinimizer";}
86 const double,
const double,
const int,
const double)
override;
93 template<
typename MODEL,
typename OBS>
100 template<
typename MODEL,
typename OBS>
103 const double costJ0Jb,
const double costJ0JoJc,
104 const int maxiter,
const double tolerance) {
113 std::vector<CtrlInc_> vvecs;
114 std::vector<CtrlInc_> zvecs;
115 std::vector<double> scals;
117 vvecs.reserve(maxiter+1);
118 zvecs.reserve(maxiter+1);
119 scals.reserve(maxiter+1);
121 const double costJ0 = costJ0Jb + costJ0JoJc;
125 lmp_.multiply(rr, sh);
128 double dotRr0 = dot_product(rr, rr);
129 double dotSr0 = dot_product(rr, ss);
130 double normReduction = 1.0;
131 double rdots = dotSr0;
132 double rdots_old = dotSr0;
136 scals.push_back(1.0/dotSr0);
138 Log::info() << std::endl;
139 for (
int jiter = 0; jiter < maxiter; ++jiter) {
140 Log::info() <<
" DRIPCG Starting Iteration " << jiter+1 << std::endl;
147 double beta = -dot_product(ss, dr)/rdots_old;
161 double rho = dot_product(pp, ap);
162 double alpha = rdots/rho;
163 Log::info() <<
"DRIPCGMinimizer rho = " << rho <<
", alpha = " << alpha << std::endl;
170 double costJ = costJ0 - 0.5 * dot_product(xx, r0);
171 double costJb = costJ0Jb + 0.5 * dot_product(xx, xh);
172 double costJoJc = costJ - costJb;
175 for (
int jj = 0; jj < jiter; ++jj) {
176 double proj = scals[jj] * dot_product(rr, zvecs[jj]);
177 rr.
axpy(-proj, vvecs[jj]);
180 lmp_.multiply(rr, sh);
184 rdots = dot_product(rr, ss);
191 normReduction = sqrt(dot_product(rr, rr)/dotRr0);
193 Log::info() <<
"DRIPCG end of iteration " << jiter+1 <<
". Norm reduction= "
194 << util::full_precision(normReduction) << std::endl
195 <<
" Quadratic cost function: J (" << jiter+1 <<
") = "
196 << util::full_precision(costJ) << std::endl
197 <<
" Quadratic cost function: Jb (" << jiter+1 <<
") = "
198 << util::full_precision(costJb) << std::endl
199 <<
" Quadratic cost function: JoJc(" << jiter+1 <<
") = "
200 << util::full_precision(costJoJc) << std::endl << std::endl;
203 lmp_.push(pp, ph, ap, rho);
205 if (normReduction < tolerance) {
206 Log::info() <<
"DRIPCG: Achieved required reduction in residual norm." << std::endl;
212 scals.push_back(1.0/rdots);
218 return normReduction;
225 #endif // OOPS_ASSIMILATION_DRIPCGMINIMIZER_H_