|
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 //---------------------------------------------------------------------- 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_classic { 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_classic