|
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 00010 #include <iostream> 00011 #include <sstream> 00012 00013 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00014 00015 #include <stk_util/parallel/Parallel.hpp> 00016 #include <stk_mesh/base/BulkData.hpp> 00017 #include <stk_mesh/base/GetEntities.hpp> 00018 #include <stk_mesh/base/Comm.hpp> 00019 #include <stk_mesh/fem/EntityRanks.hpp> 00020 00021 #include <unit_tests/UnitTestBulkData.hpp> 00022 #include <unit_tests/UnitTestRingMeshFixture.hpp> 00023 00024 //---------------------------------------------------------------------- 00025 //---------------------------------------------------------------------- 00026 00027 namespace stk { 00028 namespace mesh { 00029 00030 //---------------------------------------------------------------------- 00031 00032 void UnitTestBulkData::testChangeParts( ParallelMachine pm ) 00033 { 00034 static const char method[] = 00035 "stk::mesh::UnitTestBulkData::testChangeParts" ; 00036 00037 std::cout << std::endl << method << std::endl ; 00038 00039 const unsigned p_size = parallel_machine_size( pm ); 00040 const unsigned p_rank = parallel_machine_rank( pm ); 00041 00042 if ( 1 < p_size ) return ; 00043 00044 // Single process, no sharing 00045 00046 // Meta data with entity ranks [0..9] 00047 std::vector<std::string> entity_names(10); 00048 for ( size_t i = 0 ; i < 10 ; ++i ) { 00049 std::ostringstream name ; 00050 name << "EntityRank_" << i ; 00051 entity_names[i] = name.str(); 00052 } 00053 00054 MetaData meta( entity_names ); 00055 BulkData bulk( meta , pm , 100 ); 00056 00057 Part & part_univ = meta.universal_part(); 00058 Part & part_owns = meta.locally_owned_part(); 00059 00060 Part & part_A_0 = meta.declare_part( std::string("A_0") , 0 ); 00061 Part & part_A_1 = meta.declare_part( std::string("A_1") , 1 ); 00062 Part & part_A_2 = meta.declare_part( std::string("A_2") , 2 ); 00063 Part & part_A_3 = meta.declare_part( std::string("A_3") , 3 ); 00064 00065 Part & part_B_0 = meta.declare_part( std::string("B_0") , 0 ); 00066 // Part & part_B_1 = meta.declare_part( std::string("B_1") , 1 ); 00067 Part & part_B_2 = meta.declare_part( std::string("B_2") , 2 ); 00068 // Part & part_B_3 = meta.declare_part( std::string("B_3") , 3 ); 00069 00070 meta.commit(); 00071 bulk.modification_begin(); 00072 00073 PartVector tmp(1); 00074 00075 tmp[0] = & part_A_0 ; 00076 Entity & entity_0_1 = bulk.declare_entity( 0 , 1 , tmp ); 00077 00078 tmp[0] = & part_A_1 ; 00079 Entity & entity_1_1 = bulk.declare_entity( 1 , 1 , tmp ); 00080 00081 tmp[0] = & part_A_2 ; 00082 Entity & entity_2_1 = bulk.declare_entity( 2 , 1 , tmp ); 00083 00084 tmp[0] = & part_A_3 ; 00085 Entity & entity_3_1 = bulk.declare_entity( 3 , 1 , tmp ); 00086 00087 entity_0_1.bucket().supersets( tmp ); 00088 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00089 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00090 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00091 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00092 00093 entity_1_1.bucket().supersets( tmp ); 00094 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00095 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00096 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00097 STKUNIT_ASSERT( tmp[2] == & part_A_1 ); 00098 00099 entity_2_1.bucket().supersets( tmp ); 00100 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00101 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00102 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00103 STKUNIT_ASSERT( tmp[2] == & part_A_2 ); 00104 00105 entity_3_1.bucket().supersets( tmp ); 00106 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00107 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00108 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00109 STKUNIT_ASSERT( tmp[2] == & part_A_3 ); 00110 00111 { 00112 tmp.resize(1); 00113 tmp[0] = & part_A_0 ; 00114 bulk.change_entity_parts( entity_0_1 , tmp ); 00115 entity_0_1.bucket().supersets( tmp ); 00116 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00117 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00118 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00119 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00120 } 00121 00122 { // Add a new part: 00123 tmp.resize(1); 00124 tmp[0] = & part_B_0 ; 00125 bulk.change_entity_parts( entity_0_1 , tmp ); 00126 entity_0_1.bucket().supersets( tmp ); 00127 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00128 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00129 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00130 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00131 STKUNIT_ASSERT( tmp[3] == & part_B_0 ); 00132 } 00133 00134 { // Remove the part just added: 00135 tmp.resize(1); 00136 tmp[0] = & part_B_0 ; 00137 bulk.change_entity_parts( entity_0_1 , PartVector() , tmp ); 00138 entity_0_1.bucket().supersets( tmp ); 00139 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00140 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00141 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00142 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00143 } 00144 00145 { // Relationship induced membership: 00146 bulk.declare_relation( entity_1_1 , entity_0_1 , 0 ); 00147 entity_0_1.bucket().supersets( tmp ); 00148 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00149 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00150 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00151 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00152 STKUNIT_ASSERT( tmp[3] == & part_A_1 ); 00153 } 00154 00155 { // Remove relationship induced membership: 00156 bulk.destroy_relation( entity_1_1 , entity_0_1 ); 00157 entity_0_1.bucket().supersets( tmp ); 00158 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00159 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00160 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00161 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00162 } 00163 00164 { // Add a new part: 00165 tmp.resize(1); 00166 tmp[0] = & part_B_2 ; 00167 bulk.change_entity_parts( entity_2_1 , tmp ); 00168 entity_2_1.bucket().supersets( tmp ); 00169 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00170 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00171 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00172 STKUNIT_ASSERT( tmp[2] == & part_A_2 ); 00173 STKUNIT_ASSERT( tmp[3] == & part_B_2 ); 00174 } 00175 00176 { // Relationship induced membership: 00177 bulk.declare_relation( entity_2_1 , entity_0_1 , 0 ); 00178 entity_0_1.bucket().supersets( tmp ); 00179 STKUNIT_ASSERT_EQUAL( size_t(5) , tmp.size() ); 00180 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00181 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00182 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00183 STKUNIT_ASSERT( tmp[3] == & part_A_2 ); 00184 STKUNIT_ASSERT( tmp[4] == & part_B_2 ); 00185 } 00186 00187 { // Remove relationship induced membership: 00188 bulk.destroy_relation( entity_2_1 , entity_0_1 ); 00189 entity_0_1.bucket().supersets( tmp ); 00190 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00191 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00192 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00193 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00194 } 00195 00196 bulk.modification_end(); 00197 00198 //------------------------------ 00199 // Now the parallel fun. Existing entities should be shared 00200 // by all processes since they have the same identifiers. 00201 // They should also have the same parts. 00202 00203 entity_0_1.bucket().supersets( tmp ); 00204 if ( entity_0_1.owner_rank() == p_rank ) { 00205 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00206 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00207 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00208 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00209 } 00210 else { 00211 STKUNIT_ASSERT_EQUAL( size_t(2) , tmp.size() ); 00212 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00213 STKUNIT_ASSERT( tmp[1] == & part_A_0 ); 00214 } 00215 00216 entity_2_1.bucket().supersets( tmp ); 00217 if ( entity_2_1.owner_rank() == p_rank ) { 00218 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00219 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00220 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00221 STKUNIT_ASSERT( tmp[2] == & part_A_2 ); 00222 STKUNIT_ASSERT( tmp[3] == & part_B_2 ); 00223 } 00224 else { 00225 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00226 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00227 STKUNIT_ASSERT( tmp[1] == & part_A_2 ); 00228 STKUNIT_ASSERT( tmp[2] == & part_B_2 ); 00229 } 00230 00231 if (bulk.parallel_size() > 1) { 00232 STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_0_1.sharing().size() ); 00233 STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_1_1.sharing().size() ); 00234 STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_2_1.sharing().size() ); 00235 STKUNIT_ASSERT_EQUAL( size_t(p_size - 1) , entity_3_1.sharing().size() ); 00236 } 00237 00238 bulk.modification_begin(); 00239 00240 // Add a new part on the owning process: 00241 00242 int ok_to_modify = entity_0_1.owner_rank() == p_rank ; 00243 00244 try { 00245 tmp.resize(1); 00246 tmp[0] = & part_B_0 ; 00247 bulk.change_entity_parts( entity_0_1 , tmp ); 00248 STKUNIT_ASSERT( ok_to_modify ); 00249 } 00250 catch( const std::exception & x ) { 00251 STKUNIT_ASSERT( ! ok_to_modify ); 00252 } 00253 00254 entity_0_1.bucket().supersets( tmp ); 00255 if ( entity_0_1.owner_rank() == p_rank ) { 00256 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00257 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00258 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00259 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00260 STKUNIT_ASSERT( tmp[3] == & part_B_0 ); 00261 } 00262 else { 00263 STKUNIT_ASSERT_EQUAL( size_t(2) , tmp.size() ); 00264 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00265 STKUNIT_ASSERT( tmp[1] == & part_A_0 ); 00266 } 00267 00268 bulk.modification_end(); 00269 00270 entity_0_1.bucket().supersets( tmp ); 00271 if ( entity_0_1.owner_rank() == p_rank ) { 00272 STKUNIT_ASSERT_EQUAL( size_t(4) , tmp.size() ); 00273 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00274 STKUNIT_ASSERT( tmp[1] == & part_owns ); 00275 STKUNIT_ASSERT( tmp[2] == & part_A_0 ); 00276 STKUNIT_ASSERT( tmp[3] == & part_B_0 ); 00277 } 00278 else { 00279 STKUNIT_ASSERT_EQUAL( size_t(3) , tmp.size() ); 00280 STKUNIT_ASSERT( tmp[0] == & part_univ ); 00281 STKUNIT_ASSERT( tmp[1] == & part_A_0 ); 00282 STKUNIT_ASSERT( tmp[2] == & part_B_0 ); 00283 } 00284 } 00285 00286 //---------------------------------------------------------------------- 00287 //---------------------------------------------------------------------- 00288 00289 void UnitTestBulkData::testChangeParts_loop( ParallelMachine pm ) 00290 { 00291 enum { nPerProc = 10 }; 00292 const unsigned p_rank = parallel_machine_rank( pm ); 00293 const unsigned p_size = parallel_machine_size( pm ); 00294 const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 ); 00295 const unsigned nLocalEdge = nPerProc ; 00296 00297 UnitTestRingMeshFixture ring_mesh( pm , nPerProc , true /* generate parts */ ); 00298 ring_mesh.m_meta_data.commit(); 00299 ring_mesh.generate_mesh( false /* no aura */ ); 00300 00301 Part & part_owns = ring_mesh.m_meta_data.locally_owned_part(); 00302 Part & part_univ = ring_mesh.m_meta_data.universal_part(); 00303 00304 Selector select_owned( ring_mesh.m_meta_data.locally_owned_part() ); 00305 Selector select_used = select_owned | ring_mesh.m_meta_data.globally_shared_part(); 00306 Selector select_all( ring_mesh.m_meta_data.universal_part() ); 00307 00308 std::vector<unsigned> local_count ; 00309 00310 for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) { 00311 const unsigned n = i + nPerProc * p_rank ; 00312 Entity * const edge = ring_mesh.m_bulk_data.get_entity( 1 , ring_mesh.m_edge_ids[n] ); 00313 STKUNIT_ASSERT( edge != NULL ); 00314 STKUNIT_ASSERT( edge->bucket().member( part_univ ) ); 00315 STKUNIT_ASSERT( edge->bucket().member( part_owns ) ); 00316 STKUNIT_ASSERT( edge->bucket().member( * ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ] ) ); 00317 } 00318 00319 for ( unsigned i = 0 ; i < nLocalNode ; ++i ) { 00320 const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size(); 00321 const unsigned e0 = n ; 00322 const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size(); 00323 const unsigned ns = ring_mesh.m_edge_parts.size(); 00324 const unsigned n0 = e0 % ns ; 00325 const unsigned n1 = e1 % ns ; 00326 Part * const epart_0 = ring_mesh.m_edge_parts[ n0 < n1 ? n0 : n1 ]; 00327 Part * const epart_1 = ring_mesh.m_edge_parts[ n0 < n1 ? n1 : n0 ]; 00328 00329 Entity * const node = ring_mesh.m_bulk_data.get_entity( 0 , ring_mesh.m_node_ids[n] ); 00330 STKUNIT_ASSERT( node != NULL ); 00331 if ( node->owner_rank() == p_rank ) { 00332 STKUNIT_ASSERT( node->bucket().member( part_univ ) ); 00333 STKUNIT_ASSERT( node->bucket().member( part_owns ) ); 00334 STKUNIT_ASSERT( node->bucket().member( *epart_0 ) ); 00335 STKUNIT_ASSERT( node->bucket().member( *epart_1 ) ); 00336 } 00337 else { 00338 STKUNIT_ASSERT( node->bucket().member( part_univ ) ); 00339 STKUNIT_ASSERT( ! node->bucket().member( part_owns ) ); 00340 STKUNIT_ASSERT( node->bucket().member( * epart_0 ) ); 00341 STKUNIT_ASSERT( node->bucket().member( * epart_1 ) ); 00342 } 00343 } 00344 00345 ring_mesh.m_bulk_data.modification_begin(); 00346 00347 if ( 0 == p_rank ) { 00348 00349 for ( unsigned i = 0 ; i < nLocalEdge ; ++i ) { 00350 const unsigned n = i + nPerProc * p_rank ; 00351 00352 PartVector add(1); add[0] = & ring_mesh.m_edge_part_extra ; 00353 PartVector rem(1); rem[0] = ring_mesh.m_edge_parts[ n % ring_mesh.m_edge_parts.size() ]; 00354 00355 Entity * const edge = ring_mesh.m_bulk_data.get_entity( 1 , ring_mesh.m_edge_ids[n] ); 00356 ring_mesh.m_bulk_data.change_entity_parts( *edge , add , rem ); 00357 STKUNIT_ASSERT( edge->bucket().member( part_univ ) ); 00358 STKUNIT_ASSERT( edge->bucket().member( part_owns ) ); 00359 STKUNIT_ASSERT( edge->bucket().member(ring_mesh.m_edge_part_extra ) ); 00360 } 00361 } 00362 00363 ring_mesh.m_bulk_data.modification_end(); 00364 00365 for ( unsigned i = 0 ; i < nLocalNode ; ++i ) { 00366 const unsigned n = ( i + nPerProc * p_rank ) % ring_mesh.m_node_ids.size(); 00367 const unsigned e0 = n ; 00368 const unsigned e1 = ( n + ring_mesh.m_edge_ids.size() - 1 ) % ring_mesh.m_edge_ids.size(); 00369 const unsigned ns = ring_mesh.m_edge_parts.size(); 00370 const unsigned n0 = e0 % ns ; 00371 const unsigned n1 = e1 % ns ; 00372 Part * ep_0 = e0 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n0] ; 00373 Part * ep_1 = e1 < nLocalEdge ? & ring_mesh.m_edge_part_extra : ring_mesh.m_edge_parts[n1] ; 00374 00375 Part * epart_0 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_0 : ep_1 ; 00376 Part * epart_1 = ep_0->mesh_meta_data_ordinal() < ep_1->mesh_meta_data_ordinal() ? ep_1 : ep_0 ; 00377 00378 Entity * const node = ring_mesh.m_bulk_data.get_entity( 0 , ring_mesh.m_node_ids[n] ); 00379 STKUNIT_ASSERT( node != NULL ); 00380 if ( node->owner_rank() == p_rank ) { 00381 STKUNIT_ASSERT( node->bucket().member( part_owns ) ); 00382 } 00383 else { 00384 STKUNIT_ASSERT( ! node->bucket().member( part_owns ) ); 00385 } 00386 00387 STKUNIT_ASSERT( node->bucket().member( part_univ ) ); 00388 STKUNIT_ASSERT( node->bucket().member( *epart_0 ) ); 00389 STKUNIT_ASSERT( node->bucket().member( *epart_1 ) ); 00390 } 00391 } 00392 00393 } // namespace mesh 00394 } // namespace stk 00395