MOAB: Mesh Oriented datABase  (version 5.5.0)
sploc_searching_perf.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"
8 #include "moab/BVHTree.hpp"
9 #include "moab/ProgOptions.hpp"
10 #include "moab/CpuTimer.hpp"
11 #include "moab/ElemEvaluator.hpp"
12 
13 #ifdef MOAB_HAVE_MPI
14 #include "moab_mpi.h"
15 #endif
16 
17 #include <cstdlib>
18 #include <sstream>
19 
20 using namespace moab;
21 
22 ErrorCode test_locator( SpatialLocator& sl, int npoints, double rtol, double& cpu_time, double& percent_outside );
23 ErrorCode create_hex_mesh( Interface& mb, Range& elems, int n, int dim );
24 
25 int main( int argc, char** argv )
26 {
27 #ifdef MOAB_HAVE_MPI
28  int fail = MPI_Init( &argc, &argv );
29  if( fail ) return fail;
30 #else
31  // silence the warning of parameters not used, in serial; there should be a smarter way :(
32  argv[0] = argv[argc - argc];
33 #endif
34 
35  int npoints = 100, dim = 3;
36  int dints = 1, dleafs = 1, ddeps = 1;
37  bool eval = false;
38  double rtol = 1.0e-10;
39 
40  ProgOptions po( "tree_searching_perf options" );
41  po.addOpt< void >( ",e", "Use ElemEvaluator in tree search", &eval );
42  po.addOpt< int >( "ints,i", "Number of doublings of intervals on each side of scd mesh", &dints );
43  po.addOpt< int >( "leaf,l", "Number of doublings of maximum number of elements per leaf", &dleafs );
44  po.addOpt< int >( "max_depth,m", "Number of 5-intervals on maximum depth of tree", &ddeps );
45  po.addOpt< int >( "npoints,n", "Number of query points", &npoints );
46  po.addOpt< int >( "dim,d", "Dimension of the mesh", &dim );
47  po.addOpt< double >( "tol,t", "Relative tolerance of point search", &rtol );
48  // po.addOpt<void>( "print,p", "Print tree details", &print_tree);
49  po.parseCommandLine( argc, argv );
50 
51  std::vector< int > ints, deps, leafs;
52  ints.push_back( 10 );
53  for( int i = 1; i < dints; i++ )
54  ints.push_back( 2 * ints[i - 1] );
55  deps.push_back( 30 );
56  for( int i = 1; i < ddeps; i++ )
57  deps.push_back( deps[i - 1] - 5 );
58  leafs.push_back( 6 );
59  for( int i = 1; i < dleafs; i++ )
60  leafs.push_back( 2 * leafs[i - 1] );
61 
62  ErrorCode rval = MB_SUCCESS;
63  std::cout << "Tree_type"
64  << " "
65  << "Elems_per_leaf"
66  << " "
67  << "Tree_depth"
68  << " "
69  << "Ints_per_side"
70  << " "
71  << "N_elements"
72  << " "
73  << "search_time"
74  << " "
75  << "perc_outside"
76  << " "
77  << "initTime"
78  << " "
79  << "nodesVisited"
80  << " "
81  << "leavesVisited"
82  << " "
83  << "numTraversals"
84  << " "
85  << "leafObjectTests" << std::endl;
86 
87  // outermost iteration: # elements
88  for( std::vector< int >::iterator int_it = ints.begin(); int_it != ints.end(); ++int_it )
89  {
90  Core mb;
91  Range elems;
92  rval = create_hex_mesh( mb, elems, *int_it, dim );
93  if( MB_SUCCESS != rval ) return rval;
94 
95  // iteration: tree depth
96  for( std::vector< int >::iterator dep_it = deps.begin(); dep_it != deps.end(); ++dep_it )
97  {
98 
99  // iteration: tree max elems/leaf
100  for( std::vector< int >::iterator leafs_it = leafs.begin(); leafs_it != leafs.end(); ++leafs_it )
101  {
102 
103  // iteration: tree type
104  for( int tree_tp = 0; tree_tp < 2; tree_tp++ )
105  {
106  // create tree
107  Tree* tree;
108  if( 0 == tree_tp )
109  tree = new BVHTree( &mb );
110  else
111  tree = new AdaptiveKDTree( &mb );
112 
113  ElemEvaluator* eeval = NULL;
114  if( eval )
115  {
116  // create an element evaluator
117  eeval = new ElemEvaluator( &mb );
118  rval = eeval->set_eval_set( *elems.begin() );
119  if( MB_SUCCESS != rval ) return rval;
120  }
121 
122  std::ostringstream opts;
123  opts << "MAX_DEPTH=" << *dep_it << ";MAX_PER_LEAF=" << *leafs_it;
124  FileOptions fo( opts.str().c_str() );
125  rval = tree->parse_options( fo );
126  if( MB_SUCCESS != rval ) return rval;
127  SpatialLocator sl( &mb, elems, tree, eeval );
128 
129  // call evaluation
130  double cpu_time, perc_outside;
131  rval = test_locator( sl, npoints, rtol, cpu_time, perc_outside );
132  if( MB_SUCCESS != rval ) return rval;
133 
134  std::cout << ( tree_tp == 0 ? "BVH" : "KD" ) << " " << *leafs_it << " " << *dep_it << " " << *int_it
135  << " " << ( *int_it ) * ( *int_it ) * ( *int_it ) << " " << cpu_time << " "
136  << perc_outside << " ";
137 
138  tree->tree_stats().output_all_stats();
139 
140  if( eeval ) delete eeval;
141 
142  } // tree_tp
143 
144  } // max elems/leaf
145 
146  } // max depth
147 
148  } // # elements
149 
150 #ifdef MOAB_HAVE_MPI
151  fail = MPI_Finalize();
152  if( fail ) return fail;
153 #endif
154 
155  return 0;
156 }
157 
158 ErrorCode test_locator( SpatialLocator& sl, int npoints, double rtol, double& cpu_time, double& percent_outside )
159 {
160  BoundBox box = sl.local_box();
161  CartVect box_del = box.bMax - box.bMin;
162 
163  std::vector< CartVect > test_pts( npoints ), test_res( npoints );
164  std::vector< EntityHandle > ents( npoints );
165  int* is_in = new int[npoints];
166 
167  double denom = 1.0 / (double)RAND_MAX;
168  for( int i = 0; i < npoints; i++ )
169  {
170  // generate a small number of random point to test
171  double rx = (double)rand() * denom, ry = (double)rand() * denom, rz = (double)rand() * denom;
172  test_pts[i] = box.bMin + CartVect( rx * box_del[0], ry * box_del[1], rz * box_del[2] );
173  }
174 
175  CpuTimer ct;
176 
177  // call spatial locator to locate points
178  ErrorCode rval =
179  sl.locate_points( test_pts[0].array(), npoints, &ents[0], test_res[0].array(), &is_in[0], rtol, 0.0 );
180  if( MB_SUCCESS != rval )
181  {
182  delete[] is_in;
183  return rval;
184  }
185 
186  cpu_time = ct.time_elapsed();
187 
188  int num_out = std::count( is_in, is_in + npoints, false );
189  percent_outside = ( (double)num_out ) / npoints;
190  delete[] is_in;
191 
192  return rval;
193 }
194 
196 {
197  ScdInterface* scdi;
198  ErrorCode rval = mb.query_interface( scdi );
199  if( MB_SUCCESS != rval ) return rval;
200 
201  HomCoord high( n - 1, -1, -1 );
202  if( dim > 1 ) high[1] = n - 1;
203  if( dim > 2 ) high[2] = n - 1;
204  ScdBox* new_box;
205  rval = scdi->construct_box( HomCoord( 0, 0, 0 ), high, NULL, 0, new_box );
206  if( MB_SUCCESS != rval ) return rval;
207  rval = mb.release_interface( scdi );
208  if( MB_SUCCESS != rval ) return rval;
209 
210  rval = mb.get_entities_by_dimension( 0, dim, elems );
211  if( MB_SUCCESS != rval ) return rval;
212 
213  return rval;
214 }