OOPS
oops/interface/VariableChange.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2018-2021 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_INTERFACE_VARIABLECHANGE_H_
9 #define OOPS_INTERFACE_VARIABLECHANGE_H_
10 
11 #include <memory>
12 #include <string>
13 
14 #include "oops/base/Geometry.h"
15 #include "oops/base/State.h"
18 #include "oops/base/Variables.h"
19 #include "oops/util/Logger.h"
20 #include "oops/util/ObjectCounter.h"
21 #include "oops/util/Printable.h"
22 #include "oops/util/Timer.h"
23 
24 namespace eckit {
25  class Configuration;
26 }
27 
28 namespace oops {
29 
30 /// \brief Encapsulates the nonlinear variable change
31 /// Note: to see methods that need to be implemented in the implementation,
32 /// see VariableChangeBase class.
33 template <typename MODEL>
34 class VariableChange : public util::Printable,
35  private util::ObjectCounter<VariableChange<MODEL> > {
39 
40  public:
41  static const std::string classname() {return "oops::VariableChange";}
42 
44  VariableChange(const Geometry_ &, const eckit::Configuration &);
45  virtual ~VariableChange();
46  VariableChange(const VariableChange &) = delete;
48  const VariableChange & operator=(const VariableChange &) = delete;
50 
51  /// change variable from state \p xin to \p xout
52  void changeVar(const State_ & xin, State_ & xout) const;
53  /// inverse of changeVar, change variables back from \p xout to \p xin
54  void changeVarInverse(const State_ & xout, State_ & xin) const;
55 
56  /// return change of variable \p xin
57  State_ changeVar(const State_ & xin) const;
58  /// return inverse of variable change applied to \p xout
59  State_ changeVarInverse(const State_ & xout) const;
60 
61  private:
62  void print(std::ostream &) const override;
63 
64  std::unique_ptr<VariableChangeBase_> chvar_; /// pointer to the VariableChange implementation
65  std::unique_ptr<Variables> varin_; /// input variables
66  std::unique_ptr<Variables> varout_; /// output variables
67 };
68 
69 // =============================================================================
70 
71 template<typename MODEL>
73  const VariableChangeParametersBase & params)
74  : chvar_()
75 {
76  Log::trace() << "VariableChange<MODEL>::VariableChange starting" << std::endl;
77  util::Timer timer(classname(), "VariableChange");
78  if (params.inputVariables.value() != boost::none) {
79  varin_.reset(new Variables(*params.inputVariables.value()));
80  Log::debug() << "VariableChange::VariableChange input variables: " << *varin_ << std::endl;
81  }
82  if (params.outputVariables.value() != boost::none) {
83  varout_.reset(new Variables(*params.outputVariables.value()));
84  Log::debug() << "VariableChange::VariableChange output variables: " << *varout_ << std::endl;
85  }
86  chvar_.reset(VariableChangeFactory<MODEL>::create(geom, params));
87  Log::trace() << "VariableChange<MODEL>::VariableChange done" << std::endl;
88 }
89 
90 // -----------------------------------------------------------------------------
91 
92 template<typename MODEL>
93 VariableChange<MODEL>::VariableChange(const Geometry_ & geom, const eckit::Configuration & conf)
94  : VariableChange(geom,
95  validateAndDeserialize<VariableChangeParametersWrapper<MODEL>>(conf).variableChangeParameters)
96 {}
97 
98 // -----------------------------------------------------------------------------
99 
100 template<typename MODEL>
102  Log::trace() << "VariableChange<MODEL>::~VariableChange starting" << std::endl;
103  util::Timer timer(classname(), "~VariableChange");
104  chvar_.reset();
105  Log::trace() << "VariableChange<MODEL>::~VariableChange done" << std::endl;
106 }
107 
108 // -----------------------------------------------------------------------------
109 
110 template<typename MODEL>
111 void VariableChange<MODEL>::changeVar(const State_ & x1, State_ & x2) const {
112  Log::trace() << "VariableChange<MODEL>::changeVar starting" << std::endl;
113  util::Timer timer(classname(), "changeVar");
114  chvar_->changeVar(x1, x2);
115  Log::trace() << "VariableChange<MODEL>::changeVar done" << std::endl;
116 }
117 
118 // -----------------------------------------------------------------------------
119 
120 template<typename MODEL>
122  Log::trace() << "VariableChange<MODEL>::changeVarInverse starting" << std::endl;
123  util::Timer timer(classname(), "changeVarInverse");
124  chvar_->changeVarInverse(x1, x2);
125  Log::trace() << "VariableChange<MODEL>::changeVarInverse done" << std::endl;
126 }
127 
128 // -----------------------------------------------------------------------------
129 
130 template<typename MODEL>
132  Log::trace() << "VariableChange<MODEL>::changeVar starting" << std::endl;
133  ASSERT(varout_);
134  State_ xout(xin.geometry(), *varout_, xin.validTime());
135  this->changeVar(xin, xout);
136  Log::trace() << "VariableChange<MODEL>::changeVar done" << std::endl;
137  return xout;
138 }
139 
140 // -----------------------------------------------------------------------------
141 
142 template<typename MODEL>
144  Log::trace() << "VariableChange<MODEL>::changeVarInverse starting" << std::endl;
145  ASSERT(varin_);
146  State_ xout(xin.geometry(), *varin_, xin.validTime());
147  this->changeVarInverse(xin, xout);
148  Log::trace() << "VariableChange<MODEL>::changeVarInverse done" << std::endl;
149  return xout;
150 }
151 
152 // -----------------------------------------------------------------------------
153 
154 template<typename MODEL>
155 void VariableChange<MODEL>::print(std::ostream & os) const {
156  Log::trace() << "VariableChange<MODEL>::print starting" << std::endl;
157  util::Timer timer(classname(), "print");
158  os << *chvar_;
159  if (varin_) os << std::endl << "Variable change from: " << *varin_;
160  if (varout_) os << std::endl << "Variable change to: " << *varout_;
161  if (varin_ || varout_) os << std::endl;
162  Log::trace() << "VariableChange<MODEL>::print done" << std::endl;
163 }
164 
165 // -----------------------------------------------------------------------------
166 
167 } // namespace oops
168 
169 #endif // OOPS_INTERFACE_VARIABLECHANGE_H_
Geometry class used in oops; subclass of interface class interface::Geometry.
State class used in oops; subclass of interface class interface::State.
VariableChange factory.
Encapsulates the nonlinear variable change Note: to see methods that need to be implemented in the im...
std::unique_ptr< VariableChangeBase_ > chvar_
void changeVar(const State_ &xin, State_ &xout) const
change variable from state xin to xout
void changeVarInverse(const State_ &xout, State_ &xin) const
inverse of changeVar, change variables back from xout to xin
GenericVariableChangeBase< MODEL > VariableChangeBase_
VariableChange(VariableChange &&)=default
VariableChange & operator=(VariableChange &&)=default
VariableChange(const Geometry_ &, const VariableChangeParametersBase &)
void print(std::ostream &) const override
static const std::string classname()
std::unique_ptr< Variables > varin_
pointer to the VariableChange implementation
VariableChange(const VariableChange &)=delete
const VariableChange & operator=(const VariableChange &)=delete
std::unique_ptr< Variables > varout_
input variables
Base class of classes storing parameters controlling specific variable changes.
OptionalParameter< Variables > inputVariables
OptionalParameter< Variables > outputVariables
Contains a polymorphic parameter holding an instance of a subclass of VariableChangeParametersBase.
Geometry_ geometry() const
Accessor to geometry associated with this State.
const util::DateTime validTime() const
Accessor to the time of this State.
Definition: FieldL95.h:22
The namespace for the main oops code.