Sierra Toolkit Version of the Day
CoarseSearch.hpp
00001 /*------------------------------------------------------------------------*/
00002 /*                 Copyright 2010 Sandia Corporation.                     */
00003 /*  Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive   */
00004 /*  license for use of this work by or on behalf of the U.S. Government.  */
00005 /*  Export of this program may require a license from the                 */
00006 /*  United States Government.                                             */
00007 /*------------------------------------------------------------------------*/
00008 
00009 #ifndef stk_search_CoarseSearch_hpp
00010 #define stk_search_CoarseSearch_hpp
00011 
00012 #include <vector>
00013 #include <utility>
00014 
00015 #include <stk_util/parallel/Parallel.hpp>
00016 #include <stk_util/parallel/ParallelComm.hpp>
00017 #include <stk_util/parallel/ParallelReduce.hpp>
00018 #include <stk_util/diag/Writer.hpp>
00019 #include <stk_search/IdentProc.hpp>
00020 #include <stk_search/BoundingBox.hpp>
00021 #include <stk_search/BihTree.hpp>
00022 #include <stk_search/BihTreeParallelOps.hpp>
00023 #include <stk_search/OctTreeOps.hpp>
00024 
00025 namespace stk {
00026 namespace search {
00027 
00028 // Structure to hold factory specification
00029 struct FactoryOrder {
00030   // Enumerate search algorithms
00031   enum Algorithm {OCTREE, BIHTREE};
00032 
00033   // Define virtual base class to derive holder for input processor cuts.
00034   class Cuts {
00035     Cuts(){}
00036     // assignment operator not needed
00037     // copy constructor not needed
00038     virtual ~Cuts();
00039   };
00040 
00041   Algorithm             m_algorithm;
00042   stk::ParallelMachine  m_communicator;
00043   Cuts *                m_cuts;
00044   unsigned *            m_search_tree_stats;
00045   unsigned              m_debug_level;
00046   FactoryOrder() :
00047     m_algorithm        (OCTREE),
00048     m_communicator     (MPI_COMM_SELF),
00049     m_cuts             (NULL),
00050     m_search_tree_stats(NULL),
00051     m_debug_level      (0)
00052   {}
00053 };
00054 
00055 template <class RangeBoundingVolume,class DomainBoundingVolume>
00056 bool parallel_bihtree_search(
00057     std::vector<std::pair<typename DomainBoundingVolume::Key,typename RangeBoundingVolume::Key> > & domain_to_range_keys,
00058     const std::vector<RangeBoundingVolume> &range,
00059     const std::vector<DomainBoundingVolume> &domain,
00060     const FactoryOrder & order)
00061 {
00062 
00063   //find the global box
00064   std::vector<float> global_box(6);
00065   stk::search::box_global_bounds(order.m_communicator,
00066       domain.size() ,
00067       &domain[0] ,
00068       range.size(),
00069       &range[0],
00070       &global_box[0]);
00071 
00072   //
00073   stk::search::oct_tree_bih_tree_proximity_search(order.m_communicator,
00074       &global_box[0],
00075       domain.size() ,
00076       &domain[0] ,
00077       range.size(),
00078       &range[0],
00079       NULL,
00080       domain_to_range_keys ,
00081       order.m_search_tree_stats);
00082 
00083   return true;
00084 }
00085 
00086 
00087 template <class RangeBoundingVolume,class DomainBoundingVolume>
00088 bool coarse_search_bihtree(
00089     std::vector<std::pair<typename DomainBoundingVolume::Key,typename RangeBoundingVolume::Key> > & domain_to_range_keys,
00090     const std::vector<RangeBoundingVolume> &range,
00091     const std::vector<DomainBoundingVolume> &domain,
00092     const FactoryOrder & order)
00093 {
00094   const unsigned p_size = parallel_machine_size( order.m_communicator );
00095   //const unsigned p_rank = parallel_machine_rank( order.m_communicator );
00096 
00097   if (p_size == 1) {
00098     bih::BihTree<RangeBoundingVolume> tree(range.begin(),range.end());
00099     unsigned size = domain.size();
00100     for (unsigned i = 0; i < size ; ++i) {
00101       tree.intersect(domain[i],domain_to_range_keys);
00102     }
00103   }
00104   else {
00105     parallel_bihtree_search(domain_to_range_keys,range,domain,order);
00106   }
00107   return true;
00108 }
00109 
00110 template <class RangeBoundingVolume,class DomainBoundingVolume>
00111 bool coarse_search_octree(
00112     std::vector<std::pair<typename DomainBoundingVolume::Key,typename RangeBoundingVolume::Key> > & domain_to_range_keys,
00113     const std::vector<RangeBoundingVolume> &range,
00114     const std::vector<DomainBoundingVolume> &domain,
00115     const FactoryOrder & order)
00116 {
00117 
00118   std::vector<float> global_box(6);
00119   stk::search::box_global_bounds(order.m_communicator,
00120       domain.size() ,
00121       &domain[0] ,
00122       range.size(),
00123       &range[0],
00124       &global_box[0]);
00125 
00126   stk::search::oct_tree_proximity_search(order.m_communicator,
00127       &global_box[0],
00128       domain.size() ,
00129       &domain[0] ,
00130       range.size(),
00131       &range[0],
00132       NULL,
00133       domain_to_range_keys ,
00134       order.m_search_tree_stats);
00135   return true;
00136 }
00137 
00138 template <class RangeBoundingVolume,class DomainBoundingVolume>
00139 bool coarse_search(
00140     std::vector<std::pair<typename DomainBoundingVolume::Key,typename RangeBoundingVolume::Key> > & domain_to_range_keys,
00141     const  std::vector<RangeBoundingVolume> &range,
00142     const std::vector<DomainBoundingVolume> &domain,
00143     const FactoryOrder & order)
00144 {
00145   switch (order.m_algorithm) {
00146     case FactoryOrder::BIHTREE:
00147       return coarse_search_bihtree(domain_to_range_keys,range,domain,order);
00148     case FactoryOrder::OCTREE:
00149       return coarse_search_octree(domain_to_range_keys,range,domain,order);
00150    break;
00151   }
00152   return false;
00153 }
00154 
00155 
00156 } // namespace search
00157 } // namespace stk
00158 
00159 #endif // stk_search_CoarseSearch_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends