FV3 Bundle
DualVector.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_DUALVECTOR_H_
12 #define OOPS_ASSIMILATION_DUALVECTOR_H_
13 
14 #include <vector>
15 #include <boost/scoped_ptr.hpp>
16 #include <boost/shared_ptr.hpp>
17 
19 #include "oops/base/Departures.h"
22 #include "oops/util/dot_product.h"
23 
24 namespace oops {
25 
26 /// Container of dual space vectors for all terms of the cost function.
27 /*!
28  * Contains dual space vectors for all terms of the cost function,
29  * that is Departures for Jo, an Increment_ for Jc, a ControlIncrement
30  * for Jb and Jq.
31  */
32 
33 // -----------------------------------------------------------------------------
34 template<typename MODEL> class DualVector {
38 
39  public:
40  DualVector(): dxjb_(), dxjo_(), dxjc_(), ijo_(), ijc_(), size_(0) {}
41  DualVector(const DualVector &);
43 
44 // Access increment
45  void dx(CtrlInc_ * dx) {dxjb_.reset(dx);}
46  const CtrlInc_ & dx() const {return *dxjb_;}
47  CtrlInc_ & dx() {return *dxjb_;}
48 
49 // Store and retrieve other elements (takes ownership)
51  boost::shared_ptr<const GeneralizedDepartures> getv(const unsigned) const;
52 
53 // Linear algebra
54  DualVector & operator=(const DualVector &);
55  DualVector & operator+=(const DualVector &);
56  DualVector & operator-=(const DualVector &);
57  DualVector & operator*=(const double);
58  void zero();
59  void axpy(const double, const DualVector &);
60  double dot_product_with(const DualVector &) const;
61 
62 // Clear everything
63  void clear();
64 
65  private:
66  bool compatible(const DualVector & other) const;
67 
68  boost::scoped_ptr<CtrlInc_> dxjb_;
69  std::vector<boost::shared_ptr<Departures_> > dxjo_;
70  std::vector<boost::shared_ptr<Increment_> > dxjc_;
71  std::vector<unsigned> ijo_;
72  std::vector<unsigned> ijc_;
73  unsigned size_;
74 };
75 
76 // =============================================================================
77 
78 template<typename MODEL>
80  : dxjb_(), dxjo_(), dxjc_(),
81  ijo_(other.ijo_), ijc_(other.ijc_), size_(other.size_)
82 {
83  if (other.dxjb_ != 0) {
84  dxjb_.reset(new CtrlInc_(*other.dxjb_));
85  }
86  for (unsigned jj = 0; jj < other.dxjo_.size(); ++jj) {
87  boost::shared_ptr<Departures_> pd(new Departures_(*other.dxjo_[jj]));
88  dxjo_.push_back(pd);
89  }
90  for (unsigned jj = 0; jj < other.dxjc_.size(); ++jj) {
91  boost::shared_ptr<Increment_> pi(new Increment_(*other.dxjc_[jj]));
92  dxjc_.push_back(pi);
93  }
94 }
95 // -----------------------------------------------------------------------------
96 template<typename MODEL>
98  dxjb_.reset();
99  dxjo_.clear();
100  dxjc_.clear();
101  ijo_.clear();
102  ijc_.clear();
103  size_ = 0;
104 }
105 // -----------------------------------------------------------------------------
106 template<typename MODEL>
108 // Since there is no duck-typing in C++, we do it manually.
109  Increment_ * pi = dynamic_cast<Increment_*>(pv);
110  if (pi != 0) {
111  boost::shared_ptr<Increment_> si(pi);
112  dxjc_.push_back(si);
113  ijc_.push_back(size_);
114  }
115  Departures_ * pd = dynamic_cast<Departures_*>(pv);
116  if (pd != 0) {
117  boost::shared_ptr<Departures_> sd(pd);
118  dxjo_.push_back(sd);
119  ijo_.push_back(size_);
120  }
121  ASSERT(pi != 0 || pd != 0);
122  ++size_;
123 }
124 // -----------------------------------------------------------------------------
125 template<typename MODEL>
126 boost::shared_ptr<const GeneralizedDepartures>
127 DualVector<MODEL>::getv(const unsigned ii) const {
128  ASSERT(ii < size_);
129  boost::shared_ptr<const GeneralizedDepartures> pv;
130  for (unsigned jj = 0; jj < ijo_.size(); ++jj) {
131  if (ijo_[jj] == ii) pv = dxjo_[jj];
132  }
133  for (unsigned jj = 0; jj < ijc_.size(); ++jj) {
134  if (ijc_[jj] == ii) pv = dxjc_[jj];
135  }
136  ASSERT(pv != 0);
137  return pv;
138 }
139 // -----------------------------------------------------------------------------
140 template<typename MODEL>
142  ASSERT(this->compatible(rhs));
143  if (dxjb_ != 0) {
144  *dxjb_ = *rhs.dxjb_;
145  }
146  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
147  *dxjo_[jj] = *rhs.dxjo_[jj];
148  }
149  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
150  *dxjc_[jj] = *rhs.dxjc_[jj];
151  }
152  return *this;
153 }
154 // -----------------------------------------------------------------------------
155 template<typename MODEL>
157  ASSERT(this->compatible(rhs));
158  if (dxjb_ != 0) {
159  *dxjb_ += *rhs.dxjb_;
160  }
161  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
162  *dxjo_[jj] += *rhs.dxjo_[jj];
163  }
164  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
165  *dxjc_[jj] += *rhs.dxjc_[jj];
166  }
167  return *this;
168 }
169 // -----------------------------------------------------------------------------
170 template<typename MODEL>
172  ASSERT(this->compatible(rhs));
173  if (dxjb_ != 0) {
174  *dxjb_ -= *rhs.dxjb_;
175  }
176  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
177  *dxjo_[jj] -= *rhs.dxjo_[jj];
178  }
179  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
180  *dxjc_[jj] -= *rhs.dxjc_[jj];
181  }
182  return *this;
183 }
184 // -----------------------------------------------------------------------------
185 template<typename MODEL>
187  if (dxjb_ != 0) {
188  *dxjb_ *= zz;
189  }
190  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
191  *dxjo_[jj] *= zz;
192  }
193  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
194  *dxjc_[jj] *= zz;
195  }
196  return *this;
197 }
198 // -----------------------------------------------------------------------------
199 template<typename MODEL>
201  if (dxjb_ != 0) {
202  dxjb_->zero();
203  }
204  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
205  dxjo_[jj]->zero();
206  }
207  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
208  dxjc_[jj]->zero();
209  }
210 }
211 // -----------------------------------------------------------------------------
212 template<typename MODEL>
213 void DualVector<MODEL>::axpy(const double zz, const DualVector & rhs) {
214  ASSERT(this->compatible(rhs));
215  if (dxjb_ != 0) {
216  dxjb_->axpy(zz, *rhs.dxjb_);
217  }
218  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
219  dxjo_[jj]->axpy(zz, *rhs.dxjo_[jj]);
220  }
221  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
222  dxjc_[jj]->axpy(zz, *rhs.dxjc_[jj]);
223  }
224 }
225 // -----------------------------------------------------------------------------
226 template<typename MODEL>
228  ASSERT(this->compatible(x2));
229  double zz = 0.0;
230  if (dxjb_ != 0) {
231  zz += dot_product(*dxjb_, *x2.dxjb_);
232  }
233  for (unsigned jj = 0; jj < dxjo_.size(); ++jj) {
234  zz += dot_product(*dxjo_[jj], *x2.dxjo_[jj]);
235  }
236  for (unsigned jj = 0; jj < dxjc_.size(); ++jj) {
237  zz += dot_product(*dxjc_[jj], *x2.dxjc_[jj]);
238  }
239  return zz;
240 }
241 // -----------------------------------------------------------------------------
242 template<typename MODEL>
243 bool DualVector<MODEL>::compatible(const DualVector & other) const {
244  bool lcheck = (dxjb_ == 0) == (other.dxjb_ == 0)
245  && (dxjo_.size() == other.dxjo_.size())
246  && (dxjc_.size() == other.dxjc_.size());
247  return lcheck;
248 }
249 // -----------------------------------------------------------------------------
250 } // namespace oops
251 
252 #endif // OOPS_ASSIMILATION_DUALVECTOR_H_
std::vector< unsigned > ijc_
Definition: DualVector.h:72
Container of dual space vectors for all terms of the cost function.
Definition: DualVector.h:34
std::vector< boost::shared_ptr< Increment_ > > dxjc_
Definition: DualVector.h:70
unsigned size_
Definition: DualVector.h:73
const CtrlInc_ & dx() const
Definition: DualVector.h:46
CtrlInc_ & dx()
Definition: DualVector.h:47
Difference between two observation vectors.
Definition: Departures.h:36
double dot_product_with(const DualVector &) const
Definition: DualVector.h:227
void dx(CtrlInc_ *dx)
Definition: DualVector.h:45
DualVector & operator-=(const DualVector &)
Definition: DualVector.h:171
ControlIncrement< MODEL > CtrlInc_
Definition: DualVector.h:36
std::vector< unsigned > ijo_
Definition: DualVector.h:71
The namespace for the main oops code.
DualVector & operator=(const DualVector &)
Definition: DualVector.h:141
Departures< MODEL > Departures_
Definition: DualVector.h:37
boost::scoped_ptr< CtrlInc_ > dxjb_
Definition: DualVector.h:68
Increment< MODEL > Increment_
Definition: DualVector.h:35
bool compatible(const DualVector &other) const
Definition: DualVector.h:243
Increment Class: Difference between two states.
DualVector & operator*=(const double)
Definition: DualVector.h:186
std::vector< boost::shared_ptr< Departures_ > > dxjo_
Definition: DualVector.h:69
Abstract base class for quantities.
void append(GeneralizedDepartures *)
Definition: DualVector.h:107
DualVector & operator+=(const DualVector &)
Definition: DualVector.h:156
boost::shared_ptr< const GeneralizedDepartures > getv(const unsigned) const
Definition: DualVector.h:127
void axpy(const double, const DualVector &)
Definition: DualVector.h:213