// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // == http://www.amdis-fem.org == // == == // ============================================================================ // // Software License for AMDiS // // Copyright (c) 2010 Dresden University of Technology // All rights reserved. // Authors: Simon Vey, Thomas Witkowski et al. // // This file is part of AMDiS // // See also license.opensource.txt in the distribution. /** \file DofComm.h */ #ifndef AMDIS_DOF_COMM_H #define AMDIS_DOF_COMM_H #include #include "FiniteElemSpace.h" #include "Global.h" namespace AMDiS { using namespace std; class DofComm { public: DofComm() : data(1) {} typedef map FeMapType; typedef FeMapType::iterator FeMapIter; typedef map DataType; typedef DataType::iterator DataIter; // meshLevel: map[rank -> map[feSpace -> DofContainer]] typedef vector LevelDataType; inline DofContainer& getDofContainer(int rank, const FiniteElemSpace *feSpace, int level = 0) { return data[level][rank][feSpace]; } void removeEmpty(); void init(int nLevels = 1) { data.clear(); data.resize(nLevels); } DataType& getData(int level = 0) { return data[level]; } protected: LevelDataType data; friend class Iterator; public: class Iterator { public: Iterator(DofComm &dc, const FiniteElemSpace *fe = NULL) : dofComm(dc), dofCounter(-1), traverseFeSpace(fe), traverseLevel(0) { goFirst(); } Iterator(DofComm &dc, int level, const FiniteElemSpace *fe = NULL) : dofComm(dc), dofCounter(-1), traverseFeSpace(fe), traverseLevel(level) { goFirst(); } inline bool end() { return (dataIter == dofComm.data[traverseLevel].end()); } inline void nextRank() { do { ++dataIter; } while (setNextFeMap() == false); } inline void nextFeSpace() { ++feMapIter; } inline void next() { ++feMapIter; if (feMapIter == dataIter->second.end()) { do { ++dataIter; } while (setNextFeMap() == false); } else { dofIter = feMapIter->second.begin(); dofCounter = 0; } } inline void beginDofIter(const FiniteElemSpace *fe = NULL) { FUNCNAME("DofComm::Iterator::beginDofIter()"); if (fe != NULL) { feMapIter = dataIter->second.begin(); while (feMapIter->first != fe && feMapIter != dataIter->second.end()) ++feMapIter; } if (feMapIter != dataIter->second.end()) { dofIter = feMapIter->second.begin(); dofCounter = 0; } } inline bool endDofIter() { if (feMapIter == dataIter->second.end()) return true; return (dofIter == feMapIter->second.end()); } inline void nextDof() { ++dofIter; ++dofCounter; } inline int getRank() { return dataIter->first; } inline const FiniteElemSpace* getFeSpace() { return feMapIter->first; } inline DofContainer& getDofs() { return feMapIter->second; } inline const DegreeOfFreedom* getDof() { return *dofIter; } inline DegreeOfFreedom getDofIndex() { return **dofIter; } inline int getDofCounter() { return dofCounter; } protected: void goFirst() { dataIter = dofComm.data[traverseLevel].begin(); while (setNextFeMap() == false) ++dataIter; } bool setNextFeMap(); protected: DofComm &dofComm; DofComm::DataIter dataIter; DofComm::FeMapIter feMapIter; DofContainer::iterator dofIter; int dofCounter; const FiniteElemSpace *traverseFeSpace; int traverseLevel; }; }; } #endif // AMDIS_DOF_COMM_H