FV3 Bundle
test/lorenz95/IncrementL95.cc
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 #include <cmath>
12 #include <fstream>
13 #include <iostream>
14 
15 #include <boost/scoped_ptr.hpp>
16 #include <boost/test/unit_test.hpp>
17 
18 #include "./TestConfig.h"
19 #include "eckit/config/LocalConfiguration.h"
20 #include "lorenz95/GomL95.h"
21 #include "lorenz95/IncrementL95.h"
22 #include "lorenz95/LocsL95.h"
23 #include "lorenz95/Resolution.h"
24 #include "lorenz95/StateL95.h"
25 #include "oops/base/Variables.h"
26 #include "oops/util/DateTime.h"
27 #include "test/TestFixture.h"
28 
29 namespace test {
30 
31 // -----------------------------------------------------------------------------
33  public:
35  file_.reset(new eckit::LocalConfiguration(TestConfig::config(), "state"));
36  eckit::LocalConfiguration res(TestConfig::config(), "resolution");
37  resol_.reset(new lorenz95::Resolution(res));
38  date_str_ = file_->getString("date");
39  time_.reset(new util::DateTime(date_str_));
41  }
43  boost::scoped_ptr<const eckit::LocalConfiguration> file_;
44  boost::scoped_ptr<lorenz95::Resolution> resol_;
45  std::string date_str_;
46  boost::scoped_ptr<util::DateTime> time_;
47  boost::scoped_ptr<oops::Variables> vars_;
48 };
49 // -----------------------------------------------------------------------------
50 
51 // -----------------------------------------------------------------------------
52 BOOST_FIXTURE_TEST_SUITE(test_IncrementL95, IncrementTestFixture)
53 
54 // -----------------------------------------------------------------------------
55  BOOST_AUTO_TEST_CASE(test_incrementL95_constructor) {
56  boost::scoped_ptr<lorenz95::IncrementL95>
57  dx(new lorenz95::IncrementL95(*resol_, *vars_, *time_));
58  BOOST_CHECK(dx.get() != NULL);
59  }
60 // -----------------------------------------------------------------------------
61  BOOST_AUTO_TEST_CASE(test_incrementL95_interpolation_constructor) {
62  boost::scoped_ptr<lorenz95::IncrementL95>
63  dx1(new lorenz95::IncrementL95(*resol_, *vars_, *time_));
64  boost::scoped_ptr<lorenz95::IncrementL95>
65  dx2(new lorenz95::IncrementL95(*resol_, *dx1));
66  BOOST_CHECK(dx2.get() != NULL);
67  }
68 // -----------------------------------------------------------------------------
69  BOOST_AUTO_TEST_CASE(test_incrementL95_copy_constructor) {
70  boost::scoped_ptr<lorenz95::IncrementL95>
71  dx1(new lorenz95::IncrementL95(*resol_, *vars_, *time_));
72  boost::scoped_ptr<lorenz95::IncrementL95> dx2(new lorenz95::IncrementL95(*dx1));
73  BOOST_CHECK(dx2.get() != NULL);
74  }
75 // -----------------------------------------------------------------------------
76  BOOST_AUTO_TEST_CASE(test_incrementL95_diff) {
77  util::DateTime tt(file_->getString("date"));
78  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
79  dx.read(*file_);
80 
81  // construct the first stateL95 object
82  lorenz95::StateL95 xx1(*resol_, *vars_, tt);
83 
84  // read in the state config info
85  xx1.read(*file_);
86  lorenz95::StateL95 xx2(xx1);
87 
88  // to vary the results a little, change the second StateL95 field values
89  double fact = 0.75;
90  dx *= fact;
91  xx2 += dx;
92 
93  dx.diff(xx1, xx2);
94 
95  // to verify the diff method has worked correctly, we need
96  // to open and read the file containing the FieldL95
97  std::string filename(file_->getString("filename"));
98  std::ifstream inStream(filename.c_str());
99  if (!inStream.is_open()) {
100  BOOST_ERROR("diff functionality cannot be determined");
101  }
102 
103  // we read in these two values but do not use them
104  int resolInt;
105  inStream >> resolInt;
106  std::string time;
107  inStream >> time;
108 
109  std::vector<double> doubleVec(resolInt);
110  for (int i = 0; i < resolInt; ++i) {
111  inStream >> doubleVec[i];
112  }
113  inStream.close();
114 
115  for (int i = 0; i < resol_->npoints(); ++i) {
116  BOOST_CHECK_CLOSE((dx.getField())[i],
117  doubleVec[i] - (doubleVec[i] + (doubleVec[i] * fact)),
118  1.0e-6);
119  }
120  }
121 // -----------------------------------------------------------------------------
122  BOOST_AUTO_TEST_CASE(test_incrementL95_zero) {
123  util::DateTime tt(file_->getString("date"));
124  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
125  dx.read(*file_);
126 
127  // first check that we have good data, ie, at least one element is non-zero
128  bool goodData = false;
129  for (int i = 0; i < resol_->npoints() && goodData == false; ++i) {
130  if ((dx.getField())[i] != 0) {
131  goodData = true;
132  }
133  }
134 
135  if (!goodData) {
136  BOOST_ERROR("unable to test zero method, since test data is already all zero");
137  } else {
138  dx.zero();
139 
140  for (int i = 0; i < resol_->npoints(); ++i) {
141  BOOST_CHECK_EQUAL(dx.getField()[i], 0);
142  }
143  }
144  }
145 // -----------------------------------------------------------------------------
146  BOOST_AUTO_TEST_CASE(test_incrementL95_zero_set_datetime) {
147  util::DateTime tt(file_->getString("date"));
148  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
149  dx.read(*file_);
150 
151  // first check that we have good data, ie, at least one element is non-zero
152  bool goodData = false;
153  for (int i = 0; i < resol_->npoints() && goodData == false; ++i) {
154  if (dx.getField()[i] != 0) {
155  goodData = true;
156  }
157  }
158 
159  if (!goodData) {
160  BOOST_ERROR("unable to test zero method, since test data is already all zero");
161  } else {
162  const std::string modified_date_string("2010-01-01T10:35:00Z");
163  const util::DateTime dtModified(modified_date_string);
164  dx.zero(dtModified);
165 
166  for (int i = 0; i < resol_->npoints(); ++i) {
167  BOOST_CHECK_EQUAL(dx.getField()[i], 0);
168  }
169 
170  BOOST_CHECK(dx.validTime().toString() != date_str_);
171  }
172  }
173 // -----------------------------------------------------------------------------
174  BOOST_AUTO_TEST_CASE(test_incrementL95_assignment) {
175  util::DateTime tt(file_->getString("date"));
176  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
177  dx1.read(*file_);
178 
179  // construct the second dx object
180  lorenz95::IncrementL95 dx2(*resol_, *vars_, tt);
181  double fact = 0.75;
182  dx2.read(*file_);
183  dx2 *= fact;
184 
185  dx1 = dx2;
186 
187  for (int i = 0; i < dx1.getField().resol(); ++i) {
188  BOOST_CHECK_EQUAL(dx1.getField()[i], dx2.getField()[i]);
189  }
190  }
191 // -----------------------------------------------------------------------------
192  BOOST_AUTO_TEST_CASE(test_incrementL95_compound_assignment_add) {
193  util::DateTime tt(file_->getString("date"));
194  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
195  dx1.read(*file_);
196 
197  // copy construct the second stateL95 object
198  lorenz95::IncrementL95 dx2(dx1);
199 
200  dx1 += dx2;
201 
202  // since the two IncrementL95 objects started off with the same data,
203  // once they've been added together incL591 will be double what incL952 is
204  for (int i = 0; i < dx1.getField().resol(); ++i) {
205  BOOST_CHECK_EQUAL(dx1.getField()[i], 2.0 * dx2.getField()[i]);
206  }
207  }
208 // -----------------------------------------------------------------------------
209  BOOST_AUTO_TEST_CASE(test_incrementL95_compound_assignment_subtract) {
210  util::DateTime tt(file_->getString("date"));
211  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
212  dx1.read(*file_);
213 
214  // copy construct the second stateL95 object
215  lorenz95::IncrementL95 dx2(dx1);
216 
217  dx1 -= dx2;
218 
219  // since the two IncrementL95 objects started off with the same data,
220  // once incL952 has been subtracted from incL951, the result is zero
221  for (int i = 0; i < dx1.getField().resol(); ++i) {
222  BOOST_CHECK_EQUAL(dx1.getField()[i], 0.0);
223  }
224  }
225 // -----------------------------------------------------------------------------
226  BOOST_AUTO_TEST_CASE(test_incrementL95_compound_assignment_multiply) {
227  util::DateTime tt(file_->getString("date"));
228  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
229  dx.read(*file_);
230 
231  // create a copy of the original data for testing against
232  std::vector<double> testData(dx.getField().resol());
233  for (unsigned int ii = 0; ii < testData.size(); ++ii) {
234  testData.at(ii) = dx.getField()[ii];
235  }
236 
237  double fact = 0.75;
238  dx *= fact;
239 
240  for (int ii = 0; ii < dx.getField().resol(); ++ii) {
241  BOOST_CHECK_EQUAL(dx.getField()[ii], testData.at(ii) * fact);
242  }
243  }
244 // -----------------------------------------------------------------------------
245  BOOST_AUTO_TEST_CASE(test_incrementL95_axpy) {
246  util::DateTime tt(file_->getString("date"));
247  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
248  dx1.read(*file_);
249 
250  // copy construct the second stateL95 object
251  lorenz95::IncrementL95 dx2(dx1);
252 
253  double fact = 0.75;
254  dx1.axpy(fact, dx2);
255 
256  for (int i = 0; i < dx1.getField().resol(); ++i) {
257  BOOST_CHECK_EQUAL(dx1.getField()[i], dx2.getField()[i] + fact * dx2.getField()[i]);
258  }
259  }
260 // -----------------------------------------------------------------------------
261  BOOST_AUTO_TEST_CASE(test_incrementL95_dot_product_with) {
262  util::DateTime tt(file_->getString("date"));
263  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
264  dx1.read(*file_);
265 
266  // copy construct the second stateL95 object
267  lorenz95::IncrementL95 dx2(dx1);
268 
269  double dpwResult = dx1.dot_product_with(dx2);
270 
271  // prepare a value to test against
272  double testResult = 0.0;
273  for (int i = 0; i < dx1.getField().resol(); ++i) {
274  testResult += (dx1.getField()[i] * dx2.getField()[i]);
275  }
276 
277  BOOST_CHECK_EQUAL(dpwResult, testResult);
278  }
279 // -----------------------------------------------------------------------------
280  BOOST_AUTO_TEST_CASE(test_incrementL95_schur_product_with) {
281  util::DateTime tt(file_->getString("date"));
282  lorenz95::IncrementL95 dx1(*resol_, *vars_, tt);
283  dx1.read(*file_);
284 
285  // copy construct the second stateL95 object
286  lorenz95::IncrementL95 dx2(dx1);
287 
288  dx1.schur_product_with(dx2);
289 
290  // both incL951 and incL952 started off with the same data in x_,
291  // so to test incL951 against incL952xincL952 is a valid test
292  for (int i = 0; i < dx1.getField().resol(); ++i) {
293  BOOST_CHECK_EQUAL(dx1.getField()[i], dx2.getField()[i] * dx2.getField()[i]);
294  }
295  }
296 // -----------------------------------------------------------------------------
297  BOOST_AUTO_TEST_CASE(test_incrementL95_read) {
298  util::DateTime tt(file_->getString("date"));
299  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
300  dx.read(*file_);
301 
302  // to verify the information has been read correctly, we need to open
303  // and read the file using ifstream functionality
304  const std::string filename(file_->getString("filename"));
305  std::ifstream inStream(filename.c_str());
306  if (!inStream.is_open()) {
307  BOOST_ERROR("read functionality cannot be determined");
308  }
309 
310  int resolInt;
311  inStream >> resolInt;
312 
313  std::string time;
314  inStream >> time;
315 
316  std::vector<double> doubleVec(resolInt);
317  for (int i = 0; i < resolInt; ++i) {
318  inStream >> doubleVec[i];
319  }
320  inStream.close();
321 
322  for (int i = 0; i < resol_->npoints(); ++i) {
323  BOOST_CHECK_EQUAL(dx.getField()[i], doubleVec[i]);
324  }
325  }
326 // -----------------------------------------------------------------------------
327  BOOST_AUTO_TEST_CASE(test_incrementL95_write) {
328  util::DateTime tt(file_->getString("date"));
329  lorenz95::IncrementL95 dx(*resol_, *vars_, tt);
330  dx.read(*file_);
331 
332  eckit::LocalConfiguration opFileCfg(TestConfig::config(), "outputFile");
333  dx.write(opFileCfg);
334 
335  // Should read back in and compare values
336  }
337 // -----------------------------------------------------------------------------
338  BOOST_AUTO_TEST_CASE(test_incrementL95_validTime) {
339  lorenz95::IncrementL95 dx(*resol_, *vars_, *time_);
340  BOOST_CHECK_EQUAL(dx.validTime().toString(), date_str_);
341  }
342 // -----------------------------------------------------------------------------
343 /*
344  BOOST_AUTO_TEST_CASE(test_incrementL95_stream_output) {
345  lorenz95::IncrementL95 dx(*resol_, *vars_, *time_);
346 
347  // use the operator<< method to write the value to a file
348  std::filebuf fb;
349  std::string filename("IncrementL95Test.txt");
350  fb.open(filename.c_str(), std::ios::out);
351  std::ostream os(&fb);
352  os << dx;
353  fb.close();
354 
355  // then read the value that was written to the file
356  std::string input;
357  std::string inputTest(" Valid time: " + date_str_);
358  std::ifstream inputFile(filename.c_str());
359  if (inputFile.is_open()) {
360  getline(inputFile, input); // ignore the first (blank) line
361  getline(inputFile, input);
362 
363  BOOST_CHECK_EQUAL(input, inputTest);
364  } else {
365  // if we can't open the file then we can't
366  // verify that the value was correctly written
367  BOOST_ERROR("operator<< functionality cannot be determined");
368  }
369  inputFile.close();
370  }
371 */
372 // -----------------------------------------------------------------------------
373  BOOST_AUTO_TEST_CASE(test_incrementL95_getField) {
374  lorenz95::IncrementL95 dx(*resol_, *vars_, *time_);
375 
376  // there are 2 values in FieldL95: the 1st is the *resol_ value,
377  // the 2nd is a vector of doubles initialised to 0.0, the size of the
378  // vector is the *resol_ value (we're just checking the final one)
379  BOOST_CHECK_EQUAL(dx.getField().resol(), resol_->npoints());
380  }
381 // -----------------------------------------------------------------------------
382 
383 BOOST_AUTO_TEST_SUITE_END()
384 } // namespace test
l_size ! loop over number of fields ke do je do i
Increment Class: Difference between two states.
Definition: IncrementL95.h:51
boost::scoped_ptr< const eckit::LocalConfiguration > file_
boost::scoped_ptr< lorenz95::Resolution > resol_
*f90 *************************************************************************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:! ***********************************************************************! this routine is used to retrieve scalar boundary data for symmetric domain. subroutine MPP_GET_BOUNDARY_2D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffer, flags, &position, complete, tile_count) type(domain2D), intent(in) ::domain MPP_TYPE_, intent(in) ::field(:,:) MPP_TYPE_, intent(inout), optional ::ebuffer(:), sbuffer(:), wbuffer(:), nbuffer(:) integer, intent(in), optional ::flags, position, tile_count logical, intent(in), optional ::complete MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_, allocatable, dimension(:,:) ::ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D integer ::xcount, ycount integer ::ntile logical ::need_ebuffer, need_sbuffer, need_wbuffer, need_nbuffer integer(LONG_KIND), dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save ::f_addrs=-9999 integer(LONG_KIND), dimension(4, MAX_DOMAIN_FIELDS, MAX_TILES), save ::b_addrs=-9999 integer, save ::bsize(4)=0, isize=0, jsize=0, ksize=0, pos, list=0, l_size=0, upflags integer ::buffer_size(4) integer ::max_ntile, tile, update_position, ishift, jshift logical ::do_update, is_complete, set_mismatch character(len=3) ::text MPP_TYPE_ ::d_type type(overlapSpec), pointer ::bound=> NULL() ntile
boost::scoped_ptr< oops::Variables > vars_
Handles resolution.
Definition: Resolution.h:25
real(fp), parameter, public e
const FieldL95 & getField() const
Access to data.
Definition: IncrementL95.h:97
boost::scoped_ptr< util::DateTime > time_
const int & resol() const
Set and get.
Definition: FieldL95.h:66
BOOST_AUTO_TEST_CASE(test_GomL95_constructor)
void read(const eckit::Configuration &)
Utilities.
static const eckit::Configuration & config()
Definition: TestConfig.h:30
L95 model state.
Definition: StateL95.h:50
void read(const eckit::Configuration &)
Utilities.
const util::DateTime & validTime() const
Definition: IncrementL95.h:92