OOPS
CostFctWeak.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_COSTFCTWEAK_H_
12 #define OOPS_ASSIMILATION_COSTFCTWEAK_H_
13 
14 #include <map>
15 #include <memory>
16 #include <string>
17 
18 #include "eckit/config/LocalConfiguration.h"
27 #include "oops/base/StateInfo.h"
30 #include "oops/base/Variables.h"
34 #include "oops/interface/Model.h"
35 #include "oops/interface/State.h"
36 #include "oops/mpi/mpi.h"
37 #include "oops/util/DateTime.h"
38 #include "oops/util/Duration.h"
39 #include "oops/util/Logger.h"
40 
41 namespace oops {
42 
43 /// Weak Constraint 4D-Var Cost Function
44 /*!
45  * General weak constraint constraint 4D-Var cost function.
46  */
47 
48 // -----------------------------------------------------------------------------
49 
50 template<typename MODEL, typename OBS> class CostFctWeak : public CostFunction<MODEL, OBS> {
61 
62  public:
63  CostFctWeak(const eckit::Configuration &, const eckit::mpi::Comm &);
65 
68  const bool idModel = false) const override;
71  const bool idModel = false) const override;
72  void zeroAD(CtrlInc_ &) const override;
73 
74  void runTLM(CtrlInc_ &, const bool idModel = false) const;
75  void runADJ(CtrlInc_ &, const bool idModel = false) const;
76  void runNL(CtrlVar_ &, PostProcessor<State_> &) const override;
77 
78  private:
79  void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor<Increment_> &) const override;
80 
81  CostJbJq<MODEL> * newJb(const eckit::Configuration &, const Geometry_ &,
82  const CtrlVar_ &) const override;
83  CostJo<MODEL, OBS> * newJo(const eckit::Configuration &) const override;
84  CostTermBase<MODEL, OBS> * newJc(const eckit::Configuration &, const Geometry_ &) const override;
85  void doLinearize(const Geometry_ &, const eckit::Configuration &,
86  const CtrlVar_ &, const CtrlVar_ &,
88  const Geometry_ & geometry() const override {return *resol_;}
89 
90  util::Duration subWinLength_;
91  util::DateTime subWinBegin_;
92  util::DateTime subWinEnd_;
93  size_t nsubwin_;
94  size_t mysubwin_;
95  std::unique_ptr<Geometry_> resol_;
96  std::unique_ptr<Model_> model_;
98  std::shared_ptr<LinearModel_> tlm_;
99  std::unique_ptr<VarCha_> an2model_;
100  std::unique_ptr<LinVarCha_> inc2model_;
101  eckit::mpi::Comm * commSpace_;
102  eckit::mpi::Comm * commTime_;
103 };
104 
105 // =============================================================================
106 
107 template<typename MODEL, typename OBS>
108 CostFctWeak<MODEL, OBS>::CostFctWeak(const eckit::Configuration & config,
109  const eckit::mpi::Comm & comm)
110  : CostFunction<MODEL, OBS>::CostFunction(config), resol_(), model_(),
111  ctlvars_(config, "analysis variables"), tlm_(), an2model_(), inc2model_(),
112  commSpace_(nullptr), commTime_(nullptr)
113 {
114  util::Duration windowLength(config.getString("window length"));
115  util::DateTime windowBegin(config.getString("window begin"));
116  subWinLength_ = util::Duration(config.getString("subwindow"));
117 
118  nsubwin_ = windowLength.toSeconds() / subWinLength_.toSeconds();
119  ASSERT(windowLength.toSeconds() == subWinLength_.toSeconds()*nsubwin_);
120 
121  size_t ntasks = comm.size();
122  ASSERT(ntasks % nsubwin_ == 0);
123  size_t myrank = comm.rank();
124  size_t ntaskpslot = ntasks / nsubwin_;
125  size_t mysubwin_ = myrank / ntaskpslot;
126 
127 // Define local sub-window
128  subWinBegin_ = windowBegin + mysubwin_ * subWinLength_;
130 
131 // Create a communicator for same sub-window, to be used for communications in space
132  std::string sgeom = "comm_geom_" + std::to_string(mysubwin_);
133  char const *geomName = sgeom.c_str();
134  commSpace_ = &comm.split(mysubwin_, geomName);
135 
136 // Create a communicator for same local area, to be used for communications in time
137  size_t myarea = commSpace_->rank();
138  std::string stime = "comm_time_" + std::to_string(myarea);
139  char const *timeName = stime.c_str();
140  commTime_ = &comm.split(myarea, timeName);
141  ASSERT(commTime_->size() == nsubwin_);
142 
143 // Now can setup the rest
144  resol_.reset(new Geometry_(eckit::LocalConfiguration(config, "geometry"),
145  *commSpace_, *commTime_));
146  model_.reset(new Model_(*resol_, eckit::LocalConfiguration(config, "model")));
147  this->setupTerms(config);
148 
150 
151  Log::trace() << "CostFctWeak constructed" << std::endl;
152 }
153 
154 // -----------------------------------------------------------------------------
155 
156 template <typename MODEL, typename OBS>
157 CostJbJq<MODEL> * CostFctWeak<MODEL, OBS>::newJb(const eckit::Configuration & jbConf,
158  const Geometry_ & resol,
159  const CtrlVar_ & xb) const {
160  return new CostJbJq<MODEL>(jbConf, *commTime_, resol, ctlvars_, xb.state());
161 }
162 
163 // -----------------------------------------------------------------------------
164 
165 template <typename MODEL, typename OBS>
166 CostJo<MODEL, OBS> * CostFctWeak<MODEL, OBS>::newJo(const eckit::Configuration & joConf) const {
167  return new CostJo<MODEL, OBS>(joConf, *commSpace_,
168  subWinBegin_, subWinEnd_, *commTime_);
169 }
170 
171 // -----------------------------------------------------------------------------
172 
173 template <typename MODEL, typename OBS>
174 CostTermBase<MODEL, OBS> * CostFctWeak<MODEL, OBS>::newJc(const eckit::Configuration & jcConf,
175  const Geometry_ & resol) const {
176  const eckit::LocalConfiguration jcdfi(jcConf, "jcdfi");
177  const util::DateTime vt(subWinBegin_ + subWinLength_/2);
178  return new CostJcDFI<MODEL, OBS>(jcdfi, resol, vt, subWinLength_);
179 }
180 
181 // -----------------------------------------------------------------------------
182 
183 template <typename MODEL, typename OBS>
185  ASSERT(xx.state().validTime() == subWinBegin_);
186 
187  State_ xm(xx.state().geometry(), model_->variables(), subWinBegin_);
188  an2model_->changeVar(xx.state(), xm);
189  model_->forecast(xm, xx.modVar(), subWinLength_, post);
190  an2model_->changeVarInverse(xm, xx.state());
191 
192  ASSERT(xx.state().validTime() == subWinEnd_);
193 }
194 
195 // -----------------------------------------------------------------------------
196 
197 template<typename MODEL, typename OBS>
199  const eckit::Configuration & innerConf,
200  const CtrlVar_ & bg, const CtrlVar_ & fg,
202  PostProcessorTLAD<MODEL> & pptraj) {
203  Log::trace() << "CostFctWeak::doLinearize start" << std::endl;
204  eckit::LocalConfiguration conf(innerConf, "linear model");
205 // Setup linear model (and trajectory)
206  tlm_.reset(new LinearModel_(resol, conf));
207  pp.enrollProcessor(new TrajectorySaver<MODEL>(conf, resol, fg.modVar(), tlm_, pptraj));
208 
209 // Setup change of variables
210  inc2model_.reset(LinearVariableChangeFactory<MODEL>::create(bg.state(), fg.state(),
211  resol, conf));
212  inc2model_->setInputVariables(ctlvars_);
213  Log::trace() << "CostFctWeak::doLinearize done" << std::endl;
214 }
215 
216 // -----------------------------------------------------------------------------
217 
218 template <typename MODEL, typename OBS>
222  const bool idModel) const {
223  Log::trace() << "CostFctWeak: runTLM start" << std::endl;
224  inc2model_->setOutputVariables(tlm_->variables());
225 
226  ASSERT(dx.state().validTime() == subWinBegin_);
227 
228  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), subWinBegin_);
229  inc2model_->multiply(dx.state(), dxmodel);
230  tlm_->forecastTL(dxmodel, dx.modVar(), subWinLength_, post, cost, idModel);
231  inc2model_->multiplyInverse(dxmodel, dx.state());
232 
233  ASSERT(dx.state().validTime() == subWinEnd_);
234  Log::trace() << "CostFctWeak: runTLM done" << std::endl;
235 }
236 
237 // -----------------------------------------------------------------------------
238 
239 template <typename MODEL, typename OBS>
240 void CostFctWeak<MODEL, OBS>::runTLM(CtrlInc_ & dx, const bool idModel) const {
243  inc2model_->setOutputVariables(tlm_->variables());
244 
245  ASSERT(dx.state().validTime() == subWinBegin_);
246 
247  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), subWinBegin_);
248  if (idModel) {
249  dx.state().updateTime(subWinLength_);
250  } else {
251  inc2model_->multiply(dx.state(), dxmodel);
252  tlm_->forecastTL(dxmodel, dx.modVar(), subWinLength_, post, cost);
253  inc2model_->multiplyInverse(dxmodel, dx.state());
254  }
255 
256  ASSERT(dx.state().validTime() == subWinEnd_);
257 }
258 
259 // -----------------------------------------------------------------------------
260 
261 template <typename MODEL, typename OBS>
263  dx.state().zero(subWinEnd_);
264  dx.modVar().zero();
265  dx.obsVar().zero();
266 }
267 
268 // -----------------------------------------------------------------------------
269 
270 template <typename MODEL, typename OBS>
274  const bool idModel) const {
275  Log::trace() << "CostFctWeak: runADJ start" << std::endl;
276  inc2model_->setOutputVariables(tlm_->variables());
277 
278  ASSERT(dx.state().validTime() == subWinEnd_);
279 
280  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), subWinEnd_);
281  inc2model_->multiplyInverseAD(dx.state(), dxmodel);
282  tlm_->forecastAD(dxmodel, dx.modVar(), subWinLength_, post, cost, idModel);
283  inc2model_->multiplyAD(dxmodel, dx.state());
284 
285  ASSERT(dx.state().validTime() == subWinBegin_);
286  Log::trace() << "CostFctWeak: runADJ done" << std::endl;
287 }
288 
289 // -----------------------------------------------------------------------------
290 
291 template <typename MODEL, typename OBS>
292 void CostFctWeak<MODEL, OBS>::runADJ(CtrlInc_ & dx, const bool idModel) const {
295  inc2model_->setOutputVariables(tlm_->variables());
296 
297  ASSERT(dx.state().validTime() == subWinEnd_);
298 
299  Increment_ dxmodel(dx.state().geometry(), tlm_->variables(), subWinEnd_);
300  if (idModel) {
301  dx.state().updateTime(-subWinLength_);
302  } else {
303  inc2model_->multiplyInverseAD(dx.state(), dxmodel);
304  tlm_->forecastAD(dxmodel, dx.modVar(), subWinLength_, post, cost);
305  inc2model_->multiplyAD(dxmodel, dx.state());
306  }
307 
308  ASSERT(dx.state().validTime() == subWinBegin_);
309 }
310 
311 // -----------------------------------------------------------------------------
312 
313 template<typename MODEL, typename OBS>
315  PostProcessor<Increment_> & post) const {
316  xx.state() += dx.state();
317 }
318 
319 // -----------------------------------------------------------------------------
320 
321 } // namespace oops
322 
323 #endif // OOPS_ASSIMILATION_COSTFCTWEAK_H_
oops::CostFctWeak::model_
std::unique_ptr< Model_ > model_
Definition: CostFctWeak.h:96
oops::State::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/State.h:60
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
CostJcDFI.h
oops::CostFctWeak::commSpace_
eckit::mpi::Comm * commSpace_
Definition: CostFctWeak.h:101
oops::VariableChangeBase
Definition: VariableChangeBase.h:49
oops::ControlIncrement::obsVar
ObsAuxIncrs_ & obsVar()
Get augmented observation control variable.
Definition: ControlIncrement.h:94
oops::CostTermBase
Base Class for Cost Function Terms.
Definition: CostTermBase.h:37
oops::CostFctWeak::State_
State< MODEL > State_
Definition: CostFctWeak.h:56
CostJbJq.h
TrajectorySaver.h
oops::Increment::geometry
Geometry_ geometry() const
Get geometry.
Definition: oops/interface/Increment.h:397
oops::LinearVariableChangeFactory
LinearVariableChange factory.
Definition: LinearVariableChangeBase.h:85
oops::CostFctWeak::subWinLength_
util::Duration subWinLength_
Definition: CostFctWeak.h:90
oops::CostFctWeak::inc2model_
std::unique_ptr< LinVarCha_ > inc2model_
Definition: CostFctWeak.h:100
oops::CostFctWeak::doLinearize
void doLinearize(const Geometry_ &, const eckit::Configuration &, const CtrlVar_ &, const CtrlVar_ &, PostProcessor< State_ > &, PostProcessorTLAD< MODEL > &) override
Definition: CostFctWeak.h:198
oops::ControlVariable
Control variable.
Definition: ControlVariable.h:41
CostFunction.h
oops::CostFctWeak::CtrlInc_
ControlIncrement< MODEL, OBS > CtrlInc_
Definition: CostFctWeak.h:52
oops::CostFctWeak::newJo
CostJo< MODEL, OBS > * newJo(const eckit::Configuration &) const override
Definition: CostFctWeak.h:166
mpi.h
oops::Increment::zero
void zero()
Linear algebra operators.
Definition: oops/interface/Increment.h:206
oops::CostFctWeak::resol_
std::unique_ptr< Geometry_ > resol_
Definition: CostFctWeak.h:95
oops::ControlIncrement::modVar
ModelAuxIncr_ & modVar()
Get augmented model control variable.
Definition: ControlIncrement.h:90
oops::CostFctWeak::runTLM
void runTLM(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
Definition: CostFctWeak.h:219
oops::CostFctWeak::nsubwin_
size_t nsubwin_
Definition: CostFctWeak.h:93
oops::CostFctWeak::runADJ
void runADJ(CtrlInc_ &, PostProcessorTLAD< MODEL > &, PostProcessor< Increment_ >, const bool idModel=false) const override
Definition: CostFctWeak.h:271
oops::CostFctWeak::runNL
void runNL(CtrlVar_ &, PostProcessor< State_ > &) const override
Definition: CostFctWeak.h:184
oops::CostFctWeak::addIncr
void addIncr(CtrlVar_ &, const CtrlInc_ &, PostProcessor< Increment_ > &) const override
Definition: CostFctWeak.h:314
oops::ControlIncrement
Definition: ControlIncrement.h:46
oops::CostFctWeak::CostFct_
CostFunction< MODEL, OBS > CostFct_
Definition: CostFctWeak.h:54
oops::ControlVariable::modVar
ModelAux_ & modVar()
Get augmented model control variable.
Definition: ControlVariable.h:73
CostTermBase.h
oops::LinearVariableChangeBase
Definition: LinearVariableChangeBase.h:53
oops::VariableChangeFactory
VariableChange factory.
Definition: VariableChangeBase.h:75
oops::Increment::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/Increment.h:72
LinearModel.h
oops::CostJcDFI
Jc DFI Cost Function.
Definition: CostJcDFI.h:44
oops::CostFctWeak::an2model_
std::unique_ptr< VarCha_ > an2model_
Definition: CostFctWeak.h:99
oops::PostProcessor::enrollProcessor
void enrollProcessor(PostBase_ *pp)
Definition: PostProcessor.h:38
oops::CostFctWeak::commTime_
eckit::mpi::Comm * commTime_
Definition: CostFctWeak.h:102
oops::CostFctWeak::Model_
Model< MODEL > Model_
Definition: CostFctWeak.h:57
oops::CostFctWeak::Increment_
Increment< MODEL > Increment_
Definition: CostFctWeak.h:51
oops::CostFctWeak::Geometry_
Geometry< MODEL > Geometry_
Definition: CostFctWeak.h:55
oops::CostFctWeak::LinearModel_
LinearModel< MODEL > LinearModel_
Definition: CostFctWeak.h:58
oops::CostFctWeak::LinVarCha_
LinearVariableChangeBase< MODEL > LinVarCha_
Definition: CostFctWeak.h:60
PostProcessor.h
oops::ModelAuxIncrement::zero
void zero()
Definition: oops/interface/ModelAuxIncrement.h:143
oops::CostFctWeak::zeroAD
void zeroAD(CtrlInc_ &) const override
Definition: CostFctWeak.h:262
oops::PostProcessorTLAD
Control model post processing.
Definition: PostProcessorTLAD.h:33
oops::CostFctWeak::subWinBegin_
util::DateTime subWinBegin_
Definition: CostFctWeak.h:91
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
Model.h
oops::ControlIncrement::state
Increment_ & state()
Get state control variable.
Definition: ControlIncrement.h:86
oops::State::geometry
Geometry_ geometry() const
Definition: oops/interface/State.h:215
oops::Increment::updateTime
void updateTime(const util::Duration &dt)
Definition: oops/interface/Increment.h:73
oops::CostFctWeak::subWinEnd_
util::DateTime subWinEnd_
Definition: CostFctWeak.h:92
oops::CostFctWeak::~CostFctWeak
~CostFctWeak()
Definition: CostFctWeak.h:64
StateInfo.h
oops::State
Encapsulates the model state.
Definition: CostJbState.h:28
oops::CostFctWeak::CostFctWeak
CostFctWeak(const eckit::Configuration &, const eckit::mpi::Comm &)
Definition: CostFctWeak.h:108
oops::PostProcessor
Control model post processing.
Definition: PostProcessor.h:30
oops::CostFctWeak
Weak Constraint 4D-Var Cost Function.
Definition: CostFctWeak.h:50
State.h
oops::CostFctWeak::CtrlVar_
ControlVariable< MODEL, OBS > CtrlVar_
Definition: CostFctWeak.h:53
CostJo.h
oops::Variables
Definition: oops/base/Variables.h:23
oops::CostFunction::setupTerms
void setupTerms(const eckit::Configuration &)
Definition: CostFunction.h:195
oops::Increment
Increment Class: Difference between two states.
Definition: CostJbState.h:27
oops::CostFctWeak::VarCha_
VariableChangeBase< MODEL > VarCha_
Definition: CostFctWeak.h:59
oops::CostFctWeak::newJb
CostJbJq< MODEL > * newJb(const eckit::Configuration &, const Geometry_ &, const CtrlVar_ &) const override
Definition: CostFctWeak.h:157
oops::TrajectorySaver
Save trajectory during forecast run.
Definition: TrajectorySaver.h:32
oops::CostJbJq
Jb + Jq Cost Function.
Definition: CostJbJq.h:39
oops::CostFctWeak::geometry
const Geometry_ & geometry() const override
Definition: CostFctWeak.h:88
oops::ObsAuxIncrements::zero
void zero()
Definition: ObsAuxIncrements.h:143
oops::CostFunction
Cost Function.
Definition: CostFunction.h:53
PostProcessorTLAD.h
LinearVariableChangeBase.h
oops::CostFctWeak::ctlvars_
const Variables ctlvars_
Definition: CostFctWeak.h:97
oops::LinearModel
Encapsulates the linear forecast model.
Definition: oops/interface/LinearModel.h:65
oops::CostFctWeak::newJc
CostTermBase< MODEL, OBS > * newJc(const eckit::Configuration &, const Geometry_ &) const override
Definition: CostFctWeak.h:174
Variables.h
oops::CostJo
Jo Cost Function.
Definition: CostJo.h:54
oops::Model
Encapsulates the nonlinear forecast model Note: to see methods that need to be implemented in the for...
Definition: oops/interface/Model.h:54
oops::CostFctWeak::tlm_
std::shared_ptr< LinearModel_ > tlm_
Definition: CostFctWeak.h:98
VariableChangeBase.h
oops::ControlVariable::state
State_ & state()
Get state control variable.
Definition: ControlVariable.h:69
oops::CostFctWeak::mysubwin_
size_t mysubwin_
Definition: CostFctWeak.h:94
Geometry.h
Increment.h