FV3 Bundle
test/interface/ModelAuxIncrement.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 TEST_INTERFACE_MODELAUXINCREMENT_H_
12 #define TEST_INTERFACE_MODELAUXINCREMENT_H_
13 
14 #include <cmath>
15 #include <iostream>
16 #include <string>
17 
18 #define BOOST_TEST_NO_MAIN
19 #define BOOST_TEST_ALTERNATIVE_INIT_API
20 #define BOOST_TEST_DYN_LINK
21 
22 #include <boost/test/unit_test.hpp>
23 
24 #include <boost/noncopyable.hpp>
25 #include <boost/scoped_ptr.hpp>
26 
27 #include "eckit/config/LocalConfiguration.h"
32 #include "oops/runs/Test.h"
33 #include "oops/util/DateTime.h"
34 #include "oops/util/dot_product.h"
35 #include "test/TestEnvironment.h"
36 
37 namespace test {
38 
39 // =============================================================================
40 
41 template <typename MODEL> class ModelAuxIncrementFixture : private boost::noncopyable {
46 
47  public:
48  static const eckit::Configuration & config() {return *getInstance().conf_;}
49  static const Covariance_ & covariance() {return *getInstance().covar_;}
50  static const Geometry_ & resol() {return *getInstance().resol_;}
51 
52  private:
54  static ModelAuxIncrementFixture<MODEL> theModelAuxIncrementFixture;
55  return theModelAuxIncrementFixture;
56  }
57 
59 // Setup a geometry
60  const eckit::LocalConfiguration resolConfig(TestEnvironment::config(), "Geometry");
61  resol_.reset(new Geometry_(resolConfig));
62 
63 // Setup a covariance matrix
64  conf_.reset(new eckit::LocalConfiguration(TestEnvironment::config(), "ModelBiasCovariance"));
65  covar_.reset(new Covariance_(*conf_, *resol_));
66  }
67 
69 
70  boost::scoped_ptr<const eckit::LocalConfiguration> conf_;
71  boost::scoped_ptr<const Geometry_> resol_;
72  boost::scoped_ptr<const Covariance_> covar_;
73 };
74 
75 // =============================================================================
76 
77 template <typename MODEL> void testModelAuxIncrementConstructor() {
78  typedef ModelAuxIncrementFixture<MODEL> Test_;
79  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
80 
81  AuxIncr_ dx(Test_::resol(), Test_::config());
82 
83  BOOST_CHECK_EQUAL(dx.norm(), 0.0);
84 }
85 
86 // -----------------------------------------------------------------------------
87 
88 template <typename MODEL> void testModelAuxIncrementCopyConstructor() {
89  typedef ModelAuxIncrementFixture<MODEL> Test_;
90  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
91 
92  AuxIncr_ dx1(Test_::resol(), Test_::config());
94 
95  AuxIncr_ dx2(dx1);
96  BOOST_CHECK(dx2.norm() > 0.0);
97  BOOST_CHECK_EQUAL(dx2.norm(), dx1.norm());
98 
99 // Check that the copy is equal to the original
100  dx2 -= dx1;
101  BOOST_CHECK_EQUAL(dx2.norm(), 0.0);
102 }
103 
104 // -----------------------------------------------------------------------------
105 
106 template <typename MODEL> void testModelAuxIncrementChangeRes() {
107  typedef ModelAuxIncrementFixture<MODEL> Test_;
108  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
109 
110  AuxIncr_ dx1(Test_::resol(), Test_::config());
112 
113  AuxIncr_ dx2(dx1, Test_::config());
114  BOOST_CHECK(dx2.norm() > 0.0);
115  BOOST_CHECK_EQUAL(dx2.norm(), dx1.norm());
116 
117 // Check that the copy is equal to the original
118  dx2 -= dx1;
119  BOOST_CHECK_EQUAL(dx2.norm(), 0.0);
120 }
121 
122 // -----------------------------------------------------------------------------
123 
124 template <typename MODEL> void testModelAuxIncrementTriangle() {
125  typedef ModelAuxIncrementFixture<MODEL> Test_;
126  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
127 
128  AuxIncr_ dx1(Test_::resol(), Test_::config());
130  AuxIncr_ dx2(Test_::resol(), Test_::config());
132 
133 // test triangle inequality
134  double dot1 = dx1.norm();
135  BOOST_CHECK(dot1 > 0.0);
136 
137  double dot2 = dx2.norm();
138  BOOST_CHECK(dot2 > 0.0);
139 
140  dx2 += dx1;
141  double dot3 = dx2.norm();
142  BOOST_CHECK(dot3 > 0.0);
143 
144  BOOST_CHECK(dot3 <= dot1 + dot2);
145 }
146 
147 // -----------------------------------------------------------------------------
148 
149 template <typename MODEL> void testModelAuxIncrementOpPlusEq() {
150  typedef ModelAuxIncrementFixture<MODEL> Test_;
151  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
152 
153  AuxIncr_ dx1(Test_::resol(), Test_::config());
155  AuxIncr_ dx2(dx1);
156 
157 // test *= and +=
158  dx2 += dx1;
159  dx1 *= 2.0;
160 
161  dx2 -= dx1;
162  BOOST_CHECK_SMALL(dx2.norm(), 1e-8);
163 }
164 
165 // -----------------------------------------------------------------------------
166 
167 template <typename MODEL> void testModelAuxIncrementDotProduct() {
168  typedef ModelAuxIncrementFixture<MODEL> Test_;
169  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
170 
171  AuxIncr_ dx1(Test_::resol(), Test_::config());
173  AuxIncr_ dx2(Test_::resol(), Test_::config());
175 
176 // test symmetry of dot product
177  double zz1 = dot_product(dx1, dx2);
178  double zz2 = dot_product(dx2, dx1);
179 
180  BOOST_CHECK_EQUAL(zz1, zz2);
181 }
182 
183 // -----------------------------------------------------------------------------
184 
185 template <typename MODEL> void testModelAuxIncrementZero() {
186  typedef ModelAuxIncrementFixture<MODEL> Test_;
187  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
188 
189  AuxIncr_ dx(Test_::resol(), Test_::config());
191  BOOST_CHECK(dx.norm() > 0.0);
192 
193 // test zero
194  dx->zero();
195  BOOST_CHECK_EQUAL(dx.norm(), 0.0);
196 }
197 
198 // -----------------------------------------------------------------------------
199 
200 template <typename MODEL> void testModelAuxIncrementAxpy() {
201  typedef ModelAuxIncrementFixture<MODEL> Test_;
202  typedef oops::ModelAuxIncrement<MODEL> AuxIncr_;
203 
204  AuxIncr_ dx1(Test_::resol(), Test_::config());
206 
207 // test axpy
208  AuxIncr_ dx2(dx1);
209  dx2.axpy(2.0, dx1);
210 
211  dx2 -= dx1;
212  dx2 -= dx1;
213  dx2 -= dx1;
214 
215  BOOST_CHECK_SMALL(dx2.norm(), 1e-8);
216 }
217 
218 // =============================================================================
219 
220 template <typename MODEL> class ModelAuxIncrement : public oops::Test {
221  public:
223  virtual ~ModelAuxIncrement() {}
224  private:
225  std::string testid() const {return "test::ModelAuxIncrement<" + MODEL::name() + ">";}
226 
227  void register_tests() const {
228  boost::unit_test::test_suite * ts = BOOST_TEST_SUITE("interface/ModelAuxIncrement");
229 
230  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementConstructor<MODEL>));
231  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementCopyConstructor<MODEL>));
232  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementChangeRes<MODEL>));
233  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementTriangle<MODEL>));
234  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementOpPlusEq<MODEL>));
235  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementDotProduct<MODEL>));
236  ts->add(BOOST_TEST_CASE(&testModelAuxIncrementAxpy<MODEL>));
237 
238  boost::unit_test::framework::master_test_suite().add(ts);
239  }
240 };
241 
242 // =============================================================================
243 
244 } // namespace test
245 
246 #endif // TEST_INTERFACE_MODELAUXINCREMENT_H_
void testModelAuxIncrementCopyConstructor()
boost::scoped_ptr< const Covariance_ > covar_
oops::ModelAuxIncrement< MODEL > AuxIncr_
void randomize(ModelAuxIncrement_ &) const
static const eckit::Configuration & config()
boost::scoped_ptr< const eckit::LocalConfiguration > conf_
character(len=32) name
oops::ModelAuxCovariance< MODEL > Covariance_
real(fp), parameter, public e
void testModelAuxIncrementDotProduct()
static const eckit::Configuration & config()
void testModelAuxIncrementConstructor()
oops::ModelAuxControl< MODEL > ModelAux_
boost::scoped_ptr< const Geometry_ > resol_
static ModelAuxIncrementFixture< MODEL > & getInstance()