11 #ifndef OOPS_ASSIMILATION_MINIMIZER_H_
12 #define OOPS_ASSIMILATION_MINIMIZER_H_
16 #include <boost/noncopyable.hpp>
18 #include "eckit/config/Configuration.h"
27 #include "oops/util/dot_product.h"
28 #include "oops/util/formats.h"
29 #include "oops/util/Logger.h"
30 #include "oops/util/PrintAdjTest.h"
37 template<
typename MODEL,
typename OBS>
class Minimizer :
private boost::noncopyable {
54 void adjTests(
const eckit::Configuration &);
58 void tlmTests(
const eckit::Configuration &);
70 template<
typename MODEL,
typename OBS>
74 this->tlmTests(config);
77 this->adjTests(config);
83 this->tlmPropagTest(config, *dx);
93 template<
typename MODEL,
typename OBS>
97 if (config.has(
"online diagnostics")) {
98 const eckit::LocalConfiguration onlineDiag(config,
"online diagnostics");
99 bool runTlmTaylorTest = onlineDiag.getBool(
"tlm taylor test",
false);
100 bool runTlmApproxTest = onlineDiag.getBool(
"tlm approx test",
false);
107 if (outerIteration_ == 0 && runTlmApproxTest) this->tlmApproxTest(H);
110 if (outerIteration_ == 0 && runTlmTaylorTest) this->tlmTaylorTest(H);
116 template<
typename MODEL,
typename OBS>
120 if (config.has(
"online diagnostics")) {
121 const eckit::LocalConfiguration onlineDiag(config,
"online diagnostics");
122 bool runAdjTlmTest = onlineDiag.getBool(
"adj tlm test",
false);
123 bool runAdjObsTest = onlineDiag.getBool(
"adj obs test",
false);
130 if (runAdjTlmTest) this->adjModelTest(Ht, H);
133 if (runAdjObsTest) this->adjObsTest(Ht, H);
139 template<
typename MODEL,
typename OBS>
149 Log::info() << std::endl
150 <<
"TLM Linear Approximation Test - starting: " << outerIteration_
151 << std::endl << std::endl;
157 J_.jb().randomize(dx);
166 J_.addIncrement(mpertxx, dx);
167 J_.runNL(mpertxx, pp);
175 Log::info() << std::endl <<
"TLM Linear Approximation Test: done." << std::endl;
180 template<
typename MODEL,
typename OBS>
191 if (config.has(
"online diagnostics")) {
192 const eckit::LocalConfiguration onlineDiag(config,
"online diagnostics");
193 bool runTlmPropagTest = onlineDiag.getBool(
"tlm propagation test",
false);
195 if (runTlmPropagTest) {
197 Log::info() <<
"TLM Propagation Test - starting: " << outerIteration_
198 << std::endl << std::endl;
209 Log::info() << std::endl <<
"TLM Propagation Test: done." << std::endl;
216 template<
typename MODEL,
typename OBS>
223 Log::info() << std::endl
224 <<
"TLM Taylor Test: " << outerIteration_
231 J_.jb().randomize(dx);
244 for (
unsigned int jj = 0; jj < 14; ++jj) {
247 pmdx *= 1./pow(10.0, jj);
248 double denom = sqrt(dot_product(pmdx, pmdx));
253 pdx *= 1./pow(10.0, jj);
254 J_.addIncrement(mpertxx, pdx);
255 J_.runNL(mpertxx, pp);
260 double nom = sqrt(dot_product(diff_nl, diff_nl));
263 Log::info() << std::endl
264 <<
"TLM Taylor test: p = " << std::setw(8) << 1./pow(10.0, jj)
265 <<
", ||M(x) - M(x+p dx)|| / ||p M'(dx)|| = "
266 << util::full_precision(1.+std::abs(1.-nom/denom))
269 Log::info() << std::endl;
274 template<
typename MODEL,
typename OBS>
286 J_.jb().randomize(dx1);
287 J_.jb().randomize(dx2);
309 double adj_tst_fwd = dot_product(mdx1, dx2);
312 double adj_tst_bwd = dot_product(dx1, mtdx2);
315 Log::info() <<
"Model Adjoint Test: " << outerIteration_ << std::endl
316 << util::PrintAdjTest(adj_tst_fwd, adj_tst_bwd,
"M")
317 << std::endl << std::endl;
322 template<
typename MODEL,
typename OBS>
340 J_.jb().randomize(dx1);
341 J_.jb().randomize(dx2);
352 double adj_tst_fwd = dot_product(hdx1, hdx2);
355 double adj_tst_bwd = dot_product(dx1, hthdx2);
358 Log::info() <<
"Obs Adjoint Test: " << outerIteration_ << std::endl
359 << util::PrintAdjTest(adj_tst_fwd, adj_tst_bwd,
"H")
360 << std::endl << std::endl;
366 template <
typename MODEL,
typename OBS>
376 static std::map < std::string, MinFactory<MODEL, OBS> * > &
getMakers() {
377 static std::map < std::string, MinFactory<MODEL, OBS> * > makers_;
384 template<
class MODEL,
class OBS,
class FCT>
388 return new FCT(conf, J);
396 template <
typename MODEL,
typename OBS>
398 if (getMakers().find(name) != getMakers().end()) {
399 throw std::runtime_error(name +
" already registered in minimizer factory.");
401 getMakers()[name] =
this;
406 template <
typename MODEL,
typename OBS>
409 std::string
id = config.getString(
"algorithm");
410 Log::info() <<
"Minimizer algorithm=" <<
id << std::endl;
411 typename std::map<std::string, MinFactory<MODEL, OBS>*>::iterator j = getMakers().find(
id);
412 if (j == getMakers().end()) {
413 throw std::runtime_error(
id +
" does not exist in minimizer factory.");
415 return (*j).second->make(config, J);
422 #endif // OOPS_ASSIMILATION_MINIMIZER_H_