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