|
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 #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