Sierra Toolkit Version of the Day
UnitTestRingMeshFixture.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 <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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends