// ============================================================================ // == == // == 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 InteriorBoundary.h */ #ifndef AMDIS_INTERIORBOUNDARY_H #define AMDIS_INTERIORBOUNDARY_H #include #include #include "AMDiS_fwd.h" #include "BoundaryObject.h" #include "parallel/MeshLevelData.h" #include "parallel/ParallelTypes.h" namespace AMDiS { using namespace std; /** \brief * Defines the interior boundary, i.e. a bound within the domain. It is used for * the classical domain decomposition parallelization. */ class InteriorBoundary { public: void create(MPI::Intracomm &mpiComm, ElementObjectDatabase &elObjDb); /// Writes this object to a file. void serialize(ostream &out); /// Reads the state of an interior boundary from a file. void deserialize(istream &in, map &elIndexMap); RankToBoundMap& getOwn() { return own; } RankToBoundMap& getOther() { return other; } RankToBoundMap& getPeriodic() { return periodic; } bool hasPeriodic() { return static_cast(periodic.size()); } private: AtomicBoundary& getNewOwn(int rank); AtomicBoundary& getNewOther(int rank); AtomicBoundary& getNewPeriodic(int rank); void serializeExcludeList(ostream &out, ExcludeList &list); void deserializeExcludeList(istream &in, ExcludeList &list); private: RankToBoundMap own, other, periodic; friend class ParallelDebug; public: /// Iterator for the interior boundary object. class iterator { public: iterator(RankToBoundMap &b, int traverseLevel = 0) : bound(b), level(traverseLevel) { reset(); } /// Set the iterator to the first position. void reset() { mapIt = bound.begin(); nextNonempty(); } /// Test if iterator is at the final position. bool end() const { return (mapIt == bound.end()); } /// Move iterator to the next position. void operator++() { do { ++vecIt; } while (vecIt->maxLevel < level && vecIt != mapIt->second.end()); if (vecIt == mapIt->second.end()) { ++mapIt; nextNonempty(); } } inline AtomicBoundary& operator*() { return *vecIt; } inline AtomicBoundary* operator->() { return &(*vecIt); } void nextRank() { ++mapIt; nextNonempty(); } inline int getRank() { return mapIt->first; } protected: inline void nextNonempty() { do { // Return, we are at the end. if (mapIt == bound.end()) return; // Search for the next non empty boundary map. while (mapIt->second.size() == 0) { ++mapIt; if (mapIt == bound.end()) return; } vecIt = mapIt->second.begin(); // Search for the next atomic boundary on the mesh level while (vecIt->maxLevel < level && vecIt != mapIt->second.end()) ++vecIt; // If vector iterator is not at the end, we have found one and // can return. if (vecIt != mapIt->second.end()) return; // In this case, no boundary on the given level is found, continue // with next rank. ++mapIt; } while (true); } protected: RankToBoundMap::iterator mapIt; vector::iterator vecIt; RankToBoundMap &bound; int level; }; }; } #endif // AMDIS_INTERIORBOUNDARY_H