Sierra Toolkit  Version of the Day
UnitTestBulkData_ChangeParts.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 
9 #include <iostream>
10 #include <sstream>
11 
12 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
13 
14 #include <stk_util/parallel/Parallel.hpp>
15 
16 #include <stk_mesh/base/BulkData.hpp>
17 #include <stk_mesh/base/GetEntities.hpp>
18 #include <stk_mesh/base/Comm.hpp>
19 
20 #include <stk_mesh/fixtures/RingFixture.hpp>
21 
22 #include <unit_tests/UnitTestModificationEndWrapper.hpp>
23 
32 
33 //----------------------------------------------------------------------
34 
35 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, testChangeParts)
36 {
37  // This unit test tests part operations and verifies operations
38  // by looking at bucket supersets. We use contrived entities
39  // (as opposed to a fixture) for simplicity and clarity.
40 
41  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
42  MPI_Barrier( pm );
43 
44  const unsigned p_size = stk_classic::parallel_machine_size( pm );
45  const unsigned p_rank = stk_classic::parallel_machine_rank( pm );
46 
47  // Single process, no sharing
48 
49  // Meta data with entity ranks [0..9]
50  const unsigned spatial_dimension = 10;
51  std::vector<std::string> entity_names(spatial_dimension+1);
52  for ( size_t i = 0 ; i <= spatial_dimension ; ++i ) {
53  std::ostringstream name ;
54  name << "EntityRank_" << i ;
55  entity_names[i] = name.str();
56  }
57 
58  // Create a mesh with a bunch of parts
59 
60  FEMMetaData meta( spatial_dimension, entity_names );
61  BulkData bulk( FEMMetaData::get_meta_data(meta) , pm , 100 );
62 
63  Part & part_univ = meta.universal_part();
64  Part & part_owns = meta.locally_owned_part();
65  Part & part_shared = meta.globally_shared_part();
66 
67  Part & part_A_0 = meta.declare_part(std::string("A_0"), 0 /*entity_rank*/);
68  Part & part_A_1 = meta.declare_part(std::string("A_1"), 1 /*entity_rank*/);
69  Part & part_A_2 = meta.declare_part(std::string("A_2"), 2 /*entity_rank*/);
70  Part & part_A_3 = meta.declare_part(std::string("A_3"), 3 /*entity_rank*/);
71 
72  Part & part_B_0 = meta.declare_part(std::string("B_0"), 0 /*entity_rank*/);
73  Part & part_B_2 = meta.declare_part(std::string("B_2"), 2 /*entity_rank*/);
74 
75  meta.commit();
76  bulk.modification_begin();
77 
78  PartVector tmp(1), no_parts;
79 
80  // Declare a few entities of various ranks. In order for the sharing
81  // to work, we need to have all the entities we'll be playing with
82  // to be in the owned-closure of a high-level non-shared entity, we'll
83  // call that entity the closure_entity because all the other entities
84  // will be in it's closure.
85 
86  Entity& closure_entity = bulk.declare_entity(4 /*entity rank*/,
87  p_rank+1 /*id*/,
88  no_parts);
89 
90  tmp[0] = & part_A_0 ;
91  Entity& entity_0_1 = bulk.declare_entity(0 /*entity rank*/, 1 /*id*/, tmp);
92  bulk.declare_relation( closure_entity , entity_0_1 , 0 /*local_rel_id*/ );
93 
94  tmp[0] = & part_A_1 ;
95  Entity& entity_1_1 = bulk.declare_entity(1 /*entity rank*/, 1 /*id*/, tmp);
96  bulk.declare_relation( closure_entity , entity_1_1 , 1 /*local_rel_id*/ );
97 
98  tmp[0] = & part_A_2 ;
99  Entity& entity_2_1 = bulk.declare_entity(2 /*entity rank*/, 1 /*id*/, tmp);
100  bulk.declare_relation( closure_entity , entity_2_1 , 2 /*local_rel_id*/ );
101 
102  tmp[0] = & part_A_3 ;
103  Entity& entity_3_1 = bulk.declare_entity(3 /*entity rank*/, 1 /*id*/, tmp);
104  bulk.declare_relation( closure_entity , entity_3_1 , 3 /*local_rel_id*/ );
105 
106  // Ensure that the supersets of the buckets containing the entities we
107  // just created are correct.
108 
109  entity_0_1.bucket().supersets( tmp );
110  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
111  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
112  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
113  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
114 
115  entity_1_1.bucket().supersets( tmp );
116  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
117  STKUNIT_ASSERT( entity_1_1.bucket().member(part_univ) );
118  STKUNIT_ASSERT( entity_1_1.bucket().member(part_owns) );
119  STKUNIT_ASSERT( entity_1_1.bucket().member(part_A_1) );
120 
121  entity_2_1.bucket().supersets( tmp );
122  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
123  STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
124  STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
125  STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
126 
127  entity_3_1.bucket().supersets( tmp );
128  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
129  STKUNIT_ASSERT( entity_3_1.bucket().member(part_univ) );
130  STKUNIT_ASSERT( entity_3_1.bucket().member(part_owns) );
131  STKUNIT_ASSERT( entity_3_1.bucket().member(part_A_3) );
132 
133  // Add entity_0_1 to the part it was already in
134  {
135  tmp.resize(1);
136  tmp[0] = & part_A_0 ;
137  bulk.change_entity_parts( entity_0_1 , tmp );
138  entity_0_1.bucket().supersets( tmp );
139  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
140  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
141  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
142  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
143  }
144 
145  // Add entity_0_1 to part_B_0
146  {
147  tmp.resize(1);
148  tmp[0] = & part_B_0 ;
149  bulk.change_entity_parts( entity_0_1 , tmp );
150  entity_0_1.bucket().supersets( tmp );
151  STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
152  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
153  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
154  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
155  STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
156  }
157 
158  // Remove entity_0_1 from the part it was just added to above
159  {
160  tmp.resize(1);
161  tmp[0] = & part_B_0 ;
162  bulk.change_entity_parts( entity_0_1 , PartVector() , tmp );
163  entity_0_1.bucket().supersets( tmp );
164  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
165  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
166  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
167  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
168  }
169 
170  // Add relation from entity_1_1 (which is in part_A_1) to
171  // entity_0_1 (which is in part_A_0). After the relation
172  // is added, there is an induced membership of entity_0_1
173  // within part A_1.
174  stk_classic::mesh::RelationIdentifier test_rel_id = 0;
175  {
176  bulk.declare_relation( entity_1_1 , entity_0_1 , test_rel_id );
177  entity_0_1.bucket().supersets( tmp );
178  STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
179  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
180  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
181  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
182  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_1) );
183  }
184 
185  // Remove the relationship added in the step above and
186  // demonstrate that the induced membership of entity_0_1
187  // in part_A_1 is gone
188  {
189  bulk.destroy_relation( entity_1_1 , entity_0_1, test_rel_id );
190  entity_0_1.bucket().supersets( tmp );
191  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
192  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
193  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
194  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
195  }
196 
197  // Add entity_2_1 to part_B_2
198  {
199  tmp.resize(1);
200  tmp[0] = & part_B_2 ;
201  bulk.change_entity_parts( entity_2_1 , tmp );
202  entity_2_1.bucket().supersets( tmp );
203  STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
204  STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
205  STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
206  STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
207  STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
208  }
209 
210  // Add relation from entity_2_1 (which is in part_A_2 and B_2) to
211  // entity_0_1 (which is in part_A_0). After the relation
212  // is added, there is an induced membership of entity_0_1
213  // within entity_2_1's parts (A_2 and B_2) (and of course entity_0_1
214  // is still in the parts it was already in).
215  {
216  bulk.declare_relation( entity_2_1 , entity_0_1 , test_rel_id );
217  entity_0_1.bucket().supersets( tmp );
218  STKUNIT_ASSERT_EQUAL( size_t(5) , tmp.size() );
219  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
220  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
221  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
222  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_2) );
223  STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_2) );
224  }
225 
226  // Remove the relationship added in the step above and
227  // demonstrate that the induced membership of entity_0_1
228  // in parts A_2 and B_2 is gone.
229  {
230  bulk.destroy_relation( entity_2_1 , entity_0_1, test_rel_id );
231  entity_0_1.bucket().supersets( tmp );
232  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
233  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
234  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
235  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
236  }
237 
238  bulk.modification_end();
239 
240  //------------------------------
241  // Now the parallel fun. Existing entities should be shared
242  // by all processes since they have the same identifiers.
243  // They should also have the same parts.
244 
245  bool parallel = p_size > 1;
246 
247  // For parallel runs, the entities should be in the same parts
248  // as they were before the modification end and they should
249  // be in the shared part as well.
250 
251  entity_0_1.bucket().supersets( tmp );
252  if ( entity_0_1.owner_rank() == p_rank ) {
253  STKUNIT_ASSERT_EQUAL( size_t(parallel ? 4 : 3) , tmp.size() );
254  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
255  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
256  if ( parallel )
257  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
258  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
259  }
260  else {
261  STKUNIT_ASSERT( parallel );
262  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
263  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
264  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
265  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
266  }
267 
268  entity_2_1.bucket().supersets( tmp );
269  if ( entity_2_1.owner_rank() == p_rank ) {
270  STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
271  STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
272  STKUNIT_ASSERT( entity_2_1.bucket().member(part_owns) );
273  if ( parallel )
274  STKUNIT_ASSERT( entity_2_1.bucket().member(part_shared) );
275  STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
276  STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
277  }
278  else {
279  STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
280  STKUNIT_ASSERT( entity_2_1.bucket().member(part_univ) );
281  STKUNIT_ASSERT( entity_2_1.bucket().member(part_shared) );
282  STKUNIT_ASSERT( entity_2_1.bucket().member(part_A_2) );
283  STKUNIT_ASSERT( entity_2_1.bucket().member(part_B_2) );
284  }
285 
286  if ( parallel ) {
287  // If parallel, check that the entities are shared across all procs.
288  STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_0_1.sharing().size() );
289  STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_1_1.sharing().size() );
290  STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_2_1.sharing().size() );
291  STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_3_1.sharing().size() );
292  }
293 
294  bulk.modification_begin();
295 
296  // Add entity_0_1 to a new part on the owning process
297 
298  int ok_to_modify = entity_0_1.owner_rank() == p_rank ;
299 
300  try {
301  tmp.resize(1);
302  tmp[0] = & part_B_0 ;
303  bulk.change_entity_parts( entity_0_1 , tmp );
304  STKUNIT_ASSERT( ok_to_modify );
305  }
306  catch( const std::exception & x ) {
307  STKUNIT_ASSERT( ! ok_to_modify );
308  }
309 
310  // Check that entity_0_1 is in the new part on the owning
311  // process, but not on other processes.
312 
313  entity_0_1.bucket().supersets( tmp );
314  if ( entity_0_1.owner_rank() == p_rank ) {
315  STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
316  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
317  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
318  if ( parallel )
319  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
320  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
321  STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
322  }
323  else {
324  STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() );
325  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
326  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
327  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
328  }
329 
330  bulk.modification_end();
331 
332  // Now that modification_end has been called, entity_0_1 should
333  // be in the new part (B_0) on all processes.
334 
335  entity_0_1.bucket().supersets( tmp );
336  if ( entity_0_1.owner_rank() == p_rank ) {
337  STKUNIT_ASSERT_EQUAL( size_t(parallel ? 5 : 4) , tmp.size() );
338  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
339  STKUNIT_ASSERT( entity_0_1.bucket().member(part_owns) );
340  if ( parallel )
341  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
342  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
343  STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
344  }
345  else {
346  STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() );
347  STKUNIT_ASSERT( entity_0_1.bucket().member(part_univ) );
348  STKUNIT_ASSERT( entity_0_1.bucket().member(part_shared) );
349  STKUNIT_ASSERT( entity_0_1.bucket().member(part_A_0) );
350  STKUNIT_ASSERT( entity_0_1.bucket().member(part_B_0) );
351  }
352 }
353 
354 //----------------------------------------------------------------------
355 //----------------------------------------------------------------------
356 
357 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, testChangeParts_ringmesh)
358 {
359  // This unit test tests part operations and verifies operations
360  // by looking at bucket supersets. We use RingMesh for a slightly
361  // more realistic test than the test above but it's a bit harder
362  // to read.
363 
364  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
365  MPI_Barrier( pm );
366 
367  const unsigned nPerProc = 10;
368  const unsigned p_rank = stk_classic::parallel_machine_rank( pm );
369  const unsigned p_size = stk_classic::parallel_machine_size( pm );
370  const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
371  const unsigned nLocalEdge = nPerProc ;
372 
373  // Create the ring mesh
374 
375  RingFixture ring_mesh( pm , nPerProc , true /* generate parts */ );
376  ring_mesh.m_meta_data.commit();
377  BulkData& bulk = ring_mesh.m_bulk_data;
378 
379  bulk.modification_begin();
380  ring_mesh.generate_mesh( );
381  STKUNIT_ASSERT(stk_classic::unit_test::modification_end_wrapper(bulk,
382  false /* no aura */));
383 
384  bulk.modification_begin();
385  ring_mesh.fixup_node_ownership();
386  STKUNIT_ASSERT(stk_classic::unit_test::modification_end_wrapper(bulk,
387  false /* no aura */));
388 
389  Part & part_owns = ring_mesh.m_meta_data.locally_owned_part();
390  Part & part_univ = ring_mesh.m_meta_data.universal_part();
391 
392  // Check that local edges are in the expected parts. Note that the
393  // RingMesh puts each edge in its own part.
394  for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) {
395  const unsigned n = i + nPerProc * p_rank ;
396  Entity * const edge = bulk.get_entity( 1 /*entity rank*/,
397  ring_mesh.m_edge_ids[n] );
398  STKUNIT_ASSERT( edge != NULL );
399  STKUNIT_ASSERT( edge->bucket().member( part_univ ) );
400  STKUNIT_ASSERT( edge->bucket().member( part_owns ) );
401  STKUNIT_ASSERT( edge->bucket().member( * ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ] ) );
402  }
403 
404  // Check that local nodes are in the expected parts. Note that the relations
405  // that nodes have to edges should cause induced membership of the node
406  // in the parts of both edges it touches.
407  for ( unsigned i = 0 ; i < nLocalNode ; ++i ) {
408  const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size();
409  const unsigned e0 = n ;
410  const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size();
411  const unsigned ns = ring_mesh.m_edge_parts.size();
412  const unsigned n0 = e0 % ns ;
413  const unsigned n1 = e1 % ns ;
414  Part * const epart_0 = ring_mesh.m_edge_parts[ n0 < n1 ? n0 : n1 ];
415  Part * const epart_1 = ring_mesh.m_edge_parts[ n0 < n1 ? n1 : n0 ];
416 
417  Entity * const node = bulk.get_entity( 0 , ring_mesh.m_node_ids[n] );
418  STKUNIT_ASSERT( node != NULL );
419  if ( node->owner_rank() == p_rank ) {
420  STKUNIT_ASSERT( node->bucket().member( part_univ ) );
421  STKUNIT_ASSERT( node->bucket().member( part_owns ) );
422  STKUNIT_ASSERT( node->bucket().member( *epart_0 ) );
423  STKUNIT_ASSERT( node->bucket().member( *epart_1 ) );
424  }
425  else {
426  STKUNIT_ASSERT( node->bucket().member( part_univ ) );
427  STKUNIT_ASSERT( ! node->bucket().member( part_owns ) );
428  STKUNIT_ASSERT( node->bucket().member( * epart_0 ) );
429  STKUNIT_ASSERT( node->bucket().member( * epart_1 ) );
430  }
431  }
432 
433  bulk.modification_begin();
434 
435  // On rank 0, change all locally owned edges to the extra-part then check
436  // for correct part membership
437  if ( 0 == p_rank ) {
438  for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) {
439  const unsigned n = i + nPerProc * p_rank ;
440 
441  PartVector add(1); add[0] = & ring_mesh.m_edge_part_extra ;
442  PartVector rem(1); rem[0] = ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ];
443 
444  Entity * const edge = bulk.get_entity( 1 , ring_mesh.m_edge_ids[n] );
445  bulk.change_entity_parts( *edge , add , rem );
446  STKUNIT_ASSERT( edge->bucket().member( part_univ ) );
447  STKUNIT_ASSERT( edge->bucket().member( part_owns ) );
448  STKUNIT_ASSERT( edge->bucket().member(ring_mesh.m_edge_part_extra ) );
449  }
450  }
451 
452  bulk.modification_end();
453 
454  // Modification end has been called, check that the part changes made
455  // in the previous step are reflected across the other procs.
456  for ( unsigned i = 0 ; i < nLocalNode ; ++i ) {
457  const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size();
458  const unsigned e0 = n ;
459  const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size();
460  const unsigned ns = ring_mesh.m_edge_parts.size();
461  const unsigned n0 = e0 % ns ;
462  const unsigned n1 = e1 % ns ;
463  Part * ep_0 = e0 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n0] ;
464  Part * ep_1 = e1 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n1] ;
465 
466  Part * epart_0 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_0 : ep_1 ;
467  Part * epart_1 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_1 : ep_0 ;
468 
469  Entity * const node = bulk.get_entity( 0 , ring_mesh.m_node_ids[n] );
470  STKUNIT_ASSERT( node != NULL );
471  if ( node->owner_rank() == p_rank ) {
472  STKUNIT_ASSERT( node->bucket().member( part_owns ) );
473  }
474  else {
475  STKUNIT_ASSERT( ! node->bucket().member( part_owns ) );
476  }
477 
478  STKUNIT_ASSERT( node->bucket().member( part_univ ) );
479  STKUNIT_ASSERT( node->bucket().member( *epart_0 ) );
480  STKUNIT_ASSERT( node->bucket().member( *epart_1 ) );
481  }
482 }
stk_classic::mesh::Entity::sharing
PairIterEntityComm sharing() const
Parallel processes which share this entity.
Definition: Entity.hpp:178
stk_classic::mesh::fixtures::RingFixture
Definition: RingFixture.hpp:37
stk_classic::parallel_machine_size
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Definition: Parallel.cpp:18
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::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::Part::mesh_meta_data_ordinal
unsigned mesh_meta_data_ordinal() const
Internally generated ordinal of this part that is unique within the owning meta data manager.
Definition: Part.hpp:72
stk_classic::ParallelMachine
MPI_Comm ParallelMachine
Definition: Parallel.hpp:32
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::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::Selector
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
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::owner_rank
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175
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::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::BulkData
Manager for an integrated collection of entities, entity relations, and buckets of field data.
Definition: BulkData.hpp:49