MOAB: Mesh Oriented datABase  (version 5.4.1)
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
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