FV3 Bundle
CostJbTotal.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_COSTJBTOTAL_H_
12 #define OOPS_ASSIMILATION_COSTJBTOTAL_H_
13 
14 #include<limits>
15 
16 #include <boost/scoped_ptr.hpp>
17 
18 #include "eckit/config/LocalConfiguration.h"
25 #include "oops/util/Logger.h"
26 
27 namespace oops {
28  template<typename MODEL> class JqTerm;
29  template<typename MODEL> class JqTermTLAD;
30 
31 // -----------------------------------------------------------------------------
32 
33 /// Total Jb cost function for all components of the control variable.
34 
35 template<typename MODEL> class CostJbTotal {
44 
45  public:
46 /// Construct \f$ J_b\f$.
47  CostJbTotal(const CtrlVar_ &, JbState_ *, const eckit::Configuration &, const Geometry_ &);
48 
49 /// Destructor
51 
52 /// Initialize before nonlinear model integration.
53  JqTerm_ * initialize(const CtrlVar_ &) const;
54  JqTermTLAD_ * initializeTraj(const CtrlVar_ &, const Geometry_ &);
55 
56 /// Finalize computation after nonlinear model integration.
57  double finalize(JqTerm_ *) const;
58  void finalizeTraj(JqTermTLAD_ *);
59 
60 /// Initialize before starting the TL run.
61  JqTermTLAD_ * initializeTL() const;
62  void finalizeTL(JqTermTLAD_ *, const CtrlInc_ &, CtrlInc_ &) const;
63 
64 /// Initialize before starting the AD run.
65  JqTermTLAD_ * initializeAD(CtrlInc_ &, const CtrlInc_ &) const;
66  void finalizeAD(JqTermTLAD_ *) const;
67 
68 /// Multiply by covariance matrix and its inverse.
69  void multiplyB(const CtrlInc_ &, CtrlInc_ &) const;
70  void multiplyBinv(const CtrlInc_ &, CtrlInc_ &) const;
71 
72 /// Randomize
73  void randomize(CtrlInc_ &) const;
74 
75 /// Add Jb gradient at first guess.
76  void addGradientFG(CtrlInc_ &) const;
77  void addGradientFG(CtrlInc_ &, CtrlInc_ &) const;
78 
79 /// Return background.
80  const CtrlVar_ & getBackground() const {return xb_;}
81 
82 /// Return first guess \f$ x_0-x_b\f$.
83  const CtrlInc_ & getFirstGuess() const {return *dxFG_;}
84 
85 /// Jb terms for ControlIncrement constructor.
86  const Geometry_ & resolution() const {return *resol_;}
87  const JbState_ & jbState() const {return *jb_;}
88  const ModelAuxCovar_ & jbModBias() const {return jbModBias_;}
89  const ObsAuxCovar_ & jbObsBias() const {return jbObsBias_;}
90 
91  private:
92  double evaluate(const CtrlInc_ &) const;
93 
94  const CtrlVar_ & xb_;
95  boost::scoped_ptr<JbState_> jb_;
98 
99  const CtrlVar_ mutable * fg_;
100 
101 /// First guess increment \f$x_0-x_b\f$ or more generally \f$ x_i-M(x_{i-1})\f$.
102  boost::scoped_ptr<CtrlInc_> dxFG_;
103 
104 /// Inner loop resolution
105  boost::scoped_ptr<Geometry_> resol_;
106 };
107 
108 // =============================================================================
109 
110 template<typename MODEL>
112  const eckit::Configuration & conf, const Geometry_ & resol)
113  : xb_(xb), jb_(jb),
114  jbModBias_(conf.getSubConfiguration("ModelBiasCovariance"), resol),
115  jbObsBias_(conf.getSubConfiguration("ObsBiasCovariance")),
116  dxFG_(0), resol_(0)
117 {
118  Log::trace() << "CostJbTotal contructed." << std::endl;
119 }
120 
121 // -----------------------------------------------------------------------------
122 
123 template<typename MODEL>
125  fg_ = &fg;
126  JqTerm_ * jqnl = jb_->initializeJq();
127  return jqnl;
128 }
129 
130 // -----------------------------------------------------------------------------
131 
132 template<typename MODEL>
133 double CostJbTotal<MODEL>::finalize(JqTerm_ * jqnl) const {
134  ASSERT(fg_);
135  CtrlInc_ dx(*this);
136 
137 // Compute x_0 - x_b for Jb
138  jb_->computeIncrement(xb_.state(), fg_->state(), dx.state());
139 
140 // Model and Obs biases
141  dx.modVar().diff(fg_->modVar(), xb_.modVar());
142  dx.obsVar().diff(fg_->obsVar(), xb_.obsVar());
143 
144  if (jqnl) jqnl->computeModelError(fg_->state(), dx.state());
145  Log::info() << "CostJb: FG-BG" << dx << std::endl;
146 
147 // Compute Jb value
148  double zjb = this->evaluate(dx);
149  return zjb;
150 }
151 
152 // -----------------------------------------------------------------------------
153 
154 template<typename MODEL>
156  const Geometry_ & resol) {
157  fg_ = &fg;
158  resol_.reset(new Geometry_(resol));
159 // Linearize terms
160  jb_->linearize(fg.state(), *resol_);
161  jbModBias_.linearize(fg.modVar(), *resol_);
162  jbObsBias_.linearize(fg.obsVar());
163 
164  JqTermTLAD_ * jqlin = jb_->initializeJqTLAD();
165 
166  return jqlin;
167 }
168 
169 // -----------------------------------------------------------------------------
170 
171 template<typename MODEL>
173  ASSERT(fg_);
174 // Compute and save first guess increment.
175  dxFG_.reset(new CtrlInc_(*this));
176 
177 // Compute x_0 - x_b for Jb
178  jb_->computeIncrement(xb_.state(), fg_->state(), dxFG_->state());
179 
180 // Model and Obs biases
181  dxFG_->modVar().diff(fg_->modVar(), xb_.modVar());
182  dxFG_->obsVar().diff(fg_->obsVar(), xb_.obsVar());
183 
184  if (jqlin) jqlin->computeModelErrorTraj(fg_->state(), dxFG_->state());
185  Log::info() << "CostJb: FG-BG" << *dxFG_ << std::endl;
186 }
187 
188 // -----------------------------------------------------------------------------
189 
190 template<typename MODEL>
191 double CostJbTotal<MODEL>::evaluate(const CtrlInc_ & dx) const {
192  CtrlInc_ gg(*this);
193  this->multiplyBinv(dx, gg);
194 
195  double zjb = 0.0;
196  double zz = 0.5 * dot_product(dx.state(), gg.state());
197  Log::info() << "CostJb : Nonlinear Jb State = " << zz << std::endl;
198  zjb += zz;
199  zz = 0.5 * dot_product(dx.modVar(), gg.modVar());
200  Log::info() << "CostJb : Nonlinear Jb Model Aux = " << zz << std::endl;
201  zjb += zz;
202  zz = 0.5 * dot_product(dx.obsVar(), gg.obsVar());
203  Log::info() << "CostJb : Nonlinear Jb Obs Aux = " << zz << std::endl;
204  zjb += zz;
205 
206  Log::info() << "CostJb : Nonlinear Jb = " << zjb << std::endl;
207 
208 // Get rid of very small values for test
209  double ztest = zjb;
210  if (zjb >= 0.0 && zjb <= std::numeric_limits<double>::epsilon()) ztest = 0.0;
211  Log::test() << "CostJb : Nonlinear Jb = " << ztest << std::endl;
212 
213  return zjb;
214 }
215 
216 // -----------------------------------------------------------------------------
217 
218 template<typename MODEL>
220  CtrlInc_ gg(grad, false);
221  this->multiplyBinv(*dxFG_, gg);
222  grad += gg;
223 }
224 
225 // -----------------------------------------------------------------------------
226 
227 template<typename MODEL>
229  jb_->addGradient(dxFG_->state(), grad.state(), gradJb.state());
230  grad.modVar() += gradJb.modVar();
231  grad.obsVar() += gradJb.obsVar();
232 }
233 
234 // -----------------------------------------------------------------------------
235 
236 template<typename MODEL>
238  JqTermTLAD_ * jqtl = jb_->initializeJqTL();
239  return jqtl;
240 }
241 
242 // -----------------------------------------------------------------------------
243 
244 template<typename MODEL>
246  CtrlInc_ & dx) const {
247  dx = bgns;
248  if (jqtl) jqtl->computeModelErrorTL(dx.state());
249 }
250 
251 // -----------------------------------------------------------------------------
252 
253 template<typename MODEL>
255  const CtrlInc_ & dx) const {
256  JqTermTLAD_ * jqad = jb_->initializeJqAD(dx.state());
257  bgns += dx;
258  return jqad;
259 }
260 
261 // -----------------------------------------------------------------------------
262 
263 template<typename MODEL>
265  if (jqad) jqad->clear();
266 }
267 
268 // -----------------------------------------------------------------------------
269 
270 template<typename MODEL>
271 void CostJbTotal<MODEL>::multiplyB(const CtrlInc_ & dxin, CtrlInc_ & dxout) const {
272  jb_->Bmult(dxin.state(), dxout.state());
273  jbModBias_.multiply(dxin.modVar(), dxout.modVar());
274  jbObsBias_.multiply(dxin.obsVar(), dxout.obsVar());
275 }
276 
277 // -----------------------------------------------------------------------------
278 
279 template<typename MODEL>
280 void CostJbTotal<MODEL>::multiplyBinv(const CtrlInc_ & dxin, CtrlInc_ & dxout) const {
281  jb_->Bminv(dxin.state(), dxout.state());
282  jbModBias_.inverseMultiply(dxin.modVar(), dxout.modVar());
283  jbObsBias_.inverseMultiply(dxin.obsVar(), dxout.obsVar());
284 }
285 
286 // -----------------------------------------------------------------------------
287 
288 template<typename MODEL>
290  jb_->randomize(dx.state());
291 }
292 
293 // -----------------------------------------------------------------------------
294 
295 } // namespace oops
296 
297 #endif // OOPS_ASSIMILATION_COSTJBTOTAL_H_
const ModelAuxCovar_ & jbModBias() const
Definition: CostJbTotal.h:88
void diff(const ObsAuxControl_ &, const ObsAuxControl_ &)
Linear algebra operators.
State4D_ & state()
Get state control variable.
boost::scoped_ptr< Geometry_ > resol_
Inner loop resolution.
Definition: CostJbTotal.h:105
void computeModelError(const State4D_ &, Increment4D_ &)
Definition: JqTerm.h:59
const JbState_ & jbState() const
Definition: CostJbTotal.h:87
ControlIncrement< MODEL > CtrlInc_
Definition: CostJbTotal.h:36
ControlVariable< MODEL > CtrlVar_
Definition: CostJbTotal.h:37
~CostJbTotal()
Destructor.
Definition: CostJbTotal.h:50
ObsAuxIncr_ & obsVar()
Get augmented observation control variable.
ModelAuxCovariance< MODEL > ModelAuxCovar_
Definition: CostJbTotal.h:42
ModelAuxIncr_ & modVar()
Get augmented model control variable.
const CtrlVar_ * fg_
Definition: CostJbTotal.h:99
Definition: conf.py:1
ObsAuxCovariance< MODEL > ObsAuxCovar_
Definition: CostJbTotal.h:43
const Geometry_ & resolution() const
Jb terms for ControlIncrement constructor.
Definition: CostJbTotal.h:86
boost::scoped_ptr< JbState_ > jb_
Definition: CostJbTotal.h:95
program test
void diff(const ModelAuxControl_ &, const ModelAuxControl_ &)
Linear algebra operators.
Control variable.
The namespace for the main oops code.
CostJbTotal(const CtrlVar_ &, JbState_ *, const eckit::Configuration &, const Geometry_ &)
Construct .
Definition: CostJbTotal.h:111
void computeModelErrorTraj(const State4D_ &, Increment4D_ &)
Definition: JqTermTLAD.h:90
ObsAuxCovar_ jbObsBias_
Definition: CostJbTotal.h:97
ModelAux_ & modVar()
Get augmented model control variable.
Geometry< MODEL > Geometry_
Definition: CostJbTotal.h:41
Increment4D_ & state()
Get state control variable.
double evaluate(const CtrlInc_ &) const
Definition: CostJbTotal.h:191
subroutine, public info(self)
const ObsAuxCovar_ & jbObsBias() const
Definition: CostJbTotal.h:89
real(fp), parameter xb
Definition: ufo_aod_mod.F90:41
void multiplyBinv(const CtrlInc_ &, CtrlInc_ &) const
Definition: CostJbTotal.h:280
void finalizeAD(JqTermTLAD_ *) const
Definition: CostJbTotal.h:264
void randomize(CtrlInc_ &) const
Randomize.
Definition: CostJbTotal.h:289
JqTermTLAD_ * initializeTL() const
Initialize before starting the TL run.
Definition: CostJbTotal.h:237
void addGradientFG(CtrlInc_ &) const
Add Jb gradient at first guess.
Definition: CostJbTotal.h:219
JqTermTLAD_ * initializeAD(CtrlInc_ &, const CtrlInc_ &) const
Initialize before starting the AD run.
Definition: CostJbTotal.h:254
ModelAuxCovar_ jbModBias_
Definition: CostJbTotal.h:96
void finalizeTraj(JqTermTLAD_ *)
Definition: CostJbTotal.h:172
Jb Cost Function Base Class.
Definition: CostJbState.h:41
void finalizeTL(JqTermTLAD_ *, const CtrlInc_ &, CtrlInc_ &) const
Definition: CostJbTotal.h:245
JqTermTLAD_ * initializeTraj(const CtrlVar_ &, const Geometry_ &)
Definition: CostJbTotal.h:155
JqTerm< MODEL > JqTerm_
Definition: CostJbTotal.h:39
real(kind=kind_real), parameter, public epsilon
boost::scoped_ptr< CtrlInc_ > dxFG_
First guess increment or more generally .
Definition: CostJbTotal.h:102
const CtrlVar_ & xb_
Definition: CostJbTotal.h:94
double finalize(JqTerm_ *) const
Finalize computation after nonlinear model integration.
Definition: CostJbTotal.h:133
void multiplyB(const CtrlInc_ &, CtrlInc_ &) const
Multiply by covariance matrix and its inverse.
Definition: CostJbTotal.h:271
JqTerm_ * initialize(const CtrlVar_ &) const
Initialize before nonlinear model integration.
Definition: CostJbTotal.h:124
void computeModelErrorTL(Increment4D_ &)
Definition: JqTermTLAD.h:108
CostJbState< MODEL > JbState_
Definition: CostJbTotal.h:38
const CtrlVar_ & getBackground() const
Return background.
Definition: CostJbTotal.h:80
ObsAuxCtrl_ & obsVar()
Get augmented observation control variable.
const CtrlInc_ & getFirstGuess() const
Return first guess .
Definition: CostJbTotal.h:83
JqTermTLAD< MODEL > JqTermTLAD_
Definition: CostJbTotal.h:40