Sierra Toolkit  Version of the Day
UnitTestBulkData_new.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010, 2011 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 
9 
10 #include <stdexcept>
11 
12 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
13 
14 #include <stk_mesh/fixtures/BoxFixture.hpp>
15 #include <stk_mesh/fixtures/HexFixture.hpp>
16 #include <stk_mesh/fixtures/QuadFixture.hpp>
17 
18 #include <stk_mesh/fem/FEMMetaData.hpp>
19 
20 #include <stk_mesh/base/EntityComm.hpp>
21 #include <stk_mesh/base/FieldData.hpp>
22 
24 
25 // UnitTestBulkData_new is the beginnings of a refactoring of the bulk
26 // data unit test. It relies on a customized BoxFixture to rapidly
27 // create a mesh for testing.
28 
29 namespace {
30 
31 void new_insert_transitive_closure( std::set<stk_classic::mesh::EntityProc,stk_classic::mesh::EntityLess> & ,
32  const stk_classic::mesh::EntityProc & entry );
33 void new_comm_sync_send_recv(
35  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess > & new_send ,
36  std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess > & new_recv );
37 
38 void new_comm_recv_to_send(
40  const std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess > & new_recv ,
41  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess > & new_send );
42 
48 class TestBoxFixture : public stk_classic::mesh::fixtures::BoxFixture
49 {
50  public:
51  TestBoxFixture(stk_classic::ParallelMachine pm = MPI_COMM_WORLD,
52  unsigned block_size = 1000) :
53  BoxFixture(pm, block_size),
54  m_test_part ( m_fem_meta.declare_part ( "Test Part" ) ),
55  m_cell_part ( m_fem_meta.declare_part ( "Cell list" , 3 /*max rank*/ ) ),
56  m_part_A_0 ( m_fem_meta.declare_part ( "Part A 0", 0 ) ),
57  m_part_A_1 ( m_fem_meta.declare_part ( "Part A 1", 1 ) ),
58  m_part_A_2 ( m_fem_meta.declare_part ( "Part A 2", 2 ) ),
59  m_part_A_3 ( m_fem_meta.declare_part ( "Part A 3", 3 ) ),
60  m_part_A_superset ( m_fem_meta.declare_part ( "Part A superset" ) ),
61  m_part_B_0 ( m_fem_meta.declare_part ( "Part B 0", 0 ) ),
62  m_part_B_1 ( m_fem_meta.declare_part ( "Part B 1", 1 ) ),
63  m_part_B_2 ( m_fem_meta.declare_part ( "Part B 2", 2 ) ),
64  m_part_B_3 ( m_fem_meta.declare_part ( "Part B 3", 3 ) ),
65  m_part_B_superset ( m_fem_meta.declare_part ( "Part B superset" ) )
66  {
67  m_fem_meta.declare_part_subset ( m_part_A_superset , m_part_A_0 );
68  m_fem_meta.declare_part_subset ( m_part_A_superset , m_part_A_1 );
69  m_fem_meta.declare_part_subset ( m_part_A_superset , m_part_A_2 );
70  m_fem_meta.declare_part_subset ( m_part_A_superset , m_part_A_3 );
71 
72  m_fem_meta.declare_part_subset ( m_part_B_superset , m_part_B_0 );
73  m_fem_meta.declare_part_subset ( m_part_B_superset , m_part_B_1 );
74  m_fem_meta.declare_part_subset ( m_part_B_superset , m_part_B_2 );
75  m_fem_meta.declare_part_subset ( m_part_B_superset , m_part_B_3 );
76 
77  // None of the tests currently need to make any addtional changes
78  // to MetaData; if this changes, the line below will have to be
79  // removed.
80  m_fem_meta.commit();
81  }
82 
83  Part & get_test_part () { return m_test_part; }
84  Part & get_cell_part () { return m_cell_part; }
85 
86  Part & get_part_a_0 () { return m_part_A_0; }
87  Part & get_part_a_1 () { return m_part_A_1; }
88  Part & get_part_a_2 () { return m_part_A_2; }
89  Part & get_part_a_3 () { return m_part_A_3; }
90 
91  Part & get_part_a_superset () { return m_part_A_superset; }
92 
93  Part & get_part_b_0 () { return m_part_B_0; }
94  Part & get_part_b_1 () { return m_part_B_1; }
95  Part & get_part_b_2 () { return m_part_B_2; }
96  Part & get_part_b_3 () { return m_part_B_3; }
97 
98  Part & get_part_b_superset () { return m_part_B_superset; }
99 
100  private:
101  Part & m_test_part; // A simple part
102  Part & m_cell_part; // A part to put cells in
103 
104  Part & m_part_A_0;
105  Part & m_part_A_1;
106  Part & m_part_A_2;
107  Part & m_part_A_3;
108 
109  Part & m_part_A_superset;
110 
111  Part & m_part_B_0;
112  Part & m_part_B_1;
113  Part & m_part_B_2;
114  Part & m_part_B_3;
115 
116  Part & m_part_B_superset;
117 };
118 
119 }
120 
121 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyAssertOwnerDeletedEntity )
122 {
123  TestBoxFixture fixture;
124 
125  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
126  stk_classic::mesh::Part &new_part = fixture.get_test_part ();
128  add_part.push_back ( &new_part );
129 
130  const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
131  int local_box[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
132 
133  bulk.modification_begin();
134  fixture.generate_boxes( root_box, local_box );
135  STKUNIT_ASSERT(bulk.modification_end());
136 
137  // Find a cell owned by this process
138  stk_classic::mesh::Entity *cell_to_delete = NULL;
139  stk_classic::mesh::Entity *cell_to_delete_copy = NULL;
140  std::vector<stk_classic::mesh::Bucket *>::const_iterator cur_bucket = bulk.buckets(3).begin();
141  while ( cur_bucket != bulk.buckets(3).end() )
142  {
143  stk_classic::mesh::Bucket::iterator cur_entity = (*cur_bucket)->begin();
144  while ( cur_entity != (*cur_bucket)->end() )
145  {
146  if ( cur_entity->owner_rank() == fixture.comm_rank() )
147  {
148  cell_to_delete = &*cur_entity;
149  break;
150  }
151  ++cur_entity;
152  }
153  ++cur_bucket;
154  }
155 
156  STKUNIT_ASSERT ( cell_to_delete != NULL );
157  cell_to_delete_copy = cell_to_delete;
158  bulk.modification_begin();
159  bulk.destroy_entity ( cell_to_delete );
160  // Destroying an already destroyed entity returns false
161  STKUNIT_ASSERT( false == bulk.destroy_entity( cell_to_delete_copy ) );
162  bulk.modification_end();
163 }
164 
165 
166 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyDetectsBadKey )
167 {
168  TestBoxFixture fixture;
169 
170  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
171  stk_classic::mesh::Part &new_part = fixture.get_test_part ();
172  stk_classic::mesh::PartVector add_part, empty_vector;
173  add_part.push_back ( &new_part );
174 
175  stk_classic::mesh::EntityKey bad_key1 ( 45 , 1 ); // Bad entity rank
176  stk_classic::mesh::EntityKey bad_key2 ( 1 , 0 ); // Bad id
177 
178  STKUNIT_ASSERT_THROW ( bulk.declare_entity(bad_key1.rank(),
179  bad_key1.id(),
180  empty_vector),
181  std::logic_error );
182  STKUNIT_ASSERT_THROW ( bulk.declare_entity(bad_key2.rank(),
183  bad_key2.id(),
184  empty_vector),
185  std::logic_error );
186 }
187 
188 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyDetectsNonOwnerChange )
189 {
190  // Set up a mesh where there are shared nodes. Take one of the nodes, and
191  // have the non-owning processes try to make a change to that node; this
192  // should cause an exception.
193 
194  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
195  unsigned p_size = stk_classic::parallel_machine_size(pm);
196  unsigned p_rank = stk_classic::parallel_machine_rank(pm);
197 
198  stk_classic::mesh::fixtures::QuadFixture fixture(pm, 1 /*nx*/, p_size /*ny*/);
199  fixture.m_fem_meta.commit();
200  fixture.generate_mesh();
201  stk_classic::mesh::BulkData & bulk = fixture.m_bulk_data;
202 
203  stk_classic::mesh::PartVector empty_vector;
204 
205  stk_classic::mesh::Entity* shared_node = fixture.node(1 /*x*/, 1 /*y*/);
206  // Assert that this node is shared
207  if ( p_size > 1 && shared_node && (p_rank == 0 || p_rank == 1) ) {
208  STKUNIT_ASSERT_GE(shared_node->sharing().size(), 1u);
209  }
210 
211  bulk.modification_begin();
212 
213  // Non-owners of shared_node will attempt to make a change to it; this should
214  // cause an exception
215  if (shared_node && p_rank != shared_node->owner_rank()) {
216  STKUNIT_ASSERT_THROW(bulk.change_entity_parts(*shared_node,
217  empty_vector, //add parts
218  empty_vector), //rem parts
219  std::logic_error);
220  }
221 
222  bulk.modification_end();
223 }
224 
225 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyGetEntityGuards )
226 {
227  TestBoxFixture fixture;
228 
229  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
230  STKUNIT_ASSERT_THROW ( bulk.get_entity ( 1 , 0 ) , std::logic_error );
231 }
232 
233 
234 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyExplicitAddInducedPart )
235 {
236  TestBoxFixture fixture;
237  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
238  stk_classic::mesh::PartVector empty_vector;
239  stk_classic::mesh::PartVector cell_part_vector;
240 
241  bulk.modification_begin();
242 
243  stk_classic::mesh::Entity &new_cell = bulk.declare_entity ( 3 , fixture.comm_rank()+1 , empty_vector );
244  stk_classic::mesh::Entity &new_node = bulk.declare_entity ( 0 , fixture.comm_rank()+1 , empty_vector );
245 
246  bulk.declare_relation ( new_cell , new_node , 1 );
247 
248  cell_part_vector.push_back ( &fixture.get_cell_part () );
249  bulk.change_entity_parts ( new_cell , cell_part_vector );
250 #ifdef SIERRA_MIGRATION
251  bulk.change_entity_parts ( new_node , cell_part_vector );
252 #else
253  STKUNIT_ASSERT_THROW ( bulk.change_entity_parts ( new_node , cell_part_vector ) , std::runtime_error );
254 #endif
255 }
256 
257 /************************
258  * This unit test is not possible currently because of the lack of
259  * separation between internal part modification routines and public
260  * part modification routines.
261 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyCannotRemoveFromSpecialParts )
262 {
263  stk_classic::mesh::fixtures::BoxFixture fixture;
264  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
265  stk_classic::mesh::PartVector test_parts;
266  stk_classic::mesh::PartVector out_parts;
267  stk_classic::mesh::PartVector empty_vector;
268 
269  stk_classic::mesh::Entity &new_cell = bulk.declare_entity ( 3 , fixture.comm_rank()+1 , empty_vector );
270  test_parts.push_back ( &fixture.fem_meta().universal_part() );
271  STKUNIT_ASSERT_THROW ( bulk.change_entity_parts ( new_cell , empty_vector , test_parts ) , std::runtime_error );
272  test_parts.clear();
273  test_parts.push_back ( &fixture.fem_meta().locally_owned_part() );
274  STKUNIT_ASSERT_THROW ( bulk.change_entity_parts ( new_cell , empty_vector , test_parts ) , std::runtime_error );
275  test_parts.clear();
276  test_parts.push_back ( &fixture.fem_meta().globally_shared_part() );
277  STKUNIT_ASSERT_THROW ( bulk.change_entity_parts ( new_cell , empty_vector , test_parts ) , std::runtime_error );
278 }
279  */
280 
281 
282 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyDefaultPartAddition )
283 {
284  TestBoxFixture fixture;
285  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
286 
287  bulk.modification_begin();
288  stk_classic::mesh::Entity &new_cell = fixture.get_new_entity ( 3 , 1 );
289  bulk.modification_end();
290 
291  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.fem_meta().universal_part() ) );
292  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.fem_meta().locally_owned_part() ) );
293 }
294 
295 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyChangePartsSerial )
296 {
297  TestBoxFixture fixture;
298  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
299  stk_classic::mesh::PartVector create_parts , remove_parts , add_parts, empty_parts;
300 
301  create_parts.push_back ( &fixture.get_test_part() );
302  create_parts.push_back ( &fixture.get_part_a_3() );
303  remove_parts.push_back ( &fixture.get_part_a_3() );
304  add_parts.push_back ( &fixture.get_part_b_superset() );
305  add_parts.push_back ( &fixture.get_cell_part() );
306 
307  bulk.modification_begin();
308  stk_classic::mesh::Entity &new_cell = fixture.get_new_entity ( 3 , 1 );
309  bulk.change_entity_parts ( new_cell , create_parts , empty_parts );
310  bulk.modification_end();
311  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_test_part() ) );
312  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_part_a_3() ) );
313  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_part_a_superset() ) );
314  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_part_b_superset() ) );
315  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_cell_part() ) );
316 
317  bulk.modification_begin();
318  bulk.change_entity_parts ( new_cell , add_parts , remove_parts );
319  bulk.modification_end();
320  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_test_part() ) );
321  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_part_a_3() ) );
322  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_part_a_superset() ) );
323  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_part_b_superset() ) );
324  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_cell_part() ) );
325 
326  bulk.modification_begin();
327  bulk.change_entity_parts ( new_cell , empty_parts , add_parts );
328  bulk.modification_end();
329  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_test_part() ) );
330  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_part_a_3() ) );
331  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.get_part_a_superset() ) );
332  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_part_b_superset() ) );
333  STKUNIT_ASSERT ( !new_cell.bucket().member ( fixture.get_cell_part() ) );
334 
335  //Verify still a member of default parts
336  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.fem_meta().universal_part() ) );
337  STKUNIT_ASSERT ( new_cell.bucket().member ( fixture.fem_meta().locally_owned_part() ) );
338 }
339 
340 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyParallelAddParts )
341 {
342  TestBoxFixture fixture;
343  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
345 
346  const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
347  int local_box[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
348 
349  add_part.push_back ( &fixture.get_part_a_0() );
350 
351  bulk.modification_begin();
352  fixture.generate_boxes( root_box, local_box );
353  STKUNIT_ASSERT(bulk.modification_end());
354 
355  bulk.modification_begin();
356 
357  for ( std::vector<stk_classic::mesh::Entity*>::const_iterator
358  cur_entity = bulk.entity_comm().begin();
359  cur_entity != bulk.entity_comm().end() ; ++cur_entity ) {
360  stk_classic::mesh::Entity & entity = **cur_entity ;
361  if ( entity.entity_rank() == 0 ) {
362  if ( entity.owner_rank() == fixture.comm_rank() ) {
363  bulk.change_entity_parts ( entity, add_part, stk_classic::mesh::PartVector() );
364  }
365  }
366  }
367 
368  bulk.modification_end();
369 
370  for ( std::vector<stk_classic::mesh::Entity*>::const_iterator
371  cur_entity = bulk.entity_comm().begin();
372  cur_entity != bulk.entity_comm().end() ; ++cur_entity ) {
373  stk_classic::mesh::Entity & entity = **cur_entity ;
374  if ( entity.entity_rank() == 0 ) {
375  STKUNIT_ASSERT ( entity.bucket().member ( fixture.get_part_a_0 () ) );
376  }
377  }
378 }
379 
380 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyInducedMembership )
381 {
382  TestBoxFixture fixture;
383  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
384  stk_classic::mesh::PartVector create_node_parts , create_cell_parts , empty_parts;
385 
386  create_node_parts.push_back ( &fixture.get_part_a_0() );
387  create_cell_parts.push_back ( &fixture.get_cell_part() );
388 
389  bulk.modification_begin();
390 
391  stk_classic::mesh::Entity &node = fixture.get_new_entity ( 0 , 1 );
392  stk_classic::mesh::Entity &cell = fixture.get_new_entity ( 3 , 1 );
393 
394  bulk.modification_begin();
395 
396  bulk.change_entity_parts ( node , create_node_parts , stk_classic::mesh::PartVector () );
397  bulk.change_entity_parts ( cell , create_cell_parts , stk_classic::mesh::PartVector () );
398  // Add node to cell part
399  stk_classic::mesh::RelationIdentifier cell_node_rel_id = 0;
400  bulk.declare_relation ( cell , node , cell_node_rel_id );
401  bulk.modification_end();
402 
403  STKUNIT_ASSERT ( node.bucket().member ( fixture.get_cell_part() ) );
404 
405  bulk.modification_begin();
406  bulk.destroy_relation ( cell , node, cell_node_rel_id );
407  bulk.modification_end();
408 
409  STKUNIT_ASSERT ( !node.bucket().member ( fixture.get_cell_part() ) );
410 }
411 
412 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyCanRemoveFromSetWithDifferentRankSubset )
413 {
414  TestBoxFixture fixture;
415  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
416  stk_classic::mesh::PartVector add_parts , remove_parts, empty_parts;
417 
418  add_parts.push_back ( &fixture.get_part_b_3() );
419  add_parts.push_back ( &fixture.get_part_a_superset() );
420 
421  remove_parts.push_back ( &fixture.get_part_a_superset() );
422 
423  bulk.modification_begin();
424 
425  stk_classic::mesh::Entity &e = bulk.declare_entity ( 3 , fixture.comm_rank()+1 , add_parts );
426  bulk.modification_end();
427 
428  bulk.modification_begin();
429  bulk.change_entity_parts ( e , empty_parts , remove_parts );
430  bulk.modification_end();
431 
432  STKUNIT_ASSERT ( e.bucket().member ( fixture.get_part_b_3() ) );
433  STKUNIT_ASSERT ( !e.bucket().member ( fixture.get_part_a_superset() ) );
434 }
435 
436 
437 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyCommonGhostingName )
438 {
439 
440  TestBoxFixture fixture;
441  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
442 
443  bulk.modification_begin();
444 
445  if ( fixture.comm_size() == 1 ) return;
446 
447  if ( fixture.comm_rank() == 0 )
448  {
449  STKUNIT_ASSERT_THROW ( bulk.create_ghosting ( "Name 1" ) , std::runtime_error );
450  }
451  else
452  {
453  STKUNIT_ASSERT_THROW ( bulk.create_ghosting ( "Name 2" ) , std::runtime_error );
454  }
455 }
456 
457 
458 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyTrivialDestroyAllGhostings )
459 {
460  TestBoxFixture fixture;
461 
462  if ( fixture.comm_size() == 1 ) return;
463 
464  stk_classic::mesh::BulkData &bulk = fixture.bulk_data();
465 
466  const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
467  int local_box[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
468 
469  bulk.modification_begin();
470  fixture.generate_boxes( root_box, local_box );
471  STKUNIT_ASSERT(bulk.modification_end());
472 
473  bulk.modification_begin();
474 
475  stk_classic::mesh::Ghosting &ghosting = bulk.create_ghosting ( "Ghost 1" );
476 
477  // Find a cell owned by this process
478  std::vector<stk_classic::mesh::Bucket *>::const_iterator cur_bucket = bulk.buckets(3).begin();
479  unsigned send_rank = 0;
480 
481  std::vector<stk_classic::mesh::EntityProc> to_send;
482  std::vector<stk_classic::mesh::Entity *> empty_vector;
483  while ( cur_bucket != bulk.buckets(3).end() )
484  {
485  stk_classic::mesh::Bucket::iterator cur_entity = (*cur_bucket)->begin();
486  while ( cur_entity != (*cur_bucket)->end() )
487  {
488  if ( cur_entity->owner_rank() == fixture.comm_rank() )
489  {
490  if ( send_rank == fixture.comm_size() ) send_rank = 0;
491  if ( send_rank != fixture.comm_rank() )
492  to_send.push_back ( std::make_pair ( &*cur_entity , send_rank ) );
493  send_rank++;
494  }
495  ++cur_entity;
496  }
497  ++cur_bucket;
498  }
499  bulk.change_ghosting ( ghosting , to_send , empty_vector );
500  bulk.modification_end();
501 
502 
503  {
504  std::vector<stk_classic::mesh::EntityProc> send_list ;
505  std::vector<stk_classic::mesh::Entity*> recv_list ;
506  ghosting.send_list( send_list );
507  ghosting.receive_list( recv_list );
508 
509  STKUNIT_ASSERT ( ! send_list.empty() );
510  STKUNIT_ASSERT ( ! recv_list.empty() );
511  }
512 
513  // Usage of operator << in Ghosting.cpp
514  std::ostringstream oss;
515  oss << ghosting;
516 
517  bulk.modification_begin();
518  bulk.destroy_all_ghosting ();
519  bulk.modification_end();
520 
521  {
522  std::vector<stk_classic::mesh::EntityProc> send_list ;
523  std::vector<stk_classic::mesh::Entity*> recv_list ;
524  ghosting.send_list( send_list );
525  ghosting.receive_list( recv_list );
526 
527  STKUNIT_ASSERT ( send_list.empty() );
528  STKUNIT_ASSERT ( recv_list.empty() );
529  }
530 }
531 
532 
533 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyChangeGhostingGuards )
534 {
535  TestBoxFixture fixture1, fixture2;
536  stk_classic::mesh::BulkData & bulk1 = fixture1.bulk_data ();
537  stk_classic::mesh::BulkData & bulk2 = fixture2.bulk_data ();
538 
539  const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
540  int local_box1[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
541  int local_box2[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
542 
543  bulk1.modification_begin();
544  fixture1.generate_boxes( root_box, local_box1 );
545  STKUNIT_ASSERT(bulk1.modification_end());
546 
547  bulk2.modification_begin();
548  fixture2.generate_boxes( root_box, local_box2 );
549  STKUNIT_ASSERT(bulk2.modification_end());
550 
551  bulk1.modification_begin();
552  bulk2.modification_begin();
553 
554  std::vector<stk_classic::mesh::EntityProc> to_send;
555  std::vector<stk_classic::mesh::Entity *> empty_vector;
556  std::vector<stk_classic::mesh::Bucket *>::const_iterator cur_bucket = bulk1.buckets(3).begin();
557  unsigned send_rank = 0;
558  while ( cur_bucket != bulk1.buckets(3).end() )
559  {
560  stk_classic::mesh::Bucket::iterator cur_entity = (*cur_bucket)->begin();
561  while ( cur_entity != (*cur_bucket)->end() )
562  {
563  if ( cur_entity->owner_rank() == fixture1.comm_rank() )
564  {
565  if ( send_rank == fixture1.comm_size() ) send_rank = 0;
566  if ( send_rank != fixture1.comm_rank() )
567  to_send.push_back ( std::make_pair ( &*cur_entity , send_rank ) );
568  ++send_rank;
569  }
570  ++cur_entity;
571  }
572  ++cur_bucket;
573  }
574 
575  stk_classic::mesh::Ghosting &ghosting = bulk1.create_ghosting ( "Ghost 1" );
576  STKUNIT_ASSERT_THROW ( bulk2.change_ghosting ( ghosting , to_send , empty_vector ) , std::runtime_error );
577  STKUNIT_ASSERT_THROW ( bulk1.change_ghosting ( bulk1.shared_aura() , to_send , empty_vector ) , std::runtime_error );
578 
579  ghosting.receive_list(empty_vector);
580  ghosting.send_list(to_send);
581 
582  bulk1.modification_end();
583  bulk2.modification_end();
584 }
585 
586 
587 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyOtherGhostingGuards )
588 {
589  TestBoxFixture fixture;
590  stk_classic::mesh::BulkData &bulk = fixture.bulk_data ();
591 
592  const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
593  int local_box[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
594 
595  bulk.modification_begin();
596  fixture.generate_boxes( root_box, local_box );
597  STKUNIT_ASSERT(bulk.modification_end());
598 
599  bulk.modification_begin();
600 
601  std::vector<stk_classic::mesh::EntityProc> to_send_unowned;
602  std::vector<stk_classic::mesh::EntityProc> empty_send;
603  std::vector<stk_classic::mesh::Entity *> to_remove_not_ghosted;
604  std::vector<stk_classic::mesh::Entity *> empty_remove;
605  std::vector<stk_classic::mesh::Bucket *>::const_iterator cur_bucket = bulk.buckets(3).begin();
606  unsigned send_rank = 0;
607  while ( cur_bucket != bulk.buckets(3).end() )
608  {
609  stk_classic::mesh::Bucket::iterator cur_entity = (*cur_bucket)->begin();
610  while ( cur_entity != (*cur_bucket)->end() )
611  {
612  if ( cur_entity->owner_rank() != fixture.comm_rank() )
613  {
614  if ( send_rank == fixture.comm_size() ) send_rank = 0;
615  if ( send_rank != fixture.comm_rank() )
616  to_send_unowned.push_back ( std::make_pair ( &*cur_entity , send_rank ) );
617  ++send_rank;
618  }
619  else
620  {
621  to_remove_not_ghosted.push_back ( &*cur_entity );
622  }
623  ++cur_entity;
624  }
625  ++cur_bucket;
626  }
627 
628  stk_classic::mesh::Ghosting &ghosting = bulk.create_ghosting ( "Ghost 1" );
629  if ( to_send_unowned.size() > 0 )
630  {
631  STKUNIT_ASSERT_THROW ( bulk.change_ghosting ( ghosting , to_send_unowned , empty_remove ) , std::runtime_error );
632  }
633  else
634  {
635  bulk.change_ghosting ( ghosting , to_send_unowned , empty_remove );
636  }
637 
638  if ( to_remove_not_ghosted.size() > 0 )
639  {
640  STKUNIT_ASSERT_THROW ( bulk.change_ghosting ( ghosting , empty_send , to_remove_not_ghosted ) , std::runtime_error );
641  }
642  else
643  {
644  bulk.change_ghosting ( ghosting , empty_send , to_remove_not_ghosted );
645  }
646  bulk.modification_end();
647 }
648 
649 
650 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyPartsOnCreate )
651 {
652  TestBoxFixture fixture;
653  stk_classic::mesh::BulkData & bulk = fixture.bulk_data ();
654  stk_classic::mesh::Part & part_a = fixture.get_part_a_0 ();
655  stk_classic::mesh::Part & part_b = fixture.get_part_b_0 ();
656 
657  stk_classic::mesh::PartVector create_vector;
658  create_vector.push_back ( &part_a );
659 
660  bulk.modification_begin();
661 
662  stk_classic::mesh::Entity &node = bulk.declare_entity ( 0 , fixture.comm_rank()+1 ,create_vector );
663  bulk.modification_end();
664 
665  STKUNIT_ASSERT ( node.bucket().member ( part_a ) );
666 
667  bulk.modification_begin();
668  create_vector.push_back ( &part_b );
669  stk_classic::mesh::Entity &node2 = bulk.declare_entity ( 0 , fixture.comm_size() + fixture.comm_rank() + 1 , create_vector );
670  bulk.modification_end();
671 
672  STKUNIT_ASSERT ( node2.bucket().member ( part_a ) );
673  STKUNIT_ASSERT ( node2.bucket().member ( part_b ) );
674 }
675 
676 //----------------------------------------------------------------------
677 
678 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , verifyBoxGhosting )
679 {
680  const unsigned p_size = stk_classic::parallel_machine_size( MPI_COMM_WORLD );
681  if ( 8 < p_size ) { return ; }
682 
683  stk_classic::mesh::fixtures::HexFixture fixture( MPI_COMM_WORLD, 2, 2, 2 );
684  fixture.m_fem_meta.commit();
685  fixture.generate_mesh();
686 
687  for ( size_t iz = 0 ; iz < 3 ; ++iz ) {
688  for ( size_t iy = 0 ; iy < 3 ; ++iy ) {
689  for ( size_t ix = 0 ; ix < 3 ; ++ix ) {
690  stk_classic::mesh::Entity * const node = fixture.node(ix,iy,iz);
691  STKUNIT_ASSERT( NULL != node );
692 
693  STKUNIT_ASSERT( fixture.node_id(ix,iy,iz) == node->identifier() );
694  stk_classic::mesh::fixtures::HexFixture::Scalar * const node_coord =
695  stk_classic::mesh::field_data( fixture.m_coord_field , *node );
696  STKUNIT_ASSERT( node_coord != NULL );
697  }
698  }
699  }
700 
701  for ( size_t iz = 0 ; iz < 2 ; ++iz ) {
702  for ( size_t iy = 0 ; iy < 2 ; ++iy ) {
703  for ( size_t ix = 0 ; ix < 2 ; ++ix ) {
704  stk_classic::mesh::Entity * const elem = fixture.elem(ix,iy,iz);
705  STKUNIT_ASSERT( NULL != elem );
706 
707  stk_classic::mesh::PairIterRelation elem_nodes = elem->relations();
708  STKUNIT_ASSERT_EQUAL( 8u , elem_nodes.size() );
709  stk_classic::mesh::fixtures::HexFixture::Scalar ** const elem_node_coord =
710  stk_classic::mesh::field_data( fixture.m_coord_gather_field , *elem );
711  for ( size_t j = 0 ; j < elem_nodes.size() ; ++j ) {
712  STKUNIT_ASSERT_EQUAL( j , elem_nodes[j].identifier() );
713  stk_classic::mesh::fixtures::HexFixture::Scalar * const node_coord =
714  stk_classic::mesh::field_data( fixture.m_coord_field , *elem_nodes[j].entity() );
715  STKUNIT_ASSERT( node_coord == elem_node_coord[ elem_nodes[j].identifier() ] );
716  }
717  if ( 8u == elem_nodes.size() ) {
718  STKUNIT_ASSERT( elem_nodes[0].entity() == fixture.node(ix,iy,iz));
719  STKUNIT_ASSERT( elem_nodes[1].entity() == fixture.node(ix+1,iy,iz));
720  STKUNIT_ASSERT( elem_nodes[2].entity() == fixture.node(ix+1,iy,iz+1));
721  STKUNIT_ASSERT( elem_nodes[3].entity() == fixture.node(ix,iy,iz+1));
722  STKUNIT_ASSERT( elem_nodes[4].entity() == fixture.node(ix,iy+1,iz));
723  STKUNIT_ASSERT( elem_nodes[5].entity() == fixture.node(ix+1,iy+1,iz));
724  STKUNIT_ASSERT( elem_nodes[6].entity() == fixture.node(ix+1,iy+1,iz+1));
725  STKUNIT_ASSERT( elem_nodes[7].entity() == fixture.node(ix,iy+1,iz+1));
726  }
727 
728  }
729  }
730  }
731 }
732 
733 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , testEntityComm )
734 {
735  //Test on unpack_field_values in EntityComm.cpp
736  //code based on ../base/BulkDataGhosting.cpp
737  //Create a simple mesh. Add nodes one element and some parts.
738 
739  const int spatial_dimension = 3;
740 
742  fem_meta.FEM_initialize(spatial_dimension, stk_classic::mesh::fem::entity_rank_names ( spatial_dimension ));
743 
744  stk_classic::mesh::fem::CellTopology tet_top(shards::getCellTopologyData<shards::Tetrahedron<4> >());
745  stk_classic::mesh::Part & part_a = fem_meta.declare_part( "block_a", tet_top );
746  stk_classic::mesh::Part & part_b = fem_meta.declare_part( "block_b", tet_top );
747 
748  stk_classic::mesh::fem::CellTopology node_top(shards::getCellTopologyData<shards::Node>());
749  stk_classic::mesh::Part & part_a_0 = fem_meta.declare_part( "block_a_0", node_top );
750 
752 
753  ScalarFieldType & volume =
754  fem_meta.declare_field < ScalarFieldType > ( "volume" , 4 );
755  ScalarFieldType & temperature =
756  fem_meta.declare_field < ScalarFieldType > ( "temperature" , 4 );
757  stk_classic::mesh::Part & universal = fem_meta.universal_part ();
758  put_field ( volume , 3 , universal );
759  put_field ( temperature , 3 , universal );
760 
761  fem_meta.commit();
762 
763  stk_classic::mesh::PartVector create_vector;
764  stk_classic::mesh::PartVector empty_vector;
765  create_vector.push_back ( &part_a );
766  create_vector.push_back ( &part_b );
767 
769  stk_classic::mesh::BulkData bulk ( meta , MPI_COMM_WORLD , 100 );
770 
771  bulk.modification_begin();
772 
773  stk_classic::mesh::Ghosting &ghosts = bulk.create_ghosting ( "Ghost 1" );
774 
775  unsigned size2 = stk_classic::parallel_machine_size( MPI_COMM_WORLD );
776  unsigned rank_count2 = stk_classic::parallel_machine_rank( MPI_COMM_WORLD );
777  int new_id2 = size2 + rank_count2;
778 
779  stk_classic::mesh::Entity &elem2 = bulk.declare_entity ( 3 , new_id2+1 ,create_vector );
780  STKUNIT_ASSERT_EQUAL( elem2.bucket().member ( part_a ), true );
781 
782  unsigned size = stk_classic::parallel_machine_size( MPI_COMM_WORLD );
783  unsigned rank_count = stk_classic::parallel_machine_rank( MPI_COMM_WORLD );
784 
785  int id_base = 0;
786  for ( id_base = 0 ; id_base < 99 ; ++id_base )
787  {
788  int new_id = size * id_base + rank_count;
789  stk_classic::mesh::Entity &new_node = bulk.declare_entity( 0 , new_id+1 , empty_vector );
790  STKUNIT_ASSERT_EQUAL( new_node.bucket().member ( part_a_0 ), false );
791  }
792 
793  //Create a bucket of nodes for sending
794 
795  std::vector<stk_classic::mesh::EntityProc> add_send;
796 
797  const std::vector<stk_classic::mesh::Bucket*> & buckets = bulk.buckets( 0 );
798 
799  std::vector<stk_classic::mesh::Bucket*>::const_iterator cur_bucket;
800 
801  cur_bucket = buckets.begin();
802 
803  unsigned send_rank = 0;
804  while ( cur_bucket != buckets.end() )
805  {
806  stk_classic::mesh::Bucket::iterator cur_entity = (*cur_bucket)->begin();
807  while ( cur_entity != (*cur_bucket)->end() )
808  {
809  if ( cur_entity->owner_rank() == rank_count )
810  {
811  if ( send_rank == size ) send_rank = 0;
812  if ( send_rank != rank_count )
813  add_send.push_back ( std::make_pair ( &*cur_entity , send_rank ) );
814  ++send_rank;
815  }
816  ++cur_entity;
817  }
818  ++cur_bucket;
819  }
820 
821  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess > new_send ;
822  std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess > new_recv ;
823 
824  // Keep the closure of the remaining received ghosts.
825  // Working from highest-to-lowest key (rank entity type)
826  // results in insertion of the transitive closure.
827  // Insertion will not invalidate the associative container's iterator.
828 
829  for ( std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess >::iterator
830  i = new_recv.end() ; i != new_recv.begin() ; ) {
831  --i ;
832 
833  const unsigned erank = (*i)->entity_rank();
834 
836  irel = (*i)->relations(); ! irel.empty() ; ++irel ) {
837  if ( irel->entity_rank() < erank &&
838  in_receive_ghost( ghosts , * irel->entity() ) ) {
839  new_recv.insert( irel->entity() );
840  }
841  }
842  }
843 
844  // Initialize the new_send from the new_recv
845  new_comm_recv_to_send( bulk , new_recv , new_send );
846 
847  //------------------------------------
848  // Add the specified entities and their closure to the send ghosting
849 
850  for ( std::vector< stk_classic::mesh::EntityProc >::const_iterator
851  i = add_send.begin() ; i != add_send.end() ; ++i ) {
852  new_insert_transitive_closure( new_send , *i );
853  }
854 
855  // Synchronize the send and receive list.
856  // If the send list contains a not-owned entity
857  // inform the owner and receiver to ad that entity
858  // to their ghost send and receive lists.
859 
860  new_comm_sync_send_recv( bulk , new_send , new_recv );
861 
862  //------------------------------------
863  // Push newly ghosted entities to the receivers and update the comm list.
864  // Unpacking must proceed in entity-rank order so that higher ranking
865  // entities that have relations to lower ranking entities will have
866  // the lower ranking entities unpacked first. The higher and lower
867  // ranking entities may be owned by different processes,
868  // as such unpacking must be performed in rank order.
869 
870  //Start of CommAll section:
871  {
872  stk_classic::CommAll comm( MPI_COMM_WORLD );
873 
874  for ( std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess >::iterator
875  j = new_send.begin(); j != new_send.end() ; ++j ) {
876  stk_classic::mesh::Entity & entity = * j->first ;
877  if ( ! in_ghost( ghosts , entity , j->second ) ) {
878  // Not already being sent , must send it.
879  stk_classic::CommBuffer & buf = comm.send_buffer( j->second );
880  buf.pack<unsigned>( entity.entity_rank() );
881  stk_classic::mesh::pack_entity_info( buf , entity );
882  stk_classic::mesh::pack_field_values( buf , entity );
883  }
884  }
885 
886  comm.allocate_buffers( size / 4 );
887 
888  for ( std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess >::iterator
889  j = new_send.begin(); j != new_send.end() ; ++j ) {
890  stk_classic::mesh::Entity & entity = * j->first ;
891  if ( ! in_ghost( ghosts , entity , j->second ) ) {
892  // Not already being sent , must send it.
893  stk_classic::CommBuffer & buf = comm.send_buffer( j->second );
894  buf.pack<unsigned>( entity.entity_rank() );
895  stk_classic::mesh::pack_entity_info( buf , entity );
896  stk_classic::mesh::pack_field_values( buf , entity );
897 
898  }
899  }
900 
901  comm.communicate();
902 
903  std::ostringstream error_msg ;
904 
905  for ( unsigned rank = 0 ; rank < rank_count ; ++rank ) {
906 
907  for ( unsigned p = 0 ; p < size ; ++p ) {
908 
909  stk_classic::CommBuffer & buf = comm.recv_buffer(p);
910 
911  while ( buf.remaining() ) {
912 
913  // Only unpack if of the current entity rank.
914  // If not the current entity rank, break the iteration
915  // until a subsequent entity rank iteration.
916  {
917  unsigned this_rank = ~0u ;
918  buf.peek<unsigned>( this_rank );
919  if ( this_rank != rank ) break ;
920 
921  buf.unpack<unsigned>( this_rank );
922  }
923 
924  // FIXME for Carol; the code below did not work with -np 4
925  //STKUNIT_ASSERT_EQUAL( stk_classic::mesh::unpack_field_values( buf , elem2 , error_msg ), false);
926  //std::cout << "Error message for unpack_field_values = " << error_msg.str() << std::endl ;
927 
928  }
929  }
930 
931  }
932  }//end of CommAll section
933 
934  bulk.modification_end ();
935 }
936 
937 STKUNIT_UNIT_TEST ( UnitTestBulkData_new , testUninitializedMetaData )
938 {
939  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
940 
941  stk_classic::mesh::MetaData meta; // Construct, but do not initialize
942  stk_classic::mesh::BulkData bulk(meta, pm);
943 
944  meta.set_entity_rank_names(stk_classic::mesh::fem::entity_rank_names(2 /*spatial-dim*/));
945 
946  meta.commit();
947 
948  bulk.modification_begin();
949 
950  STKUNIT_ASSERT_THROW( bulk.declare_entity(0, /*rank*/
951  1, /*id*/
953  std::logic_error);
954 }
955 
956 namespace {
957 
958 void new_insert_transitive_closure( std::set<stk_classic::mesh::EntityProc,stk_classic::mesh::EntityLess> & new_send ,
959  const stk_classic::mesh::EntityProc & entry )
960 {
961  // Do not insert if I can determine that this entity is already
962  // owned or shared by the receiving processor.
963 
964  if ( entry.second != entry.first->owner_rank() &&
965  ! in_shared( * entry.first , entry.second ) ) {
966 
967  std::pair< std::set<stk_classic::mesh::EntityProc,stk_classic::mesh::EntityLess>::iterator , bool >
968  result = new_send.insert( entry );
969 
970  if ( result.second ) {
971  // A new insertion, must also insert the closure
972 
973  const unsigned etype = entry.first->entity_rank();
974  stk_classic::mesh::PairIterRelation irel = entry.first->relations();
975 
976  for ( ; ! irel.empty() ; ++irel ) {
977  if ( irel->entity_rank() < etype ) {
978  stk_classic::mesh::EntityProc tmp( irel->entity() , entry.second );
979  new_insert_transitive_closure( new_send , tmp );
980  }
981  }
982  }
983  }
984 }
985 
986 
987 // Synchronize the send list to the receive list.
988 
989 void new_comm_sync_send_recv(
991  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess > & new_send ,
992  std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess > & new_recv )
993 {
994  const unsigned parallel_rank = mesh.parallel_rank();
995  const unsigned parallel_size = mesh.parallel_size();
996 
997  stk_classic::CommAll all( mesh.parallel() );
998 
999  // Communication sizing:
1000 
1001  for ( std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess >::iterator
1002  i = new_send.begin() ; i != new_send.end() ; ++i ) {
1003  const unsigned owner = i->first->owner_rank();
1004  all.send_buffer( i->second ).skip<stk_classic::mesh::EntityKey>(2);
1005  if ( owner != parallel_rank ) {
1006  all.send_buffer( owner ).skip<stk_classic::mesh::EntityKey>(2);
1007  }
1008  }
1009 
1010  all.allocate_buffers( parallel_size / 4 , false /* Not symmetric */ );
1011 
1012  // Communication packing (with message content comments):
1013  for ( std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess >::iterator
1014  i = new_send.begin() ; i != new_send.end() ; ) {
1015  const unsigned owner = i->first->owner_rank();
1016 
1017  // Inform receiver of ghosting, the receiver does not own
1018  // and does not share this entity.
1019  // The ghost either already exists or is a to-be-done new ghost.
1020  // This status will be resolved on the final communication pass
1021  // when new ghosts are packed and sent.
1022 
1023  const stk_classic::mesh::EntityKey &entity_key = i->first->key();
1024  const uint64_t &proc = i->second;
1025 
1026  all.send_buffer( i->second ).pack(entity_key).pack(proc);
1027 
1028  if ( owner != parallel_rank ) {
1029  // I am not the owner of this entity.
1030  // Inform the owner of this ghosting need.
1031  all.send_buffer( owner ).pack(entity_key).pack(proc);
1032 
1033  // Erase it from my processor's ghosting responsibility:
1034  // The iterator passed to the erase method will be invalidated.
1035  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess >::iterator jrem = i ; ++i ;
1036  new_send.erase( jrem );
1037  }
1038  else {
1039  ++i ;
1040  }
1041  }
1042 
1043  all.communicate();
1044 
1045  // Communication unpacking:
1046  for ( unsigned p = 0 ; p < parallel_size ; ++p ) {
1047  stk_classic::CommBuffer & buf = all.recv_buffer(p);
1048  while ( buf.remaining() ) {
1049 
1050  stk_classic::mesh::EntityKey entity_key;
1051  uint64_t proc(0);
1052 
1053  buf.unpack(entity_key).unpack(proc);
1054 
1055  stk_classic::mesh::Entity * const e = mesh.get_entity( entity_key );
1056 
1057  if ( parallel_rank != proc ) {
1058  // Receiving a ghosting need for an entity I own.
1059  // Add it to my send list.
1060  STKUNIT_ASSERT( e != NULL );
1061  stk_classic::mesh::EntityProc tmp( e , proc );
1062  new_send.insert( tmp );
1063  }
1064  else if ( e != NULL ) {
1065  // I am the receiver for this ghost.
1066  // If I already have it add it to the receive list,
1067  // otherwise don't worry about it - I will receive
1068  // it in the final new-ghosting communication.
1069  new_recv.insert( e );
1070  }
1071  }
1072  }
1073 }
1074 
1075 void new_comm_recv_to_send(
1077  const std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess > & new_recv ,
1078  std::set< stk_classic::mesh::EntityProc , stk_classic::mesh::EntityLess > & new_send )
1079 {
1080  const unsigned parallel_size = mesh.parallel_size();
1081 
1082  stk_classic::CommAll all( mesh.parallel() );
1083 
1084  for ( std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess >::const_iterator
1085  i = new_recv.begin() ; i != new_recv.end() ; ++i ) {
1086  const unsigned owner = (*i)->owner_rank();
1087  all.send_buffer( owner ).skip<stk_classic::mesh::EntityKey>(1);
1088  }
1089 
1090  all.allocate_buffers( parallel_size / 4 , false /* Not symmetric */ );
1091 
1092  for ( std::set< stk_classic::mesh::Entity * , stk_classic::mesh::EntityLess >::const_iterator
1093  i = new_recv.begin() ; i != new_recv.end() ; ++i ) {
1094  const unsigned owner = (*i)->owner_rank();
1095  const stk_classic::mesh::EntityKey key = (*i)->key();
1096  all.send_buffer( owner ).pack<stk_classic::mesh::EntityKey>( & key , 1 );
1097  }
1098 
1099  all.communicate();
1100 
1101  for ( unsigned p = 0 ; p < parallel_size ; ++p ) {
1102  stk_classic::CommBuffer & buf = all.recv_buffer(p);
1103  while ( buf.remaining() ) {
1105  buf.unpack<stk_classic::mesh::EntityKey>( & key , 1 );
1106  stk_classic::mesh::EntityProc tmp( mesh.get_entity( entity_rank(key), entity_id(key) ) , p );
1107  new_send.insert( tmp );
1108  }
1109  }
1110 }
1111 
1112 }
stk_classic::mesh::put_field
field_type & put_field(field_type &field, EntityRank entity_rank, const Part &part, const void *init_value=NULL)
Declare a field to exist for a given entity type and Part.
stk_classic::mesh::Entity::sharing
PairIterEntityComm sharing() const
Parallel processes which share this entity.
Definition: Entity.hpp:178
stk_classic::mesh::EntityKey
Integer type for the entity keys, which is an encoding of the entity type and entity identifier.
Definition: base/EntityKey.hpp:63
stk_classic::mesh::field_data
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
Definition: FieldData.hpp:116
stk_classic::mesh::BulkData::parallel
ParallelMachine parallel() const
The parallel machine.
Definition: BulkData.hpp:79
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::BulkData::parallel_rank
unsigned parallel_rank() const
Rank of the parallel machine's local processor.
Definition: BulkData.hpp:85
stk_classic::mesh::fixtures::BoxFixture
Definition: BoxFixture.hpp:26
stk_classic::mesh::Field< double >
stk_classic::mesh::BulkData::shared_aura
Ghosting & shared_aura() const
Query the shared-entity aura. Is likely to be stale if ownership or sharing has changed and the 'modi...
Definition: BulkData.hpp:375
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::Bucket::member
bool member(const Part &) const
Bucket is a subset of the given part.
Definition: Bucket.cpp:60
stk_classic::mesh::Part
An application-defined subset of a problem domain.
Definition: Part.hpp:49
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::mesh::MetaData::commit
void commit()
Commit the part and field declarations so that the meta data manager can be used to create mesh bulk ...
Definition: MetaData.cpp:368
stk_classic::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
stk_classic::mesh::BulkData::destroy_all_ghosting
void destroy_all_ghosting()
Empty every single Ghosting. Same result, but more efficient than, calling change_ghosting to remove ...
Definition: BulkDataGhosting.cpp:102
stk_classic::mesh::fixtures::HexFixture
Definition: HexFixture.hpp:36
stk_classic::mesh::BulkData::get_entity
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
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::Ghosting::send_list
void send_list(std::vector< EntityProc > &) const
Locally owned entities ghosted on other processors.
Definition: Ghosting.cpp:17
stk_classic::mesh::fem::FEMMetaData::get_meta_data
static MetaData & get_meta_data(FEMMetaData &fem_meta)
Getter for MetaData off of a FEMMetaData object.
Definition: FEMMetaData.hpp:113
stk_classic::mesh::fem::FEMMetaData::declare_part
Part & declare_part(const std::string &name, fem::CellTopology cell_topology)
Declare a part with a given cell topology.
Definition: FEMMetaData.hpp:240
stk_classic::mesh::fem::FEMMetaData::commit
void commit()
Commit the part and field declarations so that the meta data manager can be used to create mesh bulk ...
Definition: FEMMetaData.hpp:466
stk_classic::mesh::MetaData::set_entity_rank_names
void set_entity_rank_names(const std::vector< std::string > &entity_rank_names)
entity-rank names
Definition: MetaData.cpp:155
stk_classic::mesh::BulkData::create_ghosting
Ghosting & create_ghosting(const std::string &name)
Asymmetric parallel relations for owner-to-ghosted mesh entities.
Definition: BulkDataGhosting.cpp:38
stk_classic::mesh::BulkData::entity_comm
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
Definition: BulkData.hpp:367
stk_classic::mesh::BulkData::destroy_relation
bool destroy_relation(Entity &e_from, Entity &e_to, const RelationIdentifier local_id)
Remove all relations between two entities.
Definition: BulkDataRelation.cpp:191
stk_classic::mesh::entity_id
EntityId entity_id(const EntityKey &key)
Given an entity key, return the identifier for the entity.
Definition: base/EntityKey.hpp:167
stk_classic::mesh::BulkData::change_ghosting
void change_ghosting(Ghosting &ghosts, const std::vector< EntityProc > &add_send, const std::vector< Entity * > &remove_receive)
Change the members of a ghosting list on the sending processor.
Definition: BulkDataGhosting.cpp:145
sierra::Env::parallel_rank
int parallel_rank()
function parallel_rank returns the rank of this processor in the current mpi communicator.
Definition: Env.cpp:318
stk_classic::PairIter
Definition: PairIter.hpp:21
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::Entity::relations
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
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::EntityProc
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Definition: Types.hpp:111
stk_classic::mesh::Ghosting
Data for ghosting mesh entities.
Definition: Ghosting.hpp:28
stk_classic::mesh::entity_rank
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).
Definition: base/EntityKey.hpp:161
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::fem::FEMMetaData::declare_field
field_type & declare_field(const std::string &name, unsigned number_of_states=1)
Declare a field of the given field_type, test name, and number of states.
Definition: FEMMetaData.hpp:427
stk_classic::mesh::fem::FEMMetaData::FEM_initialize
void FEM_initialize(size_t spatial_dimension, const std::vector< std::string > &in_entity_rank_names=std::vector< std::string >())
Initialize the spatial dimension and an optional list of entity rank names associated with each rank.
Definition: FEMMetaData.cpp:61
stk_classic::mesh::Ghosting::receive_list
void receive_list(std::vector< Entity * > &) const
Entities ghosted on this processor from the owner.
Definition: Ghosting.cpp:33
stk_classic::mesh::Entity::owner_rank
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175
sierra::Env::parallel_size
int parallel_size()
function parallel_size returns the number of processors in the current mpi communicator.
Definition: Env.cpp:314
stk_classic::mesh::fixtures::QuadFixture
Definition: QuadFixture.hpp:36
stk_classic::parallel_machine_rank
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
Definition: Parallel.cpp:29
stk_classic::mesh::fem::FEMMetaData
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
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::fem::FEMMetaData::universal_part
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part.
Definition: FEMMetaData.hpp:272
stk_classic::mesh::fem::declare_part
Part & declare_part(FEMMetaData &meta_data, const std::string &name)
Declare a part with a given cell topology. This is just a convenient function that wraps FEMMetaData'...
Definition: FEMHelpers.hpp:93
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