OOPS
ControlIncrement.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_CONTROLINCREMENT_H_
12 #define OOPS_ASSIMILATION_CONTROLINCREMENT_H_
13 
14 #include <cmath>
15 #include <ostream>
16 #include <sstream>
17 #include <string>
18 #include <vector>
19 
20 #include "eckit/config/Configuration.h"
21 #include "oops/base/Geometry.h"
22 #include "oops/base/Increment.h"
25 #include "oops/util/dot_product.h"
26 #include "oops/util/Logger.h"
27 #include "oops/util/ObjectCounter.h"
28 #include "oops/util/Printable.h"
29 #include "oops/util/Serializable.h"
30 
31 namespace oops {
32 
33 /// Control variable increment
34 /*!
35  * The control variable acts as a container for the inputs of the variational
36  * data assimilation cost functions in physical space.
37  * That includes the states at the start the assimilation window or of each
38  * sub-window but also additional variables such as model bias, VarBC
39  * coefficients, or other control variables for algorithms that use them.
40  * The control variable increment contains variations of the
41  * control variable.
42  */
43 
44 template<typename MODEL, typename OBS> class CostJbTotal;
45 
46 template<typename MODEL, typename OBS> class ControlIncrement;
47 
48 // -----------------------------------------------------------------------------
49 template<typename MODEL, typename OBS>
50 class ControlIncrement : public util::Printable,
51  public util::Serializable,
52  private util::ObjectCounter<ControlIncrement<MODEL, OBS> > {
58 
59  public:
60  static const std::string classname() {return "oops::ControlIncrement";}
61 
62 /// Constructor, destructor
63  explicit ControlIncrement(const JbTotal_ &);
64  ControlIncrement(const ControlIncrement &, const bool copy = true);
65  ControlIncrement(const ControlIncrement &, const eckit::Configuration &);
68 
69 /// Linear algebra operators
70  void zero();
74  ControlIncrement & operator*=(const double);
75  void axpy(const double, const ControlIncrement &);
76  double dot_product_with(const ControlIncrement &) const;
77 
78 /// I/O and diagnostics
79  void read(const eckit::Configuration &);
80  void write(const eckit::Configuration &) const;
81 
82 /// Get geometry
83  Geometry_ geometry() const {return increment_.geometry();}
84 
85 /// Get state control variable
86  Increment_ & state() {return increment_;}
87  const Increment_ & state() const {return increment_;}
88 
89 /// Get augmented model control variable
91  const ModelAuxIncr_ & modVar() const {return modbias_;}
92 
93 /// Get augmented observation control variable
95  const ObsAuxIncrs_ & obsVar() const {return obsbias_;}
96 
97 /// Serialize and deserialize ControlIncrement
98  size_t serialSize() const override;
99  void serialize(std::vector<double> &) const override;
100  void deserialize(const std::vector<double> &, size_t &) override;
101 
102  void shift_forward();
103  void shift_backward();
104 
105  private:
106  void print(std::ostream &) const override;
107 
109  ModelAuxIncr_ modbias_; // not only for bias, better name?
110  ObsAuxIncrs_ obsbias_; // not only for bias, better name?
111  const util::DateTime windowBegin_;
112  const util::DateTime windowEnd_;
113 };
114 
115 // =============================================================================
116 
117 template<typename MODEL, typename OBS>
119  : increment_(*jb.jbState().newStateIncrement()), // not good, extra copy
120  modbias_(jb.resolution(), jb.jbModBias().config()),
121  obsbias_(jb.jbObsBias().obspaces(), jb.jbObsBias().config()),
122  windowBegin_(jb.windowBegin()), windowEnd_(jb.windowEnd())
123 {
124  this->setObjectSize(this->serialSize()*sizeof(double));
125  Log::trace() << "ControlIncrement:ControlIncrement created." << std::endl;
126 }
127 // -----------------------------------------------------------------------------
128 template<typename MODEL, typename OBS>
130  : increment_(other.increment_, copy), modbias_(other.modbias_, copy),
131  obsbias_(other.obsbias_, copy), windowBegin_(other.windowBegin_), windowEnd_(other.windowEnd_)
132 {
133  this->setObjectSize(this->serialSize()*sizeof(double));
134  Log::trace() << "ControlIncrement:ControlIncrement copied." << std::endl;
135 }
136 // -----------------------------------------------------------------------------
137 template<typename MODEL, typename OBS>
139  const eckit::Configuration & tlConf)
140  : increment_(other.increment_, tlConf), modbias_(other.modbias_, tlConf),
141  obsbias_(other.obsbias_, tlConf), windowBegin_(other.windowBegin_), windowEnd_(other.windowEnd_)
142 {
143  this->setObjectSize(this->serialSize()*sizeof(double));
144  Log::trace() << "ControlIncrement:ControlIncrement copied." << std::endl;
145 }
146 // -----------------------------------------------------------------------------
147 template<typename MODEL, typename OBS>
149  const ControlIncrement & other)
150  : increment_(geom, other.increment_), modbias_(other.modbias_, true),
151  obsbias_(other.obsbias_, true), windowBegin_(other.windowBegin_), windowEnd_(other.windowEnd_)
152 {
153  this->setObjectSize(this->serialSize()*sizeof(double));
154  Log::trace() << "ControlIncrement:ControlIncrement copied." << std::endl;
155 }
156 // -----------------------------------------------------------------------------
157 template<typename MODEL, typename OBS>
159 // -----------------------------------------------------------------------------
160 template<typename MODEL, typename OBS> ControlIncrement<MODEL, OBS> &
162  increment_ = rhs.increment_;
163  modbias_ = rhs.modbias_;
164  obsbias_ = rhs.obsbias_;
165  return *this;
166 }
167 // -----------------------------------------------------------------------------
168 template<typename MODEL, typename OBS> ControlIncrement<MODEL, OBS> &
170  increment_ += rhs.increment_;
171  modbias_ += rhs.modbias_;
172  obsbias_ += rhs.obsbias_;
173  return *this;
174 }
175 // -----------------------------------------------------------------------------
176 template<typename MODEL, typename OBS> ControlIncrement<MODEL, OBS> &
178  increment_ -= rhs.increment_;
179  modbias_ -= rhs.modbias_;
180  obsbias_ -= rhs.obsbias_;
181  return *this;
182 }
183 // -----------------------------------------------------------------------------
184 template<typename MODEL, typename OBS>
186  increment_ *= zz;
187  modbias_ *= zz;
188  obsbias_ *= zz;
189  return *this;
190 }
191 // -----------------------------------------------------------------------------
192 template<typename MODEL, typename OBS>
194  increment_.zero();
195  modbias_.zero();
196  obsbias_.zero();
197 }
198 // -----------------------------------------------------------------------------
199 template<typename MODEL, typename OBS>
200 void ControlIncrement<MODEL, OBS>::axpy(const double zz, const ControlIncrement & rhs) {
201  increment_.axpy(zz, rhs.increment_);
202  modbias_.axpy(zz, rhs.modbias_);
203  obsbias_.axpy(zz, rhs.obsbias_);
204 }
205 // -----------------------------------------------------------------------------
206 template<typename MODEL, typename OBS>
207 void ControlIncrement<MODEL, OBS>::read(const eckit::Configuration & config) {
208  increment_.read(config);
209  modbias_.read(config);
210  obsbias_.read(config);
211 }
212 // -----------------------------------------------------------------------------
213 template<typename MODEL, typename OBS>
214 void ControlIncrement<MODEL, OBS>::write(const eckit::Configuration & config) const {
215  increment_.write(config);
216  modbias_.write(config);
217  obsbias_.write(config);
218 }
219 // -----------------------------------------------------------------------------
220 template <typename MODEL, typename OBS>
221 void ControlIncrement<MODEL, OBS>::print(std::ostream & outs) const {
222  outs << increment_;
223  outs << modbias_;
224  outs << obsbias_;
225 }
226 // -----------------------------------------------------------------------------
227 template<typename MODEL, typename OBS>
229  double zz = 0.0;
230  zz += dot_product(increment_, x2.increment_);
231  zz += dot_product(modbias_, x2.modbias_);
232  zz += dot_product(obsbias_, x2.obsbias_);
233  return zz;
234 }
235 // -----------------------------------------------------------------------------
236 template<typename MODEL, typename OBS>
238  size_t ss = 4;
239  ss += increment_.serialSize();
240  ss += modbias_.serialSize();
241  ss += obsbias_.serialSize();
242  return ss;
243 }
244 // -----------------------------------------------------------------------------
245 template<typename MODEL, typename OBS>
246 void ControlIncrement<MODEL, OBS>::serialize(std::vector<double> & vec) const {
247  vec.reserve(vec.size() + this->serialSize()); // allocate memory to avoid reallocations
248 
249  vec.push_back(-111.0);
250  increment_.serialize(vec);
251 
252  vec.push_back(-222.0);
253  modbias_.serialize(vec);
254 
255  vec.push_back(-333.0);
256  obsbias_.serialize(vec);
257 
258  vec.push_back(-444.0);
259 }
260 // -----------------------------------------------------------------------------
261 template<typename MODEL, typename OBS>
262 void ControlIncrement<MODEL, OBS>::deserialize(const std::vector<double> & vec, size_t & indx) {
263  ASSERT(vec.at(indx) == -111.0);
264  ++indx;
265 
266  increment_.deserialize(vec, indx);
267 
268  ASSERT(vec.at(indx) == -222.0);
269  ++indx;
270 
271  modbias_.deserialize(vec, indx);
272 
273  ASSERT(vec.at(indx) == -333.0);
274  ++indx;
275 
276  obsbias_.deserialize(vec, indx);
277  ASSERT(vec.at(indx) == -444.0);
278  ++indx;
279 }
280 // -----------------------------------------------------------------------------
281 template<typename MODEL, typename OBS>
283  increment_.shift_forward(windowBegin_);
284 // Probably needs some gathering of contributions for modbias_ and obsbias_
285 }
286 // -----------------------------------------------------------------------------
287 template<typename MODEL, typename OBS>
289  increment_.shift_backward(windowEnd_);
290 // Probably needs some gathering of contributions for modbias_ and obsbias_
291 }
292 // -----------------------------------------------------------------------------
293 
294 } // namespace oops
295 
296 #endif // OOPS_ASSIMILATION_CONTROLINCREMENT_H_
ObsAuxIncrs_ & obsVar()
Get augmented observation control variable.
void zero()
Linear algebra operators.
ControlIncrement & operator=(const ControlIncrement &)
Increment_ & state()
Get state control variable.
const util::DateTime windowEnd_
const util::DateTime windowBegin_
Increment< MODEL > Increment_
double dot_product_with(const ControlIncrement &) const
void deserialize(const std::vector< double > &, size_t &) override
const Increment_ & state() const
ModelAuxIncrement< MODEL > ModelAuxIncr_
ControlIncrement & operator-=(const ControlIncrement &)
Geometry_ geometry() const
Get geometry.
ControlIncrement(const JbTotal_ &)
Constructor, destructor.
const ModelAuxIncr_ & modVar() const
ControlIncrement & operator*=(const double)
ControlIncrement & operator+=(const ControlIncrement &)
Geometry< MODEL > Geometry_
CostJbTotal< MODEL, OBS > JbTotal_
const ObsAuxIncrs_ & obsVar() const
void write(const eckit::Configuration &) const
ObsAuxIncrements< OBS > ObsAuxIncrs_
void serialize(std::vector< double > &) const override
static const std::string classname()
void read(const eckit::Configuration &)
I/O and diagnostics.
ModelAuxIncr_ & modVar()
Get augmented model control variable.
size_t serialSize() const override
Serialize and deserialize ControlIncrement.
void axpy(const double, const ControlIncrement &)
void print(std::ostream &) const override
Control variable increment.
Definition: CostJbTotal.h:36
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
Auxiliary Increment related to model, not used at the moment.
Holds a vector of ObsAuxIncrement.
Geometry_ geometry() const
Accessor to geometry associated with this Increment.
The namespace for the main oops code.