Sierra Toolkit  Version of the Day
UnitTestBoxFixture.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 
10 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
11 
12 #include <stk_mesh/fixtures/BoxFixture.hpp>
13 
14 #include <stk_mesh/base/MetaData.hpp>
15 #include <stk_mesh/base/BulkData.hpp>
16 #include <stk_mesh/base/Entity.hpp>
17 #include <stk_mesh/base/Selector.hpp>
18 #include <stk_mesh/base/GetEntities.hpp>
19 
24 using stk_classic::mesh::EntityId;
25 using stk_classic::mesh::EntityRank;
27 
28 namespace {
29 
30 const EntityRank NODE_RANK = FEMMetaData::NODE_RANK;
31 
32 class ExposePartition : public BoxFixture
33 {
34  public:
35  static void expose_box_partition( int ip , int up , int axis ,
36  const BOX box ,
37  BOX p_box[] )
38  {
39  box_partition(ip, up, axis, box, p_box);
40  }
41 };
42 
43 }
44 
45 STKUNIT_UNIT_TEST( UnitTestBoxFixture, verifyBoxFixture )
46 {
47  // A unit test to verify the correctness of the BoxFixture fixture.
48 
49  stk_classic::ParallelMachine pm = MPI_COMM_WORLD;
50  MPI_Barrier( pm );
51 
52  // Create the box fixture we'll be testing
53 
54  // box specifications
55  const BoxFixture::BOX root_box = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
56  BoxFixture::BOX local_box = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
57 
58  BoxFixture fixture(pm);
59  FEMMetaData& meta = fixture.fem_meta();
60  BulkData& bulk = fixture.bulk_data();
61 
62  const EntityRank element_rank = meta.element_rank();
63 
64  const unsigned p_rank = bulk.parallel_rank();
65  const unsigned p_size = bulk.parallel_size();
66 
67  BoxFixture::BOX * const p_box = new BoxFixture::BOX[ p_size ];
68  ExposePartition::expose_box_partition( 0, p_size, 2, root_box, &p_box[0] );
69 
70  meta.commit();
71 
72  bulk.modification_begin();
73  fixture.generate_boxes( root_box, local_box );
74 
75  const unsigned nx = local_box[0][1] - local_box[0][0] ;
76  const unsigned ny = local_box[1][1] - local_box[1][0] ;
77  const unsigned nz = local_box[2][1] - local_box[2][0] ;
78 
79  const unsigned e_local = nx * ny * nz ;
80  const unsigned n_local = ( nx + 1 ) * ( ny + 1 ) * ( nz + 1 );
81 
82  const unsigned ngx = root_box[0][1] - root_box[0][0] ;
83  const unsigned ngy = root_box[1][1] - root_box[1][0] ;
84 
85  std::vector<unsigned> local_count ;
86 
87  // Verify that the correct entities are on this process
88 
89  for ( int k = local_box[2][0] ; k < local_box[2][1] ; ++k ) {
90  for ( int j = local_box[1][0] ; j < local_box[1][1] ; ++j ) {
91  for ( int i = local_box[0][0] ; i < local_box[0][1] ; ++i ) {
92 
93  const EntityId n0= 1 + (i+0) + (j+0) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
94  const EntityId n1= 1 + (i+1) + (j+0) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
95  const EntityId n2= 1 + (i+1) + (j+1) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
96  const EntityId n3= 1 + (i+0) + (j+1) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
97  const EntityId n4= 1 + (i+0) + (j+0) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
98  const EntityId n5= 1 + (i+1) + (j+0) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
99  const EntityId n6= 1 + (i+1) + (j+1) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
100  const EntityId n7= 1 + (i+0) + (j+1) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
101 
102  const EntityId elem_id = 1 + i + j * ngx + k * ngx * ngy;
103 
104  std::vector<Entity*> nodes(8);
105  nodes[0] = bulk.get_entity( NODE_RANK, n0 );
106  nodes[1] = bulk.get_entity( NODE_RANK, n1 );
107  nodes[2] = bulk.get_entity( NODE_RANK, n2 );
108  nodes[3] = bulk.get_entity( NODE_RANK, n3 );
109  nodes[4] = bulk.get_entity( NODE_RANK, n4 );
110  nodes[5] = bulk.get_entity( NODE_RANK, n5 );
111  nodes[6] = bulk.get_entity( NODE_RANK, n6 );
112  nodes[7] = bulk.get_entity( NODE_RANK, n7 );
113 
114  Entity* elem = bulk.get_entity( element_rank, elem_id );
115 
116  std::vector<Entity*> elems ;
118  STKUNIT_ASSERT_EQUAL( elems.size() , size_t(1) );
119  STKUNIT_ASSERT_EQUAL( elems[0] , elem );
120 
121  stk_classic::mesh::get_entities_through_relations(nodes, element_rank, elems);
122  STKUNIT_ASSERT_EQUAL( elems.size() , size_t(1) );
123  STKUNIT_ASSERT_EQUAL( elems[0] , elem );
124 
125  }
126  }
127  }
128 
129  Selector select_owned( meta.locally_owned_part() );
130  Selector select_used = select_owned |
131  meta.globally_shared_part();
132  Selector select_all( meta.universal_part() );
133 
134  stk_classic::mesh::count_entities( select_used , bulk , local_count );
135  STKUNIT_ASSERT_EQUAL( e_local , local_count[3] );
136  STKUNIT_ASSERT_EQUAL( 0u , local_count[2] );
137  STKUNIT_ASSERT_EQUAL( 0u , local_count[1] );
138  STKUNIT_ASSERT_EQUAL( n_local , local_count[0] );
139 
140  STKUNIT_ASSERT(bulk.modification_end());
141 
142  // Verify declarations and sharing
143 
144  stk_classic::mesh::count_entities( select_used , bulk , local_count );
145  STKUNIT_ASSERT_EQUAL( local_count[3] , e_local );
146  STKUNIT_ASSERT_EQUAL( local_count[2] , 0u );
147  STKUNIT_ASSERT_EQUAL( local_count[1] , 0u );
148  STKUNIT_ASSERT_EQUAL( local_count[0] , n_local );
149 
150  for ( int k = local_box[2][0] ; k <= local_box[2][1] ; ++k ) {
151  for ( int j = local_box[1][0] ; j <= local_box[1][1] ; ++j ) {
152  for ( int i = local_box[0][0] ; i <= local_box[0][1] ; ++i ) {
153  EntityRank node_type = 0;
154  EntityId node_id = 1 + i + j * (ngx+1) + k * (ngx+1) * (ngy+1);
155  Entity * const node = bulk.get_entity( node_type , node_id );
156  STKUNIT_ASSERT( node != NULL );
157  // Shared if on a processor boundary.
158  const bool shared =
159  ( k == local_box[2][0] && k != root_box[2][0] ) ||
160  ( k == local_box[2][1] && k != root_box[2][1] ) ||
161  ( j == local_box[1][0] && j != root_box[1][0] ) ||
162  ( j == local_box[1][1] && j != root_box[1][1] ) ||
163  ( i == local_box[0][0] && i != root_box[0][0] ) ||
164  ( i == local_box[0][1] && i != root_box[0][1] );
165  if (bulk.parallel_size() > 1) {
166  STKUNIT_ASSERT_EQUAL( shared , ! node->sharing().empty() );
167  }
168  }
169  }
170  }
171 
172  size_t count_shared_node_pairs = 0 ;
173  for ( unsigned p = 0 ; p < p_size ; ++p ) if ( p != p_rank ) {
174  for ( int k = p_box[p][2][0] ; k <= p_box[p][2][1] ; ++k )
175  if ( local_box[2][0] <= k && k <= local_box[2][1] ) {
176 
177  for ( int j = p_box[p][1][0] ; j <= p_box[p][1][1] ; ++j )
178  if ( local_box[1][0] <= j && j <= local_box[1][1] ) {
179 
180  for ( int i = p_box[p][0][0] ; i <= p_box[p][0][1] ; ++i )
181  if ( local_box[0][0] <= i && i <= local_box[0][1] ) {
182 
183  EntityRank node_type = 0;
184  EntityId node_id = 1 + i + j * (ngx+1) + k * (ngx+1) * (ngy+1);
185  Entity * const node = bulk.get_entity( node_type , node_id );
186  STKUNIT_ASSERT( node != NULL );
187  // Must be shared with 'p'
188  stk_classic::mesh::PairIterEntityComm iter = node->sharing();
189  for ( ; ! iter.empty() && iter->proc != p ; ++iter );
190  STKUNIT_ASSERT( ! iter.empty() );
191 
192  ++count_shared_node_pairs ;
193  }
194  }
195  }
196  }
197 
198  size_t count_shared_entities = 0 ;
199  for (std::vector<Entity*>::const_iterator
200  i = bulk.entity_comm().begin() ;
201  i != bulk.entity_comm().end() ;
202  ++i) {
203  const stk_classic::mesh::PairIterEntityComm ec = (**i).sharing();
204  count_shared_entities += ec.size();
205  }
206  STKUNIT_ASSERT_EQUAL( count_shared_entities , count_shared_node_pairs );
207 
208  delete [] p_box;
209 }
stk_classic::mesh::BulkData::parallel_size
unsigned parallel_size() const
Size of the parallel machine.
Definition: BulkData.hpp:82
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::count_entities
void count_entities(const Selector &selector, const BulkData &mesh, std::vector< EntityRank > &count)
Local count selected entities of each type.
Definition: GetEntities.cpp:113
stk_classic::mesh::fem::FEMMetaData::locally_owned_part
Part & locally_owned_part() const
Subset for the problem domain that is owned by the local process. Ghost entities are not members of t...
Definition: FEMMetaData.hpp:277
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::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::BulkData::entity_comm
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
Definition: BulkData.hpp:367
stk_classic::PairIter
Definition: PairIter.hpp:21
stk_classic::mesh::fem::FEMMetaData::globally_shared_part
Part & globally_shared_part() const
Subset for the problem domain that is shared with another process. Ghost entities are not members of ...
Definition: FEMMetaData.hpp:282
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::Selector
This is a class for selecting buckets based on a set of meshparts and set logic.
Definition: Selector.hpp:112
stk_classic::mesh::get_entities_through_relations
void get_entities_through_relations(const std::vector< Entity * > &entities, std::vector< Entity * > &entities_related)
Query which mesh entities have a relation to all of the input mesh entities.
Definition: Relation.cpp:156
stk_classic::mesh::fixtures::BoxFixture::box_partition
static void box_partition(int ip, int up, int axis, const BOX box, BOX p_box[])
Definition: BoxFixture.cpp:108
stk_classic::mesh::fem::FEMMetaData::element_rank
EntityRank element_rank() const
Returns the element rank which is always equal to spatial dimension.
Definition: FEMMetaData.hpp:160
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::BulkData
Manager for an integrated collection of entities, entity relations, and buckets of field data.
Definition: BulkData.hpp:49