|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 #include <stdexcept> 00009 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00010 #include <stk_mesh/fixtures/HexFixture.hpp> 00011 00012 #include <stk_mesh/fem/SkinMesh.hpp> 00013 00014 namespace { 00015 00016 using stk_classic::mesh::Entity; 00017 using stk_classic::mesh::EntityRank; 00018 using stk_classic::mesh::EntityId; 00019 00020 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_x ) 00021 { 00022 // Test 3x1x1 HexFixture structure 00023 const unsigned NX = 3; 00024 const unsigned NY = 1; 00025 const unsigned NZ = 1; 00026 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00027 hf.m_fem_meta.commit(); 00028 hf.generate_mesh(); 00029 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00030 STKUNIT_EXPECT_EQUAL( hf.elem_id(1,0,0), 2u ); 00031 STKUNIT_EXPECT_EQUAL( hf.elem_id(2,0,0), 3u ); 00032 } 00033 00034 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_x ) 00035 { 00036 // Test 3x3x3 HexFixture structure 00037 const unsigned NX = 3; 00038 const unsigned NY = 3; 00039 const unsigned NZ = 3; 00040 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00041 hf.m_fem_meta.commit(); 00042 hf.generate_mesh(); 00043 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00044 STKUNIT_EXPECT_EQUAL( hf.elem_id(1,0,0), 2u ); 00045 STKUNIT_EXPECT_EQUAL( hf.elem_id(2,0,0), 3u ); 00046 } 00047 00048 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_y ) 00049 { 00050 // Test 1x3x1 HexFixture structure 00051 const unsigned NX = 1; 00052 const unsigned NY = 3; 00053 const unsigned NZ = 1; 00054 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00055 hf.m_fem_meta.commit(); 00056 hf.generate_mesh(); 00057 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00058 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,1,0), 2u ); 00059 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,2,0), 3u ); 00060 } 00061 00062 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_y ) 00063 { 00064 // Test 3x3x3 HexFixture structure 00065 const unsigned NX = 3; 00066 const unsigned NY = 3; 00067 const unsigned NZ = 3; 00068 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00069 hf.m_fem_meta.commit(); 00070 hf.generate_mesh(); 00071 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00072 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,1,0), 4u ); 00073 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,2,0), 7u ); 00074 } 00075 00076 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_1d_z ) 00077 { 00078 // Test 1x1x3 HexFixture structure 00079 const unsigned NX = 1; 00080 const unsigned NY = 1; 00081 const unsigned NZ = 3; 00082 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00083 hf.m_fem_meta.commit(); 00084 hf.generate_mesh(); 00085 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00086 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,1), 2u ); 00087 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,2), 3u ); 00088 } 00089 00090 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_z ) 00091 { 00092 // Test 3x3x3 HexFixture structure 00093 const unsigned NX = 3; 00094 const unsigned NY = 3; 00095 const unsigned NZ = 3; 00096 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00097 hf.m_fem_meta.commit(); 00098 hf.generate_mesh(); 00099 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00100 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,1), 10u ); 00101 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,2), 19u ); 00102 } 00103 00104 STKUNIT_UNIT_TEST( UnitTestHexFixture, elem_ids_3d_diag ) 00105 { 00106 // Test 3x3x3 HexFixture structure 00107 const unsigned NX = 3; 00108 const unsigned NY = 3; 00109 const unsigned NZ = 3; 00110 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00111 hf.m_fem_meta.commit(); 00112 hf.generate_mesh(); 00113 STKUNIT_EXPECT_EQUAL( hf.elem_id(0,0,0), 1u ); 00114 STKUNIT_EXPECT_EQUAL( hf.elem_id(1,1,1), 14u ); 00115 STKUNIT_EXPECT_EQUAL( hf.elem_id(2,2,2), 27u ); 00116 } 00117 00118 STKUNIT_UNIT_TEST( UnitTestHexFixture, trivial_parallel_2 ) 00119 { 00120 // Test a customized element distribution with one element on proc 0 and 1 00121 // and none on the other procs 00122 00123 const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD); 00124 const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD); 00125 00126 // Skip unless p_size is at least 2 00127 if (p_size < 2) 00128 return; 00129 00130 const unsigned NX = 2; 00131 const unsigned NY = 1; 00132 const unsigned NZ = 1; 00133 00134 // map< processor, vector of element ids >, this is our custom parallel 00135 // distribution. One element will go on rank 0, the other on rank 1, any 00136 // other ranks get nothing. 00137 std::map<unsigned,std::vector<EntityId> > parallel_distribution; 00138 { 00139 std::vector< EntityId> element_ids; 00140 element_ids.push_back(1); 00141 parallel_distribution[0] = element_ids; 00142 element_ids[0] = 2; 00143 parallel_distribution[1] = element_ids; 00144 } 00145 00146 // Create the fixture 00147 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00148 hf.m_fem_meta.commit(); 00149 if (p_rank <= 1) { 00150 hf.generate_mesh(parallel_distribution[p_rank]); 00151 } 00152 else { 00153 std::vector<EntityId> empty_vector; 00154 hf.generate_mesh( empty_vector ) ; 00155 } 00156 00157 stk_classic::mesh::BulkData & mesh = hf.m_bulk_data; 00158 00159 // Verify element_id 1 is owned by proc 0 00160 // Verify element_id 2 is owned by proc 1 00161 const EntityRank element_rank = hf.m_fem_meta.element_rank(); 00162 Entity * entity_1 = mesh.get_entity(element_rank, 1); 00163 Entity * entity_2 = mesh.get_entity(element_rank ,2); 00164 if (p_rank <= 1) { 00165 STKUNIT_ASSERT_TRUE( entity_1 != NULL ); 00166 STKUNIT_ASSERT_TRUE( entity_2 != NULL ); 00167 STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() ); 00168 STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() ); 00169 } 00170 else { 00171 STKUNIT_EXPECT_TRUE( entity_1 == NULL ); 00172 STKUNIT_EXPECT_TRUE( entity_2 == NULL ); 00173 } 00174 } 00175 00176 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_psizex1x1 ) 00177 { 00178 // Test a customized element distribution with one element on each proc 00179 00180 const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD); 00181 const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD); 00182 00183 const unsigned NX = p_size; 00184 const unsigned NY = 1; 00185 const unsigned NZ = 1; 00186 00187 // map< processor, vector of element ids >, this is our custom parallel 00188 // distribution. Assign each processor an element such that rank+1 = elem_id 00189 std::map<unsigned,std::vector<EntityId> > parallel_distribution; 00190 for (unsigned p=0 ; p < p_size ; ++p) { 00191 std::vector< EntityId> element_ids; 00192 element_ids.push_back(p+1); // element id's start at 1 00193 parallel_distribution[p] = element_ids; 00194 } 00195 00196 // Create the fixture 00197 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00198 hf.m_fem_meta.commit(); 00199 hf.generate_mesh(parallel_distribution[p_rank]); 00200 stk_classic::mesh::BulkData & mesh = hf.m_bulk_data; 00201 const EntityRank element_rank = hf.m_fem_meta.element_rank(); 00202 00203 // We should always know about, and own, the element assigned to us 00204 Entity * my_entity = mesh.get_entity(element_rank, p_rank + 1); 00205 STKUNIT_ASSERT_TRUE( my_entity != NULL ); 00206 STKUNIT_EXPECT_EQUAL( p_rank, my_entity->owner_rank() ); 00207 00208 // If applicable, we know about the element on adjacent lower rank 00209 if (p_rank > 0) { 00210 Entity * prior_entity = mesh.get_entity(element_rank, p_rank); 00211 STKUNIT_ASSERT_TRUE( prior_entity != NULL ); 00212 STKUNIT_EXPECT_EQUAL( p_rank - 1, prior_entity->owner_rank() ); 00213 } 00214 00215 // If applicable, we know about the element on adjacent higher rank 00216 if (p_rank < p_size - 1) { 00217 Entity * next_entity = mesh.get_entity(element_rank, p_rank + 2); 00218 STKUNIT_ASSERT_TRUE( next_entity != NULL ); 00219 STKUNIT_EXPECT_EQUAL( p_rank + 1, next_entity->owner_rank() ); 00220 } 00221 } 00222 00223 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_4x2x1 ) 00224 { 00225 // layout: 4x2x1 hex mesh 00226 // elements: 00227 // [ e_1, e_2, e_3, e_4 ] 00228 // [ e_5, e_6, e_7, e_8 ] 00229 // processors: 00230 // [ p_0, p_1, p_1, p_1 ] 00231 // [ p_1, p_0, p_1, p_1 ] 00232 // 00233 00234 const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD); 00235 const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD); 00236 00237 // Skip unless p_size is at least 2 00238 if (p_size < 2) 00239 return; 00240 00241 const unsigned NX = 4; 00242 const unsigned NY = 2; 00243 const unsigned NZ = 1; 00244 00245 // map< processor, vector of element ids >, this is our custom parallel 00246 // distribution. Assign 1,6 to proc 0, all the rest to proc 1. The other 00247 // procs get nothing. 00248 std::map<unsigned,std::vector<EntityId> > parallel_distribution; 00249 { 00250 std::vector< EntityId> element_ids; 00251 element_ids.push_back(1); 00252 element_ids.push_back(6); 00253 parallel_distribution[0] = element_ids; // proc 0 00254 element_ids.clear(); 00255 element_ids.push_back(2); 00256 element_ids.push_back(3); 00257 element_ids.push_back(4); 00258 element_ids.push_back(5); 00259 element_ids.push_back(7); 00260 element_ids.push_back(8); 00261 parallel_distribution[1] = element_ids; // proc 1 00262 } 00263 00264 // Create the fixture 00265 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00266 hf.m_fem_meta.commit(); 00267 if (p_rank <= 1) { 00268 hf.generate_mesh(parallel_distribution[p_rank]); 00269 } 00270 else { 00271 std::vector<EntityId> empty_vector; 00272 hf.generate_mesh( empty_vector ) ; 00273 } 00274 00275 stk_classic::mesh::BulkData & mesh = hf.m_bulk_data; 00276 00277 // Verify that the entities and known and owned by the appropriate procs 00278 const EntityRank element_rank = hf.m_fem_meta.element_rank(); 00279 Entity * entity_1 = mesh.get_entity(element_rank, 1); 00280 Entity * entity_2 = mesh.get_entity(element_rank, 2); 00281 Entity * entity_3 = mesh.get_entity(element_rank, 3); 00282 Entity * entity_4 = mesh.get_entity(element_rank, 4); 00283 Entity * entity_5 = mesh.get_entity(element_rank, 5); 00284 Entity * entity_6 = mesh.get_entity(element_rank, 6); 00285 Entity * entity_7 = mesh.get_entity(element_rank, 7); 00286 Entity * entity_8 = mesh.get_entity(element_rank, 8); 00287 if (p_rank == 0) { 00288 STKUNIT_ASSERT_TRUE( entity_1 != NULL ); 00289 STKUNIT_ASSERT_TRUE( entity_2 != NULL ); 00290 STKUNIT_ASSERT_TRUE( entity_3 != NULL ); 00291 STKUNIT_ASSERT_TRUE( entity_4 == NULL ); 00292 STKUNIT_ASSERT_TRUE( entity_5 != NULL ); 00293 STKUNIT_ASSERT_TRUE( entity_6 != NULL ); 00294 STKUNIT_ASSERT_TRUE( entity_7 != NULL ); 00295 STKUNIT_ASSERT_TRUE( entity_8 == NULL ); 00296 STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() ); 00297 STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() ); 00298 STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() ); 00299 STKUNIT_EXPECT_EQUAL( 1u, entity_5->owner_rank() ); 00300 STKUNIT_EXPECT_EQUAL( 0u, entity_6->owner_rank() ); 00301 STKUNIT_EXPECT_EQUAL( 1u, entity_7->owner_rank() ); 00302 } 00303 else if (p_rank == 1) { 00304 STKUNIT_ASSERT_TRUE( entity_1 != NULL ); 00305 STKUNIT_ASSERT_TRUE( entity_2 != NULL ); 00306 STKUNIT_ASSERT_TRUE( entity_3 != NULL ); 00307 STKUNIT_ASSERT_TRUE( entity_4 != NULL ); 00308 STKUNIT_ASSERT_TRUE( entity_5 != NULL ); 00309 STKUNIT_ASSERT_TRUE( entity_6 != NULL ); 00310 STKUNIT_ASSERT_TRUE( entity_7 != NULL ); 00311 STKUNIT_ASSERT_TRUE( entity_8 != NULL ); 00312 STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() ); 00313 STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() ); 00314 STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() ); 00315 STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() ); 00316 STKUNIT_EXPECT_EQUAL( 1u, entity_5->owner_rank() ); 00317 STKUNIT_EXPECT_EQUAL( 0u, entity_6->owner_rank() ); 00318 STKUNIT_EXPECT_EQUAL( 1u, entity_7->owner_rank() ); 00319 STKUNIT_EXPECT_EQUAL( 1u, entity_8->owner_rank() ); 00320 } 00321 else { 00322 STKUNIT_EXPECT_TRUE( entity_1 == NULL ); 00323 STKUNIT_EXPECT_TRUE( entity_2 == NULL ); 00324 STKUNIT_EXPECT_TRUE( entity_3 == NULL ); 00325 STKUNIT_EXPECT_TRUE( entity_4 == NULL ); 00326 STKUNIT_EXPECT_TRUE( entity_5 == NULL ); 00327 STKUNIT_EXPECT_TRUE( entity_6 == NULL ); 00328 STKUNIT_EXPECT_TRUE( entity_7 == NULL ); 00329 STKUNIT_EXPECT_TRUE( entity_8 == NULL ); 00330 } 00331 } 00332 00333 STKUNIT_UNIT_TEST( UnitTestHexFixture, disjoint_parallel_5x1x1 ) 00334 { 00335 // layout: 00336 // [ e_1, e_2, e_3, e_4, e_5 ] elements 00337 // [ p_0, p_1, p_1, p_1, p_0 ] processors 00338 // 00339 const unsigned p_rank = stk_classic::parallel_machine_rank(MPI_COMM_WORLD); 00340 const unsigned p_size = stk_classic::parallel_machine_size(MPI_COMM_WORLD); 00341 00342 // Skip unless p_size is at least 2 00343 if (p_size < 2) 00344 return; 00345 00346 const unsigned NX = 5; 00347 const unsigned NY = 1; 00348 const unsigned NZ = 1; 00349 00350 // map< processor, vector of element ids >, this is our custom parallel 00351 // distribution. Assign 1,5 to proc 0, all the rest to proc 1. The other 00352 // procs get nothing. 00353 std::map<unsigned,std::vector<EntityId> > parallel_distribution; 00354 { 00355 std::vector< EntityId> element_ids; 00356 element_ids.push_back(1); 00357 element_ids.push_back(5); 00358 parallel_distribution[0] = element_ids; 00359 element_ids.clear(); 00360 element_ids.push_back(2); 00361 element_ids.push_back(3); 00362 element_ids.push_back(4); 00363 parallel_distribution[1] = element_ids; 00364 } 00365 00366 // Create the fixture 00367 stk_classic::mesh::fixtures::HexFixture hf(MPI_COMM_WORLD,NX,NY,NZ); 00368 hf.m_fem_meta.commit(); 00369 if (p_rank <= 1) { 00370 hf.generate_mesh(parallel_distribution[p_rank]); 00371 } 00372 else { 00373 std::vector<EntityId> empty_vector; 00374 hf.generate_mesh( empty_vector ) ; 00375 } 00376 00377 stk_classic::mesh::BulkData & mesh = hf.m_bulk_data; 00378 00379 // Verify that the entities and known and owned by the appropriate procs 00380 const EntityRank element_rank = hf.m_fem_meta.element_rank(); 00381 Entity * entity_1 = mesh.get_entity(element_rank, 1); 00382 Entity * entity_2 = mesh.get_entity(element_rank, 2); 00383 Entity * entity_3 = mesh.get_entity(element_rank, 3); 00384 Entity * entity_4 = mesh.get_entity(element_rank, 4); 00385 Entity * entity_5 = mesh.get_entity(element_rank, 5); 00386 if (p_rank == 0) { 00387 STKUNIT_ASSERT_TRUE( entity_1 != NULL ); 00388 STKUNIT_ASSERT_TRUE( entity_2 != NULL ); 00389 STKUNIT_ASSERT_TRUE( entity_3 == NULL ); 00390 STKUNIT_ASSERT_TRUE( entity_4 != NULL ); 00391 STKUNIT_ASSERT_TRUE( entity_5 != NULL ); 00392 STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() ); 00393 STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() ); 00394 STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() ); 00395 STKUNIT_EXPECT_EQUAL( 0u, entity_5->owner_rank() ); 00396 } 00397 else if (p_rank == 1) { 00398 STKUNIT_ASSERT_TRUE( entity_1 != NULL ); 00399 STKUNIT_ASSERT_TRUE( entity_2 != NULL ); 00400 STKUNIT_ASSERT_TRUE( entity_3 != NULL ); 00401 STKUNIT_ASSERT_TRUE( entity_4 != NULL ); 00402 STKUNIT_ASSERT_TRUE( entity_5 != NULL ); 00403 STKUNIT_EXPECT_EQUAL( 0u, entity_1->owner_rank() ); 00404 STKUNIT_EXPECT_EQUAL( 1u, entity_2->owner_rank() ); 00405 STKUNIT_EXPECT_EQUAL( 1u, entity_3->owner_rank() ); 00406 STKUNIT_EXPECT_EQUAL( 1u, entity_4->owner_rank() ); 00407 STKUNIT_EXPECT_EQUAL( 0u, entity_5->owner_rank() ); 00408 } 00409 else { 00410 STKUNIT_EXPECT_TRUE( entity_1 == NULL ); 00411 STKUNIT_EXPECT_TRUE( entity_2 == NULL ); 00412 STKUNIT_EXPECT_TRUE( entity_3 == NULL ); 00413 STKUNIT_EXPECT_TRUE( entity_4 == NULL ); 00414 STKUNIT_EXPECT_TRUE( entity_5 == NULL ); 00415 } 00416 } 00417 00418 } // end namespace