UnitTestBulkData.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 <sstream>
00011 
00012 #include <unit_tests/stk_utest_macros.hpp>
00013 
00014 #include <stk_util/parallel/Parallel.hpp>
00015 #include <stk_mesh/base/BulkData.hpp>
00016 #include <stk_mesh/base/GetEntities.hpp>
00017 #include <stk_mesh/base/EntityComm.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 STKUNIT_UNIT_TEST(UnitTestingOfBulkData, testUnit)
00025 {
00026   MPI_Barrier( MPI_COMM_WORLD );
00027   stk::mesh::UnitTestBulkData::testBulkData( MPI_COMM_WORLD );
00028   stk::mesh::UnitTestBulkData::testChangeOwner_nodes( MPI_COMM_WORLD );
00029   stk::mesh::UnitTestBulkData::testChangeOwner_loop( MPI_COMM_WORLD );
00030   stk::mesh::UnitTestBulkData::testChangeOwner_box( MPI_COMM_WORLD );
00031   stk::mesh::UnitTestBulkData::testCreateMore_error( MPI_COMM_WORLD );
00032   stk::mesh::UnitTestBulkData::testChangeParts( MPI_COMM_WORLD );
00033   stk::mesh::UnitTestBulkData::testChangeParts_loop( MPI_COMM_WORLD );
00034   stk::mesh::UnitTestBulkData::testDestroy_nodes( MPI_COMM_WORLD );
00035   stk::mesh::UnitTestBulkData::testDestroy_loop( MPI_COMM_WORLD );
00036 }
00037 
00038 //----------------------------------------------------------------------
00039 //----------------------------------------------------------------------
00040 
00041 
00042 
00043 namespace stk {
00044 namespace mesh {
00045 
00046 bool UnitTestBulkData::modification_end( BulkData & mesh , bool aura )
00047 { return mesh.internal_modification_end( aura ); }
00048 
00049 // Unit test the Part functionality in isolation:
00050 
00051 void UnitTestBulkData::testBulkData( ParallelMachine pm )
00052 {
00053   static const char method[] = "stk::mesh::UnitTestBulkData" ;
00054 
00055   std::cout << std::endl ;
00056 
00057   std::vector<std::string> entity_names(10);
00058   for ( size_t i = 0 ; i < 10 ; ++i ) {
00059     std::ostringstream name ;
00060     name << "EntityType" << i ;
00061     entity_names[i] = name.str();
00062   }
00063 
00064   MetaData meta( entity_names );
00065 
00066   meta.commit();
00067 
00068   BulkData bulk( meta , pm , 100 );
00069 
00070   for ( size_t i = 0 ; i < 4 ; ++i ) {
00071     STKUNIT_ASSERT( bulk.modification_begin() );
00072     STKUNIT_ASSERT_EQUAL( i , bulk.synchronized_count() );
00073     STKUNIT_ASSERT( bulk.modification_end() );
00074   }
00075 
00076   std::vector<Part*> no_parts ;
00077 
00078   Entity * e[10] ;
00079 
00080   STKUNIT_ASSERT( bulk.modification_begin() );
00081   for ( size_t i = 0 ; i < 10 ; ++i ) {
00082     e[i] = & bulk.declare_entity(  i , 1 , no_parts );
00083   }
00084   STKUNIT_ASSERT( bulk.modification_end() );
00085 
00086   for ( size_t i = 0 ; i < 10 ; ++i ) {
00087     STKUNIT_ASSERT( e[i] == bulk.get_entity( i , 1 ) );
00088   }
00089 
00090   bool ok = false ;
00091   STKUNIT_ASSERT( bulk.modification_begin() );
00092   try {
00093     bulk.declare_entity( 11 , 1 , no_parts );
00094   }
00095   catch( const std::exception & x ) {
00096     std::cout << method << " correctly caught: " << x.what() << std::endl ;
00097     ok = true ;
00098   }
00099   STKUNIT_ASSERT( ok );
00100   STKUNIT_ASSERT( bulk.modification_end() );
00101 
00102   // Catch not-ok-to-modify
00103   ok = false ;
00104   try {
00105     bulk.declare_entity( 0 , 2 , no_parts );
00106   }
00107   catch( const std::exception & x ) {
00108     std::cout << method << " correctly caught: " << x.what() << std::endl ;
00109     ok = true ;
00110   }
00111   STKUNIT_ASSERT( ok );
00112 }
00113 
00114 //----------------------------------------------------------------------
00115 // Testing for mesh entities without relations
00116 
00117 void UnitTestBulkData::testChangeOwner_nodes( ParallelMachine pm )
00118 {
00119   enum { nPerProc = 10 };
00120   const unsigned p_rank = parallel_machine_rank( pm );
00121   const unsigned p_size = parallel_machine_size( pm );
00122   const unsigned id_total = nPerProc * p_size ;
00123   const unsigned id_begin = nPerProc * p_rank ;
00124   const unsigned id_end   = nPerProc * ( p_rank + 1 );
00125 
00126   MetaData meta( fem_entity_type_names() );
00127   BulkData bulk( meta , pm , 100 );
00128 
00129   const PartVector no_parts ;
00130 
00131   meta.commit();
00132   bulk.modification_begin();
00133 
00134   // Ids for all entities (all entities have type 0):
00135 
00136   std::vector<EntityId> ids( id_total );
00137 
00138   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00139     ids[i] = i + 1;
00140   }
00141 
00142   // Declare just those entities in my range of ids:
00143 
00144   for ( unsigned i = id_begin ; i < id_end ; ++i ) {
00145     bulk.declare_entity( 0 , ids[i] , no_parts );
00146   }
00147 
00148   STKUNIT_ASSERT( bulk.modification_end() );
00149 
00150   // Verify that I only have entities in my range:
00151 
00152   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00153     Entity * e = bulk.get_entity( 0 , ids[ i ] );
00154     if ( id_begin <= i && i < id_end ) {
00155       STKUNIT_ASSERT( NULL != e );
00156     }
00157     else {
00158       STKUNIT_ASSERT( NULL == e );
00159     }
00160   }
00161 
00162   // Test change owner no-op first:
00163 
00164   std::vector<EntityProc> change ;
00165 
00166   STKUNIT_ASSERT( bulk.modification_begin() );
00167   bulk.change_entity_owner( change );
00168   STKUNIT_ASSERT( bulk.modification_end() );
00169 
00170   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00171     Entity * e = bulk.get_entity( 0 , ids[ i ] );
00172     if ( id_begin <= i && i < id_end ) {
00173       STKUNIT_ASSERT( NULL != e );
00174     }
00175     else {
00176       STKUNIT_ASSERT( NULL == e );
00177     }
00178   }
00179 
00180   // Can only test changing owner in parallel.
00181 
00182   if ( 1 < p_size ) {
00183     // Give my last two ids to the next process
00184     // Get the previous process' last two ids
00185 
00186     const unsigned p_give = ( p_rank + 1 ) % p_size ;
00187     const unsigned id_give = id_end - 2 ;
00188     const unsigned id_get  = ( id_begin + id_total - 2 ) % id_total ;
00189 
00190     STKUNIT_ASSERT( NULL != bulk.get_entity( 0 , ids[id_give] ) );
00191     STKUNIT_ASSERT( NULL != bulk.get_entity( 0 , ids[id_give+1] ) );
00192     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_get] ) );
00193     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_get+1] ) );
00194   
00195     change.resize(2);
00196     change[0].first = bulk.get_entity( 0 , ids[id_give] );
00197     change[0].second = p_give ;
00198     change[1].first = bulk.get_entity( 0 , ids[id_give+1] );
00199     change[1].second = p_give ;
00200 
00201     STKUNIT_ASSERT( bulk.modification_begin() );
00202     bulk.change_entity_owner( change );
00203     STKUNIT_ASSERT( bulk.modification_end() );
00204 
00205     STKUNIT_ASSERT( NULL != bulk.get_entity( 0 , ids[id_get] ) );
00206     STKUNIT_ASSERT( NULL != bulk.get_entity( 0 , ids[id_get+1] ) );
00207 
00208     // Entities given away are destroyed until the next modification cycle
00209     {
00210       Entity * const e0 = bulk.get_entity( 0 , ids[id_give] );
00211       Entity * const e1 = bulk.get_entity( 0 , ids[id_give+1] );
00212       STKUNIT_ASSERT( NULL != e0 && e0->bucket().capacity() == 0 );
00213       STKUNIT_ASSERT( NULL != e1 && e1->bucket().capacity() == 0 );
00214     }
00215 
00216     STKUNIT_ASSERT( bulk.modification_begin() );
00217     STKUNIT_ASSERT( bulk.modification_end() );
00218 
00219     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_give] ) );
00220     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_give+1] ) );
00221   }
00222 
00223   std::cout << std::endl
00224             << "P" << p_rank
00225             << ": UnitTestBulkData::testChangeOwner_nodes( NP = "
00226             << p_size << " ) SUCCESSFULL " << std::endl ;
00227 }
00228 
00229 //----------------------------------------------------------------------
00230 // Testing for error using mesh entities without relations
00231 
00232 void UnitTestBulkData::testCreateMore_error( ParallelMachine pm )
00233 {
00234   enum { nPerProc = 10 };
00235 
00236   const unsigned p_size = parallel_machine_size( pm );
00237   const unsigned p_rank = parallel_machine_rank( pm );
00238 
00239   if ( 1 < p_size ) {
00240 
00241     std::cout << std::endl
00242               << "P" << p_rank
00243               << ": UnitTestBulkData::testCreateMore_error( NP = "
00244               << p_size << " ) TESTING FOR PARALLEL ERROR CATCHING"
00245               << std::endl ;
00246     std::cout.flush();
00247 
00248     const unsigned id_total = nPerProc * p_size ;
00249     const unsigned id_begin = nPerProc * p_rank ;
00250     const unsigned id_end   = nPerProc * ( p_rank + 1 );
00251 
00252     MetaData meta( fem_entity_type_names() );
00253 
00254     const PartVector no_parts ;
00255 
00256     meta.commit();
00257 
00258     BulkData bulk( meta , pm , 100 );
00259 
00260     bulk.modification_begin();
00261 
00262     // Ids for all entities (all entities have type 0):
00263 
00264     std::vector<EntityId> ids( id_total );
00265 
00266     for ( unsigned i = 0 ; i < id_total ; ++i ) { ids[i] = i + 1; }
00267 
00268     // Declare just those entities in my range of ids:
00269 
00270     for ( unsigned i = id_begin ; i < id_end ; ++i ) {
00271       bulk.declare_entity( 0 , ids[i] , no_parts );
00272     }
00273 
00274     STKUNIT_ASSERT( bulk.modification_end() );
00275 
00276     // Only one process create entities with previous process' last two ids
00277 
00278     const unsigned id_get  = ( id_begin + id_total - 2 ) % id_total ;
00279 
00280     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_get] ) );
00281     STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[id_get+1] ) );
00282 
00283     STKUNIT_ASSERT( bulk.modification_begin() );
00284 
00285     if ( 1 == p_rank ) {
00286       bulk.declare_entity( 0 , ids[ id_get ] , no_parts );
00287       bulk.declare_entity( 0 , ids[ id_get + 1 ] , no_parts );
00288     }
00289   
00290     std::string error_msg ;
00291     bool exception_thrown = false ;
00292     try {
00293       bulk.modification_end();
00294     }
00295     catch( const std::exception & x ) {
00296       exception_thrown = true ;
00297       error_msg.append( x.what() );
00298       std::cerr.flush();
00299     }
00300 
00301     STKUNIT_ASSERT( exception_thrown );
00302 
00303     std::cout << std::endl
00304               << "P" << p_rank
00305               << ": UnitTestBulkData::testCreateMore_error( NP = "
00306               << p_size << " ) SUCCESSFULLY CAUGHT "
00307               << error_msg
00308               << std::endl ;
00309     std::cout.flush();
00310   }
00311 }
00312 
00313 //----------------------------------------------------------------------
00314 //----------------------------------------------------------------------
00315 
00316 void UnitTestBulkData::testChangeOwner_loop( ParallelMachine pm )
00317 {
00318   enum { nPerProc = 10 };
00319   const unsigned p_rank = parallel_machine_rank( pm );
00320   const unsigned p_size = parallel_machine_size( pm );
00321   const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
00322   const unsigned nLocalEdge = nPerProc ;
00323 
00324   std::vector<unsigned> local_count ;
00325 
00326   //------------------------------
00327   {
00328     RingMeshFixture ring_mesh( pm , nPerProc , false /* no edge parts */ );
00329 
00330     ring_mesh.generate_loop( false /* no aura */ );
00331 
00332     const Selector select_used(  ring_mesh.m_meta_data.locally_used_part() );
00333     const Selector select_all(   ring_mesh.m_meta_data.universal_part() );
00334 
00335     count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00336     STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
00337     STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
00338 
00339     count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00340     STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
00341     STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
00342 
00343     // Shift loop by two nodes and edges.
00344 
00345     if ( 1 < p_size ) {
00346       ring_mesh.test_shift_loop( false /* no aura */ );
00347 
00348       count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00349       STKUNIT_ASSERT( local_count[0] == nLocalNode );
00350       STKUNIT_ASSERT( local_count[1] == nLocalEdge );
00351 
00352       count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00353       STKUNIT_ASSERT( local_count[0] == nLocalNode );
00354       STKUNIT_ASSERT( local_count[1] == nLocalEdge );
00355     }
00356   }
00357 
00358   //------------------------------
00359   // Test shift starting with ghosting but not regenerated ghosting.
00360   {
00361     RingMeshFixture ring_mesh( pm , nPerProc , false /* no edge parts */ );
00362 
00363     ring_mesh.generate_loop( true /* with aura */ );
00364 
00365     const Selector select_owned( ring_mesh.m_meta_data.locally_owned_part() );
00366     const Selector select_used(  ring_mesh.m_meta_data.locally_used_part() );
00367     const Selector select_all(   ring_mesh.m_meta_data.universal_part() );
00368 
00369     count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00370     STKUNIT_ASSERT_EQUAL( local_count[0] , nLocalNode );
00371     STKUNIT_ASSERT_EQUAL( local_count[1] , nLocalEdge );
00372 
00373     count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00374     const unsigned n_extra = 1 < p_size ? 2 : 0 ;
00375     STKUNIT_ASSERT( local_count[0] == nLocalNode + n_extra );
00376     STKUNIT_ASSERT( local_count[1] == nLocalEdge + n_extra );
00377 
00378     if ( 1 < p_size ) {
00379       ring_mesh.test_shift_loop( false /* no aura */ );
00380 
00381       count_entities( select_owned , ring_mesh.m_bulk_data , local_count );
00382       STKUNIT_ASSERT( local_count[0] == nPerProc );
00383       STKUNIT_ASSERT( local_count[1] == nPerProc );
00384 
00385       count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00386       STKUNIT_ASSERT( local_count[0] == nLocalNode );
00387       STKUNIT_ASSERT( local_count[1] == nLocalEdge );
00388 
00389       // All of my ghosts were disrupted and therefore deleted:
00390       count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00391       STKUNIT_ASSERT_EQUAL( nLocalEdge , local_count[1] );
00392       STKUNIT_ASSERT_EQUAL( nLocalNode , local_count[0] );
00393     }
00394   }
00395   //------------------------------
00396   // Test shift starting with ghosting and regenerating ghosting.
00397   {
00398     RingMeshFixture ring_mesh( pm , nPerProc , false /* no edge parts */ );
00399 
00400     ring_mesh.generate_loop( true /* with aura */ );
00401 
00402     const Selector select_owned( ring_mesh.m_meta_data.locally_owned_part() );
00403     const Selector select_used(  ring_mesh.m_meta_data.locally_used_part() );
00404     const Selector select_all(   ring_mesh.m_meta_data.universal_part() );
00405 
00406     count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00407     STKUNIT_ASSERT( local_count[0] == nLocalNode );
00408     STKUNIT_ASSERT( local_count[1] == nLocalEdge );
00409 
00410     count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00411     const unsigned n_extra = 1 < p_size ? 2 : 0 ;
00412     STKUNIT_ASSERT( local_count[0] == nLocalNode + n_extra );
00413     STKUNIT_ASSERT( local_count[1] == nLocalEdge + n_extra );
00414 
00415     if ( 1 < p_size ) {
00416       ring_mesh.test_shift_loop( true /* with aura */ );
00417 
00418       count_entities( select_owned , ring_mesh.m_bulk_data , local_count );
00419       STKUNIT_ASSERT( local_count[0] == nPerProc );
00420       STKUNIT_ASSERT( local_count[1] == nPerProc );
00421 
00422       count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00423       STKUNIT_ASSERT( local_count[0] == nLocalNode );
00424       STKUNIT_ASSERT( local_count[1] == nLocalEdge );
00425 
00426       // All of my ghosts were regenerated:
00427       count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00428       STKUNIT_ASSERT( local_count[0] == nLocalNode + n_extra );
00429       STKUNIT_ASSERT( local_count[1] == nLocalEdge + n_extra );
00430     }
00431   }
00432   //------------------------------
00433   // Test bad owner change catching:
00434   if ( 1 < p_size ) {
00435     RingMeshFixture ring_mesh( pm , nPerProc , false /* no edge parts */ );
00436 
00437     ring_mesh.generate_loop( true /* with aura */ );
00438 
00439     std::vector<EntityProc> change ;
00440 
00441     if ( 0 == p_rank ) {
00442       change.resize(4);
00443       // Error to change to bad owner:
00444       change[0].first = ring_mesh.m_bulk_data.get_entity( 0 , ring_mesh.m_node_ids[1] );
00445       change[0].second = p_size ;
00446       // Error to change a ghost:
00447       for ( std::vector<Entity*>::const_iterator
00448             ec =  ring_mesh.m_bulk_data.entity_comm().begin() ;
00449             ec != ring_mesh.m_bulk_data.entity_comm().end() ; ++ec ) {
00450         if ( in_receive_ghost( **ec ) ) {
00451           change[1].first = *ec ;
00452           break ;
00453         }
00454       }
00455       change[1].second = p_rank ;
00456       // Error to change to multiple owners:
00457       change[2].first = ring_mesh.m_bulk_data.get_entity( 0 , ring_mesh.m_node_ids[1] );
00458       change[2].second = ( p_rank + 1 ) % p_size ;
00459       change[3].first = change[2].first ;
00460       change[3].second = ( p_rank + 2 ) % p_size ;
00461     }
00462 
00463     STKUNIT_ASSERT( ring_mesh.m_bulk_data.modification_begin() );
00464 
00465     std::string error_msg ;
00466     bool exception_thrown = false ;
00467     try {
00468       ring_mesh.m_bulk_data.change_entity_owner( change );
00469     }
00470     catch( const std::exception & x ) {
00471       exception_thrown = true ;
00472       error_msg.assign( x.what() );
00473     }
00474     STKUNIT_ASSERT( exception_thrown );
00475     std::cout
00476       << std::endl
00477       << "  UnitTestBulkData::testChangeOwner_loop SUCCESSFULLY CAUGHT: "
00478       << error_msg << std::endl ;
00479     std::cout.flush();
00480   }
00481   //------------------------------
00482   // Test move one element with initial ghosting but not regenerated ghosting:
00483   // last processor give its shared node to P0
00484   if ( 1 < p_size ) {
00485     RingMeshFixture ring_mesh( pm , nPerProc , false /* no edge parts */ );
00486 
00487     ring_mesh.generate_loop( true /* with aura */ );
00488 
00489     const Selector select_owned( ring_mesh.m_meta_data.locally_owned_part() );
00490     const Selector select_used(  ring_mesh.m_meta_data.locally_used_part() );
00491     const Selector select_all(   ring_mesh.m_meta_data.universal_part() );
00492 
00493     std::vector<EntityProc> change ;
00494 
00495     if ( p_rank + 1 == p_size ) {
00496       EntityProc entry ;
00497       entry.first = ring_mesh.m_bulk_data.get_entity( 0 , ring_mesh.m_node_ids[0] );
00498       entry.second = 0 ;
00499       STKUNIT_ASSERT_EQUAL( p_rank , entry.first->owner_rank() );
00500       change.push_back( entry );
00501     }
00502 
00503     STKUNIT_ASSERT( ring_mesh.m_bulk_data.modification_begin() );
00504     ring_mesh.m_bulk_data.change_entity_owner( change );
00505     STKUNIT_ASSERT( UnitTestBulkData::modification_end( ring_mesh.m_bulk_data , false ) );
00506 
00507     count_entities( select_owned , ring_mesh.m_bulk_data , local_count );
00508     const unsigned n_node = p_rank == 0          ? nPerProc + 1 : (
00509                             p_rank + 1 == p_size ? nPerProc - 1 :
00510                                                    nPerProc );
00511               
00512     STKUNIT_ASSERT_EQUAL( n_node , local_count[0] );
00513     STKUNIT_ASSERT_EQUAL( (unsigned) nPerProc , local_count[1] );
00514 
00515     count_entities( select_used , ring_mesh.m_bulk_data , local_count );
00516     STKUNIT_ASSERT_EQUAL( nLocalNode , local_count[0] );
00517     STKUNIT_ASSERT_EQUAL( nLocalEdge , local_count[1] );
00518 
00519     // Moving the node disrupted ghosting on first and last process
00520     count_entities( select_all , ring_mesh.m_bulk_data , local_count );
00521     const unsigned n_extra = p_rank + 1 == p_size || p_rank == 0 ? 1 : 2 ;
00522     STKUNIT_ASSERT_EQUAL( nLocalNode + n_extra , local_count[0] );
00523     STKUNIT_ASSERT_EQUAL( nLocalEdge + n_extra , local_count[1] );
00524   }
00525 
00526   //------------------------------
00527 
00528   std::cout << std::endl
00529             << "P" << p_rank
00530             << ": UnitTestBulkData::testChangeOwner_loop( NP = "
00531             << p_size << " ) SUCCESSFULL" << std::endl ;
00532 }
00533 
00534 //----------------------------------------------------------------------
00535 //----------------------------------------------------------------------
00536 // Testing for collection of boxes
00537 
00538 namespace {
00539 
00540 void donate_one_element( BulkData & mesh , bool aura )
00541 {
00542   const unsigned p_rank = mesh.parallel_rank();
00543 
00544   Selector select_owned( mesh.mesh_meta_data().locally_owned_part() );
00545 
00546   std::vector<unsigned> before_count ;
00547   std::vector<unsigned> after_count ;
00548 
00549   count_entities( select_owned , mesh , before_count );
00550 
00551   // Change owner of an element on a process boundary
00552   // from P0 to P1, and then recount to confirm ownership change
00553 
00554   std::vector<EntityProc> change ;
00555 
00556   // A shared node:
00557   Entity * node = NULL ;
00558   Entity * elem = NULL ;
00559 
00560   for ( std::vector<Entity*>::const_iterator
00561         i =  mesh.entity_comm().begin() ;
00562         i != mesh.entity_comm().end() ; ++i ) {
00563     if ( in_shared( **i ) && (**i).entity_rank() == Node ) {
00564       node = *i ;
00565       break ;
00566     }
00567   }
00568 
00569   STKUNIT_ASSERT( node != NULL );
00570 
00571   for ( PairIterRelation rel = node->relations( 3 );
00572         ! rel.empty() && elem == NULL ; ++rel ) {
00573     elem = rel->entity();
00574     if ( elem->owner_rank() != p_rank ) { elem = NULL ; }
00575   }
00576 
00577   STKUNIT_ASSERT( elem != NULL );
00578 
00579   unsigned donated_nodes = 0 ;
00580 
00581   // Only process #0 donates an element and its owned nodes:
00582   if ( 0 == p_rank ) {
00583     EntityProc entry ;
00584     entry.first = elem ;
00585     entry.second = node->sharing()[0].proc ;
00586     change.push_back( entry );
00587     for ( PairIterRelation
00588           rel = elem->relations(0) ; ! rel.empty() ; ++rel ) {
00589       if ( rel->entity()->owner_rank() == p_rank ) {
00590         entry.first = rel->entity();
00591         change.push_back( entry );
00592         ++donated_nodes ;
00593       }
00594     }
00595   }
00596 
00597   STKUNIT_ASSERT( mesh.modification_begin() );
00598   mesh.change_entity_owner( change );
00599   STKUNIT_ASSERT( UnitTestBulkData::modification_end( mesh , aura ) );
00600 
00601   count_entities( select_owned , mesh , after_count );
00602 
00603   if ( 0 == p_rank ) {
00604     STKUNIT_ASSERT_EQUAL( before_count[3] - 1 , after_count[3] );
00605     STKUNIT_ASSERT_EQUAL( before_count[0] - donated_nodes, after_count[0] );
00606   }
00607 }
00608 
00609 void donate_all_shared_nodes( BulkData & mesh , bool aura )
00610 {
00611   const unsigned p_rank = mesh.parallel_rank();
00612 
00613   Selector select_used( mesh.mesh_meta_data().locally_used_part() );
00614 
00615   std::vector<unsigned> before_count ;
00616   std::vector<unsigned> after_count ;
00617 
00618   count_entities( select_used , mesh , before_count );
00619 
00620   // Donate owned shared nodes to first sharing process.
00621 
00622   const std::vector<Entity*> & entity_comm = mesh.entity_comm(); 
00623 
00624   STKUNIT_ASSERT( ! entity_comm.empty() );
00625 
00626   std::vector<EntityProc> change ;
00627 
00628   for ( std::vector<Entity*>::const_iterator
00629         i =  entity_comm.begin() ;
00630         i != entity_comm.end() &&
00631         (**i).entity_rank() == Node ; ++i ) {
00632     Entity * const node = *i ;
00633     const PairIterEntityComm ec = node->sharing();
00634 
00635     if ( node->owner_rank() == p_rank && ! ec.empty() ) {
00636       change.push_back( EntityProc( node , ec->proc ) );
00637     }
00638   }
00639 
00640   STKUNIT_ASSERT( mesh.modification_begin() );
00641   mesh.change_entity_owner( change );
00642   STKUNIT_ASSERT( UnitTestBulkData::modification_end( mesh , aura ) );
00643 
00644   count_entities( select_used , mesh , after_count );
00645 
00646   STKUNIT_ASSERT( 3 <= after_count.size() );
00647   STKUNIT_ASSERT_EQUAL( before_count[0] , after_count[0] );
00648   STKUNIT_ASSERT_EQUAL( before_count[1] , after_count[1] );
00649   STKUNIT_ASSERT_EQUAL( before_count[2] , after_count[2] );
00650   STKUNIT_ASSERT_EQUAL( before_count[3] , after_count[3] );
00651 }
00652 
00653 }
00654 
00655 void UnitTestBulkData::testChangeOwner_box( ParallelMachine pm )
00656 {
00657   const int root_box[3][2] = { { 0 , 4 } , { 0 , 5 } , { 0 , 6 } };
00658   int local_box[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
00659 
00660   const unsigned p_rank = parallel_machine_rank( pm );
00661   const unsigned p_size = parallel_machine_size( pm );
00662 
00663   MetaData meta( fem_entity_type_names() );
00664 
00665   meta.commit();
00666 
00667   Selector select_owned( meta.locally_owned_part() );
00668   Selector select_used(  meta.locally_used_part() );
00669   Selector select_all(   meta.universal_part() );
00670 
00671   //------------------------------
00672   {
00673     BulkData bulk( meta , pm , 100 );
00674     bulk.modification_begin();
00675     generate_boxes( bulk , false /* no aura */ , root_box , local_box );
00676 
00677     if ( 1 < p_size ) {
00678       donate_one_element( bulk , false /* no aura */ );
00679     }
00680   }
00681 
00682   if ( 1 < p_size ) {
00683     BulkData bulk( meta , pm , 100 );
00684     bulk.modification_begin();
00685 
00686     generate_boxes( bulk , false /* no aura */ , root_box , local_box );
00687 
00688     donate_all_shared_nodes( bulk , false /* no aura */ );
00689   }
00690   //------------------------------
00691   if ( 1 < p_size ) {
00692     BulkData bulk( meta , pm , 100 );
00693     bulk.modification_begin();
00694 
00695     generate_boxes( bulk , false /* no aura */ , root_box , local_box );
00696 
00697     donate_one_element( bulk , false /* no aura */ );
00698   }
00699   //------------------------------
00700   // Introduce ghosts:
00701   if ( 1 < p_size ) {
00702     BulkData bulk( meta , pm , 100 );
00703     bulk.modification_begin();
00704 
00705     generate_boxes( bulk , true /* aura */ , root_box , local_box );
00706 
00707     std::vector<unsigned> used_count ;
00708     std::vector<unsigned> all_count ;
00709 
00710     count_entities( select_all , bulk , all_count );
00711     count_entities( select_used , bulk , used_count );
00712 
00713     STKUNIT_ASSERT( used_count[0] < all_count[0] );
00714     STKUNIT_ASSERT( used_count[3] < all_count[3] );
00715 
00716     donate_all_shared_nodes( bulk , false /* don't regenerate aura */ );
00717 
00718     count_entities( select_all , bulk , all_count );
00719     count_entities( select_used , bulk , used_count );
00720 
00721     STKUNIT_ASSERT_EQUAL( used_count[0] , all_count[0] );
00722     STKUNIT_ASSERT_EQUAL( used_count[3] , all_count[3] );
00723   }
00724   //------------------------------
00725 
00726   std::cout << std::endl
00727             << "P" << p_rank
00728             << ": UnitTestBulkData::testChangeOwner_box( NP = "
00729             << p_size << " ) SUCCESSFULL" << std::endl ;
00730 }
00731 
00732 //----------------------------------------------------------------------
00733 //----------------------------------------------------------------------
00734 
00735 } // namespace mesh
00736 } // namespace stk
00737 

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