Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
ReadSparseTag.h
Go to the documentation of this file.
00001 #ifndef __smoab_detail_ReadSparseTag_h
00002 #define __smoab_detail_ReadSparseTag_h
00003 
00004 #include "SimpleMoab.h"
00005 
00006 #include <vtkIntArray.h>
00007 
00008 #include <string>
00009 #include <algorithm>
00010 #include <vector>
00011 
00012 namespace smoab
00013 {
00014 namespace detail
00015 {
00016 
00017     struct ReadSparseTag
00018     {
00019 
00020         ReadSparseTag( const smoab::CellSets& mSets, const smoab::Range& cells, const smoab::Interface& interface )
00021             : Interface( interface ), MeshSets( mSets ), Cells( cells )
00022         {
00023         }
00024 
00025         //the cellTag describes the tag mapping between the cells
00026         //and meshsets.
00027         void fill( vtkIntArray* array, const Tag* cellTag ) const;
00028         void fill( vtkIdTypeArray* array, const Tag* cellTag ) const;
00029 
00030       private:
00031         template < typename T >
00032         void fillRawArray( T* sparseTagArray, std::size_t length, const Tag* cellTag ) const;
00033 
00034         template < typename T >
00035         void singleSetRead( T* sparseTagArray, const std::vector< int >& values, std::size_t length ) const;
00036 
00037         template < typename T >
00038         void multiSetRead( T* sparseTagArray,
00039                            const std::vector< int >& values,
00040                            std::size_t length,
00041                            int defaultTagValue ) const;
00042 
00043         const smoab::Interface& Interface;
00044         const smoab::CellSets& MeshSets;
00045         const smoab::Range& Cells;
00046     };
00047 
00048     //----------------------------------------------------------------------------
00049     void ReadSparseTag::fill( vtkIntArray* array, const Tag* cellTag ) const
00050     {
00051         const std::size_t length = this->Cells.size();
00052         array->SetNumberOfValues( length );
00053         int* raw = static_cast< int* >( array->GetVoidPointer( 0 ) );
00054         this->fillRawArray( raw, length, cellTag );
00055     }
00056 
00057     //----------------------------------------------------------------------------
00058     void ReadSparseTag::fill( vtkIdTypeArray* array, const Tag* cellTag ) const
00059     {
00060         const std::size_t length = this->Cells.size();
00061         array->SetNumberOfValues( length );
00062         vtkIdType* raw = static_cast< vtkIdType* >( array->GetVoidPointer( 0 ) );
00063         this->fillRawArray( raw, length, cellTag );
00064     }
00065 
00066     //----------------------------------------------------------------------------
00067     template < typename T >
00068     void ReadSparseTag::fillRawArray( T* sparseTagArray, std::size_t length, const smoab::Tag* sparseTag ) const
00069     {
00070 
00071         typedef std::vector< int >::const_iterator IdConstIterator;
00072         typedef std::vector< int >::iterator IdIterator;
00073         typedef smoab::CellSets::const_iterator CellSetIterator;
00074 
00075         std::vector< int > sparseTagValues( this->MeshSets.size() );
00076         //first off iterate the entities and determine which ones
00077         //have moab material ids
00078 
00079         //todo get proper default value from moab
00080         //wrap this area with scope, to remove local variables
00081 
00082         {
00083             const moab::Tag stag = this->Interface.getMoabTag( *sparseTag );
00084             IdIterator tagIds    = sparseTagValues.begin();
00085             for( CellSetIterator i = this->MeshSets.begin(); i != this->MeshSets.end(); ++i, ++tagIds )
00086             {
00087                 //getTagData clobbers defaultValue
00088                 int defaultValue = this->Interface.getDefaultTagVaue< int >( stag );
00089                 *tagIds          = this->Interface.getTagData( stag, i->entity(), defaultValue );
00090             }
00091 
00092             //now determine ids for all entities that don't have materials
00093             IdConstIterator maxPos = std::max_element( sparseTagValues.begin(), sparseTagValues.end() );
00094             int maxValue           = *maxPos;
00095             for( IdIterator i = sparseTagValues.begin(); i != sparseTagValues.end(); ++i )
00096             {
00097                 if( *i == -1 )
00098                 {
00099                     *i = ++maxValue;
00100                 }
00101             }
00102         }
00103         if( this->MeshSets.size() == 1 )
00104         {
00105             this->singleSetRead( sparseTagArray, sparseTagValues, length );
00106         }
00107         else
00108         {
00109             int defaultValue = this->Interface.getDefaultTagVaue< int >( *sparseTag );
00110             this->multiSetRead( sparseTagArray, sparseTagValues, length, defaultValue );
00111         }
00112     }
00113 
00114     //----------------------------------------------------------------------------
00115     template < typename T >
00116     void ReadSparseTag::singleSetRead( T* sparseTagArray, const std::vector< int >& values, std::size_t length ) const
00117     {
00118 
00119         //now we set all the values as this has a single meshset so we
00120         //have no complicated logic for mapping each cell to a meshset
00121         T value = static_cast< T >( values[0] );
00122         std::fill( sparseTagArray, sparseTagArray + length, value );
00123     }
00124 
00125     //----------------------------------------------------------------------------
00126     template < typename T >
00127     void ReadSparseTag::multiSetRead( T* sparseTagArray,
00128                                       const std::vector< int >& sparseTagValues,
00129                                       std::size_t numCells,
00130                                       int defaultTagValue ) const
00131     {
00132         typedef std::vector< smoab::EntityHandle >::const_iterator EntityHandleIterator;
00133         typedef std::vector< int >::const_iterator IdConstIterator;
00134         typedef smoab::CellSets::const_iterator CellSetIterator;
00135         typedef smoab::Range::const_iterator RangeIterator;
00136 
00137         //create the search structure as a range is really slow to search with
00138         //lower_bounds
00139         std::vector< smoab::EntityHandle > searchableCells;
00140         smoab::RangeToVector( this->Cells, searchableCells );
00141 
00142         //pre fill with -1 to mark cells we don't touch, since some cells
00143         //might no have a default tag
00144         T defaultValue = T( defaultTagValue );
00145         std::fill( sparseTagArray, sparseTagArray + numCells, defaultValue );
00146 
00147         EntityHandleIterator s_begin = searchableCells.begin();
00148         EntityHandleIterator s_end   = searchableCells.end();
00149 
00150         IdConstIterator currentTagValue = sparseTagValues.begin();
00151         for( CellSetIterator i = this->MeshSets.begin(); i != this->MeshSets.end(); ++i, ++currentTagValue )
00152         {
00153             T value = static_cast< T >( *currentTagValue );
00154 
00155             const smoab::Range& entitiesCells = i->cells();
00156             for( RangeIterator j = entitiesCells.begin(); j != entitiesCells.end(); ++j )
00157             {
00158                 EntityHandleIterator result = std::lower_bound( s_begin, s_end, *j );
00159                 std::size_t newId           = std::distance( s_begin, result );
00160                 sparseTagArray[newId]       = value;
00161             }
00162         }
00163     }
00164 
00165 }  // namespace detail
00166 }  // namespace smoab
00167 
00168 #endif  // __smoab_detail_ReadSparseTag_h
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines