|
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 #include <unit_tests/UnitTestRingMeshFixture.hpp> 00010 #include <unit_tests/UnitTestBulkData.hpp> 00011 00012 #include <Shards_BasicTopologies.hpp> 00013 00014 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00015 #include <stk_util/parallel/Parallel.hpp> 00016 00017 #include <stk_mesh/base/MetaData.hpp> 00018 #include <stk_mesh/base/BulkData.hpp> 00019 #include <stk_mesh/base/Entity.hpp> 00020 #include <stk_mesh/base/EntityComm.hpp> 00021 #include <stk_mesh/base/GetEntities.hpp> 00022 00023 #include <stk_mesh/fem/EntityRanks.hpp> 00024 #include <stk_mesh/fem/TopologyHelpers.hpp> 00025 00026 using namespace stk; 00027 using namespace stk::mesh; 00028 00029 UnitTestRingMeshFixture::UnitTestRingMeshFixture( 00030 ParallelMachine pm , 00031 unsigned num_edge_per_proc , 00032 bool use_edge_parts ) 00033 : m_spatial_dimension(3), 00034 m_meta_data( TopologicalMetaData::entity_rank_names(m_spatial_dimension) ), 00035 m_bulk_data( m_meta_data, pm, 100 ), 00036 m_top_data( m_meta_data, m_spatial_dimension ), 00037 m_edge_parts(), 00038 m_edge_part_extra( m_meta_data.declare_part( "edge_extra" , m_top_data.edge_rank ) ), 00039 m_num_edge_per_proc( num_edge_per_proc ), 00040 m_node_ids(), 00041 m_edge_ids() 00042 { 00043 if ( use_edge_parts ) { 00044 m_edge_parts.resize( num_edge_per_proc ); 00045 for ( unsigned i = 0 ; i < num_edge_per_proc ; ++i ) { 00046 std::ostringstream name ; 00047 name << "EdgePart_" << i ; 00048 m_edge_parts[i] = & m_meta_data.declare_part( name.str() , m_top_data.edge_rank ); 00049 } 00050 } 00051 } 00052 00053 UnitTestRingMeshFixture::~UnitTestRingMeshFixture() 00054 {} 00055 00056 void UnitTestRingMeshFixture::generate_mesh( bool generate_aura ) 00057 { 00058 //if ( ! m_meta_data.is_commit() ) { 00059 // throw std::runtime_error("Please commit meta-data before calling " 00060 // "generate_mesh"); 00061 //} 00062 00063 const unsigned p_rank = m_bulk_data.parallel_rank(); 00064 const unsigned p_size = m_bulk_data.parallel_size(); 00065 const unsigned nPerProc = m_num_edge_per_proc ; 00066 const unsigned id_total = nPerProc * p_size ; 00067 const unsigned id_begin = nPerProc * p_rank ; 00068 const unsigned id_end = nPerProc * ( p_rank + 1 ); 00069 const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 ); 00070 const unsigned nLocalEdge = nPerProc ; 00071 const unsigned n_extra = generate_aura && 1 < p_size ? 2 : 0 ; 00072 00073 m_node_ids.resize( id_total ); 00074 m_edge_ids.resize( id_total ); 00075 std::vector<unsigned> local_count ; 00076 00077 for ( unsigned i = 0 ; i < id_total ; ++i ) { 00078 m_node_ids[i] = i + 1; 00079 m_edge_ids[i] = i + 1; 00080 } 00081 00082 m_bulk_data.modification_begin(); 00083 00084 // Create a loop of edges: 00085 { 00086 const PartVector no_parts ; 00087 PartVector add_parts ; 00088 00089 if ( ! m_edge_parts.empty() ) { add_parts.resize(1); } 00090 00091 for ( unsigned i = id_begin ; i < id_end ; ++i ) { 00092 const unsigned n0 = i ; 00093 const unsigned n1 = ( i + 1 ) % id_total ; 00094 if ( ! m_edge_parts.empty() ) { 00095 add_parts[0] = m_edge_parts[ i % m_edge_parts.size() ]; 00096 } 00097 Entity & e_node_0 = m_bulk_data.declare_entity( 0 , m_node_ids[n0] , no_parts ); 00098 Entity & e_node_1 = m_bulk_data.declare_entity( 0 , m_node_ids[n1] , no_parts ); 00099 Entity & e_edge = m_bulk_data.declare_entity( 1 , m_edge_ids[i] , add_parts ); 00100 m_bulk_data.declare_relation( e_edge , e_node_0 , 0 ); 00101 m_bulk_data.declare_relation( e_edge , e_node_1 , 1 ); 00102 } 00103 } 00104 00105 Selector select_owned( m_bulk_data.mesh_meta_data().locally_owned_part() ); 00106 Selector select_used = m_bulk_data.mesh_meta_data().locally_owned_part() | 00107 m_bulk_data.mesh_meta_data().globally_shared_part(); 00108 Selector select_all( m_bulk_data.mesh_meta_data().universal_part() ); 00109 00110 stk::mesh::count_entities( select_used , m_bulk_data , local_count ); 00111 STKUNIT_ASSERT( local_count[m_top_data.node_rank] == nLocalNode ); 00112 STKUNIT_ASSERT( local_count[m_top_data.edge_rank] == nLocalEdge ); 00113 00114 std::vector<Entity*> all_nodes; 00115 get_entities( m_bulk_data, m_top_data.node_rank, all_nodes); 00116 00117 unsigned num_selected_nodes = 00118 count_selected_entities( select_used, m_bulk_data.buckets(m_top_data.node_rank) ); 00119 STKUNIT_ASSERT( num_selected_nodes == local_count[m_top_data.node_rank] ); 00120 00121 std::vector<Entity*> universal_nodes; 00122 get_selected_entities( select_all, m_bulk_data.buckets(m_top_data.node_rank), universal_nodes ); 00123 STKUNIT_ASSERT( universal_nodes.size() == all_nodes.size() ); 00124 00125 STKUNIT_ASSERT( UnitTestBulkData::modification_end( m_bulk_data , generate_aura ) ); 00126 00127 // Verify declarations and sharing two end nodes: 00128 00129 stk::mesh::count_entities( select_used , m_bulk_data , local_count ); 00130 STKUNIT_ASSERT( local_count[0] == nLocalNode ); 00131 STKUNIT_ASSERT( local_count[1] == nLocalEdge ); 00132 00133 if ( 1 < p_size ) { 00134 const unsigned n0 = id_end < id_total ? id_begin : 0 ; 00135 const unsigned n1 = id_end < id_total ? id_end : id_begin ; 00136 00137 Entity * const node0 = m_bulk_data.get_entity( m_top_data.node_rank , m_node_ids[n0] ); 00138 Entity * const node1 = m_bulk_data.get_entity( m_top_data.node_rank , m_node_ids[n1] ); 00139 00140 STKUNIT_ASSERT( node0 != NULL ); 00141 STKUNIT_ASSERT( node1 != NULL ); 00142 00143 STKUNIT_ASSERT_EQUAL( node0->sharing().size() , size_t(1) ); 00144 STKUNIT_ASSERT_EQUAL( node1->sharing().size() , size_t(1) ); 00145 } 00146 00147 // Test no-op first: 00148 00149 std::vector<EntityProc> change ; 00150 00151 STKUNIT_ASSERT( m_bulk_data.modification_begin() ); 00152 m_bulk_data.change_entity_owner( change ); 00153 STKUNIT_ASSERT( UnitTestBulkData::modification_end( m_bulk_data , generate_aura ) ); 00154 00155 stk::mesh::count_entities( select_used , m_bulk_data , local_count ); 00156 STKUNIT_ASSERT( local_count[0] == nLocalNode ); 00157 STKUNIT_ASSERT( local_count[1] == nLocalEdge ); 00158 00159 stk::mesh::count_entities( select_all , m_bulk_data , local_count ); 00160 STKUNIT_ASSERT( local_count[0] == nLocalNode + n_extra ); 00161 STKUNIT_ASSERT( local_count[1] == nLocalEdge + n_extra ); 00162 00163 // Make sure that edge->owner_rank() == edge->node[1]->owner_rank() 00164 if ( 1 < p_size ) { 00165 Entity * const e_node_0 = m_bulk_data.get_entity( 0 , m_node_ids[id_begin] ); 00166 if ( p_rank == e_node_0->owner_rank() ) { 00167 EntityProc entry ; 00168 entry.first = e_node_0 ; 00169 entry.second = ( p_rank + p_size - 1 ) % p_size ; 00170 change.push_back( entry ); 00171 } 00172 STKUNIT_ASSERT( m_bulk_data.modification_begin() ); 00173 m_bulk_data.change_entity_owner( change ); 00174 STKUNIT_ASSERT( UnitTestBulkData::modification_end( m_bulk_data , generate_aura ) ); 00175 00176 stk::mesh::count_entities( select_all , m_bulk_data , local_count ); 00177 STKUNIT_ASSERT( local_count[0] == nLocalNode + n_extra ); 00178 STKUNIT_ASSERT( local_count[1] == nLocalEdge + n_extra ); 00179 00180 stk::mesh::count_entities( select_used , m_bulk_data , local_count ); 00181 STKUNIT_ASSERT( local_count[0] == nLocalNode ); 00182 STKUNIT_ASSERT( local_count[1] == nLocalEdge ); 00183 00184 stk::mesh::count_entities( select_owned , m_bulk_data , local_count ); 00185 STKUNIT_ASSERT( local_count[0] == nPerProc ); 00186 STKUNIT_ASSERT( local_count[1] == nPerProc ); 00187 } 00188 } 00189 00190 00191 void UnitTestRingMeshFixture::test_shift_loop( bool generate_aura ) 00192 { 00193 const unsigned p_rank = m_bulk_data.parallel_rank(); 00194 const unsigned p_size = m_bulk_data.parallel_size(); 00195 const unsigned nPerProc = m_num_edge_per_proc ; 00196 const unsigned id_total = nPerProc * p_size ; 00197 const unsigned id_begin = nPerProc * p_rank ; 00198 const unsigned id_end = nPerProc * ( p_rank + 1 ); 00199 const unsigned nLocalNode = nPerProc + ( 1 < p_size ? 1 : 0 ); 00200 const unsigned nLocalEdge = nPerProc ; 00201 00202 const unsigned p_send = ( p_rank + 1 ) % p_size ; 00203 const unsigned id_send = id_end - 2 ; 00204 const unsigned id_recv = ( id_begin + id_total - 2 ) % id_total ; 00205 00206 Selector select_used = m_meta_data.locally_owned_part() | 00207 m_meta_data.globally_shared_part(); 00208 00209 std::vector<unsigned> local_count ; 00210 std::vector<EntityProc> change ; 00211 00212 Entity * send_edge_1 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_send ] ); 00213 Entity * send_edge_2 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_send + 1 ] ); 00214 Entity * send_node_1 = send_edge_1->relations()[1].entity(); 00215 Entity * send_node_2 = send_edge_2->relations()[1].entity(); 00216 Entity * recv_edge_1 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_recv ] ); 00217 Entity * recv_edge_2 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_recv + 1 ] ); 00218 00219 STKUNIT_ASSERT( NULL != send_edge_1 && p_rank == send_edge_1->owner_rank() ); 00220 STKUNIT_ASSERT( NULL != send_edge_2 && p_rank == send_edge_2->owner_rank() ); 00221 STKUNIT_ASSERT( NULL == recv_edge_1 || p_rank != recv_edge_1->owner_rank() ); 00222 STKUNIT_ASSERT( NULL == recv_edge_2 || p_rank != recv_edge_2->owner_rank() ); 00223 00224 if ( p_rank == send_node_1->owner_rank() ) { 00225 EntityProc entry( send_node_1 , p_send ); 00226 change.push_back( entry ); 00227 } 00228 if ( p_rank == send_node_2->owner_rank() ) { 00229 EntityProc entry( send_node_2 , p_send ); 00230 change.push_back( entry ); 00231 } 00232 { 00233 EntityProc entry( send_edge_1 , p_send ); 00234 change.push_back( entry ); 00235 } 00236 { 00237 EntityProc entry( send_edge_2 , p_send ); 00238 change.push_back( entry ); 00239 } 00240 00241 send_edge_1 = NULL ; 00242 send_edge_2 = NULL ; 00243 send_node_1 = NULL ; 00244 send_node_2 = NULL ; 00245 recv_edge_1 = NULL ; 00246 recv_edge_2 = NULL ; 00247 00248 STKUNIT_ASSERT( m_bulk_data.modification_begin() ); 00249 m_bulk_data.change_entity_owner( change ); 00250 STKUNIT_ASSERT( UnitTestBulkData::modification_end( m_bulk_data , generate_aura ) ); 00251 00252 send_edge_1 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_send ] ); 00253 send_edge_2 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_send + 1 ] ); 00254 recv_edge_1 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_recv ] ); 00255 recv_edge_2 = m_bulk_data.get_entity( 1 , m_edge_ids[ id_recv + 1 ] ); 00256 00257 STKUNIT_ASSERT( NULL == send_edge_1 || p_rank != send_edge_1->owner_rank() ); 00258 STKUNIT_ASSERT( NULL == send_edge_2 || p_rank != send_edge_2->owner_rank() ); 00259 STKUNIT_ASSERT( NULL != recv_edge_1 && p_rank == recv_edge_1->owner_rank() ); 00260 STKUNIT_ASSERT( NULL != recv_edge_2 && p_rank == recv_edge_2->owner_rank() ); 00261 00262 stk::mesh::count_entities( select_used , m_bulk_data , local_count ); 00263 STKUNIT_ASSERT( local_count[0] == nLocalNode ); 00264 STKUNIT_ASSERT( local_count[1] == nLocalEdge ); 00265 00266 unsigned count_shared = 0 ; 00267 for ( std::vector<Entity*>::const_iterator 00268 i = m_bulk_data.entity_comm().begin() ; 00269 i != m_bulk_data.entity_comm().end() ; ++i ) { 00270 if ( in_shared( **i ) ) { ++count_shared ; } 00271 } 00272 STKUNIT_ASSERT( count_shared == 2u ); 00273 00274 { 00275 Entity * const node_recv = m_bulk_data.get_entity( m_top_data.node_rank , m_node_ids[id_recv] ); 00276 Entity * const node_send = m_bulk_data.get_entity( m_top_data.node_rank , m_node_ids[id_send] ); 00277 00278 STKUNIT_ASSERT( node_recv->sharing().size() == 1 ); 00279 STKUNIT_ASSERT( node_send->sharing().size() == 1 ); 00280 } 00281 } 00282