MOAB: Mesh Oriented datABase  (version 5.5.0)
par_spatial_locator_test.cpp
Go to the documentation of this file.
1 #include "moab/Core.hpp"
3 #include "moab/Tree.hpp"
4 #include "moab/HomXform.hpp"
5 #include "moab/ScdInterface.hpp"
6 #include "moab/CartVect.hpp"
7 #include "moab/BVHTree.hpp"
8 #include "moab/ProgOptions.hpp"
9 #include "moab/CpuTimer.hpp"
10 #include "moab/ParallelComm.hpp"
11 #include "moab_mpi.h"
12 
13 #include "TestUtil.hpp"
14 
15 #include <cstdlib>
16 #include <sstream>
17 #include <string>
18 
19 using namespace moab;
20 
21 void test_kd_tree();
22 void test_bvh_tree();
23 void test_locator( SpatialLocator* sl );
24 
25 ErrorCode create_hex_mesh( Interface& mb, Range& elems, int n, int dim );
26 ErrorCode load_file( Interface& mb, std::string& fn, Range& elems );
27 
28 int max_depth = 30;
29 int npoints = 1000;
30 int leaf = 6;
31 int tree = -1;
32 bool print_tree = false;
33 int ints = 10;
34 std::string fname;
35 
36 int main( int argc, char** argv )
37 {
38  int fail = MPI_Init( &argc, &argv );
39  if( fail ) return fail;
40 
41  ProgOptions po( "spatial_locator_test options" );
42  po.addOpt< std::string >( "file,f", "Input filename", &fname );
43  po.addOpt< int >( "ints,i", "Number of intervals on each side of scd mesh", &ints );
44  po.addOpt< int >( "leaf,l", "Maximum number of elements per leaf", &leaf );
45  po.addOpt< int >( "max_depth,m", "Maximum depth of tree", &max_depth );
46  po.addOpt< int >( "npoints,n", "Number of query points", &npoints );
47  po.addOpt< void >( "print,p", "Print tree details", &print_tree );
48  po.addOpt< int >( "tree,t", "Tree type (-1=all (default), 0=AdaptiveKD, 1=BVH", &tree );
49  po.parseCommandLine( argc, argv );
50 
51  if( -1 == tree || 0 == tree ) RUN_TEST( test_kd_tree );
52  if( -1 == tree || 1 == tree ) RUN_TEST( test_bvh_tree );
53 
54  fail = MPI_Finalize();
55  if( fail ) return fail;
56 
57  return 0;
58 }
59 
61 {
62  ErrorCode rval;
63  Core mb;
64 
65  // create a simple mesh to test
66  Range elems;
67  if( fname.empty() )
68  {
69  rval = create_hex_mesh( mb, elems, ints, 3 );CHECK_ERR( rval );
70  }
71  else
72  {
73  rval = load_file( mb, fname, elems );CHECK_ERR( rval );
74  }
75 
76  // initialize spatial locator with the elements and the default tree type
77  SpatialLocator* sl = new SpatialLocator( &mb, elems );
78 
79  test_locator( sl );
80 
81  // destroy spatial locator, and tree along with it
82  delete sl;
83 }
84 
86 {
87  ErrorCode rval;
88  Core mb;
89 
90  // create a simple mesh to test
91  Range elems;
92  if( fname.empty() )
93  {
94  rval = create_hex_mesh( mb, elems, ints, 3 );CHECK_ERR( rval );
95  }
96  else
97  {
98  rval = load_file( mb, fname, elems );CHECK_ERR( rval );
99  }
100 
101  // initialize spatial locator with the elements and a BVH tree
102  BVHTree bvh( &mb );
103  std::ostringstream opts;
104  opts << "MAX_DEPTH=" << max_depth << ";MAX_PER_LEAF=" << leaf;
105  FileOptions fo( opts.str().c_str() );
106  rval = bvh.parse_options( fo );
107  SpatialLocator* sl = new SpatialLocator( &mb, elems, &bvh );
108  test_locator( sl );
109 
110  // destroy spatial locator, and tree along with it
111  delete sl;
112 }
113 
114 bool is_neg( int is_neg )
115 {
116  return ( is_neg < 0 );
117 }
118 
120 {
121  CartVect box_del;
122  BoundBox box = sl->local_box();
123  box_del = box.bMax - box.bMin;
124 
125  double denom = 1.0 / (double)RAND_MAX;
126  std::vector< CartVect > test_pts( npoints );
127 
128  for( int i = 0; i < npoints; i++ )
129  {
130  // generate a small number of random point to test
131  double rx = (double)rand() * denom, ry = (double)rand() * denom, rz = (double)rand() * denom;
132  test_pts[i] = box.bMin + CartVect( rx * box_del[0], ry * box_del[1], rz * box_del[2] );
133  }
134 
135  // call spatial locator to locate points
136  ParallelComm* pc = ParallelComm::get_pcomm( sl->moab(), 0 );
137  CHECK( pc != NULL );
138 
139  ErrorCode rval = sl->par_locate_points( pc, test_pts[0].array(), npoints );CHECK_ERR( rval );
140  if( pc->rank() == 0 )
141  {
142  int num_out = std::count_if( sl->par_loc_table().vi_rd, sl->par_loc_table().vi_rd + 2 * npoints, is_neg );
143  num_out /= 2;
144 
145  std::cout << "Number of points inside an element = " << npoints - num_out << "/" << npoints << " ("
146  << 100.0 * ( (double)npoints - num_out ) / npoints << "%)" << std::endl;
147  std::cout << "Traversal stats:" << std::endl;
149 
150  if( print_tree )
151  {
152  std::cout << "Tree information: " << std::endl;
153  rval = sl->get_tree()->print();CHECK_ERR( rval );
154  }
155  }
156 }
157 
159 {
160  ScdInterface* scdi;
161  ErrorCode rval = mb.query_interface( scdi );CHECK_ERR( rval );
162  ScdParData spd;
163  spd.gDims[0] = spd.gDims[1] = spd.gDims[2] = 0;
164  spd.gDims[3] = n;
166  if( dim > 1 ) spd.gDims[4] = n;
167  if( dim > 2 ) spd.gDims[5] = n;
168  ScdBox* new_box;
169  rval = scdi->construct_box( HomCoord( 0, 0, 0 ), HomCoord( 0, 0, 0 ), NULL, 0, new_box, NULL, &spd, false, 0 );CHECK_ERR( rval );
170 
171  rval = mb.get_entities_by_dimension( 0, dim, elems );CHECK_ERR( rval );
172 
173  return rval;
174 }
175 
176 ErrorCode load_file( Interface& mb, std::string& fn, Range& elems )
177 {
178  std::string options;
179  ErrorCode rval;
180 
181  options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;";
182  rval = mb.load_file( fn.c_str(), NULL, options.c_str() );
183  if( MB_SUCCESS != rval ) return rval;
184 
185  rval = mb.get_entities_by_dimension( 0, 3, elems );
186  if( MB_SUCCESS != rval ) return rval;
187 
188  if( elems.empty() )
189  {
190  rval = mb.get_entities_by_dimension( 0, 2, elems );
191  if( MB_SUCCESS != rval ) return rval;
192  }
193 
194  return MB_SUCCESS;
195 }