|
Sierra Toolkit Version of the Day
|
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