FV3 Bundle
CostFct4DEnsVar.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_ASSIMILATION_COSTFCT4DENSVAR_H_
12 #define OOPS_ASSIMILATION_COSTFCT4DENSVAR_H_
13 
14 #include <map>
15 
16 #include "eckit/config/LocalConfiguration.h"
25 #include "oops/base/StateInfo.h"
26 #include "oops/base/Variables.h"
29 #include "oops/interface/Model.h"
30 #include "oops/interface/State.h"
31 #include "oops/util/DateTime.h"
32 #include "oops/util/Duration.h"
33 #include "oops/util/Logger.h"
34 
35 namespace oops {
36 
37 /// 4D-Ens-Var Cost Function
38 /*!
39  * Although so far only used for 4D-Ens-Var this cost function can
40  * be interpreted more generally as a four dimensional 3D-Var in the
41  * sense that the control variable is 4D (like weak-constraint 4D-Var)
42  * but the observation operator is 3D (does not involve the forecast
43  * model).
44  */
45 
46 // -----------------------------------------------------------------------------
47 
48 template<typename MODEL> class CostFct4DEnsVar : public CostFunction<MODEL> {
57 
58  public:
59  CostFct4DEnsVar(const eckit::Configuration &, const Geometry_ &, const Model_ &);
61 
64  const bool idModel = false) const override;
67  const bool idModel = false) const override;
68  void zeroAD(CtrlInc_ &) const override;
69 
70  void runNL(CtrlVar_ &, PostProcessor<State_>&) const override;
71 
72  private:
73  void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor<Increment_>&) const override;
74 
75  CostJb4D<MODEL> * newJb(const eckit::Configuration &, const Geometry_ &,
76  const CtrlVar_ &) const override;
77  CostJo<MODEL> * newJo(const eckit::Configuration &) const override;
78  CostTermBase<MODEL> * newJc(const eckit::Configuration &, const Geometry_ &) const override;
79  void doLinearize(const Geometry_ &, const eckit::Configuration &,
80  const CtrlVar_ &, const CtrlVar_ &) override;
81 
82  util::Duration windowLength_;
83  util::DateTime windowBegin_;
84  util::DateTime windowEnd_;
85  util::Duration windowSub_;
86  util::Duration zero_;
87  unsigned int ncontrol_;
89  boost::scoped_ptr<ChangeVar_> an2model_;
90 };
91 
92 // =============================================================================
93 
94 template<typename MODEL>
95 CostFct4DEnsVar<MODEL>::CostFct4DEnsVar(const eckit::Configuration & config,
96  const Geometry_ & resol, const Model_ & model)
97  : CostFunction<MODEL>::CostFunction(config, resol, model), zero_(0), ctlvars_(config), an2model_()
98 {
99  windowLength_ = util::Duration(config.getString("window_length"));
100  windowBegin_ = util::DateTime(config.getString("window_begin"));
102  windowSub_ = util::Duration(config.getString("window_sub"));
103 
104  ncontrol_ = windowLength_.toSeconds() / windowSub_.toSeconds();
105  ASSERT(windowLength_.toSeconds() == windowSub_.toSeconds()*ncontrol_);
106 
107  this->setupTerms(config);
108  Log::trace() << "CostFct4DEnsVar constructed" << std::endl;
109 }
110 
111 // -----------------------------------------------------------------------------
112 
113 template <typename MODEL>
114 CostJb4D<MODEL> * CostFct4DEnsVar<MODEL>::newJb(const eckit::Configuration & jbConf,
115  const Geometry_ & resol,
116  const CtrlVar_ & xb) const {
117  return new CostJb4D<MODEL>(jbConf, resol, ctlvars_, zero_, xb.state());
118 }
119 
120 // -----------------------------------------------------------------------------
121 
122 template <typename MODEL>
123 CostJo<MODEL> * CostFct4DEnsVar<MODEL>::newJo(const eckit::Configuration & joConf) const {
124  return new CostJo<MODEL>(joConf, windowBegin_, windowEnd_, windowSub_, true);
125 }
126 
127 // -----------------------------------------------------------------------------
128 
129 template <typename MODEL>
130 CostTermBase<MODEL> * CostFct4DEnsVar<MODEL>::newJc(const eckit::Configuration & jcConf,
131  const Geometry_ & resol) const {
132  const eckit::LocalConfiguration jcdfi(jcConf, "jcdfi");
133  const util::DateTime vt(windowBegin_ + windowLength_/2);
134  return new CostJcDFI<MODEL>(jcdfi, resol, vt, windowLength_, windowSub_);
135 }
136 
137 // -----------------------------------------------------------------------------
138 
139 template <typename MODEL>
141  PostProcessor<State_> & post) const {
142  State_ xm(xx.state()[0].geometry(), CostFct_::getModel().variables(), windowBegin_);
143  for (unsigned int jsub = 0; jsub <= ncontrol_; ++jsub) {
144  util::DateTime now(windowBegin_ + jsub*windowSub_);
145 
146  ASSERT(xx.state()[jsub].validTime() == now);
147  xm = xx.state()[jsub];
148  CostFct_::getModel().forecast(xm, xx.modVar(), util::Duration(0), post);
149  xx.state()[jsub] = xm;
150  ASSERT(xx.state()[jsub].validTime() == now);
151  }
152 }
153 
154 // -----------------------------------------------------------------------------
155 
156 template<typename MODEL>
158  const eckit::Configuration & innerConf,
159  const CtrlVar_ & bg, const CtrlVar_ & fg) {
160  Log::trace() << "CostFct4DEnsVar::doLinearize start" << std::endl;
161  eckit::LocalConfiguration conf(innerConf, "linearmodel");
162  an2model_.reset(LinearVariableChangeFactory<MODEL>::create(bg.state()[0], fg.state()[0],
163  resol, conf));
164  an2model_->setInputVariables(ctlvars_);
165  an2model_->setOutputVariables(CostFct_::getTLM().variables());
166  Log::trace() << "CostFct4DEnsVar::doLinearize done" << std::endl;
167 }
168 
169 // -----------------------------------------------------------------------------
170 
171 template <typename MODEL>
175  const bool) const {
176  Increment_ dxmodel(dx.state()[0].geometry(), CostFct_::getTLM().variables(), windowBegin_);
177 
178  for (unsigned int jsub = 0; jsub <= ncontrol_; ++jsub) {
179  util::DateTime now(windowBegin_ + jsub*windowSub_);
180 
181  ASSERT(dx.state()[jsub].validTime() == now);
182  an2model_->multiply(dx.state()[jsub], dxmodel);
183  CostFct_::getTLM(jsub).forecastTL(dxmodel, dx.modVar(), util::Duration(0), post, cost);
184  an2model_->multiplyInverse(dxmodel, dx.state()[jsub]);
185  ASSERT(dx.state()[jsub].validTime() == now);
186  }
187 }
188 
189 // -----------------------------------------------------------------------------
190 
191 template <typename MODEL>
193  util::DateTime now(windowBegin_);
194  for (unsigned int jsub = 0; jsub <= ncontrol_; ++jsub) {
195  dx.state()[jsub].zero(now);
196  now += windowSub_;
197  }
198  dx.modVar().zero();
199  dx.obsVar().zero();
200 }
201 
202 // -----------------------------------------------------------------------------
203 
204 template <typename MODEL>
208  const bool) const {
209  Increment_ dxmodel(dx.state()[0].geometry(), CostFct_::getTLM().variables(), windowEnd_);
210 
211  for (int jsub = ncontrol_; jsub >= 0; --jsub) {
212  util::DateTime now(windowBegin_ + jsub*windowSub_);
213 
214  ASSERT(dx.state()[jsub].validTime() == now);
215  an2model_->multiplyInverseAD(dx.state()[jsub], dxmodel);
216  CostFct_::getTLM(jsub).forecastAD(dxmodel, dx.modVar(), util::Duration(0), post, cost);
217  an2model_->multiplyAD(dxmodel, dx.state()[jsub]);
218  ASSERT(dx.state()[jsub].validTime() == now);
219  }
220 }
221 
222 // -----------------------------------------------------------------------------
223 
224 template<typename MODEL>
226  PostProcessor<Increment_> &) const {
227  for (unsigned jsub = 0; jsub <= ncontrol_; ++jsub) {
228  xx.state()[jsub] += dx.state()[jsub];
229  }
230 }
231 
232 // -----------------------------------------------------------------------------
233 
234 } // namespace oops
235 
236 #endif // OOPS_ASSIMILATION_COSTFCT4DENSVAR_H_
void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > &) const override
State4D_ & state()
Get state control variable.
ControlIncrement< MODEL > CtrlInc_
void zeroAD(CtrlInc_ &) const override
State< MODEL > State_
4D-Ens-Var Cost Function
Increment< MODEL > Increment_
ObsAuxIncr_ & obsVar()
Get augmented observation control variable.
ModelAuxIncr_ & modVar()
Get augmented model control variable.
void doLinearize(const Geometry_ &, const eckit::Configuration &, const CtrlVar_ &, const CtrlVar_ &) override
Model< MODEL > Model_
util::Duration zero_
Definition: conf.py:1
void runNL(CtrlVar_ &, PostProcessor< State_ > &) const override
Geometry< MODEL > Geometry_
util::Duration windowSub_
void runTLM(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
Cost Function.
Definition: CostFunction.h:56
Encapsulates the model state.
boost::scoped_ptr< ChangeVar_ > an2model_
Jc DFI Cost Function.
Definition: CostJcDFI.h:45
Control variable.
LinearVariableChangeBase< MODEL > ChangeVar_
CostFunction< MODEL > CostFct_
The namespace for the main oops code.
ControlVariable< MODEL > CtrlVar_
ModelAux_ & modVar()
Get augmented model control variable.
real, dimension(:,:,:), allocatable vt
Increment4D_ & state()
Get state control variable.
real(fp), parameter xb
Definition: ufo_aod_mod.F90:41
util::DateTime windowEnd_
CostTermBase< MODEL > * newJc(const eckit::Configuration &, const Geometry_ &) const override
CostJb4D< MODEL > * newJb(const eckit::Configuration &, const Geometry_ &, const CtrlVar_ &) const override
LinearVariableChangeFactory Factory.
Control model post processing.
Base class for generic variable transform.
Encapsulates the nonlinear forecast model.
enddo ! cludge for now
CostFct4DEnsVar(const eckit::Configuration &, const Geometry_ &, const Model_ &)
const Variables ctlvars_
Increment Class: Difference between two states.
Jo Cost Function.
Definition: CostJo.h:54
Base Class for Cost Function Terms.
Definition: CostTermBase.h:37
Geometry_ geometry() const
Get geometry.
Definition: Increment4D.h:73
4D Jb Cost Function
Definition: CostJb4D.h:45
Control model post processing.
Definition: PostProcessor.h:31
CostJo< MODEL > * newJo(const eckit::Configuration &) const override
void setupTerms(const eckit::Configuration &)
Definition: CostFunction.h:212
void runADJ(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
util::DateTime windowBegin_
util::Duration windowLength_