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
MeshSetSequence.cpp
Go to the documentation of this file.
1 /* 2  * MOAB, a Mesh-Oriented datABase, is a software component for creating, 3  * storing and accessing finite element mesh data. 4  * 5  * Copyright 2004 Sandia Corporation. Under the terms of Contract 6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 7  * retains certain rights in this software. 8  * 9  * This library is free software; you can redistribute it and/or 10  * modify it under the terms of the GNU Lesser General Public 11  * License as published by the Free Software Foundation; either 12  * version 2.1 of the License, or (at your option) any later version. 13  * 14  */ 15  16 /**\file MeshSetSequence.cpp 17  *\author Jason Kraftcheck (kraftche@cae.wisc.edu) 18  *\date 2007-04-30 19  */ 20  21 #include "MeshSetSequence.hpp" 22 #include "SequenceManager.hpp" 23  24 namespace moab 25 { 26  27 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, SequenceData* dat ) 28  : EntitySequence( start, count, dat ) 29 { 30  initialize( flags ); 31 } 32  33 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, SequenceData* dat ) 34  : EntitySequence( start, count, dat ) 35 { 36  std::vector< unsigned > vect( count, flags ); 37  initialize( &vect[0] ); 38 } 39  40 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, EntityID data_size ) 41  : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) ) 42 { 43  initialize( flags ); 44 } 45  46 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, EntityID data_size ) 47  : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) ) 48 { 49  std::vector< unsigned > vect( count, flags ); 50  initialize( &vect[0] ); 51 } 52  53 void MeshSetSequence::initialize( const unsigned* flags ) 54 { 55  if( !data()->get_sequence_data( 0 ) ) data()->create_sequence_data( 0, SET_SIZE ); 56  57  EntityID offset = start_handle() - data()->start_handle(); 58  for( EntityID i = 0; i < size(); ++i ) 59  allocate_set( flags[i], i + offset ); 60 } 61  62 MeshSetSequence::~MeshSetSequence() 63 { 64  EntityID offset = start_handle() - data()->start_handle(); 65  EntityID count = size(); 66  for( EntityID i = 0; i < count; ++i ) 67  deallocate_set( i + offset ); 68 } 69  70 EntitySequence* MeshSetSequence::split( EntityHandle here ) 71 { 72  return new MeshSetSequence( *this, here ); 73 } 74  75 ErrorCode MeshSetSequence::pop_back( EntityID count ) 76 { 77  EntityID offset = end_handle() + 1 - count - data()->start_handle(); 78  ErrorCode rval = EntitySequence::pop_back( count ); 79  if( MB_SUCCESS == rval ) 80  for( EntityID i = 0; i < count; ++i ) 81  deallocate_set( i + offset ); 82  return rval; 83 } 84  85 ErrorCode MeshSetSequence::pop_front( EntityID count ) 86 { 87  EntityID offset = start_handle() - data()->start_handle(); 88  ErrorCode rval = EntitySequence::pop_front( count ); 89  if( MB_SUCCESS == rval ) 90  for( EntityID i = 0; i < count; ++i ) 91  deallocate_set( i + offset ); 92  return rval; 93 } 94  95 ErrorCode MeshSetSequence::push_back( EntityID count, const unsigned* flags ) 96 { 97  EntityID offset = end_handle() + 1 - data()->start_handle(); 98  ErrorCode rval = EntitySequence::append_entities( count ); 99  if( MB_SUCCESS == rval ) 100  for( EntityID i = 0; i < count; ++i ) 101  allocate_set( flags[i], i + offset ); 102  return rval; 103 } 104  105 ErrorCode MeshSetSequence::push_front( EntityID count, const unsigned* flags ) 106 { 107  EntityID offset = start_handle() - data()->start_handle() - count; 108  ErrorCode rval = EntitySequence::prepend_entities( count ); 109  if( MB_SUCCESS == rval ) 110  for( EntityID i = 0; i < count; ++i ) 111  allocate_set( flags[i], i + offset ); 112  return rval; 113 } 114  115 void MeshSetSequence::get_const_memory_use( unsigned long& per_ent, unsigned long& seq_size ) const 116 { 117  per_ent = SET_SIZE; 118  seq_size = sizeof( *this ); 119 } 120  121 unsigned long MeshSetSequence::get_per_entity_memory_use( EntityHandle first, EntityHandle last ) const 122 { 123  if( first < start_handle() ) first = start_handle(); 124  if( last > end_handle() ) last = end_handle(); 125  126  unsigned long sum = 0; 127  for( EntityHandle h = first; h <= last; ++h ) 128  sum += get_set( h )->get_memory_use(); 129  return sum; 130 } 131  132 ErrorCode MeshSetSequence::get_entities( const SequenceManager* seqman, 133  EntityHandle handle, 134  Range& entities, 135  bool recursive ) const 136 { 137  if( !recursive ) 138  { 139  get_set( handle )->get_entities( entities ); 140  return MB_SUCCESS; 141  } 142  else 143  { 144  std::vector< const MeshSet* > list; 145  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 146  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 147  ( *i )->get_non_set_entities( entities ); 148  return rval; 149  } 150 } 151  152 ErrorCode MeshSetSequence::get_entities( EntityHandle handle, std::vector< EntityHandle >& entities ) const 153 { 154  get_set( handle )->get_entities( entities ); 155  return MB_SUCCESS; 156 } 157  158 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman, 159  EntityHandle handle, 160  int dimension, 161  std::vector< EntityHandle >& entities, 162  bool recursive ) const 163 { 164  if( !recursive ) 165  { 166  get_set( handle )->get_entities_by_dimension( dimension, entities ); 167  return MB_SUCCESS; 168  } 169  else 170  { 171  std::vector< const MeshSet* > list; 172  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 173  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 174  ( *i )->get_entities_by_dimension( dimension, entities ); 175  return rval; 176  } 177 } 178  179 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman, 180  EntityHandle handle, 181  int dimension, 182  Range& entities, 183  bool recursive ) const 184 { 185  if( !recursive ) 186  { 187  get_set( handle )->get_entities_by_dimension( dimension, entities ); 188  return MB_SUCCESS; 189  } 190  else 191  { 192  std::vector< const MeshSet* > list; 193  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 194  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 195  ( *i )->get_entities_by_dimension( dimension, entities ); 196  return rval; 197  } 198 } 199  200 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman, 201  EntityHandle handle, 202  EntityType tp, 203  std::vector< EntityHandle >& entities, 204  bool recursive ) const 205 { 206  if( !recursive ) 207  { 208  get_set( handle )->get_entities_by_type( tp, entities ); 209  return MB_SUCCESS; 210  } 211  else if( tp == MBENTITYSET ) 212  { 213  return recursive_get_sets( handle, seqman, 0, 0, &entities ); 214  } 215  else if( tp == MBMAXTYPE ) 216  { 217  Range tmp; 218  ErrorCode rval = get_entities( seqman, handle, tmp, recursive ); 219  if( MB_SUCCESS == rval ) 220  { 221 #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT 222  std::copy( tmp.begin(), tmp.end(), std::back_inserter( entities ) ); 223 #else 224  entities.insert( entities.end(), tmp.begin(), tmp.end() ); 225 #endif 226  } 227  return rval; 228  } 229  else 230  { 231  std::vector< const MeshSet* > list; 232  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 233  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 234  ( *i )->get_entities_by_type( tp, entities ); 235  return rval; 236  } 237 } 238  239 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman, 240  EntityHandle handle, 241  EntityType tp, 242  Range& entities, 243  bool recursive ) const 244 { 245  if( !recursive ) 246  { 247  get_set( handle )->get_entities_by_type( tp, entities ); 248  return MB_SUCCESS; 249  } 250  else if( tp == MBENTITYSET ) 251  { 252  return recursive_get_sets( handle, seqman, 0, &entities ); 253  } 254  else if( tp == MBMAXTYPE ) 255  { 256  std::vector< const MeshSet* > list; 257  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 258  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 259  ( *i )->get_non_set_entities( entities ); 260  return rval; 261  } 262  else 263  { 264  std::vector< const MeshSet* > list; 265  ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 266  for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 267  ( *i )->get_entities_by_type( tp, entities ); 268  return rval; 269  } 270 } 271  272 ErrorCode MeshSetSequence::num_entities( const SequenceManager* seqman, 273  EntityHandle handle, 274  int& number, 275  bool recursive ) const 276 { 277  if( !recursive ) 278  { 279  number = get_set( handle )->num_entities(); 280  return MB_SUCCESS; 281  } 282  else 283  { 284  Range range; 285  ErrorCode result = get_entities( seqman, handle, range, true ); 286  number = range.size(); 287  return result; 288  } 289 } 290  291 ErrorCode MeshSetSequence::num_dimension( const SequenceManager* seqman, 292  EntityHandle handle, 293  int dimension, 294  int& number, 295  bool recursive ) const 296 { 297  if( !recursive ) 298  { 299  number = get_set( handle )->num_entities_by_dimension( dimension ); 300  return MB_SUCCESS; 301  } 302  else 303  { 304  Range range; 305  ErrorCode result = get_dimension( seqman, handle, dimension, range, true ); 306  number = range.size(); 307  return result; 308  } 309 } 310  311 ErrorCode MeshSetSequence::num_type( const SequenceManager* seqman, 312  EntityHandle handle, 313  EntityType tp, 314  int& number, 315  bool recursive ) const 316 { 317  if( !recursive ) 318  { 319  number = get_set( handle )->num_entities_by_type( tp ); 320  return MB_SUCCESS; 321  } 322  else 323  { 324  Range range; 325  ErrorCode result = get_type( seqman, handle, tp, range, true ); 326  number = range.size(); 327  return result; 328  } 329 } 330  331 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set, 332  const SequenceManager* seq_sets, 333  std::vector< const MeshSet* >* sets, 334  Range* set_handles, 335  std::vector< EntityHandle >* set_vector ) 336 { 337  std::set< EntityHandle > visited; 338  std::vector< EntityHandle > stack; 339  stack.push_back( start_set ); 340  bool remove_start_set = true; 341  while( !stack.empty() ) 342  { 343  EntityHandle handle = stack.back(); 344  stack.pop_back(); 345  346  if( !visited.insert( handle ).second ) 347  { 348  if( handle == start_set ) remove_start_set = false; 349  continue; 350  } 351  352  const EntitySequence* seq; 353  ErrorCode rval = seq_sets->find( handle, seq ); 354  if( MB_SUCCESS != rval ) return rval; 355  356  const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq ); 357  const MeshSet* ms_ptr = mseq->get_set( handle ); 358  if( sets ) sets->push_back( ms_ptr ); 359  360  Range tmp_range; 361  ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range ); 362  std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) ); 363  } 364  365  if( set_handles ) 366  { 367  if( remove_start_set ) visited.erase( start_set ); 368  Range::iterator hint = set_handles->begin(); 369  std::set< EntityHandle >::iterator it; 370  for( it = visited.begin(); it != visited.end(); ++it ) 371  hint = set_handles->insert( hint, *it, *it ); 372  } 373  374  if( set_vector ) 375  { 376  if( remove_start_set ) visited.erase( start_set ); 377  std::copy( visited.begin(), visited.end(), std::back_inserter( *set_vector ) ); 378  } 379  380  return MB_SUCCESS; 381 } 382  383 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set, 384  SequenceManager* seq_sets, 385  std::vector< MeshSet* >& sets ) 386 { 387  std::set< EntityHandle > visited; 388  std::vector< EntityHandle > stack; 389  stack.push_back( start_set ); 390  while( !stack.empty() ) 391  { 392  EntityHandle handle = stack.back(); 393  stack.pop_back(); 394  395  if( !visited.insert( handle ).second ) continue; 396  397  EntitySequence* seq; 398  ErrorCode rval = seq_sets->find( handle, seq ); 399  if( MB_SUCCESS != rval ) return rval; 400  401  MeshSetSequence* mseq = reinterpret_cast< MeshSetSequence* >( seq ); 402  MeshSet* ms_ptr = mseq->get_set( handle ); 403  sets.push_back( ms_ptr ); 404  405  Range tmp_range; 406  ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range ); 407  std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) ); 408  } 409  410  return MB_SUCCESS; 411 } 412  413 ErrorCode MeshSetSequence::get_parent_child_meshsets( EntityHandle meshset, 414  const SequenceManager* seq_sets, 415  std::vector< EntityHandle >& results, 416  int num_hops, 417  SearchType link_type ) const 418 { 419  ErrorCode result = MB_SUCCESS; 420  std::vector< EntityHandle >::iterator i; 421  const EntityHandle *tmp_array = 0, *end; 422  EntityHandle s, e; 423  int count = 0; 424  size_t n; 425  426  // Skip any meshsets already in input vector (yes, don't 427  // get their children either even if num_hops would indicate 428  // that we should.) There is an exception to that if the 429  // input meshset is in the list, which is handled by the order 430  // of checks in the main loop below. 431  std::set< EntityHandle > visited; 432  for( i = results.begin(); i != results.end(); ++i ) 433  visited.insert( *i ); 434  435  // Two lists for breadth-first search 436  std::vector< EntityHandle > lists[2]; 437  int index = 0; // which list to read from (write to lists[1-index]) 438  lists[index].push_back( meshset ); // begin with input set 439  // loop for num_hops (or until no more sets) 440  for( ; num_hops && !lists[index].empty(); --num_hops ) 441  { 442  // for each set at the current num_hops 443  for( i = lists[index].begin(); i != lists[index].end(); ++i ) 444  { 445  // get meshset from handle 446  const EntitySequence* seq; 447  ErrorCode rval = seq_sets->find( *i, seq ); 448  if( MB_SUCCESS != rval ) return rval; 449  const MeshSet* ms_ptr = reinterpret_cast< const MeshSetSequence* >( seq )->get_set( *i ); 450  451  switch( link_type ) 452  { 453  case CONTAINED: 454  tmp_array = ms_ptr->get_contents( n ); 455  end = tmp_array + n; 456  if( ms_ptr->vector_based() ) 457  { 458  for( ; tmp_array != end; ++tmp_array ) 459  if( MBENTITYSET == TYPE_FROM_HANDLE( *tmp_array ) && visited.insert( *tmp_array ).second ) 460  lists[1 - index].push_back( *tmp_array ); 461  } 462  else 463  { 464  assert( n % 2 == 0 ); 465  tmp_array = std::lower_bound( tmp_array, tmp_array + n, FIRST_HANDLE( MBENTITYSET ) ); 466  // only part of first block is of type 467  if( ( end - tmp_array ) % 2 ) 468  { 469  ++tmp_array; 470  s = FIRST_HANDLE( MBENTITYSET ); 471  e = *tmp_array; 472  for( ; s <= e; ++s ) 473  if( visited.insert( s ).second ) lists[1 - index].push_back( s ); 474  } 475  while( tmp_array < end ) 476  { 477  s = *tmp_array++; 478  e = *tmp_array++; 479  for( ; s <= e; ++s ) 480  if( visited.insert( s ).second ) lists[1 - index].push_back( s ); 481  } 482  } 483  continue; 484  case PARENTS: 485  tmp_array = ms_ptr->get_parents( count ); 486  break; 487  case CHILDREN: 488  tmp_array = ms_ptr->get_children( count ); 489  break; 490  } 491  492  // copy any parents/children we haven't visited yet into list 493  for( end = tmp_array + count; tmp_array != end; ++tmp_array ) 494  if( visited.insert( *tmp_array ).second ) lists[1 - index].push_back( *tmp_array ); 495  } 496  497  // iterate 498  lists[index].clear(); 499  index = 1 - index; 500  // append each level of sets to the output list. 501  // note: to make a more useful search (e.g. get entities 3 hops away, 502  // rather than entities up to and including 3 hops) move this outside 503  // the loop, but then need to handle the get all (num_hops < 0) case 504  // specially. 505  std::copy( lists[index].begin(), lists[index].end(), std::back_inserter( results ) ); 506  } 507  508  return result; 509 } 510  511 ErrorCode MeshSetSequence::get_parents( const SequenceManager* seqman, 512  EntityHandle handle, 513  std::vector< EntityHandle >& parents, 514  int num_hops ) const 515 { 516  if( num_hops == 1 ) 517  { 518  int count; 519  const EntityHandle* tmp_array = get_set( handle )->get_parents( count ); 520  if( parents.empty() ) 521  { 522  parents.resize( count ); 523  std::copy( tmp_array, tmp_array + count, parents.begin() ); 524  return MB_SUCCESS; 525  } 526  else if( !count ) 527  { 528  return MB_SUCCESS; 529  } 530  } 531  532  if( num_hops > 0 ) 533  return get_parent_child_meshsets( handle, seqman, parents, num_hops, PARENTS ); 534  else 535  return get_parent_child_meshsets( handle, seqman, parents, -1, PARENTS ); 536 } 537  538 ErrorCode MeshSetSequence::get_children( const SequenceManager* seqman, 539  EntityHandle handle, 540  std::vector< EntityHandle >& children, 541  int num_hops ) const 542 { 543  if( num_hops == 1 ) 544  { 545  int count; 546  const EntityHandle* tmp_array = get_set( handle )->get_children( count ); 547  if( children.empty() ) 548  { 549  children.resize( count ); 550  std::copy( tmp_array, tmp_array + count, children.begin() ); 551  return MB_SUCCESS; 552  } 553  else if( !count ) 554  { 555  return MB_SUCCESS; 556  } 557  } 558  559  if( num_hops > 0 ) 560  return get_parent_child_meshsets( handle, seqman, children, num_hops, CHILDREN ); 561  else 562  return get_parent_child_meshsets( handle, seqman, children, -1, CHILDREN ); 563 } 564  565 ErrorCode MeshSetSequence::get_contained_sets( const SequenceManager* seqman, 566  EntityHandle handle, 567  std::vector< EntityHandle >& contained, 568  int num_hops ) const 569 { 570  if( num_hops == 1 && contained.empty() ) 571  { 572  return get_set( handle )->get_entities_by_type( MBENTITYSET, contained ); 573  } 574  575  if( num_hops > 0 ) 576  return get_parent_child_meshsets( handle, seqman, contained, num_hops, CONTAINED ); 577  else 578  return get_parent_child_meshsets( handle, seqman, contained, -1, CONTAINED ); 579 } 580  581 ErrorCode MeshSetSequence::num_parents( const SequenceManager* seqman, 582  EntityHandle handle, 583  int& number, 584  int num_hops ) const 585 { 586  if( num_hops == 1 ) 587  { 588  number = get_set( handle )->num_parents(); 589  return MB_SUCCESS; 590  } 591  592  std::vector< EntityHandle > parents; 593  ErrorCode result = get_parents( seqman, handle, parents, num_hops ); 594  number = parents.size(); 595  return result; 596 } 597  598 ErrorCode MeshSetSequence::num_children( const SequenceManager* seqman, 599  EntityHandle handle, 600  int& number, 601  int num_hops ) const 602 { 603  if( num_hops == 1 ) 604  { 605  number = get_set( handle )->num_children(); 606  return MB_SUCCESS; 607  } 608  609  std::vector< EntityHandle > children; 610  ErrorCode result = get_children( seqman, handle, children, num_hops ); 611  number = children.size(); 612  return result; 613 } 614  615 ErrorCode MeshSetSequence::num_contained_sets( const SequenceManager* seqman, 616  EntityHandle handle, 617  int& number, 618  int num_hops ) const 619 { 620  if( num_hops == 1 ) 621  { 622  number = get_set( handle )->num_entities_by_type( MBENTITYSET ); 623  return MB_SUCCESS; 624  } 625  626  std::vector< EntityHandle > contained; 627  ErrorCode result = get_contained_sets( seqman, handle, contained, num_hops ); 628  number = contained.size(); 629  return result; 630 } 631  632 } // namespace moab