|
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 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 }