moab
linear_hex_map.hpp
Go to the documentation of this file.
00001 #ifndef MOAB_LINEAR_HEX_HPP
00002 #define MOAB_LINEAR_HEX_HPP
00003 
00004 #include "moab/Matrix3.hpp"
00005 #include "moab/CartVect.hpp"
00006 #include <sstream>
00007 #include <iomanip>
00008 #include <iostream>
00009 
00010 namespace moab { 
00011 
00012 namespace element_utility {
00013 
00014 class Linear_hex_map {
00015   public: 
00016     //Constructor
00017     Linear_hex_map() {}
00018     //Copy constructor
00019     Linear_hex_map( const Linear_hex_map &) {}
00020 
00021  public:
00022     //Natural coordinates
00023     template< typename Moab, typename Entity_handle, 
00024           typename Points, typename Point>
00025     std::pair< bool, CartVect> evaluate_reverse(const double *verts,
00026                                                 const double *eval_point,
00027                                                 const double tol=1.e-6) const{
00028       CartVect params(3, 0.0);
00029       solve_inverse(eval_point, params, verts);
00030       bool point_found = solve_inverse(eval_point, params, verts, tol) && 
00031           is_contained(params, tol);
00032       return std::make_pair(point_found, params);
00033     }
00034 
00035   private:
00036     //This is a hack to avoid a .cpp file and C++11
00037     //reference_points(i,j) will be a 1 or -1;
00038     //This should unroll..
00039   inline const CartVect &reference_points(const std::size_t& i) const{
00040     const CartVect rpts[8] = { CartVect( -1, -1, -1),
00041                               CartVect( 1, -1, -1),
00042                               CartVect( 1,  1, -1),
00043                               CartVect(-1,  1, -1),
00044                               CartVect(-1, -1,  1),
00045                               CartVect( 1, -1,  1),
00046                               CartVect( 1,  1,  1),
00047                               CartVect(-1,  1,  1)};
00048     return rpts[ i];
00049   }
00050 
00051   bool is_contained( const CartVect & params, const double tol) const{
00052      //just look at the box+tol here
00053     return ( params[0]>=-1.-tol) && (params[0]<=1.+tol) &&
00054         ( params[1]>=-1.-tol) && (params[1]<=1.+tol) &&
00055         ( params[2]>=-1.-tol) && (params[2]<=1.+tol);
00056   }
00057 
00058   bool solve_inverse(const CartVect &point, 
00059                      CartVect &params,
00060                      const CartVect *verts, 
00061                      const double tol=1.e-6) const {
00062     const double error_tol_sqr = tol*tol;
00063     CartVect delta(0.0, 0.0, 0.0);
00064     params = delta;
00065     evaluate_forward(params, verts, delta);
00066     delta -= point;
00067     std::size_t num_iterations=0;
00068 #ifdef LINEAR_HEX_DEBUG
00069     std::stringstream ss;
00070     ss << "CartVect: "; 
00071     ss << point[0] << ", " << point[1] << ", " << point [2] << std::endl;
00072     ss << "Hex: ";
00073     for(int i = 0; i < 8; ++i)
00074       ss << points[i][0] << ", " << points[i][1] << ", " << points[i][2] << std::endl;
00075     ss << std::endl;
00076 #endif
00077     while ( delta.length_squared() > error_tol_sqr) {
00078 #ifdef LINEAR_HEX_DEBUG
00079       ss << "Iter #: "  << num_iterations 
00080          << " Err: " << delta.length() << " Iterate: ";
00081       ss << params[0] << ", " << params[1] << ", " << params[2] << std::endl;
00082 #endif
00083       if( ++num_iterations >= 5){ return false; }
00084       Matrix3 J;
00085       jacobian( params, verts, J);
00086       double det = moab::Matrix3::determinant3(J);
00087       if (fabs(det) < 1.e-10){
00088 #ifdef LINEAR_HEX_DEBUG
00089         std::cerr << ss.str();
00090 #endif
00091 #ifndef LINEAR_HEX_DEBUG
00092         std::cerr << x[0] << ", " << x[1] << ", " << x [2] << std::endl;
00093 #endif
00094         std::cerr << "inverse solve failure: det: " << det << std::endl;
00095         exit(-1);
00096       }
00097       params -= moab::Matrix3::inverse(J, 1.0/det) * delta;
00098       evaluate_forward(params, points, delta);
00099       delta -= x;
00100     }
00101     return true;
00102   }
00103 
00104   void evaluate_forward(const CartVect &p, const CartVect *verts, CartVect &f) const{ 
00105     typedef typename Points::value_type Vector;
00106     f.set(0.0, 0.0, 0.0);
00107     for (unsigned i = 0; i < 8; ++i) {
00108       const double N_i = (1 + p[0]*reference_points(i)[0])
00109           * (1 + p[1]*reference_points(i)[1])
00110           * (1 + p[2]*reference_points(i)[2]);
00111       f += N_i * verts[ i];
00112     }
00113     f *= 0.125;
00114     return f;
00115   }
00116 
00117   double integrate_scalar_field(const CartVect *points, 
00118                                 const double *field_values) const {
00119   }
00120 
00121   template< typename Point, typename Points>
00122   Matrix3& jacobian( const Point & p, const Points & points, Matrix3 & J) const{
00123   }
00124 private:
00125 }; //Class Linear_hex_map
00126 
00127 }// namespace element_utility
00128 
00129 }// namespace moab
00130 #endif //MOAB_LINEAR_HEX_nPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines