Commit 2c1211fd authored by Thomas Witkowski's avatar Thomas Witkowski
Browse files

So, it compiles and all four parallel tests are fine.

parent 227aa1e9
...@@ -104,7 +104,8 @@ namespace AMDiS { ...@@ -104,7 +104,8 @@ namespace AMDiS {
*/ */
struct AtomicBoundary { struct AtomicBoundary {
AtomicBoundary() AtomicBoundary()
: type(INTERIOR) : type(INTERIOR),
maxLevel(0)
{} {}
bool operator==(const AtomicBoundary& other) const; bool operator==(const AtomicBoundary& other) const;
...@@ -119,6 +120,8 @@ namespace AMDiS { ...@@ -119,6 +120,8 @@ namespace AMDiS {
/// boundaries. Till now it is used only for periodic boundaries, which are /// boundaries. Till now it is used only for periodic boundaries, which are
/// also handles as interior boundaries. /// also handles as interior boundaries.
BoundaryType type; BoundaryType type;
int maxLevel;
}; };
......
...@@ -388,6 +388,10 @@ namespace AMDiS { ...@@ -388,6 +388,10 @@ namespace AMDiS {
vertexInRank.clear(); vertexInRank.clear();
for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin(); for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin();
it != vertexElements.end(); ++it) { it != vertexElements.end(); ++it) {
vector<std::set<int> > ranksInLevel;
ranksInLevel.resize(nLevel);
for (vector<ElementObjectData>::iterator it2 = it->second.begin(); for (vector<ElementObjectData>::iterator it2 = it->second.begin();
it2 != it->second.end(); ++it2) { it2 != it->second.end(); ++it2) {
int elementInRank = macroElementRankMap[it2->elIndex]; int elementInRank = macroElementRankMap[it2->elIndex];
...@@ -400,7 +404,18 @@ namespace AMDiS { ...@@ -400,7 +404,18 @@ namespace AMDiS {
vertexOwner[it->first][level] = vertexOwner[it->first][level] =
std::max(vertexOwner[it->first][level], levelId); std::max(vertexOwner[it->first][level], levelId);
} }
ranksInLevel[0].insert(elementInRank);
for (int level = 1; level < nLevel; level++)
ranksInLevel[level].insert(levelData.getLevelId(level, elementInRank));
} }
int maxLevel = 0;
for (int level = 1; level < nLevel; level++)
if (ranksInLevel[level].size() > 1)
maxLevel = level;
vertexMaxLevel[it->first] = maxLevel;
} }
...@@ -408,6 +423,10 @@ namespace AMDiS { ...@@ -408,6 +423,10 @@ namespace AMDiS {
edgeInRank.clear(); edgeInRank.clear();
for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin(); for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin();
it != edgeElements.end(); ++it) { it != edgeElements.end(); ++it) {
vector<std::set<int> > ranksInLevel;
ranksInLevel.resize(nLevel);
for (vector<ElementObjectData>::iterator it2 = it->second.begin(); for (vector<ElementObjectData>::iterator it2 = it->second.begin();
it2 != it->second.end(); ++it2) { it2 != it->second.end(); ++it2) {
int elementInRank = macroElementRankMap[it2->elIndex]; int elementInRank = macroElementRankMap[it2->elIndex];
...@@ -420,7 +439,18 @@ namespace AMDiS { ...@@ -420,7 +439,18 @@ namespace AMDiS {
edgeOwner[it->first][level] = edgeOwner[it->first][level] =
std::max(edgeOwner[it->first][level], levelId); std::max(edgeOwner[it->first][level], levelId);
} }
ranksInLevel[0].insert(elementInRank);
for (int level = 1; level < nLevel; level++)
ranksInLevel[level].insert(levelData.getLevelId(level, elementInRank));
} }
int maxLevel = 0;
for (int level = 1; level < nLevel; level++)
if (ranksInLevel[level].size() > 1)
maxLevel = level;
edgeMaxLevel[it->first] = maxLevel;
} }
...@@ -428,6 +458,10 @@ namespace AMDiS { ...@@ -428,6 +458,10 @@ namespace AMDiS {
faceInRank.clear(); faceInRank.clear();
for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin(); for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin();
it != faceElements.end(); ++it) { it != faceElements.end(); ++it) {
vector<std::set<int> > ranksInLevel;
ranksInLevel.resize(nLevel);
for (vector<ElementObjectData>::iterator it2 = it->second.begin(); for (vector<ElementObjectData>::iterator it2 = it->second.begin();
it2 != it->second.end(); ++it2) { it2 != it->second.end(); ++it2) {
int elementInRank = macroElementRankMap[it2->elIndex]; int elementInRank = macroElementRankMap[it2->elIndex];
...@@ -440,7 +474,18 @@ namespace AMDiS { ...@@ -440,7 +474,18 @@ namespace AMDiS {
faceOwner[it->first][level] = faceOwner[it->first][level] =
std::max(faceOwner[it->first][level], levelId); std::max(faceOwner[it->first][level], levelId);
} }
ranksInLevel[0].insert(elementInRank);
for (int level = 1; level < nLevel; level++)
ranksInLevel[level].insert(levelData.getLevelId(level, elementInRank));
} }
int maxLevel = 0;
for (int level = 1; level < nLevel; level++)
if (ranksInLevel[level].size() > 1)
maxLevel = level;
faceMaxLevel[it->first] = maxLevel;
} }
} }
......
...@@ -279,6 +279,26 @@ namespace AMDiS { ...@@ -279,6 +279,26 @@ namespace AMDiS {
} }
} }
/// Returns the rank owner of the current iterator position.
int getIterateMaxLevel()
{
switch (iterGeoPos) {
case VERTEX:
return vertexMaxLevel[vertexIter->first];
break;
case EDGE:
return edgeMaxLevel[edgeIter->first];
break;
case FACE:
return faceMaxLevel[faceIter->first];
break;
default:
ERROR_EXIT("Should not happen!\n");
// Will never be reached, just to avoid compiler warnings.
return -1;
}
}
/// Returns the rank owner of a vertex DOF. /// Returns the rank owner of a vertex DOF.
int getOwner(DegreeOfFreedom vertex, int level) int getOwner(DegreeOfFreedom vertex, int level)
...@@ -554,6 +574,13 @@ namespace AMDiS { ...@@ -554,6 +574,13 @@ namespace AMDiS {
/// Defines for all faces the rank that ownes this face. /// Defines for all faces the rank that ownes this face.
map<DofFace, LevelRank> faceOwner; map<DofFace, LevelRank> faceOwner;
map<DegreeOfFreedom, int> vertexMaxLevel;
map<DofEdge, int> edgeMaxLevel;
map<DofFace, int> faceMaxLevel;
/// Defines to each vertex DOF a map that maps to each rank number the element /// Defines to each vertex DOF a map that maps to each rank number the element
/// objects that have this vertex DOF in common. /// objects that have this vertex DOF in common.
......
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
namespace AMDiS { namespace AMDiS {
AtomicBoundary& InteriorBoundary::getNewAtomic(int level, int rank) AtomicBoundary& InteriorBoundary::getNewAtomic(int rank)
{ {
int size = boundary[level][rank].size(); int size = boundary[rank].size();
boundary[level][rank].resize(size + 1); boundary[rank].resize(size + 1);
return boundary[level][rank][size]; return boundary[rank][size];
} }
...@@ -34,20 +34,20 @@ namespace AMDiS { ...@@ -34,20 +34,20 @@ namespace AMDiS {
return false; return false;
for (unsigned int level = 0; level < boundary.size(); level++) { for (unsigned int level = 0; level < boundary.size(); level++) {
for (RankToBoundMap::const_iterator it = boundary[level].begin(); for (RankToBoundMap::const_iterator it = boundary.begin();
it != boundary[level].end(); ++it) { it != boundary.end(); ++it) {
if (other2.boundary[level].count(it->first) == 0) if (other2.boundary.count(it->first) == 0)
return false; return false;
if (other2.boundary[level][it->first].size() != it->second.size()) if (other2.boundary[it->first].size() != it->second.size())
return false; return false;
for (unsigned int i = 0; i < it->second.size(); i++) { for (unsigned int i = 0; i < it->second.size(); i++) {
std::vector<AtomicBoundary>::iterator bIt = std::vector<AtomicBoundary>::iterator bIt =
find(other2.boundary[level][it->first].begin(), find(other2.boundary[it->first].begin(),
other2.boundary[level][it->first].end(), it->second[i]); other2.boundary[it->first].end(), it->second[i]);
if (bIt == other2.boundary[level][it->first].end()) if (bIt == other2.boundary[it->first].end())
return false; return false;
} }
} }
...@@ -57,14 +57,11 @@ namespace AMDiS { ...@@ -57,14 +57,11 @@ namespace AMDiS {
} }
void InteriorBoundary::reset(int level) void InteriorBoundary::clear()
{ {
FUNCNAME("InteriorBoundary::reset()"); FUNCNAME("InteriorBoundary::clear()");
nLevel = level;
boundary.clear(); boundary.clear();
boundary.resize(nLevel);
} }
......
...@@ -45,49 +45,36 @@ namespace AMDiS { ...@@ -45,49 +45,36 @@ namespace AMDiS {
/// Iterator for the interior boundary object. /// Iterator for the interior boundary object.
class iterator { class iterator {
public: public:
iterator(InteriorBoundary &b) iterator(InteriorBoundary &b, int traverseLevel = 0)
: bound(b), : bound(b),
level(0) level(traverseLevel)
{ {
reset(); reset();
} }
iterator(InteriorBoundary &b, int level)
: bound(b),
level(level)
{
TEST_EXIT_DBG(level < bound.boundary.size())
("Should not happen!\n");
reset();
}
/// Set the iterator to the first position. /// Set the iterator to the first position.
void reset() void reset()
{ {
mapIt = bound.boundary[level].begin(); mapIt = bound.boundary.begin();
nextNonempty(); nextNonempty();
if (mapIt != bound.boundary[level].end())
vecIt = mapIt->second.begin();
} }
/// Test if iterator is at the final position. /// Test if iterator is at the final position.
bool end() const bool end() const
{ {
return (mapIt == bound.boundary[level].end()); return (mapIt == bound.boundary.end());
} }
/// Move iterator to the next position. /// Move iterator to the next position.
void operator++() void operator++()
{ {
++vecIt; do {
++vecIt;
} while (vecIt->maxLevel < level && vecIt != mapIt->second.end());
if (vecIt == mapIt->second.end()) { if (vecIt == mapIt->second.end()) {
++mapIt; ++mapIt;
nextNonempty(); nextNonempty();
if (mapIt != bound.boundary[level].end())
vecIt = mapIt->second.begin();
} }
} }
...@@ -105,9 +92,6 @@ namespace AMDiS { ...@@ -105,9 +92,6 @@ namespace AMDiS {
{ {
++mapIt; ++mapIt;
nextNonempty(); nextNonempty();
if (mapIt != bound.boundary[level].end())
vecIt = mapIt->second.begin();
} }
inline int getRank() inline int getRank()
...@@ -119,14 +103,33 @@ namespace AMDiS { ...@@ -119,14 +103,33 @@ namespace AMDiS {
inline void nextNonempty() inline void nextNonempty()
{ {
if (mapIt == bound.boundary[level].end()) do {
return; // Return, we are at the end.
if (mapIt == bound.boundary.end())
while (mapIt->second.size() == 0) { return;
// Search for the next non empty boundary map.
while (mapIt->second.size() == 0) {
++mapIt;
if (mapIt == bound.boundary.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; ++mapIt;
if (mapIt == bound.boundary[level].end()) } while (true);
return;
}
} }
protected: protected:
...@@ -140,15 +143,9 @@ namespace AMDiS { ...@@ -140,15 +143,9 @@ namespace AMDiS {
}; };
public: public:
InteriorBoundary(int l = 1) void clear();
: nLevel(l)
{
boundary.resize(nLevel);
}
void reset(int nLevel); AtomicBoundary& getNewAtomic(int rank);
AtomicBoundary& getNewAtomic(int level, int rank);
/// Writes this object to a file. /// Writes this object to a file.
void serialize(ostream &out); void serialize(ostream &out);
...@@ -166,10 +163,7 @@ namespace AMDiS { ...@@ -166,10 +163,7 @@ namespace AMDiS {
void deserializeExcludeList(istream &in, ExcludeList &list); void deserializeExcludeList(istream &in, ExcludeList &list);
public: public:
vector<RankToBoundMap> boundary; RankToBoundMap boundary;
protected:
int nLevel;
}; };
} }
......
...@@ -1576,19 +1576,9 @@ namespace AMDiS { ...@@ -1576,19 +1576,9 @@ namespace AMDiS {
// === Clear all relevant data structures. === // === Clear all relevant data structures. ===
int nLevel = levelData.getLevelNumber(); rankIntBoundary.clear();
rankIntBoundary.reset(nLevel); otherIntBoundary.clear();
otherIntBoundary.reset(nLevel); periodicBoundary.clear();
periodicBoundary.reset(nLevel);
for (int level = 0; level < nLevel; level++)
createBoundaryData(level);
}
void MeshDistributor::createBoundaryData(int level)
{
FUNCNAME("MeshDistributor::createBoundaryData()");
// === Create interior boundary data structure. === // === Create interior boundary data structure. ===
...@@ -1600,10 +1590,12 @@ namespace AMDiS { ...@@ -1600,10 +1590,12 @@ namespace AMDiS {
if (!(objData.count(mpiRank) && objData.size() > 1)) if (!(objData.count(mpiRank) && objData.size() > 1))
continue; continue;
int owner = elObjDb.getIterateOwner(level); int owner = elObjDb.getIterateOwner(0);
ElementObjectData& rankBoundEl = objData[mpiRank]; ElementObjectData& rankBoundEl = objData[mpiRank];
AtomicBoundary bound; AtomicBoundary bound;
bound.maxLevel = elObjDb.getIterateMaxLevel();
bound.rankObj.el = macroElIndexMap[rankBoundEl.elIndex]; bound.rankObj.el = macroElIndexMap[rankBoundEl.elIndex];
bound.rankObj.elIndex = rankBoundEl.elIndex; bound.rankObj.elIndex = rankBoundEl.elIndex;
bound.rankObj.elType = macroElIndexTypeMap[rankBoundEl.elIndex]; bound.rankObj.elType = macroElIndexTypeMap[rankBoundEl.elIndex];
...@@ -1634,7 +1626,7 @@ namespace AMDiS { ...@@ -1634,7 +1626,7 @@ namespace AMDiS {
bound.type = INTERIOR; bound.type = INTERIOR;
AtomicBoundary& b = rankIntBoundary.getNewAtomic(level, it2->first); AtomicBoundary& b = rankIntBoundary.getNewAtomic(it2->first);
b = bound; b = bound;
if (geoIndex == EDGE) if (geoIndex == EDGE)
b.neighObj.reverseMode = b.neighObj.reverseMode =
...@@ -1658,7 +1650,7 @@ namespace AMDiS { ...@@ -1658,7 +1650,7 @@ namespace AMDiS {
bound.type = INTERIOR; bound.type = INTERIOR;
AtomicBoundary& b = otherIntBoundary.getNewAtomic(level, owner); AtomicBoundary& b = otherIntBoundary.getNewAtomic(owner);
b = bound; b = bound;
if (geoIndex == EDGE) if (geoIndex == EDGE)
b.rankObj.reverseMode = b.rankObj.reverseMode =
...@@ -1707,11 +1699,11 @@ namespace AMDiS { ...@@ -1707,11 +1699,11 @@ namespace AMDiS {
bound.rankObj.ithObj == 1 || bound.rankObj.ithObj == 1 ||
bound.rankObj.elIndex == 78 && bound.rankObj.elIndex == 78 &&
bound.rankObj.ithObj == 2) { bound.rankObj.ithObj == 2) {
AtomicBoundary& b = periodicBoundary.getNewAtomic(level, otherElementRank); AtomicBoundary& b = periodicBoundary.getNewAtomic(otherElementRank);
b = bound; b = bound;
} }
} else { } else {
AtomicBoundary& b = periodicBoundary.getNewAtomic(level, otherElementRank); AtomicBoundary& b = periodicBoundary.getNewAtomic(otherElementRank);
b = bound; b = bound;
} }
} }
...@@ -1746,7 +1738,7 @@ namespace AMDiS { ...@@ -1746,7 +1738,7 @@ namespace AMDiS {
bound.type = it->second; bound.type = it->second;
AtomicBoundary& b = periodicBoundary.getNewAtomic(level, otherElementRank); AtomicBoundary& b = periodicBoundary.getNewAtomic(otherElementRank);
b = bound; b = bound;
if (mpiRank > otherElementRank) if (mpiRank > otherElementRank)
...@@ -1792,7 +1784,7 @@ namespace AMDiS { ...@@ -1792,7 +1784,7 @@ namespace AMDiS {
bound.type = it->second; bound.type = it->second;
AtomicBoundary& b = periodicBoundary.getNewAtomic(level, otherElementRank); AtomicBoundary& b = periodicBoundary.getNewAtomic(otherElementRank);
b = bound; b = bound;
if (mpiRank > otherElementRank) if (mpiRank > otherElementRank)
...@@ -1811,8 +1803,8 @@ namespace AMDiS { ...@@ -1811,8 +1803,8 @@ namespace AMDiS {
// === share the bounday. === // === share the bounday. ===
StdMpi<vector<AtomicBoundary> > stdMpi(mpiComm); StdMpi<vector<AtomicBoundary> > stdMpi(mpiComm);
stdMpi.send(rankIntBoundary.boundary[level]); stdMpi.send(rankIntBoundary.boundary);
stdMpi.recv(otherIntBoundary.boundary[level]); stdMpi.recv(otherIntBoundary.boundary);
stdMpi.startCommunication(); stdMpi.startCommunication();
...@@ -1821,8 +1813,8 @@ namespace AMDiS { ...@@ -1821,8 +1813,8 @@ namespace AMDiS {
// === the same order. If not, the atomic boundaries are swaped to the === // === the same order. If not, the atomic boundaries are swaped to the ===
// === correct order. === // === correct order. ===
for (RankToBoundMap::iterator rankIt = otherIntBoundary.boundary[level].begin(); for (RankToBoundMap::iterator rankIt = otherIntBoundary.boundary.begin();
rankIt != otherIntBoundary.boundary[level].end(); ++rankIt) { rankIt != otherIntBoundary.boundary.end(); ++rankIt) {