|
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_BihTreeParallelOps_hpp 00010 #define stk_search_BihTreeParallelOps_hpp 00011 00012 #include <stk_search/BihTree.hpp> 00013 #include <stk_search/BoundingBox.hpp> 00014 #include <stk_search/IdentProc.hpp> 00015 #include <stk_search/OctTreeOps.hpp> 00016 00017 namespace stk { 00018 namespace search { 00019 00020 template <class DomainBoundingBox, class RangeBoundingBox> 00021 bool oct_tree_bih_tree_proximity_search( 00022 ParallelMachine arg_comm , 00023 const float * const arg_global_box , 00024 const size_t arg_domain_boxes_number , 00025 const DomainBoundingBox * const arg_domain_boxes , 00026 const size_t arg_range_boxes_number , 00027 const RangeBoundingBox * const arg_range_boxes , 00028 const OctTreeKey * const arg_cuts , 00029 std::vector< std::pair< typename DomainBoundingBox::Key, typename RangeBoundingBox::Key > > & arg_relation , 00030 unsigned * const arg_search_tree_stats = NULL ) 00031 { 00032 typedef typename DomainBoundingBox::Key DomainKey; 00033 typedef typename RangeBoundingBox::Key RangeKey; 00034 typedef std::map< stk::OctTreeKey, std::pair< std::list< DomainBoundingBox >, std::list< RangeBoundingBox > > > SearchTree ; 00035 00036 enum { Dim = 3 }; 00037 00038 const unsigned p_rank = parallel_machine_rank( arg_comm ); 00039 00040 //---------------------------------------------------------------------- 00041 // Search tree defined by oct-tree covering for boxes 00042 00043 bool local_violations = false ; 00044 bool global_violations = false ; 00045 00046 SearchTree search_tree ; 00047 00048 { 00049 stk::OctTreeKey covering[8] ; 00050 unsigned number = 0 ; 00051 00052 double scale = arg_global_box[0+Dim] - arg_global_box[0]; 00053 for ( unsigned i = 1 ; i < Dim ; ++i ) { 00054 double tst_scale = arg_global_box[i+Dim] - arg_global_box[i]; 00055 if (tst_scale > scale) scale = tst_scale; 00056 } 00057 if (scale > 0.0) // Not an error. Could arise with a point bounding box in the range/domain... 00058 scale = 1.0 / scale; 00059 else 00060 scale = 1.0; 00061 00062 for ( size_t i = 0 ; i < arg_domain_boxes_number ; ++i ) { 00063 00064 DomainBoundingBox tmp( arg_domain_boxes[i] ); 00065 00066 tmp.key.proc = p_rank ; 00067 00068 float box[6]; 00069 00070 for (int x=0; x<Dim; ++x) { 00071 box[x] = tmp.lower(x); 00072 box[x+Dim] = tmp.upper(x); 00073 } 00074 00075 const bool valid = 00076 hsfc_box_covering( arg_global_box, box, covering, number, scale ); 00077 00078 if ( ! valid ) { local_violations = true ; } 00079 00080 for ( unsigned k = 0 ; k < number ; ++k ) { 00081 const stk::OctTreeKey key = covering[k] ; 00082 search_tree[key].first.push_back(tmp); 00083 } 00084 } 00085 00086 for ( size_t i = 0 ; i < arg_range_boxes_number ; ++i ) { 00087 00088 RangeBoundingBox tmp( arg_range_boxes[i] ); 00089 00090 tmp.key. proc = p_rank ; 00091 00092 float box[6]; 00093 00094 for (int x=0; x<Dim; ++x) { 00095 box[x] = tmp.lower(x); 00096 box[x+Dim] = tmp.upper(x); 00097 } 00098 00099 const bool valid = 00100 hsfc_box_covering( arg_global_box, box, covering, number, scale ); 00101 00102 if ( ! valid ) { local_violations = true ; } 00103 00104 for ( unsigned k = 0 ; k < number ; ++k ) { 00105 const stk::OctTreeKey key = covering[k] ; 00106 search_tree[key].second.push_back(tmp); 00107 } 00108 } 00109 } 00110 00111 //---------------------------------------------------------------------- 00112 // Use a set to provide a unique and sorted result. 00113 00114 std::set< std::pair<DomainKey, RangeKey> > tmp_relation ; 00115 00116 { 00117 // Communicate search_tree members 00118 00119 SearchTree local_tree ; 00120 00121 std::set< std::pair<DomainKey, RangeKey> > local_relation ; 00122 00123 if ( arg_cuts ) { 00124 global_violations = 00125 communicate<DomainBoundingBox, RangeBoundingBox>( arg_comm , arg_cuts , search_tree , local_tree , 00126 local_violations ); 00127 } 00128 else { 00129 const double tolerance = 0.001 ; 00130 00131 std::vector< stk::OctTreeKey > cuts ; 00132 00133 oct_tree_partition( arg_comm , search_tree , tolerance , cuts ); 00134 00135 global_violations = 00136 communicate<DomainBoundingBox, RangeBoundingBox>(arg_comm , & cuts[0] , search_tree , local_tree , 00137 local_violations ); 00138 } 00139 00140 // Local proximity search with received members 00141 00142 if ( arg_search_tree_stats ) { 00143 search_tree_statistics( arg_comm , local_tree , 00144 arg_search_tree_stats ); 00145 } 00146 00147 std::set<DomainBoundingBox, stk::search::box::compare::Compare< DomainBoundingBox, box::compare::KEY> > domain; 00148 std::set<RangeBoundingBox, stk::search::box::compare::Compare< RangeBoundingBox , box::compare::KEY> > range; 00149 00150 for (typename SearchTree::iterator i = local_tree.begin(); i != local_tree.end(); ++i) { 00151 //insert domain list 00152 std::list<DomainBoundingBox> & domain_list = i->second.first; 00153 for (typename std::list<DomainBoundingBox>::iterator j = domain_list.begin(); j != domain_list.end(); ++j) 00154 domain.insert(*j); 00155 00156 //insert range list 00157 std::list<RangeBoundingBox> & range_list = i->second.second; 00158 for (typename std::list<RangeBoundingBox>::iterator j = range_list.begin(); j != range_list.end(); ++j) 00159 range.insert(*j); 00160 } 00161 00162 stk::search::bih::BihTree<RangeBoundingBox> tree(range.begin(),range.end()); 00163 for (typename std::set<DomainBoundingBox, box::compare::Compare<DomainBoundingBox,box::compare::KEY> >::iterator i = domain.begin(); 00164 i != domain.end() ; ++i) 00165 { 00166 tree.intersect(*i,local_relation); 00167 } 00168 00169 00170 00171 00172 // Communicate relations back to domain and range processors 00173 00174 communicate<DomainBoundingBox,RangeBoundingBox>( arg_comm , local_relation , tmp_relation ); 00175 } 00176 00177 arg_relation.clear(); 00178 arg_relation.reserve( tmp_relation.size() ); 00179 00180 typename std::set< std::pair<DomainKey,RangeKey> >::iterator ir ; 00181 for ( ir = tmp_relation.begin() ; ir != tmp_relation.end() ; ++ir ) { 00182 arg_relation.push_back( *ir ); 00183 } 00184 return global_violations ; 00185 } 00186 00187 } //namespace search 00188 } //namespace stk 00189 #endif //stk_search_BihTreeParallelOps_hpp