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 <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