#include <boost/test/unit_test.hpp>
#include <usml/netcdf/netcdf_files.h>
#include <usml/waveq3d/waveq3d.h>
#include <usml/waveq3d/reverberation_model.h>
#include <iostream>
#include <iomanip>
#include <fstream>
BOOST_AUTO_TEST_SUITE(reflection_test)
using namespace boost::unit_test ;
using namespace usml::netcdf ;
using namespace usml::waveq3d ;
using namespace boost::numeric::ublas ;
BOOST_AUTO_TEST_CASE( reflect_slope_test ) {
cout << "=== reflection_test: reflect_slope_test ===" << endl ;
try {
const double c0 = 1500.0 ;
profile_model* profile = new profile_linear(c0) ;
boundary_model* surface = new boundary_flat() ;
wposition1 slope_ref( 45.1, -45.0, 0.0 ) ;
reflect_loss_model* slope_loss = new reflect_loss_rayleigh( reflect_loss_rayleigh::SILT ) ;
boundary_model* bottom = new boundary_slope(
slope_ref, 1000.0, to_radians(1.0), 0.0, slope_loss ) ;
ocean_model ocean( surface, bottom, profile ) ;
seq_log freq( 10.0, 10.0, 1 ) ;
wposition1 pos( 45.0, -45.0, 0.0 ) ;
seq_linear de( -5.175034664, 0.0, 1 ) ;
seq_linear az( 0.0, 0.0, 1 ) ;
const double time_step = 0.001 ;
wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
const char* name = USML_TEST_DIR "/waveq3d/test/reflect_slope_test.csv" ;
std::ofstream os(name) ;
cout << "Writing tables to " << name << endl ;
os << "t,"
<< "lat,lng,alt,"
<< "de,az,bot,surf,"
<< "r,theta,phi,"
<< "rd,thd,phid,"
<< "mu,eta,nu,"
<< "mud,etad,nud,"
<< "c,dcdz"
<< endl ;
os << std::scientific << std::showpoint << std::setprecision(18) ;
cout << "time step = " << time_step << " secs" << endl ;
int bounce = 0 ;
double old_de = de(0) ;
while ( wave.time() < 25.0 ) {
wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
double de, az ;
ndir.direction( &de, &az ) ;
os << wave.time() << ','
<< wave.curr()->position.latitude(0,0) << ','
<< wave.curr()->position.longitude(0,0) << ','
<< wave.curr()->position.altitude(0,0) << ','
<< de << "," << az << ","
<< wave.curr()->surface(0,0) << ','
<< wave.curr()->bottom(0,0) << ','
<< wave.curr()->position.rho(0,0) << ','
<< wave.curr()->position.theta(0,0) << ','
<< wave.curr()->position.phi(0,0) << ','
<< wave.curr()->pos_gradient.rho(0,0) << ','
<< wave.curr()->pos_gradient.theta(0,0) << ','
<< wave.curr()->pos_gradient.phi(0,0) << ','
<< wave.curr()->ndirection.rho(0,0) << ','
<< wave.curr()->ndirection.theta(0,0) << ','
<< wave.curr()->ndirection.phi(0,0) << ','
<< wave.curr()->ndir_gradient.rho(0,0) << ','
<< wave.curr()->ndir_gradient.theta(0,0) << ','
<< wave.curr()->ndir_gradient.phi(0,0) << ','
<< wave.curr()->sound_speed(0,0) << ','
<< wave.curr()->sound_gradient.rho(0,0) << endl ;
wave.step() ;
if ( old_de * de < 0.0 ) {
++bounce ;
if ( old_de < 0.0 ) {
cout << "bottom reflection at t=" << wave.time()
<< " lat=" << wave.curr()->position.latitude(0,0)
<< " old de=" << old_de << " new de=" << de
<< " diff=" << (de+old_de)
<< endl ;
BOOST_CHECK_SMALL( 2.0-(de+old_de), 0.001 ) ;
} else {
cout << "surface reflection at t=" << wave.time()
<< " lat=" << wave.curr()->position.latitude(0,0)
<< " old de=" << old_de << " new de=" << de
<< " diff=" << (old_de+de)
<< endl ;
BOOST_CHECK_SMALL( old_de+de, 0.001 ) ;
}
}
old_de = de ;
}
cout << "wave propagates for " << wave.time() << " secs" << endl ;
} catch ( std::exception* except ) {
BOOST_ERROR( except->what() ) ;
}
}
BOOST_AUTO_TEST_CASE( reflect_grid_test ) {
const char* csvname = USML_TEST_DIR "/waveq3d/test/reflect_grid_test.csv" ;
const char* ncname = USML_TEST_DIR "/waveq3d/test/reflect_grid_test.nc" ;
cout << "=== reflection_test: reflect_grid_test ===" << endl ;
try {
const double c0 = 1500.0 ;
const double lat1 = 35.5 ;
const double lat2 = 36.5 ;
const double lng1 = 15.25 ;
const double lng2 = 16.25 ;
wposition::compute_earth_radius( (lat1+lat2)/2.0 ) ;
wposition1 pos( 35.983333333, 16.0, -10.0 ) ;
seq_linear de( -20.0, 1.0, 1 ) ;
seq_linear az( 270.0, 1.0, 1 ) ;
const double time_step = 0.1 ;
const double time_max = 80.0 ;
seq_log freq( 3000.0, 1.0, 1 ) ;
cout << "load bathymetry" << endl ;
boundary_model* bottom = new boundary_grid<double,2>( new netcdf_bathy(
USML_DATA_DIR "/bathymetry/ETOPO1_Ice_g_gmt4.grd",
lat1, lat2, lng1, lng2 ) ) ;
profile_model* profile = new profile_linear(c0) ;
boundary_model* surface = new boundary_flat() ;
ocean_model ocean( surface, bottom, profile ) ;
std::ofstream os(csvname) ;
cout << "writting tables to " << csvname << endl ;
os << "t,"
<< "lat,lng,alt,"
<< "de,az,surf,bot,"
<< "r,theta,phi,"
<< "rd,thd,phid,"
<< "mu,eta,nu,"
<< "mud,etad,nud,"
<< "c,dcdz"
<< endl ;
os << std::scientific << std::showpoint << std::setprecision(18) ;
cout << "time step = " << time_step << " secs" << endl ;
wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
cout << "Writing wavefronts to " << ncname << endl ;
wave.init_netcdf( ncname ) ;
wave.save_netcdf() ;
while ( wave.time() < time_max ) {
wave.step() ;
wave.save_netcdf() ;
wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
double de, az ;
ndir.direction( &de, &az ) ;
os << wave.time() << ','
<< wave.curr()->position.latitude(0,0) << ','
<< wave.curr()->position.longitude(0,0) << ','
<< wave.curr()->position.altitude(0,0) << ','
<< de << "," << az << ","
<< wave.curr()->surface(0,0) << ','
<< wave.curr()->bottom(0,0) << ','
<< wave.curr()->position.rho(0,0) << ','
<< wave.curr()->position.theta(0,0) << ','
<< wave.curr()->position.phi(0,0) << ','
<< wave.curr()->pos_gradient.rho(0,0) << ','
<< wave.curr()->pos_gradient.theta(0,0) << ','
<< wave.curr()->pos_gradient.phi(0,0) << ','
<< wave.curr()->ndirection.rho(0,0) << ','
<< wave.curr()->ndirection.theta(0,0) << ','
<< wave.curr()->ndirection.phi(0,0) << ','
<< wave.curr()->ndir_gradient.rho(0,0) << ','
<< wave.curr()->ndir_gradient.theta(0,0) << ','
<< wave.curr()->ndir_gradient.phi(0,0) << ','
<< wave.curr()->sound_speed(0,0) << ','
<< wave.curr()->sound_gradient.rho(0,0) << endl ;
}
wave.close_netcdf() ;
cout << "wave propagates for " << wave.time() << " secs" << endl ;
#ifdef __FAST_MATH__
const double position_accuracy = 5e-4 ;
#else
const double position_accuracy = 0.09 ;
#endif
BOOST_CHECK_CLOSE( wave.curr()->position.latitude(0,0), 36.169253160619995, position_accuracy ) ;
BOOST_CHECK_CLOSE( wave.curr()->position.longitude(0,0), 16.012084836798909, position_accuracy ) ;
} catch ( std::exception* except ) {
BOOST_ERROR( except->what() ) ;
}
}
BOOST_AUTO_TEST_CASE( reflect_interp_spd_acc_test ){
const char* csvname = USML_TEST_DIR "/waveq3d/test/reflect_interp_test.csv" ;
cout << "=== reflection_test: reflect_interp_spd_acc_test ===" << endl ;
const double c0 = 1500.0 ;
const double lat1 = 35.5 ;
const double lat2 = 36.5 ;
const double lng1 = 15.25 ;
const double lng2 = 16.25 ;
wposition::compute_earth_radius( (lat1+lat2)/2.0 ) ;
wposition1 pos( 35.983333333, 16.0, -10.0 ) ;
seq_linear de( -20.0, 1.0, 1 ) ;
seq_linear az( 270.0, 1.0, 1 ) ;
const double time_step = 0.1 ;
const double time_max = 80.0 ;
seq_log freq( 3000.0, 1.0, 1 ) ;
cout << "load bathymetry" << endl ;
boundary_model* bottom = new boundary_grid<double,2>( new netcdf_bathy(
USML_DATA_DIR "/bathymetry/ETOPO1_Ice_g_gmt4.grd",
lat1, lat2, lng1, lng2 ) ) ;
profile_model* profile = new profile_linear(c0) ;
boundary_model* surface = new boundary_flat() ;
ocean_model ocean( surface, bottom, profile ) ;
std::ofstream os(csvname) ;
cout << "Writing tables to " << csvname << endl ;
os << "t,"
<< "lat,lng,alt,"
<< "de,az,surf,bot,"
<< "r,theta,phi,"
<< "rd,thd,phid,"
<< "mu,eta,nu,"
<< "mud,etad,nud,"
<< "c,dcdz"
<< endl ;
os << std::scientific << std::showpoint << std::setprecision(18) ;
cout << "time step = " << time_step << " secs" << endl ;
wave_queue wave( ocean, freq, pos, de, az, time_step ) ;
while ( wave.time() < time_max ) {
wave.step() ;
wvector1 ndir( wave.curr()->ndirection, 0, 0 ) ;
double de, az ;
ndir.direction( &de, &az ) ;
os << wave.time() << ','
<< wave.curr()->position.latitude(0,0) << ','
<< wave.curr()->position.longitude(0,0) << ','
<< wave.curr()->position.altitude(0,0) << ','
<< de << "," << az << ","
<< wave.curr()->surface(0,0) << ','
<< wave.curr()->bottom(0,0) << ','
<< wave.curr()->position.rho(0,0) << ','
<< wave.curr()->position.theta(0,0) << ','
<< wave.curr()->position.phi(0,0) << ','
<< wave.curr()->pos_gradient.rho(0,0) << ','
<< wave.curr()->pos_gradient.theta(0,0) << ','
<< wave.curr()->pos_gradient.phi(0,0) << ','
<< wave.curr()->ndirection.rho(0,0) << ','
<< wave.curr()->ndirection.theta(0,0) << ','
<< wave.curr()->ndirection.phi(0,0) << ','
<< wave.curr()->ndir_gradient.rho(0,0) << ','
<< wave.curr()->ndir_gradient.theta(0,0) << ','
<< wave.curr()->ndir_gradient.phi(0,0) << ','
<< wave.curr()->sound_speed(0,0) << ','
<< wave.curr()->sound_gradient.rho(0,0) << endl ;
}
}
BOOST_AUTO_TEST_SUITE_END()