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