8 #ifndef TEST_UFO_GEOVALS_H_
9 #define TEST_UFO_GEOVALS_H_
18 #define ECKIT_TESTING_SELF_REGISTER_CASES 0
20 #include "eckit/config/LocalConfiguration.h"
21 #include "eckit/testing/Test.h"
22 #include "ioda/ObsSpace.h"
23 #include "oops/mpi/mpi.h"
24 #include "oops/runs/Test.h"
25 #include "oops/util/FloatCompare.h"
26 #include "oops/util/Logger.h"
27 #include "test/TestEnvironment.h"
28 #include "ufo/GeoVaLs.h"
29 #include "ufo/Locations.h"
38 const eckit::LocalConfiguration
conf(::test::TestEnvironment::config());
39 util::DateTime bgn(
conf.getString(
"window begin"));
40 util::DateTime end(
conf.getString(
"window end"));
42 std::vector<eckit::LocalConfiguration> confs;
43 conf.get(
"geovals test", confs);
44 for (
size_t jconf = 0; jconf < confs.size(); ++jconf) {
46 const eckit::LocalConfiguration obsconf(confs[jconf],
"obs space");
47 ioda::ObsSpace ospace(obsconf, oops::mpi::world(), bgn, end, oops::mpi::myself());
50 const eckit::LocalConfiguration gconf(confs[jconf],
"geovals");
51 const oops::Variables ingeovars(gconf,
"state variables");
52 const GeoVaLs gval(gconf, ospace, ingeovars);
54 const double tol = gconf.getDouble(
"tolerance");
58 "GeoVaLs default constructor - does not allocate fields" << std::endl;
62 if (gconf.has(
"one location check")) {
63 oops::Log::trace() <<
"Check that GeoVaLs constructor for one location works" << std::endl;
64 const eckit::LocalConfiguration gconfone(gconf,
"one location check");
65 const std::string var = gconfone.getString(
"variable");
66 const std::vector<int> ind = gconfone.getIntVector(
"indices");
67 const std::vector<float> values = gconfone.getFloatVector(
"values");
68 const float oneloctol = gconfone.getFloat(
"tolerance");
71 oops::TestVerbosity verbosity = oops::TestVerbosity::LOG_SUCCESS_AND_FAILURE;
72 for (std::size_t i = 0; i < ind.size(); ++i) {
74 std::vector<float> gv_val(1);
75 gv_one.get(gv_val, var, 1);
76 EXPECT(oops::is_close_absolute(gv_val[0], values[i], oneloctol, verbosity));
79 oops::Log::trace() <<
"Test just the constructor for a one location GeoVaLs" << std::endl;
85 if (gconf.has(
"reorderzdir check")) {
86 const eckit::LocalConfiguration gconfchk(gconf,
"reorderzdir check");
87 const std::string flipto = gconfchk.getString(
"direction");
88 std::string flipback = (flipto ==
"bottom2top") ?
"top2bottom" :
"bottom2top";
89 std::size_t nobs = ospace.nlocs();
90 gv.reorderzdir(
"air_pressure_levels", flipto);
91 std::vector<float> gvar(nobs);
92 std::vector<float> gvarref(nobs);
94 for (
size_t i = 0; i < ingeovars.size(); ++i) {
95 size_t nlevs = gv.nlevs(ingeovars[i]);
97 for (
size_t k = 0; k < nlevs; ++k) {
98 size_t kk = nlevs - k;
99 gv.get(gvar, ingeovars[i], k+1);
100 gval.get(gvarref, ingeovars[i], kk);
101 for (
size_t j = 0; j < nobs; ++j) {
102 gvar[j] = gvar[j] - gvarref[j];
103 sum += sum + gvar[j];
107 gv.reorderzdir(
"air_pressure_levels", flipback);
108 const double tol = gconfchk.getDouble(
"tolerance");
109 EXPECT(
abs(sum) < tol);
113 oops::Log::trace() <<
114 "GeoVaLs merge followed by a split gives back the original geovals" << std::endl;
116 double dp_gval = gval.dot_product_with(gval);
117 oops::Log::debug()<<
"initial gval dot product with itself " << dp_gval << std::endl;
120 gv.merge(gval, gval);
122 double dp_gv_merged = gv.dot_product_with(gv);
123 oops::Log::debug()<<
"gv dot product with itself after merge " << dp_gv_merged << std::endl;
124 EXPECT(
abs(dp_gv_merged - 2.0 * dp_gval)/dp_gv_merged < tol);
126 GeoVaLs gv1(ospace.comm()), gv2(ospace.comm());
129 double dp_gv1_split = gv1.dot_product_with(gv1);
130 double dp_gv2_split = gv2.dot_product_with(gv2);
133 << dp_gv1_split <<
" " << dp_gv2_split << std::endl;
135 EXPECT(gv1.rms() == gv2.rms());
136 EXPECT(gv1.rms() == gval.rms());
137 EXPECT(
abs(dp_gv1_split - dp_gv2_split)/dp_gv1_split < tol);
138 EXPECT(
abs(dp_gv1_split - dp_gval)/dp_gv1_split < tol);
140 oops::Log::trace() <<
141 "GeoVaLs merge followed by a split test succeeded" << std::endl;
144 oops::Log::trace() <<
145 "Check that GeoVaLs & operator *= (const std::vector<float>);" << std::endl;
147 std::size_t nlocs = ospace.nlocs();
149 std::vector<float> tw(nlocs, 1.0f);
151 EXPECT(gv1.rms() == gval.rms());
154 std::vector<float> tw(nlocs, 2.0f);
158 rms2 = 2.0 * gval.rms();
160 EXPECT(rms1 == rms2);
162 oops::Log::trace() <<
163 "GeoVaLs & operator *= (const std::vector<float>); test succeeded" << std::endl;
173 std::string
testid()
const override {
return "ufo::test::GeoVaLs";}
176 std::vector<eckit::testing::Test>& ts = eckit::testing::specification();
178 ts.emplace_back(
CASE(
"ufo/GeoVaLs/testGeoVaLs")
190 #endif // TEST_UFO_GEOVALS_H_