MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /* 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 /**\file MeshSetSequence.cpp 00017 *\author Jason Kraftcheck (kraftche@cae.wisc.edu) 00018 *\date 2007-04-30 00019 */ 00020 00021 #include "MeshSetSequence.hpp" 00022 #include "SequenceManager.hpp" 00023 00024 namespace moab 00025 { 00026 00027 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, SequenceData* dat ) 00028 : EntitySequence( start, count, dat ) 00029 { 00030 initialize( flags ); 00031 } 00032 00033 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, SequenceData* dat ) 00034 : EntitySequence( start, count, dat ) 00035 { 00036 std::vector< unsigned > vect( count, flags ); 00037 initialize( &vect[0] ); 00038 } 00039 00040 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, const unsigned* flags, EntityID data_size ) 00041 : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) ) 00042 { 00043 initialize( flags ); 00044 } 00045 00046 MeshSetSequence::MeshSetSequence( EntityHandle start, EntityID count, unsigned flags, EntityID data_size ) 00047 : EntitySequence( start, count, new SequenceData( 1, start, start + data_size - 1 ) ) 00048 { 00049 std::vector< unsigned > vect( count, flags ); 00050 initialize( &vect[0] ); 00051 } 00052 00053 void MeshSetSequence::initialize( const unsigned* flags ) 00054 { 00055 if( !data()->get_sequence_data( 0 ) ) data()->create_sequence_data( 0, SET_SIZE ); 00056 00057 EntityID offset = start_handle() - data()->start_handle(); 00058 for( EntityID i = 0; i < size(); ++i ) 00059 allocate_set( flags[i], i + offset ); 00060 } 00061 00062 MeshSetSequence::~MeshSetSequence() 00063 { 00064 EntityID offset = start_handle() - data()->start_handle(); 00065 EntityID count = size(); 00066 for( EntityID i = 0; i < count; ++i ) 00067 deallocate_set( i + offset ); 00068 } 00069 00070 EntitySequence* MeshSetSequence::split( EntityHandle here ) 00071 { 00072 return new MeshSetSequence( *this, here ); 00073 } 00074 00075 ErrorCode MeshSetSequence::pop_back( EntityID count ) 00076 { 00077 EntityID offset = end_handle() + 1 - count - data()->start_handle(); 00078 ErrorCode rval = EntitySequence::pop_back( count ); 00079 if( MB_SUCCESS == rval ) 00080 for( EntityID i = 0; i < count; ++i ) 00081 deallocate_set( i + offset ); 00082 return rval; 00083 } 00084 00085 ErrorCode MeshSetSequence::pop_front( EntityID count ) 00086 { 00087 EntityID offset = start_handle() - data()->start_handle(); 00088 ErrorCode rval = EntitySequence::pop_front( count ); 00089 if( MB_SUCCESS == rval ) 00090 for( EntityID i = 0; i < count; ++i ) 00091 deallocate_set( i + offset ); 00092 return rval; 00093 } 00094 00095 ErrorCode MeshSetSequence::push_back( EntityID count, const unsigned* flags ) 00096 { 00097 EntityID offset = end_handle() + 1 - data()->start_handle(); 00098 ErrorCode rval = EntitySequence::append_entities( count ); 00099 if( MB_SUCCESS == rval ) 00100 for( EntityID i = 0; i < count; ++i ) 00101 allocate_set( flags[i], i + offset ); 00102 return rval; 00103 } 00104 00105 ErrorCode MeshSetSequence::push_front( EntityID count, const unsigned* flags ) 00106 { 00107 EntityID offset = start_handle() - data()->start_handle() - count; 00108 ErrorCode rval = EntitySequence::prepend_entities( count ); 00109 if( MB_SUCCESS == rval ) 00110 for( EntityID i = 0; i < count; ++i ) 00111 allocate_set( flags[i], i + offset ); 00112 return rval; 00113 } 00114 00115 void MeshSetSequence::get_const_memory_use( unsigned long& per_ent, unsigned long& seq_size ) const 00116 { 00117 per_ent = SET_SIZE; 00118 seq_size = sizeof( *this ); 00119 } 00120 00121 unsigned long MeshSetSequence::get_per_entity_memory_use( EntityHandle first, EntityHandle last ) const 00122 { 00123 if( first < start_handle() ) first = start_handle(); 00124 if( last > end_handle() ) last = end_handle(); 00125 00126 unsigned long sum = 0; 00127 for( EntityHandle h = first; h <= last; ++h ) 00128 sum += get_set( h )->get_memory_use(); 00129 return sum; 00130 } 00131 00132 ErrorCode MeshSetSequence::get_entities( const SequenceManager* seqman, EntityHandle handle, Range& entities, 00133 bool recursive ) const 00134 { 00135 if( !recursive ) 00136 { 00137 get_set( handle )->get_entities( entities ); 00138 return MB_SUCCESS; 00139 } 00140 else 00141 { 00142 std::vector< const MeshSet* > list; 00143 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00144 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00145 ( *i )->get_non_set_entities( entities ); 00146 return rval; 00147 } 00148 } 00149 00150 ErrorCode MeshSetSequence::get_entities( EntityHandle handle, std::vector< EntityHandle >& entities ) const 00151 { 00152 get_set( handle )->get_entities( entities ); 00153 return MB_SUCCESS; 00154 } 00155 00156 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman, EntityHandle handle, int dimension, 00157 std::vector< EntityHandle >& entities, bool recursive ) const 00158 { 00159 if( !recursive ) 00160 { 00161 get_set( handle )->get_entities_by_dimension( dimension, entities ); 00162 return MB_SUCCESS; 00163 } 00164 else 00165 { 00166 std::vector< const MeshSet* > list; 00167 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00168 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00169 ( *i )->get_entities_by_dimension( dimension, entities ); 00170 return rval; 00171 } 00172 } 00173 00174 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman, EntityHandle handle, int dimension, 00175 Range& entities, bool recursive ) const 00176 { 00177 if( !recursive ) 00178 { 00179 get_set( handle )->get_entities_by_dimension( dimension, entities ); 00180 return MB_SUCCESS; 00181 } 00182 else 00183 { 00184 std::vector< const MeshSet* > list; 00185 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00186 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00187 ( *i )->get_entities_by_dimension( dimension, entities ); 00188 return rval; 00189 } 00190 } 00191 00192 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman, EntityHandle handle, EntityType tp, 00193 std::vector< EntityHandle >& entities, bool recursive ) const 00194 { 00195 if( !recursive ) 00196 { 00197 get_set( handle )->get_entities_by_type( tp, entities ); 00198 return MB_SUCCESS; 00199 } 00200 else if( tp == MBENTITYSET ) 00201 { 00202 return recursive_get_sets( handle, seqman, 0, 0, &entities ); 00203 } 00204 else if( tp == MBMAXTYPE ) 00205 { 00206 Range tmp; 00207 ErrorCode rval = get_entities( seqman, handle, tmp, recursive ); 00208 if( MB_SUCCESS == rval ) 00209 { 00210 #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT 00211 std::copy( tmp.begin(), tmp.end(), std::back_inserter( entities ) ); 00212 #else 00213 entities.insert( entities.end(), tmp.begin(), tmp.end() ); 00214 #endif 00215 } 00216 return rval; 00217 } 00218 else 00219 { 00220 std::vector< const MeshSet* > list; 00221 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00222 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00223 ( *i )->get_entities_by_type( tp, entities ); 00224 return rval; 00225 } 00226 } 00227 00228 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman, EntityHandle handle, EntityType tp, Range& entities, 00229 bool recursive ) const 00230 { 00231 if( !recursive ) 00232 { 00233 get_set( handle )->get_entities_by_type( tp, entities ); 00234 return MB_SUCCESS; 00235 } 00236 else if( tp == MBENTITYSET ) 00237 { 00238 return recursive_get_sets( handle, seqman, 0, &entities ); 00239 } 00240 else if( tp == MBMAXTYPE ) 00241 { 00242 std::vector< const MeshSet* > list; 00243 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00244 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00245 ( *i )->get_non_set_entities( entities ); 00246 return rval; 00247 } 00248 else 00249 { 00250 std::vector< const MeshSet* > list; 00251 ErrorCode rval = recursive_get_sets( handle, seqman, &list ); 00252 for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i ) 00253 ( *i )->get_entities_by_type( tp, entities ); 00254 return rval; 00255 } 00256 } 00257 00258 ErrorCode MeshSetSequence::num_entities( const SequenceManager* seqman, EntityHandle handle, int& number, 00259 bool recursive ) const 00260 { 00261 if( !recursive ) 00262 { 00263 number = get_set( handle )->num_entities(); 00264 return MB_SUCCESS; 00265 } 00266 else 00267 { 00268 Range range; 00269 ErrorCode result = get_entities( seqman, handle, range, true ); 00270 number = range.size(); 00271 return result; 00272 } 00273 } 00274 00275 ErrorCode MeshSetSequence::num_dimension( const SequenceManager* seqman, EntityHandle handle, int dimension, 00276 int& number, bool recursive ) const 00277 { 00278 if( !recursive ) 00279 { 00280 number = get_set( handle )->num_entities_by_dimension( dimension ); 00281 return MB_SUCCESS; 00282 } 00283 else 00284 { 00285 Range range; 00286 ErrorCode result = get_dimension( seqman, handle, dimension, range, true ); 00287 number = range.size(); 00288 return result; 00289 } 00290 } 00291 00292 ErrorCode MeshSetSequence::num_type( const SequenceManager* seqman, EntityHandle handle, EntityType tp, int& number, 00293 bool recursive ) const 00294 { 00295 if( !recursive ) 00296 { 00297 number = get_set( handle )->num_entities_by_type( tp ); 00298 return MB_SUCCESS; 00299 } 00300 else 00301 { 00302 Range range; 00303 ErrorCode result = get_type( seqman, handle, tp, range, true ); 00304 number = range.size(); 00305 return result; 00306 } 00307 } 00308 00309 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set, const SequenceManager* seq_sets, 00310 std::vector< const MeshSet* >* sets, Range* set_handles, 00311 std::vector< EntityHandle >* set_vector ) 00312 { 00313 std::set< EntityHandle > visited; 00314 std::vector< EntityHandle > stack; 00315 stack.push_back( start_set ); 00316 bool remove_start_set = true; 00317 while( !stack.empty() ) 00318 { 00319 EntityHandle handle = stack.back(); 00320 stack.pop_back(); 00321 00322 if( !visited.insert( handle ).second ) 00323 { 00324 if( handle == start_set ) remove_start_set = false; 00325 continue; 00326 } 00327 00328 const EntitySequence* seq; 00329 ErrorCode rval = seq_sets->find( handle, seq ); 00330 if( MB_SUCCESS != rval ) return rval; 00331 00332 const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq ); 00333 const MeshSet* ms_ptr = mseq->get_set( handle ); 00334 if( sets ) sets->push_back( ms_ptr ); 00335 00336 Range tmp_range; 00337 ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range ); 00338 std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) ); 00339 } 00340 00341 if( set_handles ) 00342 { 00343 if( remove_start_set ) visited.erase( start_set ); 00344 Range::iterator hint = set_handles->begin(); 00345 std::set< EntityHandle >::iterator it; 00346 for( it = visited.begin(); it != visited.end(); ++it ) 00347 hint = set_handles->insert( hint, *it, *it ); 00348 } 00349 00350 if( set_vector ) 00351 { 00352 if( remove_start_set ) visited.erase( start_set ); 00353 std::copy( visited.begin(), visited.end(), std::back_inserter( *set_vector ) ); 00354 } 00355 00356 return MB_SUCCESS; 00357 } 00358 00359 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set, SequenceManager* seq_sets, 00360 std::vector< MeshSet* >& sets ) 00361 { 00362 std::set< EntityHandle > visited; 00363 std::vector< EntityHandle > stack; 00364 stack.push_back( start_set ); 00365 while( !stack.empty() ) 00366 { 00367 EntityHandle handle = stack.back(); 00368 stack.pop_back(); 00369 00370 if( !visited.insert( handle ).second ) continue; 00371 00372 EntitySequence* seq; 00373 ErrorCode rval = seq_sets->find( handle, seq ); 00374 if( MB_SUCCESS != rval ) return rval; 00375 00376 MeshSetSequence* mseq = reinterpret_cast< MeshSetSequence* >( seq ); 00377 MeshSet* ms_ptr = mseq->get_set( handle ); 00378 sets.push_back( ms_ptr ); 00379 00380 Range tmp_range; 00381 ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range ); 00382 std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) ); 00383 } 00384 00385 return MB_SUCCESS; 00386 } 00387 00388 ErrorCode MeshSetSequence::get_parent_child_meshsets( EntityHandle meshset, const SequenceManager* seq_sets, 00389 std::vector< EntityHandle >& results, int num_hops, 00390 SearchType link_type ) const 00391 { 00392 ErrorCode result = MB_SUCCESS; 00393 std::vector< EntityHandle >::iterator i; 00394 const EntityHandle *tmp_array = 0, *end; 00395 EntityHandle s, e; 00396 int count = 0; 00397 size_t n; 00398 00399 // Skip any meshsets already in input vector (yes, don't 00400 // get their children either even if num_hops would indicate 00401 // that we should.) There is an exception to that if the 00402 // input meshset is in the list, which is handled by the order 00403 // of checks in the main loop below. 00404 std::set< EntityHandle > visited; 00405 for( i = results.begin(); i != results.end(); ++i ) 00406 visited.insert( *i ); 00407 00408 // Two lists for breadth-first search 00409 std::vector< EntityHandle > lists[2]; 00410 int index = 0; // which list to read from (write to lists[1-index]) 00411 lists[index].push_back( meshset ); // begin with input set 00412 // loop for num_hops (or until no more sets) 00413 for( ; num_hops && !lists[index].empty(); --num_hops ) 00414 { 00415 // for each set at the current num_hops 00416 for( i = lists[index].begin(); i != lists[index].end(); ++i ) 00417 { 00418 // get meshset from handle 00419 const EntitySequence* seq; 00420 ErrorCode rval = seq_sets->find( *i, seq ); 00421 if( MB_SUCCESS != rval ) return rval; 00422 const MeshSet* ms_ptr = reinterpret_cast< const MeshSetSequence* >( seq )->get_set( *i ); 00423 00424 switch( link_type ) 00425 { 00426 case CONTAINED: 00427 tmp_array = ms_ptr->get_contents( n ); 00428 end = tmp_array + n; 00429 if( ms_ptr->vector_based() ) 00430 { 00431 for( ; tmp_array != end; ++tmp_array ) 00432 if( MBENTITYSET == TYPE_FROM_HANDLE( *tmp_array ) && visited.insert( *tmp_array ).second ) 00433 lists[1 - index].push_back( *tmp_array ); 00434 } 00435 else 00436 { 00437 assert( n % 2 == 0 ); 00438 tmp_array = std::lower_bound( tmp_array, tmp_array + n, FIRST_HANDLE( MBENTITYSET ) ); 00439 // only part of first block is of type 00440 if( ( end - tmp_array ) % 2 ) 00441 { 00442 ++tmp_array; 00443 s = FIRST_HANDLE( MBENTITYSET ); 00444 e = *tmp_array; 00445 for( ; s <= e; ++s ) 00446 if( visited.insert( s ).second ) lists[1 - index].push_back( s ); 00447 } 00448 while( tmp_array < end ) 00449 { 00450 s = *tmp_array++; 00451 e = *tmp_array++; 00452 for( ; s <= e; ++s ) 00453 if( visited.insert( s ).second ) lists[1 - index].push_back( s ); 00454 } 00455 } 00456 continue; 00457 case PARENTS: 00458 tmp_array = ms_ptr->get_parents( count ); 00459 break; 00460 case CHILDREN: 00461 tmp_array = ms_ptr->get_children( count ); 00462 break; 00463 } 00464 00465 // copy any parents/children we haven't visited yet into list 00466 for( end = tmp_array + count; tmp_array != end; ++tmp_array ) 00467 if( visited.insert( *tmp_array ).second ) lists[1 - index].push_back( *tmp_array ); 00468 } 00469 00470 // iterate 00471 lists[index].clear(); 00472 index = 1 - index; 00473 // append each level of sets to the output list. 00474 // note: to make a more useful search (e.g. get entities 3 hops away, 00475 // rather than entities up to and including 3 hops) move this outside 00476 // the loop, but then need to handle the get all (num_hops < 0) case 00477 // specially. 00478 std::copy( lists[index].begin(), lists[index].end(), std::back_inserter( results ) ); 00479 } 00480 00481 return result; 00482 } 00483 00484 ErrorCode MeshSetSequence::get_parents( const SequenceManager* seqman, EntityHandle handle, 00485 std::vector< EntityHandle >& parents, int num_hops ) const 00486 { 00487 if( num_hops == 1 ) 00488 { 00489 int count; 00490 const EntityHandle* tmp_array = get_set( handle )->get_parents( count ); 00491 if( parents.empty() ) 00492 { 00493 parents.resize( count ); 00494 std::copy( tmp_array, tmp_array + count, parents.begin() ); 00495 return MB_SUCCESS; 00496 } 00497 else if( !count ) 00498 { 00499 return MB_SUCCESS; 00500 } 00501 } 00502 00503 if( num_hops > 0 ) 00504 return get_parent_child_meshsets( handle, seqman, parents, num_hops, PARENTS ); 00505 else 00506 return get_parent_child_meshsets( handle, seqman, parents, -1, PARENTS ); 00507 } 00508 00509 ErrorCode MeshSetSequence::get_children( const SequenceManager* seqman, EntityHandle handle, 00510 std::vector< EntityHandle >& children, int num_hops ) const 00511 { 00512 if( num_hops == 1 ) 00513 { 00514 int count; 00515 const EntityHandle* tmp_array = get_set( handle )->get_children( count ); 00516 if( children.empty() ) 00517 { 00518 children.resize( count ); 00519 std::copy( tmp_array, tmp_array + count, children.begin() ); 00520 return MB_SUCCESS; 00521 } 00522 else if( !count ) 00523 { 00524 return MB_SUCCESS; 00525 } 00526 } 00527 00528 if( num_hops > 0 ) 00529 return get_parent_child_meshsets( handle, seqman, children, num_hops, CHILDREN ); 00530 else 00531 return get_parent_child_meshsets( handle, seqman, children, -1, CHILDREN ); 00532 } 00533 00534 ErrorCode MeshSetSequence::get_contained_sets( const SequenceManager* seqman, EntityHandle handle, 00535 std::vector< EntityHandle >& contained, int num_hops ) const 00536 { 00537 if( num_hops == 1 && contained.empty() ) 00538 { return get_set( handle )->get_entities_by_type( MBENTITYSET, contained ); } 00539 00540 if( num_hops > 0 ) 00541 return get_parent_child_meshsets( handle, seqman, contained, num_hops, CONTAINED ); 00542 else 00543 return get_parent_child_meshsets( handle, seqman, contained, -1, CONTAINED ); 00544 } 00545 00546 ErrorCode MeshSetSequence::num_parents( const SequenceManager* seqman, EntityHandle handle, int& number, 00547 int num_hops ) const 00548 { 00549 if( num_hops == 1 ) 00550 { 00551 number = get_set( handle )->num_parents(); 00552 return MB_SUCCESS; 00553 } 00554 00555 std::vector< EntityHandle > parents; 00556 ErrorCode result = get_parents( seqman, handle, parents, num_hops ); 00557 number = parents.size(); 00558 return result; 00559 } 00560 00561 ErrorCode MeshSetSequence::num_children( const SequenceManager* seqman, EntityHandle handle, int& number, 00562 int num_hops ) const 00563 { 00564 if( num_hops == 1 ) 00565 { 00566 number = get_set( handle )->num_children(); 00567 return MB_SUCCESS; 00568 } 00569 00570 std::vector< EntityHandle > children; 00571 ErrorCode result = get_children( seqman, handle, children, num_hops ); 00572 number = children.size(); 00573 return result; 00574 } 00575 00576 ErrorCode MeshSetSequence::num_contained_sets( const SequenceManager* seqman, EntityHandle handle, int& number, 00577 int num_hops ) const 00578 { 00579 if( num_hops == 1 ) 00580 { 00581 number = get_set( handle )->num_entities_by_type( MBENTITYSET ); 00582 return MB_SUCCESS; 00583 } 00584 00585 std::vector< EntityHandle > contained; 00586 ErrorCode result = get_contained_sets( seqman, handle, contained, num_hops ); 00587 number = contained.size(); 00588 return result; 00589 } 00590 00591 } // namespace moab