MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "TestUtil.hpp" 00002 #include "ElemUtil.hpp" 00003 #include <iostream> 00004 00005 using namespace moab; 00006 00007 void test_hex_nat_coords(); 00008 00009 int main() 00010 { 00011 int rval = 0; 00012 rval += RUN_TEST( test_hex_nat_coords ); 00013 return rval; 00014 } 00015 00016 const CartVect cube_corners[8] = { CartVect( 0, 0, 0 ), CartVect( 1, 0, 0 ), CartVect( 1, 1, 0 ), CartVect( 0, 1, 0 ), 00017 CartVect( 0, 0, 1 ), CartVect( 1, 0, 1 ), CartVect( 1, 1, 1 ), CartVect( 0, 1, 1 ) }; 00018 00019 const CartVect hex_corners[8] = { CartVect( 1.0e0, 0.0e0, 0.0e0 ), CartVect( 1.0e0, 1.0e0, 0.3e0 ), 00020 CartVect( 0.0e0, 2.0e0, 0.6e0 ), CartVect( 0.2e0, 1.1e0, 0.4e0 ), 00021 CartVect( 1.5e0, 0.3e0, 1.0e0 ), CartVect( 1.5e0, 1.3e0, 1.0e0 ), 00022 CartVect( 0.5e0, 2.3e0, 1.0e0 ), CartVect( 0.7e0, 1.4e0, 1.0e0 ) }; 00023 00024 /** shape function for trilinear hex */ 00025 CartVect hex_map( const CartVect& xi, const CartVect* corners ) 00026 { 00027 CartVect x( 0.0 ); 00028 x += ( 1 - xi[0] ) * ( 1 - xi[1] ) * ( 1 - xi[2] ) * corners[0]; 00029 x += ( 1 + xi[0] ) * ( 1 - xi[1] ) * ( 1 - xi[2] ) * corners[1]; 00030 x += ( 1 + xi[0] ) * ( 1 + xi[1] ) * ( 1 - xi[2] ) * corners[2]; 00031 x += ( 1 - xi[0] ) * ( 1 + xi[1] ) * ( 1 - xi[2] ) * corners[3]; 00032 x += ( 1 - xi[0] ) * ( 1 - xi[1] ) * ( 1 + xi[2] ) * corners[4]; 00033 x += ( 1 + xi[0] ) * ( 1 - xi[1] ) * ( 1 + xi[2] ) * corners[5]; 00034 x += ( 1 + xi[0] ) * ( 1 + xi[1] ) * ( 1 + xi[2] ) * corners[6]; 00035 x += ( 1 - xi[0] ) * ( 1 + xi[1] ) * ( 1 + xi[2] ) * corners[7]; 00036 return x *= 0.125; 00037 } 00038 00039 static void hex_bounding_box( const CartVect* corners, CartVect& min, CartVect& max ) 00040 { 00041 min = max = corners[0]; 00042 for( unsigned i = 1; i < 8; ++i ) 00043 for( unsigned d = 0; d < 3; ++d ) 00044 if( corners[i][d] < min[d] ) 00045 min[d] = corners[i][d]; 00046 else if( corners[i][d] > max[d] ) 00047 max[d] = corners[i][d]; 00048 } 00049 00050 static bool in_range( const CartVect& xi ) 00051 { 00052 return fabs( xi[0] ) <= 1 && fabs( xi[1] ) <= 1 && fabs( xi[2] ) <= 1; 00053 } 00054 00055 void test_hex_nat_coords() 00056 { 00057 CartVect xi, result_xi; 00058 bool valid; 00059 // rename EPS to EPS1 because of conflict with definition of EPS in types.h 00060 // types.h is now included in the header. 00061 const double EPS1 = 1e-6; 00062 00063 // first test with cube because it's easier to debug failures 00064 std::vector< CartVect > cube_corners2; 00065 std::copy( cube_corners, cube_corners + 8, std::back_inserter( cube_corners2 ) ); 00066 Element::LinearHex hex( cube_corners2 ); 00067 for( xi[0] = -1; xi[0] <= 1; xi[0] += 0.2 ) 00068 { 00069 for( xi[1] = -1; xi[1] <= 1; xi[1] += 0.2 ) 00070 { 00071 for( xi[2] = -1; xi[2] <= 1; xi[2] += 0.2 ) 00072 { 00073 const CartVect pt = hex_map( xi, cube_corners ); 00074 result_xi = hex.ievaluate( pt, EPS1 / 10 ); 00075 double dum = EPS1 / 10; 00076 valid = hex.inside_nat_space( result_xi, dum ); 00077 CHECK( valid ); 00078 CHECK_REAL_EQUAL( xi[0], result_xi[0], EPS1 ); 00079 CHECK_REAL_EQUAL( xi[1], result_xi[1], EPS1 ); 00080 CHECK_REAL_EQUAL( xi[2], result_xi[2], EPS1 ); 00081 } 00082 } 00083 } 00084 00085 // now test with distorted hex 00086 std::vector< CartVect > hex_corners2; 00087 std::copy( hex_corners, hex_corners + 8, std::back_inserter( hex_corners2 ) ); 00088 Element::LinearHex hex2( hex_corners2 ); 00089 for( xi[0] = -1; xi[0] <= 1; xi[0] += 0.2 ) 00090 { 00091 for( xi[1] = -1; xi[1] <= 1; xi[1] += 0.2 ) 00092 { 00093 for( xi[2] = -1; xi[2] <= 1; xi[2] += 0.2 ) 00094 { 00095 const CartVect pt = hex_map( xi, hex_corners ); 00096 result_xi = hex2.ievaluate( pt, EPS1 / 10 ); 00097 double dum = EPS1 / 10; 00098 valid = hex2.inside_nat_space( result_xi, dum ); 00099 CHECK( valid ); 00100 CHECK_REAL_EQUAL( xi[0], result_xi[0], EPS1 ); 00101 CHECK_REAL_EQUAL( xi[1], result_xi[1], EPS1 ); 00102 CHECK_REAL_EQUAL( xi[2], result_xi[2], EPS1 ); 00103 } 00104 } 00105 } 00106 00107 // test points outside of element 00108 CartVect x, min, max; 00109 hex_bounding_box( cube_corners, min, max ); 00110 for( x[0] = -1; x[0] <= 2; x[0] += 0.4 ) 00111 { 00112 for( x[1] = -1; x[1] <= 2; x[1] += 0.4 ) 00113 { 00114 for( x[2] = -1; x[2] <= 2; x[2] += 0.4 ) 00115 { 00116 bool in_box = x[0] >= min[0] && x[0] <= max[0] && x[1] >= min[1] && x[1] <= max[1] && x[2] >= min[2] && 00117 x[2] <= max[2]; 00118 if( in_box ) continue; 00119 result_xi = hex.ievaluate( x, EPS1 / 10 ); 00120 double dum = EPS1 / 10; 00121 valid = hex.inside_nat_space( result_xi, dum ); 00122 00123 // std::cout << (valid ? 'y' : 'n'); 00124 CHECK( !valid || !in_range( result_xi ) ); 00125 } 00126 } 00127 } 00128 // std::cout << std::endl; 00129 00130 hex_bounding_box( hex_corners, min, max ); 00131 for( x[0] = -1; x[0] <= 3; x[0] += 0.5 ) 00132 { 00133 for( x[1] = -2; x[1] <= 4; x[1] += 0.5 ) 00134 { 00135 for( x[2] = -1; x[2] <= 2; x[2] += 0.4 ) 00136 { 00137 bool in_box = x[0] >= min[0] && x[0] <= max[0] && x[1] >= min[1] && x[1] <= max[1] && x[2] >= min[2] && 00138 x[2] <= max[2]; 00139 if( in_box ) continue; 00140 try 00141 { 00142 result_xi = hex2.ievaluate( x, EPS1 / 10 ); 00143 } 00144 catch( Element::Map::EvaluationError& /* err */ ) 00145 { 00146 valid = false; 00147 } 00148 // std::cout << (valid ? 'y' : 'n'); 00149 CHECK( !valid || !in_range( result_xi ) ); 00150 } 00151 } 00152 } 00153 // std::cout << std::endl; 00154 }