Loading [MathJax]/extensions/tex2jax.js
OOPS
All Classes Namespaces Files Functions Variables Typedefs Macros Pages
generic/LinearModelBase.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2018-2020 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_GENERIC_LINEARMODELBASE_H_
9 #define OOPS_GENERIC_LINEARMODELBASE_H_
10 
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 #include <boost/make_unique.hpp>
17 #include <boost/noncopyable.hpp>
18 
19 #include "oops/base/Geometry.h"
20 #include "oops/base/Increment.h"
21 #include "oops/base/State.h"
24 #include "oops/util/AssociativeContainers.h"
25 #include "oops/util/Duration.h"
26 #include "oops/util/Logger.h"
27 #include "oops/util/parameters/ConfigurationParameter.h"
28 #include "oops/util/parameters/HasParameters_.h"
29 #include "oops/util/parameters/OptionalParameter.h"
30 #include "oops/util/parameters/Parameters.h"
31 #include "oops/util/parameters/ParametersOrConfiguration.h"
32 #include "oops/util/parameters/RequiredPolymorphicParameter.h"
33 #include "oops/util/Printable.h"
34 
35 namespace eckit {
36  class Configuration;
37 }
38 
39 namespace oops {
40 
41 // -----------------------------------------------------------------------------
42 
43 /// \brief Base class for generic implementations of the linearized forecasting models.
44 /// Use this class as a base class for generic implementations,
45 /// and interface::LinearModelBase as a base class for MODEL-specific implementations.
46 ///
47 /// Note: implementations of this interface can opt to extract their settings either from
48 /// a Configuration object or from a subclass of LinearModelParametersBase.
49 ///
50 /// In the former case, they should provide a constructor with the following signature:
51 ///
52 /// LinearModelBase(const Geometry_ &, const eckit::Configuration &);
53 ///
54 /// In the latter case, the implementer should first define a subclass of LinearModelParametersBase
55 /// holding the settings of the linear model in question. The implementation of the LinearModelBase
56 /// interface should then typedef `Parameters_` to the name of that subclass and provide a
57 /// constructor with the following signature:
58 ///
59 /// LinearModelBase(const Geometry_ &, const Parameters_ &);
60 ///
61 template <typename MODEL>
62 class LinearModelBase : public util::Printable,
63  private boost::noncopyable {
68 
69  public:
70  static const std::string classname() {return "oops::LinearModelBase";}
71 
72  LinearModelBase() = default;
73  virtual ~LinearModelBase() = default;
74 
75  /// \brief Tangent linear initialization, called before every run
76  virtual void initializeTL(Increment_ &) const = 0;
77  /// \brief Tangent linear "step", called during run; updates increment to the next time
78  virtual void stepTL(Increment_ &, const ModelAuxInc_ &) const = 0;
79  /// \brief Tangent linear finalization; called after each run
80  virtual void finalizeTL(Increment_ &) const = 0;
81 
82  /// \brief Tangent linear initialization, called before every run
83  virtual void initializeAD(Increment_ &) const = 0;
84  /// \brief Tangent linear "step", called during run; updates increment to the next time
85  virtual void stepAD(Increment_ &, ModelAuxInc_ &) const = 0;
86  /// \brief Tangent linear finalization; called after each run
87  virtual void finalizeAD(Increment_ &) const = 0;
88 
89  /// \brief Set the trajectory for the linear model, called after each step of the forecast
90  virtual void setTrajectory(const State_ &, State_ &, const ModelAuxCtl_ &) = 0;
91 
92  /// \brief Time step for running LinearModel's forecast in oops (frequency with which the
93  /// increment will be updated)
94  virtual const util::Duration & timeResolution() const = 0;
95  /// \brief LinearModel variables (only used in 4DVar)
96  virtual const oops::Variables & variables() const = 0;
97 
98  private:
99  /// \brief Print; used for logging
100  virtual void print(std::ostream &) const = 0;
101 };
102 
103 // =============================================================================
104 
105 template <typename MODEL>
106 class LinearModelFactory;
107 
108 // -----------------------------------------------------------------------------
109 
110 /// \brief Base class for classes storing linear model-specific parameters.
111 class LinearModelParametersBase : public Parameters {
112  OOPS_ABSTRACT_PARAMETERS(LinearModelParametersBase, Parameters)
113  public:
114  /// \brief LinearModel name.
115  ///
116  /// \note This parameter is marked as optional because it is only required in certain
117  /// circumstances (e.g. when linear model parameters are deserialized into a
118  /// LinearModelParametersWrapper and used by LinearModelFactory to instantiate a linear model
119  /// whose type is determined at runtime), but not others (e.g. in tests written with a particular
120  /// linear model in mind). LinearModelParametersWrapper will throw an exception if this parameter
121  /// is not provided.
122  OptionalParameter<std::string> name{"name", this};
123 };
124 
125 // -----------------------------------------------------------------------------
126 
127 /// \brief A subclass of LinearModelParametersBase storing the values of all options in a
128 /// single Configuration object.
129 ///
130 /// This object can be accessed by calling the value() method of the \p config member variable.
131 ///
132 /// The ConfigurationParameter class does not perform any parameter validation; linear models using
133 /// GenericLinearModelParameters should therefore ideally be refactored, replacing this class with a
134 /// dedicated subclass of LinearModelParametersBase storing each parameter in a separate
135 /// (Optional/Required)Parameter object.
138  public:
139  ConfigurationParameter config{this};
140 };
141 
142 // -----------------------------------------------------------------------------
143 
144 /// \brief Contains a polymorphic parameter holding an instance of a subclass of
145 /// LinearModelParametersBase.
146 template <typename MODEL>
147 class LinearModelParametersWrapper : public Parameters {
148  OOPS_CONCRETE_PARAMETERS(LinearModelParametersWrapper, Parameters)
149  public:
150  /// After deserializtion, holds an instance of a subclass of LinearModelParametersBase controlling
151  /// the behavior of a linear model. The type of the subclass is determined by the value of the
152  /// "name" key in the Configuration object from which this object is deserialized.
153  RequiredPolymorphicParameter<LinearModelParametersBase, LinearModelFactory<MODEL>>
154  linearModelParameters{"name", this};
155 };
156 
157 // =============================================================================
158 
159 /// LinearModel factory
160 template <typename MODEL>
163 
164  public:
165  /// \brief Create and return a new linear model.
166  ///
167  /// The linear model's type is determined by the \c name attribute of \p parameters.
168  /// \p parameters must be an instance of the subclass of LinearModelParametersBase
169  /// associated with that linear model type, otherwise an exception will be thrown.
170  static LinearModelBase<MODEL> * create(const Geometry_ &,
171  const LinearModelParametersBase & parameters);
172 
173  /// \brief Create and return an instance of the subclass of LinearModelParametersBase
174  /// storing parameters of linear models of the specified type.
175  static std::unique_ptr<LinearModelParametersBase> createParameters(const std::string &name);
176 
177  /// \brief Return the names of all linear models that can be created by one of the registered
178  /// makers.
179  static std::vector<std::string> getMakerNames() {
180  return keys(getMakers());
181  }
182 
183  virtual ~LinearModelFactory() = default;
184 
185  protected:
186  /// \brief Register a maker able to create linear models of type \p name.
187  explicit LinearModelFactory(const std::string & name);
188 
189  private:
191 
192  virtual std::unique_ptr<LinearModelParametersBase> makeParameters() const = 0;
193 
194  static std::map < std::string, LinearModelFactory<MODEL> * > & getMakers() {
195  static std::map < std::string, LinearModelFactory<MODEL> * > makers_;
196  return makers_;
197  }
198 };
199 
200 // -----------------------------------------------------------------------------
201 
202 /// \brief A subclass of LinearModelFactory able to create instances of T (a concrete subclass of
203 /// LinearModelBase<MODEL>). Passes Geometry<MODEL> to the constructor of T.
204 template<class MODEL, class T>
205 class LinearModelMaker : public LinearModelFactory<MODEL> {
206  private:
207  /// Defined as T::Parameters_ if T defines a Parameters_ type; otherwise as
208  /// GenericLinearModelParameters.
209  typedef TParameters_IfAvailableElseFallbackType_t<T, GenericLinearModelParameters> Parameters_;
210 
211  public:
213 
214  explicit LinearModelMaker(const std::string & name) : LinearModelFactory<MODEL>(name) {}
215 
217  const LinearModelParametersBase & parameters) override {
218  Log::trace() << "LinearModelBase<MODEL>::make starting" << std::endl;
219  const auto &stronglyTypedParameters = dynamic_cast<const Parameters_&>(parameters);
220  return new T(geom,
221  parametersOrConfiguration<HasParameters_<T>::value>(stronglyTypedParameters));
222  }
223 
224  std::unique_ptr<LinearModelParametersBase> makeParameters() const override {
225  return boost::make_unique<Parameters_>();
226  }
227 };
228 
229 // -----------------------------------------------------------------------------
230 
231 template <typename MODEL>
233  if (getMakers().find(name) != getMakers().end()) {
234  throw std::runtime_error(name + " already registered in the linear model factory.");
235  }
236  getMakers()[name] = this;
237 }
238 
239 // -----------------------------------------------------------------------------
240 
241 template <typename MODEL>
243  const LinearModelParametersBase & parameters) {
244  Log::trace() << "LinearModelFactory<MODEL>::create starting" << std::endl;
245  const std::string &id = parameters.name.value().value();
246  typename std::map<std::string, LinearModelFactory<MODEL>*>::iterator
247  jerr = getMakers().find(id);
248  if (jerr == getMakers().end()) {
249  throw std::runtime_error(id + " does not exist in the linear model factory");
250  }
251  LinearModelBase<MODEL> * ptr = jerr->second->make(geom, parameters);
252  Log::trace() << "LinearModelFactory<MODEL>::create done" << std::endl;
253  return ptr;
254 }
255 
256 // -----------------------------------------------------------------------------
257 
258 template <typename MODEL>
259 std::unique_ptr<LinearModelParametersBase> LinearModelFactory<MODEL>::createParameters(
260  const std::string &name) {
261  Log::trace() << "LinearModelFactory<MODEL>::createParameters starting" << std::endl;
262  typename std::map<std::string, LinearModelFactory<MODEL>*>::iterator it = getMakers().find(name);
263  if (it == getMakers().end()) {
264  throw std::runtime_error(name + " does not exist in the linear model factory");
265  }
266  return it->second->makeParameters();
267 }
268 
269 // -----------------------------------------------------------------------------
270 
271 } // namespace oops
272 
273 #endif // OOPS_GENERIC_LINEARMODELBASE_H_
A subclass of LinearModelParametersBase storing the values of all options in a single Configuration o...
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
Base class for generic implementations of the linearized forecasting models. Use this class as a base...
virtual void print(std::ostream &) const =0
Print; used for logging.
virtual const oops::Variables & variables() const =0
LinearModel variables (only used in 4DVar)
virtual void setTrajectory(const State_ &, State_ &, const ModelAuxCtl_ &)=0
Set the trajectory for the linear model, called after each step of the forecast.
virtual void initializeAD(Increment_ &) const =0
Tangent linear initialization, called before every run.
virtual void finalizeTL(Increment_ &) const =0
Tangent linear finalization; called after each run.
virtual void finalizeAD(Increment_ &) const =0
Tangent linear finalization; called after each run.
Increment< MODEL > Increment_
ModelAuxIncrement< MODEL > ModelAuxInc_
virtual void initializeTL(Increment_ &) const =0
Tangent linear initialization, called before every run.
virtual void stepTL(Increment_ &, const ModelAuxInc_ &) const =0
Tangent linear "step", called during run; updates increment to the next time.
virtual void stepAD(Increment_ &, ModelAuxInc_ &) const =0
Tangent linear "step", called during run; updates increment to the next time.
virtual const util::Duration & timeResolution() const =0
Time step for running LinearModel's forecast in oops (frequency with which the increment will be upda...
virtual ~LinearModelBase()=default
ModelAuxControl< MODEL > ModelAuxCtl_
static const std::string classname()
LinearModelFactory(const std::string &name)
Register a maker able to create linear models of type name.
virtual ~LinearModelFactory()=default
static LinearModelBase< MODEL > * create(const Geometry_ &, const LinearModelParametersBase &parameters)
Create and return a new linear model.
virtual std::unique_ptr< LinearModelParametersBase > makeParameters() const =0
static std::vector< std::string > getMakerNames()
Return the names of all linear models that can be created by one of the registered makers.
static std::map< std::string, LinearModelFactory< MODEL > * > & getMakers()
virtual LinearModelBase< MODEL > * make(const Geometry_ &, const LinearModelParametersBase &)=0
static std::unique_ptr< LinearModelParametersBase > createParameters(const std::string &name)
Create and return an instance of the subclass of LinearModelParametersBase storing parameters of line...
A subclass of LinearModelFactory able to create instances of T (a concrete subclass of LinearModelBas...
std::unique_ptr< LinearModelParametersBase > makeParameters() const override
LinearModelMaker(const std::string &name)
TParameters_IfAvailableElseFallbackType_t< T, GenericLinearModelParameters > Parameters_
LinearModelBase< MODEL > * make(const Geometry_ &geom, const LinearModelParametersBase &parameters) override
Base class for classes storing linear model-specific parameters.
OptionalParameter< std::string > name
LinearModel name.
Contains a polymorphic parameter holding an instance of a subclass of LinearModelParametersBase.
RequiredPolymorphicParameter< LinearModelParametersBase, LinearModelFactory< MODEL > > linearModelParameters
Auxiliary state related to model (could be e.g. model bias), not used at the moment.
Auxiliary Increment related to model, not used at the moment.
State class used in oops; subclass of interface class interface::State.
Definition: FieldL95.h:22
The namespace for the main oops code.