Sierra Toolkit  Version of the Day
UnitTestRingFixture.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 <stk_util/unit_test_support/stk_utest_macros.hpp>
10 
11 #include <stk_mesh/fixtures/RingFixture.hpp>
12 
13 #include <stk_mesh/base/MetaData.hpp>
14 #include <stk_mesh/base/BulkData.hpp>
15 #include <stk_mesh/base/GetEntities.hpp>
16 
17 #include <unit_tests/UnitTestModificationEndWrapper.hpp>
18 
26 
27 namespace {
28 
29 const stk_classic::mesh::EntityRank NODE_RANK = stk_classic::mesh::fem::FEMMetaData::NODE_RANK;
30 
31 STKUNIT_UNIT_TEST( UnitTestBoxFixture, verifyRingFixture )
32 {
33  // A unit test to verify the correctness of the RingFixture fixture.
34 
35  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
36  MPI_Barrier( pm );
37 
38  // Create the ring fixture we'll be testing
39 
40  RingFixture fixture(pm);
41  FEMMetaData& meta = fixture.m_meta_data;
42  BulkData& bulk = fixture.m_bulk_data;
43 
44  const stk_classic::mesh::EntityRank element_rank = meta.element_rank();
45 
46  meta.commit();
47 
48  const unsigned p_rank = bulk.parallel_rank();
49  const unsigned p_size = bulk.parallel_size();
50  const unsigned nPerProc = fixture.m_num_edge_per_proc ;
51  const unsigned id_total = nPerProc * p_size ;
52  const unsigned id_begin = nPerProc * p_rank ;
53  const unsigned id_end = nPerProc * ( p_rank + 1 );
54  const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
55  const unsigned nLocalEdge = nPerProc ;
56  const unsigned n_extra = 1 < p_size ? 2 : 0 ;
57 
58  bulk.modification_begin();
59  fixture.generate_mesh();
60 
61  Selector select_owned( meta.locally_owned_part() );
62  Selector select_used = meta.locally_owned_part() |
63  meta.globally_shared_part();
64  Selector select_all( meta.universal_part() );
65 
66  std::vector<unsigned> local_count;
67  stk_classic::mesh::count_entities( select_used , bulk , local_count );
68  STKUNIT_ASSERT_EQUAL( local_count[NODE_RANK] , nLocalNode );
69  STKUNIT_ASSERT_EQUAL( local_count[element_rank] , nLocalEdge );
70 
71  std::vector<Entity*> all_nodes;
72  get_entities( bulk, NODE_RANK, all_nodes);
73 
74  unsigned num_selected_nodes =
75  count_selected_entities( select_used, bulk.buckets(NODE_RANK) );
76  STKUNIT_ASSERT_EQUAL( num_selected_nodes , local_count[NODE_RANK] );
77 
78  std::vector<Entity*> universal_nodes;
79  get_selected_entities(select_all, bulk.buckets(NODE_RANK),
80  universal_nodes );
81  STKUNIT_ASSERT_EQUAL( universal_nodes.size() , all_nodes.size() );
82 
83  STKUNIT_ASSERT(bulk.modification_end());
84 
85  // Verify declarations and sharing two end nodes:
86 
87  stk_classic::mesh::count_entities( select_used , bulk , local_count );
88  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
89  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
90 
91  if ( 1 < p_size ) {
92  const unsigned n0 = id_end < id_total ? id_begin : 0 ;
93  const unsigned n1 = id_end < id_total ? id_end : id_begin ;
94 
95  Entity * const node0 = bulk.get_entity( NODE_RANK , fixture.m_node_ids[n0] );
96  Entity * const node1 = bulk.get_entity( NODE_RANK , fixture.m_node_ids[n1] );
97 
98  STKUNIT_ASSERT( node0 != NULL );
99  STKUNIT_ASSERT( node1 != NULL );
100 
101  STKUNIT_ASSERT_EQUAL( node0->sharing().size() , size_t(1) );
102  STKUNIT_ASSERT_EQUAL( node1->sharing().size() , size_t(1) );
103  }
104 
105  // Test no-op first:
106 
107  std::vector<EntityProc> change ;
108 
109  STKUNIT_ASSERT( bulk.modification_begin() );
110  bulk.change_entity_owner( change );
111  STKUNIT_ASSERT( bulk.modification_end());
112 
113  stk_classic::mesh::count_entities( select_used , bulk , local_count );
114  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
115  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
116 
117  stk_classic::mesh::count_entities( select_all , bulk , local_count );
118  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode + n_extra );
119  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge + n_extra );
120 
121  bulk.modification_begin();
122  fixture.fixup_node_ownership();
123  STKUNIT_ASSERT(bulk.modification_end());
124 
125  // Make sure that edge->owner_rank() == edge->node[1]->owner_rank()
126  if ( 1 < p_size ) {
127  stk_classic::mesh::count_entities( select_all , bulk , local_count );
128  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode + n_extra );
129  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge + n_extra );
130 
131  stk_classic::mesh::count_entities( select_used , bulk , local_count );
132  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
133  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
134 
135  stk_classic::mesh::count_entities( select_owned , bulk , local_count );
136  STKUNIT_ASSERT_EQUAL( local_count[0] , nPerProc );
137  STKUNIT_ASSERT_EQUAL( local_count[1] , nPerProc );
138  }
139 }
140 
141 }
142 
143 namespace stk_classic {
144 namespace unit_test {
145 
146 void test_shift_ring( RingFixture& ring, bool generate_aura=true )
147 {
148  FEMMetaData& meta = ring.m_meta_data;
149  BulkData& bulk = ring.m_bulk_data;
150 
151  const unsigned p_rank = bulk.parallel_rank();
152  const unsigned p_size = bulk.parallel_size();
153  const unsigned nPerProc = ring.m_num_edge_per_proc ;
154  const unsigned id_total = nPerProc * p_size ;
155  const unsigned id_begin = nPerProc * p_rank ;
156  const unsigned id_end = nPerProc * ( p_rank + 1 );
157  const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
158  const unsigned nLocalEdge = nPerProc ;
159 
160  const unsigned p_send = ( p_rank + 1 ) % p_size ;
161  const unsigned id_send = id_end - 2 ;
162  const unsigned id_recv = ( id_begin + id_total - 2 ) % id_total ;
163 
164  Selector select_used = meta.locally_owned_part() |
165  meta.globally_shared_part();
166 
167  std::vector<unsigned> local_count ;
168  std::vector<EntityProc> change ;
169 
170  Entity * send_edge_1 = bulk.get_entity( 1 , ring.m_edge_ids[ id_send ] );
171  Entity * send_edge_2 = bulk.get_entity( 1 , ring.m_edge_ids[ id_send + 1 ] );
172  Entity * send_node_1 = send_edge_1->relations()[1].entity();
173  Entity * send_node_2 = send_edge_2->relations()[1].entity();
174  Entity * recv_edge_1 = bulk.get_entity( 1 , ring.m_edge_ids[ id_recv ] );
175  Entity * recv_edge_2 = bulk.get_entity( 1 , ring.m_edge_ids[ id_recv + 1 ] );
176 
177  STKUNIT_ASSERT( NULL != send_edge_1 && p_rank == send_edge_1->owner_rank() );
178  STKUNIT_ASSERT( NULL != send_edge_2 && p_rank == send_edge_2->owner_rank() );
179  STKUNIT_ASSERT( NULL == recv_edge_1 || p_rank != recv_edge_1->owner_rank() );
180  STKUNIT_ASSERT( NULL == recv_edge_2 || p_rank != recv_edge_2->owner_rank() );
181 
182  if ( p_rank == send_node_1->owner_rank() ) {
183  EntityProc entry( send_node_1 , p_send );
184  change.push_back( entry );
185  }
186  if ( p_rank == send_node_2->owner_rank() ) {
187  EntityProc entry( send_node_2 , p_send );
188  change.push_back( entry );
189  }
190  {
191  EntityProc entry( send_edge_1 , p_send );
192  change.push_back( entry );
193  }
194  {
195  EntityProc entry( send_edge_2 , p_send );
196  change.push_back( entry );
197  }
198 
199  send_edge_1 = NULL ;
200  send_edge_2 = NULL ;
201  send_node_1 = NULL ;
202  send_node_2 = NULL ;
203  recv_edge_1 = NULL ;
204  recv_edge_2 = NULL ;
205 
206  STKUNIT_ASSERT( bulk.modification_begin() );
207  bulk.change_entity_owner( change );
208  STKUNIT_ASSERT( stk_classic::unit_test::modification_end_wrapper( bulk , generate_aura ) );
209 
210  send_edge_1 = bulk.get_entity( 1 , ring.m_edge_ids[ id_send ] );
211  send_edge_2 = bulk.get_entity( 1 , ring.m_edge_ids[ id_send + 1 ] );
212  recv_edge_1 = bulk.get_entity( 1 , ring.m_edge_ids[ id_recv ] );
213  recv_edge_2 = bulk.get_entity( 1 , ring.m_edge_ids[ id_recv + 1 ] );
214 
215  STKUNIT_ASSERT( NULL == send_edge_1 || p_rank != send_edge_1->owner_rank() );
216  STKUNIT_ASSERT( NULL == send_edge_2 || p_rank != send_edge_2->owner_rank() );
217  STKUNIT_ASSERT( NULL != recv_edge_1 && p_rank == recv_edge_1->owner_rank() );
218  STKUNIT_ASSERT( NULL != recv_edge_2 && p_rank == recv_edge_2->owner_rank() );
219 
220  stk_classic::mesh::count_entities( select_used , bulk , local_count );
221  STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
222  STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
223 
224  unsigned count_shared = 0 ;
225  for ( std::vector<Entity*>::const_iterator
226  i = bulk.entity_comm().begin() ;
227  i != bulk.entity_comm().end() ; ++i ) {
228  if ( in_shared( **i ) ) { ++count_shared ; }
229  }
230  STKUNIT_ASSERT_EQUAL( count_shared , 2u );
231 
232  {
233  Entity * const node_recv = bulk.get_entity( NODE_RANK , ring.m_node_ids[id_recv] );
234  Entity * const node_send = bulk.get_entity( NODE_RANK , ring.m_node_ids[id_send] );
235 
236  STKUNIT_ASSERT_EQUAL( node_recv->sharing().size() , 1u );
237  STKUNIT_ASSERT_EQUAL( node_send->sharing().size() , 1u );
238  }
239 }
240 
241 }
242 }
Part & locally_owned_part() const
Subset for the problem domain that is owned by the local process. Ghost entities are not members of t...
FEMMetaData is a class that implements a Finite Element Method skin on top of the Sierra Tool Kit Met...
Definition: FEMMetaData.hpp:54
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
PairIterEntityComm sharing() const
Parallel processes which share this entity.
Definition: Entity.hpp:178
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
Definition: BulkData.hpp:367
unsigned count_selected_entities(const Selector &selector, const std::vector< Bucket * > &input_buckets)
Count entities in selected buckets (selected by the given selector instance), and sorted by ID...
Definition: GetEntities.cpp:59
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
Part & universal_part() const
Universal subset for the problem domain. All other parts are a subset of the universal part...
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
const std::vector< Bucket * > & buckets(EntityRank rank) const
Query all buckets of a given entity rank.
Definition: BulkData.hpp:195
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
std::pair< Entity *, unsigned > EntityProc
Pairing of an entity with a processor rank.
Definition: Types.hpp:111
void get_selected_entities(const Selector &selector, const std::vector< Bucket * > &input_buckets, std::vector< Entity * > &entities)
Get entities in selected buckets (selected by the given selector instance), and sorted by ID...
Definition: GetEntities.cpp:77
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
Part & globally_shared_part() const
Subset for the problem domain that is shared with another process. Ghost entities are not members of ...
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
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
Definition: Entity.hpp:161
void get_entities(const BulkData &mesh, EntityRank entity_rank, std::vector< Entity *> &entities)
Get all entities of the specified type, sorted by ID.
Definition: GetEntities.cpp:25
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
void commit()
Commit the part and field declarations so that the meta data manager can be used to create mesh bulk ...
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120
Sierra Toolkit.
void count_entities(const Selector &selector, const BulkData &mesh, std::vector< EntityRank > &count)
Local count selected entities of each type.
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.
unsigned parallel_rank() const
Rank of the parallel machine&#39;s local processor.
Definition: BulkData.hpp:85
unsigned owner_rank() const
Parallel processor rank of the processor which owns this entity.
Definition: Entity.hpp:175