11 #ifndef OOPS_ASSIMILATION_DUALVECTOR_H_
12 #define OOPS_ASSIMILATION_DUALVECTOR_H_
22 #include "oops/util/dot_product.h"
34 template<
typename MODEL,
typename OBS>
class DualVector {
50 void append(std::unique_ptr<GeneralizedDepartures> &&);
51 std::shared_ptr<const GeneralizedDepartures>
getv(
const unsigned)
const;
68 std::unique_ptr<CtrlInc_>
dxjb_;
69 std::vector<std::shared_ptr<Departures_> >
dxjo_;
70 std::vector<std::shared_ptr<Increment_> >
dxjc_;
71 std::vector<unsigned>
ijo_;
72 std::vector<unsigned>
ijc_;
78 template<
typename MODEL,
typename OBS>
80 : dxjb_(), dxjo_(), dxjc_(),
81 ijo_(other.ijo_), ijc_(other.ijc_), size_(other.size_)
83 if (other.
dxjb_ != 0) {
86 for (
unsigned jj = 0; jj < other.
dxjo_.size(); ++jj) {
90 for (
unsigned jj = 0; jj < other.
dxjc_.size(); ++jj) {
96 template<
typename MODEL,
typename OBS>
106 template<
typename MODEL,
typename OBS>
109 std::shared_ptr<GeneralizedDepartures> sv = std::move(uv);
110 std::shared_ptr<Increment_> si = std::dynamic_pointer_cast<Increment_>(sv);
113 ijc_.push_back(size_);
115 std::shared_ptr<Departures_> sd = std::dynamic_pointer_cast<Departures_>(sv);
118 ijo_.push_back(size_);
120 ASSERT(si !=
nullptr || sd !=
nullptr);
124 template<
typename MODEL,
typename OBS>
125 std::shared_ptr<const GeneralizedDepartures>
128 std::shared_ptr<const GeneralizedDepartures> pv;
129 for (
unsigned jj = 0; jj < ijo_.size(); ++jj) {
130 if (ijo_[jj] == ii) pv = dxjo_[jj];
132 for (
unsigned jj = 0; jj < ijc_.size(); ++jj) {
133 if (ijc_[jj] == ii) pv = dxjc_[jj];
139 template<
typename MODEL,
typename OBS>
141 ASSERT(this->compatible(rhs));
145 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
146 *dxjo_[jj] = *rhs.
dxjo_[jj];
148 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
149 *dxjc_[jj] = *rhs.
dxjc_[jj];
154 template<
typename MODEL,
typename OBS>
156 ASSERT(this->compatible(rhs));
158 *dxjb_ += *rhs.
dxjb_;
160 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
161 *dxjo_[jj] += *rhs.
dxjo_[jj];
163 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
164 *dxjc_[jj] += *rhs.
dxjc_[jj];
169 template<
typename MODEL,
typename OBS>
171 ASSERT(this->compatible(rhs));
173 *dxjb_ -= *rhs.
dxjb_;
175 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
176 *dxjo_[jj] -= *rhs.
dxjo_[jj];
178 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
179 *dxjc_[jj] -= *rhs.
dxjc_[jj];
184 template<
typename MODEL,
typename OBS>
189 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
192 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
198 template<
typename MODEL,
typename OBS>
203 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
206 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
211 template<
typename MODEL,
typename OBS>
213 ASSERT(this->compatible(rhs));
215 dxjb_->axpy(zz, *rhs.
dxjb_);
217 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
218 dxjo_[jj]->axpy(zz, *rhs.
dxjo_[jj]);
220 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
221 dxjc_[jj]->axpy(zz, *rhs.
dxjc_[jj]);
225 template<
typename MODEL,
typename OBS>
227 ASSERT(this->compatible(x2));
230 zz += dot_product(*dxjb_, *x2.
dxjb_);
232 for (
unsigned jj = 0; jj < dxjo_.size(); ++jj) {
233 zz += dot_product(*dxjo_[jj], *x2.
dxjo_[jj]);
235 for (
unsigned jj = 0; jj < dxjc_.size(); ++jj) {
236 zz += dot_product(*dxjc_[jj], *x2.
dxjc_[jj]);
241 template<
typename MODEL,
typename OBS>
243 bool lcheck = (dxjb_ == 0) == (other.
dxjb_ == 0)
244 && (dxjo_.size() == other.
dxjo_.size())
245 && (dxjc_.size() == other.
dxjc_.size());
251 #endif // OOPS_ASSIMILATION_DUALVECTOR_H_