Sierra Toolkit Version of the Day
UnitTestSkinIrregular.cpp
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::mesh::EntityId;
00038 using stk::mesh::EntityRank;
00039 
00040 //---------------------------------------------------------------------------------------
00041 
00042 STKUNIT_UNIT_TEST( UnitTestSkin, SkinPocket)
00043 {
00044   enum { SpatialDim = 3 };
00045 
00046   stk::ParallelMachine pm = MPI_COMM_WORLD ;
00047   const unsigned p_rank = stk::parallel_machine_rank( pm );
00048   const unsigned p_size = stk::parallel_machine_size( pm );
00049 
00050   stk::mesh::fem::FEMMetaData fem_meta;
00051   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00052   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00053   stk::mesh::BulkData bulk_data( meta_data , pm );
00054   stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >());
00055   stk::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::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::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::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::mesh::Entity * element = bulk_data.get_entity( element_rank, element_id);
00103     if ( element != NULL) {
00104       stk::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::ParallelMachine pm = MPI_COMM_WORLD ;
00115   const unsigned p_rank = stk::parallel_machine_rank( pm );
00116   const unsigned p_size = stk::parallel_machine_size( pm );
00117 
00118   stk::mesh::fem::FEMMetaData fem_meta;
00119   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00120   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00121   stk::mesh::BulkData bulk_data( meta_data , pm );
00122   stk::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >());
00123   stk::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::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::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::mesh::skin_mesh(bulk_data, element_rank);
00168 
00169   //count number of sides in mesh
00170   {
00171     stk::mesh::Selector select_sides = meta_data.locally_owned_part()  ;
00172     const std::vector<stk::mesh::Bucket*>& side_buckets = bulk_data.buckets(side_rank);
00173     int num_sides = stk::mesh::count_selected_entities( select_sides, side_buckets);
00174 
00175 
00176     stk::all_reduce(MPI_COMM_WORLD, stk::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::ParallelMachine pm = MPI_COMM_WORLD ;
00190   const unsigned p_rank = stk::parallel_machine_rank( pm );
00191   const unsigned p_size = stk::parallel_machine_size( pm );
00192 
00193   stk::mesh::fem::FEMMetaData fem_meta;
00194   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00195   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00196   stk::mesh::BulkData bulk_data( meta_data , pm );
00197   stk::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >());
00198   stk::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::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::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::mesh::skin_mesh(bulk_data, element_rank);
00250 
00251   //count number of sides in mesh
00252   {
00253     stk::mesh::Selector select_sides = meta_data.locally_owned_part()  ;
00254     const std::vector<stk::mesh::Bucket*>& side_buckets = bulk_data.buckets( side_rank);
00255     int num_sides = stk::mesh::count_selected_entities( select_sides, side_buckets);
00256 
00257 
00258     stk::all_reduce(MPI_COMM_WORLD, stk::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::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id);
00271       if ( shell != NULL) {
00272         stk::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::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id);
00305       if ( shell != NULL) {
00306         stk::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::ParallelMachine pm = MPI_COMM_WORLD ;
00346   const unsigned p_rank = stk::parallel_machine_rank( pm );
00347   const unsigned p_size = stk::parallel_machine_size( pm );
00348 
00349   stk::mesh::fem::FEMMetaData fem_meta;
00350   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00351   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00352   stk::mesh::BulkData bulk_data( meta_data , pm );
00353   stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >());
00354   stk::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top );
00355   stk::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >());
00356   stk::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::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::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::mesh::skin_mesh(bulk_data, element_rank);
00402 
00403   //check hex
00404   {
00405     EntityId hex_id = 1;
00406     stk::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id);
00407     if ( element != NULL) {
00408       stk::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::mesh::Entity * element = bulk_data.get_entity( element_rank, shell_id);
00423     if ( element != NULL) {
00424       stk::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::ParallelMachine pm = MPI_COMM_WORLD ;
00443   const unsigned p_rank = stk::parallel_machine_rank( pm );
00444   const unsigned p_size = stk::parallel_machine_size( pm );
00445 
00446   stk::mesh::fem::FEMMetaData fem_meta;
00447   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00448   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00449   stk::mesh::BulkData bulk_data( meta_data , pm );
00450   stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >());
00451   stk::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top );
00452   stk::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >());
00453   stk::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::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::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::mesh::skin_mesh(bulk_data, element_rank);
00500 
00501   //check hex
00502   {
00503     EntityId hex_id = 1;
00504     stk::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id);
00505     if ( element != NULL) {
00506       stk::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::mesh::Entity * element = bulk_data.get_entity( element_rank, shell_id);
00521     if ( element != NULL) {
00522       stk::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::ParallelMachine pm = MPI_COMM_WORLD ;
00541   const unsigned p_rank = stk::parallel_machine_rank( pm );
00542   const unsigned p_size = stk::parallel_machine_size( pm );
00543 
00544   stk::mesh::fem::FEMMetaData fem_meta;
00545   fem_meta.FEM_initialize(SpatialDim, stk::mesh::fem::entity_rank_names(SpatialDim));
00546   stk::mesh::MetaData & meta_data = stk::mesh::fem::FEMMetaData::get_meta_data(fem_meta);
00547   stk::mesh::BulkData bulk_data( meta_data , pm );
00548   stk::mesh::fem::CellTopology hex_top(shards::getCellTopologyData<shards::Hexahedron<8> >());
00549   stk::mesh::Part & hex_part = fem_meta.declare_part( "hex_part", hex_top );
00550   stk::mesh::fem::CellTopology shell_top(shards::getCellTopologyData<shards::ShellQuadrilateral<4> >());
00551   stk::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::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::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::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::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::mesh::skin_mesh(bulk_data, element_rank);
00617 
00618   //check hex
00619   {
00620     EntityId hex_id = 1;
00621     stk::mesh::Entity * element = bulk_data.get_entity( element_rank, hex_id);
00622     if ( element != NULL) {
00623       stk::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::mesh::Entity * shell = bulk_data.get_entity( element_rank, shell_id);
00639       if ( shell != NULL) {
00640         stk::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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends