moab
|
00001 00030 #ifndef MOAB_SPATIALLOCATOR_HPP 00031 #define MOAB_SPATIALLOCATOR_HPP 00032 00033 #include "moab/Types.hpp" 00034 #include "moab/Tree.hpp" 00035 #include "moab/Range.hpp" 00036 #include "moab/TupleList.hpp" 00037 #include "moab/BoundBox.hpp" 00038 #include "moab/SpatialLocatorTimes.hpp" 00039 #include "moab/CpuTimer.hpp" 00040 00041 #include <string> 00042 #include <vector> 00043 #include <map> 00044 #include <math.h> 00045 00046 namespace moab { 00047 00048 class Interface; 00049 class ElemEvaluator; 00050 class ParallelComm; 00051 00052 class SpatialLocator 00053 { 00054 public: 00055 /* constructor */ 00056 SpatialLocator(Interface *impl, Range &elems, Tree *tree = NULL, ElemEvaluator *eval = NULL); 00057 00058 /* destructor */ 00059 virtual ~SpatialLocator(); 00060 00061 /* add elements to be searched */ 00062 ErrorCode add_elems(Range &elems); 00063 00064 /* get bounding box of this locator */ 00065 BoundBox &local_box() {return localBox;} 00066 00067 /* get bounding box of this locator */ 00068 const BoundBox &local_box() const {return localBox;} 00069 00070 /* locate a set of vertices, Range variant */ 00071 ErrorCode locate_points(Range &vertices, 00072 EntityHandle *ents, double *params, int *is_inside = NULL, 00073 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00074 const double inside_tol = 1.0e-6); 00075 00076 /* locate a set of points */ 00077 ErrorCode locate_points(const double *pos, int num_points, 00078 EntityHandle *ents, double *params, int *is_inside = NULL, 00079 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00080 const double inside_tol = 1.0e-6); 00081 00082 /* locate a set of vertices or entity centroids, storing results on TupleList in this class 00083 * Locate a set of vertices or entity centroids, storing the detailed results in member 00084 * variable (TupleList) locTable (see comments on locTable for structure of that tuple). 00085 */ 00086 ErrorCode locate_points(Range &ents, 00087 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00088 const double inside_tol = 1.0e-6); 00089 00090 /* locate a set of points, storing results on TupleList in this class 00091 * Locate a set of points, storing the detailed results in member variable (TupleList) locTable 00092 * (see comments on locTable for structure of that tuple). 00093 */ 00094 ErrorCode locate_points(const double *pos, int num_points, 00095 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00096 const double inside_tol = 1.0e-6); 00097 00098 /* Count the number of located points in locTable 00099 * Return the number of entries in locTable that have non-zero entity handles, which 00100 * represents the number of points in targetEnts that were inside one element in sourceEnts 00101 * 00102 */ 00103 int local_num_located(); 00104 00105 /* Count the number of located points in parLocTable 00106 * Return the number of entries in parLocTable that have a non-negative index in on a remote 00107 * proc in parLocTable, which gives the number of points located in at least one element in a 00108 * remote proc's sourceEnts. 00109 */ 00110 int remote_num_located(); 00111 00112 #ifdef USE_MPI 00113 /* locate a set of vertices or entity centroids, storing results on TupleList in this class 00114 * Locate a set of vertices or entity centroids, storing the detailed results in member 00115 * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for 00116 * structure of those tuples). 00117 */ 00118 ErrorCode par_locate_points(ParallelComm *pc, 00119 Range &vertices, 00120 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00121 const double inside_tol = 1.0e-6); 00122 00123 /* locate a set of points, storing results on TupleList in this class 00124 * Locate a set of points, storing the detailed results in member 00125 * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for 00126 * structure of those tuples). 00127 */ 00128 ErrorCode par_locate_points(ParallelComm *pc, 00129 const double *pos, int num_points, 00130 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00131 const double inside_tol = 1.0e-6); 00132 #endif 00133 00136 Interface* moab() { return mbImpl; } 00137 00138 /* locate a point */ 00139 ErrorCode locate_point(const double *pos, 00140 EntityHandle &ent, double *params, int *is_inside = NULL, 00141 const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10, 00142 const double inside_tol = 1.0e-6); 00143 00144 /* return the tree */ 00145 Tree *get_tree() {return myTree;} 00146 00147 /* get the locTable 00148 */ 00149 TupleList &loc_table() {return locTable;} 00150 00151 /* get the locTable 00152 */ 00153 const TupleList &loc_table() const {return locTable;} 00154 00155 /* get the parLocTable 00156 */ 00157 TupleList &par_loc_table() {return parLocTable;} 00158 00159 /* get the parLocTable 00160 */ 00161 const TupleList &par_loc_table() const {return parLocTable;} 00162 00163 /* get elemEval */ 00164 ElemEvaluator *elem_eval() {return elemEval;} 00165 00166 /* get elemEval */ 00167 const ElemEvaluator *elem_eval() const {return elemEval;} 00168 00169 /* set elemEval */ 00170 void elem_eval(ElemEvaluator *eval) {elemEval = eval; if (myTree) myTree->set_eval(eval);} 00171 00173 SpatialLocatorTimes &sl_times() {return myTimes;} 00174 00176 const SpatialLocatorTimes &sl_times() const {return myTimes;} 00177 00178 private: 00179 00180 #ifdef USE_MPI 00181 /* MPI_ReduceAll source mesh bounding boxes to get global source mesh bounding box 00182 */ 00183 ErrorCode initialize_intermediate_partition(ParallelComm *pc); 00184 00185 /* for a given point in space, compute its ijk location in the intermediate decomposition; tolerance is 00186 * used only to test proximity to global box extent, not for local box test 00187 */ 00188 inline ErrorCode get_point_ijk(const CartVect &point, const double abs_iter_tol, int *ijk) const; 00189 00190 /* given an ijk location in the intermediate partition, return the proc rank for that location 00191 */ 00192 inline int proc_from_ijk(const int *ijk) const; 00193 00194 /* given a point in space, return the proc responsible for that point from the intermediate decomp; no tolerances 00195 * applied here, so first proc in lexicographic ijk ordering is returned 00196 */ 00197 inline int proc_from_point(const double *pos, const double abs_iter_tol) const; 00198 00199 /* register my source mesh with intermediate decomposition procs 00200 */ 00201 ErrorCode register_src_with_intermediate_procs(ParallelComm *pc, double abs_iter_tol, TupleList &TLreg_o); 00202 00203 #endif 00204 00209 void create_tree(); 00210 00211 /* MOAB instance */ 00212 Interface* mbImpl; 00213 00214 /* elements being located */ 00215 Range myElems; 00216 00217 /* dimension of entities in locator */ 00218 int myDim; 00219 00220 /* tree used for location */ 00221 Tree *myTree; 00222 00223 /* element evaluator */ 00224 ElemEvaluator *elemEval; 00225 00226 /* whether I created the tree or not (determines whether to delete it or not on destruction) */ 00227 bool iCreatedTree; 00228 00229 /* \brief local locations table 00230 * This table stores detailed local location data results from locate_points, that is, location data 00231 * for points located on the local mesh. Data is stored 00232 * in a TupleList, where each tuple consists of (p_i, hs_ul, r[3]_d), where 00233 * p_i = (int) proc from which request for this point was made (0 if serial) 00234 * hs_ul = (unsigned long) source entity containing the point 00235 * r[3]_d = (double) parametric coordinates of the point in hs 00236 */ 00237 TupleList locTable; 00238 00239 /* \brief parallel locations table 00240 * This table stores information about points located on a local or remote processor. For 00241 * points located on this processor's local mesh, detailed location data is stored in locTable. 00242 * For points located on remote processors, more communication is required to retrieve specific 00243 * location data (usually that information isn't useful on this processor). 00244 * 00245 * The tuple structure of this TupleList is (p_i, ri_i), where: 00246 * p_i = (int) processor rank containing this point 00247 * ri_i = (int) index into locTable on remote proc containing this point's location information 00248 * The indexing of parLocTable corresponds to that of the points/entities passed in. 00249 */ 00250 TupleList parLocTable; 00251 00252 /* \brief Local bounding box, duplicated from tree 00253 */ 00254 BoundBox localBox; 00255 00256 /* \brief Global bounding box, used in parallel spatial location 00257 */ 00258 BoundBox globalBox; 00259 00260 /* \brief Regional delta xyz, used in parallel spatial location 00261 */ 00262 CartVect regDeltaXYZ; 00263 00264 /* \brief Number of regions in each of 3 directions 00265 */ 00266 int regNums[3]; 00267 00268 /* \brief Map from source processor to bounding box of that proc's source mesh 00269 * 00270 */ 00271 std::map<int, BoundBox> srcProcBoxes; 00272 00273 /* \brief Timing object for spatial location 00274 */ 00275 SpatialLocatorTimes myTimes; 00276 00277 /* \brief Timer object to manage overloaded search functions 00278 */ 00279 CpuTimer myTimer; 00280 00281 /* \brief Flag to manage initialization of timer for overloaded search functions 00282 */ 00283 bool timerInitialized; 00284 }; 00285 00286 inline SpatialLocator::~SpatialLocator() 00287 { 00288 if (iCreatedTree && myTree) delete myTree; 00289 } 00290 00291 inline ErrorCode SpatialLocator::locate_point(const double *pos, 00292 EntityHandle &ent, double *params, int *is_inside, 00293 const double rel_iter_tol, const double abs_iter_tol, 00294 const double inside_tol) 00295 { 00296 return locate_points(pos, 1, &ent, params, is_inside, rel_iter_tol, abs_iter_tol, inside_tol); 00297 } 00298 00299 #ifdef USE_MPI 00300 inline ErrorCode SpatialLocator::get_point_ijk(const CartVect &point, const double abs_iter_tol, int *ijk) const 00301 { 00302 for (int i = 0; i < 3; i++) { 00303 if (point[i] < globalBox.bMin[i]-abs_iter_tol || point[i] > globalBox.bMax[i]+abs_iter_tol) 00304 ijk[i] = -1; 00305 else { 00306 ijk[i] = point[i] - globalBox.bMin[i] / regDeltaXYZ[i]; 00307 if (ijk[i] >= regNums[i] && point[i] <= globalBox.bMax[i]+abs_iter_tol) 00308 ijk[i] = regNums[i]-1; 00309 } 00310 } 00311 00312 return (ijk[0] >= 0 && ijk[1] >= 0 && ijk[2] >= 0 ? MB_SUCCESS : MB_FAILURE);; 00313 } 00314 00315 inline int SpatialLocator::proc_from_ijk(const int *ijk) const 00316 { 00317 return ijk[2] * regNums[0]*regNums[1] + ijk[1] * regNums[0] + ijk[0]; 00318 } 00319 00320 inline int SpatialLocator::proc_from_point(const double *pos, const double abs_iter_tol) const 00321 { 00322 int ijk[3]; 00323 ErrorCode rval = get_point_ijk(CartVect(pos), abs_iter_tol, ijk); 00324 if (MB_SUCCESS != rval) return -1; 00325 00326 return ijk[2] * regNums[0]*regNums[1] + ijk[1] * regNums[0] + ijk[0]; 00327 } 00328 #endif 00329 00330 } // namespace moab 00331 00332 #endif