11 #ifndef TEST_INTERFACE_LINEARVARIABLECHANGE_H_ 12 #define TEST_INTERFACE_LINEARVARIABLECHANGE_H_ 19 #define BOOST_TEST_NO_MAIN 20 #define BOOST_TEST_ALTERNATIVE_INIT_API 21 #define BOOST_TEST_DYN_LINK 23 #include <boost/noncopyable.hpp> 24 #include <boost/scoped_ptr.hpp> 25 #include <boost/test/unit_test.hpp> 27 #include "eckit/config/Configuration.h" 35 #include "oops/util/DateTime.h" 36 #include "oops/util/dot_product.h" 37 #include "oops/util/Logger.h" 50 static std::vector<eckit::LocalConfiguration>
59 return theLinearVariableChangeFixture;
63 oops::instantiateLinearVariableChangeFactory<MODEL>();
72 time_.reset(
new util::DateTime(
xx_->validTime()));
80 boost::scoped_ptr<const State_ >
xx_;
81 boost::scoped_ptr<const Geometry_>
resol_;
82 boost::scoped_ptr<const util::DateTime>
time_;
93 for (std::size_t jj = 0; jj < Test_::linvarchgconfs().size(); ++jj) {
94 eckit::LocalConfiguration varinconf(Test_::linvarchgconfs()[jj],
"inputVariables");
95 eckit::LocalConfiguration varoutconf(Test_::linvarchgconfs()[jj],
"outputVariables");
100 Test_::xx(), Test_::xx(),
101 Test_::resol(), Test_::linvarchgconfs()[jj]));
103 Increment_ dxin(Test_::resol(), varin,
Test_::time());
104 Increment_ KTdxin(Test_::resol(), varout,
Test_::time());
105 Increment_ dxout(Test_::resol(), varout,
Test_::time());
106 Increment_ Kdxout(Test_::resol(), varin,
Test_::time());
110 changevar->multiply(dxout, Kdxout);
111 BOOST_CHECK_EQUAL(Kdxout.norm(), 0.0);
115 changevar->multiplyAD(dxin, KTdxin);
116 BOOST_CHECK_EQUAL(KTdxin.norm(), 0.0);
118 const bool testinverse = Test_::linvarchgconfs()[jj].getBool(
"testinverse",
true);
123 changevar->multiply(dxout, Kdxout);
124 BOOST_CHECK_EQUAL(Kdxout.norm(), 0.0);
127 changevar->multiplyAD(dxin, KTdxin);
128 BOOST_CHECK_EQUAL(KTdxin.norm(), 0.0);
142 for (std::size_t jj = 0; jj < Test_::linvarchgconfs().size(); ++jj) {
143 eckit::LocalConfiguration varinconf(Test_::linvarchgconfs()[jj],
"inputVariables");
144 eckit::LocalConfiguration varoutconf(Test_::linvarchgconfs()[jj],
"outputVariables");
149 Test_::xx(), Test_::xx(),
150 Test_::resol(), Test_::linvarchgconfs()[jj]));
152 Increment_ dxin(Test_::resol(), varin,
Test_::time());
153 Increment_ KTdxin(Test_::resol(), varout,
Test_::time());
154 Increment_ dxout(Test_::resol(), varout,
Test_::time());
155 Increment_ Kdxout(Test_::resol(), varin,
Test_::time());
160 Increment_ dxin0(dxin);
161 Increment_ dxout0(dxout);
163 changevar->multiply(dxout, Kdxout);
164 changevar->multiplyAD(dxin, KTdxin);
167 double zz1 = dot_product(Kdxout, dxin0);
169 double zz2 = dot_product(dxout0, KTdxin);
172 << (zz1-zz2)/zz1 << std::endl;
174 << (zz1-zz2)/zz2 << std::endl;
175 const double tol = 1
e-8;
176 BOOST_CHECK_CLOSE(zz1, zz2,
tol);
177 const bool testinverse = Test_::linvarchgconfs()[jj].getBool(
"testinverse",
true);
185 changevar->multiplyInverse(dxout, Kdxout);
186 changevar->multiplyInverseAD(dxin, KTdxin);
187 zz1 = dot_product(Kdxout, dxin0);
188 zz2 = dot_product(dxout0, KTdxin);
189 oops::Log::info() <<
"<dxout,KinvTdxin>-<Kinvdxout,dxin>/<dxout,KinvTdxin>=" 190 << (zz1-zz2)/zz1 << std::endl;
191 oops::Log::info() <<
"<dxout,KinvTdxin>-<Kinvdxout,dxin>/<Kinvdxout,dxin>=" 192 << (zz1-zz2)/zz2 << std::endl;
193 BOOST_CHECK_CLOSE(zz1, zz2,
tol);
195 oops::Log::info() <<
"Not doing adjoint test for inverse" << std::endl;
208 for (std::size_t jj = 0; jj < Test_::linvarchgconfs().size(); ++jj) {
209 eckit::LocalConfiguration varinconf(Test_::linvarchgconfs()[jj],
"inputVariables");
210 eckit::LocalConfiguration varoutconf(Test_::linvarchgconfs()[jj],
"outputVariables");
214 const double tol = Test_::linvarchgconfs()[jj].getDouble(
"toleranceInverse");
216 const bool testinverse = Test_::linvarchgconfs()[jj].getBool(
"testinverse",
false);
221 Test_::xx(), Test_::xx(),
222 Test_::resol(), Test_::linvarchgconfs()[jj]));
224 Increment_ dxin(Test_::resol(), varin,
Test_::time());
225 Increment_ KIdxin(Test_::resol(), varout,
Test_::time());
226 Increment_ KKIdxin(Test_::resol(), varin,
Test_::time());
230 changevar->multiplyInverse(dxin, KIdxin);
231 changevar->multiply(KIdxin, KKIdxin);
233 const double zz1 = dxin.norm();
234 const double zz2 = KKIdxin.norm();
236 oops::Log::info() <<
"<x>, <KK^{-1}x>=" << zz1 <<
" " << zz2 << std::endl;
239 BOOST_CHECK((zz1-zz2) <
tol);
242 BOOST_CHECK(1.0 < 2.0);
257 boost::unit_test::test_suite * ts = BOOST_TEST_SUITE(
"interface/LinearVariableChange");
259 ts->add(BOOST_TEST_CASE(&testLinearVariableChangeZero<MODEL>));
260 ts->add(BOOST_TEST_CASE(&testLinearVariableChangeAdjoint<MODEL>));
261 ts->add(BOOST_TEST_CASE(&testLinearVariableChangeInverse<MODEL>));
263 boost::unit_test::framework::master_test_suite().add(ts);
271 #endif // TEST_INTERFACE_LINEARVARIABLECHANGE_H_ virtual ~LinearVariableChange()
void testLinearVariableChangeInverse()
subroutine, public create(self, c_conf)
Encapsulates the model state.
static const eckit::Configuration & config()
boost::scoped_ptr< const State_ > xx_
static LinearVariableChangeFixture< MODEL > & getInstance()
void testLinearVariableChangeZero()
static const State_ & xx()
real(fp), parameter, public e
oops::Geometry< MODEL > Geometry_
subroutine, public info(self)
static std::vector< eckit::LocalConfiguration > & linvarchgconfs()
void register_tests() const
static const DateTime_ & time()
LinearVariableChangeFactory Factory.
Base class for generic variable transform.
static const Geometry_ & resol()
oops::State< MODEL > State_
boost::scoped_ptr< const Geometry_ > resol_
Increment Class: Difference between two states.
boost::scoped_ptr< const util::DateTime > time_
std::vector< eckit::LocalConfiguration > linvarchgconfs_
void testLinearVariableChangeAdjoint()
std::string testid() const