OOPS
oops/interface/State.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  * (C) Copyright 2017-2019 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_INTERFACE_STATE_H_
13 #define OOPS_INTERFACE_STATE_H_
14 
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "eckit/config/Configuration.h"
21 #include "oops/base/Variables.h"
23 #include "oops/util/DateTime.h"
24 #include "oops/util/gatherPrint.h"
25 #include "oops/util/ObjectCounter.h"
26 #include "oops/util/Printable.h"
27 #include "oops/util/Serializable.h"
28 #include "oops/util/Timer.h"
29 
30 namespace oops {
31 
32 /// Encapsulates the model state
33 
34 // -----------------------------------------------------------------------------
35 
36 template <typename MODEL>
37 class State : public util::Printable,
38  public util::Serializable,
39  private util::ObjectCounter<State<MODEL> > {
40  typedef typename MODEL::State State_;
42 
43  public:
44  static const std::string classname() {return "oops::State";}
45 
46 /// Constructor, destructor
47  State(const Geometry_ &, const Variables &, const util::DateTime &);
48  State(const Geometry_ &, const eckit::Configuration &);
49  State(const Geometry_ &, const State &);
50  State(const State &);
51  explicit State(const State_ &);
52  ~State();
53  State & operator=(const State &); // Is that used anywhere?
54 
55 /// Interfacing
56  State_ & state() {return *state_;}
57  const State_ & state() const {return *state_;}
58 
59 /// Time
60  const util::DateTime validTime() const {return state_->validTime();}
61  void updateTime(const util::Duration & dt) {state_->updateTime(dt);}
62 
63 /// I/O and diagnostics
64  void read(const eckit::Configuration &);
65  void write(const eckit::Configuration &) const;
66  double norm() const; // Only for tests
67  Geometry_ geometry() const;
68  const Variables & variables() const;
69 
70 /// Accumulator
71  void zero();
72  void accumul(const double &, const State &);
73 
74 /// Serialize and deserialize
75  size_t serialSize() const override;
76  void serialize(std::vector<double> &) const override;
77  void deserialize(const std::vector<double> &, size_t &) override;
78 
79  private:
80  void print(std::ostream &) const override;
81  std::unique_ptr<State_> state_;
82  const eckit::mpi::Comm & commTime_;
83 };
84 
85 // =============================================================================
86 
87 template<typename MODEL>
88 State<MODEL>::State(const Geometry_ & resol, const Variables & vars,
89  const util::DateTime & time) : state_(), commTime_(resol.timeComm())
90 {
91  Log::trace() << "State<MODEL>::State starting" << std::endl;
92  util::Timer timer(classname(), "State");
93  state_.reset(new State_(resol.geometry(), vars, time));
94  Log::trace() << "State<MODEL>::State done" << std::endl;
95 }
96 
97 // -----------------------------------------------------------------------------
98 
99 template<typename MODEL>
100 State<MODEL>::State(const Geometry_ & resol, const eckit::Configuration & conf)
101  : state_(), commTime_(resol.timeComm())
102 {
103  Log::trace() << "State<MODEL>::State read starting" << std::endl;
104  util::Timer timer(classname(), "State");
105 
106  eckit::LocalConfiguration myconf;
107  if (conf.has("states")) {
108 // Parallel 4D state:
109  std::vector<eckit::LocalConfiguration> confs;
110  conf.get("states", confs);
111  ASSERT(confs.size() == resol.timeComm().size());
112  myconf = confs[resol.timeComm().rank()];
113  } else {
114 // 3D state:
115  myconf = eckit::LocalConfiguration(conf);
116  }
117 
118  state_.reset(new State_(resol.geometry(), myconf));
119  Log::trace() << "State<MODEL>::State read done" << std::endl;
120 }
121 
122 // -----------------------------------------------------------------------------
123 
124 template<typename MODEL>
125 State<MODEL>::State(const Geometry_ & resol, const State & other)
126  : state_(), commTime_(resol.timeComm())
127 {
128  Log::trace() << "State<MODEL>::State interpolated starting" << std::endl;
129  util::Timer timer(classname(), "State");
130  state_.reset(new State_(resol.geometry(), *other.state_));
131  Log::trace() << "State<MODEL>::State interpolated done" << std::endl;
132 }
133 
134 // -----------------------------------------------------------------------------
135 
136 template<typename MODEL>
137 State<MODEL>::State(const State & other) : state_(), commTime_(other.commTime_)
138 {
139  Log::trace() << "State<MODEL>::State starting copy" << std::endl;
140  util::Timer timer(classname(), "State");
141  state_.reset(new State_(*other.state_));
142  Log::trace() << "State<MODEL>::State copy done" << std::endl;
143 }
144 
145 // -----------------------------------------------------------------------------
146 
147 template<typename MODEL>
148 State<MODEL>::State(const State_ & target) : state_(), commTime_(oops::mpi::myself())
149 {
150  Log::trace() << "State<MODEL>::State starting copy from derived state" << std::endl;
151  util::Timer timer(classname(), "State");
152  Log::warning() << "State<MODEL>::State creating State from derived state" << std::endl;
153  state_.reset(new State_(target));
154  Log::trace() << "State<MODEL>::State copy from derived state done" << std::endl;
155 }
156 
157 // -----------------------------------------------------------------------------
158 
159 template<typename MODEL>
161  Log::trace() << "State<MODEL>::~State starting" << std::endl;
162  util::Timer timer(classname(), "~State");
163  state_.reset();
164  Log::trace() << "State<MODEL>::~State done" << std::endl;
165 }
166 
167 // -----------------------------------------------------------------------------
168 
169 template<typename MODEL>
171  Log::trace() << "State<MODEL>::operator= starting" << std::endl;
172  util::Timer timer(classname(), "operator=");
173  *state_ = *rhs.state_;
174  Log::trace() << "State<MODEL>::operator= done" << std::endl;
175  return *this;
176 }
177 
178 // -----------------------------------------------------------------------------
179 
180 template<typename MODEL>
181 void State<MODEL>::read(const eckit::Configuration & conf) {
182  Log::trace() << "State<MODEL>::read starting" << std::endl;
183  util::Timer timer(classname(), "read");
184  state_->read(conf);
185  Log::trace() << "State<MODEL>::read done" << std::endl;
186 }
187 
188 // -----------------------------------------------------------------------------
189 
190 template<typename MODEL>
191 void State<MODEL>::write(const eckit::Configuration & conf) const {
192  Log::trace() << "State<MODEL>::write starting" << std::endl;
193  util::Timer timer(classname(), "write");
194  state_->write(conf);
195  Log::trace() << "State<MODEL>::write done" << std::endl;
196 }
197 
198 // -----------------------------------------------------------------------------
199 
200 template<typename MODEL>
201 double State<MODEL>::norm() const {
202  Log::trace() << "State<MODEL>::norm starting" << std::endl;
203  util::Timer timer(classname(), "norm");
204  double zz = state_->norm();
205  zz *= zz;
206  commTime_.allReduceInPlace(zz, eckit::mpi::Operation::SUM);
207  zz = sqrt(zz);
208  Log::trace() << "State<MODEL>::norm done" << std::endl;
209  return zz;
210 }
211 
212 // -----------------------------------------------------------------------------
213 
214 template<typename MODEL>
216  Log::trace() << "State<MODEL>::geometry starting" << std::endl;
217  util::Timer timer(classname(), "geometry");
218  Geometry<MODEL> geom(state_->geometry());
219  Log::trace() << "State<MODEL>::geometry done" << std::endl;
220  return geom;
221 }
222 
223 // -----------------------------------------------------------------------------
224 
225 template<typename MODEL>
227  Log::trace() << "State<MODEL>::variables starting" << std::endl;
228  util::Timer timer(classname(), "variables");
229  return state_->variables();
230 }
231 
232 // -----------------------------------------------------------------------------
233 
234 template<typename MODEL>
235 size_t State<MODEL>::serialSize() const {
236  Log::trace() << "State<MODEL>::serialSize" << std::endl;
237  util::Timer timer(classname(), "serialSize");
238  return state_->serialSize();
239 }
240 
241 // -----------------------------------------------------------------------------
242 
243 template<typename MODEL>
244 void State<MODEL>::serialize(std::vector<double> & vect) const {
245  Log::trace() << "State<MODEL>::serialize starting" << std::endl;
246  util::Timer timer(classname(), "serialize");
247  state_->serialize(vect);
248  Log::trace() << "State<MODEL>::serialize done" << std::endl;
249 }
250 
251 // -----------------------------------------------------------------------------
252 
253 template<typename MODEL>
254 void State<MODEL>::deserialize(const std::vector<double> & vect, size_t & current) {
255  Log::trace() << "State<MODEL>::State deserialize starting" << std::endl;
256  util::Timer timer(classname(), "deserialize");
257  state_->deserialize(vect, current);
258  Log::trace() << "State<MODEL>::State deserialize done" << std::endl;
259 }
260 
261 // -----------------------------------------------------------------------------
262 
263 template<typename MODEL>
264 void State<MODEL>::print(std::ostream & os) const {
265  Log::trace() << "State<MODEL>::print starting" << std::endl;
266  util::Timer timer(classname(), "print");
267  if (commTime_.size() > 1) {
268  gatherPrint(os, *state_, commTime_);
269  } else {
270  os << *state_;
271  }
272  Log::trace() << "State<MODEL>::print done" << std::endl;
273 }
274 
275 // -----------------------------------------------------------------------------
276 
277 template<typename MODEL>
279  Log::trace() << "State<MODEL>::zero starting" << std::endl;
280  util::Timer timer(classname(), "zero");
281  state_->zero();
282  Log::trace() << "State<MODEL>::zero done" << std::endl;
283 }
284 
285 // -----------------------------------------------------------------------------
286 
287 template<typename MODEL>
288 void State<MODEL>::accumul(const double & zz, const State & xx) {
289  Log::trace() << "State<MODEL>::accumul starting" << std::endl;
290  util::Timer timer(classname(), "accumul");
291  state_->accumul(zz, *xx.state_);
292  Log::trace() << "State<MODEL>::accumul done" << std::endl;
293 }
294 
295 // -----------------------------------------------------------------------------
296 
297 } // namespace oops
298 
299 #endif // OOPS_INTERFACE_STATE_H_
oops::State::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/State.h:60
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::State::state_
std::unique_ptr< State_ > state_
Definition: oops/interface/State.h:81
oops::State::variables
const Variables & variables() const
Definition: oops/interface/State.h:226
oops::Geometry::timeComm
const eckit::mpi::Comm & timeComm() const
Accessor to the MPI communicator for distribution in time.
Definition: oops/interface/Geometry.h:209
oops::State::serialSize
size_t serialSize() const override
Serialize and deserialize.
Definition: oops/interface/State.h:235
oops::State::updateTime
void updateTime(const util::Duration &dt)
Definition: oops/interface/State.h:61
oops::State::~State
~State()
Definition: oops/interface/State.h:160
oops::State::state
const State_ & state() const
Definition: oops/interface/State.h:57
oops::State::read
void read(const eckit::Configuration &)
I/O and diagnostics.
Definition: oops/interface/State.h:181
oops::State::operator=
State & operator=(const State &)
Definition: oops/interface/State.h:170
oops::State::State_
MODEL::State State_
Definition: oops/interface/State.h:40
oops::mpi::myself
const eckit::mpi::Comm & myself()
Default communicator with each MPI task by itself.
Definition: oops/mpi/mpi.cc:28
oops::State::commTime_
const eckit::mpi::Comm & commTime_
Definition: oops/interface/State.h:82
oops::State::state
State_ & state()
Interfacing.
Definition: oops/interface/State.h:56
oops::State::zero
void zero()
Accumulator.
Definition: oops/interface/State.h:278
oops::State::print
void print(std::ostream &) const override
Definition: oops/interface/State.h:264
oops::State::write
void write(const eckit::Configuration &) const
Definition: oops/interface/State.h:191
oops::State::Geometry_
Geometry< MODEL > Geometry_
Definition: oops/interface/State.h:41
PostProcessor.h
oops::State::classname
static const std::string classname()
Definition: oops/interface/State.h:44
oops::State::State
State(const Geometry_ &, const Variables &, const util::DateTime &)
Constructor, destructor.
Definition: oops/interface/State.h:88
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
oops::State::norm
double norm() const
Definition: oops/interface/State.h:201
oops::State::geometry
Geometry_ geometry() const
Definition: oops/interface/State.h:215
oops::State
Encapsulates the model state.
Definition: CostJbState.h:28
oops::State::serialize
void serialize(std::vector< double > &) const override
Definition: oops/interface/State.h:244
oops::State::accumul
void accumul(const double &, const State &)
Definition: oops/interface/State.h:288
oops::Variables
Definition: oops/base/Variables.h:23
oops::State::deserialize
void deserialize(const std::vector< double > &, size_t &) override
Definition: oops/interface/State.h:254
Variables.h
Geometry.h
oops::Geometry::geometry
const Geometry_ & geometry() const
Interfacing with other oops classes.
Definition: oops/interface/Geometry.h:206