Sierra Toolkit Version of the Day
BoxFixture.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 
00010 #include <stk_mesh/fixtures/BoxFixture.hpp>
00011 
00012 #include <stk_util/environment/ReportHandler.hpp>
00013 
00014 #include <stk_mesh/base/Types.hpp>
00015 #include <stk_mesh/base/MetaData.hpp>
00016 #include <stk_mesh/base/BulkData.hpp>
00017 #include <stk_mesh/base/GetEntities.hpp>
00018 #include <stk_mesh/base/Field.hpp>
00019 #include <stk_mesh/base/FieldData.hpp>
00020 #include <stk_mesh/base/Comm.hpp>
00021 #include <stk_mesh/base/GetBuckets.hpp>
00022 
00023 #include <stdexcept>
00024 
00025 namespace stk {
00026 namespace mesh {
00027 namespace fixtures {
00028 
00029 BoxFixture::BoxFixture( stk::ParallelMachine pm ,
00030                         unsigned block_size,
00031                         const std::vector<std::string>& entity_names )
00032   : m_fem_meta ( spatial_dimension, entity_names ),
00033     m_bulk_data ( fem::FEMMetaData::get_meta_data(m_fem_meta) , pm , block_size ),
00034     m_comm_rank( stk::parallel_machine_rank( pm ) ),
00035     m_comm_size( stk::parallel_machine_size( pm ) ),
00036     m_previous_state ( stk::mesh::BulkData::MODIFIABLE )
00037 {}
00038 
00039 Entity& BoxFixture::get_new_entity ( EntityRank rank , EntityId parallel_dependent_id )
00040 {
00041   return m_bulk_data.declare_entity ( rank , parallel_dependent_id*m_comm_size + m_comm_rank + 1 , std::vector<Part *> () );
00042 }
00043 
00044 void BoxFixture::generate_boxes( const BOX   root_box,
00045                                        BOX   local_box )
00046 {
00047   const unsigned p_rank = m_bulk_data.parallel_rank();
00048   const unsigned p_size = m_bulk_data.parallel_size();
00049   const unsigned ngx = root_box[0][1] - root_box[0][0] ;
00050   const unsigned ngy = root_box[1][1] - root_box[1][0] ;
00051 
00052   BOX * const p_box = new BOX[ p_size ];
00053 
00054   box_partition( 0 , p_size , 2 , root_box , & p_box[0] );
00055 
00056   local_box[0][0] = p_box[ p_rank ][0][0] ;
00057   local_box[0][1] = p_box[ p_rank ][0][1] ;
00058   local_box[1][0] = p_box[ p_rank ][1][0] ;
00059   local_box[1][1] = p_box[ p_rank ][1][1] ;
00060   local_box[2][0] = p_box[ p_rank ][2][0] ;
00061   local_box[2][1] = p_box[ p_rank ][2][1] ;
00062 
00063   // Create elements:
00064 
00065   std::vector<unsigned> local_count ;
00066 
00067   const stk::mesh::PartVector no_parts ;
00068 
00069   for ( int k = local_box[2][0] ; k < local_box[2][1] ; ++k ) {
00070   for ( int j = local_box[1][0] ; j < local_box[1][1] ; ++j ) {
00071   for ( int i = local_box[0][0] ; i < local_box[0][1] ; ++i ) {
00072     const EntityId n0= 1 + (i+0) + (j+0) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
00073     const EntityId n1= 1 + (i+1) + (j+0) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
00074     const EntityId n2= 1 + (i+1) + (j+1) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
00075     const EntityId n3= 1 + (i+0) + (j+1) * (ngx+1) + (k+0) * (ngx+1) * (ngy+1);
00076     const EntityId n4= 1 + (i+0) + (j+0) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
00077     const EntityId n5= 1 + (i+1) + (j+0) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
00078     const EntityId n6= 1 + (i+1) + (j+1) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
00079     const EntityId n7= 1 + (i+0) + (j+1) * (ngx+1) + (k+1) * (ngx+1) * (ngy+1);
00080 
00081     const EntityId elem_id =  1 + i + j * ngx + k * ngx * ngy;
00082 
00083     Entity & node0 = m_bulk_data.declare_entity( 0 , n0 , no_parts );
00084     Entity & node1 = m_bulk_data.declare_entity( 0 , n1 , no_parts );
00085     Entity & node2 = m_bulk_data.declare_entity( 0 , n2 , no_parts );
00086     Entity & node3 = m_bulk_data.declare_entity( 0 , n3 , no_parts );
00087     Entity & node4 = m_bulk_data.declare_entity( 0 , n4 , no_parts );
00088     Entity & node5 = m_bulk_data.declare_entity( 0 , n5 , no_parts );
00089     Entity & node6 = m_bulk_data.declare_entity( 0 , n6 , no_parts );
00090     Entity & node7 = m_bulk_data.declare_entity( 0 , n7 , no_parts );
00091     Entity & elem  = m_bulk_data.declare_entity( 3 , elem_id , no_parts );
00092 
00093     m_bulk_data.declare_relation( elem , node0 , 0 );
00094     m_bulk_data.declare_relation( elem , node1 , 1 );
00095     m_bulk_data.declare_relation( elem , node2 , 2 );
00096     m_bulk_data.declare_relation( elem , node3 , 3 );
00097     m_bulk_data.declare_relation( elem , node4 , 4 );
00098     m_bulk_data.declare_relation( elem , node5 , 5 );
00099     m_bulk_data.declare_relation( elem , node6 , 6 );
00100     m_bulk_data.declare_relation( elem , node7 , 7 );
00101   }
00102   }
00103   }
00104 
00105   delete[] p_box ;
00106 }
00107 
00108 void BoxFixture::box_partition( int ip , int up , int axis ,
00109                                 const BOX box ,
00110                                 BOX p_box[] )
00111 {
00112   const int np = up - ip ;
00113   if ( 1 == np ) {
00114     p_box[ip][0][0] = box[0][0] ; p_box[ip][0][1] = box[0][1] ;
00115     p_box[ip][1][0] = box[1][0] ; p_box[ip][1][1] = box[1][1] ;
00116     p_box[ip][2][0] = box[2][0] ; p_box[ip][2][1] = box[2][1] ;
00117   }
00118   else {
00119     const int n = box[ axis ][1] - box[ axis ][0] ;
00120     const int np_low = np / 2 ;  /* Rounded down */
00121     const int np_upp = np - np_low ;
00122 
00123     const int n_upp = (int) (((double) n) * ( ((double)np_upp) / ((double)np)));
00124     const int n_low = n - n_upp ;
00125     const int next_axis = ( axis + 2 ) % 3 ;
00126 
00127     if ( np_low ) { /* P = [ip,ip+np_low) */
00128       BOX dbox ;
00129       dbox[0][0] = box[0][0] ; dbox[0][1] = box[0][1] ;
00130       dbox[1][0] = box[1][0] ; dbox[1][1] = box[1][1] ;
00131       dbox[2][0] = box[2][0] ; dbox[2][1] = box[2][1] ;
00132 
00133       dbox[ axis ][1] = dbox[ axis ][0] + n_low ;
00134 
00135       box_partition( ip, ip + np_low, next_axis,
00136                      (const int (*)[2]) dbox, p_box );
00137     }
00138 
00139     if ( np_upp ) { /* P = [ip+np_low,ip+np_low+np_upp) */
00140       BOX dbox ;
00141       dbox[0][0] = box[0][0] ; dbox[0][1] = box[0][1] ;
00142       dbox[1][0] = box[1][0] ; dbox[1][1] = box[1][1] ;
00143       dbox[2][0] = box[2][0] ; dbox[2][1] = box[2][1] ;
00144 
00145       ip += np_low ;
00146       dbox[ axis ][0] += n_low ;
00147       dbox[ axis ][1]  = dbox[ axis ][0] + n_upp ;
00148 
00149       box_partition( ip, ip + np_upp, next_axis,
00150                      (const int (*)[2]) dbox, p_box );
00151     }
00152   }
00153 }
00154 
00155 }
00156 }
00157 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends