|
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 <algorithm> 00010 #include <sstream> 00011 #include <stdexcept> 00012 00013 #include <stk_mesh/base/Ghosting.hpp> 00014 #include <stk_mesh/base/Bucket.hpp> 00015 #include <stk_mesh/base/BulkData.hpp> 00016 #include <stk_mesh/base/MetaData.hpp> 00017 00018 #include <stk_mesh/baseImpl/EntityImpl.hpp> 00019 00020 namespace stk_classic { 00021 namespace mesh { 00022 namespace impl { 00023 00024 00025 PairIterRelation EntityImpl::relations( unsigned rank ) const 00026 { 00027 RelationVector::const_iterator i = m_relation.begin(); 00028 RelationVector::const_iterator e = m_relation.end(); 00029 00030 //Nodes 00031 if ( rank != 0 ) { 00032 const Relation::raw_relation_id_type lo_attr = Relation::raw_relation_id( rank , 0 ); 00033 i = std::lower_bound( i , e , lo_attr , LessRelation() ); 00034 } 00035 00036 const Relation::raw_relation_id_type hi_attr = Relation::raw_relation_id( rank + 1 , 0 ); 00037 e = std::lower_bound( i , e , hi_attr , LessRelation() ); 00038 00039 return PairIterRelation( i , e ); 00040 } 00041 00042 00043 namespace { 00044 00045 inline bool is_degenerate_relation ( const Relation &r1 , const Relation &r2 ) 00046 { 00047 return r1.raw_relation_id() == r2.raw_relation_id() && r1.entity() != r2.entity() ; 00048 } 00049 00050 } 00051 00052 void EntityImpl::log_resurrect() 00053 { 00054 TraceIfWatching("stk_classic::mesh::impl::EntityImpl::log_resurrect", LOG_ENTITY, key()); 00055 00056 ThrowErrorMsgIf( EntityLogDeleted != m_mod_log, 00057 "Trying to resurrect non-deleted entity: " << 00058 print_entity_key( MetaData::get( bucket() ), key() ) ); 00059 00060 m_mod_log = EntityLogModified; 00061 m_bucket = NULL; 00062 } 00063 00064 void EntityImpl::log_modified_and_propagate() 00065 { 00066 TraceIfWatching("stk_classic::mesh::impl::EntityImpl::log_modified_and_propagate", LOG_ENTITY, key()); 00067 00068 // If already in modified state, return 00069 if (m_mod_log != EntityLogNoChange) { 00070 return; 00071 } 00072 00073 // mark this entity as modified 00074 m_mod_log = EntityLogModified; 00075 00076 // recurse on related entities w/ higher rank 00077 EntityRank rank_of_original_entity = entity_rank(); 00078 for ( PairIterRelation irel = relations() ; irel.first != irel.second ; ) { 00079 --irel.second; 00080 Entity & entity = *(irel.second->entity()); 00081 if ( rank_of_original_entity >= entity.entity_rank() ) { 00082 break; //we're done 00083 } 00084 else if ( entity.log_query() == EntityLogNoChange ) { 00085 entity.m_entityImpl.log_modified_and_propagate(); 00086 } 00087 } 00088 00089 } 00090 00091 void EntityImpl::compress_relation_capacity() 00092 { 00093 RelationVector tmp(m_relation); 00094 tmp.swap(m_relation); 00095 } 00096 00097 void EntityImpl::log_created_parallel_copy() 00098 { 00099 TraceIfWatching("stk_classic::mesh::impl::EntityImpl::log_created_parallel_copy", LOG_ENTITY, key()); 00100 00101 if ( EntityLogCreated == m_mod_log ) { 00102 m_mod_log = EntityLogModified ; 00103 } 00104 } 00105 00106 bool EntityImpl::destroy_relation( Entity& e_to, const RelationIdentifier local_id ) 00107 { 00108 TraceIfWatching("stk_classic::mesh::impl::EntityImpl::destroy_relation", LOG_ENTITY, key()); 00109 00110 bool destroyed_relations = false; 00111 for ( RelationVector::iterator 00112 i = m_relation.begin() ; i != m_relation.end() ; ++i ) { 00113 if ( i->entity() == & e_to && i->identifier() == local_id ) { 00114 i = m_relation.erase( i ); // invalidates iterators, but we're breaking so it's OK 00115 destroyed_relations = true; 00116 break; 00117 } 00118 } 00119 return destroyed_relations; 00120 } 00121 00122 bool EntityImpl::declare_relation( Entity & e_to, 00123 const RelationIdentifier local_id, 00124 unsigned sync_count, 00125 bool is_back_relation ) 00126 { 00127 TraceIfWatching("stk_classic::mesh::impl::EntityImpl::declare_relation", LOG_ENTITY, key()); 00128 00129 const MetaData & meta_data = MetaData::get( bucket() ); 00130 00131 Relation new_relation( e_to , local_id ); 00132 #ifdef SIERRA_MIGRATION 00133 new_relation.setRelationType( e_to.entity_rank() > entity_rank() ? Relation::USED_BY : Relation::USES ); 00134 new_relation.setOrientation(0); 00135 #endif 00136 00137 const RelationVector::iterator rel_end = m_relation.end(); 00138 RelationVector::iterator rel_begin = m_relation.begin(); 00139 RelationVector::iterator lower; 00140 00141 lower = std::lower_bound( rel_begin , rel_end , new_relation , LessRelation() ); 00142 00143 // The ordering of the Relations allows for two situations that do 00144 // not arise often in meshes. The first situation is 2 relations between 00145 // e_from and e_to with the same kind but different local_ids. This 00146 // can happen if, for example, a triangle should be used as a quad. In 00147 // this case, one node of the triangle must be two different local nodes of 00148 // the quad. This situation is a valid state of mesh entities. 00149 00150 // The second situation involves malformed stencils. Given e_from, e_to1, 00151 // and e_to2, e_to1 and eto2 can share a relation with e_from with the same 00152 // kind and local_id. This can arise, for instance, if an edge has three 00153 // nodes. The local_id 1 of the edge may point to two different nodes. 00154 // This situation is disallowed in the mesh. We now check for it. 00155 00156 // "Degenerate" -> case where we have two relations whose attributes 00157 // (rel id + rel rank) match but point to different entities. It's 00158 // OK for back-relations to be degenerate because there's nothing 00159 // wrong with a node having several back-relations (with similar id) 00160 // to different elements. 00161 00162 // Check for bad degenerate relations (degenerate forward relations) 00163 // Cannot be degenerate relation if there are no prior relations 00164 if ( !m_relation.empty() && !is_back_relation ) { 00165 // Since LessRelation takes the related entity into account, we must check 00166 // the result of lower_bound AND the iter before to be sure this isn't a 00167 // bad degenerate relation. 00168 RelationVector::iterator start, end; 00169 start = (lower == rel_begin) ? rel_begin : lower - 1; 00170 end = (lower == rel_end) ? rel_end : lower + 1; 00171 00172 for (RelationVector::iterator itr = start; itr != end; ++itr) { 00173 ThrowErrorMsgIf( is_degenerate_relation ( new_relation , *itr ), 00174 "Could not declare relation from " << 00175 print_entity_key( meta_data, key() ) << " to " << 00176 print_entity_key( meta_data, e_to.key() ) << ", with id " << 00177 local_id << ". Relation already exists to " << 00178 print_entity_key( meta_data, itr->entity()->key() )); 00179 } 00180 } 00181 00182 bool not_already_exists = (rel_end == lower) || 00183 ( !is_back_relation && new_relation.raw_relation_id() != lower->raw_relation_id() ) || 00184 ( is_back_relation && new_relation != *lower ); 00185 00186 // If the relation does not already exist, we add it 00187 if (not_already_exists) { 00188 lower = m_relation.insert( lower , new_relation ); 00189 00190 set_sync_count( sync_count ); 00191 00192 return true; 00193 } 00194 else { 00195 return false; 00196 } 00197 } 00198 00199 void EntityImpl::set_key(EntityKey key) 00200 { 00201 m_key = key; 00202 } 00203 00204 void EntityImpl::update_key(EntityKey key) 00205 { 00206 m_key = key; 00207 00208 std::sort(m_relation.begin(), m_relation.end(), LessRelation()); 00209 log_modified_and_propagate(); 00210 00211 for ( RelationVector::iterator i = m_relation.begin(), e = m_relation.end(); 00212 i != e; 00213 ++i 00214 ) 00215 { 00216 EntityImpl & entity = i->entity()->m_entityImpl; 00217 std::sort(entity.m_relation.begin(), entity.m_relation.end(), LessRelation()); 00218 entity.log_modified_and_propagate(); 00219 } 00220 00221 } 00222 00223 PairIterEntityComm EntityImpl::comm() const 00224 { 00225 return BulkData::get(bucket()).entity_comm(m_key); 00226 } 00227 00228 PairIterEntityComm EntityImpl::sharing() const 00229 { 00230 return BulkData::get(bucket()).entity_comm_sharing(m_key); 00231 } 00232 00233 PairIterEntityComm EntityImpl::comm( const Ghosting & sub ) const 00234 { 00235 return BulkData::get(bucket()).entity_comm(m_key,sub); 00236 } 00237 00238 bool EntityImpl::insert( const EntityCommInfo & val ) 00239 { 00240 return BulkData::get(bucket()).entity_comm_insert(m_key,val); 00241 } 00242 00243 bool EntityImpl::erase( const EntityCommInfo & val ) 00244 { 00245 return BulkData::get(bucket()).entity_comm_erase(m_key,val); 00246 } 00247 00248 bool EntityImpl::erase( const Ghosting & ghost ) 00249 { 00250 return BulkData::get(bucket()).entity_comm_erase(m_key,ghost); 00251 } 00252 00253 void EntityImpl::comm_clear_ghosting() 00254 { 00255 return BulkData::get(bucket()).entity_comm_clear_ghosting(m_key); 00256 } 00257 00258 void EntityImpl::comm_clear() 00259 { 00260 return BulkData::get(bucket()).entity_comm_clear(m_key); 00261 } 00262 00263 } // namespace impl 00264 } // namespace mesh 00265 } // namespace stk_classic 00266