Sierra Toolkit  Version of the Day
UnitTestTransactionLog.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
16 #if 0
17 
18 #include <sstream>
19 #include <stdexcept>
20 
21 #include <unit_tests/stk_utest_macros.hpp>
22 
23 #include <stk_util/parallel/Parallel.hpp>
24 
25 #include <stk_mesh/base/BulkData.hpp>
26 #include <stk_mesh/base/GetEntities.hpp>
27 #include <stk_mesh/base/Field.hpp>
28 #include <stk_mesh/base/FieldData.hpp>
29 #include <stk_mesh/base/Comm.hpp>
30 #include <stk_mesh/base/GetBuckets.hpp>
31 
32 
33 #include <stk_mesh/fixtures/BoxFixture.hpp>
34 
39 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyBulkOnCreate)
40 {
41  stk_classic::mesh::MetaData meta ( stk_classic::mesh::fem_entity_rank_names() );
42  stk_classic::mesh::Part &new_part = meta.declare_part ( "another part" );
43  meta.commit ();
44 
45  stk_classic::ParallelMachine comm(MPI_COMM_WORLD);
46  stk_classic::mesh::BulkData bulk ( meta , comm , 100 );
47  std::vector<stk_classic::mesh::Part *> add_part;
48  add_part.push_back ( &new_part );
49 
50  int size , rank;
53 
54  for ( int i = 0 ; i != 100 ; i++ )
55  {
56  int new_id = size*i+rank;
57  bulk.declare_entity ( 0 , new_id+1 , add_part );
58  }
59  bulk.modification_end();
60 
61  // If something shows up in the insert incremental log, then
62  // not in bulk state
63  STKUNIT_ASSERT ( bulk.get_transaction_log().get_inserted_buckets(0).size() == 0 );
64  STKUNIT_ASSERT ( bulk.get_transaction_log().get_modified_buckets(0).size() == 0 );
65  STKUNIT_ASSERT ( bulk.get_transaction_log().get_deleted_buckets(0).size() == 0 );
66 
67  // Verify that things are inserted in the bulk transaction
68  stk_classic::mesh::PartVector inserted_parts;
69  bulk.get_transaction_log().get_parts_with_inserted_entities ( inserted_parts );
70  STKUNIT_ASSERT ( inserted_parts.size() > 0 );
71 }
72 
78 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyBulkInsert)
79 {
81  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
82  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
83 
84  stk_classic::mesh::Part &new_part = fixture.get_test_part ();
86  add_part.push_back ( &new_part );
87 
88  // This test need only run in serial
89  if ( fixture.comm_size() > 1 ) return;
90 
91  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
92  bulk.modification_begin ();
93  bulk.declare_entity ( 0 , fixture.comm_size()*1000 + fixture.comm_rank() , add_part );
94  bulk.modification_end ();
95 
96  // Verify the entity did not go into the log explicitly
97  STKUNIT_ASSERT ( bulk.get_transaction_log().get_inserted_buckets(0).size() == 0 );
98 
99  // Check to see if the new_part is in the inserted parts;
100  stk_classic::mesh::PartVector inserted_parts;
101  bool found = false;
102  bulk.get_transaction_log().get_parts_with_inserted_entities ( inserted_parts );
103  for ( size_t i = 0 ; i != inserted_parts.size() ; i++ )
104  {
105  if ( inserted_parts[i] == &new_part )
106  found = true;
107  }
108  STKUNIT_ASSERT ( found );
109 
110  // Verify there is nothing in the modified_parts set
111  stk_classic::mesh::PartVector modified_parts;
112  found = false;
113  bulk.get_transaction_log().get_parts_with_modified_entities ( modified_parts );
114  for ( size_t i = 0 ; i != modified_parts.size() ; i++ )
115  {
116  if ( modified_parts[i] == &new_part )
117  found = true;
118  }
119  STKUNIT_ASSERT ( !found );
120 
121  // Verify there is nothing in the deleted_parts set
122  stk_classic::mesh::PartVector deleted_parts;
123  found = false;
124  bulk.get_transaction_log().get_parts_with_deleted_entities ( deleted_parts );
125  for ( size_t i = 0 ; i != deleted_parts.size() ; i++ )
126  {
127  if ( deleted_parts[i] == &new_part )
128  found = true;
129  }
130  STKUNIT_ASSERT ( !found );
131 }
132 
133 
139 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyBulkModify)
140 {
142  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
143  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
144 
145  stk_classic::mesh::Part &new_part = fixture.get_test_part();
146  stk_classic::mesh::PartVector add_part,blank_part;
147  add_part.push_back ( &new_part );
148 
149  // This test need only run in serial
150  if ( fixture.comm_size() > 1 ) return;
151 
152  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
153  bulk.modification_begin ();
154  stk_classic::mesh::Entity &new_entity = bulk.declare_entity ( 0 , fixture.comm_size()*1000 + fixture.comm_rank() , add_part );
155  bulk.modification_end ();
156 
157  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
158  bulk.modification_begin ();
159  bulk.change_entity_parts ( new_entity , blank_part , add_part );
160  bulk.modification_end ();
161 
162  STKUNIT_ASSERT ( bulk.get_transaction_log().get_modified_buckets(0).size() == 0 );
163 
164  stk_classic::mesh::PartVector inserted_parts;
165  bool found = false;
166  bulk.get_transaction_log().get_parts_with_inserted_entities ( inserted_parts );
167  for ( size_t i = 0 ; i != inserted_parts.size() ; i++ )
168  {
169  if ( inserted_parts[i] == &new_part )
170  found = true;
171  }
172  STKUNIT_ASSERT ( !found );
173 
174  stk_classic::mesh::PartVector modified_parts;
175  found = false;
176  bulk.get_transaction_log().get_parts_with_modified_entities ( modified_parts );
177  for ( size_t i = 0 ; i != modified_parts.size() ; i++ )
178  {
179  if ( modified_parts[i] == &new_part )
180  found = true;
181  }
182  STKUNIT_ASSERT ( found );
183 
184  stk_classic::mesh::PartVector deleted_parts;
185  found = false;
186  bulk.get_transaction_log().get_parts_with_deleted_entities ( deleted_parts );
187  for ( size_t i = 0 ; i != deleted_parts.size() ; i++ )
188  {
189  if ( deleted_parts[i] == &new_part )
190  found = true;
191  }
192  STKUNIT_ASSERT ( !found );
193 }
194 
200 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyBulkAddRelation)
201 {
203  fixture.generate_boxes();
204  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
205  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
206 
207  stk_classic::mesh::Part &new_part = fixture.get_test_part();
208  stk_classic::mesh::PartVector add_part,blank_part, buffer_vec;
209  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
210  add_part.push_back ( &new_part );
211 
212  // This test need only run in serial
213  if ( fixture.comm_size() > 1 ) return;
214 
215  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
216  bulk.modification_begin();
217  stk_classic::mesh::Entity &new_node = bulk.declare_entity ( 0 , 123456789 , blank_part );
218  stk_classic::mesh::Entity &existing_cell = *bulk.buckets(3)[0]->begin();
219  bulk.declare_relation ( existing_cell, new_node , 10 );
220  bulk.modification_end();
221 
222  // Verify that nodes were inserted.
223  log.get_parts_with_inserted_entities ( buffer_vec );
224  STKUNIT_ASSERT ( buffer_vec.size() > 0u );
225 
226  // Verify that the element is modified
227  buffer_vec.clear();
228  log.get_parts_with_modified_entities ( buffer_vec );
229  STKUNIT_ASSERT ( buffer_vec.size() > 0u );
230 
231 }
232 
233 
239 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyBulkDelete)
240 {
242  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
243  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
244 
245  stk_classic::mesh::Part &new_part = fixture.get_test_part();
246  stk_classic::mesh::PartVector add_part,blank_part;
247  add_part.push_back ( &new_part );
248 
249 
250  // This test need only run in serial
251  if ( fixture.comm_size() > 1 ) return;
252 
253  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
254  bulk.modification_begin ();
255  stk_classic::mesh::Entity *new_entity = &bulk.declare_entity ( 0 , fixture.comm_size()*1000 + fixture.comm_rank() , add_part );
256  bulk.modification_end ();
257 
258  bulk.reset_transaction ( stk_classic::mesh::Transaction::BULK );
259  bulk.modification_begin ();
260  bulk.destroy_entity ( new_entity );
261  bulk.modification_end ();
262 
263  STKUNIT_ASSERT ( bulk.get_transaction_log().get_deleted_buckets(0).size() == 0 );
264 
265  stk_classic::mesh::PartVector inserted_parts;
266  stk_classic::mesh::PartVector modified_parts;
267  stk_classic::mesh::PartVector deleted_parts;
268  bool inserted_found = false;
269  bulk.get_transaction_log().get_parts_with_inserted_entities ( inserted_parts );
270  for ( size_t i = 0 ; i != deleted_parts.size() ; i++ )
271  {
272  if ( inserted_parts[i] == &new_part )
273  inserted_found = true;
274  }
275  STKUNIT_ASSERT ( !inserted_found );
276 
277  bool modified_found = false;
278  bulk.get_transaction_log().get_parts_with_modified_entities ( modified_parts );
279  for ( size_t i = 0 ; i != deleted_parts.size() ; i++ )
280  {
281  if ( modified_parts[i] == &new_part )
282  modified_found = true;
283  }
284  STKUNIT_ASSERT ( !modified_found );
285 
286  bool deleted_found = false;
287  bulk.get_transaction_log().get_parts_with_deleted_entities ( deleted_parts );
288  for ( size_t i = 0 ; i != deleted_parts.size() ; i++ )
289  {
290  if ( deleted_parts[i] == &new_part )
291  deleted_found = true;
292  }
293  STKUNIT_ASSERT ( deleted_found );
294 }
295 
301 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyTransactionSpanningModifications)
302 {
303  // HCE 3/4/10:
304  // For transactions to span multiple modifications destroyed
305  // mesh entities would have to be retained across multiple
306  // transactions. This creates a problem where the transaction
307  // has to take ownership of the mesh entities away from the
308  // creating bulk data.
309  // This capability needs to be re-thought.
310 
311  return ;
312 
313 
315  fixture.generate_boxes();
316  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
317  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
318 
319  stk_classic::mesh::Part &new_part = fixture.get_test_part();
320  stk_classic::mesh::PartVector add_part,blank_part;
321  add_part.push_back ( &new_part );
322 
323  // This test need only run in serial
324  if ( fixture.comm_size() > 1 ) return;
325 
326 
327  // Here are two modifications. The first adds an edge to the mesh,
328  // the second changes the state of a node
329  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
330  bulk.modification_begin();
331  bulk.declare_entity ( 1 , 10001 , blank_part );
332  bulk.modification_end();
333 
334  bulk.modification_begin();
335  stk_classic::mesh::Entity &n = *(*bulk.buckets(0).begin())->begin();
336  bulk.change_entity_parts ( n , add_part );
337  bulk.modification_end();
338 
339 
340  // Verify both changes are logged
341  STKUNIT_ASSERT ( bulk.get_transaction_log().get_modified_buckets(0).size() == 1 );
342  STKUNIT_ASSERT ( bulk.get_transaction_log().get_inserted_buckets(1).size() == 1 );
343 
344  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
345  // Verify the log is cleared
346  STKUNIT_ASSERT ( bulk.get_transaction_log().get_inserted_buckets(0).size() == 0 );
347  STKUNIT_ASSERT ( bulk.get_transaction_log().get_inserted_buckets(1).size() == 0 );
348 
349 
350  // Cannot end a transaction while the mesh is modifiable
351  // Even though the transaction can span modifications, it cannot be
352  // reset in the middle of a modification
353  bulk.modification_begin();
354  STKUNIT_ASSERT_THROW ( bulk.reset_transaction () , std::runtime_error );
355  bulk.modification_end();
356 
357 }
358 
359 
364 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyIncrementalInsert)
365 {
367  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
368  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
369 
370  stk_classic::mesh::Part &new_part = fixture.get_test_part();
371  stk_classic::mesh::PartVector add_part,blank_part;
372  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
373  add_part.push_back ( &new_part );
374 
375  // This test need only run in serial
376  if ( fixture.comm_size() > 1 ) return;
377 
378  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
379  bulk.modification_begin();
380  // Add 4 entities to the mesh
381  stk_classic::mesh::Entity *entities[4];
382  entities[0] = &bulk.declare_entity ( 0 , 123456789 , blank_part );
383  entities[1] = &bulk.declare_entity ( 1 , 123456789 , blank_part );
384  entities[2] = &bulk.declare_entity ( 2 , 123456789 , blank_part );
385  entities[3] = &bulk.declare_entity ( 3 , 123456789 , blank_part );
386 
387  // Modify one entity to ensure modification does not appear in log
388  bulk.change_entity_parts ( *entities[1] , add_part );
389 
390  // Delete one entity to ensure the entity disappears from log
391  bulk.destroy_entity ( entities[3] );
392  bulk.modification_end();
393 
394  // The first three entities should exist in the insert buckets in
395  // the transaction log
396  for ( unsigned i = 0 ; i != 3 ; i++ )
397  {
398  // Make sure there is only one bucket
399  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(i).size() , 1u );
400  // Make sure the entity is the only thing in the bucket
401  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(i)[0]->size() , 1u );
402 
403  stk_classic::mesh::Entity &new_entity = *((*log.get_inserted_buckets(i).begin())->begin());
404  // Make sure we find the right entity
405  STKUNIT_ASSERT_EQUAL ( &new_entity , entities[i] );
406  // Verify nothing happend to modified and deleted
407  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(i).size() , 0u );
408  STKUNIT_ASSERT_EQUAL ( log.get_deleted_buckets(i).size() , 0u );
409  }
410 
411  // Verify entities[3] disappeared from the log
412  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(3).size() , 0u );
413  STKUNIT_ASSERT_EQUAL ( log.get_deleted_buckets(3).size() , 0u );
414  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(3).size() , 0u );
415 }
416 
417 
418 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyIncrementalModify)
419 {
421  fixture.generate_boxes();
422  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
423  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
424 
425  stk_classic::mesh::Part &new_part = fixture.get_test_part();
426  stk_classic::mesh::PartVector add_part,blank_part;
427  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
428  add_part.push_back ( &new_part );
429 
430  // This test need only run in serial
431  if ( fixture.comm_size() > 1 ) return;
432 
433  // Modify the state of a node and entity in the mesh
434  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
435  bulk.modification_begin();
436  stk_classic::mesh::Entity *entities[2];
437  entities[0] = &*bulk.buckets(0)[0]->begin();
438  entities[1] = &*bulk.buckets(3)[0]->begin();
439  bulk.change_entity_parts ( *entities[0] , add_part );
440  bulk.change_entity_parts ( *entities[1] , add_part );
441  bulk.modification_end();
442 
443  for ( unsigned i = 0 ; i != 2 ; i++ )
444  {
445  unsigned enttype = i*3;
446  // Make sure there is only one bucket
447  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(enttype).size() , 1u );
448  // Make sure the entity is the only thing in the bucket
449  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(enttype)[0]->size() , 1u );
450  stk_classic::mesh::Entity &mod_entity = *log.get_modified_buckets(enttype)[0]->begin();
451  // Make sure we find the right entity
452  STKUNIT_ASSERT_EQUAL ( &mod_entity , entities[i] );
453  // Verify nothing happend to modified and deleted
454  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(enttype).size() , 0u );
455  STKUNIT_ASSERT_EQUAL ( log.get_deleted_buckets(enttype).size() , 0u );
456 
457  // Verify the transaction recorded the modification accurately
458  // 1) Make sure the new part is not part of the previous parts
459  // 2) Make sure the previous parts are in the new parts
460  STKUNIT_ASSERT ( mod_entity.transaction_bucket() != 0 );
461  STKUNIT_ASSERT ( !mod_entity.transaction_bucket()->member ( new_part ) );
462  stk_classic::mesh::PartVector modified_bucket_parts;
463  mod_entity.transaction_bucket()->supersets ( modified_bucket_parts );
464  STKUNIT_ASSERT ( mod_entity.bucket().member_all ( modified_bucket_parts ));
465  }
466 }
467 
468 
469 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyIncrementalAddRelation)
470 {
472  fixture.generate_boxes();
473  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
474  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
475 
476  stk_classic::mesh::Part &new_part = fixture.get_test_part();
477  stk_classic::mesh::PartVector add_part,blank_part;
478  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
479  add_part.push_back ( &new_part );
480 
481  // This test need only run in serial
482  if ( fixture.comm_size() > 1 ) return;
483 
484  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
485  bulk.modification_begin();
486  stk_classic::mesh::Entity &new_node = bulk.declare_entity ( 0 , 123456789 , blank_part );
487  stk_classic::mesh::Entity &existing_cell = *bulk.buckets(3)[0]->begin();
488  bulk.declare_relation ( existing_cell, new_node , 10 );
489  bulk.modification_end();
490 
491  // Verify that no nodes were modified, only inserted.
492  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(0).size() , 1u );
493  STKUNIT_ASSERT_EQUAL ( log.get_inserted_buckets(0)[0]->size() , 1u );
494  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(0).size() , 0u );
495  STKUNIT_ASSERT_EQUAL ( &*log.get_inserted_buckets(0)[0]->begin() , &new_node );
496 
497  // Verify that the element is modified
498  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(3).size() , 1u );
499  STKUNIT_ASSERT_EQUAL ( log.get_modified_buckets(3)[0]->size() , 1u );
500  STKUNIT_ASSERT_EQUAL ( &*log.get_modified_buckets(3)[0]->begin() , &existing_cell );
501 
502  // Make sure the parts have not changed for the existing cell
503  stk_classic::mesh::PartVector old_parts , new_parts;
504  STKUNIT_ASSERT ( existing_cell.transaction_bucket() != 0 );
505  existing_cell.transaction_bucket()->supersets ( old_parts );
506  STKUNIT_ASSERT ( existing_cell.bucket().member_all ( old_parts ) );
507  existing_cell.bucket().supersets ( new_parts );
508  STKUNIT_ASSERT ( existing_cell.transaction_bucket()->member_all ( new_parts ) );
509 
510 }
511 
512 
513 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyIncrementalDelete)
514 {
516  fixture.generate_boxes();
517  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
518  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
519 
520  stk_classic::mesh::Part &new_part = fixture.get_test_part();
521  stk_classic::mesh::PartVector add_part,old_parts;
522  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
523  add_part.push_back ( &new_part );
524 
525  // This test need only run in serial
526  if ( fixture.comm_size() > 1 ) return;
527 
528  // destroy does not delete. element will not be deleted until next
529  // transaction reset
530  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
531  bulk.modification_begin();
532  stk_classic::mesh::Entity *deleted_cell = &*bulk.buckets(3)[0]->begin();
533 
534  // Record the old parts for testing later
535  deleted_cell->bucket().supersets ( old_parts );
536  stk_classic::mesh::EntityId deleted_cell_id = deleted_cell->identifier();
537  bulk.destroy_entity ( deleted_cell );
538  bulk.modification_end();
539 
540  // Verify that the element is deleted
541  STKUNIT_ASSERT_EQUAL ( log.get_deleted_buckets(3).size() , 1u );
542  STKUNIT_ASSERT_EQUAL ( log.get_deleted_buckets(3)[0]->size() , 1u );
543  STKUNIT_ASSERT_EQUAL ( (*log.get_deleted_buckets(3)[0]->begin()).identifier() , deleted_cell_id );
544 
545  // Check for the old parts
546  deleted_cell = &*log.get_deleted_buckets(3)[0]->begin();
547  STKUNIT_ASSERT ( deleted_cell->transaction_bucket() != 0 );
548  STKUNIT_ASSERT ( deleted_cell->transaction_bucket()->member_all ( old_parts ) );
549  stk_classic::mesh::PartVector old_in_trans;
550  deleted_cell->transaction_bucket()->supersets ( old_in_trans );
551  STKUNIT_ASSERT_EQUAL ( old_in_trans.size() , old_parts.size() );
552 }
553 
554 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyParallelChangeOwnership)
555 {
557  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
558  bulk.modification_end(); // Comes out of fixture in MODIFIABLE
559 
560  stk_classic::mesh::Part &new_part = fixture.get_test_part();
561  stk_classic::mesh::PartVector add_part,blank_part;
562 // const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
563  add_part.push_back ( &new_part );
564 
565  // This test needs four processes to work
566  if ( fixture.comm_size() < 4 ) return;
567 
568  bulk.modification_begin ();
569  stk_classic::mesh::Entity *entity = 0;
570  bulk.declare_entity ( 0 , fixture.comm_rank()+1 , blank_part );
571  if ( fixture.comm_rank() < 3 )
572  entity = &bulk.declare_entity ( 0 , 1234 , blank_part );
573  bulk.modification_end();
574 
575  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
576  std::vector <stk_classic::mesh::EntityProc> change_owner;
577  if ( entity )
578  if ( fixture.comm_rank() == entity->owner_rank() )
579  {
580  int other_rank = fixture.comm_rank()==0?1:0;
581  change_owner.push_back ( std::make_pair ( entity , other_rank ) );
582  }
583  bulk.modification_begin();
584  bulk.change_entity_owner ( change_owner );
585  bulk.modification_end();
586 
587  /********* This needs to be fixed: we need to know what correct
588  * behavior should be
589  if ( entity )
590  {
591  if ( fixture.comm_rank() < 3 )
592  {
593  STKUNIT_ASSERT ( entity->transaction_bucket()->transaction_state() == stk_classic::mesh::Transaction::MODIFIED );
594  }
595  }
596  ******************/
597 }
598 
599 STKUNIT_UNIT_TEST(UnitTestTransaction, verifyParallelResolutionModify)
600 {
602  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
603  bulk.modification_end();
604 
605  stk_classic::mesh::Part &new_part = fixture.get_test_part();
606  const stk_classic::mesh::MetaData &meta = fixture.meta_data();
607  const stk_classic::mesh::Transaction &log = bulk.get_transaction_log();
608  stk_classic::mesh::PartVector add_part,old_parts;
609  add_part.push_back ( &new_part );
610 
611  // This test need only run in parallel
612  if ( fixture.comm_size() == 1 ) return;
613  fixture.generate_boxes ();
614 
615 
616  // Find a node to alter, preferable one that is shared
617  const std::vector<stk_classic::mesh::EntityProc> &shared_entities = bulk.shared_entities();
618  stk_classic::mesh::Entity *node_to_modify = 0;
619  for ( unsigned i = 0 ; i != shared_entities.size() ;i++ )
620  {
621  if ( shared_entities[i].first->entity_rank() == 0 )
622  if ( shared_entities[i].first->bucket().member ( meta.locally_owned_part () ) )
623  {
624  node_to_modify = shared_entities[i].first;
625  break;
626  }
627  }
628 
629  // Once found, tell all processes which one. If not found, tell
630  // them that as well
631  int *found_node_list = new int [ bulk.parallel_size() ];
632  stk_classic::mesh::EntityId *found_node_id_list = new stk_classic::mesh::EntityId [ bulk.parallel_size() ];
633 
634 #ifdef STK_HAS_MPI
635  stk_classic::mesh::EntityId node_id = node_to_modify ? node_to_modify->identifier() : 0;
636  int found_a_node = node_to_modify ? 1 : 0;
637 
638  MPI_Allgather ( &found_a_node , 1 , MPI_INT , found_node_list , 1 , MPI_INT , bulk.parallel() );
639  MPI_Allgather ( &node_id , 1 , MPI_INT , found_node_id_list , 1 , MPI_INT , bulk.parallel() );
640 #endif
641 
642  // Modify the node
643  bulk.reset_transaction ( stk_classic::mesh::Transaction::INCREMENTAL );
644  bulk.modification_begin ();
645  if ( node_to_modify )
646  bulk.change_entity_parts ( *node_to_modify , add_part );
647  bulk.modification_end ();
648 
649  // Verify parallel consistent modification
650  // First, loop over everythin in the modified buckets
651  std::vector<stk_classic::mesh::Bucket *>::const_iterator cur_modified_node_bucket = log.get_modified_buckets(0).begin();
652  while ( cur_modified_node_bucket != log.get_modified_buckets(0).end() )
653  {
654  stk_classic::mesh::BucketIterator cur_modified_node = (*cur_modified_node_bucket)->begin();
655  while ( cur_modified_node != (*cur_modified_node_bucket)->begin() )
656  {
657  // For everything located in the buckets, verify it was changed
658  // by another process
659  bool valid_change = false;
660  for ( unsigned i = 0 ; i != bulk.parallel_size() ; i++ )
661  if ( found_node_list[i] == 1 )
662  if ( cur_modified_node->identifier() == found_node_id_list[i] )
663  valid_change = true;
664  STKUNIT_ASSERT ( valid_change );
665  ++cur_modified_node;
666  }
667  ++cur_modified_node_bucket;
668  }
669 
670  delete [] found_node_list;
671  delete [] found_node_id_list;
672 }
673 
674 #endif
675 
stk_classic::mesh::BulkData::parallel
ParallelMachine parallel() const
The parallel machine.
Definition: BulkData.hpp:79
stk_classic::mesh::BulkData::change_entity_owner
void change_entity_owner(const std::vector< EntityProc > &arg_change)
Give away ownership of entities to other parallel processes.
Definition: BulkDataOwner.cpp:313
stk_classic::mesh::BulkData::parallel_size
unsigned parallel_size() const
Size of the parallel machine.
Definition: BulkData.hpp:82
stk_classic::parallel_machine_size
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Definition: Parallel.cpp:18
stk_classic::mesh::MetaData::locally_owned_part
Part & locally_owned_part() const
Subset for the problem domain that is owned by the local process. Ghost entities are not members of t...
Definition: MetaData.hpp:93
stk_classic::mesh::fixtures::BoxFixture
Definition: BoxFixture.hpp:26
stk_classic::mesh::BulkData::destroy_entity
bool destroy_entity(Entity *&entity)
Request the destruction an entity on the local process.
Definition: BulkData.cpp:698
stk_classic::mesh::Part
An application-defined subset of a problem domain.
Definition: Part.hpp:49
stk_classic::mesh::fixtures::BoxFixture::generate_boxes
void generate_boxes(const BOX root_box, BOX local_box)
Definition: BoxFixture.cpp:44
stk_classic::mesh::BulkData::declare_entity
Entity & declare_entity(EntityRank ent_rank, EntityId ent_id, const PartVector &parts)
Create or retrieve a locally owned entity of a given rank and id.
Definition: BulkData.cpp:215
stk_classic::mesh::BulkData::change_entity_parts
void change_entity_parts(Entity &entity, const PartVector &add_parts, const PartVector &remove_parts=PartVector())
Change the parallel-locally-owned entity's part membership by adding and/or removing parts.
Definition: BulkData.hpp:249
stk_classic::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
stk_classic::mesh::BulkData::modification_end
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state.
Definition: BulkDataEndSync.cpp:729
stk_classic::mesh::BulkData::declare_relation
void declare_relation(Entity &e_from, Entity &e_to, const RelationIdentifier local_id)
Declare a relation and its converse between entities in the same mesh.
Definition: BulkDataRelation.cpp:129
stk_classic::mesh::BulkData::modification_begin
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent....
Definition: BulkData.cpp:172
stk_classic::mesh::MetaData
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
stk_classic::mesh::PartVector
std::vector< Part * > PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
stk_classic::mesh::Entity::bucket
Bucket & bucket() const
The bucket which holds this mesh entity's field data.
Definition: Entity.hpp:141
stk_classic::mesh::Entity::identifier
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
Definition: Entity.hpp:133
stk_classic::mesh::Bucket::member_all
bool member_all(const PartVector &) const
Bucket is a subset of all of the given parts.
Definition: Bucket.cpp:71
stk_classic::parallel_machine_rank
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
Definition: Parallel.cpp:29
stk_classic::mesh::Bucket::supersets
void supersets(PartVector &) const
This bucket is a subset of these parts.
Definition: Bucket.cpp:164
stk_classic::mesh::Entity
A fundamental unit within the discretization of a problem domain, including but not limited to nodes,...
Definition: Entity.hpp:120
stk_classic::mesh::BulkData
Manager for an integrated collection of entities, entity relations, and buckets of field data.
Definition: BulkData.hpp:49
stk_classic::mesh::BulkData::buckets
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195