FV3 Bundle
Increment4D.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_INCREMENT4D_H_
12 #define OOPS_ASSIMILATION_INCREMENT4D_H_
13 
14 #include <cmath>
15 #include <ostream>
16 #include <sstream>
17 #include <string>
18 #include <vector>
19 
20 #include <boost/ptr_container/ptr_map.hpp>
21 
22 #include "eckit/config/LocalConfiguration.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 #include "oops/util/Printable.h"
32 
33 namespace oops {
34 
35 /// State increment
36 /*!
37  * The state increment contains the increment to the 3D or 4D state part of
38  * the VDA control variable.
39  */
40 
41 // -----------------------------------------------------------------------------
42 template<typename MODEL> class Increment4D : public util::Printable {
47 
48  public:
49  static const std::string classname() {return "Increment4D";}
50 
51 /// Constructor, destructor
52  explicit Increment4D(const JbState_ &);
53  Increment4D(const Increment4D &, const bool copy = true);
54  Increment4D(const Increment4D &, const eckit::Configuration &);
55  Increment4D(const Geometry_ &, const Increment4D &);
56  ~Increment4D();
57 
58 /// Linear algebra operators
59  void diff(const State4D_ &, const State4D_ &);
60  void zero();
64  Increment4D & operator*=(const double);
65  void axpy(const double, const Increment4D &);
66  double dot_product_with(const Increment4D &) const;
67 
68 /// I/O and diagnostics
69  void read(const eckit::Configuration &);
70  void write(const eckit::Configuration &) const;
71 
72 /// Get geometry
73  Geometry_ geometry() const {return this->get(first_).geometry();}
74 
75 /// Get model space control variable
76  Increment_ & operator[](const int ii) {return this->get(ii);}
77  const Increment_ & operator[](const int ii) const {return this->get(ii);}
78  int first() const {return first_;}
79  int last() const {return last_;}
80 
81 /// To be removed
82  void shift_forward();
83  void shift_backward();
84 
85  private:
86  Increment_ & get(const int);
87  const Increment_ & get(const int) const;
88  void print(std::ostream &) const;
89 
90  typedef typename boost::ptr_map<int, Increment_>::iterator iter_;
91  typedef typename boost::ptr_map<int, Increment_>::const_iterator icst_;
92  boost::ptr_map<int, Increment_> incr4d_;
93  int first_;
94  int last_;
95 };
96 
97 // =============================================================================
98 
99 template<typename MODEL>
101  : incr4d_(), first_(0), last_(jb.nstates() - 1)
102 {
103  for (int jsub = 0; jsub <= last_; ++jsub) {
104  Increment_ * incr = jb.newStateIncrement(jsub);
105  incr4d_.insert(jsub, incr);
106  }
107  Log::trace() << "Increment4D:Increment4D created." << std::endl;
108 }
109 // -----------------------------------------------------------------------------
110 template<typename MODEL>
112  : incr4d_(), first_(other.first_), last_(other.last_)
113 {
114  for (icst_ jsub = other.incr4d_.begin(); jsub != other.incr4d_.end(); ++jsub) {
115  int isub = jsub->first;
116  Increment_ * tmp = new Increment_(*jsub->second, copy);
117  incr4d_.insert(isub, tmp);
118  }
119  Log::trace() << "Increment4D:Increment4D copied." << std::endl;
120 }
121 // -----------------------------------------------------------------------------
122 template<typename MODEL>
123 Increment4D<MODEL>::Increment4D(const Increment4D & other, const eckit::Configuration & tlConf)
124  : incr4d_(), first_(other.first_), last_(other.last_)
125 {
126  for (icst_ jsub = other.incr4d_.begin(); jsub != other.incr4d_.end(); ++jsub) {
127  int isub = jsub->first;
128  Increment_ * tmp = new Increment_(*jsub->second);
129  incr4d_.insert(isub, tmp);
130  }
131  Log::trace() << "Increment4D:Increment4D copied." << std::endl;
132 }
133 // -----------------------------------------------------------------------------
134 template<typename MODEL>
136  : incr4d_(), first_(other.first_), last_(other.last_)
137 {
138  for (icst_ jsub = other.incr4d_.begin(); jsub != other.incr4d_.end(); ++jsub) {
139  int isub = jsub->first;
140  Increment_ * tmp = new Increment_(geom, *jsub->second);
141  incr4d_.insert(isub, tmp);
142  }
143  Log::trace() << "Increment4D:Increment4D copied." << std::endl;
144 }
145 // -----------------------------------------------------------------------------
146 template<typename MODEL>
148  iter_ it = incr4d_.find(ii);
149  ASSERT(it != incr4d_.end());
150  return *it->second;
151 }
152 // -----------------------------------------------------------------------------
153 template<typename MODEL>
154 const Increment<MODEL> & Increment4D<MODEL>::get(const int ii) const {
155  icst_ it = incr4d_.find(ii);
156  ASSERT(it != incr4d_.end());
157  return *it->second;
158 }
159 // -----------------------------------------------------------------------------
160 template<typename MODEL>
162 // -----------------------------------------------------------------------------
163 template<typename MODEL>
165  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
166  jsub->second->zero();
167  }
168 }
169 // -----------------------------------------------------------------------------
170 template<typename MODEL>
171 void Increment4D<MODEL>::diff(const State4D_ & cv1, const State4D_ & cv2) {
172  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
173  jsub->second->diff(cv1[jsub->first], cv2[jsub->first]);
174  }
175 }
176 // -----------------------------------------------------------------------------
177 template<typename MODEL>
179  incr4d_ = rhs.incr4d_;
180  return *this;
181 }
182 // -----------------------------------------------------------------------------
183 template<typename MODEL>
185  for (int jsub = rhs.first(); jsub <= rhs.last(); ++jsub) {
186  this->get(jsub) += rhs[jsub];
187  }
188  return *this;
189 }
190 // -----------------------------------------------------------------------------
191 template<typename MODEL>
193  for (int jsub = rhs.first(); jsub <= rhs.last(); ++jsub) {
194  this->get(jsub) -= rhs[jsub];
195  }
196  return *this;
197 }
198 // -----------------------------------------------------------------------------
199 template<typename MODEL>
201  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
202  *jsub->second *= zz;
203  }
204  return *this;
205 }
206 // -----------------------------------------------------------------------------
207 template<typename MODEL>
208 void Increment4D<MODEL>::axpy(const double zz, const Increment4D & rhs) {
209  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
210  jsub->second->axpy(zz, rhs[jsub->first]);
211  }
212 }
213 // -----------------------------------------------------------------------------
214 template<typename MODEL>
215 void Increment4D<MODEL>::read(const eckit::Configuration & config) {
216  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
217  std::stringstream ss;
218  ss << jsub->first+1;
219  std::string query = "increment[@indx='" + ss.str() + "']";
220  eckit::LocalConfiguration fileConfig(config, query);
221  jsub->second->read(fileConfig);
222  Log::info() << "Increment4D:read increment" << *jsub->second << std::endl;
223  }
224 }
225 // -----------------------------------------------------------------------------
226 template<typename MODEL>
227 void Increment4D<MODEL>::write(const eckit::Configuration & config) const {
228  for (icst_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
229  jsub->second->write(config);
230  }
231 }
232 // -----------------------------------------------------------------------------
233 template <typename MODEL>
234 void Increment4D<MODEL>::print(std::ostream & outs) const {
235  for (icst_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
236  outs << *jsub->second << std::endl;
237  }
238 }
239 // -----------------------------------------------------------------------------
240 template<typename MODEL>
242  double zz = 0.0;
243  for (icst_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
244  zz += dot_product(*jsub->second, x2[jsub->first]);
245  }
246  return zz;
247 }
248 // -----------------------------------------------------------------------------
249 template<typename MODEL>
251  typedef typename boost::ptr_map<int, Increment_>::reverse_iterator rit;
252  for (rit jsub = incr4d_.rbegin(); jsub != incr4d_.rend(); ++jsub) {
253  const int isub = jsub->first;
254  if (isub > first_) this->get(isub) = this->get(isub-1);
255  }
256  incr4d_.erase(first_);
257  Log::info() << "Increment4D::shift_forward erased " << first_ << std::endl;
258  first_ += 1;
259 }
260 // -----------------------------------------------------------------------------
261 template<typename MODEL>
263  for (iter_ jsub = incr4d_.begin(); jsub != incr4d_.end(); ++jsub) {
264  const int isub = jsub->first;
265  if (isub < last_) this->get(isub) = this->get(isub+1);
266  }
267  incr4d_.erase(last_);
268  Log::info() << "Increment4D::shift_backward erased " << last_ << std::endl;
269  last_ -= 1;
270 }
271 // -----------------------------------------------------------------------------
272 } // namespace oops
273 
274 #endif // OOPS_ASSIMILATION_INCREMENT4D_H_
Increment4D(const JbState_ &)
Constructor, destructor.
Definition: Increment4D.h:100
CostJbState< MODEL > JbState_
Definition: Increment4D.h:45
State4D< MODEL > State4D_
Definition: Increment4D.h:46
int first() const
Definition: Increment4D.h:78
subroutine, public copy(self, rhs)
Increment4D & operator=(const Increment4D &)
Definition: Increment4D.h:178
void diff(const State4D_ &, const State4D_ &)
Linear algebra operators.
Definition: Increment4D.h:171
void print(std::ostream &) const
Definition: Increment4D.h:234
Geometry< MODEL > Geometry_
Definition: Increment4D.h:43
The namespace for the main oops code.
Increment4D & operator-=(const Increment4D &)
Definition: Increment4D.h:192
Increment4D & operator+=(const Increment4D &)
Definition: Increment4D.h:184
static const std::string classname()
Definition: Increment4D.h:49
void axpy(const double, const Increment4D &)
Definition: Increment4D.h:208
Increment_ & operator[](const int ii)
Get model space control variable.
Definition: Increment4D.h:76
virtual Increment_ * newStateIncrement(const unsigned int) const =0
subroutine, public info(self)
boost::ptr_map< int, Increment_ >::const_iterator icst_
Definition: Increment4D.h:91
State increment.
Definition: CostJbState.h:28
Four dimensional state.
Definition: CostJbState.h:29
boost::ptr_map< int, Increment_ >::iterator iter_
Definition: Increment4D.h:90
void read(const eckit::Configuration &)
I/O and diagnostics.
Definition: Increment4D.h:215
const Increment_ & operator[](const int ii) const
Definition: Increment4D.h:77
Increment4D & operator*=(const double)
Definition: Increment4D.h:200
Increment_ & get(const int)
Definition: Increment4D.h:147
Jb Cost Function Base Class.
Definition: CostJbState.h:41
int last() const
Definition: Increment4D.h:79
boost::ptr_map< int, Increment_ > incr4d_
Definition: Increment4D.h:92
Increment Class: Difference between two states.
Geometry_ geometry() const
Get geometry.
Definition: Increment4D.h:73
Increment< MODEL > Increment_
Definition: Increment4D.h:44
double dot_product_with(const Increment4D &) const
Definition: Increment4D.h:241
void write(const eckit::Configuration &) const
Definition: Increment4D.h:227
void shift_forward()
To be removed.
Definition: Increment4D.h:250