LCOV - code coverage report
Current view: top level - src/moab - SpatialLocator.hpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 7 18 38.9 %
Date: 2020-12-16 07:07:30 Functions: 3 5 60.0 %
Branches: 2 34 5.9 %

           Branch data     Line data    Source code
       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 <math.h>
      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                 :          4 :     BoundBox& local_box()
      70                 :            :     {
      71                 :          4 :         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, EntityHandle* ents, double* params, int* is_inside = NULL,
      82                 :            :                              const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10,
      83                 :            :                              const double inside_tol = 1.0e-6 );
      84                 :            : 
      85                 :            :     /* locate a set of points */
      86                 :            :     ErrorCode locate_points( const double* pos, int num_points, EntityHandle* ents, double* params,
      87                 :            :                              int* is_inside = NULL, const double rel_iter_tol = 1.0e-10,
      88                 :            :                              const double abs_iter_tol = 1.0e-10, const double inside_tol = 1.0e-6 );
      89                 :            : 
      90                 :            :     /* locate a set of vertices or entity centroids, storing results on TupleList in this class
      91                 :            :      * Locate a set of vertices or entity centroids, storing the detailed results in member
      92                 :            :      * variable (TupleList) locTable (see comments on locTable for structure of that tuple).
      93                 :            :      */
      94                 :            :     ErrorCode locate_points( Range& ents, const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10,
      95                 :            :                              const double inside_tol = 1.0e-6 );
      96                 :            : 
      97                 :            :     /* locate a set of points, storing results on TupleList in this class
      98                 :            :      * Locate a set of points, storing the detailed results in member variable (TupleList) locTable
      99                 :            :      * (see comments on locTable for structure of that tuple).
     100                 :            :      */
     101                 :            :     ErrorCode locate_points( const double* pos, int num_points, const double rel_iter_tol = 1.0e-10,
     102                 :            :                              const double abs_iter_tol = 1.0e-10, const double inside_tol = 1.0e-6 );
     103                 :            : 
     104                 :            :     /* Count the number of located points in locTable
     105                 :            :      * Return the number of entries in locTable that have non-zero entity handles, which
     106                 :            :      * represents the number of points in targetEnts that were inside one element in sourceEnts
     107                 :            :      *
     108                 :            :      */
     109                 :            :     int local_num_located();
     110                 :            : 
     111                 :            :     /* Count the number of located points in parLocTable
     112                 :            :      * Return the number of entries in parLocTable that have a non-negative index in on a remote
     113                 :            :      * proc in parLocTable, which gives the number of points located in at least one element in a
     114                 :            :      * remote proc's sourceEnts.
     115                 :            :      */
     116                 :            :     int remote_num_located();
     117                 :            : 
     118                 :            : #ifdef MOAB_HAVE_MPI
     119                 :            :     /* locate a set of vertices or entity centroids, storing results on TupleList in this class
     120                 :            :      * Locate a set of vertices or entity centroids, storing the detailed results in member
     121                 :            :      * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for
     122                 :            :      * structure of those tuples).
     123                 :            :      */
     124                 :            :     ErrorCode par_locate_points( ParallelComm* pc, Range& vertices, const double rel_iter_tol = 1.0e-10,
     125                 :            :                                  const double abs_iter_tol = 1.0e-10, const double inside_tol = 1.0e-6 );
     126                 :            : 
     127                 :            :     /* locate a set of points, storing results on TupleList in this class
     128                 :            :      * Locate a set of points, storing the detailed results in member
     129                 :            :      * variables (TupleList) locTable and parLocTable (see comments on locTable and parLocTable for
     130                 :            :      * structure of those tuples).
     131                 :            :      */
     132                 :            :     ErrorCode par_locate_points( ParallelComm* pc, const double* pos, int num_points,
     133                 :            :                                  const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10,
     134                 :            :                                  const double inside_tol = 1.0e-6 );
     135                 :            : #endif
     136                 :            : 
     137                 :            :     /** \brief Return the MOAB interface associated with this locator
     138                 :            :      */
     139                 :            :     Interface* moab()
     140                 :            :     {
     141                 :            :         return mbImpl;
     142                 :            :     }
     143                 :            : 
     144                 :            :     /* locate a point */
     145                 :            :     ErrorCode locate_point( const double* pos, EntityHandle& ent, double* params, int* is_inside = NULL,
     146                 :            :                             const double rel_iter_tol = 1.0e-10, const double abs_iter_tol = 1.0e-10,
     147                 :            :                             const double inside_tol = 1.0e-6 );
     148                 :            : 
     149                 :            :     /* return the tree */
     150                 :          4 :     Tree* get_tree()
     151                 :            :     {
     152                 :          4 :         return myTree;
     153                 :            :     }
     154                 :            : 
     155                 :            :     /* get the locTable
     156                 :            :      */
     157                 :            :     TupleList& loc_table()
     158                 :            :     {
     159                 :            :         return locTable;
     160                 :            :     }
     161                 :            : 
     162                 :            :     /* get the locTable
     163                 :            :      */
     164                 :            :     const TupleList& loc_table() const
     165                 :            :     {
     166                 :            :         return locTable;
     167                 :            :     }
     168                 :            : 
     169                 :            :     /* get the parLocTable
     170                 :            :      */
     171                 :            :     TupleList& par_loc_table()
     172                 :            :     {
     173                 :            :         return parLocTable;
     174                 :            :     }
     175                 :            : 
     176                 :            :     /* get the parLocTable
     177                 :            :      */
     178                 :            :     const TupleList& par_loc_table() const
     179                 :            :     {
     180                 :            :         return parLocTable;
     181                 :            :     }
     182                 :            : 
     183                 :            :     /* get elemEval */
     184                 :            :     ElemEvaluator* elem_eval()
     185                 :            :     {
     186                 :            :         return elemEval;
     187                 :            :     }
     188                 :            : 
     189                 :            :     /* get elemEval */
     190                 :            :     const ElemEvaluator* elem_eval() const
     191                 :            :     {
     192                 :            :         return elemEval;
     193                 :            :     }
     194                 :            : 
     195                 :            :     /* set elemEval */
     196                 :            :     void elem_eval( ElemEvaluator* eval )
     197                 :            :     {
     198                 :            :         elemEval = eval;
     199                 :            :         if( myTree ) myTree->set_eval( eval );
     200                 :            :     }
     201                 :            : 
     202                 :            :     /** \brief Get spatial locator times object */
     203                 :            :     SpatialLocatorTimes& sl_times()
     204                 :            :     {
     205                 :            :         return myTimes;
     206                 :            :     }
     207                 :            : 
     208                 :            :     /** \brief Get spatial locator times object */
     209                 :            :     const SpatialLocatorTimes& sl_times() const
     210                 :            :     {
     211                 :            :         return myTimes;
     212                 :            :     }
     213                 :            : 
     214                 :            :   private:
     215                 :            : #ifdef MOAB_HAVE_MPI
     216                 :            :     /* MPI_ReduceAll source mesh bounding boxes to get global source mesh bounding box
     217                 :            :      */
     218                 :            :     ErrorCode initialize_intermediate_partition( ParallelComm* pc );
     219                 :            : 
     220                 :            :     /* for a given point in space, compute its ijk location in the intermediate decomposition;
     221                 :            :      * tolerance is used only to test proximity to global box extent, not for local box test
     222                 :            :      */
     223                 :            :     inline ErrorCode get_point_ijk( const CartVect& point, const double abs_iter_tol, int* ijk ) const;
     224                 :            : 
     225                 :            : #if 0
     226                 :            :         /* given an ijk location in the intermediate partition, return the proc rank for that location
     227                 :            :          */
     228                 :            :       inline int proc_from_ijk(const int *ijk) const;
     229                 :            : #endif
     230                 :            : 
     231                 :            :     /* given a point in space, return the proc responsible for that point from the intermediate
     232                 :            :      * decomp; no tolerances applied here, so first proc in lexicographic ijk ordering is returned
     233                 :            :      */
     234                 :            :     inline int proc_from_point( const double* pos, const double abs_iter_tol ) const;
     235                 :            : 
     236                 :            :     /* register my source mesh with intermediate decomposition procs
     237                 :            :      */
     238                 :            :     ErrorCode register_src_with_intermediate_procs( ParallelComm* pc, double abs_iter_tol, TupleList& TLreg_o );
     239                 :            : 
     240                 :            : #endif
     241                 :            : 
     242                 :            :     /** Create a tree
     243                 :            :      * Tree type depends on what's in myElems: if empty or all vertices, creates a kdtree,
     244                 :            :      * otherwise creates a BVHTree.
     245                 :            :      */
     246                 :            :     void create_tree();
     247                 :            : 
     248                 :            :     /* MOAB instance */
     249                 :            :     Interface* mbImpl;
     250                 :            : 
     251                 :            :     /* elements being located */
     252                 :            :     Range myElems;
     253                 :            : 
     254                 :            :     /* dimension of entities in locator */
     255                 :            :     int myDim;
     256                 :            : 
     257                 :            :     /* tree used for location */
     258                 :            :     Tree* myTree;
     259                 :            : 
     260                 :            :     /* element evaluator */
     261                 :            :     ElemEvaluator* elemEval;
     262                 :            : 
     263                 :            :     /* whether I created the tree or not (determines whether to delete it or not on destruction) */
     264                 :            :     bool iCreatedTree;
     265                 :            : 
     266                 :            :     /* \brief local locations table
     267                 :            :      * This table stores detailed local location data results from locate_points, that is, location
     268                 :            :      * data for points located on the local mesh.  Data is stored in a TupleList, where each tuple
     269                 :            :      * consists of (p_i, hs_ul, r[3]_d), where p_i = (int) proc from which request for this point
     270                 :            :      * was made (0 if serial) hs_ul = (unsigned long) source entity containing the point r[3]_d =
     271                 :            :      * (double) parametric coordinates of the point in hs
     272                 :            :      */
     273                 :            :     TupleList locTable;
     274                 :            : 
     275                 :            :     /* \brief parallel locations table
     276                 :            :      * This table stores information about points located on a local or remote processor.  For
     277                 :            :      * points located on this processor's local mesh, detailed location data is stored in locTable.
     278                 :            :      * For points located on remote processors, more communication is required to retrieve specific
     279                 :            :      * location data (usually that information isn't useful on this processor).
     280                 :            :      *
     281                 :            :      * The tuple structure of this TupleList is (p_i, ri_i), where:
     282                 :            :      *   p_i = (int) processor rank containing this point
     283                 :            :      *   ri_i = (int) index into locTable on remote proc containing this point's location
     284                 :            :      * information The indexing of parLocTable corresponds to that of the points/entities passed in.
     285                 :            :      */
     286                 :            :     TupleList parLocTable;
     287                 :            : 
     288                 :            :     /* \brief Local bounding box, duplicated from tree
     289                 :            :      */
     290                 :            :     BoundBox localBox;
     291                 :            : 
     292                 :            :     /* \brief Global bounding box, used in parallel spatial location
     293                 :            :      */
     294                 :            :     BoundBox globalBox;
     295                 :            : 
     296                 :            :     /* \brief Regional delta xyz, used in parallel spatial location
     297                 :            :      */
     298                 :            :     CartVect regDeltaXYZ;
     299                 :            : 
     300                 :            :     /* \brief Number of regions in each of 3 directions
     301                 :            :      */
     302                 :            :     int regNums[3];
     303                 :            : 
     304                 :            :     /* \brief Map from source processor to bounding box of that proc's source mesh
     305                 :            :      *
     306                 :            :      */
     307                 :            :     std::map< int, BoundBox > srcProcBoxes;
     308                 :            : 
     309                 :            :     /* \brief Timing object for spatial location
     310                 :            :      */
     311                 :            :     SpatialLocatorTimes myTimes;
     312                 :            : 
     313                 :            :     /* \brief Timer object to manage overloaded search functions
     314                 :            :      */
     315                 :            :     CpuTimer myTimer;
     316                 :            : 
     317                 :            :     /* \brief Flag to manage initialization of timer for overloaded search functions
     318                 :            :      */
     319                 :            :     bool timerInitialized;
     320                 :            : };
     321                 :            : 
     322                 :          6 : inline SpatialLocator::~SpatialLocator()
     323                 :            : {
     324 [ -  + ][ #  # ]:          2 :     if( iCreatedTree && myTree ) delete myTree;
                 [ #  # ]
     325         [ -  + ]:          4 : }
     326                 :            : 
     327                 :            : inline ErrorCode SpatialLocator::locate_point( const double* pos, EntityHandle& ent, double* params, int* is_inside,
     328                 :            :                                                const double rel_iter_tol, const double abs_iter_tol,
     329                 :            :                                                const double inside_tol )
     330                 :            : {
     331                 :            :     return locate_points( pos, 1, &ent, params, is_inside, rel_iter_tol, abs_iter_tol, inside_tol );
     332                 :            : }
     333                 :            : 
     334                 :            : #ifdef MOAB_HAVE_MPI
     335                 :          0 : inline ErrorCode SpatialLocator::get_point_ijk( const CartVect& point, const double abs_iter_tol, int* ijk ) const
     336                 :            : {
     337         [ #  # ]:          0 :     for( int i = 0; i < 3; i++ )
     338                 :            :     {
     339 [ #  # ][ #  # ]:          0 :         if( point[i] < globalBox.bMin[i] - abs_iter_tol || point[i] > globalBox.bMax[i] + abs_iter_tol )
                 [ #  # ]
     340                 :          0 :             ijk[i] = -1;
     341                 :            :         else
     342                 :            :         {
     343                 :          0 :             ijk[i] = point[i] - globalBox.bMin[i] / regDeltaXYZ[i];
     344 [ #  # ][ #  # ]:          0 :             if( ijk[i] >= regNums[i] && point[i] <= globalBox.bMax[i] + abs_iter_tol ) ijk[i] = regNums[i] - 1;
                 [ #  # ]
     345                 :            :         }
     346                 :            :     }
     347                 :            : 
     348 [ #  # ][ #  # ]:          0 :     return ( ijk[0] >= 0 && ijk[1] >= 0 && ijk[2] >= 0 ? MB_SUCCESS : MB_FAILURE );
                 [ #  # ]
     349                 :            :     ;
     350                 :            : }
     351                 :            : 
     352                 :            : #if 0
     353                 :            :     inline int SpatialLocator::proc_from_ijk(const int *ijk) const
     354                 :            :     {
     355                 :            :       return ijk[2] * regNums[0]*regNums[1] + ijk[1] * regNums[0] + ijk[0];
     356                 :            :     }
     357                 :            : #endif
     358                 :            : 
     359                 :          0 : inline int SpatialLocator::proc_from_point( const double* pos, const double abs_iter_tol ) const
     360                 :            : {
     361                 :            :     int ijk[3];
     362 [ #  # ][ #  # ]:          0 :     ErrorCode rval = get_point_ijk( CartVect( pos ), abs_iter_tol, ijk );
     363         [ #  # ]:          0 :     if( MB_SUCCESS != rval ) return -1;
     364                 :            : 
     365                 :          0 :     return ijk[2] * regNums[0] * regNums[1] + ijk[1] * regNums[0] + ijk[0];
     366                 :            : }
     367                 :            : #endif
     368                 :            : 
     369                 :            : }  // namespace moab
     370                 :            : 
     371                 :            : #endif

Generated by: LCOV version 1.11