FV3 Bundle
oops/interface/LinearModel.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_INTERFACE_LINEARMODEL_H_
12 #define OOPS_INTERFACE_LINEARMODEL_H_
13 
14 #include <string>
15 
16 #include <boost/noncopyable.hpp>
17 #include <boost/scoped_ptr.hpp>
18 
26 #include "oops/interface/State.h"
27 #include "oops/util/Duration.h"
28 #include "oops/util/Logger.h"
29 #include "oops/util/ObjectCounter.h"
30 #include "oops/util/Printable.h"
31 #include "oops/util/Timer.h"
32 
33 namespace eckit {
34  class Configuration;
35 }
36 
37 namespace oops {
38 
39 /// Encapsulates the linear forecast model.
40 /*!
41  * This class provides the operations associated with the LinearModel. It wraps
42  * the actual linear model which can be a model specific one or a generic one
43  * (identity). The interface for the linear model comprises two levels (LinearModel
44  * and LinearModelBase) because we want run time polymorphism.
45  */
46 // -----------------------------------------------------------------------------
47 
48 template <typename MODEL>
49 class LinearModel : public util::Printable,
50  private boost::noncopyable,
51  private util::ObjectCounter<LinearModel<MODEL> > {
58 
59  public:
60  static const std::string classname() {return "oops::LinearModel";}
61 
62  LinearModel(const Geometry_ &, const eckit::Configuration &);
63  ~LinearModel();
64 
65 /// Run the tangent linear forecast
66  void forecastTL(Increment_ &, const ModelAuxIncr_ &, const util::Duration &,
69  const bool idmodel = false) const;
70 
71 /// Run the adjoint forecast
72  void forecastAD(Increment_ &, ModelAuxIncr_ &, const util::Duration &,
75  const bool idmodel = false) const;
76 
77 // Set the linearization trajectory
78  void setTrajectory(const State_ &, State_ &, const ModelAux_ &);
79 
80 // Information and diagnostics
81  const util::Duration & timeResolution() const {return tlm_->timeResolution();}
82  const oops::Variables & variables() const {return tlm_->variables();}
83 
84  protected:
85 // Run the TL forecast
86  void initializeTL(Increment_ &) const;
87  void stepTL(Increment_ &, const ModelAuxIncr_ &) const;
88  void finalizeTL(Increment_ &) const;
89 
90 // Run the AD forecast
91  void initializeAD(Increment_ &) const;
92  void stepAD(Increment_ &, ModelAuxIncr_ &) const;
93  void finalizeAD(Increment_ &) const;
94 
95  private:
96 // diagnostics
97  void print(std::ostream &) const;
98 
99  boost::scoped_ptr<LinearModelBase_> tlm_;
100 };
101 
102 // =============================================================================
103 
104 template<typename MODEL>
105 LinearModel<MODEL>::LinearModel(const Geometry_ & resol, const eckit::Configuration & conf)
106  : tlm_()
107 {
108  Log::trace() << "LinearModel<MODEL>::LinearModel starting" << std::endl;
109  util::Timer timer(classname(), "LinearModel");
110  Log::debug() << "LinearModel config is:" << conf << std::endl;
112  Log::trace() << "LinearModel<MODEL>::LinearModel done" << std::endl;
113 }
114 
115 // -----------------------------------------------------------------------------
116 
117 template<typename MODEL>
119  Log::trace() << "LinearModel<MODEL>::~LinearModel starting" << std::endl;
120  util::Timer timer(classname(), "~LinearModel");
121  tlm_.reset();
122  Log::trace() << "LinearModel<MODEL>::~LinearModel done" << std::endl;
123 }
124 
125 // -----------------------------------------------------------------------------
126 
127 // -----------------------------------------------------------------------------
128 /// Run forecast TL and AD
129 // -----------------------------------------------------------------------------
130 
131 template<typename MODEL>
133  const util::Duration & len,
136  const bool idmodel) const {
137  Log::trace() << "LinearModel<MODEL>::forecastTL starting" << std::endl;
138  util::Timer timer(classname(), "forecastTL");
139 
140  const util::DateTime end(dx.validTime() + len);
141  const util::Duration tstep(tlm_->timeResolution());
142  Log::info() << "LinearModel<MODEL>::forecastTL: Starting " << dx << std::endl;
143  this->initializeTL(dx);
144  cost.initializeTL(dx, end, tstep);
145  post.initialize(dx, end, tstep);
146  cost.processTL(dx);
147  post.process(dx);
148  if (idmodel) {
149  while (dx.validTime() < end) {
150  dx.updateTime(tstep);
151  cost.processTL(dx);
152  post.process(dx);
153  }
154  } else {
155  while (dx.validTime() < end) {
156  this->stepTL(dx, mctl);
157  cost.processTL(dx);
158  post.process(dx);
159  }
160  }
161  cost.finalizeTL(dx);
162  post.finalize(dx);
163  this->finalizeTL(dx);
164  Log::info() << "LinearModel<MODEL>::forecastTL: Finished " << dx << std::endl;
165  ASSERT(dx.validTime() == end);
166 
167  Log::trace() << "LinearModel<MODEL>::forecastTL done" << std::endl;
168 }
169 
170 // -----------------------------------------------------------------------------
171 
172 template<typename MODEL>
174  const util::Duration & len,
177  const bool idmodel) const {
178  Log::trace() << "LinearModel<MODEL>::forecastAD starting" << std::endl;
179  util::Timer timer(classname(), "forecastAD");
180 
181  const util::DateTime bgn(dx.validTime() - len);
182  const util::Duration tstep(tlm_->timeResolution());
183  Log::info() << "LinearModel<MODEL>::forecastAD: Starting " << dx << std::endl;
184  this->initializeAD(dx);
185  post.initialize(dx, bgn, tstep);
186  cost.initializeAD(dx, bgn, tstep);
187  if (idmodel) {
188  while (dx.validTime() > bgn) {
189  cost.processAD(dx);
190  dx.updateTime(-tstep);
191  post.process(dx);
192  }
193  } else {
194  while (dx.validTime() > bgn) {
195  cost.processAD(dx);
196  this->stepAD(dx, mctl);
197  post.process(dx);
198  }
199  }
200  cost.processAD(dx);
201  post.process(dx);
202  cost.finalizeAD(dx);
203  post.finalize(dx);
204  this->finalizeAD(dx);
205  Log::info() << "LinearModel<MODEL>::forecastAD: Finished " << dx << std::endl;
206  ASSERT(dx.validTime() == bgn);
207 
208  Log::trace() << "LinearModel<MODEL>::forecastAD done" << std::endl;
209 }
210 
211 // -----------------------------------------------------------------------------
212 
213 template<typename MODEL>
215  const ModelAux_ & maux) {
216  Log::trace() << "LinearModel<MODEL>::setTrajectory starting" << std::endl;
217  util::Timer timer(classname(), "setTrajectory");
218  tlm_->setTrajectory(xx, xlr, maux);
219  Log::trace() << "LinearModel<MODEL>::setTrajectory done" << std::endl;
220 }
221 
222 // -----------------------------------------------------------------------------
223 
224 template<typename MODEL>
226  Log::trace() << "LinearModel<MODEL>::initializeTL starting" << std::endl;
227  util::Timer timer(classname(), "initializeTL");
228  tlm_->initializeTL(dx);
229  Log::trace() << "LinearModel<MODEL>::initializeTL done" << std::endl;
230 }
231 
232 // -----------------------------------------------------------------------------
233 
234 template<typename MODEL>
235 void LinearModel<MODEL>::stepTL(Increment_ & dx, const ModelAuxIncr_ & merr) const {
236  Log::trace() << "LinearModel<MODEL>::stepTL starting" << std::endl;
237  util::Timer timer(classname(), "stepTL");
238  tlm_->stepTL(dx, merr);
239  Log::trace() << "LinearModel<MODEL>::stepTL done" << std::endl;
240 }
241 
242 // -----------------------------------------------------------------------------
243 
244 template<typename MODEL>
246  Log::trace() << "LinearModel<MODEL>::finalizeTL starting" << std::endl;
247  util::Timer timer(classname(), "finalizeTL");
248  tlm_->finalizeTL(dx);
249  Log::trace() << "LinearModel<MODEL>::finalizeTL done" << std::endl;
250 }
251 
252 // -----------------------------------------------------------------------------
253 
254 template<typename MODEL>
256  Log::trace() << "LinearModel<MODEL>::initializeAD starting" << std::endl;
257  util::Timer timer(classname(), "initializeAD");
258  tlm_->initializeAD(dx);
259  Log::trace() << "LinearModel<MODEL>::initializeAD done" << std::endl;
260 }
261 
262 // -----------------------------------------------------------------------------
263 
264 template<typename MODEL>
266  Log::trace() << "LinearModel<MODEL>::stepAD starting" << std::endl;
267  util::Timer timer(classname(), "stepAD");
268  tlm_->stepAD(dx, merr);
269  Log::trace() << "LinearModel<MODEL>::stepAD done" << std::endl;
270 }
271 
272 // -----------------------------------------------------------------------------
273 
274 template<typename MODEL>
276  Log::trace() << "LinearModel<MODEL>::finalizeAD starting" << std::endl;
277  util::Timer timer(classname(), "finalizeAD");
278  tlm_->finalizeAD(dx);
279  Log::trace() << "LinearModel<MODEL>::finalizeAD done" << std::endl;
280 }
281 
282 // -----------------------------------------------------------------------------
283 
284 template<typename MODEL>
285 void LinearModel<MODEL>::print(std::ostream & os) const {
286  Log::trace() << "LinearModel<MODEL>::print starting" << std::endl;
287  util::Timer timer(classname(), "print");
288  os << *tlm_;
289  Log::trace() << "LinearModel<MODEL>::print done" << std::endl;
290 }
291 
292 // -----------------------------------------------------------------------------
293 
294 } // namespace oops
295 
296 #endif // OOPS_INTERFACE_LINEARMODEL_H_
Increment< MODEL > Increment_
void initializeAD(Increment_ &dx, const util::DateTime &bgn, const util::Duration &step)
Adjoint methods.
void finalizeAD(Increment_ &) const
static const std::string classname()
************************************************************************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
Definition: conf.py:1
void stepAD(Increment_ &, ModelAuxIncr_ &) const
const oops::Variables & variables() const
const util::DateTime validTime() const
Time.
void stepTL(Increment_ &, const ModelAuxIncr_ &) const
Encapsulates the model state.
void finalizeTL(const Increment_ &dx)
void finalizeAD(Increment_ &dx)
boost::scoped_ptr< LinearModelBase_ > tlm_
LinearModelBase< MODEL > LinearModelBase_
ModelAuxControl< MODEL > ModelAux_
void updateTime(const util::Duration &dt)
The namespace for the main oops code.
logical debug
Definition: mpp.F90:1297
void processTL(const Increment_ &dx)
subroutine, public info(self)
void processAD(Increment_ &dx)
void finalizeTL(Increment_ &) const
void finalize(const FLDS &xx)
Definition: PostProcessor.h:60
Control model post processing.
void setTrajectory(const State_ &, State_ &, const ModelAux_ &)
void process(const FLDS &xx)
Definition: PostProcessor.h:56
Base class for encapsulation of the linear forecast model.
LinearModelFactory Factory.
const util::Duration & timeResolution() const
Increment Class: Difference between two states.
void initializeTL(const Increment_ &dx, const util::DateTime &end, const util::Duration &step)
Tangent linear methods.
void forecastAD(Increment_ &, ModelAuxIncr_ &, const util::Duration &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), PostProcessorTLAD< MODEL > cost=PostProcessorTLAD< MODEL >(), const bool idmodel=false) const
Run the adjoint forecast.
void forecastTL(Increment_ &, const ModelAuxIncr_ &, const util::Duration &, PostProcessor< Increment_ > post=PostProcessor< Increment_ >(), PostProcessorTLAD< MODEL > cost=PostProcessorTLAD< MODEL >(), const bool idmodel=false) const
Run the tangent linear forecast.
Control model post processing.
Definition: PostProcessor.h:31
LinearModel(const Geometry_ &, const eckit::Configuration &)
void initialize(const FLDS &xx, const util::DateTime &end, const util::Duration &step)
Definition: PostProcessor.h:50
Encapsulates the linear forecast model.
void initializeAD(Increment_ &) const
void initializeTL(Increment_ &) const
ModelAuxIncrement< MODEL > ModelAuxIncr_
void print(std::ostream &) const