Sierra Toolkit Version of the Day
RingFixture.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_mesh/fixtures/RingFixture.hpp>
00010 
00011 #include <stk_util/parallel/Parallel.hpp>
00012 
00013 #include <stk_util/environment/ReportHandler.hpp>
00014 
00015 #include <stk_mesh/base/Types.hpp>
00016 #include <stk_mesh/base/MetaData.hpp>
00017 #include <stk_mesh/base/BulkData.hpp>
00018 #include <stk_mesh/base/MetaData.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 <Shards_BasicTopologies.hpp>
00024 
00025 namespace stk {
00026 namespace mesh {
00027 namespace fixtures {
00028 
00035 RingFixture::RingFixture( stk::ParallelMachine pm ,
00036                           unsigned num_edge_per_proc ,
00037                           bool use_edge_parts )
00038   : m_spatial_dimension(1),
00039     m_meta_data( m_spatial_dimension ),
00040     m_bulk_data( fem::FEMMetaData::get_meta_data(m_meta_data), pm, 100 ),
00041     m_edge_parts(),
00042     m_edge_part_extra( m_meta_data.declare_part("edge_extra" , m_meta_data.element_rank() ) ),
00043     m_num_edge_per_proc( num_edge_per_proc ),
00044     m_node_ids(),
00045     m_edge_ids()
00046 {
00047   if ( use_edge_parts ) {
00048     m_edge_parts.resize( num_edge_per_proc );
00049     for ( unsigned i = 0 ; i < num_edge_per_proc ; ++i ) {
00050       std::ostringstream name ;
00051       name << "EdgePart_" << i ;
00052       m_edge_parts[i] = & m_meta_data.declare_part( name.str() , m_meta_data.element_rank() );
00053     }
00054   }
00055 }
00056 
00057 void RingFixture::generate_mesh( )
00058 {
00059   const unsigned p_rank     = m_bulk_data.parallel_rank();
00060   const unsigned p_size     = m_bulk_data.parallel_size();
00061   const unsigned nPerProc   = m_num_edge_per_proc ;
00062   const unsigned id_total   = nPerProc * p_size ;
00063   const unsigned id_begin   = nPerProc * p_rank ;
00064   const unsigned id_end     = nPerProc * ( p_rank + 1 );
00065 
00066   m_node_ids.resize( id_total );
00067   m_edge_ids.resize( id_total );
00068   std::vector<unsigned> local_count ;
00069 
00070   for ( unsigned i = 0 ; i < id_total ; ++i ) {
00071     m_node_ids[i] = i + 1;
00072     m_edge_ids[i] = i + 1;
00073   }
00074 
00075   // Create a loop of edges:
00076   {
00077     const PartVector no_parts ;
00078     PartVector add_parts ;
00079 
00080     if ( ! m_edge_parts.empty() ) { add_parts.resize(1); }
00081 
00082     for ( unsigned i = id_begin ; i < id_end ; ++i ) {
00083       const unsigned n0 = i ;
00084       const unsigned n1 = ( i + 1 ) % id_total ;
00085       if ( ! m_edge_parts.empty() ) {
00086         add_parts[0] = m_edge_parts[ i % m_edge_parts.size() ];
00087       }
00088       Entity & e_node_0 = m_bulk_data.declare_entity( 0 , m_node_ids[n0] , no_parts );
00089       Entity & e_node_1 = m_bulk_data.declare_entity( 0 , m_node_ids[n1] , no_parts );
00090       Entity & e_edge   = m_bulk_data.declare_entity( 1 , m_edge_ids[i] , add_parts );
00091       m_bulk_data.declare_relation( e_edge , e_node_0 , 0 );
00092       m_bulk_data.declare_relation( e_edge , e_node_1 , 1 );
00093     }
00094   }
00095 }
00096 
00097 void RingFixture::fixup_node_ownership()
00098 {
00099   const unsigned p_rank     = m_bulk_data.parallel_rank();
00100   const unsigned p_size     = m_bulk_data.parallel_size();
00101   const unsigned nPerProc   = m_num_edge_per_proc ;
00102   const unsigned id_begin   = nPerProc * p_rank ;
00103 
00104   // Make sure that edge->owner_rank() == edge->node[1]->owner_rank()
00105 
00106   if ( 1 < p_size ) {
00107     std::vector<EntityProc> change ;
00108     Entity * const e_node_0 = m_bulk_data.get_entity( 0 , m_node_ids[id_begin] );
00109     if ( p_rank == e_node_0->owner_rank() ) {
00110       EntityProc entry ;
00111       entry.first = e_node_0 ;
00112       entry.second = ( p_rank + p_size - 1 ) % p_size ;
00113       change.push_back( entry );
00114     }
00115     m_bulk_data.change_entity_owner( change );
00116   }
00117 }
00118 
00119 }
00120 }
00121 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends