IODA Bundle
oops/interface/Increment.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  * (C) Copyright 2017-2021 UCAR.
4  *
5  * This software is licensed under the terms of the Apache Licence Version 2.0
6  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
7  * In applying this licence, ECMWF does not waive the privileges and immunities
8  * granted to it by virtue of its status as an intergovernmental organisation nor
9  * does it submit to any jurisdiction.
10  */
11 
12 #ifndef OOPS_INTERFACE_INCREMENT_H_
13 #define OOPS_INTERFACE_INCREMENT_H_
14 
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "atlas/field.h"
20 
22 #include "oops/base/Geometry.h"
24 #include "oops/base/State.h"
25 #include "oops/base/Variables.h"
27 #include "oops/util/DateTime.h"
28 #include "oops/util/Duration.h"
29 #include "oops/util/ObjectCounter.h"
30 #include "oops/util/Serializable.h"
31 #include "oops/util/Timer.h"
32 
33 namespace oops {
34 
35 namespace interface {
36 
37 /// Increment: Difference between two model states.
38 /// Some fields that are present in a State may not be present in an Increment.
39 template <typename MODEL>
41  public util::Serializable,
42  private util::ObjectCounter<Increment<MODEL> > {
43  typedef typename MODEL::Increment Increment_;
47 
48  public:
49  static const std::string classname() {return "oops::Increment";}
50 
51  /// Constructor for specified \p geometry, with \p variables, valid on \p date
52  Increment(const Geometry_ & geometry, const Variables & variables, const util::DateTime & date);
53  /// Copies \p other increment, changing its resolution to \p geometry
54  Increment(const Geometry_ & geometry, const Increment & other);
55  /// Creates Increment with the same geometry and variables as \p other.
56  /// Copies \p other if \p copy is true, otherwise creates zero increment
57  Increment(const Increment &, const bool copy = true);
58 
59  /// Destructor (defined explicitly for timing and tracing)
60  virtual ~Increment();
61 
62  /// Set this Increment to be difference between \p state1 and \p state2
63  void diff(const State_ & state1, const State_ & state2);
64 
65  /// Accessor to the time of this Increment
66  const util::DateTime validTime() const {return increment_->validTime();}
67  /// Updates this Increment's valid time by \p dt (used in PseudoModel)
68  void updateTime(const util::Duration & dt) {increment_->updateTime(dt);}
69 
70  /// Zero out this Increment
71  void zero();
72  /// Zero out this Increment and set its date to \p date
73  void zero(const util::DateTime & date);
74  /// Set this Increment to ones (used in tests)
75  void ones();
76  /// Set Increment according to the configuration (used in Dirac application)
77  void dirac(const eckit::Configuration &);
78 
79  /// Assignment operator
80  Increment & operator =(const Increment &);
81  /// Linear algebra operators
82  Increment & operator+=(const Increment &);
83  Increment & operator-=(const Increment &);
84  Increment & operator*=(const double &);
85  /// Add \p w * \p dx to the Increment. If \p check is set, check whether this and \p dx's
86  /// dates are the same
87  void axpy(const double & w, const Increment & dx, const bool check = true);
88  /// Compute dot product of this Increment with \p other
89  double dot_product_with(const Increment & other) const;
90  /// Compute Schur product of this Increment with \p other, assign to this Increment
91  void schur_product_with(const Increment & other);
92 
93  /// Randomize the Increment (used in tests)
94  void random();
95  /// Accumulate (add \p w * \p x to the increment), used in WeightedDiff with Accumulator
96  void accumul(const double & w, const State_ & x);
97 
98  /// Read this Increment from file
99  void read(const eckit::Configuration &);
100  /// Write this Increment out to file
101  void write(const eckit::Configuration &) const;
102  /// Norm (used in tests)
103  double norm() const;
104 
105  /// Get local (at \p iter local volume) increment (used in LocalEnsembleSolver)
106  LocalIncrement getLocal(const GeometryIterator_ & iter) const;
107  /// Set local (at \p iter local volume) increment to be \p gp (used in LocalEnsembleSolver)
108  void setLocal(const LocalIncrement & gp, const GeometryIterator_ & iter);
109 
110  /// Accessor to geometry associated with this Increment
111  Geometry_ geometry() const;
112 
113  /// ATLAS FieldSet (used in SABER)
114  void setAtlas(atlas::FieldSet *) const;
115  void toAtlas(atlas::FieldSet *) const;
116  void fromAtlas(atlas::FieldSet *);
117 
118  /// Serialize and deserialize (used in 4DEnVar, weak-constraint 4DVar and Block-Lanczos minimizer)
119  size_t serialSize() const override;
120  void serialize(std::vector<double> &) const override;
121  void deserialize(const std::vector<double> &, size_t &) override;
122 
123  /// Accessor to MODEL::Increment, used in the other interface classes in oops.
124  /// Does not need to be implemented.
125  const Increment_ & increment() const {return *this->increment_;}
126  Increment_ & increment() {return *this->increment_;}
127 
128  protected:
129  std::unique_ptr<Increment_> increment_; /// pointer to the Increment implementation
130 
131  private:
132  void print(std::ostream &) const override;
133 };
134 
135 // -----------------------------------------------------------------------------
136 
137 template<typename MODEL>
138 Increment<MODEL>::Increment(const Geometry_ & resol, const Variables & vars,
139  const util::DateTime & time)
140  : increment_()
141 {
142  Log::trace() << "Increment<MODEL>::Increment starting" << std::endl;
143  util::Timer timer(classname(), "Increment");
144  increment_.reset(new Increment_(resol.geometry(), vars, time));
145  this->setObjectSize(increment_->serialSize()*sizeof(double));
146  Log::trace() << "Increment<MODEL>::Increment done" << std::endl;
147 }
148 
149 // -----------------------------------------------------------------------------
150 
151 template<typename MODEL>
152 Increment<MODEL>::Increment(const Geometry_ & resol, const Increment & other)
153  : increment_()
154 {
155  Log::trace() << "Increment<MODEL>::Increment starting" << std::endl;
156  util::Timer timer(classname(), "Increment");
157  increment_.reset(new Increment_(resol.geometry(), *other.increment_));
158  this->setObjectSize(increment_->serialSize()*sizeof(double));
159  Log::trace() << "Increment<MODEL>::Increment done" << std::endl;
160 }
161 
162 // -----------------------------------------------------------------------------
163 
164 template<typename MODEL>
165 Increment<MODEL>::Increment(const Increment & other, const bool copy)
166  : increment_()
167 {
168  Log::trace() << "Increment<MODEL>::Increment copy starting" << std::endl;
169  util::Timer timer(classname(), "Increment");
170  increment_.reset(new Increment_(*other.increment_, copy));
171  this->setObjectSize(increment_->serialSize()*sizeof(double));
172  Log::trace() << "Increment<MODEL>::Increment copy done" << std::endl;
173 }
174 
175 // -----------------------------------------------------------------------------
176 
177 template<typename MODEL>
179  Log::trace() << "Increment<MODEL>::~Increment starting" << std::endl;
180  util::Timer timer(classname(), "~Increment");
181  increment_.reset();
182  Log::trace() << "Increment<MODEL>::~Increment done" << std::endl;
183 }
184 
185 // -----------------------------------------------------------------------------
186 
187 template<typename MODEL>
188 void Increment<MODEL>::diff(const State_ & x1, const State_ & x2) {
189  Log::trace() << "Increment<MODEL>::diff starting" << std::endl;
190  util::Timer timer(classname(), "diff");
191  increment_->diff(x1.state(), x2.state());
192  Log::trace() << "Increment<MODEL>::diff done" << std::endl;
193 }
194 
195 // -----------------------------------------------------------------------------
196 
197 template<typename MODEL>
199  Log::trace() << "Increment<MODEL>::zero starting" << std::endl;
200  util::Timer timer(classname(), "zero");
201  increment_->zero();
202  Log::trace() << "Increment<MODEL>::zero done" << std::endl;
203 }
204 
205 // -----------------------------------------------------------------------------
206 
207 template<typename MODEL>
208 void Increment<MODEL>::zero(const util::DateTime & tt) {
209  Log::trace() << "Increment<MODEL>::zero starting" << std::endl;
210  util::Timer timer(classname(), "zero");
211  increment_->zero(tt);
212  Log::trace() << "Increment<MODEL>::zero done" << std::endl;
213 }
214 
215 // -----------------------------------------------------------------------------
216 
217 template<typename MODEL>
219  Log::trace() << "Increment<MODEL>::ones starting" << std::endl;
220  util::Timer timer(classname(), "ones");
221  increment_->ones();
222  Log::trace() << "Increment<MODEL>::ones done" << std::endl;
223 }
224 
225 // -----------------------------------------------------------------------------
226 
227 template<typename MODEL>
228 void Increment<MODEL>::dirac(const eckit::Configuration & config) {
229  Log::trace() << "Increment<MODEL>::dirac starting" << std::endl;
230  util::Timer timer(classname(), "dirac");
231  increment_->dirac(config);
232  Log::trace() << "Increment<MODEL>::dirac done" << std::endl;
233 }
234 
235 // -----------------------------------------------------------------------------
236 
237 template<typename MODEL>
239  Log::trace() << "Increment<MODEL>::operator= starting" << std::endl;
240  util::Timer timer(classname(), "operator=");
241  *increment_ = *rhs.increment_;
242  Log::trace() << "Increment<MODEL>::operator= done" << std::endl;
243  return *this;
244 }
245 
246 // -----------------------------------------------------------------------------
247 
248 template<typename MODEL>
250  Log::trace() << "Increment<MODEL>::operator+= starting" << std::endl;
251  util::Timer timer(classname(), "operator+=");
252  *increment_ += *rhs.increment_;
253  Log::trace() << "Increment<MODEL>::operator+= done" << std::endl;
254  return *this;
255 }
256 
257 // -----------------------------------------------------------------------------
258 
259 template<typename MODEL>
261  Log::trace() << "Increment<MODEL>::operator-= starting" << std::endl;
262  util::Timer timer(classname(), "operator-=");
263  *increment_ -= *rhs.increment_;
264  Log::trace() << "Increment<MODEL>::operator-= done" << std::endl;
265  return *this;
266 }
267 
268 // -----------------------------------------------------------------------------
269 
270 template<typename MODEL>
272  Log::trace() << "Increment<MODEL>::operator*= starting" << std::endl;
273  util::Timer timer(classname(), "operator*=");
274  *increment_ *= zz;
275  Log::trace() << "Increment<MODEL>::operator*= done" << std::endl;
276  return *this;
277 }
278 
279 // -----------------------------------------------------------------------------
280 
281 template<typename MODEL>
282 void Increment<MODEL>::axpy(const double & zz, const Increment & dx, const bool check) {
283  Log::trace() << "Increment<MODEL>::axpy starting" << std::endl;
284  util::Timer timer(classname(), "axpy");
285  increment_->axpy(zz, *dx.increment_, check);
286  Log::trace() << "Increment<MODEL>::axpy done" << std::endl;
287 }
288 
289 // -----------------------------------------------------------------------------
290 
291 template<typename MODEL>
293  Log::trace() << "Increment<MODEL>::dot_product_with starting" << std::endl;
294  util::Timer timer(classname(), "dot_product_with");
295  double zz = increment_->dot_product_with(*dx.increment_);
296  Log::trace() << "Increment<MODEL>::dot_product_with done" << std::endl;
297  return zz;
298 }
299 
300 // -----------------------------------------------------------------------------
301 
302 template<typename MODEL>
304  Log::trace() << "Increment<MODEL>::schur_product_with starting" << std::endl;
305  util::Timer timer(classname(), "schur_product_with");
306  increment_->schur_product_with(*dx.increment_);
307  Log::trace() << "Increment<MODEL>::schur_product_with done" << std::endl;
308 }
309 
310 // -----------------------------------------------------------------------------
311 
312 template<typename MODEL>
314  Log::trace() << "Increment<MODEL>::random starting" << std::endl;
315  util::Timer timer(classname(), "random");
316  increment_->random();
317  Log::trace() << "Increment<MODEL>::random done" << std::endl;
318 }
319 
320 // -----------------------------------------------------------------------------
321 
322 template<typename MODEL>
323 void Increment<MODEL>::accumul(const double & zz, const State_ & xx) {
324  Log::trace() << "Increment<MODEL>::accumul starting" << std::endl;
325  util::Timer timer(classname(), "accumul");
326  increment_->accumul(zz, xx.state());
327  Log::trace() << "Increment<MODEL>::accumul done" << std::endl;
328 }
329 
330 // -----------------------------------------------------------------------------
331 
332 template<typename MODEL>
334  Log::trace() << "Increment<MODEL>::getLocal starting" << std::endl;
335  util::Timer timer(classname(), "getLocal");
336  LocalIncrement gp = increment_->getLocal(iter.geometryiter());
337  Log::trace() << "Increment<MODEL>::getLocal done" << std::endl;
338  return gp;
339 }
340 
341 // -----------------------------------------------------------------------------
342 template<typename MODEL>
344  const GeometryIterator_ & iter) {
345  Log::trace() << "Increment<MODEL>::setLocal starting" << std::endl;
346  util::Timer timer(classname(), "setLocal");
347  increment_->setLocal(gp, iter.geometryiter());
348  Log::trace() << "Increment<MODEL>::setLocal done" << std::endl;
349 }
350 
351 // -----------------------------------------------------------------------------
352 
353 template<typename MODEL>
354 void Increment<MODEL>::read(const eckit::Configuration & conf) {
355  Log::trace() << "Increment<MODEL>::read starting" << std::endl;
356  util::Timer timer(classname(), "read");
357  increment_->read(conf);
358  Log::trace() << "Increment<MODEL>::read done" << std::endl;
359 }
360 
361 // -----------------------------------------------------------------------------
362 
363 template<typename MODEL>
364 void Increment<MODEL>::write(const eckit::Configuration & conf) const {
365  Log::trace() << "Increment<MODEL>::write starting" << std::endl;
366  util::Timer timer(classname(), "write");
367  increment_->write(conf);
368  Log::trace() << "Increment<MODEL>::write done" << std::endl;
369 }
370 
371 // -----------------------------------------------------------------------------
372 
373 template<typename MODEL>
374 double Increment<MODEL>::norm() const {
375  Log::trace() << "Increment<MODEL>::norm starting" << std::endl;
376  util::Timer timer(classname(), "norm");
377  double zz = increment_->norm();
378  Log::trace() << "Increment<MODEL>::norm done" << std::endl;
379  return zz;
380 }
381 
382 // -----------------------------------------------------------------------------
383 
384 template<typename MODEL>
386  Log::trace() << "Increment<MODEL>::geometry starting" << std::endl;
387  util::Timer timer(classname(), "geometry");
388  oops::Geometry<MODEL> geom(increment_->geometry());
389  Log::trace() << "Increment<MODEL>::geometry done" << std::endl;
390  return geom;
391 }
392 
393 // -----------------------------------------------------------------------------
394 
395 template<typename MODEL>
396 void Increment<MODEL>::setAtlas(atlas::FieldSet * atlasFieldSet) const {
397  Log::trace() << "Increment<MODEL>::setAtlas starting" << std::endl;
398  util::Timer timer(classname(), "setAtlas");
399  increment_->setAtlas(atlasFieldSet);
400  Log::trace() << "Increment<MODEL>::setAtlas done" << std::endl;
401 }
402 
403 // -----------------------------------------------------------------------------
404 
405 template<typename MODEL>
406 void Increment<MODEL>::toAtlas(atlas::FieldSet * atlasFieldSet) const {
407  Log::trace() << "Increment<MODEL>::toAtlas starting" << std::endl;
408  util::Timer timer(classname(), "toAtlas");
409  increment_->toAtlas(atlasFieldSet);
410  Log::trace() << "Increment<MODEL>::toAtlas done" << std::endl;
411 }
412 
413 // -----------------------------------------------------------------------------
414 
415 template<typename MODEL>
416 void Increment<MODEL>::fromAtlas(atlas::FieldSet * atlasFieldSet) {
417  Log::trace() << "Increment<MODEL>::fromAtlas starting" << std::endl;
418  util::Timer timer(classname(), "fromAtlas");
419  increment_->fromAtlas(atlasFieldSet);
420  Log::trace() << "Increment<MODEL>::fromAtlas done" << std::endl;
421 }
422 
423 // -----------------------------------------------------------------------------
424 
425 template<typename MODEL>
427  Log::trace() << "Increment<MODEL>::serialSize" << std::endl;
428  util::Timer timer(classname(), "serialSize");
429  return increment_->serialSize();
430 }
431 
432 // -----------------------------------------------------------------------------
433 
434 template<typename MODEL>
435 void Increment<MODEL>::serialize(std::vector<double> & vect) const {
436  Log::trace() << "Increment<MODEL>::serialize starting" << std::endl;
437  util::Timer timer(classname(), "serialize");
438  increment_->serialize(vect);
439  Log::trace() << "Increment<MODEL>::serialize done" << std::endl;
440 }
441 
442 // -----------------------------------------------------------------------------
443 
444 template<typename MODEL>
445 void Increment<MODEL>::deserialize(const std::vector<double> & vect, size_t & current) {
446  Log::trace() << "Increment<MODEL>::Increment deserialize starting" << std::endl;
447  util::Timer timer(classname(), "deserialize");
448  increment_->deserialize(vect, current);
449  Log::trace() << "Increment<MODEL>::Increment deserialize done" << std::endl;
450 }
451 
452 // -----------------------------------------------------------------------------
453 
454 template<typename MODEL>
455 void Increment<MODEL>::print(std::ostream & os) const {
456  Log::trace() << "Increment<MODEL>::print starting" << std::endl;
457  util::Timer timer(classname(), "print");
458  os << *increment_;
459  Log::trace() << "Increment<MODEL>::print done" << std::endl;
460 }
461 
462 // -----------------------------------------------------------------------------
463 
464 } // namespace interface
465 
466 } // namespace oops
467 
468 #endif // OOPS_INTERFACE_INCREMENT_H_
Abstract base class for quantities.
Geometry class used in oops; subclass of interface class interface::Geometry.
const GeometryIterator_ & geometryiter() const
Interfacing.
State class used in oops; subclass of interface class interface::State.
const Geometry_ & geometry() const
void setLocal(const LocalIncrement &gp, const GeometryIterator_ &iter)
Set local (at iter local volume) increment to be gp (used in LocalEnsembleSolver)
void axpy(const double &w, const Increment &dx, const bool check=true)
const Increment_ & increment() const
void deserialize(const std::vector< double > &, size_t &) override
Increment & operator*=(const double &)
void dirac(const eckit::Configuration &)
Set Increment according to the configuration (used in Dirac application)
void updateTime(const util::Duration &dt)
Updates this Increment's valid time by dt (used in PseudoModel)
static const std::string classname()
void schur_product_with(const Increment &other)
Compute Schur product of this Increment with other, assign to this Increment.
void fromAtlas(atlas::FieldSet *)
void setAtlas(atlas::FieldSet *) const
ATLAS FieldSet (used in SABER)
Increment(const Geometry_ &geometry, const Variables &variables, const util::DateTime &date)
Constructor for specified geometry, with variables, valid on date.
Increment & operator+=(const Increment &)
Linear algebra operators.
void random()
Randomize the Increment (used in tests)
virtual ~Increment()
Destructor (defined explicitly for timing and tracing)
LocalIncrement getLocal(const GeometryIterator_ &iter) const
Get local (at iter local volume) increment (used in LocalEnsembleSolver)
void read(const eckit::Configuration &)
Read this Increment from file.
Geometry_ geometry() const
Accessor to geometry associated with this Increment.
Increment & operator-=(const Increment &)
GeometryIterator< MODEL > GeometryIterator_
void toAtlas(atlas::FieldSet *) const
void diff(const State_ &state1, const State_ &state2)
Set this Increment to be difference between state1 and state2.
double dot_product_with(const Increment &other) const
Compute dot product of this Increment with other.
double norm() const
Norm (used in tests)
void serialize(std::vector< double > &) const override
oops::Geometry< MODEL > Geometry_
void accumul(const double &w, const State_ &x)
Accumulate (add w * x to the increment), used in WeightedDiff with Accumulator.
std::unique_ptr< Increment_ > increment_
void print(std::ostream &) const override
pointer to the Increment implementation
void write(const eckit::Configuration &) const
Write this Increment out to file.
Increment & operator=(const Increment &)
Assignment operator.
void zero()
Zero out this Increment.
void ones()
Set this Increment to ones (used in tests)
size_t serialSize() const override
Serialize and deserialize (used in 4DEnVar, weak-constraint 4DVar and Block-Lanczos minimizer)
const util::DateTime validTime() const
Accessor to the time of this Increment.
State_ & state()
Accessor.
subroutine check(status)
IODA_DL void copy(const ObjectSelection &from, ObjectSelection &to, const ScaleMapping &scale_map)
Generic data copying function.
Definition: Copying.cpp:63
The namespace for the main oops code.