FV3 Bundle
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 <boost/scoped_ptr.hpp>
17 #include <boost/shared_ptr.hpp>
18 
19 #include "eckit/config/LocalConfiguration.h"
20 #include "oops/base/Accumulator.h"
22 #include "oops/base/PostBaseTLAD.h"
23 #include "oops/base/Variables.h"
24 #include "oops/base/WeightedDiff.h"
25 #include "oops/base/WeightingFct.h"
28 #include "oops/interface/State.h"
29 #include "oops/util/DateTime.h"
30 #include "oops/util/Duration.h"
31 
32 namespace oops {
33 
34 // -----------------------------------------------------------------------------
35 
36 /// Compute time average of states or increments during linear model run.
37 /*!
38  * Derived classes will compute different types of averages (plain
39  * mean, various types of digital filters) by overwriting the weights
40  * computation method.
41  *
42  * A lot of code here is common with WeightedDiff and even WeightedMean,
43  * the design could be improved to reduce code duplication. YT
44  */
45 
46 template <typename MODEL>
47 class WeightedDiffTLAD : public PostBaseTLAD<MODEL> {
51 
52  public:
53  WeightedDiffTLAD(const eckit::Configuration &, const util::DateTime &, const util::Duration &,
54  const util::Duration &, const Geometry_ &, WeightingFct &);
55  virtual ~WeightedDiffTLAD() {}
56 
57  Increment_ * releaseDiff() {return wdiff_.releaseDiff();}
58  Increment_ * releaseOutputFromTL() override;
59  void setupTL(const Geometry_ &);
60  void setupAD(boost::shared_ptr<const Increment_>);
61 
62  private:
63  void doInitializeTraj(const State_ &,
64  const util::DateTime &, const util::Duration &) override;
65  void doProcessingTraj(const State_ &) override;
66  void doFinalizeTraj(const State_ &) override;
67 
68  void doInitializeTL(const Increment_ &,
69  const util::DateTime &, const util::Duration &) override;
70  void doProcessingTL(const Increment_ &) override;
71  void doFinalizeTL(const Increment_ &) override {}
72 
73  void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override;
74  void doProcessingAD(Increment_ &) override;
75  void doLastAD(Increment_ &) override {}
76 
77  const eckit::LocalConfiguration conf_;
80  std::map< util::DateTime, double > weights_;
81  boost::shared_ptr<const Increment_> forcing_;
83  double sum_;
84  bool linit_;
85  const util::DateTime vtime_;
86  const util::DateTime bgn_;
87  const util::DateTime end_;
88  util::Duration tstep_;
89  util::DateTime bgnleg_;
90  util::DateTime endleg_;
91 };
92 
93 // =============================================================================
94 
95 template <typename MODEL>
96 WeightedDiffTLAD<MODEL>::WeightedDiffTLAD(const eckit::Configuration & config,
97  const util::DateTime & vt,
98  const util::Duration & span,
99  const util::Duration & tstep,
100  const Geometry_ & resol,
101  WeightingFct & wfct)
102  : PostBaseTLAD<MODEL>(vt-span/2, vt+span/2),
103  conf_(config), wfct_(wfct), wdiff_(conf_, vt, span, tstep, resol, wfct_),
104  weights_(), forcing_(), avg_(0), sum_(0.0), linit_(false),
105  vtime_(vt), bgn_(vt-span/2), end_(vt+span/2), tstep_(tstep),
106  bgnleg_(), endleg_()
107 {
108  Log::trace() << "WeightedDiffTLAD::WeightedDiffTLAD" << std::endl;
109 }
110 
111 // -----------------------------------------------------------------------------
112 
113 template <typename MODEL>
115  const util::DateTime & end, const util::Duration & tstep) {
116  Log::trace() << "WeightedDiffTLAD::doInitializeTraj start" << std::endl;
117  wdiff_.initialize(xx, end, tstep);
118  Log::trace() << "WeightedDiffTLAD::doInitializeTraj done" << std::endl;
119 }
120 
121 // -----------------------------------------------------------------------------
122 
123 template <typename MODEL>
125  Log::trace() << "WeightedDiffTLAD::doProcessingTraj start" << std::endl;
126  wdiff_.process(xx);
127  Log::trace() << "WeightedDiffTLAD::doProcessingTraj done" << std::endl;
128 }
129 
130 // -----------------------------------------------------------------------------
131 
132 template <typename MODEL>
134  Log::trace() << "WeightedDiffTLAD::doFinalizeTraj start" << std::endl;
135  wdiff_.finalize(xx);
136  Log::trace() << "WeightedDiffTLAD::doFinalizeTraj done" << std::endl;
137 }
138 
139 // -----------------------------------------------------------------------------
140 
141 template <typename MODEL>
143  Log::trace() << "WeightedDiffTLAD::setupTL start" << std::endl;
144  const Variables vars(conf_);
145  avg_ = new Accumulator<MODEL, Increment_, Increment_>(resol, vars, vtime_);
146  Log::trace() << "WeightedDiffTLAD::setupTL done" << std::endl;
147 }
148 
149 // -----------------------------------------------------------------------------
150 
151 template <typename MODEL>
153  const util::DateTime & end,
154  const util::Duration & tstep) {
155  Log::trace() << "WeightedDiffTLAD::doInitializeTL start" << std::endl;
156  const util::DateTime bgn(dx.validTime());
157  ASSERT(bgn <= end);
158  if (!linit_ && bgn <= end_ && end >= bgn_) {
159  if (tstep_ == util::Duration(0)) tstep_ = tstep;
160  ASSERT(tstep_ > util::Duration(0));
161  weights_ = wfct_.setWeights(bgn_, end_, tstep_);
162  linit_ = true;
163  ASSERT(weights_.find(vtime_) != weights_.end());
164  weights_[vtime_] -= 1.0;
165  }
166  bgnleg_ = bgn;
167  endleg_ = end;
168  Log::trace() << "WeightedDiffTLAD::doInitializeTL done" << std::endl;
169 }
170 
171 // -----------------------------------------------------------------------------
172 
173 template <typename MODEL>
175  Log::trace() << "WeightedDiffTLAD::doProcessingTL start" << std::endl;
176  const util::DateTime now(xx.validTime());
177  if (((bgnleg_ < end_ && endleg_ > bgn_) || bgnleg_ == endleg_) &&
178  (now != endleg_ || now == end_ || now == bgnleg_)) {
179  ASSERT(weights_.find(now) != weights_.end());
180  const double zz = weights_[now];
181  avg_->axpy(zz, xx, false);
182  sum_ += zz;
183  }
184  Log::trace() << "WeightedDiffTLAD::doProcessingTL done" << std::endl;
185 }
186 
187 // -----------------------------------------------------------------------------
188 
189 template <typename MODEL>
191  Log::trace() << "WeightedDiffTLAD::releaseOutputFromTL" << std::endl;
192  ASSERT(linit_);
193  ASSERT(std::abs(sum_) < 1.0e-8);
194  return avg_;
195 }
196 
197 // -----------------------------------------------------------------------------
198 
199 template <typename MODEL>
200 void WeightedDiffTLAD<MODEL>::setupAD(boost::shared_ptr<const Increment_> forcing) {
201  Log::trace() << "WeightedDiffTLAD::setupAD start" << std::endl;
202  forcing_ = forcing;
203  Log::trace() << "WeightedDiffTLAD::setupAD done" << std::endl;
204 }
205 
206 // -----------------------------------------------------------------------------
207 
208 
209 template <typename MODEL>
211  const util::DateTime & bgn,
212  const util::Duration & tstep) {
213  Log::trace() << "WeightedDiffTLAD::doFirstAD start" << std::endl;
214  const util::DateTime end(dx.validTime());
215  ASSERT(bgn <= end);
216  if (!linit_ && bgn <= end_ && end >= bgn_) {
217  if (tstep_ == util::Duration(0)) tstep_ = tstep;
218  ASSERT(tstep_ > util::Duration(0));
219  weights_ = wfct_.setWeights(bgn_, end_, tstep_);
220  linit_ = true;
221  ASSERT(weights_.find(vtime_) != weights_.end());
222  weights_[vtime_] -= 1.0;
223  }
224  bgnleg_ = bgn;
225  endleg_ = end;
226  Log::trace() << "WeightedDiffTLAD::doFirstAD done" << std::endl;
227 }
228 
229 // -----------------------------------------------------------------------------
230 
231 template <typename MODEL>
233  Log::trace() << "WeightedDiffTLAD::doProcessingAD start" << std::endl;
234  ASSERT(forcing_);
235  const util::DateTime now(dx.validTime());
236  if (((bgnleg_ < end_ && endleg_ > bgn_) || bgnleg_ == endleg_) &&
237  (now != endleg_ || now == end_ || now == bgnleg_)) {
238  ASSERT(weights_.find(now) != weights_.end());
239  const double zz = weights_[now];
240  dx.axpy(zz, *forcing_, false);
241  sum_ += zz;
242  }
243  Log::trace() << "WeightedDiffTLAD::doProcessingAD done" << std::endl;
244 }
245 
246 // -----------------------------------------------------------------------------
247 
248 } // namespace oops
249 
250 #endif // OOPS_BASE_WEIGHTEDDIFFTLAD_H_
Geometry< MODEL > Geometry_
WeightedDiff< MODEL, Increment_, State_ > wdiff_
Compute time average of states or increments during model run.
Definition: WeightedDiff.h:41
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! MPP_TRANSMIT !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine MPP_TRANSMIT_(put_data, put_len, to_pe, get_data, get_len, from_pe, block, tag, recv_request, send_request)!a message-passing routine intended to be reminiscent equally of both MPI and SHMEM!put_data and get_data are contiguous MPP_TYPE_ arrays!at each call, your put_data array is put to to_pe 's get_data! your get_data array is got from from_pe 's put_data!i.e we assume that typically(e.g updating halo regions) each PE performs a put _and_ a get!special PE designations:! NULL_PE:to disable a put or a get(e.g at boundaries)! ANY_PE:if remote PE for the put or get is to be unspecific! ALL_PES:broadcast and collect operations(collect not yet implemented)!ideally we would not pass length, but this f77-style call performs better(arrays passed by address, not descriptor)!further, this permits< length > contiguous words from an array of any rank to be passed(avoiding f90 rank conformance check)!caller is responsible for completion checks(mpp_sync_self) before and after integer, intent(in) ::put_len, to_pe, get_len, from_pe MPP_TYPE_, intent(in) ::put_data(*) MPP_TYPE_, intent(out) ::get_data(*) logical, intent(in), optional ::block integer, intent(in), optional ::tag integer, intent(out), optional ::recv_request, send_request logical ::block_comm integer ::i MPP_TYPE_, allocatable, save ::local_data(:) !local copy used by non-parallel code(no SHMEM or MPI) integer ::comm_tag integer ::rsize if(.NOT.module_is_initialized) call mpp_error(FATAL, 'MPP_TRANSMIT:You must first call mpp_init.') if(to_pe.EQ.NULL_PE .AND. from_pe.EQ.NULL_PE) return block_comm=.true. if(PRESENT(block)) block_comm=block if(debug) then call SYSTEM_CLOCK(tick) write(stdout_unit,'(a, i18, a, i6, a, 2i6, 2i8)')&'T=', tick, ' PE=', pe, ' MPP_TRANSMIT begin:to_pe, from_pe, put_len, get_len=', to_pe, from_pe, put_len, get_len end if comm_tag=DEFAULT_TAG if(present(tag)) comm_tag=tag!do put first and then get if(to_pe.GE.0 .AND. to_pe.LT.npes) then!use non-blocking sends if(debug .and.(current_clock.NE.0)) call SYSTEM_CLOCK(start_tick)!z1l:truly non-blocking send.! if(request(to_pe).NE.MPI_REQUEST_NULL) then !only one message from pe-> to_pe in queue *PE waiting for to_pe ! call error else get_len so only do gets but you cannot have a pure get with MPI call a get means do a wait to ensure put on remote PE is complete error call increase mpp_nml request_multiply call MPP_TRANSMIT end
WeightedDiffTLAD(const eckit::Configuration &, const util::DateTime &, const util::Duration &, const util::Duration &, const Geometry_ &, WeightingFct &)
Increment< MODEL > Increment_
const util::DateTime validTime() const
Time.
Handles post-processing of model fields related to cost function.
Definition: PostBaseTLAD.h:39
void doInitializeTraj(const State_ &, const util::DateTime &, const util::Duration &) override
Encapsulates the model state.
void doFinalizeTraj(const State_ &) override
integer(long), parameter false
Accumulator< MODEL, Increment_, Increment_ > * avg_
The namespace for the main oops code.
real(fp), parameter, public e
Increment_ * releaseOutputFromTL() override
Return TL dual space output.
real, dimension(:,:,:), allocatable vt
void setupTL(const Geometry_ &)
boost::shared_ptr< const Increment_ > forcing_
const util::DateTime end_
void doProcessingTL(const Increment_ &) override
void doFinalizeTL(const Increment_ &) override
enddo ! cludge for now
void axpy(const double &, const Increment &, const bool check=true)
void doProcessingTraj(const State_ &) override
void doLastAD(Increment_ &) override
void doProcessingAD(Increment_ &) override
Increment Class: Difference between two states.
void setupAD(boost::shared_ptr< const Increment_ >)
const util::DateTime vtime_
Compute time average of states or increments during linear model run.
void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override
Weighting Function.
Definition: WeightingFct.h:36
void doInitializeTL(const Increment_ &, const util::DateTime &, const util::Duration &) override
std::map< util::DateTime, double > weights_
Increment_ * releaseDiff()
const util::DateTime bgn_
const eckit::LocalConfiguration conf_