![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 #ifndef __smoab_detail_ReadSparseTag_h
00002 #define __smoab_detail_ReadSparseTag_h
00003
00004 #include "SimpleMoab.h"
00005
00006 #include
00007
00008 #include
00009 #include
00010 #include
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