Sierra Toolkit Version of the Day
EntityRepository.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 <sstream>
00010 #include <stdexcept>
00011 
00012 #include <stk_mesh/baseImpl/EntityRepository.hpp>
00013 #include <stk_mesh/base/Bucket.hpp>
00014 #include <stk_mesh/base/BulkData.hpp>
00015 #include <stk_mesh/base/MetaData.hpp>
00016 
00017 namespace stk {
00018 namespace mesh {
00019 namespace impl {
00020 
00021 EntityRepository::~EntityRepository()
00022 {
00023   try {
00024     while ( ! m_entities.empty() ) {
00025       internal_expunge_entity( m_entities.begin() );
00026     }
00027   } catch(...){}
00028 }
00029 
00030 void EntityRepository::internal_expunge_entity( EntityMap::iterator i )
00031 {
00032   TraceIfWatching("stk::mesh::impl::EntityRepository::internal_expunge_entity", LOG_ENTITY, i->first);
00033 
00034   ThrowErrorMsgIf( i->second == NULL,
00035                    "For key " << entity_rank(i->first) << " " <<
00036                    entity_id(i->first) << ", value was NULL");
00037 
00038   ThrowErrorMsgIf( i->first != i->second->key(),
00039     "Key " << print_entity_key(MetaData::get( *i->second ), i->first) <<
00040     " != " << print_entity_key(i->second));
00041 
00042   delete i->second ;
00043   i->second = NULL ;
00044   m_entities.erase( i );
00045 }
00046 
00047 std::pair<Entity*,bool>
00048 EntityRepository::internal_create_entity( const EntityKey & key )
00049 {
00050   TraceIfWatching("stk::mesh::impl::EntityRepository::internal_create_entity", LOG_ENTITY, key);
00051 
00052   EntityMap::value_type tmp(key,NULL);
00053 
00054   const std::pair< EntityMap::iterator , bool >
00055     insert_result = m_entities.insert( tmp );
00056 
00057   std::pair<Entity*,bool>
00058     result( insert_result.first->second , insert_result.second );
00059 
00060   if ( insert_result.second )  { // A new entity
00061     insert_result.first->second = result.first = new Entity( key );
00062   }
00063   else if ( EntityLogDeleted == result.first->log_query() ) {
00064     // resurrection
00065     result.first->m_entityImpl.log_resurrect();
00066     result.second = true;
00067   }
00068 
00069   return result ;
00070 }
00071 
00072 void EntityRepository::log_created_parallel_copy( Entity & entity )
00073 {
00074   TraceIfWatching("stk::mesh::impl::EntityRepository::log_created_parallel_copy", LOG_ENTITY, entity.key());
00075 
00076   entity.m_entityImpl.log_created_parallel_copy();
00077 }
00078 
00079 Entity * EntityRepository::get_entity(const EntityKey &key) const
00080 {
00081   ThrowErrorMsgIf( ! entity_key_valid( key ),
00082       "Invalid key: " << entity_rank(key) << " " << entity_id(key));
00083 
00084   const EntityMap::const_iterator i = m_entities.find( key );
00085 
00086   return i != m_entities.end() ? i->second : NULL ;
00087 }
00088 
00089 void EntityRepository::clean_changes()
00090 {
00091   TraceIf("stk::mesh::impl::EntityRepository::clean_changes", LOG_ENTITY);
00092 
00093   for ( EntityMap::iterator
00094       i = m_entities.begin() ; i != m_entities.end() ; )
00095   {
00096     const EntityMap::iterator j = i ;
00097     ++i ;
00098 
00099     if ( j->second->m_entityImpl.marked_for_destruction() ) {
00100       // Clear out the entities destroyed in the previous modification.
00101       // They were retained for change-logging purposes.
00102       internal_expunge_entity( j );
00103     }
00104     else {
00105       j->second->m_entityImpl.log_clear();
00106     }
00107   }
00108 }
00109 
00110 bool EntityRepository::erase_ghosting( Entity & e, const Ghosting & ghosts) const
00111 {
00112   TraceIfWatching("stk::mesh::impl::EntityRepository::erase_ghosting", LOG_ENTITY, e.key());
00113 
00114   return e.m_entityImpl.erase( ghosts );
00115 }
00116 
00117 bool EntityRepository::erase_comm_info( Entity & e, const EntityCommInfo & comm_info) const
00118 {
00119   TraceIfWatching("stk::mesh::impl::EntityRepository::erase_comm_info", LOG_ENTITY, e.key());
00120 
00121   return e.m_entityImpl.erase( comm_info );
00122 }
00123 
00124 bool EntityRepository::insert_comm_info( Entity & e, const EntityCommInfo & comm_info) const
00125 {
00126   TraceIfWatching("stk::mesh::impl::EntityRepository::insert_comm_info", LOG_ENTITY, e.key());
00127 
00128   return e.m_entityImpl.insert( comm_info );
00129 }
00130 
00131 void EntityRepository::destroy_later( Entity & e, Bucket* nil_bucket )
00132 {
00133   TraceIfWatching("stk::mesh::impl::EntityRepository::destroy_later", LOG_ENTITY, e.key());
00134 
00135   ThrowErrorMsgIf( e.log_query() == EntityLogDeleted,
00136                    "double deletion of entity: " << print_entity_key( e ));
00137 
00138   change_entity_bucket( *nil_bucket, e, 0);
00139   e.m_entityImpl.log_deleted(); //important that this come last
00140 }
00141 
00142 void EntityRepository::change_entity_bucket( Bucket & b, Entity & e,
00143                                              unsigned ordinal)
00144 {
00145   TraceIfWatching("stk::mesh::impl::EntityRepository::change_entity_bucket", LOG_ENTITY, e.key());
00146   DiagIfWatching(LOG_ENTITY, e.key(), "New bucket: " << b << ", ordinal: " << ordinal);
00147 
00148   const bool modified_parts = ! e.m_entityImpl.is_bucket_valid() ||
00149                               ! b.equivalent( e.bucket() );
00150   if ( modified_parts ) {
00151     e.m_entityImpl.log_modified_and_propagate();
00152   }
00153   e.m_entityImpl.set_bucket_and_ordinal( &b, ordinal);
00154 }
00155 
00156 Bucket * EntityRepository::get_entity_bucket( Entity & e ) const
00157 {
00158   // Note, this allows for returning NULL bucket
00159   return e.m_entityImpl.bucket_ptr();
00160 }
00161 
00162 bool EntityRepository::destroy_relation( Entity & e_from,
00163                                          Entity & e_to,
00164                                          const RelationIdentifier local_id )
00165 {
00166   TraceIfWatching("stk::mesh::impl::EntityRepository::destroy_relation", LOG_ENTITY, e_from.key());
00167 
00168   bool caused_change_fwd = e_from.m_entityImpl.destroy_relation(e_to, local_id);
00169 
00170   // Relationships should always be symmetrical
00171   if ( caused_change_fwd ) {
00172     bool caused_change_inv = e_to.m_entityImpl.destroy_relation(e_from, local_id);
00173     ThrowErrorMsgIf( !caused_change_inv,
00174         " Internal error - could not destroy inverse relation of " <<
00175         print_entity_key( e_from ) << " to " << print_entity_key( e_to ) <<
00176         " with local relation id of " << local_id);
00177   }
00178 
00179   // It is critical that the modification be done AFTER the relations are
00180   // changed so that the propagation can happen correctly.
00181   if ( caused_change_fwd ) {
00182     e_to.m_entityImpl.log_modified_and_propagate();
00183     e_from.m_entityImpl.log_modified_and_propagate();
00184   }
00185 
00186   return caused_change_fwd;
00187 }
00188 
00189 void EntityRepository::declare_relation( Entity & e_from,
00190                                          Entity & e_to,
00191                                          const RelationIdentifier local_id,
00192                                          unsigned sync_count )
00193 {
00194   TraceIfWatching("stk::mesh::impl::EntityRepository::declare_relation", LOG_ENTITY, e_from.key());
00195 
00196   bool caused_change_fwd =
00197     e_from.m_entityImpl.declare_relation( e_to, local_id, sync_count);
00198 
00199   // Relationships should always be symmetrical
00200   if ( caused_change_fwd ) {
00201 
00202     // the setup for the converse relationship works slightly differently
00203     bool is_converse = true;
00204     bool caused_change_inv =
00205       e_to.m_entityImpl.declare_relation( e_from, local_id, sync_count,
00206                                           is_converse );
00207 
00208     ThrowErrorMsgIf( !caused_change_inv,
00209         " Internal error - could not create inverse relation of " <<
00210         print_entity_key( e_from ) << " to " << print_entity_key( e_to ));
00211   }
00212 
00213   // It is critical that the modification be done AFTER the relations are
00214   // added so that the propagation can happen correctly.
00215   if ( caused_change_fwd ) {
00216     e_to.m_entityImpl.log_modified_and_propagate();
00217     e_from.m_entityImpl.log_modified_and_propagate();
00218   }
00219 }
00220 
00221 } // namespace impl
00222 } // namespace mesh
00223 } // namespace stk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends