IODA Bundle
CostFct4DVar.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2009-2016 ECMWF.
3  * (C) Copyright 2020-2021 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_ASSIMILATION_COSTFCT4DVAR_H_
13 #define OOPS_ASSIMILATION_COSTFCT4DVAR_H_
14 
15 #include <memory>
16 
17 #include "eckit/config/LocalConfiguration.h"
18 #include "eckit/mpi/Comm.h"
24 #include "oops/base/Geometry.h"
25 #include "oops/base/Increment.h"
27 #include "oops/base/Model.h"
30 #include "oops/base/State.h"
31 #include "oops/base/StateInfo.h"
33 #include "oops/base/Variables.h"
36 #include "oops/util/DateTime.h"
37 #include "oops/util/Duration.h"
38 #include "oops/util/Logger.h"
39 
40 namespace oops {
41 
42 /// Strong Constraint 4D-Var Cost Function
43 /*!
44  * This class is not really necessary since it is only a special
45  * case of the more general weak constraint 4D-Var cost function
46  * with one sub-window. It is provided for readability.
47  */
48 
49 // -----------------------------------------------------------------------------
50 
51 template<typename MODEL, typename OBS> class CostFct4DVar : public CostFunction<MODEL, OBS> {
62 
63  public:
64  CostFct4DVar(const eckit::Configuration &, const eckit::mpi::Comm &);
66 
69  const bool idModel = false) const override;
72  const bool idModel = false) const override;
73  void zeroAD(CtrlInc_ &) const override;
74 
75  void runNL(CtrlVar_ &, PostProcessor<State_>&) const override;
76 
77  private:
78  void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor<Increment_>&) const override;
79 
80  CostJb3D<MODEL> * newJb(const eckit::Configuration &, const Geometry_ &,
81  const CtrlVar_ &) const override;
82  CostJo<MODEL, OBS> * newJo(const eckit::Configuration &) const override;
83  CostTermBase<MODEL, OBS> * newJc(const eckit::Configuration &, const Geometry_ &) const override;
84  void doLinearize(const Geometry_ &, const eckit::Configuration &,
85  const CtrlVar_ &, const CtrlVar_ &,
87  const Geometry_ & geometry() const override {return resol_;}
88 
89  util::Duration windowLength_;
90  util::DateTime windowBegin_;
91  util::DateTime windowEnd_;
92  const eckit::mpi::Comm & comm_;
96  std::shared_ptr<LinearModel_> tlm_;
98  std::unique_ptr<LinVarCha_> inc2model_;
99 };
100 
101 // =============================================================================
102 
103 template<typename MODEL, typename OBS>
104 CostFct4DVar<MODEL, OBS>::CostFct4DVar(const eckit::Configuration & config,
105  const eckit::mpi::Comm & comm)
106  : CostFunction<MODEL, OBS>::CostFunction(config), comm_(comm),
107  resol_(eckit::LocalConfiguration(config, "geometry"), comm),
108  model_(resol_, eckit::LocalConfiguration(config, "model")),
109  ctlvars_(config, "analysis variables"), tlm_(), an2model_(resol_, config),
110  inc2model_()
111 {
112  Log::trace() << "CostFct4DVar:CostFct4DVar" << std::endl;
113  windowLength_ = util::Duration(config.getString("window length"));
114  windowBegin_ = util::DateTime(config.getString("window begin"));
116  this->setupTerms(config);
117  // ASSERT(ctlvars_ <= this->background().state().variables());
118  Log::trace() << "CostFct4DVar constructed" << std::endl;
119 }
120 
121 // -----------------------------------------------------------------------------
122 
123 template <typename MODEL, typename OBS>
124 CostJb3D<MODEL> * CostFct4DVar<MODEL, OBS>::newJb(const eckit::Configuration & jbConf,
125  const Geometry_ & resol,
126  const CtrlVar_ & xb) const {
127  return new CostJb3D<MODEL>(jbConf, resol, ctlvars_, windowLength_, xb.state());
128 }
129 
130 // -----------------------------------------------------------------------------
131 
132 template <typename MODEL, typename OBS>
133 CostJo<MODEL, OBS> * CostFct4DVar<MODEL, OBS>::newJo(const eckit::Configuration & joConf) const {
134  return new CostJo<MODEL, OBS>(joConf, comm_, windowBegin_, windowEnd_);
135 }
136 
137 // -----------------------------------------------------------------------------
138 
139 template <typename MODEL, typename OBS>
140 CostTermBase<MODEL, OBS> * CostFct4DVar<MODEL, OBS>::newJc(const eckit::Configuration & jcConf,
141  const Geometry_ & resol) const {
142  const eckit::LocalConfiguration jcdfi(jcConf, "jcdfi");
143  const util::DateTime vt(windowBegin_ + windowLength_/2);
144  return new CostJcDFI<MODEL, OBS>(jcdfi, resol, vt, windowLength_);
145 }
146 
147 // -----------------------------------------------------------------------------
148 
149 template <typename MODEL, typename OBS>
151  ASSERT(xx.state().validTime() == windowBegin_);
152 
153  State_ xm(xx.state().geometry(), model_.variables(), windowBegin_);
154  an2model_.changeVar(xx.state(), xm);
155  model_.forecast(xm, xx.modVar(), windowLength_, post);
156  an2model_.changeVarInverse(xm, xx.state());
157 
158  ASSERT(xx.state().validTime() == windowEnd_);
159 }
160 
161 // -----------------------------------------------------------------------------
162 
163 template<typename MODEL, typename OBS>
165  const eckit::Configuration & innerConf,
166  const CtrlVar_ & bg, const CtrlVar_ & fg,
168  PostProcessorTLAD<MODEL> & pptraj) {
169  Log::trace() << "CostFct4DVar::doLinearize start" << std::endl;
170  eckit::LocalConfiguration conf(innerConf, "linear model");
171 // Setup linear model (and trajectory)
172  tlm_.reset(new LinearModel_(resol, conf));
173  pp.enrollProcessor(new TrajectorySaver<MODEL>(conf, resol, fg.modVar(), tlm_, pptraj));
174 
175 // Setup change of variables
176  inc2model_.reset(LinearVariableChangeFactory<MODEL>::create(bg.state(), fg.state(),
177  resol, conf));
178  inc2model_->setInputVariables(ctlvars_);
179  Log::trace() << "CostFct4DVar::doLinearize done" << std::endl;
180 }
181 
182 // -----------------------------------------------------------------------------
183 
184 template <typename MODEL, typename OBS>
188  const bool idModel) const {
189  inc2model_->setOutputVariables(tlm_->variables());
190 
191  ASSERT(dx.state().validTime() == windowBegin_);
192 
193  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), windowBegin_);
194  inc2model_->multiply(dx.state(), dxmodel);
195  tlm_->forecastTL(dxmodel, dx.modVar(), windowLength_, post, cost, idModel);
196  inc2model_->multiplyInverse(dxmodel, dx.state());
197 
198  ASSERT(dx.state().validTime() == windowEnd_);
199 }
200 
201 // -----------------------------------------------------------------------------
202 
203 template <typename MODEL, typename OBS>
205  dx.state().zero(windowEnd_);
206  dx.modVar().zero();
207  dx.obsVar().zero();
208 }
209 
210 // -----------------------------------------------------------------------------
211 
212 template <typename MODEL, typename OBS>
216  const bool idModel) const {
217  ASSERT(dx.state().validTime() == windowEnd_);
218 
219  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), windowEnd_);
220  inc2model_->setOutputVariables(tlm_->variables());
221  inc2model_->multiplyInverseAD(dx.state(), dxmodel);
222  tlm_->forecastAD(dxmodel, dx.modVar(), windowLength_, post, cost, idModel);
223  inc2model_->multiplyAD(dxmodel, dx.state());
224 
225  ASSERT(dx.state().validTime() == windowBegin_);
226 }
227 
228 // -----------------------------------------------------------------------------
229 
230 template<typename MODEL, typename OBS>
232  PostProcessor<Increment_> &) const {
233  xx.state() += dx.state();
234 }
235 
236 // -----------------------------------------------------------------------------
237 
238 } // namespace oops
239 
240 #endif // OOPS_ASSIMILATION_COSTFCT4DVAR_H_
ObsAuxIncrs_ & obsVar()
Get augmented observation control variable.
Increment_ & state()
Get state control variable.
ModelAuxIncr_ & modVar()
Get augmented model control variable.
Control variable.
ModelAux_ & modVar()
Get augmented model control variable.
State_ & state()
Get state control variable.
Strong Constraint 4D-Var Cost Function.
Definition: CostFct4DVar.h:51
VariableChange< MODEL > VarCha_
Definition: CostFct4DVar.h:60
std::shared_ptr< LinearModel_ > tlm_
Definition: CostFct4DVar.h:96
const Variables ctlvars_
Definition: CostFct4DVar.h:95
void runADJ(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
Definition: CostFct4DVar.h:213
CostJb3D< MODEL > * newJb(const eckit::Configuration &, const Geometry_ &, const CtrlVar_ &) const override
Definition: CostFct4DVar.h:124
Geometry< MODEL > Geometry_
Definition: CostFct4DVar.h:56
void runNL(CtrlVar_ &, PostProcessor< State_ > &) const override
Definition: CostFct4DVar.h:150
const Geometry_ & geometry() const override
Definition: CostFct4DVar.h:87
CostFct4DVar(const eckit::Configuration &, const eckit::mpi::Comm &)
Definition: CostFct4DVar.h:104
util::DateTime windowEnd_
Definition: CostFct4DVar.h:91
util::DateTime windowBegin_
Definition: CostFct4DVar.h:90
std::unique_ptr< LinVarCha_ > inc2model_
Definition: CostFct4DVar.h:98
State< MODEL > State_
Definition: CostFct4DVar.h:57
util::Duration windowLength_
Definition: CostFct4DVar.h:89
const eckit::mpi::Comm & comm_
Definition: CostFct4DVar.h:92
ControlIncrement< MODEL, OBS > CtrlInc_
Definition: CostFct4DVar.h:53
Model< MODEL > Model_
Definition: CostFct4DVar.h:58
Increment< MODEL > Increment_
Definition: CostFct4DVar.h:52
void doLinearize(const Geometry_ &, const eckit::Configuration &, const CtrlVar_ &, const CtrlVar_ &, PostProcessor< State_ > &, PostProcessorTLAD< MODEL > &) override
Definition: CostFct4DVar.h:164
void zeroAD(CtrlInc_ &) const override
Definition: CostFct4DVar.h:204
CostFunction< MODEL, OBS > CostFct_
Definition: CostFct4DVar.h:55
LinearModel< MODEL > LinearModel_
Definition: CostFct4DVar.h:59
CostJo< MODEL, OBS > * newJo(const eckit::Configuration &) const override
Definition: CostFct4DVar.h:133
void runTLM(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
Definition: CostFct4DVar.h:185
ControlVariable< MODEL, OBS > CtrlVar_
Definition: CostFct4DVar.h:54
void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > &) const override
Definition: CostFct4DVar.h:231
LinearVariableChangeBase< MODEL > LinVarCha_
Definition: CostFct4DVar.h:61
CostTermBase< MODEL, OBS > * newJc(const eckit::Configuration &, const Geometry_ &) const override
Definition: CostFct4DVar.h:140
Cost Function.
Definition: CostFunction.h:53
void setupTerms(const eckit::Configuration &)
Definition: CostFunction.h:194
Jb Cost Function.
Definition: CostJb3D.h:43
Jc DFI Cost Function.
Definition: CostJcDFI.h:44
Jo Cost Function.
Definition: CostJo.h:52
Base Class for Cost Function Terms.
Definition: CostTermBase.h:36
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
Encapsulates the linear forecast model.
Abstract nonlinear forecast model used by high level algorithms and applications.
Control model post processing.
Definition: PostProcessor.h:30
void enrollProcessor(PostBase_ *pp)
Definition: PostProcessor.h:38
Control model post processing.
State class used in oops; subclass of interface class interface::State.
Save trajectory during forecast run.
Encapsulates the nonlinear variable change Note: to see methods that need to be implemented in the im...
Geometry_ geometry() const
Accessor to geometry associated with this Increment.
void zero()
Zero out this Increment.
const util::DateTime validTime() const
Accessor to the time of this Increment.
Geometry_ geometry() const
Accessor to geometry associated with this State.
const util::DateTime validTime() const
Accessor to the time of this State.
The namespace for the main oops code.