9 #include <stk_mesh/baseImpl/FieldBaseImpl.hpp> 17 #include <stk_util/util/SimpleArrayOps.hpp> 19 #include <stk_mesh/base/Types.hpp> 20 #include <stk_mesh/base/FieldBase.hpp> 21 #include <stk_mesh/base/Part.hpp> 22 #include <stk_mesh/base/MetaData.hpp> 23 #include <stk_mesh/base/Trace.hpp> 33 FieldRestrictionVector::const_iterator
34 find(
const FieldRestrictionVector & v ,
const FieldRestriction & restr )
36 FieldRestrictionVector::const_iterator
37 i = std::lower_bound( v.begin() , v.end() , restr );
39 if ( i != v.end() && !(*i == restr) ) { i = v.end(); }
48 FieldBaseImpl::FieldBaseImpl(
49 MetaData * arg_mesh_meta_data ,
50 unsigned arg_ordinal ,
51 const std::string & arg_name ,
52 const DataTraits & arg_traits ,
54 const shards::ArrayDimTag *
const * arg_dim_tags,
55 unsigned arg_number_of_states ,
60 m_data_traits( arg_traits ),
61 m_meta_data( arg_mesh_meta_data ),
62 m_ordinal( arg_ordinal ),
63 m_num_states( arg_number_of_states ),
64 m_this_state( arg_this_state ),
65 m_field_rank( arg_rank ),
67 m_selector_restrictions(),
68 m_initial_value(NULL),
69 m_initial_value_num_bytes(0)
71 TraceIfWatching(
"stk_classic::mesh::impl::FieldBaseImpl::FieldBaseImpl", LOG_FIELD, m_ordinal);
73 FieldBase *
const pzero = NULL ;
74 const shards::ArrayDimTag *
const dzero = NULL ;
75 Copy<MaximumFieldStates>( m_field_states , pzero );
76 Copy<MaximumFieldDimension>( m_dim_tags , dzero );
78 for (
unsigned i = 0 ; i < arg_rank ; ++i ) {
79 m_dim_tags[i] = arg_dim_tags[i];
84 FieldBaseImpl::~FieldBaseImpl()
87 void*& init_val = m_initial_value;
89 delete []
reinterpret_cast<char*
>(init_val);
95 const FieldRestrictionVector & FieldBaseImpl::restrictions()
const 96 {
return m_field_states[0]->m_impl.m_dim_map ; }
98 const FieldRestrictionVector & FieldBaseImpl::selector_restrictions()
const 99 {
return m_field_states[0]->m_impl.m_selector_restrictions ; }
101 FieldRestrictionVector & FieldBaseImpl::restrictions()
102 {
return m_field_states[0]->m_impl.m_dim_map ; }
104 FieldRestrictionVector & FieldBaseImpl::selector_restrictions()
105 {
return m_field_states[0]->m_impl.m_selector_restrictions ; }
115 void FieldBaseImpl::insert_restriction(
116 const char * arg_method ,
117 EntityRank arg_entity_rank ,
118 const Part & arg_part ,
119 const unsigned * arg_stride,
120 const void* arg_init_value )
122 TraceIfWatching(
"stk_classic::mesh::impl::FieldBaseImpl::insert_restriction", LOG_FIELD, m_ordinal);
124 FieldRestriction tmp( arg_entity_rank , arg_part.mesh_meta_data_ordinal() );
128 if ( m_field_rank ) {
129 for ( i = 0 ; i < m_field_rank ; ++i ) { tmp.stride(i) = arg_stride[i] ; }
136 for ( ; i < MaximumFieldDimension ; ++i ) {
137 tmp.stride(i) = tmp.stride(i-1) ;
140 for ( i = 1 ; i < m_field_rank ; ++i ) {
141 const bool bad_stride = 0 == tmp.stride(i) ||
142 0 != tmp.stride(i) % tmp.stride(i-1);
143 ThrowErrorMsgIf( bad_stride,
144 arg_method <<
" FAILED for " << *
this <<
145 " WITH BAD STRIDE " <<
146 print_restriction( tmp, arg_entity_rank, arg_part, m_field_rank ));;
150 if (arg_init_value != NULL) {
165 size_t num_scalars = 1;
168 if (m_field_rank > 0) num_scalars = tmp.stride(m_field_rank-1);
170 size_t sizeof_scalar = m_data_traits.size_of;
171 size_t nbytes = sizeof_scalar * num_scalars;
173 size_t old_nbytes = 0;
174 if (get_initial_value() != NULL) {
175 old_nbytes = get_initial_value_num_bytes();
178 if (nbytes > old_nbytes) {
179 set_initial_value(arg_init_value, num_scalars, nbytes);
184 FieldRestrictionVector & restrs = restrictions();
186 FieldRestrictionVector::iterator restr = restrs.begin();
187 FieldRestrictionVector::iterator last_restriction = restrs.end();
189 restr = std::lower_bound(restr,last_restriction,tmp);
191 const bool new_restriction = ( ( restr == last_restriction ) || !(*restr == tmp) );
193 if ( new_restriction ) {
195 ThrowRequireMsg(!m_meta_data->is_commit(),
"mesh MetaData has been committed.");
196 unsigned num_subsets = 0;
197 for(FieldRestrictionVector::iterator i=restrs.begin(), iend=restrs.end(); i!=iend; ++i) {
198 if (i->entity_rank() != arg_entity_rank)
continue;
200 const Part& partI = *m_meta_data->get_parts()[i->part_ordinal()];
201 bool found_subset =
contain(arg_part.subsets(), partI);
203 ThrowErrorMsgIf( i->not_equal_stride(tmp),
204 arg_method <<
" FAILED for " << *
this <<
" " <<
205 print_restriction( *i, arg_entity_rank, arg_part, m_field_rank ) <<
206 " WITH INCOMPATIBLE REDECLARATION " <<
207 print_restriction( tmp, arg_entity_rank, arg_part, m_field_rank ));
212 bool found_superset =
contain(arg_part.supersets(), partI);
213 if (found_superset) {
214 ThrowErrorMsgIf( i->not_equal_stride(tmp),
215 arg_method <<
" FAILED for " << *
this <<
" " <<
216 print_restriction( *i, arg_entity_rank, arg_part, m_field_rank ) <<
217 " WITH INCOMPATIBLE REDECLARATION " <<
218 print_restriction( tmp, arg_entity_rank, arg_part, m_field_rank ));
224 if (num_subsets == 0) {
225 restrs.insert( restr , tmp );
230 std::sort(restrs.begin(), restrs.end());
231 FieldRestrictionVector::iterator it = std::unique(restrs.begin(), restrs.end());
232 restrs.resize(it - restrs.begin());
236 ThrowErrorMsgIf( restr->not_equal_stride(tmp),
237 arg_method <<
" FAILED for " << *
this <<
" " <<
238 print_restriction( *restr, arg_entity_rank, arg_part, m_field_rank ) <<
239 " WITH INCOMPATIBLE REDECLARATION " <<
240 print_restriction( tmp, arg_entity_rank, arg_part, m_field_rank ));
245 void FieldBaseImpl::insert_restriction(
246 const char * arg_method ,
247 EntityRank arg_entity_rank ,
248 const Selector & arg_selector ,
249 const unsigned * arg_stride,
250 const void* arg_init_value )
252 TraceIfWatching(
"stk_classic::mesh::impl::FieldBaseImpl::insert_restriction", LOG_FIELD, m_ordinal);
254 FieldRestriction tmp( arg_entity_rank , arg_selector );
258 if ( m_field_rank ) {
259 for ( i = 0 ; i < m_field_rank ; ++i ) { tmp.stride(i) = arg_stride[i] ; }
266 for ( ; i < MaximumFieldDimension ; ++i ) {
267 tmp.stride(i) = tmp.stride(i-1) ;
270 for ( i = 1 ; i < m_field_rank ; ++i ) {
271 const bool bad_stride = 0 == tmp.stride(i) ||
272 0 != tmp.stride(i) % tmp.stride(i-1);
273 ThrowErrorMsgIf( bad_stride,
274 arg_method <<
" FAILED for " << *
this <<
275 " WITH BAD STRIDE!");
279 if (arg_init_value != NULL) {
294 size_t num_scalars = 1;
297 if (m_field_rank > 0) num_scalars = tmp.stride(m_field_rank-1);
299 size_t sizeof_scalar = m_data_traits.size_of;
300 size_t nbytes = sizeof_scalar * num_scalars;
302 size_t old_nbytes = 0;
303 if (get_initial_value() != NULL) {
304 old_nbytes = get_initial_value_num_bytes();
307 if (nbytes > old_nbytes) {
308 set_initial_value(arg_init_value, num_scalars, nbytes);
313 FieldRestrictionVector & srvec = selector_restrictions();
315 bool restriction_already_exists =
false;
316 for(FieldRestrictionVector::const_iterator it=srvec.begin(), it_end=srvec.end();
319 restriction_already_exists =
true;
320 if (tmp.not_equal_stride(*it)) {
321 ThrowErrorMsg(
"Incompatible selector field-restrictions!");
326 if ( !restriction_already_exists ) {
328 ThrowRequireMsg(!m_meta_data->is_commit(),
"mesh MetaData has been committed.");
329 srvec.push_back( tmp );
334 void FieldBaseImpl::verify_and_clean_restrictions(
335 const char * arg_method ,
336 const Part& superset,
340 TraceIfWatching(
"stk_classic::mesh::impl::FieldBaseImpl::verify_and_clean_restrictions", LOG_FIELD, m_ordinal);
342 FieldRestrictionVector & restrs = restrictions();
346 FieldRestrictionVector::iterator superset_restriction = restrs.end();
347 FieldRestrictionVector::iterator subset_restriction = restrs.end();
348 for (FieldRestrictionVector::iterator i = restrs.begin() ; i != restrs.end() ; ++i ) {
349 if (i->part_ordinal() == superset.mesh_meta_data_ordinal()) {
350 superset_restriction = i;
351 if (subset_restriction != restrs.end() && subset_restriction->entity_rank() == superset_restriction->entity_rank())
break;
353 if (i->part_ordinal() == subset.mesh_meta_data_ordinal()) {
354 subset_restriction = i;
355 if (superset_restriction != restrs.end() && subset_restriction->entity_rank() == superset_restriction->entity_rank())
break;
359 if (superset_restriction != restrs.end() && subset_restriction != restrs.end() &&
360 superset_restriction->entity_rank() == subset_restriction->entity_rank()) {
361 ThrowErrorMsgIf( superset_restriction->not_equal_stride(*subset_restriction),
362 "Incompatible field restrictions for parts "<<superset.name()<<
" and "<<subset.name());
364 restrs.erase(subset_restriction);
368 const void* FieldBaseImpl::get_initial_value()
const 370 return m_field_states[0]->m_impl.m_initial_value;
373 void* FieldBaseImpl::get_initial_value() {
374 return m_field_states[0]->m_impl.m_initial_value;
377 unsigned FieldBaseImpl::get_initial_value_num_bytes()
const {
378 return m_field_states[0]->m_impl.m_initial_value_num_bytes;
381 void FieldBaseImpl::set_initial_value(
const void* new_initial_value,
unsigned num_scalars,
unsigned num_bytes) {
382 void*& init_val = m_field_states[0]->m_impl.m_initial_value;
384 delete []
reinterpret_cast<char*
>(init_val);
385 init_val =
new char[num_bytes];
387 m_field_states[0]->m_impl.m_initial_value_num_bytes = num_bytes;
389 m_data_traits.copy(init_val, new_initial_value, num_scalars);
397 const FieldRestriction &
398 FieldBaseImpl::restriction(
unsigned entity_rank ,
const Part & part )
const 400 static const FieldRestriction empty ;
402 const FieldRestrictionVector & rMap = restrictions();
403 const FieldRestrictionVector::const_iterator ie = rMap.end() ;
404 FieldRestrictionVector::const_iterator i ;
406 const PartVector::const_iterator ipe = part.supersets().end();
407 PartVector::const_iterator ip = part.supersets().begin() ;
411 static FieldRestriction restr;
413 restr.set_part_ordinal( part.mesh_meta_data_ordinal() );
415 while ( ie == ( i =
find( rMap , restr ) ) && ipe != ip ) {
418 restr.set_part_ordinal( (*ip)->mesh_meta_data_ordinal() );
422 return ie == i ? empty : *i ;
425 unsigned FieldBaseImpl::max_size(
unsigned entity_rank )
const 429 const FieldRestrictionVector & rMap = restrictions();
430 const FieldRestrictionVector::const_iterator ie = rMap.end() ;
431 FieldRestrictionVector::const_iterator i = rMap.begin();
433 for ( ; i != ie ; ++i ) {
435 const unsigned len = m_field_rank ? i->stride( m_field_rank - 1 ) : 1 ;
436 if ( max < len ) { max = len ; }
443 void FieldBaseImpl::set_field_states( FieldBase ** field_states)
445 TraceIfWatching(
"stk_classic::mesh::impl::FieldBaseImpl::set_field_states", LOG_FIELD, m_ordinal);
447 for (
unsigned i = 0; i < m_num_states; ++i) {
448 m_field_states[i] = field_states[i];
456 std::ostream & operator << ( std::ostream & s ,
const FieldBaseImpl & field )
458 s <<
"FieldBaseImpl<" ;
459 s << field.data_traits().name ;
460 for (
unsigned i = 0 ; i < field.rank() ; ++i ) {
461 s <<
"," << field.dimension_tags()[i]->name();
467 s <<
"\" , #states = " ;
468 s << field.number_of_states();
473 std::ostream &
print( std::ostream & s ,
474 const char *
const b ,
475 const FieldBase & field )
477 const PartVector & all_parts = MetaData::get(field).get_parts();
478 const std::vector<FieldBase::Restriction> & rMap = field.restrictions();
481 for ( FieldBase::RestrictionVector::const_iterator
482 i = rMap.begin() ; i != rMap.end() ; ++i ) {
483 s << std::endl << b <<
" " ;
484 i->print( s, i->entity_rank(), * all_parts[ i->part_ordinal() ], field.rank() );
487 s << std::endl << b <<
"}" ;
std::ostream & print(std::ostream &os, const std::string &indent, const Bucket &bucket)
Print the parts and entities of this bucket.
bool contain(const PartVector &v, const Part &part)
Query containment within properly ordered PartVector.
State of a field with one state.
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Part * find(const PartVector &parts, const std::string &name)
Find a part by name in a collection of parts.
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).
FieldState
Enumeration of states for multi-state fields.