Sierra Toolkit  Version of the Day
BucketImpl.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 //----------------------------------------------------------------------
10 #include <sstream>
11 #include <cstdlib>
12 #include <cstring>
13 #include <stdexcept>
14 #include <stk_mesh/baseImpl/BucketImpl.hpp>
15 #include <stk_mesh/base/Bucket.hpp>
16 #include <stk_mesh/base/BulkData.hpp>
17 #include <stk_mesh/base/FindRestriction.hpp>
18 //----------------------------------------------------------------------
19 
20 namespace stk_classic {
21 namespace mesh {
22 namespace impl {
23 
24 //----------------------------------------------------------------------
25 
26 namespace {
27 
28 void memory_copy( unsigned char * dst , const unsigned char * src , unsigned n )
29 { std::memcpy( dst , src , n ); }
30 
31 
32 void memory_zero( unsigned char * dst , unsigned n )
33 { std::memset( dst , 0 , n ); }
34 
35 } // namespace
36 
37 //----------------------------------------------------------------------
38 
39 void BucketImpl::update_state()
40 {
41  const MetaData & meta = MetaData::get(m_mesh);
42  const std::vector<FieldBase*> & field_set = meta.get_fields();
43 
44  for ( unsigned i = 0 ; i < field_set.size() ; ) {
45 
46  DataMap * const tmp = &m_field_map[0] + i ;
47  const FieldBase & field = * field_set[i] ;
48  const unsigned num_state = field.number_of_states();
49  i += num_state ;
50 
51  if ( 1 < num_state && tmp->m_size ) {
52  unsigned offset[ MaximumFieldStates ] ;
53 
54  offset[0] = tmp[num_state-1].m_base;
55  for ( unsigned j = 1 ; j < num_state ; ++j ) {
56  offset[j] = tmp[j-1].m_base ;
57  }
58 
59  for ( unsigned j = 0 ; j < num_state ; ++j ) {
60  tmp[j].m_base = offset[j] ;
61  }
62  }
63  }
64 }
65 
66 //----------------------------------------------------------------------
67 // Every bucket in the family points to the first bucket,
68 // except the first bucket which points to the last bucket.
69 
70 Bucket * BucketImpl::last_bucket_in_family() const
71 {
72  Bucket * last = last_bucket_in_family_impl();
73 
74  ThrowRequireMsg( NULL != last, "Last is NULL");
75  ThrowRequireMsg( last->size() != 0, "Last bucket is empty");
76 
77  return last ;
78 }
79 
80 Bucket * BucketImpl::last_bucket_in_family_impl() const
81 {
82  bool this_is_first_bucket_in_family = (bucket_counter() == 0);
83 
84  Bucket * last = NULL;
85 
86  if (this_is_first_bucket_in_family) {
87  last = m_bucket;
88  } else {
89  last = m_bucket->m_bucketImpl.m_bucket;
90  }
91 
92  return last;
93 }
94 
95 //----------------------------------------------------------------------
96 
97 Bucket * BucketImpl::first_bucket_in_family() const
98 {
99  return last_bucket_in_family_impl()->m_bucketImpl.m_bucket;
100 }
101 
102 //----------------------------------------------------------------------
103 
104 void BucketImpl::set_last_bucket_in_family( Bucket * last_bucket )
105 {
106  Bucket * last = last_bucket_in_family_impl();
107  Bucket * first = last->m_bucketImpl.m_bucket;
108  first->m_bucketImpl.m_bucket = last_bucket;
109 }
110 
111 //----------------------------------------------------------------------
112 
113 void BucketImpl::set_first_bucket_in_family( Bucket * first_bucket )
114 {
115  m_bucket = first_bucket;
116 }
117 
118 //----------------------------------------------------------------------
119 
120 BucketImpl::DataMap * BucketImpl::get_field_map()
121 {
122  return &m_field_map[0];
123 }
124 
125 //----------------------------------------------------------------------
126 
127 void BucketImpl::initialize_fields( unsigned i_dst )
128 {
129  const std::vector<FieldBase*> & field_set =
130  MetaData::get(m_mesh).get_fields();
131 
132  unsigned char * const p = m_field_data;
133  const DataMap * i = &m_field_map[0];
134  const DataMap * const e = i + field_set.size();
135 
136  for (std::vector<FieldBase*>::const_iterator field_iter=field_set.begin() ;
137  i != e ; ++i, ++field_iter ) {
138 
139  if (i->m_size == 0) {
140  continue;
141  }
142 
143  const unsigned char* init_val = reinterpret_cast<const unsigned char*>((*field_iter)->get_initial_value());
144  if (init_val != NULL) {
145  memory_copy( p + i->m_base + i->m_size * i_dst , init_val, i->m_size );
146  }
147  else {
148  memory_zero( p + i->m_base + i->m_size * i_dst , i->m_size );
149  }
150  }
151 }
152 
153 void BucketImpl::replace_fields( unsigned i_dst , Bucket & k_src , unsigned i_src )
154 {
155  const std::vector<FieldBase*> & field_set =
156  MetaData::get(m_mesh).get_fields();
157 
158  unsigned char * const s = k_src.m_bucketImpl.m_field_data;
159  unsigned char * const d = m_field_data;
160  const DataMap * j = &(k_src.m_bucketImpl.m_field_map[0]);
161  const DataMap * i = &m_field_map[0];
162  const DataMap * const e = i + field_set.size();
163 
164  for (std::vector<FieldBase*>::const_iterator field_iter=field_set.begin() ;
165  i != e ; ++i , ++j, ++field_iter ) {
166 
167  if ( i->m_size ) {
168  if ( j->m_size ) {
169  ThrowAssertMsg( i->m_size == j->m_size,
170  "Incompatible field sizes: " << i->m_size << " != " << j->m_size );
171 
172  memory_copy( d + i->m_base + i->m_size * i_dst ,
173  s + j->m_base + j->m_size * i_src , i->m_size );
174  }
175  else {
176  const unsigned char* init_val = reinterpret_cast<const unsigned char*>((*field_iter)->get_initial_value());
177  if (init_val != NULL) {
178  memory_copy( d + i->m_base + i->m_size * i_dst ,
179  init_val, i->m_size );
180  }
181  else {
182  memory_zero( d + i->m_base + i->m_size * i_dst , i->m_size );
183  }
184  }
185  }
186  }
187 }
188 
189 //----------------------------------------------------------------------
190 namespace {
191 inline unsigned align( size_t nb )
192 {
193  enum { BYTE_ALIGN = 16 };
194  const unsigned gap = nb % BYTE_ALIGN ;
195  if ( gap ) { nb += BYTE_ALIGN - gap ; }
196  return nb ;
197 }
198 }//namespace anonymous
199 
200 //----------------------------------------------------------------------
201 
202 BucketImpl::BucketImpl( BulkData & arg_mesh,
203  EntityRank arg_entity_rank,
204  const std::vector<unsigned> & arg_key,
205  size_t arg_capacity
206  )
207  : m_mesh(arg_mesh)
208  , m_entity_rank(arg_entity_rank)
209  , m_key(arg_key)
210  , m_capacity(arg_capacity)
211  , m_size(0)
212  , m_bucket(NULL)
213  , m_field_map( m_mesh.mesh_meta_data().get_fields().size()+1)
214  , m_entities(arg_capacity)
215  , m_field_data(NULL)
216  , m_field_data_end(NULL)
217 {
218  //calculate the size of the field_data
219 
220  const std::vector< FieldBase * > & field_set =
221  arg_mesh.mesh_meta_data().get_fields();
222 
223  const size_t num_fields = field_set.size();
224 
225  size_t field_data_size = 0;
226 
227  if (arg_capacity != 0) {
228  for ( size_t i = 0; i<num_fields; ++i) {
229  const FieldBase & field = * field_set[i] ;
230  unsigned num_bytes_per_entity = 0 ;
231 
232  const FieldBase::Restriction & restriction =
233  find_restriction( field, arg_entity_rank, &m_key[1], &m_key[1]+(m_key[0]-1), PartOrdLess());
234 
235  if ( restriction.dimension() > 0 ) { // Exists
236 
237  const unsigned type_stride = field.data_traits().stride_of ;
238  const unsigned field_rank = field.rank();
239 
240  num_bytes_per_entity = type_stride *
241  ( field_rank ? restriction.stride( field_rank - 1 ) : 1 );
242  }
243  m_field_map[i].m_base = field_data_size ;
244  m_field_map[i].m_size = num_bytes_per_entity ;
245  m_field_map[i].m_stride = &restriction.stride(0);
246 
247  field_data_size += align( num_bytes_per_entity * m_capacity );
248  }
249 
250  m_field_map[ num_fields ].m_base = field_data_size ;
251  m_field_map[ num_fields ].m_size = 0 ;
252  m_field_map[ num_fields ].m_stride = NULL ;
253  }
254  else { //nil bucket
255 
256  FieldBase::Restriction::size_type empty_stride[ MaximumFieldDimension ];
257  Copy<MaximumFieldDimension>( empty_stride , FieldBase::Restriction::size_type(0) );
258 
259  for ( size_t i = 0; i<num_fields; ++i) {
260  m_field_map[i].m_base = 0 ;
261  m_field_map[i].m_size = 0 ;
262  m_field_map[i].m_stride = empty_stride;
263  }
264  m_field_map[ num_fields ].m_base = 0 ;
265  m_field_map[ num_fields ].m_size = 0 ;
266  m_field_map[ num_fields ].m_stride = NULL ;
267  }
268 
269  //allocate space for the fields
270  m_field_data = field_data_size > 0 ? new unsigned char[field_data_size] : NULL;
271 
272  //
273  //[TODO] ALAN, TODD: to investigate if memory_zero is necessary to fix valgrind
274  //issues in the following regression test:
275  //adagio_rtest/presto/super_elem_rigid_body/super_elem_rigid_body.test|np1_explicit_reverseMPC
276  //memory_zero(m_field_data, field_data_size);
277  //ABW UPDATE: found and fixed bug in strumento/src/element/SuperElementHandler.C
278  //which was reading past end of field, so this memory_zero is no longer
279  //necessary. 8/9/2012
280  //std::memset( m_field_data , 0xfff , field_data_size );
281 
282  m_field_data_end = m_field_data + field_data_size;
283 }
284 
285 } // namespace impl
286 } // namespace mesh
287 } // namespace stk_classic
unsigned field_data_size(const FieldBase &field) const
Query the size of this field data specified by FieldBase.
Definition: Bucket.hpp:128
Sierra Toolkit.