Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
moab::ReorderTool Class Reference

#include <ReorderTool.hpp>

+ Collaboration diagram for moab::ReorderTool:

Public Member Functions

 ReorderTool (Core *moab)
 
ErrorCode handle_order_from_int_tag (Tag ordering_tag, int ordering_tag_skip_value, Tag &new_handle_tag_out)
 Calculate new handle order by tag value. More...
 
ErrorCode handle_order_from_int_tag (EntityType type, int vals_per_ent, Tag ordering_tag, int ordering_tag_skip_value, Tag new_handle_tag)
 Calculate new handle order by tag value. More...
 
ErrorCode handle_order_from_sets_and_adj (const Range &sets, Tag &new_handle_tag_out)
 Calculate new handle order by set containment. More...
 
ErrorCode reorder_entities (Tag new_handle_tag)
 Do the re-ordering indicated by the passed handle tag. More...
 

Private Member Functions

ErrorCode reorder_tag_data (EntityType type, Tag new_handles, Tag reorder_tag)
 helper function for reorder_entities More...
 
ErrorCode update_set_contents (Tag new_handles)
 helper function for reorder_entities More...
 
void get_entities (EntityType t, int vals_per_ent, Range &result)
 Get all entities of specified type and size. More...
 
ErrorCode get_reordered_handles (Tag tag, const Range &old_handles, std::vector< EntityHandle > &new_handles)
 Get new handles corresponding to old handles. More...
 
ErrorCode get_reordered_handles (Tag tag, const std::vector< EntityHandle > &old_handles, std::vector< EntityHandle > &new_handles)
 Get new handles corresponding to old handles. More...
 
ErrorCode get_reordered_handles (Tag tag, const EntityHandle *old_handles, EntityHandle *new_handles, size_t num_handles)
 Get new handles corresponding to old handles. More...
 
ErrorCode get_new_handles (Tag tag, Range &old_handles, std::vector< EntityHandle > &newhandles)
 Remove any non-ordered handles and return new handles for remaining. More...
 
ErrorCode int_order_from_sets_and_adj (const Range &sets, Tag order_tag, int skip_val, std::vector< std::vector< EntityHandle > * > &data)
 convert from input for handle_order_from_sets_and_adj to input for handle_order_from_int_tag More...
 

Private Attributes

CoremMB
 

Detailed Description

Definition at line 18 of file ReorderTool.hpp.

Constructor & Destructor Documentation

◆ ReorderTool()

moab::ReorderTool::ReorderTool ( Core moab)
inline

Definition at line 21 of file ReorderTool.hpp.

21 : mMB( moab ) {}

Member Function Documentation

◆ get_entities()

void moab::ReorderTool::get_entities ( EntityType  t,
int  vals_per_ent,
Range result 
)
private

Get all entities of specified type and size.

Parameters
tthe type of entity to retreive
vals_per_ententity size (connectivity length for elements, dimension for vertices)

Definition at line 101 of file ReorderTool.cpp.

102 {
103  Range::iterator hint = entities.begin();
104  ;
105  TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
107  for( s = seqs.begin(); s != seqs.end(); ++s )
108  {
109  EntitySequence* seq = *s;
110  if( seq->values_per_entity() == vals_per_ent )
111  hint = entities.insert( hint, seq->start_handle(), seq->end_handle() );
112  }
113 }

References moab::TypeSequenceManager::begin(), moab::TypeSequenceManager::end(), moab::EntitySequence::end_handle(), entities, moab::SequenceManager::entity_map(), mMB, moab::Core::sequence_manager(), moab::EntitySequence::start_handle(), t, and moab::EntitySequence::values_per_entity().

Referenced by handle_order_from_int_tag(), and reorder_entities().

◆ get_new_handles()

ErrorCode moab::ReorderTool::get_new_handles ( Tag  tag,
Range old_handles,
std::vector< EntityHandle > &  newhandles 
)
private

Remove any non-ordered handles and return new handles for remaining.

Parameters
tagTag containing old->new mapping

Definition at line 372 of file ReorderTool.cpp.

