Sierra Toolkit Version of the Day
Relation.cpp
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 #include <stdexcept>
00010 #include <iostream>
00011 #include <sstream>
00012 #include <algorithm>
00013 
00014 #include <stk_mesh/base/MetaData.hpp>
00015 #include <stk_mesh/base/BulkData.hpp>
00016 #include <stk_mesh/base/Entity.hpp>
00017 #include <stk_mesh/base/Bucket.hpp>
00018 #include <stk_mesh/base/Relation.hpp>
00019 #include <stk_mesh/base/FieldData.hpp>
00020 
00021 namespace stk {
00022 namespace mesh {
00023 
00024 //----------------------------------------------------------------------
00025 
00026 std::ostream &
00027 operator << ( std::ostream & s , const Relation & rel )
00028 {
00029   Entity * const e = rel.entity();
00030 
00031   if ( e ) {
00032     const MetaData & meta_data = MetaData::get(*e);
00033 
00034     s << meta_data.entity_rank_name( rel.entity_rank() );
00035     s << "[" << rel.identifier() << "]->" ;
00036     print_entity_key( s , meta_data , e->key() );
00037   }
00038   else {
00039     s << rel.entity_rank();
00040     s << "[" << rel.identifier() << "]->NULL" ;
00041   }
00042 
00043   return s ;
00044 }
00045 
00046 //----------------------------------------------------------------------
00047 
00048 Relation::Relation( Entity & entity , RelationIdentifier identifier )
00049   : m_raw_relation( Relation::raw_relation_id( entity.entity_rank() , identifier ) ),
00050     m_entity( & entity )
00051 {}
00052 
00053 
00054 bool Relation::operator < ( const Relation & r ) const
00055 {
00056   bool result = false;
00057 
00058   if ( m_raw_relation.value != r.m_raw_relation.value ) {
00059     result = m_raw_relation.value < r.m_raw_relation.value ;
00060   }
00061   else {
00062     const EntityKey lhs = m_entity   ? m_entity->key()   : EntityKey() ;
00063     const EntityKey rhs = r.m_entity ? r.m_entity->key() : EntityKey() ;
00064     result = lhs < rhs ;
00065   }
00066   return result ;
00067 }
00068 
00069 //----------------------------------------------------------------------
00070 
00071 namespace {
00072 
00073 void get_entities_through_relations(
00074   PairIterRelation rel ,
00075   const std::vector<Entity*>::const_iterator i_beg ,
00076   const std::vector<Entity*>::const_iterator i_end ,
00077   std::vector<Entity*> & entities_related )
00078 {
00079   for ( ; rel.first != rel.second ; ++rel.first ) {
00080 
00081     // Do all input entities have a relation to this entity ?
00082 
00083     Entity * const e = rel.first->entity();
00084 
00085     std::vector<Entity*>::const_iterator i = i_beg ;
00086 
00087     for ( ; i != i_end ; ++i ) {
00088       PairIterRelation r = (*i)->relations();
00089       while ( r.first != r.second && e != r.first->entity() ) {
00090         ++r.first ;
00091       }
00092       if ( r.first == r.second ) { break ; }
00093     }
00094 
00095     if ( i == i_end ) {
00096       entities_related.push_back( e );
00097     }
00098   }
00099 }
00100 
00101 }
00102 
00103 void get_entities_through_relations(
00104   const std::vector<Entity*> & entities ,
00105         std::vector<Entity*> & entities_related )
00106 {
00107   entities_related.clear();
00108 
00109   if ( ! entities.empty() ) {
00110           std::vector<Entity*>::const_iterator i = entities.begin();
00111     const std::vector<Entity*>::const_iterator j = entities.end();
00112 
00113     PairIterRelation rel = (*i)->relations(); ++i ;
00114 
00115     get_entities_through_relations( rel , i , j , entities_related );
00116   }
00117 }
00118 
00119 void get_entities_through_relations(
00120   const std::vector<Entity*> & entities ,
00121         unsigned               entities_related_rank ,
00122         std::vector<Entity*> & entities_related )
00123 {
00124   entities_related.clear();
00125 
00126   if ( ! entities.empty() ) {
00127           std::vector<Entity*>::const_iterator i = entities.begin();
00128     const std::vector<Entity*>::const_iterator j = entities.end();
00129 
00130     PairIterRelation rel = (*i)->relations( entities_related_rank ); ++i ;
00131 
00132     get_entities_through_relations( rel , i , j , entities_related );
00133   }
00134 }
00135 
00136 //----------------------------------------------------------------------
00137 
00141 bool membership_is_induced( const Part & part , unsigned entity_rank )
00142 {
00143   const MetaData & meta = MetaData::get(part);
00144 
00145   const bool induced_by_type =
00146      entity_rank < part.primary_entity_rank() &&
00147                    part.primary_entity_rank() < meta.entity_rank_count() ;
00148 
00149   const bool induced_by_stencil =
00150     ! part.relations().empty() &&
00151       part.relations().begin()->m_target == & part ;
00152 
00153   return induced_by_type || induced_by_stencil ;
00154 }
00155 
00156 //----------------------------------------------------------------------
00157 
00158 void induced_part_membership( Part & part ,
00159                               unsigned entity_rank_from ,
00160                               unsigned entity_rank_to ,
00161                               RelationIdentifier relation_identifier ,
00162                               PartVector & induced_parts )
00163 {
00164   if ( entity_rank_to < entity_rank_from &&
00165        part.primary_entity_rank() == entity_rank_from ) {
00166 
00167     // Direct relationship:
00168 
00169     insert( induced_parts , part );
00170 
00171     // Stencil relationship where 'part' is the root:
00172     // The 'target' should not have subsets or supersets.
00173 
00174     const std::vector<PartRelation> & part_rel = part.relations();
00175 
00176     for ( std::vector<PartRelation>::const_iterator
00177           j = part_rel.begin() ; j != part_rel.end() ; ++j ) {
00178 
00179       if ( & part == j->m_root &&
00180            0 <= (* j->m_function)( entity_rank_from , entity_rank_to ,
00181                                    relation_identifier ) ) {
00182         insert( induced_parts , * j->m_target );
00183       }
00184     }
00185   }
00186 }
00187 
00188 //----------------------------------------------------------------------
00189 //  What are this entity's part memberships that can be deduced from
00190 //  this entity's relationship.  Can only trust 'entity_from' to be
00191 //  accurate if it is owned by the local process.
00192 
00193 void induced_part_membership( const Entity           & entity_from ,
00194                               const PartVector       & omit ,
00195                                     unsigned           entity_rank_to ,
00196                                     RelationIdentifier relation_identifier ,
00197                                     PartVector       & induced_parts )
00198 {
00199   const Bucket   & bucket_from    = entity_from.bucket();
00200   const BulkData & mesh           = BulkData::get(bucket_from);
00201   const unsigned local_proc_rank  = mesh.parallel_rank();
00202   const unsigned entity_rank_from = entity_from.entity_rank();
00203 
00204   // Only induce parts for normal (not back) relations. Can only trust
00205   // 'entity_from' to be accurate if it is owned by the local process.
00206   if ( entity_rank_to < entity_rank_from &&
00207        local_proc_rank == entity_from.owner_rank() ) {
00208     const MetaData   & meta        = MetaData::get(mesh);
00209     const PartVector & all_parts   = meta.get_parts();
00210 
00211     const std::pair<const unsigned *, const unsigned *>
00212       bucket_superset_ordinals = bucket_from.superset_part_ordinals();
00213 
00214     // Contributions of the 'from' entity:
00215     for ( const unsigned * i = bucket_superset_ordinals.first ;
00216                            i != bucket_superset_ordinals.second ; ++i ) {
00217       ThrowAssertMsg( *i < all_parts.size(), "Index " << *i << " out of bounds" );
00218       Part & part = * all_parts[*i] ;
00219 
00220       if ( part.primary_entity_rank() == entity_rank_from &&
00221            ! contain( omit , part )) {
00222         induced_part_membership( part,
00223                                  entity_rank_from ,
00224                                  entity_rank_to ,
00225                                  relation_identifier ,
00226                                  induced_parts );
00227       }
00228     }
00229   }
00230 }
00231 
00232 //----------------------------------------------------------------------
00233 
00234 void induced_part_membership( const Entity     & entity ,
00235                               const PartVector & omit ,
00236                                     PartVector & induced_parts )
00237 {
00238   for ( PairIterRelation
00239         rel = entity.relations() ; ! rel.empty() ; ++rel ) {
00240 
00241     induced_part_membership( * rel->entity() , omit ,
00242                              entity.entity_rank() ,
00243                              rel->identifier() ,
00244                              induced_parts );
00245   }
00246 }
00247 
00248 //----------------------------------------------------------------------
00249 
00250 } // namespace mesh
00251 } // namespace stk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends