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 }
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
const std::vector< Entity * > & entity_comm() const
All entities with communication information.
Definition: BulkData.hpp:367
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
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
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
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
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 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
unsigned parallel_rank() const
Rank of the parallel machine&#39;s local processor.
Definition: BulkData.hpp:85
static void box_partition(int ip, int up, int axis, const BOX box, BOX p_box[])
Definition: BoxFixture.cpp:108