moab
|
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 ¶ms, 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