|
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 <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_classic { 00018 namespace mesh { 00019 namespace impl { 00020 00021 boost::fast_pool_allocator<Entity>& entity_allocator() 00022 { 00023 static boost::fast_pool_allocator<Entity> entity_pool_allocator; 00024 return entity_pool_allocator; 00025 } 00026 00027 #ifdef SIERRA_MIGRATION 00028 boost::fast_pool_allocator<fmwk_attributes>& fmwk_attr_allocator() 00029 { 00030 static boost::fast_pool_allocator<fmwk_attributes> fmwk_attr_allocator; 00031 return fmwk_attr_allocator; 00032 } 00033 #endif 00034 00035 Entity* EntityRepository::allocate_entity(bool use_pool) 00036 { 00037 if (use_pool) { 00038 static Entity tmp_entity; 00039 Entity* new_entity = entity_allocator().allocate(); 00040 entity_allocator().construct(new_entity, tmp_entity); 00041 return new_entity; 00042 } 00043 //else 00044 return new Entity; 00045 } 00046 00047 #ifdef SIERRA_MIGRATION 00048 fmwk_attributes* allocate_fmwk_attr(bool use_pool) 00049 { 00050 if (use_pool) { 00051 static fmwk_attributes tmp_attributes; 00052 fmwk_attributes* fmwk_attrs = fmwk_attr_allocator().allocate(); 00053 fmwk_attr_allocator().construct(fmwk_attrs, tmp_attributes); 00054 return fmwk_attrs; 00055 } 00056 //else 00057 return new fmwk_attributes; 00058 } 00059 #endif 00060 00061 void destroy_entity(Entity* entity, bool use_pool) 00062 { 00063 if (use_pool) { 00064 entity_allocator().destroy(entity); 00065 entity_allocator().deallocate(entity, 1); 00066 return; 00067 } 00068 //else 00069 delete entity; 00070 } 00071 00072 #ifdef SIERRA_MIGRATION 00073 void destroy_fmwk_attr(fmwk_attributes* fmwk_attr, bool use_pool) 00074 { 00075 if (use_pool) { 00076 fmwk_attr_allocator().destroy(fmwk_attr); 00077 fmwk_attr_allocator().deallocate(fmwk_attr, 1); 00078 return; 00079 } 00080 //else 00081 delete fmwk_attr; 00082 } 00083 #endif 00084 00085 void release_all_entity_memory(bool use_pool) 00086 { 00087 if (use_pool) { 00088 boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(Entity)>::release_memory(); 00089 } 00090 } 00091 00092 #ifdef SIERRA_MIGRATION 00093 void release_all_fmwk_attr_memory(bool use_pool) 00094 { 00095 if (use_pool) { 00096 boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(fmwk_attributes)>::release_memory(); 00097 } 00098 } 00099 #endif 00100 00101 EntityRepository::~EntityRepository() 00102 { 00103 try { 00104 while ( ! m_entities.empty() ) { 00105 internal_expunge_entity( m_entities.begin() ); 00106 } 00107 } catch(...){} 00108 00109 release_all_entity_memory(m_use_pool); 00110 #ifdef SIERRA_MIGRATION 00111 release_all_fmwk_attr_memory(m_use_pool); 00112 #endif 00113 } 00114 00115 void EntityRepository::internal_expunge_entity( EntityMap::iterator i ) 00116 { 00117 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::internal_expunge_entity", LOG_ENTITY, i->first); 00118 00119 ThrowErrorMsgIf( i->second == NULL, 00120 "For key " << entity_rank(i->first) << " " << 00121 entity_id(i->first) << ", value was NULL"); 00122 00123 ThrowErrorMsgIf( i->first != i->second->key(), 00124 "Key " << print_entity_key(MetaData::get( *i->second ), i->first) << 00125 " != " << print_entity_key(i->second)); 00126 00127 Entity* deleted_entity = i->second; 00128 00129 #ifdef SIERRA_MIGRATION 00130 destroy_fmwk_attr(deleted_entity->m_fmwk_attrs, m_use_pool); 00131 #endif 00132 destroy_entity(deleted_entity, m_use_pool); 00133 i->second = NULL; 00134 m_entities.erase( i ); 00135 } 00136 00137 Entity* 00138 EntityRepository::internal_allocate_entity(EntityKey entity_key) 00139 { 00140 Entity* new_entity = allocate_entity(m_use_pool); 00141 new_entity->set_key(entity_key); 00142 #ifdef SIERRA_MIGRATION 00143 fmwk_attributes* fmwk_attrs = allocate_fmwk_attr(m_use_pool); 00144 new_entity->m_fmwk_attrs = fmwk_attrs; 00145 #endif 00146 return new_entity; 00147 } 00148 00149 std::pair<Entity*,bool> 00150 EntityRepository::internal_create_entity( const EntityKey & key ) 00151 { 00152 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::internal_create_entity", LOG_ENTITY, key); 00153 00154 EntityMap::value_type tmp(key,NULL); 00155 00156 const std::pair< EntityMap::iterator , bool > 00157 insert_result = m_entities.insert( tmp ); 00158 00159 std::pair<Entity*,bool> 00160 result( insert_result.first->second , insert_result.second ); 00161 00162 if ( insert_result.second ) { // A new entity 00163 Entity* new_entity = internal_allocate_entity(key); 00164 insert_result.first->second = result.first = new_entity; 00165 } 00166 else if ( EntityLogDeleted == result.first->log_query() ) { 00167 // resurrection 00168 result.first->m_entityImpl.log_resurrect(); 00169 result.second = true; 00170 } 00171 00172 return result ; 00173 } 00174 00175 void EntityRepository::log_created_parallel_copy( Entity & entity ) 00176 { 00177 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::log_created_parallel_copy", LOG_ENTITY, entity.key()); 00178 00179 entity.m_entityImpl.log_created_parallel_copy(); 00180 } 00181 00182 Entity * EntityRepository::get_entity(const EntityKey &key) const 00183 { 00184 ThrowErrorMsgIf( ! entity_key_valid( key ), 00185 "Invalid key: " << entity_rank(key) << " " << entity_id(key)); 00186 00187 const EntityMap::const_iterator i = m_entities.find( key ); 00188 00189 return i != m_entities.end() ? i->second : NULL ; 00190 } 00191 00192 void EntityRepository::clean_changes() 00193 { 00194 TraceIf("stk_classic::mesh::impl::EntityRepository::clean_changes", LOG_ENTITY); 00195 00196 for ( EntityMap::iterator 00197 i = m_entities.begin() ; i != m_entities.end() ; ) 00198 { 00199 const EntityMap::iterator j = i ; 00200 ++i ; 00201 00202 if ( j->second->m_entityImpl.marked_for_destruction() ) { 00203 // Clear out the entities destroyed in the previous modification. 00204 // They were retained for change-logging purposes. 00205 internal_expunge_entity( j ); 00206 } 00207 else { 00208 j->second->m_entityImpl.log_clear(); 00209 } 00210 } 00211 } 00212 00213 bool EntityRepository::erase_ghosting( Entity & e, const Ghosting & ghosts) const 00214 { 00215 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::erase_ghosting", LOG_ENTITY, e.key()); 00216 00217 return e.m_entityImpl.erase( ghosts ); 00218 } 00219 00220 bool EntityRepository::erase_comm_info( Entity & e, const EntityCommInfo & comm_info) const 00221 { 00222 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::erase_comm_info", LOG_ENTITY, e.key()); 00223 00224 return e.m_entityImpl.erase( comm_info ); 00225 } 00226 00227 bool EntityRepository::insert_comm_info( Entity & e, const EntityCommInfo & comm_info) const 00228 { 00229 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::insert_comm_info", LOG_ENTITY, e.key()); 00230 00231 return e.m_entityImpl.insert( comm_info ); 00232 } 00233 00234 void EntityRepository::destroy_later( Entity & e, Bucket* nil_bucket ) 00235 { 00236 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::destroy_later", LOG_ENTITY, e.key()); 00237 00238 ThrowErrorMsgIf( e.log_query() == EntityLogDeleted, 00239 "double deletion of entity: " << print_entity_key( e )); 00240 00241 change_entity_bucket( *nil_bucket, e, 0); 00242 e.m_entityImpl.log_deleted(); //important that this come last 00243 } 00244 00245 void EntityRepository::change_entity_bucket( Bucket & b, Entity & e, 00246 unsigned ordinal) 00247 { 00248 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::change_entity_bucket", LOG_ENTITY, e.key()); 00249 DiagIfWatching(LOG_ENTITY, e.key(), "New bucket: " << b << ", ordinal: " << ordinal); 00250 00251 const bool modified_parts = ! e.m_entityImpl.is_bucket_valid() || 00252 ! b.equivalent( e.bucket() ); 00253 if ( modified_parts ) { 00254 e.m_entityImpl.log_modified_and_propagate(); 00255 } 00256 e.m_entityImpl.set_bucket_and_ordinal( &b, ordinal); 00257 } 00258 00259 Bucket * EntityRepository::get_entity_bucket( Entity & e ) const 00260 { 00261 // Note, this allows for returning NULL bucket 00262 return e.m_entityImpl.bucket_ptr(); 00263 } 00264 00265 bool EntityRepository::destroy_relation( Entity & e_from, 00266 Entity & e_to, 00267 const RelationIdentifier local_id ) 00268 { 00269 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::destroy_relation", LOG_ENTITY, e_from.key()); 00270 00271 bool caused_change_fwd = e_from.m_entityImpl.destroy_relation(e_to, local_id); 00272 00273 // Relationships should always be symmetrical 00274 if ( caused_change_fwd ) { 00275 bool caused_change_inv = e_to.m_entityImpl.destroy_relation(e_from, local_id); 00276 ThrowErrorMsgIf( !caused_change_inv, 00277 " Internal error - could not destroy inverse relation of " << 00278 print_entity_key( e_from ) << " to " << print_entity_key( e_to ) << 00279 " with local relation id of " << local_id); 00280 } 00281 00282 // It is critical that the modification be done AFTER the relations are 00283 // changed so that the propagation can happen correctly. 00284 if ( caused_change_fwd ) { 00285 e_to.m_entityImpl.log_modified_and_propagate(); 00286 e_from.m_entityImpl.log_modified_and_propagate(); 00287 } 00288 00289 return caused_change_fwd; 00290 } 00291 00292 void EntityRepository::declare_relation( Entity & e_from, 00293 Entity & e_to, 00294 const RelationIdentifier local_id, 00295 unsigned sync_count ) 00296 { 00297 TraceIfWatching("stk_classic::mesh::impl::EntityRepository::declare_relation", LOG_ENTITY, e_from.key()); 00298 00299 bool caused_change_fwd = 00300 e_from.m_entityImpl.declare_relation( e_to, local_id, sync_count); 00301 00302 // Relationships should always be symmetrical 00303 if ( caused_change_fwd ) { 00304 00305 // the setup for the converse relationship works slightly differently 00306 bool is_converse = true; 00307 bool caused_change_inv = 00308 e_to.m_entityImpl.declare_relation( e_from, local_id, sync_count, 00309 is_converse ); 00310 00311 ThrowErrorMsgIf( !caused_change_inv, 00312 " Internal error - could not create inverse relation of " << 00313 print_entity_key( e_from ) << " to " << print_entity_key( e_to )); 00314 } 00315 00316 // It is critical that the modification be done AFTER the relations are 00317 // added so that the propagation can happen correctly. 00318 if ( caused_change_fwd ) { 00319 e_to.m_entityImpl.log_modified_and_propagate(); 00320 e_from.m_entityImpl.log_modified_and_propagate(); 00321 } 00322 } 00323 00324 void EntityRepository::update_entity_key(EntityKey key, Entity & entity) 00325 { 00326 EntityKey old_key = entity.key(); 00327 00328 EntityMap::iterator old_itr = m_entities.find( old_key ); 00329 00330 EntityMap::iterator itr = m_entities.find(key); 00331 if (itr != m_entities.end()) { 00332 Entity* key_entity = itr->second; 00333 ThrowRequireMsg( key_entity->log_query() == EntityLogDeleted, "update_entity_key ERROR: non-deleted entity already present for new key (" << key.rank()<<","<<key.id()<<")"); 00334 00335 //We found an entity with 'key', we'll change its key to old_key and then 00336 //entity (old_itr) will adopt key. 00337 00338 key_entity->m_entityImpl.update_key(old_key); 00339 //key_entity is already marked for deletion 00340 00341 old_itr->second->m_entityImpl.update_key(key); 00342 00343 //We also need to swap the entities on these map iterators so that 00344 //they map to the right keys: 00345 itr->second = old_itr->second; 00346 old_itr->second = key_entity; 00347 } 00348 else { 00349 m_entities.insert(std::make_pair(key,&entity)); 00350 00351 entity.m_entityImpl.update_key(key); 00352 00353 old_itr->second = internal_allocate_entity(old_key); 00354 00355 old_itr->second->m_entityImpl.log_deleted(); 00356 } 00357 } 00358 00359 } // namespace impl 00360 } // namespace mesh 00361 } // namespace stk_classic