373 {
374  // get new handles for tagged entities
375  newhandles.resize( old_handles.size() );
376  ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( newhandles.empty() ) ? NULL : &newhandles[0] );CHKERR;
377 
378  // remove entities that were not reordered
379  Range::iterator i = old_handles.begin();
380  size_t w = 0;
381  for( size_t r = 0; r < newhandles.size(); ++r )
382  {
383  if( 0 != newhandles[r] )
384  {
385  newhandles[w] = newhandles[r];
386  ++w;
387  ++i;
388  }
389  else
390  {
391  i = old_handles.erase( i );
392  }
393  }
394  newhandles.resize( w );
395  assert( newhandles.size() == old_handles.size() );
396  return MB_SUCCESS;
397 }

References moab::Range::begin(), CHKERR, moab::Range::erase(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().

Referenced by reorder_tag_data(), and update_set_contents().

◆ get_reordered_handles() [1/3]

ErrorCode moab::ReorderTool::get_reordered_handles ( Tag  tag,
const EntityHandle old_handles,
EntityHandle new_handles,
size_t  num_handles 
)
private

Get new handles corresponding to old handles.

Parameters
tagTag containing old->new mapping

Definition at line 359 of file ReorderTool.cpp.

363 {
364  ErrorCode rval = mMB->tag_get_data( tag, old_handles, num_handles, new_handles );CHKERR;
365 
366  for( size_t i = 0; i < num_handles; ++i )
367  if( 0 == new_handles[i] ) new_handles[i] = old_handles[i];
368 
369  return MB_SUCCESS;
370 }

References CHKERR, ErrorCode, MB_SUCCESS, mMB, and moab::Core::tag_get_data().

◆ get_reordered_handles() [2/3]

ErrorCode moab::ReorderTool::get_reordered_handles ( Tag  tag,
const Range old_handles,
std::vector< EntityHandle > &  new_handles 
)
private

Get new handles corresponding to old handles.

Parameters
tagTag containing old->new mapping

Definition at line 336 of file ReorderTool.cpp.

339 {
340  new_handles.resize( old_handles.size() );
341  ErrorCode rval = mMB->tag_get_data( tag, old_handles, ( new_handles.empty() ) ? NULL : &new_handles[0] );CHKERR;
342 
343  Range::const_iterator it1 = old_handles.begin();
344  std::vector< EntityHandle >::iterator it2 = new_handles.begin();
345  for( ; it1 != old_handles.end(); ++it1, ++it2 )
346  if( 0 == *it2 ) *it2 = *it1;
347 
348  return MB_SUCCESS;
349 }

References moab::Range::begin(), CHKERR, moab::Range::end(), ErrorCode, MB_SUCCESS, mMB, moab::Range::size(), and moab::Core::tag_get_data().

Referenced by get_reordered_handles(), reorder_entities(), reorder_tag_data(), and update_set_contents().

◆ get_reordered_handles() [3/3]

ErrorCode moab::ReorderTool::get_reordered_handles ( Tag  tag,
const std::vector< EntityHandle > &  old_handles,
std::vector< EntityHandle > &  new_handles 
)
private

Get new handles corresponding to old handles.

Parameters
tagTag containing old->new mapping

Definition at line 351 of file ReorderTool.cpp.

354 {
355  new_handles.resize( old_handles.size() );
356  return get_reordered_handles( tag, &old_handles[0], &new_handles[0], old_handles.size() );
357 }

References get_reordered_handles().

◆ handle_order_from_int_tag() [1/2]

ErrorCode moab::ReorderTool::handle_order_from_int_tag ( EntityType  type,
int  vals_per_ent,
Tag  ordering_tag,
int  ordering_tag_skip_value,
Tag  new_handle_tag 
)

Calculate new handle order by tag value.

Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.

Parameters
typeEntity type for which to calculate re-ordering.
vals_per_entZero for vertices. Connectivity length for elements.
ordering_tagSinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values.
ordering_tag_skip_valueDo not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set.
new_handle_tagTag into which to store new handle for each entity. Tag must be defined to store a single entity handle and must have a default value of zero.

Definition at line 115 of file ReorderTool.cpp.

120 {
121  ErrorCode rval;
122 
123  // check that input tag handles are what we expect
124  rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
125  rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
126 
127  // get entities to re-order
128  Range entities;
129  get_entities( t, vals_per_ent, entities );
130 
131  // get entity order values
132  std::vector< int > sortvals( entities.size() );
133  rval = mMB->tag_get_data( tag, entities, &sortvals[0] );CHKERR;
134 
135  // remove any entities for which value is skip_value
136  size_t r = 0, w = 0;
137  for( Range::iterator i = entities.begin(); i != entities.end(); ++r )
138  {
139  if( sortvals[r] == skip_value )
140  i = entities.erase( i );
141  else
142  {
143  sortvals[w++] = sortvals[r];
144  ++i;
145  }
146  }
147  sortvals.resize( w );
148 
149  // sort
150  std::sort( sortvals.begin(), sortvals.end() );
151  // Convert to unique list and offsets for each value
152  // When done, sortvals will contain unique, sortvals and
153  // offsets will contain, for each unique value in sortvals,
154  // the number of values that occured in the non-unique list
155  // before the first instance of that value.
156  std::vector< size_t > offsets;
157  offsets.push_back( 0 );
158  offsets.push_back( 1 );
159  for( w = 0, r = 1; r < sortvals.size(); ++r )
160  {
161  if( sortvals[r] == sortvals[w] )
162  {
163  ++offsets.back();
164  }
165  else
166  {
167  ++w;
168  sortvals[w] = sortvals[r];
169  offsets.push_back( offsets.back() + 1 );
170  }
171  }
172  ++w;
173  assert( w + 1 == offsets.size() );
174  sortvals.resize( w );
175 
176  // Tag each entity with its new handle
177  for( Range::iterator i = entities.begin(); i != entities.end(); ++i )
178  {
179  int val;
180  rval = mMB->tag_get_data( tag, &*i, 1, &val );CHKERR;
181  w = std::lower_bound( sortvals.begin(), sortvals.end(), val ) - sortvals.begin();
182  assert( w < sortvals.size() );
183  size_t offset = offsets[w];
184  ++offsets[w];
185  // should maybe copy range into array to avoid possibly n^2 behavior here
186  EntityHandle h = *( entities.begin() + offset );
187  rval = mMB->tag_set_data( new_handles, &*i, 1, &h );CHKERR;
188  }
189 
190  return MB_SUCCESS;
191 }

References moab::check_tag_type(), CHKERR, entities, ErrorCode, get_entities(), MB_SUCCESS, MB_TYPE_HANDLE, MB_TYPE_INTEGER, mMB, t, moab::Core::tag_get_data(), and moab::Core::tag_set_data().

◆ handle_order_from_int_tag() [2/2]

ErrorCode moab::ReorderTool::handle_order_from_int_tag ( Tag  ordering_tag,
int  ordering_tag_skip_value,
Tag new_handle_tag_out 
)

Calculate new handle order by tag value.

Given a tag containing integer values, calculate new order for entities in the database (except entity sets) such that all entities with tag value A occur before all entities with tag value B in the handle space where A < B. Ordering will be stable for entities with the same tag value.

Parameters
ordering_tagSinlge integer tag, where value on each entity determines the new position in the handle ordering. Entities may have duplicate values.
ordering_tag_skip_valueDo not reorder entities with this tag value. This is typically the default value of ordering_tag. Specifying this limits the re-ordering to only those entities for which ordering_tag has been set.
new_handle_tag_outPassed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered.

Definition at line 59 of file ReorderTool.cpp.

60 {
61  ErrorCode rval;
62 
63  // check that input tag handles are what we expect
64  rval = check_tag_type( mMB, tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
65  EntityHandle zero = 0;
66  rval = mMB->tag_get_handle( 0, 1, MB_TYPE_HANDLE, new_handles, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &zero );CHKERR;
67 
68  // Can only reorder within same type/connectivity (or vertex/num_coords)
69  // groupings. Call helper function for each such grouping.
70  for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
71  {
72  // Get list of all connectivity lengths (or vertex dimensions)
73  // that exist for type t.
74  TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
76  std::set< int > values;
77  for( i = seqs.begin(); i != seqs.end(); ++i )
78  {
79  EntitySequence* seq = *i;
80  // 0 values per entity implies structured data, which
81  // we cannot reorder. Skip those.
82  if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
83  }
84 
85  // Call helper function for each (type,size) tuple.
86  std::set< int >::iterator j;
87  for( j = values.begin(); j != values.end(); ++j )
88  {
89  rval = handle_order_from_int_tag( t, *j, tag, skip_value, new_handles );
90  if( MB_SUCCESS != rval )
91  {
92  mMB->tag_delete( new_handles );
93  return error( rval );
94  }
95  }
96  }
97 
98  return MB_SUCCESS;
99 }

References moab::TypeSequenceManager::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), moab::SequenceManager::entity_map(), moab::error(), ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MBENTITYSET, MBVERTEX, mMB, moab::Core::sequence_manager(), t, moab::Core::tag_delete(), moab::Core::tag_get_handle(), and moab::EntitySequence::values_per_entity().

Referenced by handle_order_from_sets_and_adj(), and main().

◆ handle_order_from_sets_and_adj()

ErrorCode moab::ReorderTool::handle_order_from_sets_and_adj ( const Range sets,
Tag new_handle_tag_out 
)

Calculate new handle order by set containment.

Given a list of sets, re-order entities such that handles are grouped contiguously by set. Will also group all adjacent mesh entities, such that entities that are are adjacent to members of two or more of the input sets will ge grouped by the combined list of sets (e.g. if the input sets contain elements then all vertices that are adjacent to only elements in the first two sets will be grouped together).

Parameters
setsEntity sets by which to group entities.
new_handle_tag_outPassed back new tag handle containing the entity mapping. The returned tag will be anonymous. The caller is responsible for releasing the tag. The value of this tag on each handle is the new handle that the entity will will be moved to. The tag value will be zero for entities that were not re-ordered.

Definition at line 193 of file ReorderTool.cpp.

194 {
195  ErrorCode rval;
196 
197  if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
198 
199  Tag order_tag;
200  const int negone = -1;
201  rval = mMB->tag_get_handle( 0, 1, MB_TYPE_INTEGER, order_tag, MB_TAG_DENSE | MB_TAG_CREAT | MB_TAG_EXCL, &negone );
202  if( MB_SUCCESS != rval )
203  {
204  mMB->tag_delete( handle_tag );
205  handle_tag = 0;
206  return error( rval );
207  }
208 
209  std::vector< std::vector< EntityHandle >* > data;
210  rval = int_order_from_sets_and_adj( sets, order_tag, negone, data );
211  for( size_t i = 0; i < data.size(); ++i )
212  delete data[i];
213  if( MB_SUCCESS != rval )
214  {
215  mMB->tag_delete( order_tag );
216  return error( rval );
217  }
218 
219  rval = handle_order_from_int_tag( order_tag, negone, handle_tag );
220  if( MB_SUCCESS != rval )
221  {
222  mMB->tag_delete( order_tag );
223  return error( rval );
224  }
225 
226  rval = mMB->tag_delete( order_tag );
227  if( MB_SUCCESS != rval ) return error( rval );
228 
229  return MB_SUCCESS;
230 }

References moab::Range::all_of_type(), moab::error(), ErrorCode, handle_order_from_int_tag(), int_order_from_sets_and_adj(), MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, mMB, moab::Core::tag_delete(), and moab::Core::tag_get_handle().

Referenced by main().

◆ int_order_from_sets_and_adj()

ErrorCode moab::ReorderTool::int_order_from_sets_and_adj ( const Range sets,
Tag  order_tag,
int  skip_val,
std::vector< std::vector< EntityHandle > * > &  data 
)
private

convert from input for handle_order_from_sets_and_adj to input for handle_order_from_int_tag

Definition at line 249 of file ReorderTool.cpp.

253 {
254  ErrorCode rval;
255 
256  if( !sets.all_of_type( MBENTITYSET ) ) return MB_TYPE_OUT_OF_RANGE;
257 
258  rval = check_tag_type( mMB, order_tag, MB_TYPE_INTEGER, sizeof( int ) );CHKERR;
259 
260  // Compare function to use for a map keyed on pointers to sorted vectors
261  CompSortedVect lessthan;
262  // Map from sorted list of handles to index
263  std::map< std::vector< EntityHandle >*, int, CompSortedVect > forMap;
264  std::map< std::vector< EntityHandle >*, int, CompSortedVect >::iterator fiter, fiter2;
265  std::vector< EntityHandle > sharing; // tmp storage for entity
266 
267  // for each set
268  for( Range::iterator s = sets.begin(); s != sets.end(); ++s )
269  {
270 
271  // gather up all entities and adjacencies
272  Range tmp, ents, adj[4]; // indexed by dimension
273  for( int dim = 0; dim < 4; ++dim )
274  {
275  rval = mMB->get_entities_by_dimension( *s, dim, tmp );CHKERR;
276  for( int ldim = 0; ldim < dim; ++ldim )
277  {
278  rval = mMB->get_adjacencies( tmp, ldim, false, adj[ldim], Interface::UNION );CHKERR;
279  }
280  for( int udim = dim + 1; udim <= 3; ++udim )
281  {
282  rval = mMB->get_adjacencies( tmp, udim, false, adj[udim], Interface::UNION );CHKERR;
283  }
284  ents.merge( tmp );
285  tmp.clear();
286  }
287  for( int dim = 0; dim < 4; ++dim )
288  {
289  ents.merge( adj[dim] );
290  adj[dim].clear();
291  }
292 
293  // process each entity
294  for( Range::iterator e = ents.begin(); e != ents.end(); ++e )
295  {
296  int val;
297  rval = mMB->tag_get_data( order_tag, &*e, 1, &val );CHKERR;
298 
299  // If this entity is already in one or more of the sets (either
300  // directly or through adjacency) then get the existing list of
301  // sets and append this set handle (we are iterating over sets
302  // in sorted order, so appending should aways maintain a sorted
303  // list.)
304  sharing.clear();
305  if( val != skip_val )
306  {
307  sharing = *revMap[val];
308  assert( std::lower_bound( sharing.begin(), sharing.end(), *s ) == sharing.end() );
309  }
310  sharing.push_back( *s );
311 
312  // Check if new sharing list already exists in forward map
313  fiter = forMap.lower_bound( &sharing );
314  if( fiter == forMap.end() || lessthan( fiter->first, &sharing ) )
315  {
316  // Add new sharing list to forward and reverse maps.
317  std::vector< EntityHandle >* newvec = new std::vector< EntityHandle >;
318  newvec->swap( sharing );
319  if( (int)revMap.size() == skip_val ) revMap.push_back( 0 );
320  fiter2 =
321  forMap.insert( fiter, std::pair< std::vector< EntityHandle >*, int >( newvec, revMap.size() ) );
322  assert( fiter2 != fiter );
323  fiter = fiter2;
324  revMap.push_back( newvec );
325  }
326 
327  // Update index on entity
328  val = fiter->second;
329  rval = mMB->tag_set_data( order_tag, &*e, 1, &val );CHKERR;
330  }
331  }
332 
333  return MB_SUCCESS;
334 }

References moab::Range::all_of_type(), moab::Range::begin(), moab::check_tag_type(), CHKERR, moab::Range::clear(), dim, moab::Range::end(), ErrorCode, moab::Core::get_adjacencies(), moab::Core::get_entities_by_dimension(), MB_SUCCESS, MB_TYPE_INTEGER, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, moab::Range::merge(), mMB, moab::Core::tag_get_data(), moab::Core::tag_set_data(), and moab::Interface::UNION.

Referenced by handle_order_from_sets_and_adj().

◆ reorder_entities()

ErrorCode moab::ReorderTool::reorder_entities ( Tag  new_handle_tag)

Do the re-ordering indicated by the passed handle tag.

The specified re-ordering must be a permutation. Each existing entity must be moved to a new, existing handle such that no two entities are moved to the same new handle.

Given a tag storing handles that define a permution, apply the described re-ordering. The passed tag must contain one entity handle per entity. The value of the tag must be zero for all entities that are not to be re-ordered. For entities to be re-ordered, the tag must contain the new handle that the entity is to be moved to. No two entities may have the same value for this tag (other than a value of zero.)

Parameters
new_handle_tagTag containing new handles for entities to reorder. Typically the output of handle_order_from_int_tag or similar.

Definition at line 399 of file ReorderTool.cpp.

400 {
401  ErrorCode rval;
402 
403  rval = check_tag_type( mMB, new_handles, MB_TYPE_HANDLE, sizeof( EntityHandle ) );CHKERR;
404  EntityHandle defval;
405  rval = mMB->tag_get_default_value( new_handles, &defval );CHKERR;
406  if( 0 != defval ) return error( MB_INDEX_OUT_OF_RANGE );
407 
408  // Can only reorder within same type/connectivity (or vertex/num_coords)
409  // groupings.
410  for( EntityType t = MBVERTEX; t < MBENTITYSET; ++t )
411  {
412  // Get list of all connectivity lengths (or vertex dimensions)
413  // that exist for type t.
414  TypeSequenceManager& seqs = mMB->sequence_manager()->entity_map( t );
416  std::set< int > values;
417  for( i = seqs.begin(); i != seqs.end(); ++i )
418  {
419  EntitySequence* seq = *i;
420  // 0 values per entity implies structured data, which
421  // we cannot reorder. Skip those.
422  if( t == MBVERTEX || 0 < seq->values_per_entity() ) values.insert( seq->values_per_entity() );
423  }
424 
425  // reorder primary data for each (type,size) tuple.
426  std::set< int >::iterator j;
427  for( j = values.begin(); j != values.end(); ++j )
428  {
429  Range entities;
430  get_entities( t, *j, entities );
431  std::vector< EntityHandle > handles;
432  rval = get_reordered_handles( new_handles, entities, handles );
433  UNRECOVERABLE( rval );
434 
435  if( t == MBVERTEX )
436  {
437  std::vector< double > coords( entities.size() * 3 );
438  rval = mMB->get_coords( entities, &coords[0] );
439  UNRECOVERABLE( rval );
440  rval = mMB->set_coords( &handles[0], handles.size(), &coords[0] );
441  UNRECOVERABLE( rval );
442  }
443  else
444  {
445  std::vector< EntityHandle > conn;
446  conn.reserve( entities.size() * *j );
447  std::vector< EntityHandle > old_handles;
448  old_handles.resize( entities.size() );
449  std::copy( entities.begin(), entities.end(), old_handles.begin() );
450  rval = mMB->get_connectivity( &old_handles[0], old_handles.size(), conn, false );
451  UNRECOVERABLE( rval );
452  old_handles.clear();
453  old_handles = conn;
454  rval = get_reordered_handles( new_handles, old_handles, conn );
455  UNRECOVERABLE( rval );
456  for( unsigned int h = 0; h < handles.size(); ++h )
457  {
458  rval = mMB->set_connectivity( handles[h], &conn[h * *j], *j );
459  UNRECOVERABLE( rval );
460  }
461  }
462  }
463  }
464 
465  // now update tag data
466  std::vector< Tag > tag_handles;
467  mMB->tag_get_tags( tag_handles );
468  for( size_t i = 0; i < tag_handles.size(); ++i )
469  {
470  Tag tag = tag_handles[i];
471  if( tag == new_handles ) // don't mess up mapping from old to new handles
472  continue;
473 
474  for( EntityType t = MBVERTEX; t <= MBENTITYSET; ++t )
475  {
476  rval = reorder_tag_data( t, new_handles, tag );
477  UNRECOVERABLE( rval );
478  }
479  }
480 
481  rval = update_set_contents( new_handles );
482  UNRECOVERABLE( rval );
483 
484  return MB_SUCCESS;
485 }

References moab::TypeSequenceManager::begin(), moab::check_tag_type(), CHKERR, moab::TypeSequenceManager::end(), entities, moab::SequenceManager::entity_map(), moab::error(), ErrorCode, moab::Core::get_connectivity(), moab::Core::get_coords(), get_entities(), get_reordered_handles(), MB_INDEX_OUT_OF_RANGE, MB_SUCCESS, MB_TYPE_HANDLE, MBENTITYSET, MBVERTEX, mMB, reorder_tag_data(), moab::Core::sequence_manager(), moab::Core::set_connectivity(), moab::Core::set_coords(), t, moab::Core::tag_get_default_value(), moab::Core::tag_get_tags(), UNRECOVERABLE, update_set_contents(), and moab::EntitySequence::values_per_entity().

Referenced by main().

◆ reorder_tag_data()

ErrorCode moab::ReorderTool::reorder_tag_data ( EntityType  type,
Tag  new_handles,
Tag  reorder_tag 
)
private

helper function for reorder_entities

Reorder tag data for all entities of specified type.

Also updates tag values for MB_TYPE_HANDLE tags.

Parameters
typeEntity type to reorder
new_handlesTag containing old->new handle mapping
reorder_tagThe tag data to reorder

Definition at line 487 of file ReorderTool.cpp.

488 {
489  ErrorCode rval;
490 
491  int tagsize;
492  DataType tagtype;
493  rval = mMB->tag_get_data_type( tag, tagtype );
494  if( MB_SUCCESS != rval ) return error( rval );
495  if( MB_TYPE_BIT == tagtype )
496  tagsize = 1;
497  else
498  {
499  rval = mMB->tag_get_bytes( tag, tagsize );
500  if( MB_VARIABLE_DATA_LENGTH == rval )
501  tagsize = -1;
502  else if( MB_SUCCESS != rval )
503  return error( rval );
504  }
505 
506  // we don't re-order set handles, so we don't care about sets
507  // unless the tag contains handles that need to be updated
508  if( MBENTITYSET == etype && MB_TYPE_HANDLE != tagtype ) return MB_SUCCESS;
509 
510  // get tagged entities
511  Range old_tagged;
512  rval = mMB->get_entities_by_type_and_tag( 0, etype, &tag, 0, 1, old_tagged );
513  if( MB_SUCCESS != rval && old_tagged.empty() ) return error( rval );
514 
515  // remove entities that were not reordered, unless the tag
516  // is handle type in which case we need to update the data
517  // for all entities, regardless of reordering.
518  std::vector< EntityHandle > newhandles;
519  if( MB_TYPE_HANDLE == tagtype )
520  rval = get_reordered_handles( new_handles, old_tagged, newhandles );
521  else
522  rval = get_new_handles( new_handles, old_tagged, newhandles );CHKERR;
523 
524  if( old_tagged.empty() ) return MB_SUCCESS;
525 
526  // get copy of all tag data
527  std::vector< unsigned char > buffer;
528  std::vector< const void* > pointers;
529  std::vector< int > sizes;
530  // if variable-length tag
531  if( -1 == tagsize )
532  {
533  pointers.resize( old_tagged.size() );
534  sizes.resize( pointers.size() );
535  rval = mMB->tag_get_by_ptr( tag, old_tagged, &pointers[0], &sizes[0] );CHKERR;
536  int total = std::accumulate( sizes.begin(), sizes.end(), 0 );
537  DataType dtype;
538  mMB->tag_get_data_type( tag, dtype );
539  int type_size;
540  switch( dtype )
541  {
542  case MB_TYPE_INTEGER:
543  type_size = sizeof( int );
544  break;
545  case MB_TYPE_DOUBLE:
546  type_size = sizeof( double );
547  break;
548  case MB_TYPE_HANDLE:
549  type_size = sizeof( EntityHandle );
550  break;
551  case MB_TYPE_BIT:
552  type_size = 1;
553  break;
554  case MB_TYPE_OPAQUE:
555  type_size = 1;
556  break;
557  default:
558  return MB_TYPE_OUT_OF_RANGE;
559  }
560  buffer.resize( total * type_size );
561  size_t off = 0;
562  for( size_t j = 0; j < pointers.size(); ++j )
563  {
564  memcpy( &buffer[off], pointers[j], type_size * sizes[j] );
565  pointers[j] = &buffer[off];
566  off += sizes[j] * type_size;
567  }
568  }
569  // if fixed-length tag
570  else
571  {
572  buffer.resize( old_tagged.size() * tagsize );
573  rval = mMB->tag_get_data( tag, old_tagged, &buffer[0] );CHKERR;
574  }
575 
576  // if handle tag, update tag values for reordered handles
577  if( MB_TYPE_HANDLE == tagtype )
578  {
579  assert( !( buffer.size() % sizeof( EntityHandle ) ) );
580  std::vector< unsigned char > buffer2( buffer.size() );
581  rval = get_reordered_handles( new_handles, reinterpret_cast< const EntityHandle* >( &buffer[0] ),
582  reinterpret_cast< EntityHandle* >( &buffer2[0] ),
583  buffer.size() / sizeof( EntityHandle ) );CHKERR;
584  // if var-length tag then do not do swap because pointers[] contains pointers
585  // into old buffer
586  if( -1 == tagsize )
587  memcpy( &buffer[0], &buffer2[0], buffer.size() );
588  else
589  buffer.swap( buffer2 );
590  }
591 
592  // store re-ordered tag data
593  if( -1 == tagsize )
594  {
595  rval = mMB->tag_set_by_ptr( tag, &newhandles[0], newhandles.size(), &pointers[0], &sizes[0] );
596  pointers.clear();
597  sizes.clear();
598  buffer.clear();
599  }
600  else
601  {
602  rval = mMB->tag_set_data( tag, &newhandles[0], newhandles.size(), &buffer[0] );
603  buffer.clear();
604  }
605  CHKERR;
606 
607  // all permutations should be cyclical, but not all permuted
608  // entities necessarily had tag values, so we might need to delete
609  // tags for some entities
610  std::sort( newhandles.begin(), newhandles.end() );
611  std::vector< EntityHandle >::iterator k = newhandles.begin();
612  Range::iterator i = old_tagged.begin();
613  while( i != old_tagged.end() )
614  {
615  while( k != newhandles.end() && *k < *i )
616  ++k;
617  if( k == newhandles.end() ) break;
618 
619  if( *i == *k ) // what old_tagged -= newhandles
620  i = old_tagged.erase( i );
621  else
622  ++i;
623  }
624 
625  if( !old_tagged.empty() )
626  {
627  rval = mMB->tag_delete_data( tag, old_tagged );CHKERR;
628  }
629 
630  return MB_SUCCESS;
631 }

References moab::Range::begin(), buffer, CHKERR, moab::Range::empty(), moab::Range::end(), moab::Range::erase(), moab::error(), ErrorCode, moab::Core::get_entities_by_type_and_tag(), get_new_handles(), get_reordered_handles(), MB_SUCCESS, MB_TYPE_BIT, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, MB_TYPE_OPAQUE, MB_TYPE_OUT_OF_RANGE, MB_VARIABLE_DATA_LENGTH, MBENTITYSET, mMB, moab::Range::size(), sizes, moab::Core::tag_delete_data(), moab::Core::tag_get_by_ptr(), moab::Core::tag_get_bytes(), moab::Core::tag_get_data(), moab::Core::tag_get_data_type(), moab::Core::tag_set_by_ptr(), and moab::Core::tag_set_data().

Referenced by reorder_entities().

◆ update_set_contents()

ErrorCode moab::ReorderTool::update_set_contents ( Tag  new_handles)
private

helper function for reorder_entities

Update set contents for changed handles.

Parameters
new_handlesTag containing old->new handle mapping

Definition at line 633 of file ReorderTool.cpp.

634 {
635  Range sets;
637 
638  std::vector< EntityHandle > old_handles, new_handles;
639  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
640  {
641  // If set is un-ordered...
642  unsigned opts = 0;
643  mMB->get_meshset_options( *i, opts );
644  if( !( opts & MESHSET_ORDERED ) )
645  {
646  Range contents;
647  rval = mMB->get_entities_by_handle( *i, contents );CHKERR;
648 
649  rval = get_new_handles( nh_tag, contents, new_handles );CHKERR;
650 
651  Range replace;
652  std::sort( new_handles.begin(), new_handles.end() );
653  Range::iterator hint = replace.begin();
654  for( size_t j = 0; j < new_handles.size(); ++j )
655  hint = replace.insert( hint, new_handles[j] );
656  Range common = intersect( contents, replace );
657  contents -= common;
658  replace -= common;
659  assert( contents.size() == replace.size() );
660  if( !contents.empty() )
661  {
662  rval = mMB->remove_entities( *i, contents );CHKERR;
663  rval = mMB->add_entities( *i, replace );
664  }
665  }
666 
667  // If set is ordered...
668  else
669  {
670  // get set contents
671  old_handles.clear();
672  rval = mMB->get_entities_by_handle( *i, old_handles );CHKERR;
673 
674  // get new handles from old contained handles
675  rval = get_reordered_handles( nh_tag, old_handles, new_handles );CHKERR;
676 
677  rval = mMB->clear_meshset( &*i, 1 );CHKERR;
678 
679  rval = mMB->add_entities( *i, &new_handles[0], new_handles.size() );CHKERR;
680  }
681  } // for each set
682 
683  return MB_SUCCESS;
684 }

References moab::Core::add_entities(), moab::Range::begin(), CHKERR, moab::Core::clear_meshset(), moab::Range::empty(), moab::Range::end(), ErrorCode, moab::Core::get_entities_by_handle(), moab::Core::get_entities_by_type(), moab::Core::get_meshset_options(), get_new_handles(), get_reordered_handles(), moab::Range::insert(), moab::intersect(), MB_SUCCESS, MBENTITYSET, mMB, moab::Core::remove_entities(), and moab::Range::size().

Referenced by reorder_entities().

Member Data Documentation

◆ mMB


The documentation for this class was generated from the following files: