Sierra Toolkit Version of the Day
EntityImpl.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 <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 {
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::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::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::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::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::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
00266 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines