FV3 Bundle
ObserverTLAD.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_OBSERVERTLAD_H_
12 #define OOPS_BASE_OBSERVERTLAD_H_
13 
14 #include <memory>
15 #include <vector>
16 
17 #include <boost/scoped_ptr.hpp>
18 #include <boost/shared_ptr.hpp>
19 
20 #include "oops/base/Departures.h"
22 #include "oops/base/Observations.h"
23 #include "oops/base/ObsFilters.h"
24 #include "oops/base/ObsOperators.h"
25 #include "oops/base/ObsSpaces.h"
26 #include "oops/base/PostBaseTLAD.h"
27 #include "oops/interface/GeoVaLs.h"
32 #include "oops/interface/State.h"
33 #include "oops/util/DateTime.h"
34 #include "oops/util/Duration.h"
35 
36 namespace oops {
37 
38 /// Computes observation equivalent TL and AD to/from increments.
39 
40 template <typename MODEL>
41 class ObserverTLAD : public PostBaseTLAD<MODEL> {
54 
55  public:
56  ObserverTLAD(const ObsSpace_ &, const ObsOperators_ &, const ObsAuxCtrl_ &, const ObsFilters_ &,
57  const util::Duration & tslot = util::Duration(0), const bool subwin = false);
59 
60  Observations_ * release() {return observer_.release();}
61  Departures_ * releaseOutputFromTL() override {return ydeptl_.release();}
62  void setupTL(const ObsAuxIncr_ &);
63  void setupAD(boost::shared_ptr<const Departures_>, ObsAuxIncr_ &);
64 
65  private:
66 // Methods
67  void doInitializeTraj(const State_ &,
68  const util::DateTime &, const util::Duration &) override;
69  void doProcessingTraj(const State_ &) override;
70  void doFinalizeTraj(const State_ &) override;
71 
72  void doInitializeTL(const Increment_ &,
73  const util::DateTime &, const util::Duration &) override;
74  void doProcessingTL(const Increment_ &) override;
75  void doFinalizeTL(const Increment_ &) override;
76 
77  void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override;
78  void doProcessingAD(Increment_ &) override;
79  void doLastAD(Increment_ &) override;
80 
81 // Obs operator
85 
86 // Data
87  std::auto_ptr<Departures_> ydeptl_;
89  boost::shared_ptr<const Departures_> ydepad_;
91 
92  util::DateTime winbgn_; //!< Begining of assimilation window
93  util::DateTime winend_; //!< End of assimilation window
94  util::DateTime bgn_; //!< Begining of currently active observations
95  util::DateTime end_; //!< End of currently active observations
96  util::Duration hslot_; //!< Half time slot
97  const bool subwindows_;
98 
99  std::vector<std::vector<boost::shared_ptr<InterpolatorTraj_> > > traj_;
100  util::Duration bintstep;
101  int nsteps;
102 
103  std::vector<boost::shared_ptr<GeoVaLs_> > gvals_;
104 };
105 
106 // -----------------------------------------------------------------------------
107 template <typename MODEL>
109  const ObsOperators_ & hop,
110  const ObsAuxCtrl_ & ybias,
111  const ObsFilters_ & filters,
112  const util::Duration & tslot, const bool subwin)
113  : PostBaseTLAD<MODEL>(obsdb.windowStart(), obsdb.windowEnd()),
114  obspace_(obsdb), hoptlad_(obspace_),
115  observer_(obspace_, hop, ybias, filters, tslot, subwin),
116  ydeptl_(), ybiastl_(), ydepad_(), ybiasad_(),
117  winbgn_(obsdb.windowStart()), winend_(obsdb.windowEnd()),
118  bgn_(winbgn_), end_(winend_), hslot_(tslot/2), subwindows_(subwin)
119 {
120  Log::trace() << "ObserverTLAD::ObserverTLAD" << std::endl;
121 }
122 // -----------------------------------------------------------------------------
123 template <typename MODEL>
125  const util::DateTime & end, const util::Duration & tstep) {
126  Log::trace() << "ObserverTLAD::doInitializeTraj start" << std::endl;
127 
128 // Create full trajectory object
129  bintstep = tstep;
130  nsteps = 1+(winend_-winbgn_).toSeconds() / tstep.toSeconds();
131  for (std::size_t ib = 0; ib < nsteps; ++ib) {
132  std::vector<boost::shared_ptr<InterpolatorTraj_> > obstraj;
133  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
134  boost::shared_ptr<InterpolatorTraj_> traj(new InterpolatorTraj_());
135  obstraj.push_back(traj);
136  }
137  traj_.push_back(obstraj);
138  }
139 
140  observer_.initialize(xx, end, tstep);
141  Log::trace() << "ObserverTLAD::doInitializeTraj done" << std::endl;
142 }
143 // -----------------------------------------------------------------------------
144 template <typename MODEL>
146  Log::trace() << "ObserverTLAD::doProcessingTraj start" << std::endl;
147 
148  // Index for current bin
149  int ib = (xx.validTime()-winbgn_).toSeconds() / bintstep.toSeconds();
150 
151  // Call nonlinear observer
152  observer_.processTraj(xx, traj_[ib]);
153 
154  Log::trace() << "ObserverTLAD::doProcessingTraj done" << std::endl;
155 }
156 // -----------------------------------------------------------------------------
157 template <typename MODEL>
159  Log::trace() << "ObserverTLAD::doFinalizeTraj start" << std::endl;
160  observer_.finalizeTraj(xx, hoptlad_);
161  Log::trace() << "ObserverTLAD::doFinalizeTraj done" << std::endl;
162 }
163 // -----------------------------------------------------------------------------
164 template <typename MODEL>
166  Log::trace() << "ObserverTLAD::setupTL start" << std::endl;
167  ydeptl_.reset(new Departures_(obspace_));
168  ybiastl_ = &ybias;
169  Log::trace() << "ObserverTLAD::setupTL done" << std::endl;
170 }
171 // -----------------------------------------------------------------------------
172 template <typename MODEL>
174  const util::DateTime & end, const util::Duration & tstep) {
175  Log::trace() << "ObserverTLAD::doInitializeTL start" << std::endl;
176  const util::DateTime bgn(dx.validTime());
177  if (hslot_ == util::Duration(0)) hslot_ = tstep/2;
178  if (subwindows_) {
179  if (bgn == end) {
180  bgn_ = bgn - hslot_;
181  end_ = end + hslot_;
182  } else {
183  bgn_ = bgn;
184  end_ = end;
185  }
186  }
187  if (bgn_ < winbgn_) bgn_ = winbgn_;
188  if (end_ > winend_) end_ = winend_;
189 
190  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
191  boost::shared_ptr<GeoVaLs_>
192  gom(new GeoVaLs_(obspace_[jj].locations(bgn_, end_), hoptlad_.variables(jj)));
193  gvals_.push_back(gom);
194  }
195  Log::trace() << "ObserverTLAD::doInitializeTL done" << std::endl;
196 }
197 // -----------------------------------------------------------------------------
198 template <typename MODEL>
200  Log::trace() << "ObserverTLAD::doProcessingTL start" << std::endl;
201  util::DateTime t1(dx.validTime()-hslot_);
202  util::DateTime t2(dx.validTime()+hslot_);
203  if (t1 < bgn_) t1 = bgn_;
204  if (t2 > end_) t2 = end_;
205 
206 // Index for current bin
207  int ib = (dx.validTime()-winbgn_).toSeconds() / bintstep.toSeconds();
208 
209 // Get increment variables at obs locations
210  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
211  dx.getValuesTL(obspace_[jj].locations(t1, t2), hoptlad_.variables(jj),
212  *gvals_.at(jj), *traj_.at(ib).at(jj));
213  }
214  Log::trace() << "ObserverTLAD::doProcessingTL done" << std::endl;
215 }
216 // -----------------------------------------------------------------------------
217 template <typename MODEL>
219  Log::trace() << "ObserverTLAD::doFinalizeTL start" << std::endl;
220  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
221  hoptlad_[jj].simulateObsTL(*gvals_.at(jj), (*ydeptl_)[jj], *ybiastl_);
222  }
223  gvals_.clear();
224  Log::trace() << "ObserverTLAD::doFinalizeTL done" << std::endl;
225 }
226 // -----------------------------------------------------------------------------
227 template <typename MODEL>
228 void ObserverTLAD<MODEL>::setupAD(boost::shared_ptr<const Departures_> ydep,
229  ObsAuxIncr_ & ybias) {
230  Log::trace() << "ObserverTLAD::setupAD start" << std::endl;
231  ydepad_ = ydep;
232  ybiasad_ = &ybias;
233  Log::trace() << "ObserverTLAD::setupAD done" << std::endl;
234 }
235 // -----------------------------------------------------------------------------
236 template <typename MODEL>
237 void ObserverTLAD<MODEL>::doFirstAD(Increment_ & dx, const util::DateTime & bgn,
238  const util::Duration & tstep) {
239  Log::trace() << "ObserverTLAD::doFirstAD start" << std::endl;
240  if (hslot_ == util::Duration(0)) hslot_ = tstep/2;
241  const util::DateTime end(dx.validTime());
242  if (subwindows_) {
243  if (bgn == end) {
244  bgn_ = bgn - hslot_;
245  end_ = end + hslot_;
246  } else {
247  bgn_ = bgn;
248  end_ = end;
249  }
250  }
251  if (bgn_ < winbgn_) bgn_ = winbgn_;
252  if (end_ > winend_) end_ = winend_;
253 
254  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
255  boost::shared_ptr<GeoVaLs_>
256  gom(new GeoVaLs_(obspace_[jj].locations(bgn_, end_), hoptlad_.variables(jj)));
257  hoptlad_[jj].simulateObsAD(*gom, (*ydepad_)[jj], *ybiasad_);
258  gvals_.push_back(gom);
259  }
260  Log::trace() << "ObserverTLAD::doFirstAD done" << std::endl;
261 }
262 // -----------------------------------------------------------------------------
263 template <typename MODEL>
265  Log::trace() << "ObserverTLAD::doProcessingAD start" << std::endl;
266  util::DateTime t1(dx.validTime()-hslot_);
267  util::DateTime t2(dx.validTime()+hslot_);
268  if (t1 < bgn_) t1 = bgn_;
269  if (t2 > end_) t2 = end_;
270 
271 // Index for current bin
272  int ib = (dx.validTime()-winbgn_).toSeconds() / bintstep.toSeconds();
273 
274 // Adjoint of get increment variables at obs locations
275  for (std::size_t jj = 0; jj < obspace_.size(); ++jj) {
276  dx.getValuesAD(obspace_[jj].locations(t1, t2), hoptlad_.variables(jj),
277  *gvals_.at(jj), *traj_.at(ib).at(jj));
278  }
279  Log::trace() << "ObserverTLAD::doProcessingAD done" << std::endl;
280 }
281 // -----------------------------------------------------------------------------
282 template <typename MODEL>
284  Log::trace() << "ObserverTLAD::doLastAD start" << std::endl;
285  gvals_.clear();
286  Log::trace() << "ObserverTLAD::doLastAD done" << std::endl;
287 }
288 // -----------------------------------------------------------------------------
289 
290 } // namespace oops
291 
292 #endif // OOPS_BASE_OBSERVERTLAD_H_
ObsOperators< MODEL > ObsOperators_
Definition: ObserverTLAD.h:51
const bool subwindows_
Definition: ObserverTLAD.h:97
ObserverTLAD(const ObsSpace_ &, const ObsOperators_ &, const ObsAuxCtrl_ &, const ObsFilters_ &, const util::Duration &tslot=util::Duration(0), const bool subwin=false)
Definition: ObserverTLAD.h:108
void doProcessingAD(Increment_ &) override
Definition: ObserverTLAD.h:264
util::DateTime winbgn_
Begining of assimilation window.
Definition: ObserverTLAD.h:92
Departures_ * releaseOutputFromTL() override
Return TL dual space output.
Definition: ObserverTLAD.h:61
util::Duration hslot_
Half time slot.
Definition: ObserverTLAD.h:96
void getValuesAD(const Locations_ &, const Variables &, const GeoVaLs_ &, const InterpolatorTraj_ &)
void setupAD(boost::shared_ptr< const Departures_ >, ObsAuxIncr_ &)
Definition: ObserverTLAD.h:228
Observations_ * release()
Definition: ObserverTLAD.h:60
Difference between two observation vectors.
Definition: Departures.h:36
State< MODEL > State_
Definition: ObserverTLAD.h:53
************************************************************************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
ObsAuxIncrement< MODEL > ObsAuxIncr_
Definition: ObserverTLAD.h:49
util::Duration bintstep
Definition: ObserverTLAD.h:100
const util::DateTime validTime() const
Time.
const ObsSpace_ & obspace_
Definition: ObserverTLAD.h:82
Handles post-processing of model fields related to cost function.
Definition: PostBaseTLAD.h:39
Increment< MODEL > Increment_
Definition: ObserverTLAD.h:44
real, parameter t2
Encapsulates the model state.
Observations Class.
Definition: Observations.h:36
boost::shared_ptr< const Departures_ > ydepad_
Definition: ObserverTLAD.h:89
Observer< MODEL, State_ > observer_
Definition: ObserverTLAD.h:84
void doFinalizeTraj(const State_ &) override
Definition: ObserverTLAD.h:158
void doLastAD(Increment_ &) override
Definition: ObserverTLAD.h:283
InterpolatorTraj< MODEL > InterpolatorTraj_
Definition: ObserverTLAD.h:45
The namespace for the main oops code.
ObsFilters< MODEL > ObsFilters_
Definition: ObserverTLAD.h:50
const ObsAuxIncr_ * ybiastl_
Definition: ObserverTLAD.h:88
std::auto_ptr< Departures_ > ydeptl_
Definition: ObserverTLAD.h:87
real, parameter t1
util::DateTime end_
End of currently active observations.
Definition: ObserverTLAD.h:95
std::vector< boost::shared_ptr< GeoVaLs_ > > gvals_
Definition: ObserverTLAD.h:103
void doProcessingTraj(const State_ &) override
Definition: ObserverTLAD.h:145
Departures< MODEL > Departures_
Definition: ObserverTLAD.h:42
Computes observation equivalent during model run.
Definition: Observer.h:43
Observations< MODEL > Observations_
Definition: ObserverTLAD.h:47
Increment Class: Difference between two states.
void doInitializeTL(const Increment_ &, const util::DateTime &, const util::Duration &) override
Definition: ObserverTLAD.h:173
void doFirstAD(Increment_ &, const util::DateTime &, const util::Duration &) override
Definition: ObserverTLAD.h:237
util::DateTime bgn_
Begining of currently active observations.
Definition: ObserverTLAD.h:94
ObsSpaces< MODEL > ObsSpace_
Definition: ObserverTLAD.h:52
void getValuesTL(const Locations_ &, const Variables &, GeoVaLs_ &, const InterpolatorTraj_ &) const
Get increment values at observation locations.
void doInitializeTraj(const State_ &, const util::DateTime &, const util::Duration &) override
Definition: ObserverTLAD.h:124
util::DateTime winend_
End of assimilation window.
Definition: ObserverTLAD.h:93
void setupTL(const ObsAuxIncr_ &)
Definition: ObserverTLAD.h:165
std::vector< std::vector< boost::shared_ptr< InterpolatorTraj_ > > > traj_
Definition: ObserverTLAD.h:99
void doProcessingTL(const Increment_ &) override
Definition: ObserverTLAD.h:199
ObsAuxControl< MODEL > ObsAuxCtrl_
Definition: ObserverTLAD.h:48
GeoVaLs< MODEL > GeoVaLs_
Definition: ObserverTLAD.h:43
LinearObsOperators< MODEL > LinearObsOperators_
Definition: ObserverTLAD.h:46
ObsAuxIncr_ * ybiasad_
Definition: ObserverTLAD.h:90
void doFinalizeTL(const Increment_ &) override
Definition: ObserverTLAD.h:218
Computes observation equivalent TL and AD to/from increments.
Definition: ObserverTLAD.h:41
LinearObsOperators_ hoptlad_
Definition: ObserverTLAD.h:83
const util::DateTime validTime() const
Time.