|
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 //---------------------------------------------------------------------- 00018 00019 namespace stk { 00020 namespace mesh { 00021 namespace impl { 00022 00023 //---------------------------------------------------------------------- 00024 00025 namespace { 00026 00027 void memory_copy( unsigned char * dst , const unsigned char * src , unsigned n ) 00028 { std::memcpy( dst , src , n ); } 00029 00030 00031 void memory_zero( unsigned char * dst , unsigned n ) 00032 { std::memset( dst , 0 , n ); } 00033 00034 } // namespace 00035 00036 00037 00038 //---------------------------------------------------------------------- 00039 BucketImpl::BucketImpl( BulkData & arg_mesh , 00040 unsigned arg_entity_rank , 00041 const unsigned * arg_key , 00042 size_t arg_alloc_size , 00043 size_t arg_capacity , 00044 impl::BucketImpl::DataMap * arg_field_map , 00045 Entity ** arg_entity_array ) 00046 : m_mesh( arg_mesh ) , 00047 m_entity_rank( arg_entity_rank ) , 00048 m_key( arg_key ) , 00049 m_alloc_size( arg_alloc_size ) , 00050 m_capacity( arg_capacity ) , 00051 m_size( 0 ) , 00052 m_bucket() , 00053 m_field_map( arg_field_map ) , 00054 m_entities( arg_entity_array ) 00055 {} 00056 00057 00058 //---------------------------------------------------------------------- 00059 BucketImpl::~BucketImpl() 00060 { 00061 bool this_is_first_bucket_in_family = (bucket_counter() == 0); 00062 if (this_is_first_bucket_in_family) { 00063 try { 00064 std::free( m_field_map ); 00065 } catch(...) {} 00066 } 00067 } 00068 00069 //---------------------------------------------------------------------- 00070 00071 void BucketImpl::update_state() 00072 { 00073 bool this_is_first_bucket_in_family = ( bucket_counter() == 0 ); 00074 if (this_is_first_bucket_in_family) { 00075 00076 const MetaData & S = m_mesh.mesh_meta_data(); 00077 const std::vector<FieldBase*> & field_set = S.get_fields(); 00078 00079 for ( unsigned i = 0 ; i < field_set.size() ; ) { 00080 00081 DataMap * const tmp = m_field_map + i ; 00082 const FieldBase & field = * field_set[i] ; 00083 const unsigned num_state = field.number_of_states(); 00084 i += num_state ; 00085 00086 if ( 1 < num_state && tmp->m_size ) { 00087 unsigned offset[ MaximumFieldStates ] ; 00088 00089 for ( unsigned j = 0 ; j < num_state ; ++j ) { 00090 offset[j] = tmp[j].m_base ; 00091 } 00092 00093 for ( unsigned j = 0 ; j < num_state ; ++j ) { 00094 const unsigned j_new = ( j + num_state - 1 ) % num_state ; 00095 tmp[j_new].m_base = offset[j] ; 00096 } 00097 } 00098 } 00099 } 00100 } 00101 00102 //---------------------------------------------------------------------- 00103 // Every bucket in the family points to the first bucket, 00104 // except the first bucket which points to the last bucket. 00105 00106 Bucket * BucketImpl::last_bucket_in_family() 00107 { 00108 static const char method[] = "stk::mesh::impl::BucketImpl::last_bucket_in_family" ; 00109 00110 Bucket * last = last_bucket_in_family_impl(); 00111 00112 if ( NULL == last || 0 == last->size() ) { 00113 throw std::logic_error( std::string(method) ); 00114 } 00115 00116 return last ; 00117 } 00118 Bucket * BucketImpl::last_bucket_in_family_impl() 00119 { 00120 00121 bool this_is_first_bucket_in_family = (bucket_counter() == 0); 00122 00123 Bucket * last = NULL; 00124 00125 if (this_is_first_bucket_in_family) { 00126 last = m_bucket; 00127 } else { 00128 last = m_bucket->m_bucketImpl.m_bucket; 00129 } 00130 00131 return last; 00132 } 00133 00134 //---------------------------------------------------------------------- 00135 00136 Bucket * BucketImpl::first_bucket_in_family() 00137 { 00138 return last_bucket_in_family_impl()->m_bucketImpl.m_bucket; 00139 } 00140 00141 //---------------------------------------------------------------------- 00142 00143 void BucketImpl::set_last_bucket_in_family( Bucket * last_bucket ) 00144 { 00145 Bucket * last = last_bucket_in_family_impl(); 00146 Bucket * first = last->m_bucketImpl.m_bucket; 00147 first->m_bucketImpl.m_bucket = last_bucket; 00148 } 00149 00150 //---------------------------------------------------------------------- 00151 00152 void BucketImpl::set_first_bucket_in_family( Bucket * first_bucket ) 00153 { 00154 m_bucket = first_bucket; 00155 } 00156 00157 //---------------------------------------------------------------------- 00158 00159 BucketImpl::DataMap * BucketImpl::get_field_map() 00160 { 00161 return m_field_map; 00162 } 00163 00164 //---------------------------------------------------------------------- 00165 00166 void BucketImpl::zero_fields( unsigned i_dst ) 00167 { 00168 const std::vector<FieldBase*> & field_set = 00169 m_mesh.mesh_meta_data().get_fields(); 00170 00171 unsigned char * const p = reinterpret_cast<unsigned char*>(m_entities); 00172 const DataMap * i = m_field_map; 00173 const DataMap * const e = i + field_set.size(); 00174 00175 for ( ; i != e ; ++i ) { 00176 if ( i->m_size ) { 00177 memory_zero( p + i->m_base + i->m_size * i_dst , i->m_size ); 00178 } 00179 } 00180 } 00181 00182 void BucketImpl::replace_fields( unsigned i_dst , Bucket & k_src , unsigned i_src ) 00183 { 00184 static const char method[] = "stk::mesh::impl::BucketImpl::replace_fields" ; 00185 00186 const std::vector<FieldBase*> & field_set = 00187 m_mesh.mesh_meta_data().get_fields(); 00188 00189 unsigned char * const s = reinterpret_cast<unsigned char*>(k_src.m_bucketImpl.m_entities); 00190 unsigned char * const d = reinterpret_cast<unsigned char*>(m_entities); 00191 const DataMap * j = k_src.m_bucketImpl.m_field_map; 00192 const DataMap * i = m_field_map; 00193 const DataMap * const e = i + field_set.size(); 00194 00195 for ( ; i != e ; ++i , ++j ) { 00196 00197 if ( i->m_size ) { 00198 if ( j->m_size ) { 00199 if ( i->m_size == j->m_size ) { 00200 memory_copy( d + i->m_base + i->m_size * i_dst , 00201 s + j->m_base + j->m_size * i_src , i->m_size ); 00202 } 00203 else { 00204 std::ostringstream msg ; 00205 msg << method ; 00206 msg << " FAILED WITH INCOMPATIBLE FIELD SIZES" ; 00207 throw std::runtime_error( msg.str() ); 00208 } 00209 } 00210 else { 00211 memory_zero( d + i->m_base + i->m_size * i_dst , i->m_size ); 00212 } 00213 } 00214 } 00215 } 00216 00217 00218 00219 } // namespace impl 00220 } // namespace mesh 00221 } // namespace stk 00222 00223