MOAB: Mesh Oriented datABase  (version 5.4.1)
spatial_locator_test.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines