OOPS
ObsAuxIncrements.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2017-2019 UCAR
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  */
7 
8 #ifndef OOPS_BASE_OBSAUXINCREMENTS_H_
9 #define OOPS_BASE_OBSAUXINCREMENTS_H_
10 
11 #include <iostream>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
17 #include "oops/base/ObsSpaces.h"
19 #include "oops/util/Logger.h"
20 #include "oops/util/ObjectCounter.h"
21 #include "oops/util/Printable.h"
22 #include "oops/util/Serializable.h"
23 
24 namespace oops {
25 
26 // -----------------------------------------------------------------------------
27 /// \brief Holds a vector of ObsAuxIncrement
28 // -----------------------------------------------------------------------------
29 
30 template <typename OBS>
31 class ObsAuxIncrements : public util::Printable,
32  public util::Serializable,
33  private util::ObjectCounter<ObsAuxIncrements<OBS> > {
37 
38  public:
39  static const std::string classname() {return "oops::ObsAuxIncrements";}
40 
41 /// Constructor, destructor
42  ObsAuxIncrements(const ObsSpaces_ &, const eckit::Configuration &);
43  ObsAuxIncrements(const ObsAuxIncrements &, const bool copy = true);
45 
46 /// Access
47  std::size_t size() const {return auxs_.size();}
48  const ObsAuxIncrement_ & operator[](const std::size_t ii) const {return *auxs_.at(ii);}
49  ObsAuxIncrement_ & operator[](const std::size_t ii) {return *auxs_.at(ii);}
50 
51 /// Linear algebra operators
52  void diff(const ObsAuxControls_ &, const ObsAuxControls_ &);
53  void zero();
57  ObsAuxIncrements & operator*=(const double &);
58  void axpy(const double &, const ObsAuxIncrements &);
59  double dot_product_with(const ObsAuxIncrements &) const;
60 
61 /// I/O and diagnostics
62  void read(const eckit::Configuration &);
63  void write(const eckit::Configuration &) const;
64  double norm() const;
65 
66 /// Serialize-Deserialize
67  size_t serialSize() const override;
68  void serialize(std::vector<double> &) const override;
69  void deserialize(const std::vector<double> &, size_t &) override;
70 
71  private:
72  void print(std::ostream &) const override;
73  std::vector<std::unique_ptr<ObsAuxIncrement_> > auxs_;
74 };
75 
76 // -----------------------------------------------------------------------------
77 
78 template <typename OBS>
80  Log::trace() << "operator+=(ObsAuxControls, ObsAuxIncrements) starting" << std::endl;
81  ASSERT(xx.size() == dx.size());
82  for (std::size_t jobs = 0; jobs < xx.size(); ++jobs) {
83  xx[jobs].obsauxcontrol() += dx[jobs].obsauxincrement();
84  }
85  Log::trace() << "operator+=(ObsAuxControls, ObsAuxIncrements) done" << std::endl;
86  return xx;
87 }
88 
89 // =============================================================================
90 
91 template<typename OBS>
92 ObsAuxIncrements<OBS>::ObsAuxIncrements(const ObsSpaces_ & odb, const eckit::Configuration & conf)
93  : auxs_(0)
94 {
95  Log::trace() << "ObsAuxIncrements<OBS>::ObsAuxIncrements starting" << std::endl;
96  size_t bytes = 0;
97  std::vector<eckit::LocalConfiguration> obsconf = conf.getSubConfigurations();
98  for (std::size_t jobs = 0; jobs < obsconf.size(); ++jobs) {
99  eckit::LocalConfiguration obsauxconf = obsconf[jobs].getSubConfiguration("obs bias");
100  typename ObsAuxIncrement_::Parameters_ obsauxparams;
101  obsauxparams.validateAndDeserialize(obsauxconf);
102  auxs_.push_back(
103  std::unique_ptr<ObsAuxIncrement_>(new ObsAuxIncrement_(odb[jobs], obsauxparams)));
104  bytes += auxs_[jobs]->serialSize();
105  }
106  this->setObjectSize(bytes*sizeof(double));
107  Log::trace() << "ObsAuxIncrements<OBS>::ObsAuxIncrements done" << std::endl;
108 }
109 // -----------------------------------------------------------------------------
110 template<typename OBS>
112  : auxs_(other.size())
113 {
114  Log::trace() << "ObsAuxIncrements<OBS>::ObsAuxIncrements copy starting" << std::endl;
115  size_t bytes = 0;
116  ASSERT(size() == other.size());
117  for (std::size_t jobs = 0; jobs < other.size(); ++jobs) {
118  auxs_[jobs].reset(new ObsAuxIncrement_(other[jobs], copy));
119  bytes += auxs_[jobs]->serialSize();
120  }
121  this->setObjectSize(bytes*sizeof(double));
122  Log::trace() << "ObsAuxIncrements<OBS>::ObsAuxIncrements copy done" << std::endl;
123 }
124 // -----------------------------------------------------------------------------
125 template<typename OBS>
127  Log::trace() << "ObsAuxIncrements<OBS>::~ObsAuxIncrements starting" << std::endl;
128  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) auxs_[jobs].reset();
129  Log::trace() << "ObsAuxIncrements<OBS>::~ObsAuxIncrements done" << std::endl;
130 }
131 // -----------------------------------------------------------------------------
132 template<typename OBS>
134  Log::trace() << "ObsAuxIncrements<OBS>::diff starting" << std::endl;
135  ASSERT(x1.size() == x2.size() && size() == x2.size());
136  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
137  auxs_[jobs]->diff(x1[jobs], x2[jobs]);
138  }
139  Log::trace() << "ObsAuxIncrements<OBS>::diff done" << std::endl;
140 }
141 // -----------------------------------------------------------------------------
142 template<typename OBS>
144  Log::trace() << "ObsAuxIncrements<OBS>::zero starting" << std::endl;
145  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
146  auxs_[jobs]->zero();
147  }
148  Log::trace() << "ObsAuxIncrements<OBS>::zero done" << std::endl;
149 }
150 // -----------------------------------------------------------------------------
151 template<typename OBS>
153  Log::trace() << "ObsAuxIncrements<OBS>::operator= starting" << std::endl;
154  ASSERT(size() == rhs.size());
155  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
156  *auxs_[jobs] = rhs[jobs];
157  }
158  Log::trace() << "ObsAuxIncrements<OBS>::operator= done" << std::endl;
159  return *this;
160 }
161 // -----------------------------------------------------------------------------
162 template<typename OBS>
164  Log::trace() << "ObsAuxIncrements<OBS>::operator+= starting" << std::endl;
165  ASSERT(size() == rhs.size());
166  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
167  *auxs_[jobs] += rhs[jobs];
168  }
169  Log::trace() << "ObsAuxIncrements<OBS>::operator+= done" << std::endl;
170  return *this;
171 }
172 // -----------------------------------------------------------------------------
173 template<typename OBS>
175  Log::trace() << "ObsAuxIncrements<OBS>::operator-= starting" << std::endl;
176  ASSERT(size() == rhs.size());
177  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
178  *auxs_[jobs] -= rhs[jobs];
179  }
180  Log::trace() << "ObsAuxIncrements<OBS>::operator-= done" << std::endl;
181  return *this;
182 }
183 // -----------------------------------------------------------------------------
184 template<typename OBS>
186  Log::trace() << "ObsAuxIncrements<OBS>::operator*= starting" << std::endl;
187  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
188  *auxs_[jobs] *= zz;
189  }
190  Log::trace() << "ObsAuxIncrements<OBS>::operator*= done" << std::endl;
191  return *this;
192 }
193 // -----------------------------------------------------------------------------
194 template<typename OBS>
195 void ObsAuxIncrements<OBS>::axpy(const double & zz, const ObsAuxIncrements & dx) {
196  Log::trace() << "ObsAuxIncrements<OBS>::axpy starting" << std::endl;
197  ASSERT(size() == dx.size());
198  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
199  auxs_[jobs]->axpy(zz, dx[jobs]);
200  }
201  Log::trace() << "ObsAuxIncrements<OBS>::axpy done" << std::endl;
202 }
203 // -----------------------------------------------------------------------------
204 template<typename OBS>
206  Log::trace() << "ObsAuxIncrements<OBS>::dot_product_with starting" << std::endl;
207  ASSERT(size() == dx.size());
208  double zz = static_cast<double>(0.0);
209  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
210  zz += auxs_[jobs]->dot_product_with(dx[jobs]);
211  }
212  Log::trace() << "ObsAuxIncrements<OBS>::dot_product_with done" << std::endl;
213  return zz;
214 }
215 // -----------------------------------------------------------------------------
216 template<typename OBS>
217 void ObsAuxIncrements<OBS>::read(const eckit::Configuration & conf) {
218  Log::trace() << "ObsAuxIncrements<OBS>::read starting" << std::endl;
219  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) auxs_[jobs]->read(conf);
220  Log::trace() << "ObsAuxIncrements<OBS>::read done" << std::endl;
221 }
222 // -----------------------------------------------------------------------------
223 template<typename OBS>
224 void ObsAuxIncrements<OBS>::write(const eckit::Configuration & conf) const {
225  Log::trace() << "ObsAuxIncrements<OBS>::write starting" << std::endl;
226  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) auxs_[jobs]->write(conf);
227  Log::trace() << "ObsAuxIncrements<OBS>::write done" << std::endl;
228 }
229 // -----------------------------------------------------------------------------
230 template<typename OBS>
232  Log::trace() << "ObsAuxIncrements<OBS>::norm starting" << std::endl;
233  double zz = static_cast<double>(0.0);
234  for (std::size_t jobs = 0; jobs < size(); ++jobs) {
235  zz += auxs_[jobs]->norm();
236  }
237  Log::trace() << "ObsAuxIncrements<OBS>::norm done" << std::endl;
238  return zz;
239 }
240 // -----------------------------------------------------------------------------
241 template<typename OBS>
243  Log::trace() << "ObsAuxIncrements<OBS>::serialSize starting" << std::endl;
244  size_t ss = 0;
245  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) {
246  ss += auxs_[jobs]->serialSize();
247  }
248  Log::trace() << "ObsAuxIncrements<OBS>::serialSize done" << std::endl;
249  return ss;
250 }
251 // -----------------------------------------------------------------------------
252 template<typename OBS>
253 void ObsAuxIncrements<OBS>::serialize(std::vector<double> & vect) const {
254  Log::trace() << "ObsAuxIncrements<OBS>::serialize starting" << std::endl;
255  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) auxs_[jobs]->serialize(vect);
256  Log::trace() << "ObsAuxIncrements<OBS>::serialize done" << std::endl;
257 }
258 // -----------------------------------------------------------------------------
259 template<typename OBS>
260 void ObsAuxIncrements<OBS>::deserialize(const std::vector<double> & vect, size_t & index) {
261  Log::trace() << "ObsAuxIncrements<OBS>::deserialize starting" << std::endl;
262  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) {
263  auxs_[jobs]->deserialize(vect, index);
264  }
265  Log::trace() << "ObsAuxIncrements<OBS>::deserialize done" << std::endl;
266 }
267 
268 // -----------------------------------------------------------------------------
269 template<typename OBS>
270 void ObsAuxIncrements<OBS>::print(std::ostream & os) const {
271  for (std::size_t jobs = 0; jobs < auxs_.size(); ++jobs) os << *auxs_[jobs];
272 }
273 // -----------------------------------------------------------------------------
274 
275 } // namespace oops
276 
277 #endif // OOPS_BASE_OBSAUXINCREMENTS_H_
Holds a vector of ObsAuxControl.
std::size_t size() const
Access.
Auxiliary increment related to observations, templated on <OBS>
ObsAuxIncrement_::Parameters_ Parameters_
Holds a vector of ObsAuxIncrement.
void print(std::ostream &) const override
void deserialize(const std::vector< double > &, size_t &) override
size_t serialSize() const override
Serialize-Deserialize.
ObsAuxIncrements & operator*=(const double &)
ObsAuxControls< OBS > ObsAuxControls_
ObsAuxIncrement_ & operator[](const std::size_t ii)
ObsAuxIncrements(const ObsSpaces_ &, const eckit::Configuration &)
Constructor, destructor.
double dot_product_with(const ObsAuxIncrements &) const
ObsSpaces< OBS > ObsSpaces_
void write(const eckit::Configuration &) const
void serialize(std::vector< double > &) const override
static const std::string classname()
ObsAuxIncrements & operator+=(const ObsAuxIncrements &)
const ObsAuxIncrement_ & operator[](const std::size_t ii) const
ObsAuxIncrements & operator=(const ObsAuxIncrements &)
void read(const eckit::Configuration &)
I/O and diagnostics.
std::vector< std::unique_ptr< ObsAuxIncrement_ > > auxs_
ObsAuxIncrement< OBS > ObsAuxIncrement_
std::size_t size() const
Access.
void diff(const ObsAuxControls_ &, const ObsAuxControls_ &)
Linear algebra operators.
ObsAuxIncrements & operator-=(const ObsAuxIncrements &)
void axpy(const double &, const ObsAuxIncrements &)
The namespace for the main oops code.
State< MODEL > & operator+=(State< MODEL > &xx, const Increment< MODEL > &dx)
Add on dx incrment to model state xx.