Sierra Toolkit Version of the Day
BucketImpl.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 <sstream>
00011 #include <cstdlib>
00012 #include <cstring>
00013 #include <stdexcept>
00014 #include <stk_mesh/baseImpl/BucketImpl.hpp>
00015 #include <stk_mesh/base/Bucket.hpp>
00016 #include <stk_mesh/base/BulkData.hpp>
00017 #include <stk_mesh/base/FindRestriction.hpp>
00018 //----------------------------------------------------------------------
00019 
00020 namespace stk {
00021 namespace mesh {
00022 namespace impl {
00023 
00024 //----------------------------------------------------------------------
00025 
00026 namespace {
00027 
00028 void memory_copy( unsigned char * dst , const unsigned char * src , unsigned n )
00029 { std::memcpy( dst , src , n ); }
00030 
00031 
00032 void memory_zero( unsigned char * dst , unsigned n )
00033 { std::memset( dst , 0 , n ); }
00034 
00035 } // namespace
00036 
00037 //----------------------------------------------------------------------
00038 
00039 void BucketImpl::update_state()
00040 {
00041   const MetaData & meta = MetaData::get(m_mesh);
00042   const std::vector<FieldBase*> & field_set = meta.get_fields();
00043 
00044   for ( unsigned i = 0 ; i < field_set.size() ; ) {
00045 
00046     DataMap * const tmp = &m_field_map[0] + i ;
00047     const FieldBase & field = * field_set[i] ;
00048     const unsigned num_state = field.number_of_states();
00049     i += num_state ;
00050 
00051     if ( 1 < num_state && tmp->m_size ) {
00052       unsigned offset[ MaximumFieldStates ] ;
00053 
00054       offset[0] = tmp[num_state-1].m_base;
00055       for ( unsigned j = 1 ; j < num_state ; ++j ) {
00056         offset[j] = tmp[j-1].m_base ;
00057       }
00058 
00059       for ( unsigned j = 0 ; j < num_state ; ++j ) {
00060         tmp[j].m_base = offset[j] ;
00061       }
00062     }
00063   }
00064 }
00065 
00066 //----------------------------------------------------------------------
00067 // Every bucket in the family points to the first bucket,
00068 // except the first bucket which points to the last bucket.
00069 
00070 Bucket * BucketImpl::last_bucket_in_family() const
00071 {
00072   Bucket * last = last_bucket_in_family_impl();
00073 
00074   ThrowRequireMsg( NULL != last, "Last is NULL");
00075   ThrowRequireMsg( last->size() != 0, "Last bucket is empty");
00076 
00077   return last ;
00078 }
00079 
00080 Bucket * BucketImpl::last_bucket_in_family_impl() const
00081 {
00082   bool this_is_first_bucket_in_family = (bucket_counter() == 0);
00083 
00084   Bucket * last = NULL;
00085 
00086   if (this_is_first_bucket_in_family) {
00087     last = m_bucket;
00088   } else {
00089     last = m_bucket->m_bucketImpl.m_bucket;
00090   }
00091 
00092   return last;
00093 }
00094 
00095 //----------------------------------------------------------------------
00096 
00097 Bucket * BucketImpl::first_bucket_in_family() const
00098 {
00099   return last_bucket_in_family_impl()->m_bucketImpl.m_bucket;
00100 }
00101 
00102 //----------------------------------------------------------------------
00103 
00104 void BucketImpl::set_last_bucket_in_family( Bucket * last_bucket )
00105 {
00106   Bucket * last = last_bucket_in_family_impl();
00107   Bucket * first = last->m_bucketImpl.m_bucket;
00108   first->m_bucketImpl.m_bucket = last_bucket;
00109 }
00110 
00111 //----------------------------------------------------------------------
00112 
00113 void BucketImpl::set_first_bucket_in_family( Bucket * first_bucket )
00114 {
00115   m_bucket = first_bucket;
00116 }
00117 
00118 //----------------------------------------------------------------------
00119 
00120 BucketImpl::DataMap * BucketImpl::get_field_map()
00121 {
00122   return &m_field_map[0];
00123 }
00124 
00125 //----------------------------------------------------------------------
00126 
00127 void BucketImpl::initialize_fields( unsigned i_dst )
00128 {
00129   const std::vector<FieldBase*> & field_set =
00130     MetaData::get(m_mesh).get_fields();
00131 
00132   unsigned char * const p = m_field_data;
00133   const DataMap *       i = &m_field_map[0];
00134   const DataMap * const e = i + field_set.size();
00135 
00136   for (std::vector<FieldBase*>::const_iterator field_iter=field_set.begin() ;
00137        i != e ; ++i, ++field_iter ) {
00138 
00139     if (i->m_size == 0) {
00140       continue;
00141     }
00142 
00143     const unsigned char* init_val = reinterpret_cast<const unsigned char*>((*field_iter)->get_initial_value());
00144     if (init_val != NULL) {
00145       memory_copy( p + i->m_base + i->m_size * i_dst , init_val, i->m_size );
00146     }
00147     else {
00148       memory_zero( p + i->m_base + i->m_size * i_dst , i->m_size );
00149     }
00150   }
00151 }
00152 
00153 void BucketImpl::replace_fields( unsigned i_dst , Bucket & k_src , unsigned i_src )
00154 {
00155   const std::vector<FieldBase*> & field_set =
00156     MetaData::get(m_mesh).get_fields();
00157 
00158   unsigned char * const s = k_src.m_bucketImpl.m_field_data;
00159   unsigned char * const d = m_field_data;
00160   const DataMap *       j = &(k_src.m_bucketImpl.m_field_map[0]);
00161   const DataMap *       i = &m_field_map[0];
00162   const DataMap * const e = i + field_set.size();
00163 
00164   for (std::vector<FieldBase*>::const_iterator field_iter=field_set.begin() ;
00165        i != e ; ++i , ++j, ++field_iter ) {
00166 
00167     if ( i->m_size ) {
00168       if ( j->m_size ) {
00169         ThrowAssertMsg( i->m_size == j->m_size,
00170             "Incompatible field sizes: " << i->m_size << " != " << j->m_size );
00171 
00172         memory_copy( d + i->m_base + i->m_size * i_dst ,
00173                      s + j->m_base + j->m_size * i_src , i->m_size );
00174       }
00175       else {
00176         const unsigned char* init_val = reinterpret_cast<const unsigned char*>((*field_iter)->get_initial_value());
00177         if (init_val != NULL) {
00178           memory_copy( d + i->m_base + i->m_size * i_dst ,
00179                        init_val, i->m_size );
00180         }
00181         else {
00182           memory_zero( d + i->m_base + i->m_size * i_dst , i->m_size );
00183         }
00184       }
00185     }
00186   }
00187 }
00188 
00189 //----------------------------------------------------------------------
00190 namespace {
00191 inline unsigned align( size_t nb )
00192 {
00193   enum { BYTE_ALIGN = 16 };
00194   const unsigned gap = nb % BYTE_ALIGN ;
00195   if ( gap ) { nb += BYTE_ALIGN - gap ; }
00196   return nb ;
00197 }
00198 }//namespace anonymous
00199 
00200 //----------------------------------------------------------------------
00201 
00202 BucketImpl::BucketImpl( BulkData & arg_mesh,
00203                         EntityRank arg_entity_rank,
00204                         const std::vector<unsigned> & arg_key,
00205                         size_t arg_capacity
00206                       )
00207   : m_mesh(arg_mesh)
00208   , m_entity_rank(arg_entity_rank)
00209   , m_key(arg_key)
00210   , m_capacity(arg_capacity)
00211   , m_size(0)
00212   , m_bucket(NULL)
00213   , m_field_map( m_mesh.mesh_meta_data().get_fields().size()+1)
00214   , m_entities(arg_capacity)
00215   , m_field_data(NULL)
00216   , m_field_data_end(NULL)
00217 {
00218   //calculate the size of the field_data
00219 
00220   const std::vector< FieldBase * > & field_set =
00221     arg_mesh.mesh_meta_data().get_fields();
00222 
00223   const size_t num_fields = field_set.size();
00224 
00225   size_t field_data_size = 0;
00226 
00227   if (arg_capacity != 0) {
00228     for ( size_t i = 0; i<num_fields; ++i) {
00229       const FieldBase  & field = * field_set[i] ;
00230       unsigned num_bytes_per_entity = 0 ;
00231 
00232       const FieldBase::Restriction & restriction =
00233         find_restriction( field, arg_entity_rank, &m_key[1], &m_key[1]+(m_key[0]-1), PartOrdLess());
00234 
00235       if ( restriction.dimension() > 0 ) { // Exists
00236 
00237         const unsigned type_stride = field.data_traits().stride_of ;
00238         const unsigned field_rank  = field.rank();
00239 
00240         num_bytes_per_entity = type_stride *
00241           ( field_rank ? restriction.stride( field_rank - 1 ) : 1 );
00242       }
00243       m_field_map[i].m_base = field_data_size ;
00244       m_field_map[i].m_size = num_bytes_per_entity ;
00245       m_field_map[i].m_stride = &restriction.stride(0);
00246 
00247       field_data_size += align( num_bytes_per_entity * m_capacity );
00248     }
00249 
00250     m_field_map[ num_fields ].m_base  = field_data_size ;
00251     m_field_map[ num_fields ].m_size = 0 ;
00252     m_field_map[ num_fields ].m_stride = NULL ;
00253   }
00254   else { //nil bucket
00255 
00256     FieldBase::Restriction::size_type empty_stride[ MaximumFieldDimension ];
00257     Copy<MaximumFieldDimension>( empty_stride , FieldBase::Restriction::size_type(0) );
00258 
00259     for ( size_t i = 0; i<num_fields; ++i) {
00260       m_field_map[i].m_base = 0 ;
00261       m_field_map[i].m_size = 0 ;
00262       m_field_map[i].m_stride = empty_stride;
00263     }
00264     m_field_map[ num_fields ].m_base   = 0 ;
00265     m_field_map[ num_fields ].m_size   = 0 ;
00266     m_field_map[ num_fields ].m_stride = NULL ;
00267   }
00268 
00269   //allocate space for the fields
00270   m_field_data = field_data_size > 0 ? new unsigned char[field_data_size] : NULL;
00271 
00272   //
00273   //[TODO] ALAN, TODD: to investigate if memory_zero is necessary to fix valgrind
00274   //issues in the following regression test:
00275   //adagio_rtest/presto/super_elem_rigid_body/super_elem_rigid_body.test|np1_explicit_reverseMPC
00276   //memory_zero(m_field_data, field_data_size);
00277   //ABW UPDATE: found and fixed bug in strumento/src/element/SuperElementHandler.C
00278   //which was reading past end of field, so this memory_zero is no longer
00279   //necessary. 8/9/2012
00280   //std::memset( m_field_data , 0xfff , field_data_size );
00281 
00282   m_field_data_end = m_field_data + field_data_size;
00283 }
00284 
00285 } // namespace impl
00286 } // namespace mesh
00287 } // namespace stk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines