FV3 Bundle
ParametersBUMP.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_GENERIC_PARAMETERSBUMP_H_
12 #define OOPS_GENERIC_PARAMETERSBUMP_H_
13 
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 
18 #include <boost/date_time/posix_time/posix_time.hpp>
19 #include <boost/scoped_ptr.hpp>
20 
21 #include "eckit/config/Configuration.h"
25 #include "oops/base/Variables.h"
26 #include "oops/generic/oobump_f.h"
30 #include "oops/util/DateTime.h"
31 #include "oops/util/Duration.h"
32 #include "oops/util/Logger.h"
33 
34 namespace eckit {
35  class Configuration;
36 }
37 
38 namespace oops {
39 
40 // -----------------------------------------------------------------------------
41 /// BUMP diagnostics.
42 
43 template<typename MODEL>
49 
51  typedef boost::shared_ptr<StateEnsemble<MODEL> > EnsemblePtr_;
53 
54  public:
55  static const std::string classname() {return "oops::ParametersBUMP";}
56  explicit ParametersBUMP(const eckit::Configuration &);
58 
59  void estimate() const;
60  void write() const;
61 
62  private:
63  const eckit::LocalConfiguration conf_;
65  int keyBUMP_;
66 };
67 
68 // =============================================================================
69 
70 template<typename MODEL>
71 ParametersBUMP<MODEL>::ParametersBUMP(const eckit::Configuration & conf)
72  : conf_(conf), colocated_(1), keyBUMP_(0)
73 {
74  Log::trace() << "ParametersBUMP<MODEL>::ParametersBUMP construction starting" << std::endl;
75  util::Timer timer(classname(), "ParametersBUMP");
76 
77  const eckit::Configuration * fconf = &conf;
78 
79 // Setup resolution
80  const eckit::LocalConfiguration resolConfig(conf_, "resolution");
81  const Geometry_ resol(resolConfig);
82 
83 // Setup variables
84  const eckit::LocalConfiguration varConfig(conf_, "variables");
85  const Variables vars(varConfig);
86 
87 // Setup time
88  const util::DateTime date(conf_.getString("date"));
89 
90 // Setup background state
91  const eckit::LocalConfiguration backgroundConfig(conf_, "background");
92  State_ xx(resol, vars, backgroundConfig);
93 
94 // Setup dummy increment
95  Increment_ dx(resol, vars, date);
96 
97 // Define unstructured grid coordinates
99  dx.ug_coord(ug, colocated_);
100 
101 // Compute the ensemble of perturbations at time of xx
102  const eckit::LocalConfiguration ensembleConfig(conf_, "ensemble");
103  EnsemblePtr_ ens_ptr(new Ensemble_(xx.validTime(), ensembleConfig));
104  ens_ptr->linearize(xx, xx, resol);
105  EnsemblesCollection_::getInstance().put(xx.validTime(), ens_ptr);
106  int ens1_ne = ens_ptr->size();
107 
108 // Setup pseudo ensemble
109  boost::ptr_vector<Increment_> bkgens;
110  int ens2_ne = 0;
111  if (conf_.has("covariance")) {
112  // Setup background error covariance
113  const eckit::LocalConfiguration covarConfig(conf_, "covariance");
114  ErrorCovariance_ cov(resol, vars, covarConfig, xx, xx);
115 
116  // Compute a pseudo ensemble using randomization
117  ens2_ne = covarConfig.getInt("pseudoens_size");
118  for (int ii = 0; ii < ens2_ne; ++ii) {
119  Increment_ * incr = new Increment_(resol, vars, date);
120  cov.randomize(*incr);
121  bkgens.push_back(incr);
122  }
123  }
124 
125 // Create BUMP
126  create_oobump_f90(keyBUMP_, ug.toFortran(), &fconf, ens1_ne, 1, ens2_ne, 1);
127 
128 // Copy ensemble members
129  const double rk = sqrt((static_cast<double>(ens1_ne) - 1.0));
130  for (int ie = 0; ie < ens1_ne; ++ie) {
131  Log::info() << "Copy ensemble member " << ie+1 << " / "
132  << ens1_ne << " to BUMP" << std::endl;
133 
134  // Renormalize member
135  dx = (*ens_ptr)[ie];
136  dx *= rk;
137 
138  // Define unstructured grid field
139  UnstructuredGrid ugmem;
140  dx.field_to_ug(ugmem, colocated_);
141 
142  // Copy field into BUMP ensemble
144  }
145 
146 // Copy pseudo-ensemble members
147  for (int ie = 0; ie < ens2_ne; ++ie) {
148  Log::info() << "Copy pseudo ensemble member " << ie+1 << " / "
149  << ens2_ne << " to BUMP" << std::endl;
150 
151  // Define unstructured grid field
152  UnstructuredGrid ugmem;
153  bkgens[ie].field_to_ug(ugmem, colocated_);
154 
155  // Copy field into BUMP ensemble
157  }
158 
159  Log::trace() << "ParametersBUMP:ParametersBUMP constructed" << std::endl;
160 }
161 
162 // -----------------------------------------------------------------------------
163 
164 template<typename MODEL>
166  Log::trace() << "ParametersBUMP<MODEL>::~ParametersBUMP destruction starting" << std::endl;
167  util::Timer timer(classname(), "~ParametersBUMP");
168  delete_oobump_f90(keyBUMP_);
169  Log::trace() << "ParametersBUMP:~ParametersBUMP destructed" << std::endl;
170 }
171 
172 // -----------------------------------------------------------------------------
173 
174 template<typename MODEL>
176  Log::trace() << "ParametersBUMP::estimate starting" << std::endl;
177  util::Timer timer(classname(), "estimate");
178 
179 // Read data from files
180  if (conf_.has("input")) {
181  // Setup resolution
182  const eckit::LocalConfiguration resolConfig(conf_, "resolution");
183  const Geometry_ resol(resolConfig);
184 
185  // Setup variables
186  const eckit::LocalConfiguration varConfig(conf_, "variables");
187  const Variables vars(varConfig);
188 
189  // Setup time
190  const util::DateTime date(conf_.getString("date"));
191 
192  // Setup dummy increment
193  Increment_ dx(resol, vars, date);
194  dx.zero();
195 
196  // Setup unstructured grid
197  UnstructuredGrid ug;
198 
199  std::vector<eckit::LocalConfiguration> inputConfigs;
200  conf_.get("input", inputConfigs);
201  for (const auto & conf : inputConfigs) {
202  dx.read(conf);
203  dx.field_to_ug(ug, colocated_);
204  std::string param = conf.getString("parameter");
205  const int nstr = param.size();
206  const char *cstr = param.c_str();
207  set_oobump_param_f90(keyBUMP_, nstr, cstr, ug.toFortran());
208  }
209  }
210 
211 // Estimate parameters
212  run_oobump_drivers_f90(keyBUMP_);
213 
214 // Copy test
215  std::ifstream infile("bump.test");
216  std::string line;
217  while (std::getline(infile, line)) Log::test() << line << std::endl;
218  remove("bump.test");
219 
220  Log::trace() << "ParametersBUMP:estimate done" << std::endl;
221 }
222 
223 // -----------------------------------------------------------------------------
224 
225 template<typename MODEL>
227  Log::trace() << "ParametersBUMP::write starting" << std::endl;
228  util::Timer timer(classname(), "write");
229 
230 // Setup resolution
231  const eckit::LocalConfiguration resolConfig(conf_, "resolution");
232  const Geometry_ resol(resolConfig);
233 
234 // Setup variables
235  const eckit::LocalConfiguration varConfig(conf_, "variables");
236  const Variables vars(varConfig);
237 
238 // Setup time
239  const util::DateTime date(conf_.getString("date"));
240 
241 // Setup dummy increment
242  Increment_ dx(resol, vars, date);
243  dx.zero();
244 
245 // Setup unstructured grid
246  UnstructuredGrid ug;
247  dx.field_to_ug(ug, colocated_);
248 
249 // Write parameters
250  std::vector<eckit::LocalConfiguration> outputConfigs;
251  conf_.get("output", outputConfigs);
252  for (const auto & conf : outputConfigs) {
253  std::string param = conf.getString("parameter");
254  const int nstr = param.size();
255  const char *cstr = param.c_str();
256  get_oobump_param_f90(keyBUMP_, nstr, cstr, ug.toFortran());
257  dx.field_from_ug(ug);
258  dx.write(conf);
259  Log::test() << "Norm of " << param << ": " << dx.norm() << std::endl;
260  }
261  Log::trace() << "ParametersBUMP::write done" << std::endl;
262 }
263 
264 // -----------------------------------------------------------------------------
265 
266 } // namespace oops
267 
268 #endif // OOPS_GENERIC_PARAMETERSBUMP_H_
void ug_coord(UnstructuredGrid &, const int &) const
Unstructured grid.
void delete_oobump_f90(const int &)
void get_oobump_param_f90(const int &, const int &, const char *, const int &)
Increment< MODEL > Increment_
boost::shared_ptr< StateEnsemble< MODEL > > EnsemblePtr_
Definition: conf.py:1
BUMP diagnostics.
static EnsemblesCollection< MODEL > & getInstance()
Wrapper for model space error covariances.
Encapsulates the model state.
string date
Definition: TLM_vs_NLM.py:10
program test
ErrorCovariance< MODEL > ErrorCovariance_
The namespace for the main oops code.
void create_oobump_f90(int &, const int &, const eckit::Configuration *const *, const int &, const int &, const int &, const int &)
State< MODEL > State_
EnsemblesCollection< MODEL > EnsemblesCollection_
void field_to_ug(UnstructuredGrid &, const int &) const
static const std::string classname()
integer, private ie
Definition: fms_io.F90:494
subroutine, public info(self)
int readEnsMember(1)
void set_oobump_param_f90(const int &, const int &, const char *, const int &)
Geometry< MODEL > Geometry_
const eckit::LocalConfiguration conf_
Increment Class: Difference between two states.
ParametersBUMP(const eckit::Configuration &)
StateEnsemble< MODEL > Ensemble_
int readPseudoEnsMember(2)
void run_oobump_drivers_f90(const int &)
void add_oobump_member_f90(const int &, const int &, const int &, const int &)
void randomize(Increment_ &) const override
const util::DateTime validTime() const
Time.