moab
SpatialLocator.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines