MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "moab/Core.hpp" 00002 #include "moab/SpatialLocator.hpp" 00003 #include "moab/Tree.hpp" 00004 #include "moab/HomXform.hpp" 00005 #include "moab/ScdInterface.hpp" 00006 #include "moab/CartVect.hpp" 00007 #include "moab/AdaptiveKDTree.hpp" 00008 #include "moab/BVHTree.hpp" 00009 #include "moab/ElemEvaluator.hpp" 00010 #include "moab/ProgOptions.hpp" 00011 #include "moab/CpuTimer.hpp" 00012 00013 #ifdef MOAB_HAVE_MPI 00014 #include "moab_mpi.h" 00015 #endif 00016 00017 #include "TestUtil.hpp" 00018 00019 #include <cstdlib> 00020 #include <sstream> 00021 00022 using namespace moab; 00023 00024 void test_kd_tree(); 00025 void test_bvh_tree(); 00026 void test_locator( SpatialLocator* sl ); 00027 00028 ErrorCode create_hex_mesh( Interface& mb, Range& elems, int n, int dim ); 00029 00030 int max_depth = 30; 00031 int npoints = 1000; 00032 int leaf = 6; 00033 bool print_tree = false; 00034 int ints = 10; 00035 00036 int main( int argc, char** argv ) 00037 { 00038 #ifdef MOAB_HAVE_MPI 00039 int fail = MPI_Init( &argc, &argv ); 00040 if( fail ) return fail; 00041 #else 00042 // silence the warning of parameters not used, in serial; there should be a smarter way :( 00043 argv[0] = argv[argc - argc]; 00044 #endif 00045 00046 ProgOptions po( "spatial_locator_test options" ); 00047 po.addOpt< int >( "ints,i", "Number of intervals on each side of scd mesh", &ints ); 00048 po.addOpt< int >( "leaf,l", "Maximum number of elements per leaf", &leaf ); 00049 po.addOpt< int >( "max_depth,m", "Maximum depth of tree", &max_depth ); 00050 po.addOpt< int >( "npoints,n", "Number of query points", &npoints ); 00051 po.addOpt< void >( "print,p", "Print tree details", &print_tree ); 00052 po.parseCommandLine( argc, argv ); 00053 00054 RUN_TEST( test_kd_tree ); 00055 RUN_TEST( test_bvh_tree ); 00056 00057 #ifdef MOAB_HAVE_MPI 00058 fail = MPI_Finalize(); 00059 if( fail ) return fail; 00060 #endif 00061 00062 return 0; 00063 } 00064 00065 void test_kd_tree() 00066 { 00067 ErrorCode rval; 00068 Core mb; 00069 00070 // create a simple mesh to test 00071 Range elems; 00072 rval = create_hex_mesh( mb, elems, ints, 3 );CHECK_ERR( rval ); 00073 00074 // initialize spatial locator with the elements and KDtree 00075 AdaptiveKDTree kd( &mb ); 00076 std::ostringstream opts; 00077 opts << "MAX_DEPTH=" << max_depth << ";MAX_PER_LEAF=" << leaf; 00078 FileOptions fo( opts.str().c_str() ); 00079 rval = kd.parse_options( fo ); 00080 SpatialLocator* sl = new SpatialLocator( &mb, elems, &kd ); 00081 00082 test_locator( sl ); 00083 00084 // test with an evaluator 00085 ElemEvaluator eval( &mb ); 00086 kd.set_eval( &eval ); 00087 test_locator( sl ); 00088 00089 // destroy spatial locator, and tree along with it 00090 delete sl; 00091 } 00092 00093 void test_bvh_tree() 00094 { 00095 ErrorCode rval; 00096 Core mb; 00097 00098 // create a simple mesh to test 00099 Range elems; 00100 rval = create_hex_mesh( mb, elems, ints, 3 );CHECK_ERR( rval ); 00101 00102 // initialize spatial locator with the elements and a BVH tree 00103 BVHTree bvh( &mb ); 00104 std::ostringstream opts; 00105 opts << "MAX_DEPTH=" << max_depth << ";MAX_PER_LEAF=" << leaf; 00106 FileOptions fo( opts.str().c_str() ); 00107 rval = bvh.parse_options( fo ); 00108 SpatialLocator* sl = new SpatialLocator( &mb, elems, &bvh ); 00109 test_locator( sl ); 00110 00111 // test with an evaluator 00112 ElemEvaluator eval( &mb ); 00113 bvh.set_eval( &eval ); 00114 test_locator( sl ); 00115 00116 // destroy spatial locator, and tree along with it 00117 delete sl; 00118 } 00119 00120 void test_locator( SpatialLocator* sl ) 00121 { 00122 CartVect box_del, test_pt, test_res; 00123 BoundBox box = sl->local_box(); 00124 box_del = box.bMax - box.bMin; 00125 00126 double denom = 1.0 / (double)RAND_MAX; 00127 int is_in; 00128 EntityHandle ent = 0; 00129 ErrorCode rval; 00130 for( int i = 0; i < npoints; i++ ) 00131 { 00132 // generate a small number of random point to test 00133 double rx = (double)rand() * denom, ry = (double)rand() * denom, rz = (double)rand() * denom; 00134 test_pt = box.bMin + CartVect( rx * box_del[0], ry * box_del[1], rz * box_del[2] ); 00135 00136 // call spatial locator to locate points 00137 rval = sl->locate_points( test_pt.array(), 1, &ent, test_res.array(), &is_in );CHECK_ERR( rval ); 00138 00139 // verify that the point was found 00140 CHECK_EQUAL( is_in, true ); 00141 } 00142 00143 std::cout << "Traversal stats:" << std::endl; 00144 sl->get_tree()->tree_stats().output_trav_stats(); 00145 00146 if( print_tree ) 00147 { 00148 std::cout << "Tree information: " << std::endl; 00149 rval = sl->get_tree()->print();CHECK_ERR( rval ); 00150 } 00151 } 00152 00153 ErrorCode create_hex_mesh( Interface& mb, Range& elems, int n, int dim ) 00154 { 00155 ScdInterface* scdi; 00156 ErrorCode rval = mb.query_interface( scdi );CHECK_ERR( rval ); 00157 HomCoord high( n - 1, -1, -1 ); 00158 if( dim > 1 ) high[1] = n - 1; 00159 if( dim > 2 ) high[2] = n - 1; 00160 ScdBox* new_box; 00161 rval = scdi->construct_box( HomCoord( 0, 0, 0 ), high, NULL, 0, new_box );CHECK_ERR( rval ); 00162 rval = mb.release_interface( scdi );CHECK_ERR( rval ); 00163 00164 rval = mb.get_entities_by_dimension( 0, dim, elems );CHECK_ERR( rval ); 00165 00166 return rval; 00167 }