12 #define CHK( ErrorCode ) \
15 if( MB_SUCCESS != ( ErrorCode ) ) fail( ( ErrorCode ), __FILE__, __LINE__ ); \
20 static void fail(
ErrorCode error_code,
const char* file_name,
int line_number );
43 const char* usage_str =
"[-k|-v] [-n <N>] [-d <N>] [-e <N>] <input_mesh>";
46 std::cerr <<
"Usage: " <<
argv0 <<
" " << usage_str << std::endl;
47 std::cerr <<
" : " <<
argv0 <<
" -h" << std::endl;
51 std::cout <<
"Usage: " <<
argv0 <<
" " << usage_str << std::endl
54 <<
" -n : Specify number of test points (default = " <<
DEFAULT_NUM_TEST <<
")" << std::endl
55 <<
" -d : Specify maximum tree depth" << std::endl
56 <<
" -e : Specify maximum elements per leaf" << std::endl
57 <<
" <input_mesh> : Mesh to build and query." << std::endl
64 std::vector< CartVect >& points,
65 std::vector< EntityHandle >& point_elems );
71 const std::vector< CartVect >& points,
72 std::vector< EntityHandle >& point_elems,
81 const std::vector< CartVect >& points,
82 std::vector< EntityHandle >& point_elems,
87 int main(
int argc,
char* argv[] )
92 long elem_per_leaf = -1;
100 for(
int i = 1; i < argc; ++i )
104 *valptr = strtol( argv[i], &endptr, 0 );
105 if( *valptr < 1 || *endptr )
107 std::cerr <<
"Invalid value for '" << argv[i - 1] <<
"' flag: " << argv[i] << std::endl;
112 else if( argv[i][0] ==
'-' && argv[i][1] && !argv[i][2] )
117 usage( argv[0],
true );
126 valptr = &tree_depth;
129 valptr = &elem_per_leaf;
132 valptr = &num_points;
135 std::cerr <<
"Invalid flag: " << argv[i] << std::endl;
146 std::cerr <<
"Unexpected argument: " << argv[i] << std::endl;
152 std::cerr <<
"Expected value following '" << argv[argc - 1] <<
"' flag" << std::endl;
157 std::cerr <<
"No input file specified." << std::endl;
166 std::string init_msg, msg;
171 std::cerr <<
input_file <<
" : failed to read file." << std::endl;
173 if( msg != init_msg ) std::cerr <<
"message : " << msg << std::endl;
182 num_unique = num_points;
183 std::vector< CartVect > points;
184 std::vector< EntityHandle > elems;
189 unsigned long long init_total_storage;
194 size_t actual_depth = 0;
195 std::vector< EntityHandle > results( points.size() );
209 unsigned long long fini_total_storage;
214 if( results != elems )
216 std::cout <<
"WARNING: Test produced invalid results" << std::endl;
221 std::cout <<
"Number of test queries: " << num_points << std::endl;
222 std::cout <<
"Tree build time: " << ( (double)
build_time ) / CLOCKS_PER_SEC <<
" seconds" << std::endl;
223 std::cout <<
"Total query time: " << ( (double)test_time ) / CLOCKS_PER_SEC <<
" seconds" << std::endl;
224 std::cout <<
"Time per query: " << ( (double)test_time ) / CLOCKS_PER_SEC / num_points <<
" seconds" << std::endl;
225 std::cout <<
"Tree depth: " << actual_depth << std::endl;
227 std::cout <<
"Total query time/depth: " << ( (double)test_time ) / CLOCKS_PER_SEC / actual_depth <<
" seconds"
229 std::cout << std::endl;
230 std::cout <<
"Bytes before tree construction: " << init_total_storage << std::endl;
231 std::cout <<
"Bytes after tree construction: " << fini_total_storage << std::endl;
232 std::cout <<
"Difference: " << fini_total_storage - init_total_storage <<
" bytes" << std::endl;
238 std::cerr <<
"Internal error (error code " << error_code <<
") at " << file <<
":" << line << std::endl;
242 const int HexSign[8][3] = { { -1, -1, -1 }, { 1, -1, -1 }, { 1, 1, -1 }, { -1, 1, -1 },
243 { -1, -1, 1 }, { 1, -1, 1 }, { 1, 1, 1 }, { -1, 1, 1 } };
247 const double f = RAND_MAX / 2;
248 CartVect xi( ( (
double)rand() - f ) / f, ( (
double)rand() - f ) / f, ( (
double)rand() - f ) / f );
255 std::cerr <<
"Invalid element" << std::endl;
259 rval =
mb.
get_coords( conn, 8,
reinterpret_cast< double*
>( coords ) );
263 for(
unsigned i = 0; i < 8; ++i )
265 double coeff = 0.125;
266 for(
unsigned j = 0; j < 3; ++j )
267 coeff *= 1 +
HexSign[i][j] * xi[j];
268 point += coeff * coords[i];
276 std::vector< CartVect >& points,
277 std::vector< EntityHandle >& point_elems )
285 std::cerr <<
"Warning: ignoring non-hexahedral elements." << std::endl;
286 std::pair< Range::iterator, Range::iterator > p = elems.
equal_range(
MBHEX );
287 elems.
erase( p.second, elems.
end() );
292 std::cerr <<
"Input file contains no hexahedral elements." << std::endl;
296 points.resize( num_points );
297 point_elems.resize( num_points );
298 const size_t num_elem = elems.
size();
299 for(
size_t i = 0; i < num_points; ++i )
302 for(
size_t x = num_elem; x > 0; x /= RAND_MAX )
305 point_elems[i] = elems[offset];
314 const std::vector< CartVect >& points,
315 std::vector< EntityHandle >& point_elems,
321 clock_t
init = clock();
324 std::ostringstream options;
325 if( tree_depth > 0 ) options <<
"MAX_DEPTH=" << tree_depth <<
";";
326 if( elem_per_leaf > 0 ) options <<
"MAX_PER_LEAF=" << elem_per_leaf <<
";";
331 rval = tool.
build_tree( all_hexes, &root, &opt );
337 std::vector< EntityHandle > hexes;
338 std::vector< EntityHandle >::iterator j;
342 for(
long i = 0; i < num_test; ++i )
344 const size_t idx = (size_t)i % points.size();
345 rval = tool.
point_search( points[idx].array(),
leaf, 1.0e-10, 1.0e-6, NULL, &root );
350 for( j = hexes.begin(); j != hexes.end(); ++j )
354 rval =
mb.
get_coords( conn, 8,
reinterpret_cast< double*
>( coords ) );
358 point_elems[idx] = *j;
362 if( j == hexes.end() ) point_elems[idx] = 0;
368 tool.
get_info( root, tmp_box, tmp_box, max_d );
376 const std::vector< CartVect >& points,
377 std::vector< EntityHandle >& point_elems,
382 clock_t
init = clock();
387 point_elems.resize( points.size() );
393 for(
long i = 0; i < num_test; ++i )
395 const size_t idx = (size_t)i % points.size();
400 rval =
mb.
get_coords( conn, 8,
reinterpret_cast< double*
>( coords ) );
404 point_elems[idx] = *h;