|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010, 2011 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 00009 #include <algorithm> 00010 #include <stdexcept> 00011 00012 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00013 00014 #include <Shards_BasicTopologies.hpp> 00015 00016 #include <stk_util/parallel/Parallel.hpp> 00017 00018 #include <stk_mesh/base/Types.hpp> 00019 #include <stk_mesh/base/MetaData.hpp> 00020 #include <stk_mesh/base/BulkData.hpp> 00021 #include <stk_mesh/base/Entity.hpp> 00022 #include <stk_mesh/base/GetEntities.hpp> 00023 #include <stk_mesh/base/GetBuckets.hpp> 00024 #include <stk_mesh/base/Selector.hpp> 00025 #include <stk_mesh/base/Field.hpp> 00026 #include <stk_mesh/base/DataTraits.hpp> 00027 00028 #include <stk_mesh/fem/FEMMetaData.hpp> 00029 #include <stk_mesh/fem/FEMHelpers.hpp> 00030 #include <stk_mesh/fem/TopologyDimensions.hpp> 00031 #include <stk_mesh/fem/SkinMesh.hpp> 00032 00033 #include <stk_util/parallel/ParallelReduce.hpp> 00034 00035 #include <iostream> 00036 00037 using stk_classic::mesh::EntityId; 00038 using stk_classic::mesh::EntityRank; 00039 00040 //--------------------------------------------------------------------------------------- 00041 00042 STKUNIT_UNIT_TEST( UnitTestSkin, SkinPocket) 00043 { 00044 enum { SpatialDim = 3 }; 00045 00046 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00047 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00048 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00049 00050 stk_classic::mesh::fem::FEMMetaData fem_meta; 00051 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00052 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00053 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00054 stk_classic::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >()); 00055 stk_classic::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top ); 00056 const EntityRank element_rank = fem_meta.element_rank(); 00057 const EntityRank side_rank = fem_meta.side_rank(); 00058 00059 //create and skin a 2 hex-element mesh with a pocket 00060 //in a normal mesh 6 and 13 would be the same node 00061 // 00062 // 8-------7-------12 00063 // /| /|\ /| 00064 // / | / | \ / | 00065 // 5-------6 | 13-11 | 00066 // | 4----|--3/---|--10 00067 // | / | // | / 00068 // |/ |// |/ 00069 // 1-------2-------9 00070 // 00071 00072 fem_meta.commit(); 00073 00074 bulk_data.modification_begin(); 00075 00076 // declare left element on first process 00077 if (p_rank == 0) 00078 { 00079 EntityId element_id = 1; 00080 EntityId node_ids[8] = { 1, 2, 3, 4, 5, 6, 7, 8}; 00081 00082 stk_classic::mesh::fem::declare_element( bulk_data, hex_part, element_id, node_ids); 00083 00084 } 00085 00086 // declare right element on last process 00087 if (p_rank == p_size -1) 00088 { 00089 EntityId element_id = 2; 00090 EntityId node_ids[8] = { 2, 9, 10, 3, 13, 11, 12, 7}; 00091 00092 stk_classic::mesh::fem::declare_element( bulk_data, hex_part, element_id, node_ids); 00093 } 00094 00095 bulk_data.modification_end(); 00096 00097 //skin the mesh 00098 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00099 00100 //each element should have 6 faces attached to it 00101 for (EntityId element_id = 1; element_id < 3; ++element_id) { 00102 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, element_id); 00103 if ( element != NULL) { 00104 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00105 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 6); 00106 } 00107 } 00108 } 00109 00110 STKUNIT_UNIT_TEST( UnitTestSkin, SkinTwoStackedShells) 00111 { 00112 enum { SpatialDim = 3 }; 00113 00114 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00115 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00116 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00117 00118 stk_classic::mesh::fem::FEMMetaData fem_meta; 00119 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00120 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00121 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00122 stk_classic::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >()); 00123 stk_classic::mesh::Part & shell_part = fem_meta.declare_part( "shell_part", shell_top ); 00124 const EntityRank element_rank = fem_meta.element_rank(); 00125 const EntityRank side_rank = fem_meta.side_rank(); 00126 00127 fem_meta.commit(); 00128 00129 //create and skin stacked shells 00130 // 4-------3 00131 // | | 00132 // | | 00133 // | | 00134 // 1-------2 00135 // 00136 // create following 8 shells 00137 // shells 1 defined with right hand rule 00138 // shells 2 defined with left hand rule 00139 // 00140 // shell_id: node_list 00141 // 1: (1,2,3,4) 00142 // 2: (1,2,3,4) 00143 00144 EntityId node_ids[4] = { 1, 2, 3, 4}; 00145 00146 bulk_data.modification_begin(); 00147 00148 { 00149 bool create_shell_on_proc = static_cast<int>(p_rank) == 0; 00150 if (create_shell_on_proc) { 00151 EntityId element_id = static_cast<EntityId>(1); 00152 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00153 } 00154 } 00155 00156 { 00157 bool create_shell_on_proc = static_cast<int>(p_rank) == (std::max(0,static_cast<int>(p_size)-1)); 00158 if (create_shell_on_proc) { 00159 EntityId element_id = static_cast<EntityId>(2); 00160 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00161 } 00162 } 00163 00164 bulk_data.modification_end(); 00165 00166 //skin the mesh 00167 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00168 00169 //count number of sides in mesh 00170 { 00171 stk_classic::mesh::Selector select_sides = meta_data.locally_owned_part() ; 00172 const std::vector<stk_classic::mesh::Bucket*>& side_buckets = bulk_data.buckets(side_rank); 00173 int num_sides = stk_classic::mesh::count_selected_entities( select_sides, side_buckets); 00174 00175 00176 stk_classic::all_reduce(MPI_COMM_WORLD, stk_classic::ReduceSum<1>(&num_sides)); 00177 00178 // Verify that the correct 2 sides are present. 00179 00180 STKUNIT_ASSERT_EQUAL( num_sides, 2 ); 00181 } 00182 } 00183 00184 //--------------------------------------------------------------------------------------- 00185 STKUNIT_UNIT_TEST( UnitTestSkin, SkinStackedShells) 00186 { 00187 enum { SpatialDim = 3 }; 00188 00189 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00190 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00191 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00192 00193 stk_classic::mesh::fem::FEMMetaData fem_meta; 00194 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00195 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00196 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00197 stk_classic::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >()); 00198 stk_classic::mesh::Part & shell_part = fem_meta.declare_part( "shell_part", shell_top ); 00199 const EntityRank element_rank = fem_meta.element_rank(); 00200 const EntityRank side_rank = fem_meta.side_rank(); 00201 00202 fem_meta.commit(); 00203 00204 //create and skin stacked shells 00205 // 4-------3 00206 // | | 00207 // | | 00208 // | | 00209 // 1-------2 00210 // 00211 // create following 8 shells 00212 // shells 1-4 defined with right hand rule 00213 // shells 5-6 defined with left hand rule 00214 // 00215 // shell_id: node_list 00216 // 1: (1,2,3,4) 00217 // 2: (2,3,4,1) 00218 // 3: (3,4,1,2) 00219 // 4: (4,1,2,3) 00220 // 5: (4,3,2,1) 00221 // 6: (3,2,1,4) 00222 // 7: (2,1,4,3) 00223 // 8: (1,4,3,2) 00224 00225 EntityId node_ids[8] = { 1, 2, 3, 4, 1, 2, 3, 4}; 00226 EntityId reverse_node_ids[8] = { 4, 3, 2, 1, 4, 3, 2, 1}; 00227 00228 bulk_data.modification_begin(); 00229 00230 //create shells 00231 for ( int i = 0; i<4; i++ ) { 00232 00233 bool create_shell_on_proc = static_cast<int>(p_rank) == (std::max(0,static_cast<int>(p_size)-1-i)); 00234 if (create_shell_on_proc) { 00235 EntityId element_id = static_cast<EntityId>(i+1); 00236 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids+i); 00237 } 00238 00239 bool create_reverse_shell_on_proc = static_cast<int>(p_rank) == (std::max(0,static_cast<int>(p_size)-1-4-i)); 00240 if (create_reverse_shell_on_proc) { 00241 EntityId reverse_element_id = static_cast<EntityId>(i+1+4); 00242 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, reverse_element_id, reverse_node_ids+i); 00243 } 00244 } 00245 00246 bulk_data.modification_end(); 00247 00248 //skin the mesh 00249 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00250 00251 //count number of sides in mesh 00252 { 00253 stk_classic::mesh::Selector select_sides = meta_data.locally_owned_part() ; 00254 const std::vector<stk_classic::mesh::Bucket*>& side_buckets = bulk_data.buckets( side_rank); 00255 int num_sides = stk_classic::mesh::count_selected_entities( select_sides, side_buckets); 00256 00257 00258 stk_classic::all_reduce(MPI_COMM_WORLD, stk_classic::ReduceSum<1>(&num_sides)); 00259 00260 // Verify that the correct 2 sides are present. 00261 00262 STKUNIT_ASSERT_EQUAL( num_sides, 2 ); 00263 } 00264 00265 //check that faces are attached to correct sides 00266 { 00267 EntityId face_1_id = 0; //invalid face id 00268 EntityId face_2_id = 0; //invalid face id 00269 for (EntityId shell_id = 1; shell_id < 5; ++shell_id) { 00270 stk_classic::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id); 00271 if ( shell != NULL) { 00272 stk_classic::mesh::PairIterRelation shell_side_relations = shell->relations(side_rank); 00273 00274 STKUNIT_ASSERT_TRUE( shell_side_relations.size() == 2); 00275 00276 // verify that only one side has been created 00277 // and that all stacked shells reference this side 00278 if (face_1_id == 0) { 00279 face_1_id = shell_side_relations->entity()->identifier(); 00280 } 00281 else { 00282 STKUNIT_EXPECT_TRUE( face_1_id == shell_side_relations->entity()->identifier()); 00283 } 00284 00285 //check that the side is one the correct local side of the shell 00286 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 0); 00287 00288 ++shell_side_relations; 00289 00290 if (face_2_id == 0) { 00291 face_2_id = shell_side_relations->entity()->identifier(); 00292 } 00293 else { 00294 STKUNIT_EXPECT_TRUE( face_2_id == shell_side_relations->entity()->identifier()); 00295 } 00296 00297 //check that the side is one the correct local side of the shell 00298 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 1); 00299 00300 } 00301 } 00302 00303 for (EntityId shell_id = 5; shell_id < 9; ++shell_id) { 00304 stk_classic::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id); 00305 if ( shell != NULL) { 00306 stk_classic::mesh::PairIterRelation shell_side_relations = shell->relations(side_rank); 00307 00308 STKUNIT_ASSERT_TRUE( shell_side_relations.size() == 2); 00309 00310 // verify that only one side has been created 00311 // and that all stacked shells reference this side 00312 if (face_2_id == 0) { 00313 face_2_id = shell_side_relations->entity()->identifier(); 00314 } 00315 else { 00316 STKUNIT_EXPECT_TRUE( face_2_id == shell_side_relations->entity()->identifier()); 00317 } 00318 00319 //check that the side is one the correct local side of the shell 00320 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 0); 00321 00322 ++shell_side_relations; 00323 00324 if (face_1_id == 0) { 00325 face_1_id = shell_side_relations->entity()->identifier(); 00326 } 00327 else { 00328 STKUNIT_EXPECT_TRUE( face_1_id == shell_side_relations->entity()->identifier()); 00329 } 00330 00331 //check that the side is one the correct local side of the shell 00332 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 1); 00333 00334 } 00335 } 00336 } 00337 } 00338 00339 //--------------------------------------------------------------------------------------- 00340 00341 STKUNIT_UNIT_TEST( UnitTestSkin, SkinShellOnHex) 00342 { 00343 enum { SpatialDim = 3 }; 00344 00345 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00346 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00347 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00348 00349 stk_classic::mesh::fem::FEMMetaData fem_meta; 00350 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00351 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00352 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00353 stk_classic::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >()); 00354 stk_classic::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top ); 00355 stk_classic::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >()); 00356 stk_classic::mesh::Part & shell_part = fem_meta.declare_part( "shell_part", shell_top ); 00357 const EntityRank element_rank = fem_meta.element_rank(); 00358 const EntityRank side_rank = fem_meta.side_rank(); 00359 00360 //create and skin a hex element mesh with a shell on the first side of the hex 00361 // Using a shell defined by the nodes (1, 2, 6, 5) produces an orientated shell 00362 // 00363 // Therefore the shell will be skinned with 1 side and the hex will have 5. 00364 // 00365 // 8-------7 00366 // /| /| 00367 // / | / | 00368 // 5=======6 | 00369 // || 4----||-3 00370 // ||/ ||/ 00371 // |/ |/ 00372 // 1=======2 00373 // 00374 00375 fem_meta.commit(); 00376 00377 bulk_data.modification_begin(); 00378 00379 // declare hex element on first process 00380 if (p_rank == 0) 00381 { 00382 EntityId element_id = 1; 00383 EntityId node_ids[8] = { 1, 2, 3, 4, 5, 6, 7, 8}; 00384 00385 stk_classic::mesh::fem::declare_element( bulk_data, hex_part, element_id, node_ids); 00386 00387 } 00388 00389 // declare shell element on last process 00390 if (p_rank == p_size -1) 00391 { 00392 EntityId element_id = 2; 00393 EntityId node_ids[8] = { 1, 2, 6, 5}; 00394 00395 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00396 } 00397 00398 bulk_data.modification_end(); 00399 00400 //skin the mesh 00401 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00402 00403 //check hex 00404 { 00405 EntityId hex_id = 1; 00406 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id); 00407 if ( element != NULL) { 00408 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00409 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 5); 00410 for (; !element_side_relations.empty(); ++element_side_relations) { 00411 unsigned local_side_id = element_side_relations->identifier(); 00412 bool correct_side_skinned = local_side_id > 0 && local_side_id < 6; 00413 STKUNIT_EXPECT_TRUE (correct_side_skinned); 00414 std::cout << "Hex local side id: " << local_side_id << std::endl; 00415 } 00416 } 00417 } 00418 00419 //check shell 00420 { 00421 EntityId shell_id = 2; 00422 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, shell_id); 00423 if ( element != NULL) { 00424 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00425 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 1); 00426 for (; !element_side_relations.empty(); ++element_side_relations) { 00427 unsigned local_side_id = element_side_relations->identifier(); 00428 bool correct_side_skinned = local_side_id == 0; 00429 STKUNIT_EXPECT_TRUE (correct_side_skinned); 00430 std::cout << "Shell local side id: " << local_side_id << std::endl; 00431 } 00432 } 00433 } 00434 } 00435 00436 //--------------------------------------------------------------------------------------- 00437 00438 STKUNIT_UNIT_TEST( UnitTestSkin, SkinInvertedShellOnHex) 00439 { 00440 enum { SpatialDim = 3 }; 00441 00442 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00443 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00444 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00445 00446 stk_classic::mesh::fem::FEMMetaData fem_meta; 00447 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00448 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00449 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00450 stk_classic::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >()); 00451 stk_classic::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top ); 00452 stk_classic::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >()); 00453 stk_classic::mesh::Part & shell_part = fem_meta.declare_part( "shell_part", shell_top ); 00454 const EntityRank element_rank = fem_meta.element_rank(); 00455 const EntityRank side_rank = fem_meta.side_rank(); 00456 00457 //create and skin a hex element mesh with an inverted shell 00458 // Using a shell defined by the nodes (1, 2, 5, 6) produces an inverted shell 00459 // with no valid orientation 00460 // 00461 // Therefore the shell will be skinned with 2 sides and the hex will have 6. 00462 // 00463 // 8-------7 00464 // /| /| 00465 // / | / | 00466 // 5=======6 | 00467 // || 4----||-3 00468 // ||/ ||/ 00469 // |/ |/ 00470 // 1=======2 00471 // 00472 00473 fem_meta.commit(); 00474 00475 bulk_data.modification_begin(); 00476 00477 // declare hex element on first process 00478 if (p_rank == 0) 00479 { 00480 EntityId element_id = 1; 00481 EntityId node_ids[8] = { 1, 2, 3, 4, 5, 6, 7, 8}; 00482 00483 stk_classic::mesh::fem::declare_element( bulk_data, hex_part, element_id, node_ids); 00484 00485 } 00486 00487 // declare shell element on last process 00488 if (p_rank == p_size -1) 00489 { 00490 EntityId element_id = 2; 00491 EntityId node_ids[8] = { 1, 2, 5, 6}; 00492 00493 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00494 } 00495 00496 bulk_data.modification_end(); 00497 00498 //skin the mesh 00499 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00500 00501 //check hex 00502 { 00503 EntityId hex_id = 1; 00504 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id); 00505 if ( element != NULL) { 00506 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00507 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 6); 00508 for (; !element_side_relations.empty(); ++element_side_relations) { 00509 unsigned local_side_id = element_side_relations->identifier(); 00510 bool correct_side_skinned = local_side_id < 6; 00511 STKUNIT_EXPECT_TRUE (correct_side_skinned); 00512 std::cout << "Hex local side id: " << local_side_id << std::endl; 00513 } 00514 } 00515 } 00516 00517 //check shell 00518 { 00519 EntityId shell_id = 2; 00520 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, shell_id); 00521 if ( element != NULL) { 00522 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00523 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 2); 00524 for (; !element_side_relations.empty(); ++element_side_relations) { 00525 unsigned local_side_id = element_side_relations->identifier(); 00526 bool correct_side_skinned = local_side_id < 2; 00527 STKUNIT_EXPECT_TRUE (correct_side_skinned); 00528 std::cout << "Shell local side id: " << element_side_relations->identifier() << std::endl; 00529 } 00530 } 00531 } 00532 } 00533 00534 //--------------------------------------------------------------------------------------- 00535 00536 STKUNIT_UNIT_TEST( UnitTestSkin, SkinStackedShellOnHex) 00537 { 00538 enum { SpatialDim = 3 }; 00539 00540 stk_classic::ParallelMachine pm = MPI_COMM_WORLD ; 00541 const unsigned p_rank = stk_classic::parallel_machine_rank( pm ); 00542 const unsigned p_size = stk_classic::parallel_machine_size( pm ); 00543 00544 stk_classic::mesh::fem::FEMMetaData fem_meta; 00545 fem_meta.FEM_initialize(SpatialDim, stk_classic::mesh::fem::entity_rank_names(SpatialDim)); 00546 stk_classic::mesh::MetaData & meta_data = stk_classic::mesh::fem::FEMMetaData::get_meta_data(fem_meta); 00547 stk_classic::mesh::BulkData bulk_data( meta_data , pm ); 00548 stk_classic::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >()); 00549 stk_classic::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top ); 00550 stk_classic::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >()); 00551 stk_classic::mesh::Part & shell_part = fem_meta.declare_part( "shell_part", shell_top ); 00552 const EntityRank element_rank = fem_meta.element_rank(); 00553 const EntityRank side_rank = fem_meta.side_rank(); 00554 00555 //create and skin a hex element mesh with 3 shells on the first side of the hex 00556 // Using shells defined by the nodes (1, 2, 6, 5), (6, 5, 1, 2), and (1, 5, 6, 2) 00557 // produces an orientated shells. 00558 // 00559 // Therefore the shells will all have a relation to the same side. 00560 // 00561 // 8-------7 00562 // /| /| 00563 // / | / | 00564 // 5=======6 | 00565 // || 4----||-3 00566 // ||/ ||/ 00567 // |/ |/ 00568 // 1=======2 00569 // 00570 00571 fem_meta.commit(); 00572 00573 bulk_data.modification_begin(); 00574 00575 bool create_hex_this_proc = (p_rank == 0); 00576 bool create_shell_1_this_proc = static_cast<int>(p_rank) == (std::max(0,static_cast<int>(p_size)-3)); 00577 bool create_shell_2_this_proc = static_cast<int>(p_rank) == (std::max(0,static_cast<int>(p_size)-2)); 00578 bool create_shell_3_this_proc = (p_rank == p_size -1); 00579 00580 if (create_hex_this_proc) 00581 { 00582 EntityId element_id = 1; 00583 EntityId node_ids[8] = { 1, 2, 3, 4, 5, 6, 7, 8}; 00584 00585 stk_classic::mesh::fem::declare_element( bulk_data, hex_part, element_id, node_ids); 00586 00587 } 00588 00589 if (create_shell_1_this_proc) 00590 { 00591 EntityId element_id = 2; 00592 EntityId node_ids[8] = { 1, 2, 6, 5}; 00593 00594 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00595 } 00596 00597 if (create_shell_2_this_proc) 00598 { 00599 EntityId element_id = 3; 00600 EntityId node_ids[8] = { 6, 5, 1, 2}; 00601 00602 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00603 } 00604 00605 if (create_shell_3_this_proc) 00606 { 00607 EntityId element_id = 4; 00608 EntityId node_ids[8] = { 1, 5, 6, 2}; 00609 00610 stk_classic::mesh::fem::declare_element( bulk_data, shell_part, element_id, node_ids); 00611 } 00612 00613 bulk_data.modification_end(); 00614 00615 //skin the mesh 00616 stk_classic::mesh::skin_mesh(bulk_data, element_rank); 00617 00618 //check hex 00619 { 00620 EntityId hex_id = 1; 00621 stk_classic::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id); 00622 if ( element != NULL) { 00623 stk_classic::mesh::PairIterRelation element_side_relations = element->relations(side_rank); 00624 STKUNIT_EXPECT_TRUE( element_side_relations.size() == 5); 00625 for (; !element_side_relations.empty(); ++element_side_relations) { 00626 unsigned local_side_id = element_side_relations->identifier(); 00627 bool correct_side_skinned = local_side_id > 0 && local_side_id < 6; 00628 STKUNIT_EXPECT_TRUE (correct_side_skinned); 00629 std::cout << "Hex local side id: " << local_side_id << std::endl; 00630 } 00631 } 00632 } 00633 00634 //check shells 00635 { 00636 EntityId face_id = 0; //invalid face id 00637 for (EntityId shell_id = 2; shell_id < 5; ++shell_id) { 00638 stk_classic::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id); 00639 if ( shell != NULL) { 00640 stk_classic::mesh::PairIterRelation shell_side_relations = shell->relations(side_rank); 00641 00642 STKUNIT_EXPECT_TRUE( shell_side_relations.size() == 1); 00643 00644 // verify that only one side has been created 00645 // and that all stacked shells reference this side 00646 if (face_id == 0) { 00647 face_id = shell_side_relations->entity()->identifier(); 00648 } 00649 else { 00650 STKUNIT_EXPECT_TRUE( face_id == shell_side_relations->entity()->identifier()); 00651 std::cout << "Shell: " << shell_id 00652 << "\tFace_id: " << face_id 00653 << "\tFace_id: " << shell_side_relations->entity()->identifier() 00654 << std::endl; 00655 } 00656 00657 //check that the side is one the correct local side of the shell 00658 //shells 1 and 2 follow the right hand rule so the side should be on 00659 //local_side_id 0. 00660 //shell 3 should have it's side on local_side_1d 1 00661 if (shell_id != 4) { 00662 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 0); 00663 } 00664 else { 00665 STKUNIT_EXPECT_TRUE( shell_side_relations->identifier() == 1); 00666 } 00667 } 00668 } 00669 } 00670 }