Sierra Toolkit Version of the Day
BihTreeParallelOps.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_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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends