Loading [MathJax]/extensions/tex2jax.js
OOPS
All Classes Namespaces Files Functions Variables Typedefs Macros Pages
oops/base/ObsVector.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2021 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_OBSVECTOR_H_
9 #define OOPS_BASE_OBSVECTOR_H_
10 
11 #include <math.h>
12 #include <memory>
13 #include <ostream>
14 #include <string>
15 #include <utility>
16 
18 
20 #include "oops/util/gatherPrint.h"
21 
22 namespace oops {
23 
24 // -----------------------------------------------------------------------------
25 /// \brief ObsVector class used in oops; subclass of interface class interface::ObsVector.
26 ///
27 /// \details
28 /// Handles additional MPI communicator parameter \p commTime_ in the constructors
29 /// (for MPI distribution in time, used in oops for 4DEnVar and weak-constraint 4DVar).
30 /// Adds communication through time to norm and print methods.
31 // -----------------------------------------------------------------------------
32 
33 template <typename OBS>
34 class ObsVector : public interface::ObsVector<OBS> {
35  typedef typename OBS::ObsVector ObsVector_;
36 
37  public:
38  static const std::string classname() {return "oops::ObsVector";}
39 
40  /// Creates vector from \p obsspace. If \p name is specified, reads the
41  /// specified \p name variable from \p obsspace. Otherwise, zero vector is created.
42  explicit ObsVector(const ObsSpace<OBS> & obsspace, const std::string name = "");
43 
44  /// Wraps an existing ObsVector_.
45  ///
46  /// \param obsvector The vector to wrap.
47  /// \param timeComm Time communicator.
48  ObsVector(std::unique_ptr<ObsVector_> obsvector, const eckit::mpi::Comm &timeComm);
49  /// Copy constructor
50  ObsVector(const ObsVector &);
51 
52  /// Use assignment operator (const ObsDataVector<OBS, float> &) from the base class
54 
55  /// Return the dot product between this ObsVector and \p other ObsVector
56  double dot_product_with(const ObsVector & other) const;
57  /// Return this ObsVector rms
58  double rms() const;
59  /// Number of non-masked out observations (across all MPI tasks)
60  unsigned int nobs() const;
61 
62  private:
63  void print(std::ostream &) const;
64  const eckit::mpi::Comm * commTime_;
65 };
66 
67 // -----------------------------------------------------------------------------
68 
69 template <typename OBS>
70 ObsVector<OBS>::ObsVector(const ObsSpace<OBS> & os, const std::string name)
71  : interface::ObsVector<OBS>(os, name), commTime_(&os.timeComm()) {}
72 
73 // -----------------------------------------------------------------------------
74 
75 template <typename OBS>
76 ObsVector<OBS>::ObsVector(std::unique_ptr<ObsVector_> obsvector, const eckit::mpi::Comm &timeComm)
77  : interface::ObsVector<OBS>(std::move(obsvector)), commTime_(&timeComm) {}
78 
79 // -----------------------------------------------------------------------------
80 
81 template <typename OBS>
82 ObsVector<OBS>::ObsVector(const ObsVector & other): interface::ObsVector<OBS>(other),
83  commTime_(other.commTime_) {}
84 
85 // -----------------------------------------------------------------------------
86 
87 template <typename OBS>
88 double ObsVector<OBS>::dot_product_with(const ObsVector & other) const {
90  commTime_->allReduceInPlace(zz, eckit::mpi::Operation::SUM);
91  return zz;
92 }
93 
94 // -----------------------------------------------------------------------------
95 
96 template <typename OBS>
97 double ObsVector<OBS>::rms() const {
98  double zz = interface::ObsVector<OBS>::rms();
99  size_t ntot = interface::ObsVector<OBS>::nobs();
100  double zzz = zz * zz * static_cast<double>(ntot);
101  commTime_->allReduceInPlace(zzz, eckit::mpi::Operation::SUM);
102  ntot = nobs();
103  if (ntot > 0) {
104  zzz /= static_cast<double>(ntot);
105  zz = std::sqrt(zzz);
106  } else {
107  zz = 0.0;
108  }
109  return zz;
110 }
111 
112 // -----------------------------------------------------------------------------
113 
114 template <typename OBS>
115 unsigned int ObsVector<OBS>::nobs() const {
116  int nobs = interface::ObsVector<OBS>::nobs();
117  commTime_->allReduceInPlace(nobs, eckit::mpi::Operation::SUM);
118  return nobs;
119 }
120 
121 // -----------------------------------------------------------------------------
122 
123 template <typename OBS>
124 void ObsVector<OBS>::print(std::ostream & os) const {
125  if (commTime_->size() > 1) {
126  gatherPrint(os, this->obsvector(), *commTime_);
127  } else {
128  os << this->obsvector();
129  }
130 }
131 
132 // -----------------------------------------------------------------------------
133 
134 } // namespace oops
135 
136 #endif // OOPS_BASE_OBSVECTOR_H_
ObsVector class used in oops; subclass of interface class interface::ObsVector.
OBS::ObsVector ObsVector_
unsigned int nobs() const
Number of non-masked out observations (across all MPI tasks)
const eckit::mpi::Comm * commTime_
void print(std::ostream &) const
double rms() const
Return this ObsVector rms.
double dot_product_with(const ObsVector &other) const
Return the dot product between this ObsVector and other ObsVector.
ObsVector(const ObsSpace< OBS > &obsspace, const std::string name="")
static const std::string classname()
Holds observation vector (e.g. vector of observation values, or of computed H(x))
double rms() const
Return this ObsVector rms.
unsigned int nobs() const
Number of non-masked out observations (across all MPI tasks)
ObsVector_ & obsvector()
Accessor.
double dot_product_with(const ObsVector &other) const
Return the dot product between this ObsVector and another one other.
The namespace for the main oops code.