Sierra Toolkit Version of the Day
UnitTestBoundaryAnalysis.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/EntityRanks.hpp>
00023 #include <stk_mesh/fem/TopologyHelpers.hpp>
00024 #include <stk_mesh/fem/TopologicalMetaData.hpp>
00025 #include <stk_mesh/fem/EntityRanks.hpp>
00026 
00027 #include <stk_mesh/fixtures/GridFixture.hpp>
00028 
00029 #include <iomanip>
00030 #include <algorithm>
00031 
00032 class UnitTestStkMeshBoundaryAnalysis {
00033 public:
00034   UnitTestStkMeshBoundaryAnalysis(stk::ParallelMachine pm) : m_comm(pm),  m_num_procs(0), m_rank(0)
00035   {
00036     m_num_procs = stk::parallel_machine_size( m_comm );
00037     m_rank = stk::parallel_machine_rank( m_comm );
00038   }
00039 
00040   void test_boundary_analysis();
00041   void test_boundary_analysis_null_topology();
00042 
00043   stk::ParallelMachine m_comm;
00044   int m_num_procs;
00045   int m_rank;
00046 };
00047 
00048 namespace {
00049 
00050 STKUNIT_UNIT_TEST( UnitTestStkMeshBoundaryAnalysis , testUnit )
00051 {
00052   UnitTestStkMeshBoundaryAnalysis unit(MPI_COMM_WORLD);
00053   unit.test_boundary_analysis();
00054 }
00055 
00056 STKUNIT_UNIT_TEST( UnitTestStkMeshBoundaryAnalysis , testNullTopology )
00057 {
00058   UnitTestStkMeshBoundaryAnalysis unit(MPI_COMM_WORLD);
00059   unit.test_boundary_analysis_null_topology();
00060 }
00061 
00062 } //end namespace
00063 
00064 void UnitTestStkMeshBoundaryAnalysis::test_boundary_analysis()
00065 {
00066   // This test will only work for np=1
00067   if (m_num_procs > 1) {
00068     return;
00069   }
00070 
00071   // set up grid_mesh
00072   stk::mesh::fixtures::GridFixture grid_mesh(MPI_COMM_WORLD);
00073 
00074   stk::mesh::BulkData& bulk_data = grid_mesh.bulk_data();
00075   stk::mesh::MetaData& meta_data = grid_mesh.meta_data();
00076   stk::mesh::TopologicalMetaData& top_data = grid_mesh.top_data();
00077 
00078   // make shell part
00079   stk::mesh::Part& shell_part = top_data.declare_part<shards::ShellLine<2> >("shell_part");
00080 
00081   meta_data.commit();
00082 
00083   bulk_data.modification_begin();
00084   grid_mesh.generate_grid();
00085 
00086   // Add some shells
00087   const unsigned num_shell_faces = 4;
00088 
00089   // get a count of entities that have already been created
00090   std::vector<unsigned> count;
00091   stk::mesh::Selector locally_owned(meta_data.locally_owned_part());
00092   stk::mesh::count_entities(locally_owned, bulk_data, count);
00093   const unsigned num_entities = count[top_data.node_rank] +
00094     count[top_data.element_rank];
00095 
00096   std::vector<stk::mesh::Entity*> shell_faces;
00097   stk::mesh::PartVector shell_parts;
00098   shell_parts.push_back(&shell_part);
00099   for (unsigned i = 1; i <= num_shell_faces; ++i) {
00100     stk::mesh::Entity& new_shell = bulk_data.declare_entity(top_data.element_rank,
00101                                                             num_entities + i,
00102                                                             shell_parts);
00103     shell_faces.push_back(&new_shell);
00104   }
00105 
00106   // declare shell relationships
00107   unsigned node_list[5] = {20, 25, 30, 35, 40};
00108   for (unsigned i = 0; i < num_shell_faces; ++i) {
00109     stk::mesh::Entity& shell = *(shell_faces[i]);
00110     stk::mesh::Entity& node1 =
00111       *(bulk_data.get_entity(top_data.node_rank, node_list[i]));
00112     stk::mesh::Entity& node2 =
00113       *(bulk_data.get_entity(top_data.node_rank, node_list[i+1]));
00114     bulk_data.declare_relation(shell, node1, 0);
00115     bulk_data.declare_relation(shell, node2, 1);
00116   }
00117 
00118   bulk_data.modification_end();
00119 
00120   // create the closure we want to analyze
00121   std::vector<stk::mesh::Entity*> closure;
00122   unsigned num_faces_in_closure = 6;
00123   unsigned ids_of_entities_in_closure[] =
00124     {6, 7, 10, 11, 14, 15, 23, 24, 25, 28, 29, 30, 33, 34, 35, 38, 39, 40};
00125   for (unsigned i = 0;
00126        i < sizeof(ids_of_entities_in_closure)/sizeof(unsigned);
00127        ++i) {
00128     stk::mesh::EntityRank rank_of_entity;
00129     if (i < num_faces_in_closure) {
00130       rank_of_entity = top_data.element_rank;
00131     }
00132     else {
00133       rank_of_entity = 0;
00134     }
00135     stk::mesh::Entity* closure_entity =
00136       bulk_data.get_entity(rank_of_entity, ids_of_entities_in_closure[i]);
00137     closure.push_back(closure_entity);
00138   }
00139   // sort the closure
00140   std::sort(closure.begin(), closure.end(), stk::mesh::EntityLess());
00141 
00142   stk::mesh::EntitySideVector boundary;
00143   stk::mesh::boundary_analysis(bulk_data, closure, top_data.element_rank, boundary);
00144   STKUNIT_EXPECT_TRUE(!boundary.empty());
00145 
00146   std::vector<std::pair<std::pair<unsigned, unsigned>,
00147                         std::pair<unsigned, unsigned> > > results;
00148   std::vector<std::pair<std::pair<unsigned, unsigned>,
00149                         std::pair<unsigned, unsigned> > > expected_results;
00150 
00151   {
00152     std::pair<unsigned, unsigned> inside(6, 0);
00153     std::pair<unsigned, unsigned> outside(5, 2);
00154     expected_results.push_back(
00155       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00156   }
00157 
00158   {
00159     std::pair<unsigned, unsigned> inside(6, 3);
00160     std::pair<unsigned, unsigned> outside(2, 1);
00161     expected_results.push_back(
00162       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00163   }
00164 
00165   {
00166     std::pair<unsigned, unsigned> inside(7, 2);
00167     std::pair<unsigned, unsigned> outside(8, 0);
00168     expected_results.push_back(
00169       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00170   }
00171 
00172   {
00173     std::pair<unsigned, unsigned> inside(7, 2);
00174     std::pair<unsigned, unsigned> outside(43, 0);
00175     expected_results.push_back(
00176       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00177   }
00178 
00179   {
00180     std::pair<unsigned, unsigned> inside(7, 3);
00181     std::pair<unsigned, unsigned> outside(3, 1);
00182     expected_results.push_back(
00183       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00184   }
00185 
00186   {
00187     std::pair<unsigned, unsigned> inside(10, 0);
00188     std::pair<unsigned, unsigned> outside(9, 2);
00189     expected_results.push_back(
00190       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00191   }
00192 
00193   {
00194     std::pair<unsigned, unsigned> inside(11, 2);
00195     std::pair<unsigned, unsigned> outside(12, 0);
00196     expected_results.push_back(
00197       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00198   }
00199 
00200   {
00201     std::pair<unsigned, unsigned> inside(11, 2);
00202     std::pair<unsigned, unsigned> outside(44, 0);
00203     expected_results.push_back(
00204       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00205   }
00206 
00207   {
00208     std::pair<unsigned, unsigned> inside(14, 0);
00209     std::pair<unsigned, unsigned> outside(13, 2);
00210     expected_results.push_back(
00211       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00212   }
00213 
00214   {
00215     std::pair<unsigned, unsigned> inside(14, 1);
00216     std::pair<unsigned, unsigned> outside(0, 0);
00217     expected_results.push_back(
00218       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00219   }
00220 
00221   {
00222     std::pair<unsigned, unsigned> inside(15, 1);
00223     std::pair<unsigned, unsigned> outside(0, 0);
00224     expected_results.push_back(
00225       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00226   }
00227 
00228   {
00229     std::pair<unsigned, unsigned> inside(15, 2);
00230     std::pair<unsigned, unsigned> outside(16, 0);
00231     expected_results.push_back(
00232       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00233   }
00234 
00235   {
00236     std::pair<unsigned, unsigned> inside(15, 2);
00237     std::pair<unsigned, unsigned> outside(45, 0);
00238     expected_results.push_back(
00239       std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00240   }
00241 
00242 
00243   for (stk::mesh::EntitySideVector::iterator itr = boundary.begin(); itr != boundary.end(); ++itr)
00244   {
00245     stk::mesh::EntitySide& side = *itr;
00246     stk::mesh::EntitySideComponent& inside_closure = side.inside;
00247     stk::mesh::EntityId inside_id = inside_closure.entity != NULL ? inside_closure.entity->identifier() : 0;
00248     stk::mesh::EntityId inside_side = inside_closure.entity != NULL ? inside_closure.side_ordinal : 0;
00249     stk::mesh::EntitySideComponent& outside_closure = side.outside;
00250     stk::mesh::EntityId outside_id = outside_closure.entity != NULL ? outside_closure.entity->identifier() : 0;
00251     stk::mesh::EntityId outside_side = outside_closure.entity != NULL ? outside_closure.side_ordinal : 0;
00252 
00253     std::pair<unsigned, unsigned> inside(inside_id, inside_side);
00254     std::pair<unsigned, unsigned> outside(outside_id, outside_side);
00255     results.push_back(std::pair<std::pair<unsigned, unsigned>, std::pair<unsigned, unsigned> >(inside, outside));
00256   }
00257   STKUNIT_EXPECT_TRUE(results == expected_results);
00258 }
00259 
00260 void UnitTestStkMeshBoundaryAnalysis::test_boundary_analysis_null_topology()
00261 {
00262   //test on boundary_analysis for closure with a NULL topology - coverage of lines 39-40 of BoundaryAnalysis.cpp
00263 
00264   //create new meta, bulk and boundary for this test
00265   const int spatial_dimension = 3;
00266   stk::mesh::MetaData meta( stk::mesh::TopologicalMetaData::entity_rank_names(spatial_dimension) );
00267   stk::mesh::TopologicalMetaData top_data(meta, spatial_dimension);
00268 
00269   //declare part with topology = NULL
00270   stk::mesh::Part & quad_part = meta.declare_part("quad_part", top_data.side_rank);
00271   meta.commit();
00272 
00273   stk::ParallelMachine comm(MPI_COMM_WORLD);
00274   stk::mesh::BulkData bulk ( meta , comm , 100 );
00275 
00276   stk::mesh::EntitySideVector boundary;
00277   std::vector<stk::mesh::Entity*> newclosure;
00278 
00279   stk::mesh::PartVector face_parts;
00280   face_parts.push_back(&quad_part);
00281 
00282   bulk.modification_begin();
00283   if (m_rank == 0) {
00284     stk::mesh::Entity & new_face = bulk.declare_entity(top_data.side_rank, 1, face_parts);
00285     newclosure.push_back(&new_face);
00286   }
00287 
00288   stk::mesh::boundary_analysis(bulk, newclosure, top_data.side_rank, boundary);
00289   /*
00290   STKUNIT_EXPECT_TRUE(!boundary.empty());
00291   */
00292 
00293   bulk.modification_end();
00294 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends