UnitTestBulkData_Destroy.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/Comm.hpp>
00018 #include <stk_mesh/fem/EntityTypes.hpp>
00019 
00020 #include <unit_tests/UnitTestBulkData.hpp>
00021 #include <unit_tests/UnitTestRingMeshFixture.hpp>
00022 
00023 //----------------------------------------------------------------------
00024 //----------------------------------------------------------------------
00025 
00026 namespace stk {
00027 namespace mesh {
00028 
00029 //----------------------------------------------------------------------
00030 // Testing for mesh entities without relations
00031 
00032 void UnitTestBulkData::testDestroy_nodes( ParallelMachine pm )
00033 {
00034   enum { nPerProc = 10 };
00035   const unsigned p_rank = parallel_machine_rank( pm );
00036   const unsigned p_size = parallel_machine_size( pm );
00037   const unsigned id_total = nPerProc * p_size ;
00038   const unsigned id_begin = nPerProc * p_rank ;
00039   const unsigned id_end   = nPerProc * ( p_rank + 1 );
00040 
00041   MetaData meta( fem_entity_type_names() );
00042 
00043   const PartVector no_parts ;
00044 
00045   meta.commit();
00046 
00047   BulkData bulk( meta , pm , 100 );
00048 
00049   // Ids for all entities (all entities have type 0):
00050 
00051   std::vector<EntityId> ids( id_total );
00052 
00053   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00054     ids[i] = i + 1;
00055   }
00056 
00057   // Declare just those entities in my range of ids:
00058 
00059   STKUNIT_ASSERT( bulk.modification_begin() );
00060   for ( unsigned i = id_begin ; i < id_end ; ++i ) {
00061     bulk.declare_entity( 0 , ids[i] , no_parts );
00062   }
00063   STKUNIT_ASSERT( bulk.modification_end() );
00064 
00065   // Verify that I only have entities in my range:
00066 
00067   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00068     Entity * e = bulk.get_entity( 0 , ids[ i ] );
00069     if ( id_begin <= i && i < id_end ) {
00070       STKUNIT_ASSERT( NULL != e );
00071       STKUNIT_ASSERT( p_rank == e->owner_rank() );
00072     }
00073     else {
00074       STKUNIT_ASSERT( NULL == e );
00075     }
00076   }
00077 
00078   // Delete one entity at a time.
00079 
00080   for ( unsigned i = id_begin ; i < id_end ; ++i ) {
00081     Entity * e = bulk.get_entity( 0 , ids[ i ] );
00082 
00083     STKUNIT_ASSERT( NULL != e );
00084 
00085     bulk.modification_begin();
00086     STKUNIT_ASSERT( bulk.destroy_entity( e ) );
00087     bulk.modification_end();
00088 
00089     // Due to change logging the previously deleted entity
00090     // should be gone, but the currently deleted entity
00091     // should exist in the 'nil' set.
00092 
00093     if ( id_begin < i ) {
00094       STKUNIT_ASSERT( NULL == bulk.get_entity( 0 , ids[ i - 1 ] ) );
00095     }
00096 
00097     e = bulk.get_entity( 0 , ids[ i ] );
00098     STKUNIT_ASSERT( NULL != e );
00099     STKUNIT_ASSERT( 0 == e->bucket().capacity() );
00100   }
00101 
00102   std::cout << std::endl
00103             << "P" << p_rank
00104             << ": UnitTestBulkData::testDestroy_nodes( NP = "
00105             << p_size << " ) SUCCESSFULL " << std::endl ;
00106 }
00107 
00108 //----------------------------------------------------------------------
00109 
00110 void assert_is_destroyed( const Entity * const entity )
00111 {
00112   STKUNIT_ASSERT( entity == NULL || entity->bucket().capacity() == 0 );
00113 }
00114 
00115 void UnitTestBulkData::testDestroy_loop( ParallelMachine pm )
00116 {
00117   enum { nPerProc = 10 };
00118   const unsigned p_rank = parallel_machine_rank( pm );
00119   const unsigned p_size = parallel_machine_size( pm );
00120   // const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 );
00121   const unsigned nLocalEdge = nPerProc ;
00122  
00123   MetaData meta( fem_entity_type_names() );
00124  
00125   meta.commit();
00126  
00127   Selector select_owned( meta.locally_owned_part() );
00128   Selector select_used( meta.locally_used_part() );
00129   Selector select_all(  meta.universal_part() );
00130  
00131   PartVector no_parts ;
00132  
00133   std::vector<unsigned> local_count ;
00134  
00135   //------------------------------
00136   { // No ghosting
00137     const bool aura_flag = false ;
00138 
00139     RingMeshFixture mesh( pm , nPerProc , false /* No edge parts */ );
00140 
00141     mesh.generate_loop( aura_flag );
00142  
00143     // This process' first element in the loop
00144     // if a parallel mesh has a shared node 
00145     Entity * edge = mesh.m_bulk_data.get_entity( 1 , mesh.m_edge_ids[ nLocalEdge * p_rank ] );
00146     Entity * node0 = edge->relations()[0].entity();
00147     Entity * node1 = edge->relations()[1].entity();
00148 
00149     const size_t node0_edges = node0->relations().size();
00150     const size_t node1_edges = node1->relations().size();
00151 
00152     STKUNIT_ASSERT( 1 <= node0_edges && node0_edges <= 2 );
00153     STKUNIT_ASSERT( 1 <= node1_edges && node1_edges <= 2 );
00154 
00155     STKUNIT_ASSERT( node0->relations()[0].entity() == edge ||
00156                     node0->relations()[1].entity() == edge );
00157 
00158     STKUNIT_ASSERT( node1->relations()[0].entity() == edge ||
00159                     node1->relations()[1].entity() == edge );
00160 
00161     mesh.m_bulk_data.modification_begin();
00162 
00163     // Destroy the element:
00164     bool result = mesh.m_bulk_data.destroy_entity( edge );
00165     STKUNIT_ASSERT( true == result );
00166     STKUNIT_ASSERT( NULL == edge );
00167 
00168     // Destroy orphanned node:
00169     if ( node0->relations().size() == 0 ) {
00170       STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( node0 ) );
00171       STKUNIT_ASSERT( NULL == node0 );
00172     }
00173     if ( node1->relations().size() == 0 ) {
00174       STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( node1 ) );
00175       STKUNIT_ASSERT( NULL == node1 );
00176     }
00177     STKUNIT_ASSERT( mesh.m_bulk_data.internal_modification_end( aura_flag ) );
00178 
00179     if ( NULL != node0 ) {
00180       STKUNIT_ASSERT_EQUAL( node0_edges - 1 , node0->relations().size() );
00181     }
00182     if ( NULL != node1 ) {
00183       STKUNIT_ASSERT_EQUAL( node1_edges - 1 , node1->relations().size() );
00184     }
00185   }
00186   //------------------------------
00187   if ( 1 < p_size ) { // With ghosting
00188     const bool aura_flag = true ;
00189 
00190     RingMeshFixture mesh( pm , nPerProc , false /* No edge parts */ );
00191 
00192     mesh.generate_loop( aura_flag );
00193  
00194     const unsigned nNotOwned = nPerProc * p_rank ;
00195 
00196     // The not-owned shared entity:
00197     Entity * node = mesh.m_bulk_data.get_entity( 0 , mesh.m_node_ids[ nNotOwned ] );
00198 
00199     STKUNIT_ASSERT( node != NULL );
00200     STKUNIT_ASSERT( p_rank != node->owner_rank() );
00201     STKUNIT_ASSERT_EQUAL( size_t(1) , node->sharing().size() );
00202     STKUNIT_ASSERT_EQUAL( size_t(2) , node->relations().size() );
00203 
00204     EntityId node_edge_ids[2] ;
00205     node_edge_ids[0] = node->relations()[0].entity()->identifier();
00206     node_edge_ids[1] = node->relations()[1].entity()->identifier();
00207 
00208     mesh.m_bulk_data.modification_begin();
00209 
00210     // This process' first node in the loop is shared, destroy it
00211     // First have to destroy attached edges.
00212     // One will be owned and the other ghosted
00213 
00214     while ( node->relations().size() ) {
00215       Entity * e = node->relations().back().entity();
00216       STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( e ) );
00217     }
00218     STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( node ) );
00219 
00220     STKUNIT_ASSERT( mesh.m_bulk_data.internal_modification_end( aura_flag ) );
00221 
00222     assert_is_destroyed( mesh.m_bulk_data.get_entity(0, mesh.m_node_ids[nNotOwned] ) );
00223     assert_is_destroyed( mesh.m_bulk_data.get_entity(1, node_edge_ids[0] ) );
00224     assert_is_destroyed( mesh.m_bulk_data.get_entity(1, node_edge_ids[1] ) );
00225   }
00226   //------------------------------
00227   if ( 1 < p_size ) { // With ghosting
00228     const bool aura_flag = true ;
00229 
00230     RingMeshFixture mesh( pm , nPerProc , false /* No edge parts */ );
00231 
00232     mesh.generate_loop( aura_flag );
00233  
00234     // The owned shared entity:
00235     const unsigned nOwned = ( nPerProc * ( p_rank + 1 ) ) % mesh.m_node_ids.size();
00236     const unsigned nNotOwned = nPerProc * p_rank ;
00237 
00238     Entity * node_owned = mesh.m_bulk_data.get_entity( 0 , mesh.m_node_ids[ nOwned ] );
00239     Entity * node_not_owned = mesh.m_bulk_data.get_entity( 0 , mesh.m_node_ids[ nNotOwned ] );
00240 
00241     STKUNIT_ASSERT( node_owned != NULL );
00242     STKUNIT_ASSERT( node_not_owned != NULL );
00243     STKUNIT_ASSERT( p_rank != node_not_owned->owner_rank() );
00244     STKUNIT_ASSERT_EQUAL( p_rank , node_owned->owner_rank() );
00245     STKUNIT_ASSERT_EQUAL( size_t(1) , node_owned->sharing().size() );
00246     STKUNIT_ASSERT_EQUAL( size_t(1) , node_not_owned->sharing().size() );
00247     STKUNIT_ASSERT_EQUAL( size_t(2) , node_owned->relations().size() );
00248 
00249     EntityId node_edge_ids[2] ;
00250     node_edge_ids[0] = node_owned->relations()[0].entity()->identifier();
00251     node_edge_ids[1] = node_owned->relations()[1].entity()->identifier();
00252 
00253     mesh.m_bulk_data.modification_begin();
00254 
00255     // This process' first node in the loop is shared, destroy it
00256     // First have to destroy attached edges.
00257     // One will be owned and the other ghosted
00258 
00259     while ( node_owned->relations().size() ) {
00260       Entity * e = node_owned->relations().back().entity();
00261       STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( e ) );
00262     }
00263     STKUNIT_ASSERT( mesh.m_bulk_data.destroy_entity( node_owned ) );
00264 
00265     STKUNIT_ASSERT( mesh.m_bulk_data.internal_modification_end( aura_flag ) );
00266 
00267     // Ownership of the other process' owned, shared, and destroyed node
00268     // has been transferred to this process.
00269 
00270     STKUNIT_ASSERT_EQUAL( p_rank , node_not_owned->owner_rank() );
00271     assert_is_destroyed( mesh.m_bulk_data.get_entity(0, mesh.m_node_ids[ nOwned ] ) );
00272     assert_is_destroyed( mesh.m_bulk_data.get_entity(1, node_edge_ids[0] ) );
00273     assert_is_destroyed( mesh.m_bulk_data.get_entity(1, node_edge_ids[1] ) );
00274   }
00275 }
00276 
00277 }
00278 }
00279 

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