FV3 Bundle
DualMinimizer.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #ifndef OOPS_ASSIMILATION_DUALMINIMIZER_H_
12 #define OOPS_ASSIMILATION_DUALMINIMIZER_H_
13 
14 #include <string>
15 
16 #include <boost/scoped_ptr.hpp>
17 
18 #include "eckit/config/Configuration.h"
28 #include "oops/util/dot_product.h"
29 #include "oops/util/Logger.h"
30 
31 namespace oops {
32 
33 /// Dual Minimizer
34 /*!
35  * Base class for all dual (observation) space minimizers.
36  */
37 
38 // -----------------------------------------------------------------------------
39 
40 template<typename MODEL> class DualMinimizer : public Minimizer<MODEL> {
48 
49  public:
50  explicit DualMinimizer(const CostFct_ & J): Minimizer_(J), J_(J), gradJb_(0) {}
52  const std::string classname() const override = 0;
53 
54  private:
55  CtrlInc_ * doMinimize(const eckit::Configuration &) override;
56  virtual double solve(Dual_ &, double &, Dual_ &, const HBHt_ &, const Rinv_ &,
57  const int &, const double &, Dual_ &, const double &) = 0;
58 
59  const CostFct_ & J_;
60  boost::scoped_ptr<CtrlInc_> gradJb_;
61 };
62 
63 // =============================================================================
64 
65 template<typename MODEL>
66 ControlIncrement<MODEL> * DualMinimizer<MODEL>::doMinimize(const eckit::Configuration & config) {
67  int ninner = config.getInt("ninner");
68  double gnreduc = config.getDouble("gradient_norm_reduction");
69 
70  bool runOnlineAdjTest = false;
71  if (config.has("onlineDiagnostics")) {
72  const eckit::LocalConfiguration onlineDiag(config, "onlineDiagnostics");
73  runOnlineAdjTest = onlineDiag.getBool("onlineAdjTest");
74  }
75 
76  if (gradJb_ == 0) {
77  gradJb_.reset(new CtrlInc_(J_.jb()));
78  } else {
79  gradJb_.reset(new CtrlInc_(J_.jb().resolution(), *gradJb_));
80  }
81 
82  Log::info() << std::endl;
83  Log::info() << classname() << ": max iter = " << ninner
84  << ", requested norm reduction = " << gnreduc << std::endl;
85 
86 // Define the matrices
87  const Bmat_ B(J_);
88  const HBHt_ HBHt(J_, runOnlineAdjTest);
89  const Rinv_ Rinv(J_);
90  const HMatrix<MODEL> H(J_);
91  const HtMatrix<MODEL> Ht(J_);
92 
93 // Define minimisation starting point in dual space
94  Dual_ vv;
95  for (unsigned jj = 0; jj < J_.nterms(); ++jj) {
96  vv.append(J_.jterm(jj).newDualVector());
97  }
98  double vvp;
99 
100 // Get R^{-1} d
101  Dual_ rr;
102  for (unsigned jj = 0; jj < J_.nterms(); ++jj) {
103  rr.append(J_.jterm(jj).newGradientFG());
104  }
105  rr *= -1.0;
106 
107 // Update rr if initial dx in model space is not a zero vector
108 // rr = rr - Rinv H dx0
109 
110 // Compute a = H (xb - xk)
111  Dual_ dy;
112  CtrlInc_ hdxfg(J_.jb().getFirstGuess());
113  H.multiply(hdxfg, dy);
114  dy *= -1.0;
115 
116 // Compute sigma = (xb - xk)^T Binv (xb - xk)
117  CtrlInc_ g0(J_.jb());
118  J_.jb().addGradientFG(g0, *gradJb_);
119 
120  double sigma = dot_product(J_.jb().getFirstGuess(), g0);
121 
122 // Solve the linear system
123  double reduc = this->solve(vv, vvp, rr, HBHt, Rinv, ninner, gnreduc, dy, sigma);
124 
125  Log::test() << classname() << ": reduction in residual norm = " << reduc << std::endl;
126 
127 // Recover solution in primal space
128  CtrlInc_ dh(J_.jb());
129  J_.zeroAD(dh);
130  Ht.multiply(vv, dh);
131  dh.axpy(-vvp, g0);
132 
133  CtrlInc_ * dx = new CtrlInc_(J_.jb());
134  B.multiply(dh, *dx); // BHtaug vvaug
135 
136  Log::info() << classname() << ": Estimated Final Jb = "
137  << 0.5 * dot_product(*dx, dh) << std::endl;
138  Log::info() << classname() << " output" << *dx << std::endl;
139 
140 // Update gradient Jb
141  *gradJb_ += dh;
142 
143  return dx;
144 }
145 
146 // -----------------------------------------------------------------------------
147 
148 } // namespace oops
149 
150 #endif // OOPS_ASSIMILATION_DUALMINIMIZER_H_
The matrix.
Definition: HMatrix.h:33
const std::string classname() const override=0
const CostFct_ & J_
Definition: DualMinimizer.h:59
BMatrix< MODEL > Bmat_
Definition: DualMinimizer.h:43
Container of dual space vectors for all terms of the cost function.
Definition: DualVector.h:34
virtual double solve(Dual_ &, double &, Dual_ &, const HBHt_ &, const Rinv_ &, const int &, const double &, Dual_ &, const double &)=0
Cost Function.
Definition: CostFunction.h:56
integer, parameter sigma
Flags to indicate where climatology pressure levels are pressure or sigma levels. ...
void multiply(CtrlInc_ &dx, DualVector< MODEL > &dy, const bool idModel=false) const
Definition: HMatrix.h:41
program test
Dual Minimizer.
Definition: DualMinimizer.h:40
The namespace for the main oops code.
DualMinimizer(const CostFct_ &J)
Definition: DualMinimizer.h:50
CostFunction< MODEL > CostFct_
Definition: DualMinimizer.h:42
HBHtMatrix< MODEL > HBHt_
Definition: DualMinimizer.h:45
The matrix.
Definition: HBHtMatrix.h:33
ControlIncrement< MODEL > CtrlInc_
Definition: DualMinimizer.h:41
void multiply(const DualVector< MODEL > &dy, ControlIncrement< MODEL > &dx, const bool idModel=false) const
Definition: HtMatrix.h:40
RinvMatrix< MODEL > Rinv_
Definition: DualMinimizer.h:47
CtrlInc_ * doMinimize(const eckit::Configuration &) override
Definition: DualMinimizer.h:66
subroutine, public info(self)
The matrix.
Definition: BMatrix.h:27
Minimizer< MODEL > Minimizer_
Definition: DualMinimizer.h:46
The matrix.
Definition: RinvMatrix.h:29
void append(GeneralizedDepartures *)
Definition: DualVector.h:107
A Minimizer knows how to minimize a cost function.
Definition: Minimizer.h:39
void multiply(const CtrlInc_ &x, CtrlInc_ &bx) const
Definition: BMatrix.h:33
boost::scoped_ptr< CtrlInc_ > gradJb_
Definition: DualMinimizer.h:60
DualVector< MODEL > Dual_
Definition: DualMinimizer.h:44
The matrix.
Definition: HtMatrix.h:33