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 
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.
void generate_boxes(const BOX root_box, BOX local_box)
Definition: BoxFixture.cpp:44
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
bool member_all(const PartVector &) const
Bucket is a subset of all of the given parts.
Definition: Bucket.cpp:71
Bucket & bucket() const
The bucket which holds this mesh entity&#39;s field data.
Definition: Entity.hpp:141
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195
An application-defined subset of a problem domain.
Definition: Part.hpp:49
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
Definition: Parallel.cpp:29
void change_entity_parts(Entity &entity, const PartVector &add_parts, const PartVector &remove_parts=PartVector())
Change the parallel-locally-owned entity&#39;s part membership by adding and/or removing parts...
Definition: BulkData.hpp:249
ParallelMachine parallel() const
The parallel machine.
Definition: BulkData.hpp:79
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
bool modification_end()
Parallel synchronization of modifications and transition to the guaranteed parallel consistent state...
unsigned parallel_size() const
Size of the parallel machine.
Definition: BulkData.hpp:82
bool modification_begin()
Begin a modification phase during which the mesh bulk data could become parallel inconsistent. This is a parallel synchronous call. The first time this method is called the mesh meta data is verified to be committed and parallel consistent. An exception is thrown if this verification fails.
Definition: BulkData.cpp:172
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Definition: Parallel.cpp:18
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
void supersets(PartVector &) const
This bucket is a subset of these parts.
Definition: Bucket.cpp:164
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
void change_entity_owner(const std::vector< EntityProc > &arg_change)
Give away ownership of entities to other parallel processes.
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
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
Definition: Entity.hpp:133
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
bool destroy_entity(Entity *&entity)
Request the destruction an entity on the local process.
Definition: BulkData.cpp:698