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