FV3 Bundle
CostJbJq.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_COSTJBJQ_H_
12 #define OOPS_ASSIMILATION_COSTJBJQ_H_
13 
14 #include <memory>
15 #include <vector>
16 
17 #include <boost/ptr_container/ptr_vector.hpp>
18 #include <boost/scoped_ptr.hpp>
19 
20 #include "eckit/config/LocalConfiguration.h"
27 #include "oops/base/Variables.h"
30 #include "oops/util/dot_product.h"
31 #include "oops/util/Duration.h"
32 #include "oops/util/Logger.h"
33 
34 namespace oops {
35  template<typename MODEL> class ControlIncrement;
36 
37 // -----------------------------------------------------------------------------
38 
39 /// Jb + Jq Cost Function
40 /*!
41  * CostJbJq encapsulates the generalized Jb term of the cost weak
42  * constraint 4D-Var function (ie Jb+Jq).
43  */
44 
45 template<typename MODEL> class CostJbJq : public CostJbState<MODEL> {
51 
52  public:
53 /// Construct \f$ J_b\f$.
54  CostJbJq(const eckit::Configuration &, const Geometry_ &, const Variables &,
55  const util::Duration &, const State4D_ &, const bool);
56 
57 /// Destructor
58  virtual ~CostJbJq() {}
59 
60 /// Finalize \f$ J_q\f$ after the model run.
61  JqTerm<MODEL> * initializeJq() const override;
62  JqTermTLAD<MODEL> * initializeJqTLAD() const override;
63 
64 /// Get increment from state (usually first guess).
65  void computeIncrement(const State4D_ &, const State4D_ &, Increment4D_ &) const override;
66 
67 /// Linearize before the linear computations.
68  void linearize(const State4D_ &, const Geometry_ &) override;
69 
70 /// Add Jb gradient.
71  void addGradient(const Increment4D_ &, Increment4D_ &, Increment4D_ &) const override;
72 
73 /// Finalize \f$ J_q\f$ after the TL run.
74  JqTermTLAD<MODEL> * initializeJqTL() const override;
75 
76 /// Initialize \f$ J_q\f$ forcing before the AD run.
77  JqTermTLAD<MODEL> * initializeJqAD(const Increment4D_ &) const override;
78 
79 /// Multiply by \f$ B\f$ and \f$ B^{-1}\f$.
80  void Bmult(const Increment4D_ &, Increment4D_ &) const override;
81  void Bminv(const Increment4D_ &, Increment4D_ &) const override;
82 
83 /// Randomize
84  void randomize(Increment4D_ &) const override;
85 
86 /// Create new increment (set to 0).
87  unsigned int nstates() const override {return B_.size();}
88  Increment_ * newStateIncrement(const unsigned int) const override;
89 
90  private:
91  boost::ptr_vector< ModelSpaceCovarianceBase<MODEL> > B_;
92  const State4D_ & xb_;
93  const util::Duration subwin_;
94  const bool forcing_;
96  boost::scoped_ptr<const Geometry_> resol_;
97  std::vector<util::DateTime> times_;
98  const eckit::LocalConfiguration conf_;
99 };
100 
101 // =============================================================================
102 
103 // Generalized Jb Term of Cost Function
104 // -----------------------------------------------------------------------------
105 
106 template<typename MODEL>
107 CostJbJq<MODEL>::CostJbJq(const eckit::Configuration & config, const Geometry_ & resolouter,
108  const Variables & ctlvars, const util::Duration & len,
109  const State4D_ & xb, const bool forcing)
110  : B_(0), xb_(xb), subwin_(len), forcing_(forcing), ctlvars_(ctlvars), resol_(), times_(),
111  conf_(config)
112 {
113  Log::trace() << "CostJbJq contructed." << std::endl;
114 }
115 
116 // -----------------------------------------------------------------------------
117 
118 template<typename MODEL>
119 void CostJbJq<MODEL>::linearize(const State4D_ & fg, const Geometry_ & lowres) {
120  ASSERT(fg.checkStatesNumber(xb_.size()));
121  resol_.reset(new Geometry_(lowres));
122  times_.clear();
123  B_.clear();
124  std::vector<eckit::LocalConfiguration> confs;
125  conf_.get("Covariance", confs);
126  for (unsigned jsub = 0; jsub < confs.size(); ++jsub) {
127  B_.push_back(CovarianceFactory<MODEL>::create(confs[jsub], lowres, ctlvars_,
128  xb_[jsub], fg[jsub]));
129  times_.push_back(fg[jsub].validTime());
130  }
131  ASSERT(fg.checkStatesNumber(B_.size()));
132 }
133 
134 // -----------------------------------------------------------------------------
135 
136 template<typename MODEL>
138  Increment4D_ & dx) const {
139 // Compute x_0 - x_b for Jb
140  dx[0].diff(fg[0], xb[0]);
141  Log::info() << "CostJbJq: x_0 - x_b" << dx[0] << std::endl;
142 }
143 
144 // -----------------------------------------------------------------------------
145 
146 template<typename MODEL>
148  Increment4D_ & gradJb) const {
149 // Jb from pre-computed gradient
150  grad[0] += gradJb[0];
151 
152 // Compute and add Jq gradient Qi^{-1} ( x_i - M(x_{i-1}) )
153  Increment4D_ gg(grad, false);
154  for (unsigned jsub = 1; jsub < B_.size(); ++jsub) {
155  B_[jsub].inverseMultiply(dxFG[jsub], gg[jsub]);
156  grad[jsub] += gg[jsub];
157  }
158 }
159 
160 // -----------------------------------------------------------------------------
161 
162 template<typename MODEL>
164  return new JqTerm<MODEL>(B_.size());
165 }
166 
167 // -----------------------------------------------------------------------------
168 
169 template<typename MODEL>
171  return new JqTermTLAD<MODEL>(B_.size());
172 }
173 
174 // -----------------------------------------------------------------------------
175 
176 template<typename MODEL>
178  JqTermTLAD<MODEL> * jqtl = 0;
179  if (!forcing_) jqtl = new JqTermTLAD<MODEL>(B_.size());
180  return jqtl;
181 }
182 
183 // -----------------------------------------------------------------------------
184 
185 template<typename MODEL>
187  JqTermTLAD<MODEL> * jqad = 0;
188  if (!forcing_) {
189  jqad = new JqTermTLAD<MODEL>(B_.size());
190  jqad->setupAD(dx);
191  }
192  return jqad;
193 }
194 
195 // -----------------------------------------------------------------------------
196 
197 template<typename MODEL>
198 void CostJbJq<MODEL>::Bmult(const Increment4D_ & dxin, Increment4D_ & dxout) const {
199  for (unsigned jsub = 0; jsub < B_.size(); ++jsub) {
200  B_[jsub].multiply(dxin[jsub], dxout[jsub]);
201 
202  if (jsub == 0) {
203  Log::debug() << "CostJbJq:multiply Jb is "
204  << 0.5 * dot_product(dxin[0], dxout[0]) << std::endl;
205  } else {
206  Log::debug() << "CostJbJq:multiply Jq(" << jsub << ") is "
207  << 0.5 * dot_product(dxin[jsub], dxout[jsub]) << std::endl;
208  }
209  }
210 }
211 
212 // -----------------------------------------------------------------------------
213 
214 template<typename MODEL>
216  for (unsigned jsub = 0; jsub < B_.size(); ++jsub) {
217  B_[jsub].randomize(dx[jsub]);
218  }
219 }
220 
221 // -----------------------------------------------------------------------------
222 
223 template<typename MODEL>
224 void CostJbJq<MODEL>::Bminv(const Increment4D_ & dxin, Increment4D_ & dxout) const {
225  Log::warning() << "*** B inverse might not always exist ***" << std::endl;
226  for (unsigned jsub = 0; jsub < B_.size(); ++jsub) {
227  B_[jsub].inverseMultiply(dxin[jsub], dxout[jsub]);
228 
229  if (jsub == 0) {
230  Log::debug() << "CostJbJq:inverseMultiply Jb is "
231  << 0.5 * dot_product(dxin[0], dxout[0]) << std::endl;
232  } else {
233  Log::debug() << "CostJbJq:inverseMultiply Jq(" << jsub << ") is "
234  << 0.5 * dot_product(dxin[jsub], dxout[jsub]) << std::endl;
235  }
236  }
237  Log::warning() << "*** B inverse might not always exist ***" << std::endl;
238 }
239 
240 // -----------------------------------------------------------------------------
241 
242 template<typename MODEL>
244 CostJbJq<MODEL>::newStateIncrement(const unsigned int isub) const {
245  Increment_ * incr = new Increment_(*resol_, ctlvars_, times_[isub]);
246  return incr;
247 }
248 
249 // -----------------------------------------------------------------------------
250 
251 } // namespace oops
252 
253 #endif // OOPS_ASSIMILATION_COSTJBJQ_H_
JqTerm< MODEL > * initializeJq() const override
Finalize after the model run.
Definition: CostJbJq.h:163
CostJbJq(const eckit::Configuration &, const Geometry_ &, const Variables &, const util::Duration &, const State4D_ &, const bool)
Construct .
Definition: CostJbJq.h:107
void randomize(Increment4D_ &) const override
Randomize.
Definition: CostJbJq.h:215
const bool forcing_
Definition: CostJbJq.h:94
integer, parameter, public warning
JqTermTLAD< MODEL > * initializeJqAD(const Increment4D_ &) const override
Initialize forcing before the AD run.
Definition: CostJbJq.h:186
const eckit::LocalConfiguration conf_
Definition: CostJbJq.h:98
Jb + Jq Cost Function.
Definition: CostJbJq.h:45
void diff(const State4D_ &, const State4D_ &)
Linear algebra operators.
Definition: Increment4D.h:171
void setupAD(const Increment4D_ &dx)
Definition: JqTermTLAD.h:122
void addGradient(const Increment4D_ &, Increment4D_ &, Increment4D_ &) const override
Add Jb gradient.
Definition: CostJbJq.h:147
The namespace for the main oops code.
Increment4D< MODEL > Increment4D_
Definition: CostJbJq.h:48
logical debug
Definition: mpp.F90:1297
JqTermTLAD< MODEL > * initializeJqTLAD() const override
Definition: CostJbJq.h:170
boost::scoped_ptr< const Geometry_ > resol_
Definition: CostJbJq.h:96
Increment< MODEL > Increment_
Definition: CostJbJq.h:46
void Bmult(const Increment4D_ &, Increment4D_ &) const override
Multiply by and .
Definition: CostJbJq.h:198
void computeIncrement(const State4D_ &, const State4D_ &, Increment4D_ &) const override
Get increment from state (usually first guess).
Definition: CostJbJq.h:137
subroutine, public info(self)
Geometry< MODEL > Geometry_
Definition: CostJbJq.h:50
real(fp), parameter xb
Definition: ufo_aod_mod.F90:41
boost::ptr_vector< ModelSpaceCovarianceBase< MODEL > > B_
Definition: CostJbJq.h:91
virtual ~CostJbJq()
Destructor.
Definition: CostJbJq.h:58
void linearize(const State4D_ &, const Geometry_ &) override
Linearize before the linear computations.
Definition: CostJbJq.h:119
const Variables ctlvars_
Definition: CostJbJq.h:95
State increment.
Definition: CostJbState.h:28
Four dimensional state.
Definition: CostJbState.h:29
Increment_ * newStateIncrement(const unsigned int) const override
Definition: CostJbJq.h:244
Jb Cost Function Base Class.
Definition: CostJbState.h:41
ControlIncrement< MODEL > CtrlInc_
Definition: CostJbJq.h:49
const util::Duration subwin_
Definition: CostJbJq.h:93
std::vector< util::DateTime > times_
Definition: CostJbJq.h:97
Increment Class: Difference between two states.
bool checkStatesNumber(const unsigned int nn) const
Get model space control variable.
Definition: State4D.h:53
unsigned int nstates() const override
Create new increment (set to 0).
Definition: CostJbJq.h:87
void Bminv(const Increment4D_ &, Increment4D_ &) const override
Definition: CostJbJq.h:224
State4D< MODEL > State4D_
Definition: CostJbJq.h:47
const State4D_ & xb_
Definition: CostJbJq.h:92
JqTermTLAD< MODEL > * initializeJqTL() const override
Finalize after the TL run.
Definition: CostJbJq.h:177