Sierra Toolkit Version of the Day
UnitTestSkinning.cpp
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 
00009 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
00010 #include <Shards_BasicTopologies.hpp>
00011 
00012 #include <stk_util/parallel/Parallel.hpp>
00013 
00014 #include <stk_mesh/base/MetaData.hpp>
00015 #include <stk_mesh/base/BulkData.hpp>
00016 #include <stk_mesh/base/Entity.hpp>
00017 #include <stk_mesh/base/GetEntities.hpp>
00018 #include <stk_mesh/base/Selector.hpp>
00019 #include <stk_mesh/base/GetBuckets.hpp>
00020 
00021 #include <stk_mesh/fem/BoundaryAnalysis.hpp>
00022 #include <stk_mesh/fem/SkinMesh.hpp>
00023 #include <stk_mesh/fem/EntityRanks.hpp>
00024 #include <stk_mesh/fem/TopologyHelpers.hpp>
00025 
00026 #include <stk_mesh/fixtures/GridFixture.hpp>
00027 
00028 #include <stk_util/parallel/ParallelReduce.hpp>
00029 
00030 #include <iomanip>
00031 #include <algorithm>
00032 
00033 class UnitTestStkMeshSkinning {
00034 public:
00035   UnitTestStkMeshSkinning(stk::ParallelMachine pm) : m_comm(pm),  m_num_procs(0), m_rank(0)
00036   {
00037     m_num_procs = stk::parallel_machine_size( m_comm );
00038     m_rank = stk::parallel_machine_rank( m_comm );
00039   }
00040 
00041   void test_skinning();
00042 
00043   stk::ParallelMachine m_comm;
00044   int m_num_procs;
00045   int m_rank;
00046 };
00047 
00048 namespace {
00049 
00050 STKUNIT_UNIT_TEST( UnitTestStkMeshSkinning , testUnit )
00051 {
00052   UnitTestStkMeshSkinning unit(MPI_COMM_WORLD);
00053   unit.test_skinning();
00054 }
00055 
00056 STKUNIT_UNIT_TEST( UnitTestStkMeshSkinning , testSingleShell )
00057 {
00058   const int spatial_dimension = 3;
00059   stk::mesh::MetaData meta_data( stk::mesh::TopologicalMetaData::entity_rank_names(spatial_dimension) );
00060   stk::mesh::BulkData bulk_data( meta_data, MPI_COMM_WORLD );
00061   stk::mesh::TopologicalMetaData top_data( meta_data, spatial_dimension );
00062 
00063   const unsigned p_rank = bulk_data.parallel_rank();
00064 
00065   stk::mesh::Part & skin_part = meta_data.declare_part("skin_part");
00066 
00067   stk::mesh::Part & shell_part = top_data.declare_part<shards::ShellQuadrilateral<4> >("shell_part");
00068 
00069   meta_data.commit();
00070 
00071   bulk_data.modification_begin();
00072 
00073   if ( p_rank == 0 ) {
00074 
00075     stk::mesh::EntityId elem_node[4] ;
00076 
00077     // Query nodes from this simple grid fixture via the (i,j,k) indices.
00078     elem_node[0] = 1;
00079     elem_node[1] = 2;
00080     elem_node[2] = 3;
00081     elem_node[3] = 4;
00082 
00083     stk::mesh::EntityId elem_id = 1;
00084 
00085     stk::mesh::declare_element( bulk_data, shell_part, elem_id, elem_node);
00086 
00087   }
00088   bulk_data.modification_end();
00089 
00090 
00091   stk::mesh::skin_mesh( bulk_data, top_data.element_rank, &skin_part);
00092 
00093   {
00094     const unsigned mesh_rank = top_data.element_rank;
00095     const stk::mesh::MetaData & meta = bulk_data.mesh_meta_data();
00096     stk::mesh::Selector select_skin = skin_part & meta.locally_owned_part()  ;
00097     const std::vector<stk::mesh::Bucket*>& buckets = bulk_data.buckets( mesh_rank -1);
00098     int num_skin_entities = stk::mesh::count_selected_entities( select_skin, buckets);
00099 
00100 
00101     stk::all_reduce(MPI_COMM_WORLD, stk::ReduceSum<1>(&num_skin_entities));
00102 
00103     // Verify that the correct 6 sides are present.
00104 
00105     STKUNIT_ASSERT_EQUAL( num_skin_entities, 2 );
00106   }
00107 }
00108 
00109 } //end namespace
00110 
00111 void UnitTestStkMeshSkinning::test_skinning()
00112 {
00113   // This test will only work for np=1
00114   if (m_num_procs > 1) {
00115     return;
00116   }
00117 
00118   stk::mesh::fixtures::GridFixture grid_mesh(MPI_COMM_WORLD);
00119 
00120   stk::mesh::BulkData& bulk_data = grid_mesh.bulk_data();
00121   stk::mesh::MetaData& meta_data = grid_mesh.meta_data();
00122   stk::mesh::TopologicalMetaData& top_data = grid_mesh.top_data();
00123 
00124   // Create a part for the skin and the shells
00125   stk::mesh::Part & skin_part = meta_data.declare_part("skin_part");
00126   stk::mesh::Part & shell_part = top_data.declare_part<shards::ShellLine<2> >("shell_part");
00127   meta_data.commit();
00128 
00129   // Begin modification cycle
00130   grid_mesh.bulk_data().modification_begin();
00131 
00132   // Generate the plain grid
00133   grid_mesh.generate_grid();
00134 
00135   // Add the shells
00136   std::vector<unsigned> count;
00137   stk::mesh::Selector locally_owned(meta_data.locally_owned_part());
00138   stk::mesh::count_entities(locally_owned, bulk_data, count);
00139   const unsigned num_shell_1_faces = 4;
00140   const unsigned num_shell_2_faces = 2;
00141   const unsigned num_shell_faces = num_shell_1_faces + num_shell_2_faces;
00142   const unsigned num_entities = count[top_data.node_rank] +
00143                                 count[top_data.element_rank];
00144 
00145   stk::mesh::PartVector shell_parts;
00146   shell_parts.push_back(&shell_part);
00147 
00148   std::vector<stk::mesh::Entity*> shell_faces;
00149   for (unsigned i = 1; i <= num_shell_faces; ++i) {
00150     stk::mesh::Entity& new_shell = bulk_data.declare_entity(top_data.element_rank,
00151                                                             num_entities + i,
00152                                                             shell_parts);
00153     shell_faces.push_back(&new_shell);
00154   }
00155 
00156   // Set up relationships for shells
00157 
00158   // declare shell relationships for first shell
00159   unsigned node_list_1[5] = {21, 26, 31, 36, 41};
00160   for (unsigned i = 0; i < num_shell_1_faces; ++i) {
00161     stk::mesh::Entity& shell = *(shell_faces[i]);
00162     stk::mesh::Entity& node1 =
00163       *(bulk_data.get_entity(top_data.node_rank, node_list_1[i]));
00164     stk::mesh::Entity& node2 =
00165       *(bulk_data.get_entity(top_data.node_rank, node_list_1[i+1]));
00166     bulk_data.declare_relation(shell, node1, 0);
00167     bulk_data.declare_relation(shell, node2, 1);
00168   }
00169 
00170   // declare shell relationships for second shell
00171   unsigned node_list_2[3] = {31, 36, 41};
00172   for (unsigned i = 0; i < num_shell_2_faces; ++i) {
00173     stk::mesh::Entity& shell = *(shell_faces[i + num_shell_1_faces]);
00174     stk::mesh::Entity& node1 =
00175       *(bulk_data.get_entity(top_data.node_rank, node_list_2[i]));
00176     stk::mesh::Entity& node2 =
00177       *(bulk_data.get_entity(top_data.node_rank, node_list_2[i+1]));
00178     bulk_data.declare_relation(shell, node1, 0);
00179     bulk_data.declare_relation(shell, node2, 1);
00180   }
00181 
00182   grid_mesh.bulk_data().modification_end();
00183 
00184   // skin the boundary
00185   stk::mesh::skin_mesh(bulk_data, top_data.element_rank, &skin_part);
00186 
00187   // Grab the skin entities
00188   stk::mesh::Selector skin_selector(skin_part);
00189   const std::vector<stk::mesh::Bucket*>& edge_buckets =
00190     bulk_data.buckets(top_data.edge_rank);
00191   std::vector<stk::mesh::Entity*> skin_entities;
00192   stk::mesh::get_selected_entities(skin_selector, edge_buckets, skin_entities);
00193 
00194   unsigned num_expected_skin_entites = 16;
00195   STKUNIT_EXPECT_EQUAL(num_expected_skin_entites, skin_entities.size());
00196 
00197   // Map the element id to the number of skins associated with that element
00198 
00199   std::map<unsigned, unsigned> results;
00200   std::map<unsigned, unsigned> expected_results;
00201 
00202   expected_results[1] = 2;
00203   expected_results[2] = 1;
00204   expected_results[3] = 1;
00205   expected_results[4] = 1;
00206   expected_results[5] = 1;
00207   expected_results[9] = 1;
00208   expected_results[13] = 2;
00209   expected_results[14] = 1;
00210   expected_results[15] = 1;
00211   expected_results[16] = 1;
00212   expected_results[42] = 1;
00213   expected_results[43] = 1;
00214   expected_results[44] = 1;
00215   expected_results[45] = 1;
00216   expected_results[46] = 1;
00217   expected_results[47] = 1;
00218 
00219   // Vector of of vector of entities (shells) that are expected to share a skin
00220 
00221   std::set<std::set<unsigned> > sharing;
00222   std::set<std::set<unsigned> > expected_sharing;
00223 
00224   std::set<unsigned> temp;
00225   temp.insert(44);
00226   temp.insert(46);
00227   expected_sharing.insert(temp);
00228 
00229   temp.clear();
00230   temp.insert(45);
00231   temp.insert(47);
00232   expected_sharing.insert(temp);
00233 
00234   // map skin-id to ids of elements it is attached to; we will use this to
00235   // compute sharing
00236   for (std::vector<stk::mesh::Entity*>::const_iterator
00237        itr = skin_entities.begin(); itr != skin_entities.end(); ++itr) {
00238     stk::mesh::PairIterRelation upward_relation_itr =
00239       (*itr)->relations(top_data.element_rank);
00240     bool has_multiple = upward_relation_itr.size() > 1;
00241     std::set<unsigned> sharing_elements;
00242     for ( ; !upward_relation_itr.empty() ; ++upward_relation_itr ) {
00243       unsigned elem_id = upward_relation_itr->entity()->identifier();
00244       if (results.find(elem_id) != results.end()) {
00245         ++results[elem_id];
00246       }
00247       else {
00248         results[elem_id] = 1;
00249       }
00250 
00251       if (has_multiple) {
00252         sharing_elements.insert(elem_id);
00253       }
00254     }
00255     if (has_multiple) {
00256       sharing.insert(sharing_elements);
00257     }
00258   }
00259 
00260   STKUNIT_EXPECT_TRUE(results == expected_results);
00261   STKUNIT_EXPECT_TRUE(sharing == expected_sharing);
00262 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends