FV3 Bundle
CostJb4D.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_COSTJB4D_H_
12 #define OOPS_ASSIMILATION_COSTJB4D_H_
13 
14 #include <memory>
15 #include <vector>
16 #include <boost/ptr_container/ptr_vector.hpp>
17 #include <boost/scoped_ptr.hpp>
18 
19 #include "eckit/config/LocalConfiguration.h"
24 #include "oops/base/Variables.h"
27 #include "oops/util/DateTime.h"
28 #include "oops/util/dot_product.h"
29 #include "oops/util/Duration.h"
30 #include "oops/util/Logger.h"
31 
32 namespace oops {
33  template<typename MODEL> class ControlIncrement;
34  template<typename MODEL> class JqTerm;
35  template<typename MODEL> class JqTermTLAD;
36 
37 // -----------------------------------------------------------------------------
38 
39 /// 4D Jb Cost Function
40 /*!
41  * CostJb4D encapsulates the generalized four dimensional Jb term of
42  * the 4D-Ens-Var cost function.
43  */
44 
45 template<typename MODEL> class CostJb4D : public CostJbState<MODEL> {
51 
52  public:
53 /// Construct \f$ J_b\f$.
54  CostJb4D(const eckit::Configuration &, const Geometry_ &, const Variables &,
55  const util::Duration &, const State4D_ &);
56 
57 /// Destructor
58  virtual ~CostJb4D() {}
59 
60 /// Empty Jq observer.
61  JqTerm<MODEL> * initializeJq() const override {return 0;}
62  JqTermTLAD<MODEL> * initializeJqTLAD() const override {return 0;}
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 /// Empty TL Jq observer.
74  JqTermTLAD<MODEL> * initializeJqTL() const override {return 0;}
75 
76 /// Empty AD Jq observer.
77  JqTermTLAD<MODEL> * initializeJqAD(const Increment4D_ &) const override {return 0;}
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  const State4D_ & xb_;
92  boost::ptr_vector< ModelSpaceCovarianceBase<MODEL> > B_;
94  boost::scoped_ptr<const Geometry_> resol_;
95  std::vector<util::DateTime> times_;
96  const eckit::LocalConfiguration conf_;
97 };
98 
99 // =============================================================================
100 
101 // Generalized Jb Term of Cost Function
102 // -----------------------------------------------------------------------------
103 
104 template<typename MODEL>
105 CostJb4D<MODEL>::CostJb4D(const eckit::Configuration & config, const Geometry_ &,
106  const Variables & ctlvars, const util::Duration &, const State4D_ & xb)
107  : xb_(xb), B_(), ctlvars_(ctlvars), resol_(), times_(), conf_(config, "Covariance")
108 {
109  Log::trace() << "CostJb4D contructed." << std::endl;
110 }
111 
112 // -----------------------------------------------------------------------------
113 
114 template<typename MODEL>
115 void CostJb4D<MODEL>::linearize(const State4D_ & fg, const Geometry_ & lowres) {
116  ASSERT(fg.checkStatesNumber(xb_.size()));
117  resol_.reset(new Geometry_(lowres));
118  times_.clear();
119  B_.clear();
120  std::vector<eckit::LocalConfiguration> confs;
121  conf_.get("covariance_time", confs);
122  for (unsigned jsub = 0; jsub < fg.size(); ++jsub) {
123  B_.push_back(CovarianceFactory<MODEL>::create(confs[jsub], lowres, ctlvars_,
124  xb_[jsub], fg[jsub]));
125  times_.push_back(fg[jsub].validTime());
126  }
127  ASSERT(fg.checkStatesNumber(B_.size()));
128 }
129 
130 // -----------------------------------------------------------------------------
131 
132 template<typename MODEL>
134  Increment4D_ & dx) const {
135  dx.diff(fg, xb);
136 }
137 
138 // -----------------------------------------------------------------------------
139 
140 template<typename MODEL>
142  Increment4D_ & gradJb) const {
143  grad += gradJb;
144 }
145 
146 // -----------------------------------------------------------------------------
147 
148 template<typename MODEL>
149 void CostJb4D<MODEL>::Bmult(const Increment4D_ & dxin, Increment4D_ & dxout) const {
150  for (unsigned k1 = 0; k1 < B_.size(); ++k1) {
151  // Apply the line k1 of the whole B matrix to the StateIncrement dxin
152  // Result is the part of dxout at time k1
153  dxout[k1].zero();
154  Increment_ dout(dxout[k1]);
155  for (unsigned k2 = 0; k2 < B_.size(); ++k2) {
156  // Apply to increment at time k2 the block B_k1k2 of the whole B matrix.
157  // We need an object B which is also at time k2
158  // Result "dout" is an increment at time k1
159  B_[k2].multiply(dxin[k2], dout);
160  dxout[k1] += dout;
161  }
162  }
163 }
164 
165 // -----------------------------------------------------------------------------
166 
167 template<typename MODEL>
168 void CostJb4D<MODEL>::Bminv(const Increment4D_ & dxin, Increment4D_ & dxout) const {
169  Log::warning() << "*** B inverse might not always exist ***" << std::endl;
170  for (unsigned jsub = 0; jsub < B_.size(); ++jsub) {
171  B_[jsub].inverseMultiply(dxin[jsub], dxout[jsub]);
172  }
173  Log::warning() << "*** B inverse might not always exist ***" << std::endl;
174 }
175 
176 // -----------------------------------------------------------------------------
177 
178 template<typename MODEL>
180  for (unsigned jsub = 0; jsub < B_.size(); ++jsub) {
181  B_[jsub].randomize(dx[jsub]);
182  }
183 }
184 
185 // -----------------------------------------------------------------------------
186 
187 template<typename MODEL>
189 CostJb4D<MODEL>::newStateIncrement(const unsigned int isub) const {
190  Increment_ * incr = new Increment_(*resol_, ctlvars_, times_[isub]);
191  return incr;
192 }
193 
194 // -----------------------------------------------------------------------------
195 
196 } // namespace oops
197 
198 #endif // OOPS_ASSIMILATION_COSTJB4D_H_
integer, parameter, public warning
boost::scoped_ptr< const Geometry_ > resol_
Definition: CostJb4D.h:94
const State4D_ & xb_
Definition: CostJb4D.h:91
void diff(const State4D_ &, const State4D_ &)
Linear algebra operators.
Definition: Increment4D.h:171
JqTermTLAD< MODEL > * initializeJqTL() const override
Empty TL Jq observer.
Definition: CostJb4D.h:74
std::vector< util::DateTime > times_
Definition: CostJb4D.h:95
void linearize(const State4D_ &, const Geometry_ &) override
Linearize before the linear computations.
Definition: CostJb4D.h:115
The namespace for the main oops code.
State4D< MODEL > State4D_
Definition: CostJb4D.h:47
Increment4D< MODEL > Increment4D_
Definition: CostJb4D.h:48
Increment< MODEL > Increment_
Definition: CostJb4D.h:46
Increment_ * newStateIncrement(const unsigned int) const override
Definition: CostJb4D.h:189
CostJb4D(const eckit::Configuration &, const Geometry_ &, const Variables &, const util::Duration &, const State4D_ &)
Construct .
Definition: CostJb4D.h:105
real(fp), parameter xb
Definition: ufo_aod_mod.F90:41
const Variables ctlvars_
Definition: CostJb4D.h:93
size_t size() const
Definition: State4D.h:54
void Bminv(const Increment4D_ &, Increment4D_ &) const override
Definition: CostJb4D.h:168
void randomize(Increment4D_ &) const override
Randomize.
Definition: CostJb4D.h:179
State increment.
Definition: CostJbState.h:28
Four dimensional state.
Definition: CostJbState.h:29
virtual ~CostJb4D()
Destructor.
Definition: CostJb4D.h:58
boost::ptr_vector< ModelSpaceCovarianceBase< MODEL > > B_
Definition: CostJb4D.h:92
Jb Cost Function Base Class.
Definition: CostJbState.h:41
void addGradient(const Increment4D_ &, Increment4D_ &, Increment4D_ &) const override
Add Jb gradient.
Definition: CostJb4D.h:141
JqTermTLAD< MODEL > * initializeJqTLAD() const override
Definition: CostJb4D.h:62
unsigned int nstates() const override
Create new increment (set to 0).
Definition: CostJb4D.h:87
Geometry< MODEL > Geometry_
Definition: CostJb4D.h:50
Increment Class: Difference between two states.
JqTermTLAD< MODEL > * initializeJqAD(const Increment4D_ &) const override
Empty AD Jq observer.
Definition: CostJb4D.h:77
ControlIncrement< MODEL > CtrlInc_
Definition: CostJb4D.h:49
bool checkStatesNumber(const unsigned int nn) const
Get model space control variable.
Definition: State4D.h:53
4D Jb Cost Function
Definition: CostJb4D.h:45
void Bmult(const Increment4D_ &, Increment4D_ &) const override
Multiply by and .
Definition: CostJb4D.h:149
JqTerm< MODEL > * initializeJq() const override
Empty Jq observer.
Definition: CostJb4D.h:61
void computeIncrement(const State4D_ &, const State4D_ &, Increment4D_ &) const override
Get increment from state (usually first guess).
Definition: CostJb4D.h:133
const eckit::LocalConfiguration conf_
Definition: CostJb4D.h:96