11 #ifndef OOPS_ASSIMILATION_PRIMALMINIMIZER_H_
12 #define OOPS_ASSIMILATION_PRIMALMINIMIZER_H_
17 #include "eckit/config/Configuration.h"
23 #include "oops/util/FloatCompare.h"
24 #include "oops/util/Logger.h"
55 const int,
const double) = 0;
62 template<
typename MODEL,
typename OBS>
65 int ninner = config.getInt(
"ninner");
66 double gnreduc = config.getDouble(
"gradient norm reduction");
68 bool runOnlineAdjTest = config.getBool(
"online diagnostics.online adj test",
false);
70 Log::info() << classname() <<
": max iter = " << ninner
71 <<
", requested norm reduction = " << gnreduc << std::endl;
74 Hessian_ hessian(J_, runOnlineAdjTest);
79 if (config.has(
"fsoi")) {
80 const eckit::LocalConfiguration FcSensitivityConfig(config,
"fsoi.input forecast sensitivity");
81 rhs.
read(FcSensitivityConfig);
82 Log::info() << classname() <<
" rhs has forecast sensitivity" << std::endl;
84 J_.computeGradientFG(rhs);
85 J_.jb().addGradientFG(rhs);
88 Log::info() << classname() <<
" rhs" << rhs << std::endl;
94 double reduc = this->solve(*dx, rhs, hessian, B, ninner, gnreduc);
96 Log::test() << classname() <<
": reduction in residual norm = " << reduc << std::endl;
97 Log::info() << classname() <<
" output" << *dx << std::endl;
99 if (config.has(
"fsoi")) {
100 Log::info() << classname() <<
" Entering Observation Sensitivity Calculation" << std::endl;
108 const std::string osensname =
"ObsSensitivity";
111 bool runFSOIincTest = config.getBool(
"fsoi.increment test",
false);
112 if (runFSOIincTest) {
115 for (
unsigned jj = 0; jj < J_.nterms(); ++jj) {
116 std::unique_ptr<GeneralizedDepartures> ww(J_.jterm(jj).newGradientFG());
117 dp.append(J_.jterm(jj).multiplyCovar(*ww));
121 double adj_tst_fwd = dot_product(rhs, rhs);
123 double adj_tst_bwd = dot_product(ys,
dp);
125 Log::info() <<
"Online FSOI increment test: " << std::endl
126 << util::PrintAdjTest(adj_tst_fwd, adj_tst_bwd,
"K") << std::endl;
128 double fsoi_inctest_tolerance = config.getDouble(
"fsoi.increment test tolerance", 1.0e-5);
129 bool passed = oops::is_close_absolute(adj_tst_fwd, adj_tst_bwd, fsoi_inctest_tolerance);
131 Log::test() <<
"FSOI increment test within tolerance." << std::endl;
133 Log::test() <<
"FSOI increment test fails tolerance bound." << std::endl;
void zero()
Linear algebra operators.
void read(const eckit::Configuration &)
I/O and diagnostics.
Container of dual space vectors for all terms of the cost function.
void saveDep(const std::string &) const
A Minimizer knows how to minimize a cost function.
virtual double solve(CtrlInc_ &, const CtrlInc_ &, const Hessian_ &, const Bmat_ &, const int, const double)=0
BMatrix< MODEL, OBS > Bmat_
ControlIncrement< MODEL, OBS > CtrlInc_
const std::string classname() const override=0
CtrlInc_ * doMinimize(const eckit::Configuration &) override
Minimizer< MODEL, OBS > Minimizer_
HessianMatrix< MODEL, OBS > Hessian_
CostFunction< MODEL, OBS > CostFct_
RinvHMatrix< MODEL, OBS > RinvH_
PrimalMinimizer(const CostFct_ &J)
void multiply(const CtrlInc_ &dx, Dual_ &zz) const
The namespace for the main oops code.