OOPS
LocalizationBase.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  * (C) Copyright 2020-2020 UCAR
4  *
5  * This software is licensed under the terms of the Apache Licence Version 2.0
6  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
7  * In applying this licence, ECMWF does not waive the privileges and immunities
8  * granted to it by virtue of its status as an intergovernmental organisation nor
9  * does it submit to any jurisdiction.
10  */
11 
12 #ifndef OOPS_BASE_LOCALIZATIONBASE_H_
13 #define OOPS_BASE_LOCALIZATIONBASE_H_
14 
15 #include <map>
16 #include <memory>
17 #include <string>
18 
19 #include <boost/noncopyable.hpp>
20 
23 #include "oops/mpi/mpi.h"
24 #include "oops/util/abor1_cpp.h"
25 #include "oops/util/Logger.h"
26 #include "oops/util/Printable.h"
27 
28 namespace eckit {
29  class Configuration;
30 }
31 
32 namespace oops {
33 
34 // -----------------------------------------------------------------------------
35 /// Model-space localization base class
36 template <typename MODEL>
37 class LocalizationBase : public util::Printable,
38  private boost::noncopyable {
40 
41  public:
42  LocalizationBase() = default;
43  virtual ~LocalizationBase() = default;
44 
45  /// default implementation of 4D localization (used in model-specific implementations)
46  virtual void localize(Increment_ &) const;
47 
48  protected:
49  virtual void multiply(Increment_ &) const = 0;
50 
51  private:
52  virtual void print(std::ostream &) const = 0;
53 };
54 
55 // -----------------------------------------------------------------------------
56 /// Default implementation of 4D localization (used in model-specific implementations)
57 template <typename MODEL>
59  Log::trace() << "LocalizationBase<MODEL>::multiply starting" << std::endl;
60  const eckit::mpi::Comm & comm = dx.timeComm();
61  static int tag = 23456;
62  size_t nslots = comm.size();
63  int mytime = comm.rank();
64 
65  if (mytime > 0) {
66  util::DateTime dt = dx.validTime(); // Save original time value
67  oops::mpi::send(comm, dx, 0, tag);
68  dx.zero();
69  oops::mpi::receive(comm, dx, 0, tag);
70  dx.updateTime(dt - dx.validTime()); // Set time back to original value
71  } else {
72  // Sum over timeslots
73  for (size_t jj = 1; jj < nslots; ++jj) {
74  Increment_ dxtmp(dx);
75  oops::mpi::receive(comm, dxtmp, jj, tag);
76  dx.axpy(1.0, dxtmp, false);
77  }
78  // Apply 3D localization
79  this->multiply(dx);
80  // Copy result to all timeslots
81  for (size_t jj = 1; jj < nslots; ++jj) {
82  oops::mpi::send(comm, dx, jj, tag);
83  }
84  }
85  ++tag;
86 
87  Log::trace() << "LocalizationBase<MODEL>::multiply done" << std::endl;
88 }
89 
90 
91 // =============================================================================
92 
93 /// Localization Factory
94 template <typename MODEL>
97  public:
98  static std::unique_ptr<LocalizationBase<MODEL>> create(const Geometry_ &,
99  const util::DateTime &,
100  const eckit::Configuration &);
101  virtual ~LocalizationFactory() = default;
102  protected:
103  explicit LocalizationFactory(const std::string &);
104  private:
106  const util::DateTime &,
107  const eckit::Configuration &) = 0;
108  static std::map < std::string, LocalizationFactory<MODEL> * > & getMakers() {
109  static std::map < std::string, LocalizationFactory<MODEL> * > makers_;
110  return makers_;
111  }
112 };
113 
114 // -----------------------------------------------------------------------------
115 
116 template<class MODEL, class T>
117 class LocalizationMaker : public LocalizationFactory<MODEL> {
119  virtual LocalizationBase<MODEL> * make(const Geometry_ & geometry,
120  const util::DateTime & time,
121  const eckit::Configuration & conf)
122  { return new T(geometry, time, conf); }
123  public:
124  explicit LocalizationMaker(const std::string & name) : LocalizationFactory<MODEL>(name) {}
125 };
126 
127 // =============================================================================
128 
129 template <typename MODEL>
131  if (getMakers().find(name) != getMakers().end()) {
132  throw std::runtime_error(name + " already registered in localization factory.");
133  }
134  getMakers()[name] = this;
135 }
136 
137 // -----------------------------------------------------------------------------
138 
139 template <typename MODEL>
140 std::unique_ptr<LocalizationBase<MODEL>>
142  const util::DateTime & time,
143  const eckit::Configuration & conf) {
144  Log::trace() << "LocalizationBase<MODEL>::create starting" << std::endl;
145  const std::string id = conf.getString("localization method");
146  typename std::map<std::string, LocalizationFactory<MODEL>*>::iterator
147  jloc = getMakers().find(id);
148  if (jloc == getMakers().end()) {
149  Log::error() << id << " does not exist in localization factory." << std::endl;
150  Log::error() << "Obs Localization Factory has " << getMakers().size()
151  << " elements:" << std::endl;
152  for (typename std::map<std::string, LocalizationFactory<MODEL>*>::const_iterator
153  jj = getMakers().begin(); jj != getMakers().end(); ++jj) {
154  Log::error() << "A " << jj->first << " Localization" << std::endl;
155  }
156  throw std::runtime_error(id + " does not exist in localization factory.");
157  }
158  std::unique_ptr<LocalizationBase<MODEL>> ptr(jloc->second->make(geometry, time, conf));
159  Log::trace() << "LocalizationBase<MODEL>::create done" << std::endl;
160  return ptr;
161 }
162 
163 // -----------------------------------------------------------------------------
164 
165 } // namespace oops
166 
167 #endif // OOPS_BASE_LOCALIZATIONBASE_H_
oops::LocalizationMaker::Geometry_
Geometry< MODEL > Geometry_
Definition: LocalizationBase.h:118
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::LocalizationBase
Model-space localization base class.
Definition: LocalizationBase.h:38
oops::Increment::timeComm
const eckit::mpi::Comm & timeComm() const
Definition: oops/interface/Increment.h:123
mpi.h
oops::Increment::zero
void zero()
Linear algebra operators.
Definition: oops/interface/Increment.h:206
oops::LocalizationBase::Increment_
Increment< MODEL > Increment_
Definition: LocalizationBase.h:39
oops::LocalizationMaker::make
virtual LocalizationBase< MODEL > * make(const Geometry_ &geometry, const util::DateTime &time, const eckit::Configuration &conf)
Definition: LocalizationBase.h:119
oops::LocalizationFactory::getMakers
static std::map< std::string, LocalizationFactory< MODEL > * > & getMakers()
Definition: LocalizationBase.h:108
oops::LocalizationFactory::make
virtual LocalizationBase< MODEL > * make(const Geometry_ &, const util::DateTime &, const eckit::Configuration &)=0
oops::LocalizationFactory
Localization Factory.
Definition: LocalizationBase.h:95
oops::LocalizationFactory::create
static std::unique_ptr< LocalizationBase< MODEL > > create(const Geometry_ &, const util::DateTime &, const eckit::Configuration &)
Definition: LocalizationBase.h:141
oops::Increment::axpy
void axpy(const double &, const Increment &, const bool check=true)
Definition: oops/interface/Increment.h:290
oops::Increment::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/Increment.h:72
oops::LocalizationBase::print
virtual void print(std::ostream &) const =0
eckit
Definition: FieldL95.h:22
oops::mpi::send
void send(const eckit::mpi::Comm &comm, const SERIALIZABLE &sendobj, const int dest, const int tag)
Extend eckit Comm for Serializable oops objects.
Definition: oops/mpi/mpi.h:36
oops::LocalizationBase::multiply
virtual void multiply(Increment_ &) const =0
oops::LocalizationBase::~LocalizationBase
virtual ~LocalizationBase()=default
oops::LocalizationBase::localize
virtual void localize(Increment_ &) const
default implementation of 4D localization (used in model-specific implementations)
Definition: LocalizationBase.h:58
oops::LocalizationFactory::LocalizationFactory
LocalizationFactory(const std::string &)
Definition: LocalizationBase.h:130
oops::LocalizationFactory::Geometry_
Geometry< MODEL > Geometry_
Definition: LocalizationBase.h:96
oops::LocalizationMaker::LocalizationMaker
LocalizationMaker(const std::string &name)
Definition: LocalizationBase.h:124
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
oops::LocalizationBase::LocalizationBase
LocalizationBase()=default
oops::Increment::updateTime
void updateTime(const util::Duration &dt)
Definition: oops/interface/Increment.h:73
oops::LocalizationFactory::~LocalizationFactory
virtual ~LocalizationFactory()=default
oops::LocalizationMaker
Definition: LocalizationBase.h:117
compare.error
int error
Definition: compare.py:168
oops::Increment
Increment Class: Difference between two states.
Definition: CostJbState.h:27
oops::mpi::receive
void receive(const eckit::mpi::Comm &comm, SERIALIZABLE &recvobj, const int source, const int tag)
Definition: oops/mpi/mpi.h:46
Geometry.h
Increment.h