OOPS
IncrementEnsemble4D.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_INCREMENTENSEMBLE4D_H_
12 #define OOPS_BASE_INCREMENTENSEMBLE4D_H_
13 
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include <boost/ptr_container/ptr_vector.hpp>
20 
21 #include "eckit/config/LocalConfiguration.h"
24 #include "oops/base/Accumulator.h"
27 #include "oops/base/Variables.h"
29 #include "oops/util/DateTime.h"
30 #include "oops/util/Logger.h"
31 
32 namespace oops {
33 
34 // -----------------------------------------------------------------------------
35 
36 /// \brief Ensemble of 4D inrements
37 template<typename MODEL> class IncrementEnsemble4D {
43 
44  typedef typename boost::ptr_vector<LinearVariableChangeBase_> ChvarVec_;
45  typedef typename ChvarVec_::const_reverse_iterator ircst_;
46 
47  public:
48  /// Constructor
49  IncrementEnsemble4D(const Geometry_ & resol,
50  const Variables & vars,
51  const std::vector<util::DateTime> &,
52  const int rank);
53  /// \brief construct ensemble of perturbations as \p ens - \p mean; holding
54  // \p vars variables
55  IncrementEnsemble4D(const StateEnsemble4D_ & ens, const State4D_ & mean,
56  const Variables & vars);
57  IncrementEnsemble4D(const eckit::Configuration &,
58  const State4D_ &, const State4D_ &, const Geometry_ &, const Variables &);
59 
60  /// Accessors
61  unsigned int size() const {
62  return ensemblePerturbs_.size();
63  }
64  Increment4D_ & operator[](const int ii) {
65  return ensemblePerturbs_[ii];
66  }
67  const Increment4D_ & operator[](const int ii) const {
68  return ensemblePerturbs_[ii];
69  }
70 
71  /// Control variables
72  const Variables & controlVariables() const {return vars_;}
73 
74  /// Release / reset
75  void releaseMember();
76  void resetMember(const Increment4D_ &);
77 
78  private:
80  std::vector<Increment4D_> ensemblePerturbs_;
81 };
82 
83 // ====================================================================================
84 
85 template<typename MODEL>
87  const std::vector<util::DateTime> & timeslots,
88  const int rank)
89  : vars_(vars), ensemblePerturbs_()
90 {
91  ensemblePerturbs_.reserve(rank);
92  for (int m = 0; m < rank; ++m) {
93  ensemblePerturbs_.emplace_back(resol, vars_, timeslots);
94  }
95  Log::trace() << "IncrementEnsemble4D:contructor done" << std::endl;
96 }
97 
98 // ====================================================================================
99 
100 template<typename MODEL>
102  const State4D_ & mean, const Variables & vars)
103  : vars_(vars), ensemblePerturbs_()
104 {
105  ensemblePerturbs_.reserve(ensemble.size());
106  for (size_t ii = 0; ii < ensemble.size(); ++ii) {
107  ensemblePerturbs_.emplace_back(ensemble[ii].geometry(), vars,
108  ensemble[ii].validTimes());
109  ensemblePerturbs_[ii].diff(ensemble[ii], mean);
110  }
111  Log::trace() << "IncrementEnsemble4D:contructor(StateEnsemble4D) done" << std::endl;
112 }
113 
114 // -----------------------------------------------------------------------------
115 
116 template<typename MODEL>
117 IncrementEnsemble4D<MODEL>::IncrementEnsemble4D(const eckit::Configuration & conf,
118  const State4D_ & xb, const State4D_ & fg,
119  const Geometry_ & resol, const Variables & vars)
120  : vars_(vars), ensemblePerturbs_()
121 {
122  // Get rank from config
123  std::vector<eckit::LocalConfiguration> memberConfig;
124  conf.get("members", memberConfig);
125 
126  // Check sizes and fill in timeslots
127  ASSERT(xb.size() == fg.size());
128  std::vector<util::DateTime> timeslots(xb.size());
129  for (unsigned jsub = 0; jsub < xb.size(); ++jsub) {
130  ASSERT(xb[jsub].validTime() == fg[jsub].validTime());
131  timeslots[jsub] = xb[jsub].validTime();
132  }
133 
134  // Read inflation field
135  std::unique_ptr<Increment4D_> inflationField;
136  if (conf.has("inflation field")) {
137  const eckit::LocalConfiguration inflationConfig(conf, "inflation field");
138  inflationField.reset(new Increment4D_(resol, vars, timeslots));
139  inflationField->read(inflationConfig);
140  }
141 
142  // Get inflation value
143  double inflationValue = 1;
144  if (conf.has("inflation value")) {
145  conf.get("inflation value", inflationValue);
146  }
147 
148  // Setup change of variable
149  ChvarVec_ chvars;
150  if (conf.has("variable changes")) {
151  std::vector<eckit::LocalConfiguration> chvarconfs;
152  conf.get("variable changes", chvarconfs);
153  for (const auto & conf : chvarconfs) {
154  chvars.push_back(LinearVariableChangeFactory<MODEL>::create(xb[0], fg[0], resol, conf));
155  }
156  }
157  // TODO(Benjamin): one change of variable for each timeslot
158 
159  // Read ensemble
160  StateEnsemble4D_ ensemble(resol, conf);
161  State4D_ bgmean = ensemble.mean();
162 
163  ensemblePerturbs_.reserve(ensemble.size());
164  for (unsigned int ie = 0; ie < ensemble.size(); ++ie) {
165  // Ensemble will be centered around ensemble mean
166  Increment4D_ dx(resol, vars_, timeslots);
167  dx.diff(ensemble[ie], bgmean);
168 
169  // Apply inflation
170  if (conf.has("inflation field")) {
171  dx.schur_product_with(*inflationField);
172  }
173  dx *= inflationValue;
174 
175  // Apply inverse of the linear balance operator
176  for (unsigned jsub = 0; jsub < timeslots.size(); ++jsub) {
177  // K_1^{-1} K_2^{-1} .. K_N^{-1}
178  for (ircst_ it = chvars.rbegin(); it != chvars.rend(); ++it) {
179  dx[jsub] = it->multiplyInverse(dx[jsub]);
180  }
181  }
182 
183  ensemblePerturbs_.emplace_back(std::move(dx));
184  }
185  Log::trace() << "IncrementEnsemble4D:contructor done" << std::endl;
186 }
187 
188 // -----------------------------------------------------------------------------
189 
190 template<typename MODEL>
192  ensemblePerturbs_.erase(ensemblePerturbs_.begin());
193 }
194 
195 // -----------------------------------------------------------------------------
196 
197 template<typename MODEL>
199  ensemblePerturbs_.emplace_back(dx);
200 }
201 
202 // -----------------------------------------------------------------------------
203 
204 } // namespace oops
205 
206 #endif // OOPS_BASE_INCREMENTENSEMBLE4D_H_
oops
The namespace for the main oops code.
Definition: ErrorCovarianceL95.cc:22
oops::IncrementEnsemble4D::controlVariables
const Variables & controlVariables() const
Control variables.
Definition: IncrementEnsemble4D.h:72
oops::IncrementEnsemble4D::ChvarVec_
boost::ptr_vector< LinearVariableChangeBase_ > ChvarVec_
Definition: IncrementEnsemble4D.h:44
StateEnsemble4D.h
oops::IncrementEnsemble4D::Increment4D_
Increment4D< MODEL > Increment4D_
Definition: IncrementEnsemble4D.h:42
oops::LinearVariableChangeFactory
LinearVariableChange factory.
Definition: LinearVariableChangeBase.h:85
Increment4D.h
oops::StateEnsemble4D::size
unsigned int size() const
Accessors.
Definition: StateEnsemble4D.h:38
oops::IncrementEnsemble4D::operator[]
Increment4D_ & operator[](const int ii)
Definition: IncrementEnsemble4D.h:64
oops::IncrementEnsemble4D::StateEnsemble4D_
StateEnsemble4D< MODEL > StateEnsemble4D_
Definition: IncrementEnsemble4D.h:41
oops::IncrementEnsemble4D::vars_
const Variables vars_
Definition: IncrementEnsemble4D.h:79
oops::LinearVariableChangeBase
Definition: LinearVariableChangeBase.h:53
oops::IncrementEnsemble4D::releaseMember
void releaseMember()
Release / reset.
Definition: IncrementEnsemble4D.h:191
oops::IncrementEnsemble4D::IncrementEnsemble4D
IncrementEnsemble4D(const Geometry_ &resol, const Variables &vars, const std::vector< util::DateTime > &, const int rank)
Constructor.
Definition: IncrementEnsemble4D.h:86
oops::IncrementEnsemble4D::ensemblePerturbs_
std::vector< Increment4D_ > ensemblePerturbs_
Definition: IncrementEnsemble4D.h:80
oops::IncrementEnsemble4D::LinearVariableChangeBase_
LinearVariableChangeBase< MODEL > LinearVariableChangeBase_
Definition: IncrementEnsemble4D.h:38
oops::Increment4D::schur_product_with
void schur_product_with(const Increment4D &)
Definition: Increment4D.h:345
oops::Increment4D::diff
void diff(const State4D_ &, const State4D_ &)
Linear algebra operators.
Definition: Increment4D.h:245
oops::IncrementEnsemble4D::size
unsigned int size() const
Accessors.
Definition: IncrementEnsemble4D.h:61
oops::IncrementEnsemble4D
Ensemble of 4D inrements.
Definition: IncrementEnsemble4D.h:37
oops::State4D
Four dimensional state.
Definition: State4D.h:35
oops::StateEnsemble4D::mean
State4D_ mean() const
calculate ensemble mean
Definition: StateEnsemble4D.h:68
oops::Geometry
Geometry class used in oops; subclass of interface class above.
Definition: oops/interface/Geometry.h:189
oops::State4D::size
size_t size() const
Definition: State4D.h:53
oops::Increment4D
State increment.
Definition: Increment4D.h:49
Accumulator.h
oops::IncrementEnsemble4D::State4D_
State4D< MODEL > State4D_
Definition: IncrementEnsemble4D.h:40
State4D.h
oops::StateEnsemble4D
Ensemble of 4D states.
Definition: StateEnsemble4D.h:26
oops::IncrementEnsemble4D::Geometry_
Geometry< MODEL > Geometry_
Definition: IncrementEnsemble4D.h:39
oops::Variables
Definition: oops/base/Variables.h:23
oops::IncrementEnsemble4D::resetMember
void resetMember(const Increment4D_ &)
Definition: IncrementEnsemble4D.h:198
LinearVariableChangeBase.h
oops::IncrementEnsemble4D::operator[]
const Increment4D_ & operator[](const int ii) const
Definition: IncrementEnsemble4D.h:67
Variables.h
oops::IncrementEnsemble4D::ircst_
ChvarVec_::const_reverse_iterator ircst_
Definition: IncrementEnsemble4D.h:45
Geometry.h