boundary_grid_fast.h

00001 
00005 #pragma once
00006 
00007 #include <usml/ocean/boundary_model.h>
00008 #include <usml/ocean/reflect_loss_rayleigh.h>
00009 
00010 namespace usml {
00011 namespace ocean {
00012 
00027 class boundary_grid_fast : public boundary_model {
00028 
00029 public:
00030 
00031     //**************************************************
00032     // height model
00033 
00045     boundary_grid_fast(data_grid_bathy* height,
00046             reflect_loss_model* reflect_loss = NULL) :
00047             boundary_model(reflect_loss), _height(height) {
00048         this->_height->interp_type(0, GRID_INTERP_PCHIP);
00049         this->_height->interp_type(1, GRID_INTERP_PCHIP);
00050         this->_height->edge_limit(0, true);
00051         this->_height->edge_limit(1, true);
00052         if ( reflect_loss == NULL) {
00053             this->reflect_loss( new reflect_loss_rayleigh(
00054                     reflect_loss_rayleigh::SAND) ) ;
00055         }
00056     }
00057 
00061     virtual ~boundary_grid_fast() {
00062         delete _height;
00063     }
00064 
00074     virtual void height(const wposition& location, matrix<double>* rho,
00075             wvector* normal = NULL, bool quick_interp = false) {
00076         if (quick_interp) {
00077             this->_height->interp_type(0, GRID_INTERP_LINEAR);
00078             this->_height->interp_type(1, GRID_INTERP_LINEAR);
00079         } else {
00080             this->_height->interp_type(0, GRID_INTERP_PCHIP);
00081             this->_height->interp_type(1, GRID_INTERP_PCHIP);
00082         }
00083         if (normal) {
00084             matrix<double> gtheta(location.size1(), location.size2());
00085             matrix<double> gphi(location.size1(), location.size2());
00086             matrix<double> t(location.size1(), location.size2());
00087             matrix<double> p(location.size1(), location.size2());
00088             this->_height->interpolate(location.theta(), location.phi(), rho,
00089                     &gtheta, &gphi);
00090 
00091             t = element_div(gtheta, *rho);  // slope = tan(angle)
00092             p = element_div(gphi, element_prod(*rho, sin(location.theta())));
00093             normal->theta(                  // normal = -sin(angle)
00094                     element_div(-t, sqrt(1.0 + abs2(t))));
00095             normal->phi(element_div(-p, sqrt(1.0 + abs2(p))));
00096             normal->rho(sqrt(                   // r=sqrt(1-t^2-p^2)
00097                     1.0 - abs2(normal->theta()) - abs2(normal->phi())));
00098         } else {
00099             this->_height->interpolate(location.theta(), location.phi(), rho);
00100         }
00101     }
00102 
00112     virtual void height(const wposition1& location, double* rho,
00113             wvector1* normal = NULL, bool quick_interp = false) {
00114         if (quick_interp) {
00115             this->_height->interp_type(0, GRID_INTERP_LINEAR);
00116             this->_height->interp_type(1, GRID_INTERP_LINEAR);
00117         } else {
00118             this->_height->interp_type(0, GRID_INTERP_PCHIP);
00119             this->_height->interp_type(1, GRID_INTERP_PCHIP);
00120         }
00121         if (normal) {
00122             double loc[2] = { location.theta(), location.phi() };
00123             double grad[2];
00124             *rho = this->_height->interpolate(loc, grad);
00125             const double t = grad[0] / (*rho);      // slope = tan(angle)
00126             const double p = grad[1] / ((*rho) * sin(location.theta()));
00127             normal->theta(-t / sqrt(1.0 + t * t));  // normal = -sin(angle)
00128             normal->phi(-p / sqrt(1.0 + p * p));
00129             const double N = normal->theta() * normal->theta()
00130                     + normal->phi() * normal->phi();
00131             normal->rho(sqrt(1.0 - N));                         // r=sqrt(1-t^2-p^2)
00132         } else {
00133             double loc[2] = { location.theta(), location.phi() };
00134             *rho = this->_height->interpolate(loc);
00135         }
00136     }
00137 
00138 private:
00139 
00141     data_grid_bathy* _height;
00142 
00143 }; // end class boundary_grid_fast
00144 
00145 }  // end of namespace ocean
00146 }  // end of namespace usml

Generated on 4 May 2015 for USML by  doxygen 1.6.1