IODA Bundle
oops/interface/LinearModel.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_LINEARMODEL_H_
12 #define OOPS_INTERFACE_LINEARMODEL_H_
13 
14 #include <memory>
15 #include <string>
16 
17 #include <boost/noncopyable.hpp>
18 
19 #include "oops/base/Geometry.h"
20 #include "oops/base/Increment.h"
24 #include "oops/base/State.h"
27 #include "oops/util/Duration.h"
28 #include "oops/util/Logger.h"
29 #include "oops/util/ObjectCounter.h"
30 #include "oops/util/Printable.h"
31 #include "oops/util/Timer.h"
32 
33 namespace eckit {
34  class Configuration;
35 }
36 
37 namespace oops {
38 
39 /// Encapsulates the linear forecast model.
40 /*!
41  * This class provides the operations associated with the LinearModel. It wraps
42  * the actual linear model which can be a model specific one or a generic one
43  * (identity). The interface for the linear model comprises two levels (LinearModel
44  * and LinearModelBase) because we want run time polymorphism.
45  *
46  * Note: implementations of this interface can opt to extract their settings either from
47  * a Configuration object or from a subclass of LinearModelParametersBase.
48  *
49  * In the former case, they should provide a constructor with the following signature:
50  *
51  * LinearModel(const Geometry_ &, const eckit::Configuration &);
52  *
53  * In the latter case, the implementer should first define a subclass of LinearModelParametersBase
54  * holding the settings of the model in question. The implementation of the LinearModel interface
55  * should then typedef `Parameters_` to the name of that subclass and provide a constructor with
56  * the following signature:
57  *
58  * LinearModel(const Geometry_ &, const Parameters_ &);
59  */
60 // -----------------------------------------------------------------------------
61 
62 template <typename MODEL>
63 class LinearModel : public util::Printable,
64  private boost::noncopyable,
65  private util::ObjectCounter<LinearModel<MODEL> > {
72 
73  public:
74  static const std::string classname() {return "oops::LinearModel";}
75 
77  LinearModel(const Geometry_ &, const eckit::Configuration &);
78  ~LinearModel();
79 
80 /// Run the tangent linear forecast
81  void forecastTL(Increment_ &, const ModelAuxIncr_ &, const util::Duration &,
84  const bool idmodel = false) const;
85 
86 /// Run the adjoint forecast
87  void forecastAD(Increment_ &, ModelAuxIncr_ &, const util::Duration &,
90  const bool idmodel = false) const;
91 
92 // Set the linearization trajectory
93  void setTrajectory(const State_ &, State_ &, const ModelAux_ &);
94 
95 // Information and diagnostics
96  const util::Duration & timeResolution() const {return tlm_->timeResolution();}
97  const oops::Variables & variables() const {return tlm_->variables();}
98 
99  protected:
100 // Run the TL forecast
101  void initializeTL(Increment_ &) const;
102  void stepTL(Increment_ &, const ModelAuxIncr_ &) const;
103  void finalizeTL(Increment_ &) const;
104 
105 // Run the AD forecast
106  void initializeAD(Increment_ &) const;
107  void stepAD(Increment_ &, ModelAuxIncr_ &) const;
108  void finalizeAD(Increment_ &) const;
109 
110  private:
111 // diagnostics
112  void print(std::ostream &) const;
113 
114  std::unique_ptr<LinearModelBase_> tlm_;
115 };
116 
117 // =============================================================================
118 
119 template<typename MODEL>
121  : tlm_()
122 {
123  Log::trace() << "LinearModel<MODEL>::LinearModel starting" << std::endl;
124  util::Timer timer(classname(), "LinearModel");
125  Log::info() << "LinearModel configuration is:" << params << std::endl;
127  Log::trace() << "LinearModel<MODEL>::LinearModel done" << std::endl;
128 }
129 
130 // -----------------------------------------------------------------------------
131 
132 template<typename MODEL>
133 LinearModel<MODEL>::LinearModel(const Geometry_ & resol, const eckit::Configuration & conf)
134  : LinearModel(resol,
135  validateAndDeserialize<LinearModelParametersWrapper<MODEL>>(conf).modelParameters)
136 {}
137 
138 // -----------------------------------------------------------------------------
139 
140 template<typename MODEL>
142  Log::trace() << "LinearModel<MODEL>::~LinearModel starting" << std::endl;
143  util::Timer timer(classname(), "~LinearModel");
144  tlm_.reset();
145  Log::trace() << "LinearModel<MODEL>::~LinearModel done" << std::endl;
146 }
147 
148 // -----------------------------------------------------------------------------
149 
150 // -----------------------------------------------------------------------------
151 /// Run forecast TL and AD
152 // -----------------------------------------------------------------------------
153 
154 template<typename MODEL>
156  const util::Duration & len,
159  const bool idmodel) const {
160  Log::trace() << "LinearModel<MODEL>::forecastTL starting" << std::endl;
161 
162  const util::DateTime end(dx.validTime() + len);
163  const util::Duration tstep(tlm_->timeResolution());
164  Log::info() << "LinearModel<MODEL>::forecastTL: Starting " << dx << std::endl;
165  this->initializeTL(dx);
166  cost.initializeTL(dx, end, tstep);
167  post.initialize(dx, end, tstep);
168  cost.processTL(dx);
169  post.process(dx);
170  if (idmodel) {
171  while (dx.validTime() < end) {
172  dx.updateTime(tstep);
173  cost.processTL(dx);
174  post.process(dx);
175  }
176  } else {
177  while (dx.validTime() < end) {
178  this->stepTL(dx, mctl);
179  cost.processTL(dx);
180  post.process(dx);
181  }
182  }
183  cost.finalizeTL(dx);
184  post.finalize(dx);
185  this->finalizeTL(dx);
186  Log::info() << "LinearModel<MODEL>::forecastTL: Finished " << dx << std::endl;
187  ASSERT(dx.validTime() == end);
188 
189  Log::trace() << "LinearModel<MODEL>::forecastTL done" << std::endl;
190 }
191 
192 // -----------------------------------------------------------------------------
193 
194 template<typename MODEL>
196  const util::Duration & len,
199  const bool idmodel) const {
200  Log::trace() << "LinearModel<MODEL>::forecastAD starting" << std::endl;
201 
202  const util::DateTime bgn(dx.validTime() - len);
203  const util::Duration tstep(tlm_->timeResolution());
204  Log::info() << "LinearModel<MODEL>::forecastAD: Starting " << dx << std::endl;
205  this->initializeAD(dx);
206  post.initialize(dx, bgn, tstep);
207  cost.initializeAD(dx, bgn, tstep);
208  if (idmodel) {
209  while (dx.validTime() > bgn) {
210  cost.processAD(dx);
211  dx.updateTime(-tstep);
212  post.process(dx);
213  }
214  } else {
215  while (dx.validTime() > bgn) {
216  cost.processAD(dx);
217  this->stepAD(dx, mctl);
218  post.process(dx);
219  }
220  }
221  cost.processAD(dx);
222  post.process(dx);
223  cost.finalizeAD(dx);
224  post.finalize(dx);
225  this->finalizeAD(dx);
226  Log::info() << "LinearModel<MODEL>::forecastAD: Finished " << dx << std::endl;
227  ASSERT(dx.validTime() == bgn);
228 
229  Log::trace() << "LinearModel<MODEL>::forecastAD done" << std::endl;
230 }
231 
232 // -----------------------------------------------------------------------------
233 
234 template<typename MODEL>
236  const ModelAux_ & maux) {
237  Log::trace() << "LinearModel<MODEL>::setTrajectory starting" << std::endl;
238  util::Timer timer(classname(), "setTrajectory");
239  tlm_->setTrajectory(xx, xlr, maux);
240  Log::trace() << "LinearModel<MODEL>::setTrajectory done" << std::endl;
241 }
242 
243 // -----------------------------------------------------------------------------
244 
245 template<typename MODEL>
247  Log::trace() << "LinearModel<MODEL>::initializeTL starting" << std::endl;
248  util::Timer timer(classname(), "initializeTL");
249  tlm_->initializeTL(dx);
250  Log::trace() << "LinearModel<MODEL>::initializeTL done" << std::endl;
251 }
252 
253 // -----------------------------------------------------------------------------
254 
255 template<typename MODEL>
256 void LinearModel<MODEL>::stepTL(Increment_ & dx, const ModelAuxIncr_ & merr) const {
257  Log::trace() << "LinearModel<MODEL>::stepTL starting" << std::endl;
258  util::Timer timer(classname(), "stepTL");
259  tlm_->stepTL(dx, merr);
260  Log::trace() << "LinearModel<MODEL>::stepTL done" << std::endl;
261 }
262 
263 // -----------------------------------------------------------------------------
264 
265 template<typename MODEL>
267  Log::trace() << "LinearModel<MODEL>::finalizeTL starting" << std::endl;
268  util::Timer timer(classname(), "finalizeTL");
269  tlm_->finalizeTL(dx);
270  Log::trace() << "LinearModel<MODEL>::finalizeTL done" << std::endl;
271 }
272 
273 // -----------------------------------------------------------------------------
274 
275 template<typename MODEL>
277  Log::trace() << "LinearModel<MODEL>::initializeAD starting" << std::endl;
278  util::Timer timer(classname(), "initializeAD");
279  tlm_->initializeAD(dx);
280  Log::trace() << "LinearModel<MODEL>::initializeAD done" << std::endl;
281 }
282 
283 // -----------------------------------------------------------------------------
284 
285 template<typename MODEL>
287  Log::trace() << "LinearModel<MODEL>::stepAD starting" << std::endl;
288  util::Timer timer(classname(), "stepAD");
289  tlm_->stepAD(dx, merr);
290  Log::trace() << "LinearModel<MODEL>::stepAD done" << std::endl;
291 }
292 
293 // -----------------------------------------------------------------------------
294 
295 template<typename MODEL>
297  Log::trace() << "LinearModel<MODEL>::finalizeAD starting" << std::endl;
298  util::Timer timer(classname(), "finalizeAD");
299  tlm_->finalizeAD(dx);
300  Log::trace() << "LinearModel<MODEL>::finalizeAD done" << std::endl;
301 }
302 
303 // -----------------------------------------------------------------------------
304 
305 template<typename MODEL>
306 void LinearModel<MODEL>::print(std::ostream & os) const {
307  Log::trace() << "LinearModel<MODEL>::print starting" << std::endl;
308  util::Timer timer(classname(), "print");
309  os << *tlm_;
310  Log::trace() << "LinearModel<MODEL>::print done" << std::endl;
311 }
312 
313 // -----------------------------------------------------------------------------
314 
315 } // namespace oops
316 
317 #endif // OOPS_INTERFACE_LINEARMODEL_H_
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
Base class for encapsulation of the linear forecast model.
Tangent linear model factory.
Encapsulates the linear forecast model.
void initializeTL(Increment_ &) const
static const std::string classname()
void forecastAD(Increment_ &, ModelAuxIncr_ &, const util::Duration &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), PostProcessorTLAD< MODEL > cost=PostProcessorTLAD< MODEL >(), const bool idmodel=false) const
Run the adjoint forecast.
LinearModelBase< MODEL > LinearModelBase_
void finalizeAD(Increment_ &) const
const util::Duration & timeResolution() const
void stepTL(Increment_ &, const ModelAuxIncr_ &) const
void stepAD(Increment_ &, ModelAuxIncr_ &) const
ModelAuxControl< MODEL > ModelAux_
void finalizeTL(Increment_ &) const
const oops::Variables & variables() const
ModelAuxIncrement< MODEL > ModelAuxIncr_
void forecastTL(Increment_ &, const ModelAuxIncr_ &, const util::Duration &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), PostProcessorTLAD< MODEL > cost=PostProcessorTLAD< MODEL >(), const bool idmodel=false) const
Run the tangent linear forecast.
void initializeAD(Increment_ &) const
LinearModel(const Geometry_ &, const LinearModelParametersBase &)
void setTrajectory(const State_ &, State_ &, const ModelAux_ &)
std::unique_ptr< LinearModelBase_ > tlm_
Increment< MODEL > Increment_
void print(std::ostream &) const
Base class for classes storing model-specific parameters.
Contains a polymorphic parameter holding an instance of a subclass of LinearModelParametersBase.
Control model post processing.
Definition: PostProcessor.h:30
void process(const FLDS &xx)
Definition: PostProcessor.h:56
void finalize(const FLDS &xx)
Definition: PostProcessor.h:62
void initialize(const FLDS &xx, const util::DateTime &end, const util::Duration &step)
Definition: PostProcessor.h:49
Control model post processing.
void finalizeAD(Increment_ &dx)
void processTL(const Increment_ &dx)
void processAD(Increment_ &dx)
void finalizeTL(const Increment_ &dx)
void initializeTL(const Increment_ &dx, const util::DateTime &end, const util::Duration &step)
Tangent linear methods.
void initializeAD(Increment_ &dx, const util::DateTime &bgn, const util::Duration &step)
Adjoint methods.
State class used in oops; subclass of interface class interface::State.
void updateTime(const util::Duration &dt)
Updates this Increment's valid time by dt (used in PseudoModel)
const util::DateTime validTime() const
Accessor to the time of this Increment.
The namespace for the main oops code.