Sierra Toolkit  Version of the Day
Bucket.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 #include <stdlib.h>
10 #include <memory.h>
11 
12 #include <stdexcept>
13 #include <iostream>
14 #include <sstream>
15 #include <algorithm>
16 
17 #include <stk_mesh/base/Bucket.hpp>
18 #include <stk_mesh/base/Entity.hpp>
19 #include <stk_mesh/base/BulkData.hpp>
20 #include <stk_mesh/base/MetaData.hpp>
21 #include <stk_mesh/base/FieldData.hpp>
22 
23 namespace stk_classic {
24 namespace mesh {
25 
26 //----------------------------------------------------------------------
27 
28 bool bucket_part_equal( const unsigned * lhs , const unsigned * rhs )
29 {
30  bool result = true ;
31  {
32  const unsigned * const end_lhs = lhs + *lhs ;
33  while ( result && end_lhs != lhs ) {
34  result = *lhs == *rhs ;
35  ++lhs ; ++rhs ;
36  }
37  }
38  return result ;
39 }
40 
41 inline
42 bool bucket_key_less( const unsigned * lhs , const unsigned * rhs )
43 {
44  const unsigned * const last_lhs = lhs + ( *lhs < *rhs ? *lhs : *rhs );
45  while ( last_lhs != lhs && *lhs == *rhs ) { ++lhs ; ++rhs ; }
46  return *lhs < *rhs ;
47 }
48 
49 // The part count and part ordinals are less
50 bool BucketLess::operator()( const Bucket * lhs_bucket ,
51  const unsigned * rhs ) const
52 { return bucket_key_less( lhs_bucket->key() , rhs ); }
53 
54 bool BucketLess::operator()( const unsigned * lhs ,
55  const Bucket * rhs_bucket ) const
56 { return bucket_key_less( lhs , rhs_bucket->key() ); }
57 
58 //----------------------------------------------------------------------
59 
60 bool Bucket::member( const Part & part ) const
61 {
62  const unsigned * const i_beg = key() + 1 ;
63  const unsigned * const i_end = key() + key()[0] ;
64 
65  const unsigned ord = part.mesh_meta_data_ordinal();
66  const unsigned * const i = std::lower_bound( i_beg , i_end , ord );
67 
68  return i_end != i && ord == *i ;
69 }
70 
71 bool Bucket::member_all( const PartVector & parts ) const
72 {
73  const unsigned * const i_beg = key() + 1 ;
74  const unsigned * const i_end = key() + key()[0] ;
75 
76  const PartVector::const_iterator ip_end = parts.end();
77  PartVector::const_iterator ip = parts.begin() ;
78 
79  bool result_all = true ;
80 
81  for ( ; result_all && ip_end != ip ; ++ip ) {
82  const unsigned ord = (*ip)->mesh_meta_data_ordinal();
83  const unsigned * const i = std::lower_bound( i_beg , i_end , ord );
84  result_all = i_end != i && ord == *i ;
85  }
86  return result_all ;
87 }
88 
89 bool Bucket::member_any( const PartVector & parts ) const
90 {
91  const unsigned * const i_beg = key() + 1 ;
92  const unsigned * const i_end = key() + key()[0] ;
93 
94  const PartVector::const_iterator ip_end = parts.end();
95  PartVector::const_iterator ip = parts.begin() ;
96 
97  bool result_none = true ;
98 
99  for ( ; result_none && ip_end != ip ; ++ip ) {
100  const unsigned ord = (*ip)->mesh_meta_data_ordinal();
101  const unsigned * const i = std::lower_bound( i_beg , i_end , ord );
102  result_none = i_end == i || ord != *i ;
103  }
104  return ! result_none ;
105 }
106 
107 bool Bucket::member_any( const OrdinalVector & parts ) const
108 {
109  const unsigned * const i_beg = key() + 1 ;
110  const unsigned * const i_end = key() + key()[0] ;
111 
112  const OrdinalVector::const_iterator ip_end = parts.end();
113  OrdinalVector::const_iterator ip = parts.begin() ;
114 
115  bool result_none = true ;
116 
117  for ( ; result_none && ip_end != ip ; ++ip ) {
118  const unsigned ord = *ip;
119  const unsigned * const i = std::lower_bound( i_beg , i_end , ord );
120  result_none = i_end == i || ord != *i ;
121  }
122  return ! result_none ;
123 }
124 
125 //----------------------------------------------------------------------
126 
127 bool has_superset( const Bucket & bucket, const unsigned & ordinal )
128 {
129  std::pair<const unsigned *, const unsigned *>
130  part_ord = bucket.superset_part_ordinals();
131 
132  part_ord.first =
133  std::lower_bound( part_ord.first , part_ord.second , ordinal );
134 
135  return part_ord.first < part_ord.second && ordinal == *part_ord.first ;
136 }
137 
138 bool has_superset( const Bucket & bucket , const Part & p )
139 {
140  const unsigned ordinal = p.mesh_meta_data_ordinal();
141  return has_superset(bucket,ordinal);
142 }
143 
144 bool has_superset( const Bucket & bucket , const PartVector & ps )
145 {
146  const std::pair<const unsigned *, const unsigned *>
147  part_ord = bucket.superset_part_ordinals();
148 
149  bool result = ! ps.empty();
150 
151  for ( PartVector::const_iterator
152  i = ps.begin() ; result && i != ps.end() ; ++i ) {
153 
154  const unsigned ordinal = (*i)->mesh_meta_data_ordinal();
155 
156  const unsigned * iter =
157  std::lower_bound( part_ord.first , part_ord.second , ordinal );
158 
159  result = iter < part_ord.second && ordinal == *iter ;
160  }
161  return result ;
162 }
163 
164 void Bucket::supersets( PartVector & ps ) const
165 {
166  const MetaData & mesh_meta_data = MetaData::get( *this );
167 
168  std::pair<const unsigned *, const unsigned *>
169  part_ord = superset_part_ordinals();
170 
171  ps.resize( part_ord.second - part_ord.first );
172 
173  for ( unsigned i = 0 ;
174  part_ord.first < part_ord.second ; ++(part_ord.first) , ++i ) {
175  ps[i] = & mesh_meta_data.get_part( * part_ord.first );
176  }
177 }
178 
179 void Bucket::supersets( OrdinalVector & ps ) const
180 {
181  std::pair<const unsigned *, const unsigned *>
182  part_ord = superset_part_ordinals();
183 
184  ps.resize( part_ord.second - part_ord.first );
185 
186  for ( unsigned i = 0 ;
187  part_ord.first < part_ord.second ; ++(part_ord.first) , ++i ) {
188  ps[i] = *part_ord.first;
189  }
190 }
191 
192 //----------------------------------------------------------------------
193 
194 bool field_data_valid( const FieldBase & f ,
195  const Bucket & k ,
196  unsigned ord ,
197  const char * required_by )
198 {
199  const MetaData * const k_mesh_meta_data = & MetaData::get(k);
200  const MetaData * const f_mesh_meta_data = & MetaData::get(f);
201  const bool ok_mesh_meta_data = k_mesh_meta_data == f_mesh_meta_data ;
202  const bool ok_ord = ord < k.size() ;
203  const bool exists = ok_mesh_meta_data && ok_ord &&
204  NULL != field_data( f , k.begin() );
205 
206  if ( required_by && ! exists ) {
207  std::ostringstream msg_begin ;
208  msg_begin << "For args: " ;
209  msg_begin << f << " , " ;
210  msg_begin << k << " , " ;
211  msg_begin << ord << " , " ;
212  msg_begin << required_by ;
213  msg_begin << "; operation FAILED with " ;
214  ThrowErrorMsgIf( ! ok_mesh_meta_data,
215  msg_begin.str() << " different MetaData");
216  ThrowErrorMsgIf( ! ok_ord, msg_begin.str() <<
217  " Ordinal " << ord << " >= " << " size " << k.size());
218  ThrowErrorMsg( msg_begin.str() << " no data");
219  }
220 
221  return exists ;
222 }
223 
224 //----------------------------------------------------------------------
226  // test equivalent() method
227  const Bucket* bucket = this;
228  const Bucket * first = m_bucketImpl.first_bucket_in_family();
229  if (!first || ! bucket->equivalent(*first) || ! first->equivalent(*bucket) )
230  return false;
231 
232  // other tests...
233 
234  return true;
235 }
236 
237 //----------------------------------------------------------------------
238 
239 std::ostream & operator << ( std::ostream & s , const Bucket & k )
240 {
241  const MetaData & mesh_meta_data = MetaData::get(k);
242  const std::string & entity_rank_name =
243  k.entity_rank() == InvalidEntityRank ? "Nil" :
244  mesh_meta_data.entity_rank_names()[ k.entity_rank() ];
245 
246  PartVector parts ; k.supersets( parts );
247 
248  s << "Bucket( " << entity_rank_name << " : " ;
249  for ( PartVector::iterator i = parts.begin() ; i != parts.end() ; ++i ) {
250  s << (*i)->name() << " " ;
251  }
252  s << ")" ;
253 
254  return s ;
255 }
256 
257 
258 std::ostream &
259 print( std::ostream & os , const std::string & indent , const Bucket & bucket )
260 {
261  const MetaData & mesh_meta_data = MetaData::get(bucket);
262  const std::string & entity_rank_name =
263  bucket.entity_rank() == InvalidEntityRank ? "Nil" :
264  mesh_meta_data.entity_rank_names()[ bucket.entity_rank() ];
265 
266  const std::pair<const unsigned *, const unsigned *>
267  part_ids = bucket.superset_part_ordinals();
268 
269  os << "Bucket(" << std::endl << indent << "Part intersection {" ;
270 
271  for ( const unsigned * i = part_ids.first ; i < part_ids.second ; ++i ) {
272  const Part & part = mesh_meta_data.get_part( *i );
273  os << " " << part.name();
274  }
275 
276  os << " }" << std::endl << indent << entity_rank_name << " members {" ;
277 
278  for ( unsigned j = 0 ; j < bucket.size() ; ++j ) {
279  const EntityId id = bucket[j].identifier();
280  os << " " << id ;
281  }
282  os << " } )" << std::endl ;
283 
284  return os ;
285 }
286 
287 } // namespace mesh
288 } // namespace stk_classic
289 
std::ostream & print(std::ostream &os, const std::string &indent, const Bucket &bucket)
Print the parts and entities of this bucket.
Definition: Bucket.cpp:259
Field base class with an anonymous data type and anonymous multi-dimension.
Definition: FieldBase.hpp:53
The manager of an integrated collection of parts and fields.
Definition: MetaData.hpp:56
bool assert_correct() const
A method to assist in unit testing - accesses private data as necessary.
Definition: Bucket.cpp:225
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
Definition: FieldData.hpp:116
bool member_all(const PartVector &) const
Bucket is a subset of all of the given parts.
Definition: Bucket.cpp:71
bool member_any(const PartVector &) const
Bucket is a subset of any of the given parts.
Definition: Bucket.cpp:89
Part * get_part(const std::string &p_name, const char *required_by=NULL) const
Get an existing part by its application-defined text name.
Definition: MetaData.cpp:185
std::pair< const unsigned *, const unsigned * > superset_part_ordinals() const
Definition: Bucket.hpp:188
An application-defined subset of a problem domain.
Definition: Part.hpp:49
size_t size() const
Number of entities associated with this bucket.
Definition: Bucket.hpp:119
const std::string & name() const
Application-defined text name of this part.
Definition: Part.hpp:67
unsigned mesh_meta_data_ordinal() const
Internally generated ordinal of this part that is unique within the owning meta data manager...
Definition: Part.hpp:72
iterator begin() const
Beginning of the bucket.
Definition: Bucket.hpp:113
bool field_data_valid(const FieldBase &f, const Bucket &k, unsigned ord, const char *required_by)
Check for existence of field data.
Definition: Bucket.cpp:194
Sierra Toolkit.
void supersets(PartVector &) const
This bucket is a subset of these parts.
Definition: Bucket.cpp:164
bool equivalent(const Bucket &b) const
Equivalent buckets have the same parts.
Definition: Bucket.hpp:192
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
Definition: Types.hpp:31
A container for the field data of a homogeneous collection of entities.
Definition: Bucket.hpp:94
bool member(const Part &) const
Bucket is a subset of the given part.
Definition: Bucket.cpp:60
bool has_superset(const Bucket &bucket, const PartVector &ps)
Is this bucket a subset of all of the given parts.
Definition: Bucket.cpp:144
unsigned entity_rank() const
Type of entities in this bucket.
Definition: Bucket.hpp:167