#include <boost/thread.hpp>
#include <boost/test/unit_test.hpp>
#include <usml/ublas/randgen.h>
#include <usml/netcdf/netcdf_files.h>
#include <usml/ocean/ocean.h>
BOOST_AUTO_TEST_SUITE(profile_lock_test)
using namespace boost::unit_test;
using namespace usml::netcdf;
using namespace usml::ocean;
class tester_base
{
public:
tester_base() :
_lockableProfile(NULL),
_temp(NULL)
{
}
virtual ~tester_base()
{
delete _lockableProfile;
delete _temp;
}
void random_wait()
{
double seed = randgen::uniform();
if (seed < 0.1) seed = 0.1;
int msec = seed * 1000;
if (msec > 1000 ) msec = 1000;
boost::this_thread::sleep(boost::posix_time::milliseconds(msec));
}
void run()
{
for (int i = 0; i < 5; ++i)
{
random_wait();
test();
std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl;
}
}
virtual void test() = 0;
protected:
usml::ocean::profile_lock* _lockableProfile;
usml::netcdf::netcdf_woa* _temp;
};
class linear_tester : public tester_base
{
public:
void setup()
{
attenuation_model* attn = new attenuation_constant(5.0);
profile_linear* model = new profile_linear();
model->attenuation(attn);
_lockableProfile = new profile_lock(model);
}
void test()
{
wposition points(1, 1);
matrix<double> speed(1, 1);
wvector gradient(1, 1);
_lockableProfile->sound_speed(points, &speed, &gradient);
BOOST_CHECK_CLOSE(speed(0, 0), 1500.0, 1e-6);
seq_linear freq(10.0,1.0,1);
scalar_matrix<double> distance(1,1,1);
matrix< vector<double> > result(1,1);
result(0,0) = scalar_vector<double> (1,1);
_lockableProfile->attenuation(points, freq, distance, &result);
BOOST_CHECK_CLOSE((result(0, 0))[0], 50.0, 1e-6);
}
};
class mackenzie_tester : public tester_base
{
public:
void setup()
{
int month = 6;
wposition::compute_earth_radius((18.5 + 22.5) / 2.0);
_temp = new netcdf_woa(
USML_DATA_DIR "/woa09/temperature_seasonal_1deg.nc",
USML_DATA_DIR "/woa09/temperature_monthly_1deg.nc",
month, 18.5, 22.5, 200.5, 205.5 ) ;
netcdf_woa* temperature = new netcdf_woa(
USML_DATA_DIR "/woa09/temperature_seasonal_1deg.nc",
USML_DATA_DIR "/woa09/temperature_monthly_1deg.nc",
month, 18.5, 22.5, 200.5, 205.5 ) ;
netcdf_woa* salinity = new netcdf_woa(
USML_DATA_DIR "/woa09/salinity_seasonal_1deg.nc",
USML_DATA_DIR "/woa09/salinity_monthly_1deg.nc",
month, 18.5, 22.5, 200.5, 205.5 ) ;
attenuation_model* attn = new attenuation_constant(5.0);
profile_grid<double,3>* profile = new profile_grid<double,3>(
data_grid_mackenzie::construct(temperature, salinity), attn) ;
_lockableProfile = new profile_lock(profile);
}
virtual void test()
{
size_t index[3];
index[1] = 0;
index[2] = 0;
matrix<double> speed(1, 1);
wposition location(1, 1);
location.latitude(0, 0, 18.5);
location.longitude(0, 0, 200.5);
wvector gradient(1, 1);
for (size_t d = 0; d < _temp->axis(0)->size(); ++d)
{
index[0] = d;
location.rho(0, 0, (*_temp->axis(0))(d));
_lockableProfile->sound_speed(location, &speed, &gradient);
switch (d) {
case 0:
BOOST_CHECK_CLOSE( speed(0, 0), 1535.9781, 1e-3 );
break;
case 18:
BOOST_CHECK_CLOSE( speed(0, 0), 1483.6464, 1e-3 );
break;
case 32:
BOOST_CHECK_CLOSE( speed(0, 0), 1549.4983, 1e-3 );
break;
default:
break;
}
}
seq_linear freq(10.0,1.0,1);
scalar_matrix<double> distance(1,1,1);
matrix< vector<double> > result(1,1);
result(0,0) = scalar_vector<double> (1,1);
_lockableProfile->attenuation(location, freq, distance, &result);
BOOST_CHECK_CLOSE((result(0, 0))[0], 50.0, 1e-6);
}
};
BOOST_AUTO_TEST_CASE( linear_profile_lock_test ) {
cout << "=== profile_lock_test: linear_profile_lock_test ===" << endl;
try {
linear_tester linear;
linear.setup();
boost::thread_group tgroup;
tgroup.create_thread(boost::bind(&linear_tester::run, &linear));
boost::this_thread::sleep(boost::posix_time::milliseconds(60));
tgroup.create_thread(boost::bind(&linear_tester::run, &linear));
tgroup.join_all();
} catch (std::exception* except) {
BOOST_ERROR(except->what());
}
}
BOOST_AUTO_TEST_CASE( mackenzie_profile_lock_test ) {
cout << "=== profile_lock_test: mackenzie_profile_lock_test ===" << endl;
try {
mackenzie_tester mackenzie;
mackenzie.setup();
boost::thread_group tgroup;
tgroup.create_thread(boost::bind(&mackenzie_tester::run, &mackenzie));
boost::this_thread::sleep(boost::posix_time::milliseconds(60));
tgroup.create_thread(boost::bind(&mackenzie_tester::run, &mackenzie));
tgroup.join_all();
} catch (std::exception* except) {
BOOST_ERROR(except->what());
}
}
BOOST_AUTO_TEST_SUITE_END()