OOPS
WeightedDiffTLAD.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_BASE_WEIGHTEDDIFFTLAD_H_
12 #define OOPS_BASE_WEIGHTEDDIFFTLAD_H_
13 
14 #include <cmath>
15 #include <map>
16 #include <memory>
17 #include <utility>
18 
19 #include "oops/base/Accumulator.h"
21 #include "oops/base/PostBaseTLAD.h"
22 #include "oops/base/Variables.h"
23 #include "oops/base/WeightedDiff.h"
24 #include "oops/base/WeightingFct.h"
27 #include "oops/interface/State.h"
28 #include "oops/util/DateTime.h"
29 #include "oops/util/Duration.h"
30 
31 namespace oops {
32 
33 // -----------------------------------------------------------------------------
34 
35 /// Compute time average of states or increments during linear model run.
36 /*!
37  * Derived classes will compute different types of averages (plain
38  * mean, various types of digital filters) by overwriting the weights
39  * computation method.
40  *
41  * A lot of code here is common with WeightedDiff and even WeightedMean,
42  * the design could be improved to reduce code duplication. YT
43  */
44 
45 template <typename MODEL>
46 class WeightedDiffTLAD : public PostBaseTLAD<MODEL> {
50 
51  public:
52  WeightedDiffTLAD(const Variables &, const util::DateTime &, const util::Duration &,
53  const util::Duration &, const Geometry_ &, WeightingFct &);
54  virtual ~WeightedDiffTLAD() {}
55 
56  Increment_ * releaseDiff() {return wdiff_.releaseDiff();}
57  std::unique_ptr<GeneralizedDepartures> releaseOutputFromTL() override;
58  void setupTL(const Geometry_ &);
59  void setupAD(std::shared_ptr<const Increment_>);
60 
61  private:
62  void doInitializeTraj(const State_ &,
63  const util::DateTime &, const util::Duration &) override;
64  void doProcessingTraj(const State_ &) override;
65  void doFinalizeTraj(const State_ &) override;
66 
67  void doInitializeTL(const Increment_ &,
68  const util::DateTime &, const util::Duration &) override;
69  void doProcessingTL(const Increment_ &) override;
70  void doFinalizeTL(const Increment_ &) override {}
71 
72  void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override;
73  void doProcessingAD(Increment_ &) override;
74  void doLastAD(Increment_ &) override {}
75 
79  std::map< util::DateTime, double > weights_;
80  std::shared_ptr<const Increment_> forcing_;
81  std::unique_ptr<Accumulator<MODEL, Increment_, Increment_>> avg_;
82  double sum_;
83  bool linit_;
84  const util::DateTime vtime_;
85  const util::DateTime bgn_;
86  const util::DateTime end_;
87  util::Duration tstep_;
88  util::DateTime bgnleg_;
89  util::DateTime endleg_;
90 };
91 
92 // =============================================================================
93 
94 template <typename MODEL>
96  const util::DateTime & vt,
97  const util::Duration & span,
98  const util::Duration & tstep,
99  const Geometry_ & resol,
100  WeightingFct & wfct)
101  : PostBaseTLAD<MODEL>(vt-span/2, vt+span/2),
102  vars_(vars), wfct_(wfct), wdiff_(vars, vt, span, tstep, resol, wfct_),
103  weights_(), forcing_(), avg_(), sum_(0.0), linit_(false),
104  vtime_(vt), bgn_(vt-span/2), end_(vt+span/2), tstep_(tstep),
105  bgnleg_(), endleg_()
106 {
107  Log::trace() << "WeightedDiffTLAD::WeightedDiffTLAD" << std::endl;
108 }
109 
110 // -----------------------------------------------------------------------------
111 
112 template <typename MODEL>
114  const util::DateTime & end, const util::Duration & tstep) {
115  Log::trace() << "WeightedDiffTLAD::doInitializeTraj start" << std::endl;
116  wdiff_.initialize(xx, end, tstep);
117  Log::trace() << "WeightedDiffTLAD::doInitializeTraj done" << std::endl;
118 }
119 
120 // -----------------------------------------------------------------------------
121 
122 template <typename MODEL>
124  Log::trace() << "WeightedDiffTLAD::doProcessingTraj start" << std::endl;
125  wdiff_.process(xx);
126  Log::trace() << "WeightedDiffTLAD::doProcessingTraj done" << std::endl;
127 }
128 
129 // -----------------------------------------------------------------------------
130 
131 template <typename MODEL>
133  Log::trace() << "WeightedDiffTLAD::doFinalizeTraj start" << std::endl;
134  wdiff_.finalize(xx);
135  Log::trace() << "WeightedDiffTLAD::doFinalizeTraj done" << std::endl;
136 }
137 
138 // -----------------------------------------------------------------------------
139 
140 template <typename MODEL>
142  Log::trace() << "WeightedDiffTLAD::setupTL start" << std::endl;
143  avg_.reset(new Accumulator<MODEL, Increment_, Increment_>(resol, vars_, vtime_));
144  Log::trace() << "WeightedDiffTLAD::setupTL done" << std::endl;
145 }
146 
147 // -----------------------------------------------------------------------------
148 
149 template <typename MODEL>
151  const util::DateTime & end,
152  const util::Duration & tstep) {
153  Log::trace() << "WeightedDiffTLAD::doInitializeTL start" << std::endl;
154  const util::DateTime bgn(dx.validTime());
155  ASSERT(bgn <= end);
156  if (!linit_ && bgn <= end_ && end >= bgn_) {
157  if (tstep_ == util::Duration(0)) tstep_ = tstep;
158  ASSERT(tstep_ > util::Duration(0));
159  weights_ = wfct_.setWeights(bgn_, end_, tstep_);
160  linit_ = true;
161  ASSERT(weights_.find(vtime_) != weights_.end());
162  weights_[vtime_] -= 1.0;
163  }
164  bgnleg_ = bgn;
165  endleg_ = end;
166  Log::trace() << "WeightedDiffTLAD::doInitializeTL done" << std::endl;
167 }
168 
169 // -----------------------------------------------------------------------------
170 
171 template <typename MODEL>
173  Log::trace() << "WeightedDiffTLAD::doProcessingTL start" << std::endl;
174  const util::DateTime now(xx.validTime());
175  if (((bgnleg_ < end_ && endleg_ > bgn_) || bgnleg_ == endleg_) &&
176  (now != endleg_ || now == end_ || now == bgnleg_)) {
177  ASSERT(weights_.find(now) != weights_.end());
178  const double zz = weights_[now];
179  avg_->axpy(zz, xx, false);
180  sum_ += zz;
181  }
182  Log::trace() << "WeightedDiffTLAD::doProcessingTL done" << std::endl;
183 }
184 
185 // -----------------------------------------------------------------------------
186 
187 template <typename MODEL>
188 std::unique_ptr<GeneralizedDepartures> WeightedDiffTLAD<MODEL>::releaseOutputFromTL() {
189  Log::trace() << "WeightedDiffTLAD::releaseOutputFromTL" << std::endl;
190  ASSERT(linit_);
191  ASSERT(std::abs(sum_) < 1.0e-8);
192  return std::move(avg_);
193 }
194 
195 // -----------------------------------------------------------------------------
196 
197 template <typename MODEL>
198 void WeightedDiffTLAD<MODEL>::setupAD(std::shared_ptr<const Increment_> forcing) {
199  Log::trace() << "WeightedDiffTLAD::setupAD start" << std::endl;
200  forcing_ = forcing;
201  Log::trace() << "WeightedDiffTLAD::setupAD done" << std::endl;
202 }
203 
204 // -----------------------------------------------------------------------------
205 
206 
207 template <typename MODEL>
209  const util::DateTime & bgn,
210  const util::Duration & tstep) {
211  Log::trace() << "WeightedDiffTLAD::doFirstAD start" << std::endl;
212  const util::DateTime end(dx.validTime());
213  ASSERT(bgn <= end);
214  if (!linit_ && bgn <= end_ && end >= bgn_) {
215  if (tstep_ == util::Duration(0)) tstep_ = tstep;
216  ASSERT(tstep_ > util::Duration(0));
217  weights_ = wfct_.setWeights(bgn_, end_, tstep_);
218  linit_ = true;
219  ASSERT(weights_.find(vtime_) != weights_.end());
220  weights_[vtime_] -= 1.0;
221  }
222  bgnleg_ = bgn;
223  endleg_ = end;
224  Log::trace() << "WeightedDiffTLAD::doFirstAD done" << std::endl;
225 }
226 
227 // -----------------------------------------------------------------------------
228 
229 template <typename MODEL>
231  Log::trace() << "WeightedDiffTLAD::doProcessingAD start" << std::endl;
232  ASSERT(forcing_);
233  const util::DateTime now(dx.validTime());
234  if (((bgnleg_ < end_ && endleg_ > bgn_) || bgnleg_ == endleg_) &&
235  (now != endleg_ || now == end_ || now == bgnleg_)) {
236  ASSERT(weights_.find(now) != weights_.end());
237  const double zz = weights_[now];
238  dx.axpy(zz, *forcing_, false);
239  sum_ += zz;
240  }
241  Log::trace() << "WeightedDiffTLAD::doProcessingAD done" << std::endl;
242 }
243 
244 // -----------------------------------------------------------------------------
245 
246 } // namespace oops
247 
248 #endif // OOPS_BASE_WEIGHTEDDIFFTLAD_H_
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::WeightedDiff
Compute time average of states or increments during model run.
Definition: WeightedDiff.h:39
oops::WeightedDiffTLAD::bgn_
const util::DateTime bgn_
Definition: WeightedDiffTLAD.h:85
oops::WeightedDiffTLAD::WeightedDiffTLAD
WeightedDiffTLAD(const Variables &, const util::DateTime &, const util::Duration &, const util::Duration &, const Geometry_ &, WeightingFct &)
Definition: WeightedDiffTLAD.h:95
oops::WeightedDiffTLAD::endleg_
util::DateTime endleg_
Definition: WeightedDiffTLAD.h:89
PostBaseTLAD.h
oops::WeightedDiffTLAD::weights_
std::map< util::DateTime, double > weights_
Definition: WeightedDiffTLAD.h:79
oops::WeightedDiffTLAD::doInitializeTraj
void doInitializeTraj(const State_ &, const util::DateTime &, const util::Duration &) override
Definition: WeightedDiffTLAD.h:113
oops::WeightedDiffTLAD::doLastAD
void doLastAD(Increment_ &) override
Definition: WeightedDiffTLAD.h:74
oops::PostBaseTLAD
Handles post-processing of model fields related to cost function.
Definition: PostBaseTLAD.h:41
oops::WeightedDiffTLAD::tstep_
util::Duration tstep_
Definition: WeightedDiffTLAD.h:87
oops::WeightedDiffTLAD::wdiff_
WeightedDiff< MODEL, Increment_, State_ > wdiff_
Definition: WeightedDiffTLAD.h:78
oops::WeightedDiffTLAD::setupAD
void setupAD(std::shared_ptr< const Increment_ >)
Definition: WeightedDiffTLAD.h:198
oops::WeightedDiffTLAD::forcing_
std::shared_ptr< const Increment_ > forcing_
Definition: WeightedDiffTLAD.h:80
oops::WeightedDiffTLAD::doFinalizeTL
void doFinalizeTL(const Increment_ &) override
Definition: WeightedDiffTLAD.h:70
oops::WeightedDiffTLAD::bgnleg_
util::DateTime bgnleg_
Definition: WeightedDiffTLAD.h:88
oops::WeightedDiffTLAD::State_
State< MODEL > State_
Definition: WeightedDiffTLAD.h:49
oops::WeightedDiffTLAD::sum_
double sum_
Definition: WeightedDiffTLAD.h:82
oops::WeightedDiffTLAD::setupTL
void setupTL(const Geometry_ &)
Definition: WeightedDiffTLAD.h:141
oops::WeightedDiffTLAD::end_
const util::DateTime end_
Definition: WeightedDiffTLAD.h:86
oops::WeightedDiffTLAD::avg_
std::unique_ptr< Accumulator< MODEL, Increment_, Increment_ > > avg_
Definition: WeightedDiffTLAD.h:81
oops::WeightedDiffTLAD::doInitializeTL
void doInitializeTL(const Increment_ &, const util::DateTime &, const util::Duration &) override
Definition: WeightedDiffTLAD.h:150
oops::WeightedDiffTLAD::Geometry_
Geometry< MODEL > Geometry_
Definition: WeightedDiffTLAD.h:47
oops::Increment::axpy
void axpy(const double &, const Increment &, const bool check=true)
Definition: oops/interface/Increment.h:290
oops::WeightedDiffTLAD::~WeightedDiffTLAD
virtual ~WeightedDiffTLAD()
Definition: WeightedDiffTLAD.h:54
oops::Increment::validTime
const util::DateTime validTime() const
Time.
Definition: oops/interface/Increment.h:72
oops::WeightedDiffTLAD::doProcessingAD
void doProcessingAD(Increment_ &) override
Definition: WeightedDiffTLAD.h:230
oops::WeightingFct
Weighting Function.
Definition: WeightingFct.h:31
DolphChebyshev.h
oops::WeightedDiffTLAD::releaseOutputFromTL
std::unique_ptr< GeneralizedDepartures > releaseOutputFromTL() override
Return TL dual space output.
Definition: WeightedDiffTLAD.h:188
oops::WeightedDiffTLAD::doFinalizeTraj
void doFinalizeTraj(const State_ &) override
Definition: WeightedDiffTLAD.h:132
oops::WeightedDiffTLAD::wfct_
WeightingFct & wfct_
Definition: WeightedDiffTLAD.h:77
oops::WeightedDiffTLAD::doFirstAD
void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override
Definition: WeightedDiffTLAD.h:208
oops::WeightedDiffTLAD::vtime_
const util::DateTime vtime_
Definition: WeightedDiffTLAD.h:84
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
Accumulator.h
oops::Accumulator
Definition: Accumulator.h:22
oops::WeightedDiffTLAD::releaseDiff
Increment_ * releaseDiff()
Definition: WeightedDiffTLAD.h:56
oops::WeightedDiffTLAD::linit_
bool linit_
Definition: WeightedDiffTLAD.h:83
oops::WeightedDiffTLAD::doProcessingTL
void doProcessingTL(const Increment_ &) override
Definition: WeightedDiffTLAD.h:172
WeightedDiff.h
oops::State
Encapsulates the model state.
Definition: CostJbState.h:28
oops::WeightedDiffTLAD::Increment_
Increment< MODEL > Increment_
Definition: WeightedDiffTLAD.h:48
State.h
oops::Variables
Definition: oops/base/Variables.h:23
oops::Increment
Increment Class: Difference between two states.
Definition: CostJbState.h:27
oops::WeightedDiffTLAD
Compute time average of states or increments during linear model run.
Definition: WeightedDiffTLAD.h:46
WeightingFct.h
Variables.h
oops::WeightedDiffTLAD::vars_
Variables vars_
Definition: WeightedDiffTLAD.h:76
Geometry.h
Increment.h
oops::WeightedDiffTLAD::doProcessingTraj
void doProcessingTraj(const State_ &) override
Definition: WeightedDiffTLAD.h:123