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