Sierra Toolkit  Version of the Day
UnitTestHexFixture.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 #include <stdexcept>
9 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
10 #include <stk_mesh/fixtures/HexFixture.hpp>
11 
12 #include <stk_mesh/fem/SkinMesh.hpp>
13 
14 namespace {
15 
17 using stk_classic::mesh::EntityRank;
18 using stk_classic::mesh::EntityId;
19 
20 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_x )
21 {
22  // Test 3x1x1 HexFixture structure
23  const unsigned NX = 3;
24  const unsigned NY = 1;
25  const unsigned NZ = 1;
26  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
27  hf.m_fem_meta.commit();
28  hf.generate_mesh();
29  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
30  STKUNIT_EXPECT_EQUAL( hf.elem_id(1,0,0), 2u );
31  STKUNIT_EXPECT_EQUAL( hf.elem_id(2,0,0), 3u );
32 }
33 
34 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_x )
35 {
36  // Test 3x3x3 HexFixture structure
37  const unsigned NX = 3;
38  const unsigned NY = 3;
39  const unsigned NZ = 3;
40  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
41  hf.m_fem_meta.commit();
42  hf.generate_mesh();
43  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
44  STKUNIT_EXPECT_EQUAL( hf.elem_id(1,0,0), 2u );
45  STKUNIT_EXPECT_EQUAL( hf.elem_id(2,0,0), 3u );
46 }
47 
48 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_y )
49 {
50  // Test 1x3x1 HexFixture structure
51  const unsigned NX = 1;
52  const unsigned NY = 3;
53  const unsigned NZ = 1;
54  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
55  hf.m_fem_meta.commit();
56  hf.generate_mesh();
57  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
58  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,1,0), 2u );
59  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,2,0), 3u );
60 }
61 
62 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_y )
63 {
64  // Test 3x3x3 HexFixture structure
65  const unsigned NX = 3;
66  const unsigned NY = 3;
67  const unsigned NZ = 3;
68  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
69  hf.m_fem_meta.commit();
70  hf.generate_mesh();
71  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
72  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,1,0), 4u );
73  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,2,0), 7u );
74 }
75 
76 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_z )
77 {
78  // Test 1x1x3 HexFixture structure
79  const unsigned NX = 1;
80  const unsigned NY = 1;
81  const unsigned NZ = 3;
82  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
83  hf.m_fem_meta.commit();
84  hf.generate_mesh();
85  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
86  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,1), 2u );
87  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,2), 3u );
88 }
89 
90 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_z )
91 {
92  // Test 3x3x3 HexFixture structure
93  const unsigned NX = 3;
94  const unsigned NY = 3;
95  const unsigned NZ = 3;
96  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
97  hf.m_fem_meta.commit();
98  hf.generate_mesh();
99  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
100  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,1), 10u );
101  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,2), 19u );
102 }
103 
104 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_diag )
105 {
106  // Test 3x3x3 HexFixture structure
107  const unsigned NX = 3;
108  const unsigned NY = 3;
109  const unsigned NZ = 3;
110  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
111  hf.m_fem_meta.commit();
112  hf.generate_mesh();
113  STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u );
114  STKUNIT_EXPECT_EQUAL( hf.elem_id(1,1,1), 14u );
115  STKUNIT_EXPECT_EQUAL( hf.elem_id(2,2,2), 27u );
116 }
117 
118 STKUNIT_UNIT_TEST( UnitTestHexFixture, trivial_parallel_2 )
119 {
120  // Test a customized element distribution with one element on proc 0 and 1
121  // and none on the other procs
122 
123  const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD);
124  const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD);
125 
126  // Skip unless p_size is at least 2
127  if (p_size < 2)
128  return;
129 
130  const unsigned NX = 2;
131  const unsigned NY = 1;
132  const unsigned NZ = 1;
133 
134  // map< processor, vector of element ids >, this is our custom parallel
135  // distribution. One element will go on rank 0, the other on rank 1, any
136  // other ranks get nothing.
137  std::map<unsigned,std::vector<EntityId> > parallel_distribution;
138  {
139  std::vector< EntityId> element_ids;
140  element_ids.push_back(1);
141  parallel_distribution[0] = element_ids;
142  element_ids[0] = 2;
143  parallel_distribution[1] = element_ids;
144  }
145 
146  // Create the fixture
147  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
148  hf.m_fem_meta.commit();
149  if (p_rank <= 1) {
150  hf.generate_mesh(parallel_distribution[p_rank]);
151  }
152  else {
153  std::vector<EntityId> empty_vector;
154  hf.generate_mesh( empty_vector ) ;
155  }
156 
157  stk_classic::mesh::BulkData & mesh = hf.m_bulk_data;
158 
159  // Verify element_id 1 is owned by proc 0
160  // Verify element_id 2 is owned by proc 1
161  const EntityRank element_rank = hf.m_fem_meta.element_rank();
162  Entity * entity_1 = mesh.get_entity(element_rank, 1);
163  Entity * entity_2 = mesh.get_entity(element_rank ,2);
164  if (p_rank <= 1) {
165  STKUNIT_ASSERT_TRUE( entity_1 != NULL );
166  STKUNIT_ASSERT_TRUE( entity_2 != NULL );
167  STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() );
168  STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() );
169  }
170  else {
171  STKUNIT_EXPECT_TRUE( entity_1 == NULL );
172  STKUNIT_EXPECT_TRUE( entity_2 == NULL );
173  }
174 }
175 
176 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_psizex1x1 )
177 {
178  // Test a customized element distribution with one element on each proc
179 
180  const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD);
181  const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD);
182 
183  const unsigned NX = p_size;
184  const unsigned NY = 1;
185  const unsigned NZ = 1;
186 
187  // map< processor, vector of element ids >, this is our custom parallel
188  // distribution. Assign each processor an element such that rank+1 = elem_id
189  std::map<unsigned,std::vector<EntityId> > parallel_distribution;
190  for (unsigned p=0 ; p < p_size ; ++p) {
191  std::vector< EntityId> element_ids;
192  element_ids.push_back(p+1); // element id's start at 1
193  parallel_distribution[p] = element_ids;
194  }
195 
196  // Create the fixture
197  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
198  hf.m_fem_meta.commit();
199  hf.generate_mesh(parallel_distribution[p_rank]);
200  stk_classic::mesh::BulkData & mesh = hf.m_bulk_data;
201  const EntityRank element_rank = hf.m_fem_meta.element_rank();
202 
203  // We should always know about, and own, the element assigned to us
204  Entity * my_entity = mesh.get_entity(element_rank, p_rank + 1);
205  STKUNIT_ASSERT_TRUE( my_entity != NULL );
206  STKUNIT_EXPECT_EQUAL( p_rank, my_entity->owner_rank() );
207 
208  // If applicable, we know about the element on adjacent lower rank
209  if (p_rank > 0) {
210  Entity * prior_entity = mesh.get_entity(element_rank, p_rank);
211  STKUNIT_ASSERT_TRUE( prior_entity != NULL );
212  STKUNIT_EXPECT_EQUAL( p_rank - 1, prior_entity->owner_rank() );
213  }
214 
215  // If applicable, we know about the element on adjacent higher rank
216  if (p_rank < p_size - 1) {
217  Entity * next_entity = mesh.get_entity(element_rank, p_rank + 2);
218  STKUNIT_ASSERT_TRUE( next_entity != NULL );
219  STKUNIT_EXPECT_EQUAL( p_rank + 1, next_entity->owner_rank() );
220  }
221 }
222 
223 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_4x2x1 )
224 {
225  // layout: 4x2x1 hex mesh
226  // elements:
227  // [ e_1, e_2, e_3, e_4 ]
228  // [ e_5, e_6, e_7, e_8 ]
229  // processors:
230  // [ p_0, p_1, p_1, p_1 ]
231  // [ p_1, p_0, p_1, p_1 ]
232  //
233 
234  const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD);
235  const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD);
236 
237  // Skip unless p_size is at least 2
238  if (p_size < 2)
239  return;
240 
241  const unsigned NX = 4;
242  const unsigned NY = 2;
243  const unsigned NZ = 1;
244 
245  // map< processor, vector of element ids >, this is our custom parallel
246  // distribution. Assign 1,6 to proc 0, all the rest to proc 1. The other
247  // procs get nothing.
248  std::map<unsigned,std::vector<EntityId> > parallel_distribution;
249  {
250  std::vector< EntityId> element_ids;
251  element_ids.push_back(1);
252  element_ids.push_back(6);
253  parallel_distribution[0] = element_ids; // proc 0
254  element_ids.clear();
255  element_ids.push_back(2);
256  element_ids.push_back(3);
257  element_ids.push_back(4);
258  element_ids.push_back(5);
259  element_ids.push_back(7);
260  element_ids.push_back(8);
261  parallel_distribution[1] = element_ids; // proc 1
262  }
263 
264  // Create the fixture
265  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
266  hf.m_fem_meta.commit();
267  if (p_rank <= 1) {
268  hf.generate_mesh(parallel_distribution[p_rank]);
269  }
270  else {
271  std::vector<EntityId> empty_vector;
272  hf.generate_mesh( empty_vector ) ;
273  }
274 
275  stk_classic::mesh::BulkData & mesh = hf.m_bulk_data;
276 
277  // Verify that the entities and known and owned by the appropriate procs
278  const EntityRank element_rank = hf.m_fem_meta.element_rank();
279  Entity * entity_1 = mesh.get_entity(element_rank, 1);
280  Entity * entity_2 = mesh.get_entity(element_rank, 2);
281  Entity * entity_3 = mesh.get_entity(element_rank, 3);
282  Entity * entity_4 = mesh.get_entity(element_rank, 4);
283  Entity * entity_5 = mesh.get_entity(element_rank, 5);
284  Entity * entity_6 = mesh.get_entity(element_rank, 6);
285  Entity * entity_7 = mesh.get_entity(element_rank, 7);
286  Entity * entity_8 = mesh.get_entity(element_rank, 8);
287  if (p_rank == 0) {
288  STKUNIT_ASSERT_TRUE( entity_1 != NULL );
289  STKUNIT_ASSERT_TRUE( entity_2 != NULL );
290  STKUNIT_ASSERT_TRUE( entity_3 != NULL );
291  STKUNIT_ASSERT_TRUE( entity_4 == NULL );
292  STKUNIT_ASSERT_TRUE( entity_5 != NULL );
293  STKUNIT_ASSERT_TRUE( entity_6 != NULL );
294  STKUNIT_ASSERT_TRUE( entity_7 != NULL );
295  STKUNIT_ASSERT_TRUE( entity_8 == NULL );
296  STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() );
297  STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() );
298  STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() );
299  STKUNIT_EXPECT_EQUAL( 1u, entity_5->owner_rank() );
300  STKUNIT_EXPECT_EQUAL( 0u, entity_6->owner_rank() );
301  STKUNIT_EXPECT_EQUAL( 1u, entity_7->owner_rank() );
302  }
303  else if (p_rank == 1) {
304  STKUNIT_ASSERT_TRUE( entity_1 != NULL );
305  STKUNIT_ASSERT_TRUE( entity_2 != NULL );
306  STKUNIT_ASSERT_TRUE( entity_3 != NULL );
307  STKUNIT_ASSERT_TRUE( entity_4 != NULL );
308  STKUNIT_ASSERT_TRUE( entity_5 != NULL );
309  STKUNIT_ASSERT_TRUE( entity_6 != NULL );
310  STKUNIT_ASSERT_TRUE( entity_7 != NULL );
311  STKUNIT_ASSERT_TRUE( entity_8 != NULL );
312  STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() );
313  STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() );
314  STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() );
315  STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() );
316  STKUNIT_EXPECT_EQUAL( 1u, entity_5->owner_rank() );
317  STKUNIT_EXPECT_EQUAL( 0u, entity_6->owner_rank() );
318  STKUNIT_EXPECT_EQUAL( 1u, entity_7->owner_rank() );
319  STKUNIT_EXPECT_EQUAL( 1u, entity_8->owner_rank() );
320  }
321  else {
322  STKUNIT_EXPECT_TRUE( entity_1 == NULL );
323  STKUNIT_EXPECT_TRUE( entity_2 == NULL );
324  STKUNIT_EXPECT_TRUE( entity_3 == NULL );
325  STKUNIT_EXPECT_TRUE( entity_4 == NULL );
326  STKUNIT_EXPECT_TRUE( entity_5 == NULL );
327  STKUNIT_EXPECT_TRUE( entity_6 == NULL );
328  STKUNIT_EXPECT_TRUE( entity_7 == NULL );
329  STKUNIT_EXPECT_TRUE( entity_8 == NULL );
330  }
331 }
332 
333 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_5x1x1 )
334 {
335  // layout:
336  // [ e_1, e_2, e_3, e_4, e_5 ] elements
337  // [ p_0, p_1, p_1, p_1, p_0 ] processors
338  //
339  const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD);
340  const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD);
341 
342  // Skip unless p_size is at least 2
343  if (p_size < 2)
344  return;
345 
346  const unsigned NX = 5;
347  const unsigned NY = 1;
348  const unsigned NZ = 1;
349 
350  // map< processor, vector of element ids >, this is our custom parallel
351  // distribution. Assign 1,5 to proc 0, all the rest to proc 1. The other
352  // procs get nothing.
353  std::map<unsigned,std::vector<EntityId> > parallel_distribution;
354  {
355  std::vector< EntityId> element_ids;
356  element_ids.push_back(1);
357  element_ids.push_back(5);
358  parallel_distribution[0] = element_ids;
359  element_ids.clear();
360  element_ids.push_back(2);
361  element_ids.push_back(3);
362  element_ids.push_back(4);
363  parallel_distribution[1] = element_ids;
364  }
365 
366  // Create the fixture
367  stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ);
368  hf.m_fem_meta.commit();
369  if (p_rank <= 1) {
370  hf.generate_mesh(parallel_distribution[p_rank]);
371  }
372  else {
373  std::vector<EntityId> empty_vector;
374  hf.generate_mesh( empty_vector ) ;
375  }
376 
377  stk_classic::mesh::BulkData & mesh = hf.m_bulk_data;
378 
379  // Verify that the entities and known and owned by the appropriate procs
380  const EntityRank element_rank = hf.m_fem_meta.element_rank();
381  Entity * entity_1 = mesh.get_entity(element_rank, 1);
382  Entity * entity_2 = mesh.get_entity(element_rank, 2);
383  Entity * entity_3 = mesh.get_entity(element_rank, 3);
384  Entity * entity_4 = mesh.get_entity(element_rank, 4);
385  Entity * entity_5 = mesh.get_entity(element_rank, 5);
386  if (p_rank == 0) {
387  STKUNIT_ASSERT_TRUE( entity_1 != NULL );
388  STKUNIT_ASSERT_TRUE( entity_2 != NULL );
389  STKUNIT_ASSERT_TRUE( entity_3 == NULL );
390  STKUNIT_ASSERT_TRUE( entity_4 != NULL );
391  STKUNIT_ASSERT_TRUE( entity_5 != NULL );
392  STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() );
393  STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() );
394  STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() );
395  STKUNIT_EXPECT_EQUAL( 0u, entity_5->owner_rank() );
396  }
397  else if (p_rank == 1) {
398  STKUNIT_ASSERT_TRUE( entity_1 != NULL );
399  STKUNIT_ASSERT_TRUE( entity_2 != NULL );
400  STKUNIT_ASSERT_TRUE( entity_3 != NULL );
401  STKUNIT_ASSERT_TRUE( entity_4 != NULL );
402  STKUNIT_ASSERT_TRUE( entity_5 != NULL );
403  STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() );
404  STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() );
405  STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() );
406  STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() );
407  STKUNIT_EXPECT_EQUAL( 0u, entity_5->owner_rank() );
408  }
409  else {
410  STKUNIT_EXPECT_TRUE( entity_1 == NULL );
411  STKUNIT_EXPECT_TRUE( entity_2 == NULL );
412  STKUNIT_EXPECT_TRUE( entity_3 == NULL );
413  STKUNIT_EXPECT_TRUE( entity_4 == NULL );
414  STKUNIT_EXPECT_TRUE( entity_5 == NULL );
415  }
416 }
417 
418 } // end namespace
Entity * get_entity(EntityRank entity_rank, EntityId entity_id) const
Get entity with a given key.
Definition: BulkData.hpp:211
unsigned parallel_machine_rank(ParallelMachine parallel_machine)
Member function parallel_machine_rank ...
Definition: Parallel.cpp:29
unsigned parallel_machine_size(ParallelMachine parallel_machine)
Member function parallel_machine_size ...
Definition: Parallel.cpp:18
Manager for an integrated collection of entities, entity relations, and buckets of field data...
Definition: BulkData.hpp:49
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
Definition: Entity.hpp:120