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

Generated on Tue Jul 13 09:27:32 2010 for Sierra Toolkit by  doxygen 1.4.7