12 #ifndef TEST_INTERFACE_INCREMENT_H_
13 #define TEST_INTERFACE_INCREMENT_H_
21 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
23 #include <boost/noncopyable.hpp>
25 #include "eckit/config/LocalConfiguration.h"
26 #include "eckit/testing/Test.h"
33 #include "oops/util/DateTime.h"
34 #include "oops/util/dot_product.h"
35 #include "oops/util/Logger.h"
62 return theIncrementFixture;
72 const double tol_default = 1e-8;
74 time_.reset(
new util::DateTime(
test_->getString(
"date")));
77 oops::Log::warning() <<
78 "Warning: Increment norm tolerance greater than 1e-8 "
79 "may not be suitable for certain solvers." <<
83 ~IncrementFixture<MODEL>() {}
87 std::unique_ptr<const eckit::LocalConfiguration>
test_;
89 std::unique_ptr<util::DateTime>
time_;
100 Increment_ dx(Test_::resol(), Test_::ctlvars(),
Test_::time());
103 EXPECT(dx.norm() == 0.0);
112 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
114 oops::Log::test() <<
"Printing random increment: " << dx1 << std::endl;
116 EXPECT(dx1.norm() > 0.0);
119 EXPECT(dx2.norm() > 0.0);
123 EXPECT(dx2.norm() == 0.0);
132 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
134 EXPECT(dx1.norm() > 0.0);
137 Increment_ dx2(dx1,
true);
138 EXPECT(dx2.norm() == dx1.norm());
141 Increment_ dx3(dx1,
false);
142 EXPECT(dx3.norm() == 0.0);
152 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
153 Increment_ dx2(Test_::resol(), dx1);
156 EXPECT(dx2.norm() == dx1.norm());
165 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
167 Increment_ dx2(Test_::resol(), Test_::ctlvars(),
Test_::time());
171 double dot1 = dx1.norm();
174 double dot2 = dx2.norm();
178 double dot3 = dx2.norm();
181 EXPECT(dot3 <= dot1 + dot2);
190 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
199 EXPECT(dx2.norm() < Test_::tolerance());
208 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
210 Increment_ dx2(Test_::resol(), Test_::ctlvars(),
Test_::time());
214 double zz1 = dot_product(dx1, dx2);
215 double zz2 = dot_product(dx2, dx1);
226 Increment_ dx(Test_::resol(), Test_::ctlvars(),
Test_::time());
228 EXPECT(dx.norm() > 0.0);
232 EXPECT(dx.norm() == 0.0);
236 util::Duration onehour(3600);
243 EXPECT(dx.norm() == 0.0);
244 EXPECT(dx.validTime() == newTime);
253 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
264 EXPECT(dx2.norm() < Test_::tolerance());
275 bool skipTest =
Test_::test().getBool(
"skip accum test",
false);
277 oops::Log::warning() <<
"Skipping Increment.accum test";
282 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
285 Increment_ dx2(Test_::resol(), Test_::ctlvars(),
Test_::time());
288 Increment_ diff(dx1);
290 EXPECT(diff.norm() != 0.0);
293 State_ x(Test_::resol(), Test_::ctlvars(),
Test_::time());
309 EXPECT(diff.norm() != 0.0);
314 EXPECT(diff.norm() == 0.0);
324 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
327 util::DateTime tt(
Test_::time() + util::Duration(
"PT15H"));
328 Increment_ dx2(Test_::resol(), Test_::ctlvars(), tt);
331 std::vector<double> vect;
333 EXPECT(vect.size() == dx1.serialSize());
336 dx2.deserialize(vect, index);
337 EXPECT(index == dx1.serialSize());
338 EXPECT(index == dx2.serialSize());
341 EXPECT(vect.size() == dx1.serialSize() * 2);
343 if (dx1.serialSize() > 0) {
344 EXPECT(dx1.norm() > 0.0);
345 EXPECT(dx2.norm() > 0.0);
349 EXPECT(dx2.norm() == 0.0);
361 bool skipTest =
Test_::test().getBool(
"skip diff test",
false);
363 oops::Log::warning() <<
"Skipping Increment.diff test";
368 State_ x1(Test_::resol(), Test_::ctlvars(),
Test_::time());
369 State_ x2(Test_::resol(), Test_::ctlvars(),
Test_::time());
372 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
375 Increment_ dx2(Test_::resol(), Test_::ctlvars(),
Test_::time());
379 Increment_ diff1(dx1);
380 Increment_ diff2(Test_::resol(), Test_::ctlvars(),
Test_::time());
382 EXPECT(diff1.norm() != 0.0);
394 EXPECT(diff1.norm() == diff2.norm());
404 Increment_ dx(Test_::resol(), Test_::ctlvars(),
Test_::time());
407 util::Duration onehour(3600);
408 dx.updateTime(onehour);
413 EXPECT(dx.validTime() == newTime);
423 Increment_ dx1(Test_::resol(), Test_::ctlvars(),
Test_::time());
426 EXPECT(dx1.norm() == dx2.norm());
429 dx1.schur_product_with(dx2);
432 EXPECT(dx1.norm() != dx2.norm());
437 dx1.schur_product_with(dx2);
438 EXPECT(dx1.norm() == 0.0);
442 Increment_ dx1in(dx1);
444 dx1.schur_product_with(dx2);
445 EXPECT(dx1.norm() == dx1in.norm());
450 template <
typename MODEL>
460 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
462 ts.emplace_back(
CASE(
"interface/Increment/testIncrementConstructor")
463 { testIncrementConstructor<MODEL>(); });
464 ts.emplace_back(
CASE(
"interface/Increment/testIncrementCopyConstructor")
465 { testIncrementCopyConstructor<MODEL>(); });
466 ts.emplace_back(
CASE(
"interface/Increment/testIncrementCopyBoolConstructor")
467 { testIncrementCopyBoolConstructor<MODEL>(); });
468 ts.emplace_back(
CASE(
"interface/Increment/testIncrementChangeResConstructor")
469 { testIncrementChangeResConstructor<MODEL>(); });
470 ts.emplace_back(
CASE(
"interface/Increment/testIncrementTriangle")
471 { testIncrementTriangle<MODEL>(); });
472 ts.emplace_back(
CASE(
"interface/Increment/testIncrementOpPlusEq")
473 { testIncrementOpPlusEq<MODEL>(); });
474 ts.emplace_back(
CASE(
"interface/Increment/testIncrementDotProduct")
475 { testIncrementDotProduct<MODEL>(); });
476 ts.emplace_back(
CASE(
"interface/Increment/testIncrementAxpy")
477 { testIncrementAxpy<MODEL>(); });
478 ts.emplace_back(
CASE(
"interface/Increment/testIncrementAccum")
479 { testIncrementAccum<MODEL>(); });
480 ts.emplace_back(
CASE(
"interface/Increment/testIncrementDiff")
481 { testIncrementDiff<MODEL>(); });
482 ts.emplace_back(
CASE(
"interface/Increment/testIncrementZero")
483 { testIncrementZero<MODEL>(); });
484 ts.emplace_back(
CASE(
"interface/Increment/testIncrementTime")
485 { testIncrementTime<MODEL>(); });
486 ts.emplace_back(
CASE(
"interface/Increment/testIncrementSchur")
487 { testIncrementSchur<MODEL>(); });
488 ts.emplace_back(
CASE(
"interface/Increment/testIncrementSerialize")
489 { testIncrementSerialize<MODEL>(); });
Geometry class used in oops; subclass of interface class interface::Geometry.
Increment class used in oops.
State class used in oops; subclass of interface class interface::State.
std::unique_ptr< bool > skipAccumTest_
static const eckit::Configuration & test()
static const double & tolerance()
static IncrementFixture< MODEL > & getInstance()
std::unique_ptr< const eckit::LocalConfiguration > test_
static const Geometry_ & resol()
std::unique_ptr< Geometry_ > resol_
std::unique_ptr< bool > skipDiffTest_
static const oops::Variables & ctlvars()
static const util::DateTime & time()
std::unique_ptr< oops::Variables > ctlvars_
std::unique_ptr< util::DateTime > time_
oops::Geometry< MODEL > Geometry_
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)
void testIncrementCopyBoolConstructor()
void testIncrementChangeResConstructor()
void testIncrementSchur()
void testIncrementSerialize()
void testIncrementCopyConstructor()
void testIncrementTriangle()
void testIncrementAccum()
void testIncrementOpPlusEq()
void testIncrementDotProduct()
void testIncrementConstructor()
tests Increment constructor and print method
CASE("assimilation/FullGMRES/FullGMRES")