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 = e->bucket().mesh().mesh_meta_data();
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::raw_attr_type
00049 Relation::attribute( unsigned rank , unsigned id )
00050 {
00051   if ( id_mask < id ) {
00052     std::ostringstream msg ;
00053     msg << "stk::mesh::Relation::attribute( " ;
00054     msg << rank << " , " << id << " ) FAILED : " ;
00055     msg << id << " > " << id_mask ;
00056     throw std::runtime_error( msg.str() );
00057   }
00058 
00059   return ( raw_attr_type(rank) << rank_shift ) | id ;
00060 }
00061 
00062 Relation::Relation( Entity & entity , unsigned identifier )
00063   : m_attr( Relation::attribute( entity.entity_rank() , identifier ) ),
00064     m_entity( & entity )
00065 {}
00066 
00067 Relation::Relation( Relation::raw_attr_type attr , Entity & entity )
00068   : m_attr( attr ), m_entity( & entity )
00069 {
00070   if ( entity_rank() != entity.entity_rank() ) {
00071     std::ostringstream msg ;
00072     msg << "stk::mesh::Relation::Relation( "  ;
00073     msg << *this ;
00074     msg << " ) INCOMPATIBLE ARGUMENTS" ;
00075     throw std::invalid_argument( msg.str() );
00076   }
00077 }
00078 
00079 bool Relation::operator < ( const Relation & r ) const
00080 {
00081   bool result = false;
00082 
00083   if ( m_attr.value != r.m_attr.value ) {
00084     result = m_attr.value < r.m_attr.value ;
00085   }
00086   else {
00087     const EntityKey lhs = m_entity   ? m_entity->key()   : EntityKey() ;
00088     const EntityKey rhs = r.m_entity ? r.m_entity->key() : EntityKey() ;
00089     result = lhs < rhs ;
00090   }
00091   return result ;
00092 }
00093 
00094 //----------------------------------------------------------------------
00095 
00096 namespace {
00097 
00098 void get_entities_through_relations(
00099   PairIterRelation rel ,
00100   const std::vector<Entity*>::const_iterator i_beg ,
00101   const std::vector<Entity*>::const_iterator i_end ,
00102   std::vector<Entity*> & entities_related )
00103 {
00104   for ( ; rel.first != rel.second ; ++rel.first ) {
00105 
00106     // Do all input entities have a relation to this entity ?
00107 
00108     Entity * const e = rel.first->entity();
00109 
00110     std::vector<Entity*>::const_iterator i = i_beg ;
00111 
00112     for ( ; i != i_end ; ++i ) {
00113       PairIterRelation r = (*i)->relations();
00114       while ( r.first != r.second && e != r.first->entity() ) {
00115         ++r.first ;
00116       }
00117       if ( r.first == r.second ) { break ; }
00118     }
00119 
00120     if ( i == i_end ) {
00121       entities_related.push_back( e );
00122     }
00123   }
00124 }
00125 
00126 }
00127 
00128 void get_entities_through_relations(
00129   const std::vector<Entity*> & entities ,
00130         std::vector<Entity*> & entities_related )
00131 {
00132   entities_related.clear();
00133 
00134   if ( ! entities.empty() ) {
00135           std::vector<Entity*>::const_iterator i = entities.begin();
00136     const std::vector<Entity*>::const_iterator j = entities.end();
00137 
00138     PairIterRelation rel = (*i)->relations(); ++i ;
00139 
00140     get_entities_through_relations( rel , i , j , entities_related );
00141   }
00142 }
00143 
00144 void get_entities_through_relations(
00145   const std::vector<Entity*> & entities ,
00146         unsigned               entities_related_rank ,
00147         std::vector<Entity*> & entities_related )
00148 {
00149   entities_related.clear();
00150 
00151   if ( ! entities.empty() ) {
00152           std::vector<Entity*>::const_iterator i = entities.begin();
00153     const std::vector<Entity*>::const_iterator j = entities.end();
00154 
00155     PairIterRelation rel = (*i)->relations( entities_related_rank ); ++i ;
00156 
00157     get_entities_through_relations( rel , i , j , entities_related );
00158   }
00159 }
00160 
00161 //----------------------------------------------------------------------
00162 
00166 bool membership_is_induced( const Part & part , unsigned entity_rank )
00167 {
00168   const MetaData & meta = part.mesh_meta_data();
00169 
00170   const bool induced_by_type =
00171      entity_rank < part.primary_entity_rank() &&
00172                    part.primary_entity_rank() < meta.entity_rank_count() ;
00173 
00174   const bool induced_by_stencil =
00175     ! part.relations().empty() &&
00176       part.relations().begin()->m_target == & part ;
00177 
00178   return induced_by_type || induced_by_stencil ;
00179 }
00180 
00181 //----------------------------------------------------------------------
00182 
00183 void induced_part_membership( Part & part ,
00184                               unsigned entity_rank_from ,
00185                               unsigned entity_rank_to ,
00186                               unsigned relation_identifier ,
00187                               PartVector & induced_parts )
00188 {
00189   if ( entity_rank_to < entity_rank_from &&
00190        part.primary_entity_rank() == entity_rank_from ) {
00191 
00192     // Direct relationship:
00193 
00194     insert( induced_parts , part );
00195 
00196     // Stencil relationship where 'part' is the root:
00197     // The 'target' should not have subsets or supersets.
00198 
00199     const std::vector<PartRelation> & part_rel = part.relations();
00200 
00201     for ( std::vector<PartRelation>::const_iterator
00202           j = part_rel.begin() ; j != part_rel.end() ; ++j ) {
00203 
00204       if ( & part == j->m_root &&
00205            0 <= (* j->m_function)( entity_rank_from , entity_rank_to ,
00206                                    relation_identifier ) ) {
00207         insert( induced_parts , * j->m_target );
00208       }
00209     }
00210   }
00211 }
00212 
00213 //----------------------------------------------------------------------
00214 //  What are this entity's part memberships that can be deduced from
00215 //  this entity's relationship.  Can only trust 'entity_from' to be
00216 //  accurate if it is owned by the local process.
00217 
00218 void induced_part_membership( const Entity     & entity_from ,
00219                               const PartVector & omit ,
00220                                     unsigned     entity_rank_to ,
00221                                     unsigned     relation_identifier ,
00222                                     PartVector & entity_to_parts )
00223 {
00224   const Bucket   & bucket_from    = entity_from.bucket();
00225   const BulkData & mesh           = bucket_from.mesh();
00226   const unsigned local_proc_rank  = mesh.parallel_rank();
00227   const unsigned entity_rank_from = entity_from.entity_rank();
00228 
00229   if ( entity_rank_to < entity_rank_from &&
00230        local_proc_rank == entity_from.owner_rank() ) {
00231     const MetaData   & meta        = mesh.mesh_meta_data();
00232     const PartVector & all_parts   = meta.get_parts();
00233 
00234     const std::pair<const unsigned *, const unsigned *>
00235       bucket_superset_ordinals = bucket_from.superset_part_ordinals();
00236 
00237     // Contributions of the 'from' entity:
00238 
00239     for ( const unsigned * i = bucket_superset_ordinals.first ;
00240                            i < bucket_superset_ordinals.second ; ++i ) {
00241 
00242       Part & part = * all_parts[*i] ;
00243 
00244       if ( ! contain( omit , part ) ) {
00245         induced_part_membership( part,
00246                                  entity_rank_from ,
00247                                  entity_rank_to ,
00248                                  relation_identifier ,
00249                                  entity_to_parts );
00250       }
00251     }
00252   }
00253 }
00254 
00255 //----------------------------------------------------------------------
00256 
00257 void induced_part_membership( const Entity     & entity ,
00258                               const PartVector & omit ,
00259                                     PartVector & induced )
00260 {
00261   for ( PairIterRelation
00262         rel = entity.relations() ; ! rel.empty() ; ++rel ) {
00263 
00264     induced_part_membership( * rel->entity() , omit ,
00265                              entity.entity_rank() ,
00266                              rel->identifier() ,
00267                              induced );
00268   }
00269 }
00270 
00271 //----------------------------------------------------------------------
00272 
00273 } // namespace mesh
00274 } // namespace stk
00275 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends