11 #ifndef TEST_INTERFACE_STATE_H_
12 #define TEST_INTERFACE_STATE_H_
20 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
22 #include <boost/noncopyable.hpp>
24 #include "eckit/config/LocalConfiguration.h"
25 #include "eckit/testing/Test.h"
31 #include "oops/util/DateTime.h"
32 #include "oops/util/dot_product.h"
33 #include "oops/util/Logger.h"
40 template <
typename MODEL>
class StateFixture :
private boost::noncopyable {
55 return theStateFixture;
65 ~StateFixture<MODEL>() {}
67 std::unique_ptr<const eckit::LocalConfiguration>
test_;
77 const double norm =
Test_::test().getDouble(
"norm file");
78 const double tol =
Test_::test().getDouble(
"tolerance");
79 const util::DateTime vt(
Test_::test().getString(
"date"));
82 const eckit::LocalConfiguration conf(
Test_::test(),
"statefile");
83 std::unique_ptr<State_> xx1(
new State_(Test_::resol(), conf));
87 const double norm1 = xx1->norm();
88 EXPECT(oops::is_close(norm1, norm, tol));
89 EXPECT(xx1->validTime() == vt);
92 std::unique_ptr<State_> xx2(
new State_(*xx1));
94 EXPECT(oops::is_close(xx2->norm(), norm, tol));
95 EXPECT(xx2->validTime() == vt);
102 const double norm2 = xx1->norm();
103 EXPECT(norm1 == norm2);
107 State_ xx3(Test_::resol(), vars, vt);
109 EXPECT(xx3.norm() == 0);
110 EXPECT(xx3.validTime() == vt);
111 EXPECT(xx3.variables() == vars);
114 State_ xx4(Test_::resol(), *xx1);
115 EXPECT(oops::is_close(xx4.norm(), norm, tol));
116 EXPECT(xx4.validTime() == vt);
117 EXPECT(xx4.variables() == xx1->variables());
129 const double norm =
Test_::test().getDouble(
"norm file");
130 const double tol =
Test_::test().getDouble(
"tolerance");
131 const util::DateTime vt(
Test_::test().getString(
"date"));
133 const eckit::LocalConfiguration conf(
Test_::test(),
"statefile");
134 State_ xx1(Test_::resol(), conf);
137 const Geometry_ & geometry = xx1.geometry();
138 State_ xx2(geometry, conf);
140 const double norm2 = xx2.norm();
141 EXPECT(oops::is_close(norm2, norm, tol));
175 oops::Log::warning() <<
"Bypassing Analytical Initial Condition Test";
179 const eckit::LocalConfiguration confgen(
Test_::test(),
"state generate");
180 const State_ xx(Test_::resol(), confgen);
182 const double norm =
Test_::test().getDouble(
"norm generated state");
183 const double tol =
Test_::test().getDouble(
"tolerance");
185 oops::Log::debug() <<
"xx.norm(): " << std::fixed << std::setprecision(8) << xx.norm()
187 oops::Log::debug() <<
"norm: " << std::fixed << std::setprecision(8) << norm << std::endl;
189 EXPECT(oops::is_close(xx.norm(), norm, tol));
208 const eckit::LocalConfiguration conf(
Test_::test(),
"statefile");
209 State_ xx(Test_::resol(), conf);
210 const double tol =
Test_::test().getDouble(
"tolerance");
214 EXPECT(xx.norm() == 0.0);
217 const State_ yy(Test_::resol(), conf);
218 const std::vector<double> mults {3.0, 0.0, -3.0};
219 for (
const auto & mult : mults) {
221 xx.accumul(mult, yy);
222 EXPECT(oops::is_close(xx.norm(), std::abs(mult) * yy.norm(), tol));
226 State_ zz(Test_::resol(), conf);
228 EXPECT_NOT(oops::is_close(zz.norm(), yy.norm(), tol, 0, oops::TestVerbosity::SILENT));
247 const eckit::LocalConfiguration conf(
Test_::test(),
"statefile");
248 State_ xx(Test_::resol(), conf);
251 const util::Duration onehour(3600);
252 xx.updateTime(onehour);
253 xx.updateTime(onehour);
256 State_ yy(Test_::resol(), conf);
259 const util::Duration twohours(7200);
260 yy.updateTime(twohours);
262 EXPECT(xx.validTime() == yy.validTime());
265 xx.updateTime(onehour);
266 EXPECT_NOT(xx.validTime() == yy.validTime());
285 const eckit::LocalConfiguration conf(
Test_::test(),
"statefile");
286 State_ xx(Test_::resol(), conf);
287 const double tol =
Test_::test().getDouble(
"tolerance");
290 const double norm = xx.norm();
299 EXPECT(xx.norm() == norm);
303 const double mult = 2.0;
304 xx.accumul(mult, xx);
307 const double normout = xx.norm();
310 const eckit::LocalConfiguration confout(
Test_::test(),
"statefileout");
316 State_ yy(Test_::resol(), confout);
319 EXPECT(oops::is_close(yy.norm(), normout, tol));
322 EXPECT_NOT(oops::is_close(norm, normout, tol, 0, oops::TestVerbosity::SILENT));
328 template <
typename MODEL>
338 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
340 ts.emplace_back(
CASE(
"interface/State/testStateConstructors")
341 { testStateConstructors<MODEL>(); });
342 ts.emplace_back(
CASE(
"interface/State/testStateGeometry")
343 { testStateGeometry<MODEL>(); });
344 ts.emplace_back(
CASE(
"interface/State/testStateAnalyticInitialCondition")
345 { testStateAnalyticInitialCondition<MODEL>(); });
346 ts.emplace_back(
CASE(
"interface/State/testStateZeroAndAccumul")
347 { testStateZeroAndAccumul<MODEL>(); });
348 ts.emplace_back(
CASE(
"interface/State/testStateDateTime")
349 { testStateDateTime<MODEL>(); });
350 ts.emplace_back(
CASE(
"interface/State/testStateReadWrite")
351 { testStateReadWrite<MODEL>(); });
Geometry class used in oops; subclass of interface class interface::Geometry.
State class used in oops; subclass of interface class interface::State.
static StateFixture< MODEL > & getInstance()
oops::State< MODEL > State_
static const eckit::Configuration & test()
static const Geometry_ & resol()
oops::Geometry< MODEL > Geometry_
std::unique_ptr< Geometry_ > resol_
std::unique_ptr< const eckit::LocalConfiguration > test_
std::string testid() const override
void clear() const override
void register_tests() const override
static const eckit::Configuration & config()
const eckit::mpi::Comm & world()
Default communicator with all MPI tasks (ie MPI_COMM_WORLD)
logical function has(this, var)
void testStateReadWrite()
Read and write tests.
void testStateDateTime()
validTime and updateTime tests
void testStateZeroAndAccumul()
Tests of zero and accumul.
void testStateGeometry()
Tests State::geometry() and Geometry copy constructors.
void testStateConstructors()
tests constructors and print method
CASE("assimilation/FullGMRES/FullGMRES")
void testStateAnalyticInitialCondition()
Interpolation test.