OOPS
oops/interface/Geometry.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_INTERFACE_GEOMETRY_H_
12 #define OOPS_INTERFACE_GEOMETRY_H_
13 
14 #include <memory>
15 #include <ostream>
16 #include <string>
17 #include <vector>
18 
19 #include "atlas/field.h"
20 #include "atlas/functionspace.h"
21 
23 #include "oops/mpi/mpi.h"
24 #include "oops/util/Logger.h"
25 #include "oops/util/ObjectCounter.h"
26 #include "oops/util/parameters/ConfigurationParameter.h"
27 #include "oops/util/parameters/GenericParameters.h"
28 #include "oops/util/parameters/HasParameters_.h"
29 #include "oops/util/parameters/Parameters.h"
30 #include "oops/util/parameters/ParametersOrConfiguration.h"
31 #include "oops/util/Printable.h"
32 #include "oops/util/Timer.h"
33 
34 namespace eckit {
35  class Configuration;
36 }
37 
38 namespace oops {
39 
40 namespace interface {
41 /// \brief Interface class for the geometry of the model/state space
42 ///
43 /// \details Can contain information about model resolution, gridpoints, MPI distribution
44 ///
45 /// Note: implementations of this interface can opt to extract their settings either from
46 /// a Configuration object or from a subclass of Parameters.
47 ///
48 /// In the former case, they should provide a constructor with the following signature:
49 ///
50 /// Geometry(const eckit::LocalConfiguration &, const eckit::mpi::Comm &);
51 ///
52 /// In the latter case, the implementer should first define a subclass of Parameters
53 /// holding the settings of the geometry in question. The implementation of the Geometry interface
54 /// should then typedef `Parameters_` to the name of that subclass and provide a constructor with
55 /// the following signature:
56 ///
57 /// Geometry(const Parameters_ &, const eckit::mpi::Comm &);
58 template <typename MODEL>
59 class Geometry : public util::Printable,
60  private util::ObjectCounter<Geometry<MODEL> > {
61  typedef typename MODEL::Geometry Geometry_;
63 
64  public:
65  /// Set to Geometry_::Parameters_ if Geometry_ provides a type called Parameters_
66  /// and to GenericParameters (a thin wrapper of an eckit::LocalConfiguration object) if not.
67  typedef TParameters_IfAvailableElseFallbackType_t<Geometry_, GenericParameters> Parameters_;
68 
69  static const std::string classname() {return "oops::Geometry";}
70 
71  /// Constructors from yaml (and mpi communicator), implement one (using Parameters preferred)
72  Geometry(const Parameters_ &, const eckit::mpi::Comm &);
73  Geometry(const eckit::Configuration &, const eckit::mpi::Comm &);
74  /// Constructor from pointer to the MODEL::Geometry (used in 1DVar filter)
75  explicit Geometry(std::shared_ptr<const Geometry_>);
76  /// Destructor (overridden for timer and log purposes)
77  virtual ~Geometry();
78 
79  /// Iterator to the first gridpoint of Geometry (only used in LocalEnsembleDA)
80  GeometryIterator_ begin() const;
81  /// Iterator to the last gridpoint fo Geometry (only used in LocalEnsembleDA)
82  GeometryIterator_ end() const;
83  /// Values of vertical coordinate in units specified by string (only used in GETKF)
84  std::vector<double> verticalCoord(std::string &) const;
85 
86  /// Accessor to the geometry communicator
87  const eckit::mpi::Comm & getComm() const {return geom_->getComm();}
88  atlas::FunctionSpace * atlasFunctionSpace() const {return geom_->atlasFunctionSpace();}
89  atlas::FieldSet * atlasFieldSet() const {return geom_->atlasFieldSet();}
90 
91  protected:
92  std::shared_ptr<const Geometry_> geom_; /// pointer to the Geometry implementation
93 
94  private:
95  void print(std::ostream &) const;
96 };
97 
98 // -----------------------------------------------------------------------------
99 
100 template <typename MODEL>
101 Geometry<MODEL>::Geometry(const eckit::Configuration & config,
102  const eckit::mpi::Comm & comm)
103  : Geometry(validateAndDeserialize<Parameters_>(config), comm)
104 {}
105 
106 // -----------------------------------------------------------------------------
107 
108 template <typename MODEL>
110  const eckit::mpi::Comm & comm): geom_() {
111  Log::trace() << "Geometry<MODEL>::Geometry starting" << std::endl;
112  util::Timer timer(classname(), "Geometry");
113  geom_.reset(new Geometry_(
114  parametersOrConfiguration<HasParameters_<Geometry_>::value>(parameters),
115  comm));
116  Log::trace() << "Geometry<MODEL>::Geometry done" << std::endl;
117 }
118 
119 // -----------------------------------------------------------------------------
120 
121 template <typename MODEL>
122 Geometry<MODEL>::Geometry(std::shared_ptr<const Geometry_> ptr)
123  : geom_(ptr)
124 {
125  Log::trace() << "Geometry<MODEL>::Geometry shared_ptr done" << std::endl;
126 }
127 
128 // -----------------------------------------------------------------------------
129 
130 template <typename MODEL>
132  Log::trace() << "Geometry<MODEL>::~Geometry starting" << std::endl;
133  util::Timer timer(classname(), "~Geometry");
134  geom_.reset();
135  Log::trace() << "Geometry<MODEL>::~Geometry done" << std::endl;
136 }
137 
138 // -----------------------------------------------------------------------------
139 
140 template <typename MODEL>
142  Log::trace() << "Geometry<MODEL>::begin starting" << std::endl;
143  util::Timer timer(classname(), "begin");
144  Log::trace() << "Geometry<MODEL>::begin done" << std::endl;
145  return GeometryIterator_(geom_->begin());
146 }
147 
148 // -----------------------------------------------------------------------------
149 
150 template <typename MODEL>
151 std::vector<double> Geometry<MODEL>::verticalCoord(std::string & str) const {
152  Log::trace() << "Geometry<MODEL>::verticalCoord starting" << std::endl;
153  util::Timer timer(classname(), "verticalCoord");
154  Log::trace() << "Geometry<MODEL>::verticalCoord done" << std::endl;
155  return geom_->verticalCoord(str);
156 }
157 
158 // -----------------------------------------------------------------------------
159 
160 template <typename MODEL>
162  Log::trace() << "Geometry<MODEL>::end starting" << std::endl;
163  util::Timer timer(classname(), "end");
164  Log::trace() << "Geometry<MODEL>::end done" << std::endl;
165  return GeometryIterator_(geom_->end());
166 }
167 
168 // -----------------------------------------------------------------------------
169 
170 template <typename MODEL>
171 void Geometry<MODEL>::print(std::ostream & os) const {
172  Log::trace() << "Geometry<MODEL>::print starting" << std::endl;
173  util::Timer timer(classname(), "print");
174  os << *geom_;
175  Log::trace() << "Geometry<MODEL>::print done" << std::endl;
176 }
177 
178 } // namespace interface
179 
180 // -----------------------------------------------------------------------------
181 /// \brief Geometry class used in oops; subclass of interface class above
182 ///
183 /// \details Handles additional MPI communicator parameter in the constructors
184 /// (for MPI distribution in time, used in oops for 4DEnVar and weak-constraint 4DVar).
185 /// Adds extra methods that do not need to be implemented in the implementations:
186 /// - geometry() (for interfacing in oops)
187 /// - timeComm() (accessor to the MPI communicator in time)
188 template <typename MODEL>
189 class Geometry : public interface::Geometry<MODEL> {
190  typedef typename MODEL::Geometry Geometry_;
191  public:
193 
194  /// Constructor from Parameters and mpi communicators: \p geometry for spatial distribution
195  /// (handled by the implementation) and \p time for distribution in time (handled by oops)
196  Geometry(const Parameters_ &, const eckit::mpi::Comm & geometry,
197  const eckit::mpi::Comm & time);
198  /// Constructor from Configuration and mpi communicators: \p geometry for spatial distribution
199  /// (handled by the implementation) and \p time for distribution in time (handled by oops)
200  Geometry(const eckit::Configuration &, const eckit::mpi::Comm & geometry,
201  const eckit::mpi::Comm & time = oops::mpi::myself());
202  /// Constructor from pointer to the MODEL::Geometry (used in 1DVar filter)
203  explicit Geometry(std::shared_ptr<const Geometry_>);
204 
205  /// Interfacing with other oops classes
206  const Geometry_ & geometry() const {return *this->geom_;}
207 
208  /// Accessor to the MPI communicator for distribution in time
209  const eckit::mpi::Comm & timeComm() const {return *timeComm_;}
210 
211  private:
212  const eckit::mpi::Comm * timeComm_; /// pointer to the MPI communicator in time
213 };
214 
215 // -----------------------------------------------------------------------------
216 
217 template <typename MODEL>
218 Geometry<MODEL>::Geometry(const eckit::Configuration & config,
219  const eckit::mpi::Comm & geometry, const eckit::mpi::Comm & time):
220  interface::Geometry<MODEL>(config, geometry), timeComm_(&time)
221 {}
222 
223 // -----------------------------------------------------------------------------
224 
225 template <typename MODEL>
227  const eckit::mpi::Comm & geometry, const eckit::mpi::Comm & time):
228  interface::Geometry<MODEL>(parameters, geometry), timeComm_(&time)
229 {}
230 
231 // -----------------------------------------------------------------------------
232 
233 template <typename MODEL>
234 Geometry<MODEL>::Geometry(std::shared_ptr<const Geometry_> ptr):
235  interface::Geometry<MODEL>(ptr), timeComm_(&oops::mpi::myself())
236 {}
237 
238 } // namespace oops
239 
240 #endif // OOPS_INTERFACE_GEOMETRY_H_
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::interface::Geometry::Geometry
Geometry(const Parameters_ &, const eckit::mpi::Comm &)
Constructors from yaml (and mpi communicator), implement one (using Parameters preferred)
Definition: oops/interface/Geometry.h:109
oops::GeometryIterator
Definition: oops/interface/GeometryIterator.h:32
oops::interface::Geometry::Parameters_
TParameters_IfAvailableElseFallbackType_t< Geometry_, GenericParameters > Parameters_
Definition: oops/interface/Geometry.h:67
oops::Geometry::timeComm
const eckit::mpi::Comm & timeComm() const
Accessor to the MPI communicator for distribution in time.
Definition: oops/interface/Geometry.h:209
mpi.h
oops::interface::Geometry::classname
static const std::string classname()
Definition: oops/interface/Geometry.h:69
oops::interface::Geometry::GeometryIterator_
GeometryIterator< MODEL > GeometryIterator_
Definition: oops/interface/Geometry.h:62
oops::interface::Geometry::atlasFunctionSpace
atlas::FunctionSpace * atlasFunctionSpace() const
Definition: oops/interface/Geometry.h:88
oops::mpi::myself
const eckit::mpi::Comm & myself()
Default communicator with each MPI task by itself.
Definition: oops/mpi/mpi.cc:28
oops::interface::Geometry::atlasFieldSet
atlas::FieldSet * atlasFieldSet() const
Definition: oops/interface/Geometry.h:89
eckit
Definition: FieldL95.h:22
oops::interface::Geometry::end
GeometryIterator_ end() const
Iterator to the last gridpoint fo Geometry (only used in LocalEnsembleDA)
Definition: oops/interface/Geometry.h:161
oops::Geometry::Geometry
Geometry(const Parameters_ &, const eckit::mpi::Comm &geometry, const eckit::mpi::Comm &time)
Definition: oops/interface/Geometry.h:226
oops::interface::Geometry
Interface class for the geometry of the model/state space.
Definition: oops/interface/Geometry.h:60
oops::interface::Geometry::Geometry_
MODEL::Geometry Geometry_
Definition: oops/interface/Geometry.h:61
oops::Geometry::timeComm_
const eckit::mpi::Comm * timeComm_
Definition: oops/interface/Geometry.h:212
oops::interface::Geometry::geom_
std::shared_ptr< const Geometry_ > geom_
Definition: oops/interface/Geometry.h:92
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
GeometryIterator.h
oops::interface::Geometry::~Geometry
virtual ~Geometry()
Destructor (overridden for timer and log purposes)
Definition: oops/interface/Geometry.h:131
oops::Geometry::Parameters_
interface::Geometry< MODEL >::Parameters_ Parameters_
Definition: oops/interface/Geometry.h:192
oops::Geometry::Geometry_
MODEL::Geometry Geometry_
Definition: oops/interface/Geometry.h:190
oops::interface::Geometry::begin
GeometryIterator_ begin() const
Iterator to the first gridpoint of Geometry (only used in LocalEnsembleDA)
Definition: oops/interface/Geometry.h:141
oops::interface::Geometry::getComm
const eckit::mpi::Comm & getComm() const
Accessor to the geometry communicator.
Definition: oops/interface/Geometry.h:87
oops::interface::Geometry::print
void print(std::ostream &) const
pointer to the Geometry implementation
Definition: oops/interface/Geometry.h:171
oops::interface::Geometry::verticalCoord
std::vector< double > verticalCoord(std::string &) const
Values of vertical coordinate in units specified by string (only used in GETKF)
Definition: oops/interface/Geometry.h:151
oops::Geometry::geometry
const Geometry_ & geometry() const
Interfacing with other oops classes.
Definition: oops/interface/Geometry.h:206