MOAB: Mesh Oriented datABase  (version 5.2.1)
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 (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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines