|
Sierra Toolkit Version of the Day
|
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