|
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 00013 #if 0 00014 00015 #include <unistd.h> // For sleep 00016 #include <stdexcept> 00017 00018 00019 00020 #include <stk_mesh/base/Entity.hpp> 00021 #include <stk_mesh/base/Bucket.hpp> 00022 #include <stk_mesh/base/BulkData.hpp> 00023 #include <stk_mesh/base/Transaction.hpp> 00024 00025 namespace stk { 00026 namespace mesh { 00027 00028 00029 void Transaction::print_bucket_list ( const BucketList &bl , std::ostream &os ) const 00030 { 00031 BucketList::const_iterator cur_bucket = bl.begin(); 00032 while ( cur_bucket != bl.end() ) 00033 { 00034 os << "Bucket key: "; 00035 for ( unsigned i = 0 ; i <= (*cur_bucket)->m_key[0] ; i++ ) 00036 os << (*cur_bucket)->m_key[i] << " "; 00037 os << "\n"; 00038 os << "Entities: "; 00039 for ( unsigned i = 0 ; i != (*cur_bucket)->m_size ; i++ ) 00040 os << (*cur_bucket)->m_entities[i]->identifier() << " "; 00041 os << "\n-------------------\n"; 00042 cur_bucket++; 00043 } 00044 } 00045 00046 00047 void Transaction::print_transaction ( unsigned type , std::ostream &os ) const 00048 { 00049 os << "Transaction details for type = " << type << "\n"; 00050 os << "-=-=- Proc " << m_bulk_data.parallel_rank() << " -=-=-\n"; 00051 print_proc_transaction ( type , os ); 00052 os << std::endl; 00053 } 00054 00055 void Transaction::print_proc_transaction ( unsigned type , std::ostream &os ) const 00056 { 00057 os << " Modified has " << m_modified[type].size() << " buckets\n" 00058 << " Nowhere has " << m_deleted[type].size() << " buckets\n" 00059 << " Inserted has " << m_inserted[type].size() << " buckets\n"; 00060 os << " Modified buckets:\n"; 00061 print_bucket_list ( m_modified[type] , os ); 00062 os << " Nowhere buckets:\n"; 00063 print_bucket_list ( m_deleted[type] , os ); 00064 os << " Inserted buckets:\n"; 00065 print_bucket_list ( m_inserted[type] , os ); 00066 } 00067 00068 std::ostream & Transaction::print_stream ( std::ostream &os ) const 00069 { 00070 for ( unsigned i = 0 ; i != m_modified.size() ; i++ ) 00071 print_transaction ( i , os ); 00072 return os; 00073 } 00074 00075 Transaction::Transaction ( BulkData &bd , TransactionType type ) : m_transaction_type(type) , 00076 m_bulk_data ( bd ) , 00077 m_modified ( ) , 00078 m_deleted ( ) , 00079 m_inserted ( ) 00080 { 00081 allocate_bucket_lists (); 00082 } 00083 00084 Transaction::~Transaction () 00085 { 00086 reset (); 00087 } 00088 00089 00090 00091 // This allocation works on the assumption that the entity types are 00092 // packed and enumerated from zero. This assumption is currently safe 00093 // since bulk data makes the same assumption. Should this ever 00094 // change in bulk data, the same change must occur here. 00095 void Transaction::allocate_bucket_lists () 00096 { 00097 m_modified.resize ( m_bulk_data.mesh_meta_data().entity_rank_count() ); 00098 m_deleted.resize ( m_bulk_data.mesh_meta_data().entity_rank_count() ); 00099 m_inserted.resize ( m_bulk_data.mesh_meta_data().entity_rank_count() ); 00100 } 00101 00102 00103 // This method will place entity e in the modified buckets. Unlike 00104 // modify_entity, this will not add the from-entity relations to the 00105 // modified bucket. This method is invoked on the to-entity of a new 00106 // or changed relation. If the entity is already in a transaction 00107 // bucket, this method returns with no change 00108 void Transaction::modify_sole_entity ( Entity &e ) 00109 { 00110 // If no bucket is specified yet, then the entity is inserted and 00111 // should be ignored 00112 if ( e.m_bucket == 0 ) return; 00113 00114 // Ignore spurious calls to internal_change_entity_parts 00115 if ( e.m_trans_bucket != 0 ) return; 00116 00117 add_parts_to_partset ( e , m_modified_parts ); 00118 00119 // If this is not an incremental transaction, ignore 00120 if ( m_transaction_type != INCREMENTAL ) return; 00121 00122 Bucket *transaction_bucket = get_unfilled_transaction_bucket ( e , m_modified[e.entity_rank()] , MODIFIED ); 00123 00124 add_entity_to_transaction_bucket ( e , transaction_bucket ); 00125 } 00126 00127 // This method will add e to the modified bucket and every entity for 00128 // which e is directly related to. This method is invoked an all 00129 // modification other than the to-entity of a new or modified 00130 // relation. If the entity is already in a transaction bucket, this 00131 // method returns with no change. 00132 void Transaction::modify_entity ( Entity &e ) 00133 { 00134 00135 // If no bucket is specified yet, then the entity is inserted and 00136 // should be ignored 00137 if ( e.m_bucket == 0 ) return; 00138 00139 // Ignore spurious calls to internal_change_entity_parts 00140 if ( e.m_trans_bucket != 0 ) return; 00141 00142 add_parts_to_partset ( e , m_modified_parts ); 00143 00144 // If this is not an incremental transaction, ignore 00145 if ( m_transaction_type != INCREMENTAL ) return; 00146 00147 Bucket *transaction_bucket = get_unfilled_transaction_bucket ( e , m_modified[e.entity_rank()] , MODIFIED ); 00148 00149 add_entity_to_transaction_bucket ( e , transaction_bucket ); 00150 00151 PairIterRelation current_relation = e.relations(); 00152 while ( current_relation.first != current_relation.second ) 00153 { 00154 if ( current_relation->entity_rank() > e.entity_rank() ) 00155 modify_sole_entity ( *(current_relation->entity()) ); 00156 current_relation++; 00157 } 00158 } 00159 00160 // If an entity is removed from this process, it is placed in the 00161 // deleted bucket. If the entity is in another transaction bucket, it 00162 // is moved to the deleted bucket and the corresponding parts the 00163 // entity is a member of is moved along with it 00164 void Transaction::delete_entity ( Entity &e ) 00165 { 00166 add_parts_to_partset ( e , m_deleted_parts ); 00167 00168 // Determine if entity has already been deleted after insert 00169 // If so, return 00170 if ( m_to_delete.find ( &e ) != m_to_delete.end () ) 00171 return; 00172 00173 // Mark for deletion if the transaction type is BULK 00174 if ( m_transaction_type == BULK ) 00175 m_to_delete.insert ( &e ); 00176 00177 // If this is not an incremental transaction, ignore 00178 if ( m_transaction_type != INCREMENTAL ) return; 00179 00180 if ( e.m_trans_bucket ) 00181 { 00182 if ( e.transaction_bucket()->transaction_state() == DELETED ) return; 00183 if ( e.transaction_bucket()->transaction_state() == MODIFIED ) 00184 { 00185 swap_entity_between_transaction_buckets ( e , m_modified[e.entity_rank()] , m_deleted[e.entity_rank()] , DELETED ); 00186 return; 00187 } 00188 if ( e.transaction_bucket()->transaction_state() == INSERTED ) 00189 { 00190 remove_entity_from_bucket ( e , m_inserted[e.entity_rank()] ); 00191 // Need to mark this for deletion at reset since it will not be 00192 // stored anywhere 00193 m_to_delete.insert ( &e ); 00194 return; 00195 } 00196 } 00197 00198 Bucket *transaction_bucket = get_unfilled_transaction_bucket ( e , m_deleted[e.entity_rank()] , DELETED ); 00199 add_entity_to_transaction_bucket ( e , transaction_bucket ); 00200 } 00201 00202 // If an entity is inserted into the mesh, it is placed in the insert 00203 // bucket. If it is a member of another bucket, this function does 00204 // nothing. It should be an error to be in another bucket and this 00205 // should be caught elsewhere. 00206 void Transaction::insert_entity ( Entity &e ) 00207 { 00208 00209 if ( e.m_trans_bucket != 0 ) return; 00210 00211 add_parts_to_partset ( e , m_inserted_parts ); 00212 00213 // If this is not an incremental transaction, ignore 00214 if ( m_transaction_type != INCREMENTAL ) return; 00215 00216 Bucket *transaction_bucket = get_unfilled_transaction_bucket ( e , m_inserted[e.entity_rank()] , INSERTED ); 00217 add_entity_to_transaction_bucket ( e , transaction_bucket ); 00218 } 00219 00220 // Upon modification_begin() in bulk data, the transaction purges the 00221 // transaction buckets. This function simply deallocates the bucket 00222 // and removes entities from the transaction bucket. 00223 void Transaction::purge_map ( BucketListByType &buckets ) 00224 { 00225 BucketListByType::iterator cur_type = buckets.begin(); 00226 while ( cur_type != buckets.end() ) 00227 { 00228 BucketList::iterator cur_bucket = cur_type->begin(); 00229 while ( cur_bucket != cur_type->end() ) 00230 { 00231 BucketIterator cur_entity = (*cur_bucket)->begin(); 00232 while ( cur_entity != (*cur_bucket)->end() ) 00233 { 00234 cur_entity->m_trans_bucket = NULL; 00235 cur_entity++; 00236 } 00237 Bucket::destroy_bucket ( *cur_bucket ); 00238 cur_bucket++; 00239 } 00240 cur_type->clear(); 00241 cur_type++; 00242 } 00243 00244 } 00245 00246 // This method will purge buckets and delete entities from memory. 00247 // This method uses the internal_destroy_entire_bucket method in 00248 // BulkData which does not, in turn, call the delete_entity 00249 // transaction function. 00250 /* 00251 void Transaction::purge_and_erase_map ( BucketListByType &buckets ) 00252 { 00253 BucketListByType::iterator cur_type = buckets.begin(); 00254 while ( cur_type != buckets.end() ) 00255 { 00256 BucketList::iterator cur_bucket = cur_type->begin(); 00257 while ( cur_bucket != cur_type->end() ) 00258 { 00259 m_bulk_data.internal_destroy_entire_bucket ( *cur_bucket ); 00260 cur_bucket++; 00261 } 00262 cur_type->clear(); 00263 cur_type++; 00264 } 00265 } 00266 00267 void Transaction::flush_deletes () 00268 { 00269 for ( std::set<Entity *>::iterator cur_del_entity = m_to_delete.begin() ; cur_del_entity != m_to_delete.end() ; cur_del_entity++ ) 00270 m_bulk_data.internal_expunge_entity ( *cur_del_entity ); 00271 m_to_delete.clear (); 00272 } 00273 */ 00274 00275 00276 void Transaction::flush() 00277 { 00278 purge_map ( m_modified ); 00279 purge_map ( m_inserted ); 00280 purge_map ( m_deleted ); 00281 00282 m_modified_parts.clear(); 00283 m_deleted_parts.clear(); 00284 m_inserted_parts.clear(); 00285 } 00286 00287 // Explicity purge and erase memory as needed. 00288 void Transaction::reset ( TransactionType type ) 00289 { 00290 m_transaction_type = type; 00291 flush(); 00292 } 00293 00294 void Transaction::add_parts_to_partset ( Entity &e , PartSet &pl ) 00295 { 00296 PartVector parts; 00297 e.bucket().supersets ( parts ); 00298 00299 for ( PartVector::iterator part_iter = parts.begin(); part_iter != parts.end() ; ++part_iter ) 00300 pl.insert ( *part_iter ); 00301 00302 00303 } 00304 00305 void Transaction::translate_partset_to_partvector ( const PartSet &in , PartVector &out ) const 00306 { 00307 out.resize ( in.size() ); 00308 unsigned i = 0; 00309 for ( PartSet::const_iterator cur_in = in.begin() ; cur_in != in.end() ; cur_in++ ) 00310 { 00311 out[i] = *cur_in; 00312 ++i; 00313 } 00314 } 00315 00316 // The bucket b is assumed to have enough space to add entity e. This 00317 // is placed on the end of the array and the size is incremented. 00318 void Transaction::add_entity_to_transaction_bucket ( Entity &e , Bucket *b ) 00319 { 00320 b->m_entities[b->m_size] = &e; 00321 e.m_trans_bucket = b; 00322 e.m_trans_bucket_ord = b->m_size; 00323 b->m_size++; 00324 } 00325 00326 // Entity e is removed from ''from'' and placed in ''to''. 00327 void Transaction::swap_entity_between_transaction_buckets ( Entity &e , BucketList &from , BucketList &to , State s ) 00328 { 00329 Bucket *to_bucket = get_unfilled_transaction_bucket ( e , to , s ); 00330 remove_entity_from_bucket ( e , from ); 00331 add_entity_to_transaction_bucket ( e , to_bucket ); 00332 } 00333 00334 00335 // This is a wrapper around the Bucket::declare_bucket. Each bucket 00336 // has no field data and has a copy of the key from the current bucket 00337 // the entity is in. 00338 Bucket *Transaction::get_unfilled_transaction_bucket ( const unsigned * const key , EntityRank type , BucketList &buckets , State s ) 00339 { 00340 Bucket *new_bucket = Bucket::declare_bucket ( m_bulk_data , 00341 type , 00342 key[0] - 1 , 00343 key+1 , 00344 m_bulk_data.bucket_capacity() , 00345 std::vector<FieldBase *> () , 00346 buckets ); 00347 00348 new_bucket->m_transaction_state = s; 00349 00350 return new_bucket; 00351 } 00352 00353 00354 // This code was copied from bulk data and used to remove entities 00355 // from buckets. In order to remove an entity, an appropriate entity 00356 // must be found to copy into the hole. This logic will find the 00357 // appropriate bucket which has an entity to copy into the bucket. 00358 void Transaction::remove_entity_from_bucket ( Entity &e , BucketList &buckets ) 00359 { 00360 Bucket *k = e.m_trans_bucket; 00361 unsigned i = e.m_trans_bucket_ord; 00362 00363 Bucket * const first = k->m_key[ *k->m_key ] ? k->m_bucket : k ; 00364 Bucket * const last = first->m_bucket ; 00365 00366 // Only move if not the last entity being removed 00367 00368 if ( last != k || k->m_size != i + 1 ) { 00369 00370 // Not the same bucket or not the last entity 00371 00372 // Copy last entity in last to ik slot i 00373 00374 Entity * const entity = last->m_entities[ last->m_size - 1 ]; 00375 00376 k->m_entities[i] = entity ; 00377 entity->m_trans_bucket = k ; 00378 entity->m_trans_bucket_ord = i ; 00379 00380 } 00381 00382 --( last->m_size ); 00383 00384 if ( last->m_size != 0 ) { 00385 last->m_entities[ last->m_size ] = NULL ; 00386 } 00387 else { 00388 00389 // The current 'last' bucket is to be deleted. 00390 // The previous 'last' bucket becomes the 00391 // new 'last' bucket in the family: 00392 00393 std::vector<Bucket*>::iterator ik = lower_bound(buckets, last->m_key); 00394 00395 if ( ik == buckets.end() || last != *ik ) { 00396 throw std::runtime_error( 00397 std::string("stk::mesh::Transaction::remove_entity_from_bucket INTERNAL FAILURE") ); 00398 } 00399 00400 ik = buckets.erase( ik ); 00401 00402 if ( first != last ) { first->m_bucket = *--ik ; } 00403 00404 Bucket::destroy_bucket( last ); 00405 } 00406 00407 e.m_trans_bucket = NULL; 00408 } 00409 00410 00411 } 00412 } 00413 00414 #endif 00415