Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SpatialLocator.hpp
Go to the documentation of this file.
1 /**\file SpatialLocator.hpp 2  * \class moab::SpatialLocator 3  * \brief Tool to facilitate spatial location of a point in a mesh 4  * 5  * SpatialLocator facilitates searching for points in or performing ray traces on collections of 6  * mesh entities in 2D or 3D. This searching is facilitated by a tree-based decomposition of the 7  * mesh. Various types of trees are implemented in MOAB and can be used by this tool, but by 8  * default it uses AdaptiveKDTree (see child classes of Tree for which others are available). 9  * Parallel and serial searching are both supported. 10  * 11  * SpatialLocator can either cache the search results for points or pass back this information in 12  * arguments. Cached information is kept in locTable, indexed in the same order as search points 13  * passed in. This information consists of the entity handle containing the point and the 14  * parametric coordinates inside that element. Information about the points searched, e.g. the 15  * entities from which those points are derived, can be stored in the calling application if 16  * desired. 17  * 18  * In parallel, there is a separation between the proc deciding which points to search for (the 19  * "target" proc), and the proc locating the point in its local mesh (the "source" proc). On the 20  * source proc, location information is cached in locTable, as in the serial case. By default, this 21  * location information (handle and parametric coords) is not returned to the target proc, since it 22  * would be of no use there. Instead, the rank of the source proc locating the point, and the index 23  * of that location info in the source proc's locTable, is returned; this information is stored on 24  * the target proc in this class's parLocTable variable. Again, information about the points 25  * searched should be stored in the calling application, if desired. 26  * 27  * This class uses the ElemEvaluator class for specification and evaluation of basis functions (used 28  * for computing parametric coords within an entity). See documentation and examples for that class 29  * for usage information. 30  * 31  */ 32  33 #ifndef MOAB_SPATIALLOCATOR_HPP 34 #define MOAB_SPATIALLOCATOR_HPP 35  36 #include "moab/Types.hpp" 37 #include "moab/Tree.hpp" 38 #include "moab/Range.hpp" 39 #include "moab/TupleList.hpp" 40 #include "moab/BoundBox.hpp" 41 #include "moab/SpatialLocatorTimes.hpp" 42 #include "moab/CpuTimer.hpp" 43  44 #include <string> 45 #include <vector> 46 #include <map> 47 #include <cmath> 48  49 namespace moab 50 { 51  52 class Interface; 53 class ElemEvaluator; 54 class ParallelComm; 55  56 class SpatialLocator 57 { 58  public: 59  /* constructor */ 60  SpatialLocator( Interface* impl, Range& elems, Tree* tree = NULL, ElemEvaluator* eval = NULL ); 61  62  /* destructor */ 63  virtual ~SpatialLocator(); 64  65  /* add elements to be searched */ 66  ErrorCode add_elems( Range& elems ); 67  68  /* get bounding box of this locator */ 69  BoundBox& local_box() 70  { 71  return localBox; 72  } 73  74  /* get bounding box of this locator */ 75  const BoundBox& local_box() const 76  { 77  return localBox; 78  } 79  80  /* locate a set of vertices, Range variant */ 81  ErrorCode locate_points( Range& vertices, 82  EntityHandle* ents, 83  double* params, 84  int* is_inside = NULL, 85  const double rel_iter_tol = 1.0e-10, 86  const double abs_iter_tol = 1.0e-10, 87  const double inside_tol = 1.0e-6 ); 88  89  /* locate a set of points */ 90  ErrorCode locate_points( const double* pos, 91  int num_points, 92  EntityHandle* ents, 93  double* params, 94  int* is_inside = NULL, 95  const double rel_iter_tol = 1.0e-10, 96  const double abs_iter_tol = 1.0e-10, 97  const double inside_tol = 1.0e-6 ); 98  99  /* locate a set of vertices or entity centroids, storing results on TupleList in this class 100  * Locate a set of vertices or entity centroids, storing the detailed results in member 101  * variable (TupleList) locTable (see comments on locTable for structure of that tuple). 102  */ 103  ErrorCode locate_points( Range& ents, 104  const double rel_iter_tol = 1.0e-10, 105  const double abs_iter_tol = 1.0e-10, 106  const double inside_tol = 1.0e-6 ); 107  108  /* locate a set of points, storing results on TupleList in this class 109  * Locate a set of points, storing the detailed results in member variable (TupleList) locTable 110  * (see comments on locTable for structure of that tuple). 111  */ 112  ErrorCode locate_points( const double* pos, 113  int num_points, 114  const double rel_iter_tol = 1.0e-10, 115  const double abs_iter_tol = 1.0e-10, 116  const double inside_tol = 1.0e-6 ); 117  118  /* Count the number of located points in locTable 119  * Return the number of entries in locTable that have non-zero entity handles, which 120  * represents the number of points in targetEnts that were inside one element in sourceEnts 121  * 122  */ 123  int local_num_located(); 124  125  /* Count the number of located points in parLocTable 126  * Return the number of entries in parLocTable that have a non-negative index in on a remote 127  * proc in parLocTable, which gives the number of points located in at least one element in a 128  * remote proc's sourceEnts. 129  */ 130  int remote_num_located(); 131  132 #ifdef MOAB_HAVE_MPI 133  /* locate a set of vertices or entity centroids, storing results on TupleList in this class 134  * Locate a set of vertices or entity centroids, storing the detailed results in member 135  * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for 136  * structure of those tuples). 137  */ 138  ErrorCode par_locate_points( ParallelComm* pc, 139  Range& vertices, 140  const double rel_iter_tol = 1.0e-10, 141  const double abs_iter_tol = 1.0e-10, 142  const double inside_tol = 1.0e-6 ); 143  144  /* locate a set of points, storing results on TupleList in this class 145  * Locate a set of points, storing the detailed results in member 146  * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for 147  * structure of those tuples). 148  */ 149  ErrorCode par_locate_points( ParallelComm* pc, 150  const double* pos, 151  int num_points, 152  const double rel_iter_tol = 1.0e-10, 153  const double abs_iter_tol = 1.0e-10, 154  const double inside_tol = 1.0e-6 ); 155 #endif 156  157  /** \brief Return the MOAB interface associated with this locator 158  */ 159  Interface* moab() 160  { 161  return mbImpl; 162  } 163  164  /* locate a point */ 165  ErrorCode locate_point( const double* pos, 166  EntityHandle& ent, 167  double* params, 168  int* is_inside = NULL, 169  const double rel_iter_tol = 1.0e-10, 170  const double abs_iter_tol = 1.0e-10, 171  const double inside_tol = 1.0e-6 ); 172  173  /* return the tree */ 174  Tree* get_tree() 175  { 176  return myTree; 177  } 178  179  /* get the locTable 180  */ 181  TupleList& loc_table() 182  { 183  return locTable; 184  } 185  186  /* get the locTable 187  */ 188  const TupleList& loc_table() const 189  { 190  return locTable; 191  } 192  193  /* get the parLocTable 194  */ 195  TupleList& par_loc_table() 196  { 197  return parLocTable; 198  } 199  200  /* get the parLocTable 201  */ 202  const TupleList& par_loc_table() const 203  { 204  return parLocTable; 205  } 206  207  /* get elemEval */ 208  ElemEvaluator* elem_eval() 209  { 210  return elemEval; 211  } 212  213  /* get elemEval */ 214  const ElemEvaluator* elem_eval() const 215  { 216  return elemEval; 217  } 218  219  /* set elemEval */ 220  void elem_eval( ElemEvaluator* eval ) 221  { 222  elemEval = eval; 223  if( myTree ) myTree->set_eval( eval ); 224  } 225  226  /** \brief Get spatial locator times object */ 227  SpatialLocatorTimes& sl_times() 228  { 229  return myTimes; 230  } 231  232  /** \brief Get spatial locator times object */ 233  const SpatialLocatorTimes& sl_times() const 234  { 235  return myTimes; 236  } 237  238  private: 239 #ifdef MOAB_HAVE_MPI 240  /* MPI_ReduceAll source mesh bounding boxes to get global source mesh bounding box 241  */ 242  ErrorCode initialize_intermediate_partition( ParallelComm* pc ); 243  244  /* for a given point in space, compute its ijk location in the intermediate decomposition; 245  * tolerance is used only to test proximity to global box extent, not for local box test 246  */ 247  inline ErrorCode get_point_ijk( const CartVect& point, const double abs_iter_tol, int* ijk ) const; 248  249 #if 0 250  /* given an ijk location in the intermediate partition, return the proc rank for that location 251  */ 252  inline int proc_from_ijk(const int *ijk) const; 253 #endif 254  255  /* given a point in space, return the proc responsible for that point from the intermediate 256  * decomp; no tolerances applied here, so first proc in lexicographic ijk ordering is returned 257  */ 258  inline int proc_from_point( const double* pos, const double abs_iter_tol ) const; 259  260  /* register my source mesh with intermediate decomposition procs 261  */ 262  ErrorCode register_src_with_intermediate_procs( ParallelComm* pc, double abs_iter_tol, TupleList& TLreg_o ); 263  264 #endif 265  266  /** Create a tree 267  * Tree type depends on what's in myElems: if empty or all vertices, creates a kdtree, 268  * otherwise creates a BVHTree. 269  */ 270  void create_tree(); 271  272  /* MOAB instance */ 273  Interface* mbImpl; 274  275  /* elements being located */ 276  Range myElems; 277  278  /* dimension of entities in locator */ 279  int myDim; 280  281  /* tree used for location */ 282  Tree* myTree; 283  284  /* element evaluator */ 285  ElemEvaluator* elemEval; 286  287  /* whether I created the tree or not (determines whether to delete it or not on destruction) */ 288  bool iCreatedTree; 289  290  /* \brief local locations table 291  * This table stores detailed local location data results from locate_points, that is, location 292  * data for points located on the local mesh. Data is stored in a TupleList, where each tuple 293  * consists of (p_i, hs_ul, r[3]_d), where p_i = (int) proc from which request for this point 294  * was made (0 if serial) hs_ul = (unsigned long) source entity containing the point r[3]_d = 295  * (double) parametric coordinates of the point in hs 296  */ 297  TupleList locTable; 298  299  /* \brief parallel locations table 300  * This table stores information about points located on a local or remote processor. For 301  * points located on this processor's local mesh, detailed location data is stored in locTable. 302  * For points located on remote processors, more communication is required to retrieve specific 303  * location data (usually that information isn't useful on this processor). 304  * 305  * The tuple structure of this TupleList is (p_i, ri_i), where: 306  * p_i = (int) processor rank containing this point 307  * ri_i = (int) index into locTable on remote proc containing this point's location 308  * information The indexing of parLocTable corresponds to that of the points/entities passed in. 309  */ 310  TupleList parLocTable; 311  312  /* \brief Local bounding box, duplicated from tree 313  */ 314  BoundBox localBox; 315  316  /* \brief Global bounding box, used in parallel spatial location 317  */ 318  BoundBox globalBox; 319  320  /* \brief Regional delta xyz, used in parallel spatial location 321  */ 322  CartVect regDeltaXYZ; 323  324  /* \brief Number of regions in each of 3 directions 325  */ 326  int regNums[3]; 327  328  /* \brief Map from source processor to bounding box of that proc's source mesh 329  * 330  */ 331  std::map< int, BoundBox > srcProcBoxes; 332  333  /* \brief Timing object for spatial location 334  */ 335  SpatialLocatorTimes myTimes; 336  337  /* \brief Timer object to manage overloaded search functions 338  */ 339  CpuTimer myTimer; 340  341  /* \brief Flag to manage initialization of timer for overloaded search functions 342  */ 343  bool timerInitialized; 344 }; 345  346 inline SpatialLocator::~SpatialLocator() 347 { 348  if( iCreatedTree && myTree ) delete myTree; 349 } 350  351 inline ErrorCode SpatialLocator::locate_point( const double* pos, 352  EntityHandle& ent, 353  double* params, 354  int* is_inside, 355  const double rel_iter_tol, 356  const double abs_iter_tol, 357  const double inside_tol ) 358 { 359  return locate_points( pos, 1, &ent, params, is_inside, rel_iter_tol, abs_iter_tol, inside_tol ); 360 } 361  362 #ifdef MOAB_HAVE_MPI 363 inline ErrorCode SpatialLocator::get_point_ijk( const CartVect& point, const double abs_iter_tol, int* ijk ) const 364 { 365  for( int i = 0; i < 3; i++ ) 366  { 367  if( point[i] < globalBox.bMin[i] - abs_iter_tol || point[i] > globalBox.bMax[i] + abs_iter_tol ) 368  ijk[i] = -1; 369  else 370  { 371  ijk[i] = point[i] - globalBox.bMin[i] / regDeltaXYZ[i]; 372  if( ijk[i] >= regNums[i] && point[i] <= globalBox.bMax[i] + abs_iter_tol ) ijk[i] = regNums[i] - 1; 373  } 374  } 375  376  return ( ijk[0] >= 0 && ijk[1] >= 0 && ijk[2] >= 0 ? MB_SUCCESS : MB_FAILURE ); 377  ; 378 } 379  380 #if 0 381  inline int SpatialLocator::proc_from_ijk(const int *ijk) const 382  { 383  return ijk[2] * regNums[0]*regNums[1] + ijk[1] * regNums[0] + ijk[0]; 384  } 385 #endif 386  387 inline int SpatialLocator::proc_from_point( const double* pos, const double abs_iter_tol ) const 388 { 389  int ijk[3]; 390  ErrorCode rval = get_point_ijk( CartVect( pos ), abs_iter_tol, ijk ); 391  if( MB_SUCCESS != rval ) return -1; 392  393  return ijk[2] * regNums[0] * regNums[1] + ijk[1] * regNums[0] + ijk[0]; 394 } 395 #endif 396  397 } // namespace moab 398  399 #endif