// ============================================================================ // == == // == 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 "parallel/ParallelTypes.h" #include "FiniteElemSpace.h" #include "Global.h" namespace AMDiS { using namespace std; class DofComm { public: DofComm() : recvDofs(1), sendDofs(1), periodicDofs(0), meshLevel(-1), nLevel(0), levelData(NULL) {} typedef map FeMapType; typedef FeMapType::iterator FeMapIter; typedef map DataType; typedef DataType::iterator DataIter; // meshLevel: map[rank -> map[feSpace -> DofContainer]] typedef vector LevelDataType; void init(int level, MeshLevelData &levelData, vector &fe); void create(InteriorBoundary &boundary); LevelDataType& getSendDofs() { return sendDofs; } LevelDataType& getRecvDofs() { return recvDofs; } LevelDataType& getPeriodicDofs() { return periodicDofs; } // Writes all data of this object to an output stream. void serialize(ostream &out) { ERROR_EXIT("MUST BE IMPLEMENTED!\n"); } // Reads the object data from an input stream. void deserialize(istream &in, map > dofIndexMap) { ERROR_EXIT("MUST BE IMPLEMENTED!\n"); } int getNumberDofs(LevelDataType &data, int level, const FiniteElemSpace *feSpace, bool countDouble = false); protected: void createContainer(RankToBoundMap &boundary, LevelDataType &data); protected: /// This map contains for each rank the list of DOFs the current rank must /// end to exchange solution DOFs at the interior boundaries. LevelDataType sendDofs; /// This map contains on each rank the list of DOFs from which the current /// rank will receive DOF values (i.e., this are all DOFs at an interior /// boundary). The DOF indices are given in rank's local numbering. LevelDataType recvDofs; /// This map contains on each rank a list of DOFs along the interior bound- /// aries to communicate with other ranks. The DOF indices are given in rank's /// local numbering. Periodic boundaries within one subdomain are not /// considered here. LevelDataType periodicDofs; int meshLevel; int nLevel; MeshLevelData *levelData; vector feSpaces; friend class Iterator; public: class Iterator { public: Iterator(LevelDataType &d, const FiniteElemSpace *fe = NULL) : data(d), dofCounter(-1), traverseFeSpace(fe), traverseLevel(0) { goFirst(); } Iterator(LevelDataType &d, int level, const FiniteElemSpace *fe = NULL) : data(d), dofCounter(-1), traverseFeSpace(fe), traverseLevel(level) { goFirst(); } inline bool end() { return (dataIter == 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 = data[traverseLevel].begin(); while (setNextFeMap() == false) ++dataIter; } bool setNextFeMap(); protected: LevelDataType &data; DofComm::DataIter dataIter; DofComm::FeMapIter feMapIter; DofContainer::iterator dofIter; int dofCounter; const FiniteElemSpace *traverseFeSpace; int traverseLevel; }; }; } #endif // AMDIS_DOF_COMM_H