Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
MeshSetSequence.cpp
Go to the documentation of this file.
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 ([email protected])
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,
00133                                          EntityHandle handle,
00134                                          Range& entities,
00135                                          bool recursive ) const
00136 {
00137     if( !recursive )
00138     {
00139         get_set( handle )->get_entities( entities );
00140         return MB_SUCCESS;
00141     }
00142     else
00143     {
00144         std::vector< const MeshSet* > list;
00145         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00146         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00147             ( *i )->get_non_set_entities( entities );
00148         return rval;
00149     }
00150 }
00151 
00152 ErrorCode MeshSetSequence::get_entities( EntityHandle handle, std::vector< EntityHandle >& entities ) const
00153 {
00154     get_set( handle )->get_entities( entities );
00155     return MB_SUCCESS;
00156 }
00157 
00158 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman,
00159                                           EntityHandle handle,
00160                                           int dimension,
00161                                           std::vector< EntityHandle >& entities,
00162                                           bool recursive ) const
00163 {
00164     if( !recursive )
00165     {
00166         get_set( handle )->get_entities_by_dimension( dimension, entities );
00167         return MB_SUCCESS;
00168     }
00169     else
00170     {
00171         std::vector< const MeshSet* > list;
00172         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00173         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00174             ( *i )->get_entities_by_dimension( dimension, entities );
00175         return rval;
00176     }
00177 }
00178 
00179 ErrorCode MeshSetSequence::get_dimension( const SequenceManager* seqman,
00180                                           EntityHandle handle,
00181                                           int dimension,
00182                                           Range& entities,
00183                                           bool recursive ) const
00184 {
00185     if( !recursive )
00186     {
00187         get_set( handle )->get_entities_by_dimension( dimension, entities );
00188         return MB_SUCCESS;
00189     }
00190     else
00191     {
00192         std::vector< const MeshSet* > list;
00193         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00194         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00195             ( *i )->get_entities_by_dimension( dimension, entities );
00196         return rval;
00197     }
00198 }
00199 
00200 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman,
00201                                      EntityHandle handle,
00202                                      EntityType tp,
00203                                      std::vector< EntityHandle >& entities,
00204                                      bool recursive ) const
00205 {
00206     if( !recursive )
00207     {
00208         get_set( handle )->get_entities_by_type( tp, entities );
00209         return MB_SUCCESS;
00210     }
00211     else if( tp == MBENTITYSET )
00212     {
00213         return recursive_get_sets( handle, seqman, 0, 0, &entities );
00214     }
00215     else if( tp == MBMAXTYPE )
00216     {
00217         Range tmp;
00218         ErrorCode rval = get_entities( seqman, handle, tmp, recursive );
00219         if( MB_SUCCESS == rval )
00220         {
00221 #ifdef MOAB_NO_VECTOR_TEMPLATE_INSERT
00222             std::copy( tmp.begin(), tmp.end(), std::back_inserter( entities ) );
00223 #else
00224             entities.insert( entities.end(), tmp.begin(), tmp.end() );
00225 #endif
00226         }
00227         return rval;
00228     }
00229     else
00230     {
00231         std::vector< const MeshSet* > list;
00232         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00233         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00234             ( *i )->get_entities_by_type( tp, entities );
00235         return rval;
00236     }
00237 }
00238 
00239 ErrorCode MeshSetSequence::get_type( const SequenceManager* seqman,
00240                                      EntityHandle handle,
00241                                      EntityType tp,
00242                                      Range& entities,
00243                                      bool recursive ) const
00244 {
00245     if( !recursive )
00246     {
00247         get_set( handle )->get_entities_by_type( tp, entities );
00248         return MB_SUCCESS;
00249     }
00250     else if( tp == MBENTITYSET )
00251     {
00252         return recursive_get_sets( handle, seqman, 0, &entities );
00253     }
00254     else if( tp == MBMAXTYPE )
00255     {
00256         std::vector< const MeshSet* > list;
00257         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00258         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00259             ( *i )->get_non_set_entities( entities );
00260         return rval;
00261     }
00262     else
00263     {
00264         std::vector< const MeshSet* > list;
00265         ErrorCode rval = recursive_get_sets( handle, seqman, &list );
00266         for( std::vector< const MeshSet* >::iterator i = list.begin(); i != list.end(); ++i )
00267             ( *i )->get_entities_by_type( tp, entities );
00268         return rval;
00269     }
00270 }
00271 
00272 ErrorCode MeshSetSequence::num_entities( const SequenceManager* seqman,
00273                                          EntityHandle handle,
00274                                          int& number,
00275                                          bool recursive ) const
00276 {
00277     if( !recursive )
00278     {
00279         number = get_set( handle )->num_entities();
00280         return MB_SUCCESS;
00281     }
00282     else
00283     {
00284         Range range;
00285         ErrorCode result = get_entities( seqman, handle, range, true );
00286         number           = range.size();
00287         return result;
00288     }
00289 }
00290 
00291 ErrorCode MeshSetSequence::num_dimension( const SequenceManager* seqman,
00292                                           EntityHandle handle,
00293                                           int dimension,
00294                                           int& number,
00295                                           bool recursive ) const
00296 {
00297     if( !recursive )
00298     {
00299         number = get_set( handle )->num_entities_by_dimension( dimension );
00300         return MB_SUCCESS;
00301     }
00302     else
00303     {
00304         Range range;
00305         ErrorCode result = get_dimension( seqman, handle, dimension, range, true );
00306         number           = range.size();
00307         return result;
00308     }
00309 }
00310 
00311 ErrorCode MeshSetSequence::num_type( const SequenceManager* seqman,
00312                                      EntityHandle handle,
00313                                      EntityType tp,
00314                                      int& number,
00315                                      bool recursive ) const
00316 {
00317     if( !recursive )
00318     {
00319         number = get_set( handle )->num_entities_by_type( tp );
00320         return MB_SUCCESS;
00321     }
00322     else
00323     {
00324         Range range;
00325         ErrorCode result = get_type( seqman, handle, tp, range, true );
00326         number           = range.size();
00327         return result;
00328     }
00329 }
00330 
00331 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set,
00332                                                const SequenceManager* seq_sets,
00333                                                std::vector< const MeshSet* >* sets,
00334                                                Range* set_handles,
00335                                                std::vector< EntityHandle >* set_vector )
00336 {
00337     std::set< EntityHandle > visited;
00338     std::vector< EntityHandle > stack;
00339     stack.push_back( start_set );
00340     bool remove_start_set = true;
00341     while( !stack.empty() )
00342     {
00343         EntityHandle handle = stack.back();
00344         stack.pop_back();
00345 
00346         if( !visited.insert( handle ).second )
00347         {
00348             if( handle == start_set ) remove_start_set = false;
00349             continue;
00350         }
00351 
00352         const EntitySequence* seq;
00353         ErrorCode rval = seq_sets->find( handle, seq );
00354         if( MB_SUCCESS != rval ) return rval;
00355 
00356         const MeshSetSequence* mseq = reinterpret_cast< const MeshSetSequence* >( seq );
00357         const MeshSet* ms_ptr       = mseq->get_set( handle );
00358         if( sets ) sets->push_back( ms_ptr );
00359 
00360         Range tmp_range;
00361         ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
00362         std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
00363     }
00364 
00365     if( set_handles )
00366     {
00367         if( remove_start_set ) visited.erase( start_set );
00368         Range::iterator hint = set_handles->begin();
00369         std::set< EntityHandle >::iterator it;
00370         for( it = visited.begin(); it != visited.end(); ++it )
00371             hint = set_handles->insert( hint, *it, *it );
00372     }
00373 
00374     if( set_vector )
00375     {
00376         if( remove_start_set ) visited.erase( start_set );
00377         std::copy( visited.begin(), visited.end(), std::back_inserter( *set_vector ) );
00378     }
00379 
00380     return MB_SUCCESS;
00381 }
00382 
00383 ErrorCode MeshSetSequence::recursive_get_sets( EntityHandle start_set,
00384                                                SequenceManager* seq_sets,
00385                                                std::vector< MeshSet* >& sets )
00386 {
00387     std::set< EntityHandle > visited;
00388     std::vector< EntityHandle > stack;
00389     stack.push_back( start_set );
00390     while( !stack.empty() )
00391     {
00392         EntityHandle handle = stack.back();
00393         stack.pop_back();
00394 
00395         if( !visited.insert( handle ).second ) continue;
00396 
00397         EntitySequence* seq;
00398         ErrorCode rval = seq_sets->find( handle, seq );
00399         if( MB_SUCCESS != rval ) return rval;
00400 
00401         MeshSetSequence* mseq = reinterpret_cast< MeshSetSequence* >( seq );
00402         MeshSet* ms_ptr       = mseq->get_set( handle );
00403         sets.push_back( ms_ptr );
00404 
00405         Range tmp_range;
00406         ms_ptr->get_entities_by_type( MBENTITYSET, tmp_range );
00407         std::copy( tmp_range.begin(), tmp_range.end(), std::back_inserter( stack ) );
00408     }
00409 
00410     return MB_SUCCESS;
00411 }
00412 
00413 ErrorCode MeshSetSequence::get_parent_child_meshsets( EntityHandle meshset,
00414                                                       const SequenceManager* seq_sets,
00415                                                       std::vector< EntityHandle >& results,
00416                                                       int num_hops,
00417                                                       SearchType link_type ) const
00418 {
00419     ErrorCode result = MB_SUCCESS;
00420     std::vector< EntityHandle >::iterator i;
00421     const EntityHandle *tmp_array = 0, *end;
00422     EntityHandle s, e;
00423     int count = 0;
00424     size_t n;
00425 
00426     // Skip any meshsets already in input vector (yes, don't
00427     // get their children either even if num_hops would indicate
00428     // that we should.)  There is an exception to that if the
00429     // input meshset is in the list, which is handled by the order
00430     // of checks in the main loop below.
00431     std::set< EntityHandle > visited;
00432     for( i = results.begin(); i != results.end(); ++i )
00433         visited.insert( *i );
00434 
00435     // Two lists for breadth-first search
00436     std::vector< EntityHandle > lists[2];
00437     int index = 0;                      // which list to read from (write to lists[1-index])
00438     lists[index].push_back( meshset );  // begin with input set
00439                                         // loop for num_hops (or until no more sets)
00440     for( ; num_hops && !lists[index].empty(); --num_hops )
00441     {
00442         // for each set at the current num_hops
00443         for( i = lists[index].begin(); i != lists[index].end(); ++i )
00444         {
00445             // get meshset from handle
00446             const EntitySequence* seq;
00447             ErrorCode rval = seq_sets->find( *i, seq );
00448             if( MB_SUCCESS != rval ) return rval;
00449             const MeshSet* ms_ptr = reinterpret_cast< const MeshSetSequence* >( seq )->get_set( *i );
00450 
00451             switch( link_type )
00452             {
00453                 case CONTAINED:
00454                     tmp_array = ms_ptr->get_contents( n );
00455                     end       = tmp_array + n;
00456                     if( ms_ptr->vector_based() )
00457                     {
00458                         for( ; tmp_array != end; ++tmp_array )
00459                             if( MBENTITYSET == TYPE_FROM_HANDLE( *tmp_array ) && visited.insert( *tmp_array ).second )
00460                                 lists[1 - index].push_back( *tmp_array );
00461                     }
00462                     else
00463                     {
00464                         assert( n % 2 == 0 );
00465                         tmp_array = std::lower_bound( tmp_array, tmp_array + n, FIRST_HANDLE( MBENTITYSET ) );
00466                         // only part of first block is of type
00467                         if( ( end - tmp_array ) % 2 )
00468                         {
00469                             ++tmp_array;
00470                             s = FIRST_HANDLE( MBENTITYSET );
00471                             e = *tmp_array;
00472                             for( ; s <= e; ++s )
00473                                 if( visited.insert( s ).second ) lists[1 - index].push_back( s );
00474                         }
00475                         while( tmp_array < end )
00476                         {
00477                             s = *tmp_array++;
00478                             e = *tmp_array++;
00479                             for( ; s <= e; ++s )
00480                                 if( visited.insert( s ).second ) lists[1 - index].push_back( s );
00481                         }
00482                     }
00483                     continue;
00484                 case PARENTS:
00485                     tmp_array = ms_ptr->get_parents( count );
00486                     break;
00487                 case CHILDREN:
00488                     tmp_array = ms_ptr->get_children( count );
00489                     break;
00490             }
00491 
00492             // copy any parents/children we haven't visited yet into list
00493             for( end = tmp_array + count; tmp_array != end; ++tmp_array )
00494                 if( visited.insert( *tmp_array ).second ) lists[1 - index].push_back( *tmp_array );
00495         }
00496 
00497         // iterate
00498         lists[index].clear();
00499         index = 1 - index;
00500         // append each level of sets to the output list.
00501         // note: to make a more useful search (e.g. get entities 3 hops away,
00502         // rather than entities up to and including 3 hops) move this outside
00503         // the loop, but then need to handle the get all (num_hops < 0) case
00504         // specially.
00505         std::copy( lists[index].begin(), lists[index].end(), std::back_inserter( results ) );
00506     }
00507 
00508     return result;
00509 }
00510 
00511 ErrorCode MeshSetSequence::get_parents( const SequenceManager* seqman,
00512                                         EntityHandle handle,
00513                                         std::vector< EntityHandle >& parents,
00514                                         int num_hops ) const
00515 {
00516     if( num_hops == 1 )
00517     {
00518         int count;
00519         const EntityHandle* tmp_array = get_set( handle )->get_parents( count );
00520         if( parents.empty() )
00521         {
00522             parents.resize( count );
00523             std::copy( tmp_array, tmp_array + count, parents.begin() );
00524             return MB_SUCCESS;
00525         }
00526         else if( !count )
00527         {
00528             return MB_SUCCESS;
00529         }
00530     }
00531 
00532     if( num_hops > 0 )
00533         return get_parent_child_meshsets( handle, seqman, parents, num_hops, PARENTS );
00534     else
00535         return get_parent_child_meshsets( handle, seqman, parents, -1, PARENTS );
00536 }
00537 
00538 ErrorCode MeshSetSequence::get_children( const SequenceManager* seqman,
00539                                          EntityHandle handle,
00540                                          std::vector< EntityHandle >& children,
00541                                          int num_hops ) const
00542 {
00543     if( num_hops == 1 )
00544     {
00545         int count;
00546         const EntityHandle* tmp_array = get_set( handle )->get_children( count );
00547         if( children.empty() )
00548         {
00549             children.resize( count );
00550             std::copy( tmp_array, tmp_array + count, children.begin() );
00551             return MB_SUCCESS;
00552         }
00553         else if( !count )
00554         {
00555             return MB_SUCCESS;
00556         }
00557     }
00558 
00559     if( num_hops > 0 )
00560         return get_parent_child_meshsets( handle, seqman, children, num_hops, CHILDREN );
00561     else
00562         return get_parent_child_meshsets( handle, seqman, children, -1, CHILDREN );
00563 }
00564 
00565 ErrorCode MeshSetSequence::get_contained_sets( const SequenceManager* seqman,
00566                                                EntityHandle handle,
00567                                                std::vector< EntityHandle >& contained,
00568                                                int num_hops ) const
00569 {
00570     if( num_hops == 1 && contained.empty() )
00571     {
00572         return get_set( handle )->get_entities_by_type( MBENTITYSET, contained );
00573     }
00574 
00575     if( num_hops > 0 )
00576         return get_parent_child_meshsets( handle, seqman, contained, num_hops, CONTAINED );
00577     else
00578         return get_parent_child_meshsets( handle, seqman, contained, -1, CONTAINED );
00579 }
00580 
00581 ErrorCode MeshSetSequence::num_parents( const SequenceManager* seqman,
00582                                         EntityHandle handle,
00583                                         int& number,
00584                                         int num_hops ) const
00585 {
00586     if( num_hops == 1 )
00587     {
00588         number = get_set( handle )->num_parents();
00589         return MB_SUCCESS;
00590     }
00591 
00592     std::vector< EntityHandle > parents;
00593     ErrorCode result = get_parents( seqman, handle, parents, num_hops );
00594     number           = parents.size();
00595     return result;
00596 }
00597 
00598 ErrorCode MeshSetSequence::num_children( const SequenceManager* seqman,
00599                                          EntityHandle handle,
00600                                          int& number,
00601                                          int num_hops ) const
00602 {
00603     if( num_hops == 1 )
00604     {
00605         number = get_set( handle )->num_children();
00606         return MB_SUCCESS;
00607     }
00608 
00609     std::vector< EntityHandle > children;
00610     ErrorCode result = get_children( seqman, handle, children, num_hops );
00611     number           = children.size();
00612     return result;
00613 }
00614 
00615 ErrorCode MeshSetSequence::num_contained_sets( const SequenceManager* seqman,
00616                                                EntityHandle handle,
00617                                                int& number,
00618                                                int num_hops ) const
00619 {
00620     if( num_hops == 1 )
00621     {
00622         number = get_set( handle )->num_entities_by_type( MBENTITYSET );
00623         return MB_SUCCESS;
00624     }
00625 
00626     std::vector< EntityHandle > contained;
00627     ErrorCode result = get_contained_sets( seqman, handle, contained, num_hops );
00628     number           = contained.size();
00629     return result;
00630 }
00631 
00632 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines