Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 ); 106  TypeSequenceManager::iterator s; 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(), 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, 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 ); 75  TypeSequenceManager::iterator i; 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(), 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 ); 415  TypeSequenceManager::iterator i; 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(), 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; 636  ErrorCode rval = mMB->get_entities_by_type( 0, MBENTITYSET, sets );CHKERR; 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: