From 5f9656c626b9e2fb13b7fc6b84817a134dcc2091 Mon Sep 17 00:00:00 2001
From: Thomas Witkowski <thomas.witkowski@gmx.de>
Date: Fri, 7 Jan 2011 14:03:26 +0000
Subject: [PATCH] Added some documentation to parallel code.

---
 AMDiS/src/parallel/ElementObjectData.cc | 364 +++++++++++++++++++++---
 AMDiS/src/parallel/ElementObjectData.h  | 268 +++++++++++------
 AMDiS/src/parallel/MeshDistributor.cc   | 293 +------------------
 3 files changed, 530 insertions(+), 395 deletions(-)

diff --git a/AMDiS/src/parallel/ElementObjectData.cc b/AMDiS/src/parallel/ElementObjectData.cc
index 3e22eaa1..b005e1fc 100644
--- a/AMDiS/src/parallel/ElementObjectData.cc
+++ b/AMDiS/src/parallel/ElementObjectData.cc
@@ -11,69 +11,369 @@
 
 
 #include "ElementObjectData.h"
+#include "VertexVector.h"
 
 namespace AMDiS {
 
-  void ElementObjects::createRankData(std::map<int, int>& macroElementRankMap) 
+  void ElementObjects::addElement(ElInfo *elInfo)
+  {
+    FUNCNAME("ElementObjects::addElement()");
+
+    TEST_EXIT_DBG(mesh)("Mesh not set!\n");
+
+    Element *el = elInfo->getElement();
+
+
+    // === First, add all element objects to the database. ===
+
+    for (int i = 0; i < el->getGeo(VERTEX); i++)
+      addVertex(el, i);
+    
+    for (int i = 0; i < el->getGeo(EDGE); i++)
+      addEdge(el, i);      
+    
+    for (int i = 0; i < el->getGeo(FACE); i++)
+      addFace(el, i);
+
+
+    // === Get periodic boundary information. === 
+    
+    switch (mesh->getDim()) {
+    case 2:
+      for (int i = 0; i < el->getGeo(EDGE); i++) {
+	if (mesh->isPeriodicAssociation(elInfo->getBoundary(EDGE, i))) {
+	  // The current element's i-th edge is periodic.
+	  Element *neigh = elInfo->getNeighbour(i);
+	  
+	  DofEdge edge0 = el->getEdge(i);
+	  DofEdge edge1 = neigh->getEdge(elInfo->getOppVertex(i));
+	  BoundaryType boundaryType = elInfo->getBoundary(EDGE, i);
+	  
+	  // Add the periodic edge.
+	  periodicEdges[make_pair(edge0, edge1)] = boundaryType;
+	  periodicEdgeAssoc[edge0].insert(edge1);
+	  
+	  // Add both vertices of the edge to be periodic.
+	  periodicVertices[make_pair(edge0.first, edge1.first)] = boundaryType;
+	  periodicVertices[make_pair(edge0.second, edge1.second)] = boundaryType;
+	  periodicDofAssoc[edge0.first].insert(boundaryType);
+	  periodicDofAssoc[edge0.second].insert(boundaryType);
+	  
+	  TEST_EXIT_DBG(edge0.first == 
+			mesh->getPeriodicAssociations(boundaryType)[edge1.first] &&
+			edge0.second == 
+			mesh->getPeriodicAssociations(boundaryType)[edge1.second])
+	    ("Should not happen!\n");
+	}
+      }
+      break;
+    case 3:
+      for (int i = 0; i < el->getGeo(FACE); i++) {
+	if (mesh->isPeriodicAssociation(elInfo->getBoundary(FACE, i))) {
+	  // The current element's i-th face is periodic.
+	  Element *neigh = elInfo->getNeighbour(i);
+	  
+	  DofFace face0 = el->getFace(i);
+	  DofFace face1 = neigh->getFace(elInfo->getOppVertex(i));
+	  BoundaryType boundaryType = elInfo->getBoundary(FACE, i);
+	  
+	  // Add the periodic face.
+	  periodicFaces[make_pair(face0, face1)] = elInfo->getBoundary(i);
+	  
+	  /// Add all three vertices of the face to be periodic.
+	  periodicVertices[make_pair(face0.get<0>(), face1.get<0>())] = boundaryType;
+	  periodicVertices[make_pair(face0.get<1>(), face1.get<1>())] = boundaryType;
+	  periodicVertices[make_pair(face0.get<2>(), face1.get<2>())] = boundaryType;
+	  
+	  periodicDofAssoc[face0.get<0>()].insert(boundaryType);
+	  periodicDofAssoc[face0.get<1>()].insert(boundaryType);
+	  periodicDofAssoc[face0.get<2>()].insert(boundaryType);
+	  
+	  TEST_EXIT_DBG(face0.get<0>() == 
+			mesh->getPeriodicAssociations(boundaryType)[face1.get<0>()] &&
+			face0.get<1>() == 
+			mesh->getPeriodicAssociations(boundaryType)[face1.get<1>()] &&
+			face0.get<2>() == 
+			mesh->getPeriodicAssociations(boundaryType)[face1.get<2>()])
+	    ("Should not happen!\n");
+	  
+	  // Create all three edges of the element and add them to be periodic.
+	  DofEdge elEdge0 = make_pair(face0.get<0>(), face0.get<1>());
+	  DofEdge elEdge1 = make_pair(face0.get<0>(), face0.get<2>());
+	  DofEdge elEdge2 = make_pair(face0.get<1>(), face0.get<2>());
+	  DofEdge neighEdge0 = make_pair(face1.get<0>(), face1.get<1>());
+	  DofEdge neighEdge1 = make_pair(face1.get<0>(), face1.get<2>());
+	  DofEdge neighEdge2 = make_pair(face1.get<1>(), face1.get<2>());
+	  	  
+	  periodicEdges[make_pair(elEdge0, neighEdge0)] = boundaryType;
+	  periodicEdges[make_pair(elEdge1, neighEdge1)] = boundaryType;
+	  periodicEdges[make_pair(elEdge2, neighEdge2)] = boundaryType;
+	  
+	  periodicEdgeAssoc[elEdge0].insert(neighEdge0);
+	  periodicEdgeAssoc[elEdge1].insert(neighEdge1);
+	  periodicEdgeAssoc[elEdge2].insert(neighEdge2);
+	}
+      }
+      break;
+    default:
+      ERROR_EXIT("Should not happen!\n");
+    }       
+  }
+
+
+  void ElementObjects::createPeriodicData()
+  {
+    FUNCNAME("ElementObjects::createPeriodicData()");
+
+    TEST_EXIT_DBG(mesh)("Mesh not set!\n");
+
+    // === Return, if there are no periodic vertices, i.e., there are no no  ===
+    // === periodic boundaries in the mesh.                                  ===
+    
+    if (periodicVertices.size() == 0)
+      return;
+   
+
+    // === Search for an unsed boundary index. ===
+
+    BoundaryType newPeriodicBoundaryType = 0;
+    for (map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin();
+	 it != mesh->getPeriodicAssociations().end(); ++it)
+      newPeriodicBoundaryType = min(newPeriodicBoundaryType, it->first);
+    
+    TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n");
+    newPeriodicBoundaryType--;
+    mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
+      new VertexVector(feSpace->getAdmin(), "");
+    
+    
+    // === Get all vertex DOFs that have multiple periodic associations. ===
+    
+    // We group all vertices together, that have either two or three periodic
+    // associations. For rectangular domains in 2D, the four corner vertices have all
+    // two periodic associations. For box domains in 3D, the eight corner vertices
+    // have all three periodic associations.
+
+    vector<DegreeOfFreedom> multPeriodicDof2, multPeriodicDof3;
+    for (map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin();
+	 it != periodicDofAssoc.end(); ++it) {
+      TEST_EXIT_DBG((mesh->getDim() == 2 && it->second.size() <= 2) ||
+		    (mesh->getDim() == 3 && it->second.size() <= 3))
+	("Should not happen!\n");
+      
+      if (it->second.size() == 2)
+	multPeriodicDof2.push_back(it->first);
+      if (it->second.size() == 3)
+	multPeriodicDof3.push_back(it->first);
+    }
+
+
+    if (mesh->getDim() == 2) {
+      TEST_EXIT_DBG(multPeriodicDof2.size() == 0 || 
+		    multPeriodicDof2.size() == 4)
+	("Should not happen (%d)!\n", multPeriodicDof2.size());
+      TEST_EXIT_DBG(multPeriodicDof3.size() == 0)("Should not happen!\n");
+    }
+    if (mesh->getDim() == 3) {
+      TEST_EXIT_DBG(multPeriodicDof3.size() == 0 || 
+		    multPeriodicDof3.size() == 8)
+	("Should not happen (%d)!\n", multPeriodicDof3.size());
+    }
+    
+    
+    if (multPeriodicDof2.size() > 0) {
+      for (unsigned int i = 0; i < multPeriodicDof2.size(); i++) {
+	DegreeOfFreedom dof0 = multPeriodicDof2[i];
+	if (dof0 == -1)
+	  continue;
+	
+	DegreeOfFreedom dof1 = -1;
+	DegreeOfFreedom dof2 = -1;
+	BoundaryType type0 = *(periodicDofAssoc[dof0].begin());
+	BoundaryType type1 = *(++(periodicDofAssoc[dof0].begin()));
+	
+	for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin();
+	     it != periodicVertices.end(); ++it) {
+	  if (it->first.first == dof0 && it->second == type0)
+	    dof1 = it->first.second;
+	  if (it->first.first == dof0 && it->second == type1)
+	    dof2 = it->first.second;
+	  
+	  if (dof1 != -1 && dof2 != -1)
+	    break;
+	}
+	
+	TEST_EXIT_DBG(dof1 != -1 && dof2 != -1)("Should not happen!\n");
+	
+	DegreeOfFreedom dof3 = -1;
+	for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin();
+	     it != periodicVertices.end(); ++it) {
+	  if (it->first.first == dof1 && it->second == type1) {
+	    dof3 = it->first.second;
+	    
+	    TEST_EXIT_DBG(periodicVertices[make_pair(dof2, dof3)] == type0)
+	      ("Should not happen!\n");
+	    
+	    break;
+	  }
+	}
+	  
+	TEST_EXIT_DBG(dof3 != -1)("Should not happen!\n");
+	TEST_EXIT_DBG(periodicVertices.count(make_pair(dof0, dof3)) == 0)
+	  ("Should not happen!\n");
+	TEST_EXIT_DBG(periodicVertices.count(make_pair(dof3, dof0)) == 0)
+	  ("Should not happen!\n");
+	
+	periodicVertices[make_pair(dof0, dof3)] = newPeriodicBoundaryType;
+	periodicVertices[make_pair(dof3, dof0)] = newPeriodicBoundaryType;
+	
+	for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++)
+	  if (multPeriodicDof2[j] == dof3)
+	    multPeriodicDof2[j] = -1;
+      }
+    }
+
+    if (multPeriodicDof3.size() > 0) {
+      int nMultPeriodicDofs = multPeriodicDof3.size();
+      for (int i = 0; i < nMultPeriodicDofs; i++) {
+	for (int j = i + 1; j < nMultPeriodicDofs; j++) {
+	  pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = 
+	    make_pair(multPeriodicDof3[i], multPeriodicDof3[j]);
+	  pair<DegreeOfFreedom, DegreeOfFreedom> perDofs1 = 
+	    make_pair(multPeriodicDof3[j], multPeriodicDof3[i]);
+	  
+	  if (periodicVertices.count(perDofs0) == 0) {
+	    TEST_EXIT_DBG(periodicVertices.count(perDofs1) == 0)
+	      ("Should not happen!\n");
+	    
+	    periodicVertices[perDofs0] = newPeriodicBoundaryType;
+	    periodicVertices[perDofs1] = newPeriodicBoundaryType;
+	    newPeriodicBoundaryType--;
+	    mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
+	      new VertexVector(feSpace->getAdmin(), "");
+	  }
+	}
+      }
+    }
+    
+    
+    // === Get all edges that have multiple periodic associations (3D only!). ===
+    
+    for (map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin();
+	 it != periodicEdgeAssoc.end(); ++it) {
+      if (it->second.size() > 1) {
+	TEST_EXIT_DBG(mesh->getDim() == 3)("Should not happen!\n");
+	TEST_EXIT_DBG(it->second.size() == 2)("Should not happen!\n");
+	
+	pair<DofEdge, DofEdge> perEdge0 =
+	  make_pair(*(it->second.begin()), *(++(it->second.begin())));
+	pair<DofEdge, DofEdge> perEdge1 =
+	  make_pair(perEdge0.second, perEdge0.first);
+	
+	periodicEdges[perEdge0] = newPeriodicBoundaryType;
+	periodicEdges[perEdge1] = newPeriodicBoundaryType;
+	newPeriodicBoundaryType--;
+	mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
+	  new VertexVector(feSpace->getAdmin(), "");      
+      }
+    }
+
+
+    // === In debug mode we make some tests, if the periodic structures are set ===
+    // === in a symmetric way, i.e., if A -> B for a specific boundary type,    ===
+    // === there must be a mapping B -> A with the same boundary type.          ===
+    
+#if (DEBUG != 0)
+    for (PerBoundMap<DegreeOfFreedom>::iterator it = periodicVertices.begin();
+	 it != periodicVertices.end(); ++it) {
+      pair<DegreeOfFreedom, DegreeOfFreedom> testVertex = 
+	make_pair(it->first.second, it->first.first);
+      
+      TEST_EXIT_DBG(periodicVertices.count(testVertex) == 1)("Should not happen!\n");
+      TEST_EXIT_DBG(periodicVertices[testVertex] == it->second)("Should not happen!\n");
+    }
+
+    for (PerBoundMap<DofEdge>::iterator it = periodicEdges.begin();
+	 it != periodicEdges.end(); ++it) {
+      pair<DofEdge, DofEdge> testEdge = 
+	make_pair(it->first.second, it->first.first);
+      
+      TEST_EXIT_DBG(periodicEdges.count(testEdge) == 1)("Should not happen!\n");
+      TEST_EXIT_DBG(periodicEdges[testEdge] == it->second)("Should not happen!\n");
+    }
+    
+    for (PerBoundMap<DofFace>::iterator it = periodicFaces.begin();
+	 it != periodicFaces.end(); ++it) {
+      pair<DofFace, DofFace> testFace = 
+	make_pair(it->first.second, it->first.first);
+      
+      TEST_EXIT_DBG(periodicFaces.count(testFace) == 1)("Should not happen!\n");
+      TEST_EXIT_DBG(periodicFaces[testFace] == it->second)("Should not happen!\n");
+    }
+#endif       
+  }
+
+
+  void ElementObjects::createRankData(map<int, int>& macroElementRankMap) 
   {
     FUNCNAME("ElementObjects::createRankData()");
 
     vertexOwner.clear();
     vertexInRank.clear();
-    for (std::map<DegreeOfFreedom, std::vector<ElementObjectData> >::iterator it = vertexElements.begin();
+    for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin();
 	 it != vertexElements.end(); ++it) {
-      for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); 
+      for (vector<ElementObjectData>::iterator it2 = it->second.begin(); 
 	   it2 != it->second.end(); ++it2) {
 	int elementInRank = macroElementRankMap[it2->elIndex];
 	
 	if (it2->elIndex > vertexInRank[it->first][elementInRank].elIndex)
 	  vertexInRank[it->first][elementInRank] = *it2;
 
-	vertexOwner[it->first] = std::max(vertexOwner[it->first], elementInRank);
+	vertexOwner[it->first] = max(vertexOwner[it->first], elementInRank);
       }
     }
     
 
     edgeOwner.clear();
     edgeInRank.clear();
-    for (std::map<DofEdge, std::vector<ElementObjectData> >::iterator it = edgeElements.begin();
+    for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin();
 	 it != edgeElements.end(); ++it) {
-      for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); 
+      for (vector<ElementObjectData>::iterator it2 = it->second.begin(); 
 	   it2 != it->second.end(); ++it2) {
 	int elementInRank = macroElementRankMap[it2->elIndex];
 	
 	if (it2->elIndex > edgeInRank[it->first][elementInRank].elIndex)
 	  edgeInRank[it->first][elementInRank] = *it2;
 
-	edgeOwner[it->first] = std::max(edgeOwner[it->first], elementInRank);
+	edgeOwner[it->first] = max(edgeOwner[it->first], elementInRank);
       }
     }
     
 
     faceOwner.clear();
     faceInRank.clear();
-    for (std::map<DofFace, std::vector<ElementObjectData> >::iterator it = faceElements.begin();
+    for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin();
 	 it != faceElements.end(); ++it) {
-      for (std::vector<ElementObjectData>::iterator it2 = it->second.begin(); 
+      for (vector<ElementObjectData>::iterator it2 = it->second.begin(); 
 	   it2 != it->second.end(); ++it2) {
 	int elementInRank = macroElementRankMap[it2->elIndex];
 	
 	if (it2->elIndex > faceInRank[it->first][elementInRank].elIndex)
 	  faceInRank[it->first][elementInRank] = *it2;
 
-	faceOwner[it->first] = std::max(faceOwner[it->first], elementInRank);
+	faceOwner[it->first] = max(faceOwner[it->first], elementInRank);
       }
     }
   }
 
 
-  void ElementObjects::serialize(std::ostream &out)
+  void ElementObjects::serialize(ostream &out)
   {
     FUNCNAME("ElementObjects::serialize()");
 
     int nSize = vertexElements.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DegreeOfFreedom, std::vector<ElementObjectData> >::iterator it = vertexElements.begin();
+    for (map<DegreeOfFreedom, vector<ElementObjectData> >::iterator it = vertexElements.begin();
 	 it != vertexElements.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -81,7 +381,7 @@ namespace AMDiS {
 
     nSize = edgeElements.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DofEdge, std::vector<ElementObjectData> >::iterator it = edgeElements.begin();
+    for (map<DofEdge, vector<ElementObjectData> >::iterator it = edgeElements.begin();
 	 it != edgeElements.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -89,7 +389,7 @@ namespace AMDiS {
 
     nSize = faceElements.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DofFace, std::vector<ElementObjectData> >::iterator it = faceElements.begin();
+    for (map<DofFace, vector<ElementObjectData> >::iterator it = faceElements.begin();
 	 it != faceElements.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -99,7 +399,7 @@ namespace AMDiS {
 
     nSize = vertexLocalMap.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin();
+    for (map<ElementObjectData, DegreeOfFreedom>::iterator it = vertexLocalMap.begin();
 	 it != vertexLocalMap.end(); ++it) {
       it->first.serialize(out);
       SerUtil::serialize(out, it->second);
@@ -107,7 +407,7 @@ namespace AMDiS {
 
     nSize = edgeLocalMap.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin();
+    for (map<ElementObjectData, DofEdge>::iterator it = edgeLocalMap.begin();
 	 it != edgeLocalMap.end(); ++it) {
       it->first.serialize(out);
       SerUtil::serialize(out, it->second);
@@ -115,7 +415,7 @@ namespace AMDiS {
 
     nSize = faceLocalMap.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin();
+    for (map<ElementObjectData, DofFace>::iterator it = faceLocalMap.begin();
 	 it != faceLocalMap.end(); ++it) {
       it->first.serialize(out);
       SerUtil::serialize(out, it->second);
@@ -130,7 +430,7 @@ namespace AMDiS {
 
     nSize = vertexInRank.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DegreeOfFreedom, std::map<int, ElementObjectData> >::iterator it = vertexInRank.begin();
+    for (map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator it = vertexInRank.begin();
 	 it != vertexInRank.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -138,7 +438,7 @@ namespace AMDiS {
 
     nSize = edgeInRank.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DofEdge, std::map<int, ElementObjectData> >::iterator it = edgeInRank.begin();
+    for (map<DofEdge, map<int, ElementObjectData> >::iterator it = edgeInRank.begin();
 	 it != edgeInRank.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -146,7 +446,7 @@ namespace AMDiS {
 
     nSize = faceInRank.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<DofFace, std::map<int, ElementObjectData> >::iterator it = faceInRank.begin();
+    for (map<DofFace, map<int, ElementObjectData> >::iterator it = faceInRank.begin();
 	 it != faceInRank.end(); ++it) {
       SerUtil::serialize(out, it->first);
       serialize(out, it->second);
@@ -158,7 +458,7 @@ namespace AMDiS {
   }
 
 
-  void ElementObjects::deserialize(std::istream &in)
+  void ElementObjects::deserialize(istream &in)
   {
     FUNCNAME("ElementObjects::deserialize()");
 
@@ -167,7 +467,7 @@ namespace AMDiS {
     vertexElements.clear();
     for (int i = 0; i < nSize; i++) {
       DegreeOfFreedom dof;
-      std::vector<ElementObjectData> data;
+      vector<ElementObjectData> data;
       SerUtil::deserialize(in, dof);
       deserialize(in, data);
       vertexElements[dof] = data;
@@ -177,7 +477,7 @@ namespace AMDiS {
     edgeElements.clear();
     for (int i = 0; i < nSize; i++) {
       DofEdge edge;
-      std::vector<ElementObjectData> data;
+      vector<ElementObjectData> data;
       SerUtil::deserialize(in, edge);
       deserialize(in, data);
       edgeElements[edge] = data;
@@ -187,7 +487,7 @@ namespace AMDiS {
     faceElements.clear();
     for (int i = 0; i < nSize; i++) {
       DofFace face;
-      std::vector<ElementObjectData> data;
+      vector<ElementObjectData> data;
       SerUtil::deserialize(in, face);
       deserialize(in, data);
       faceElements[face] = data;
@@ -235,7 +535,7 @@ namespace AMDiS {
     vertexInRank.clear();
     for (int i = 0; i < nSize; i++) {
       DegreeOfFreedom dof;
-      std::map<int, ElementObjectData> data;
+      map<int, ElementObjectData> data;
       SerUtil::deserialize(in, dof);
       deserialize(in, data);
       vertexInRank[dof] = data;
@@ -245,7 +545,7 @@ namespace AMDiS {
     edgeInRank.clear();
     for (int i = 0; i < nSize; i++) {
       DofEdge edge;
-      std::map<int, ElementObjectData> data;
+      map<int, ElementObjectData> data;
       SerUtil::deserialize(in, edge);
       deserialize(in, data);
       edgeInRank[edge] = data;
@@ -255,7 +555,7 @@ namespace AMDiS {
     faceInRank.clear();
     for (int i = 0; i < nSize; i++) {
       DofFace face;
-      std::map<int, ElementObjectData> data;
+      map<int, ElementObjectData> data;
       SerUtil::deserialize(in, face);
       deserialize(in, data);
       faceInRank[face] = data;
@@ -267,7 +567,7 @@ namespace AMDiS {
   }
 
 
-  void ElementObjects::serialize(std::ostream &out, std::vector<ElementObjectData>& elVec)
+  void ElementObjects::serialize(ostream &out, vector<ElementObjectData>& elVec)
   {
     int nSize = elVec.size();
     SerUtil::serialize(out, nSize);
@@ -276,7 +576,7 @@ namespace AMDiS {
   }
 
 
-  void ElementObjects::deserialize(std::istream &in, std::vector<ElementObjectData>& elVec)
+  void ElementObjects::deserialize(istream &in, vector<ElementObjectData>& elVec)
   {
     int nSize;
     SerUtil::deserialize(in, nSize);
@@ -286,11 +586,11 @@ namespace AMDiS {
   }
 
   
-  void ElementObjects::serialize(std::ostream &out, std::map<int, ElementObjectData>& data)
+  void ElementObjects::serialize(ostream &out, map<int, ElementObjectData>& data)
   {
     int nSize = data.size();
     SerUtil::serialize(out, nSize);
-    for (std::map<int, ElementObjectData>::iterator it = data.begin();
+    for (map<int, ElementObjectData>::iterator it = data.begin();
 	 it != data.end(); ++it) {
       SerUtil::serialize(out, it->first);
       it->second.serialize(out);
@@ -298,7 +598,7 @@ namespace AMDiS {
   }
 
   
-  void ElementObjects::deserialize(std::istream &in, std::map<int, ElementObjectData>& data)
+  void ElementObjects::deserialize(istream &in, map<int, ElementObjectData>& data)
   {
     int nSize;
     SerUtil::deserialize(in, nSize);
diff --git a/AMDiS/src/parallel/ElementObjectData.h b/AMDiS/src/parallel/ElementObjectData.h
index 6c900bff..bbe33bcc 100644
--- a/AMDiS/src/parallel/ElementObjectData.h
+++ b/AMDiS/src/parallel/ElementObjectData.h
@@ -31,138 +31,137 @@
 #include "Global.h"
 #include "Boundary.h"
 #include "Serializer.h"
+#include "FiniteElemSpace.h"
 
 namespace AMDiS {
 
   using namespace std;
 
+  /// Just to templatize the typedef.
   template<typename T>
-  struct PerBoundMap 
-  {
+  struct PerBoundMap {
     typedef map<pair<T, T>, BoundaryType> type;
     typedef typename type::iterator iterator;
   };
 
+
+  /// Defines one element object. This may be either a vertex, edge or face.
   struct ElementObjectData {
-    ElementObjectData(int a = -1, int b = 0, BoundaryType c = INTERIOR)
+    ElementObjectData(int a = -1, int b = 0)
       : elIndex(a),
-	ithObject(b),
-	boundaryType(c)
+	ithObject(b)
     {}
-    
+
+    /// Index of the element this object is part of.
     int elIndex;
     
+    /// Index of the object within the element.
     int ithObject;
     
-    BoundaryType boundaryType;
-
-
+    /// Write this element object to disk.
     void serialize(ostream &out) const
     {
       SerUtil::serialize(out, elIndex);
       SerUtil::serialize(out, ithObject);
-      SerUtil::serialize(out, boundaryType);
     }
 
-
+    /// Read this element object from disk.
     void deserialize(istream &in)
     {
       SerUtil::deserialize(in, elIndex);
       SerUtil::deserialize(in, ithObject);
-      SerUtil::deserialize(in, boundaryType);
     }
 
-
+    /// Compare this element object with another one.
     bool operator==(ElementObjectData& cmp) const
     {
-      return (elIndex == cmp.elIndex &&
-	      ithObject == cmp.ithObject &&
-	      boundaryType == cmp.boundaryType);
+      return (elIndex == cmp.elIndex && ithObject == cmp.ithObject);
     }
 
+    /// Define a strict order on element objects.
     bool operator<(const ElementObjectData& rhs) const
     {
-      return (elIndex < rhs.elIndex ||
-	      (elIndex == rhs.elIndex &&
-	       ithObject < rhs.ithObject));
+      return (elIndex < rhs.elIndex || 
+	      (elIndex == rhs.elIndex && ithObject < rhs.ithObject));
     }
   };
 
 
 
+  /** \brief
+   * This class is a database of element objects. An element object is either a
+   * vertex, edge or the face of a specific element. This database is used to store
+   * all objects of all elements of a mesh. The information is stored in a way that
+   * makes it possible to identify all elements, which have a given vertex, edge or
+   * face in common. If is is known which element is owned by which rank in parallel
+   * computations, it is thus possible to get all interior boundaries on object 
+   * level. This is required, because two elements may share a common vertex without
+   * beging neighbours in the definition of AMDiS.
+   */
   class ElementObjects {
   public:
     ElementObjects()
-      : iterGeoPos(CENTER)
+      : feSpace(NULL),
+	mesh(NULL),
+	iterGeoPos(CENTER)
     {}
 
 
-    void addVertex(Element *el, int ith, BoundaryType bound = INTERIOR)
-    {
-      DegreeOfFreedom vertex = el->getDof(ith, 0);
-      int elIndex = el->getIndex();
-      ElementObjectData elObj(elIndex, ith, bound);
-
-      vertexElements[vertex].push_back(elObj);
-      vertexLocalMap[elObj] = vertex;
-    }
-
-
-    void addEdge(Element *el, int ith, BoundaryType bound = INTERIOR)
+    /// Set the finite element space that should be used for the database (especially
+    /// the mesh is of interest).
+    void setFeSpace(FiniteElemSpace *fe)
     {
-      DofEdge edge = el->getEdge(ith);
-      int elIndex = el->getIndex();
-      ElementObjectData elObj(elIndex, ith, bound);
-
-      edgeElements[edge].push_back(elObj);
-      edgeLocalMap[elObj] = edge;
+      feSpace = fe;
+      mesh = feSpace->getMesh();
     }
 
 
-    void addFace(Element *el, int ith, BoundaryType bound = INTERIOR)
-    {
-      DofFace face = el->getFace(ith);
-      int elIndex = el->getIndex();
-      ElementObjectData elObj(elIndex, ith, bound);
-
-      faceElements[face].push_back(elObj);
-      faceLocalMap[elObj] = face;
-    }
-
-
-    void addElement(Element *el, BoundaryType bound = INTERIOR)
-    {
-      for (int i = 0; i < el->getGeo(VERTEX); i++)
-	addVertex(el, i);
-
-      for (int i = 0; i < el->getGeo(EDGE); i++)
-	addEdge(el, i);      
-
-      for (int i = 0; i < el->getGeo(FACE); i++)
-	addFace(el, i);
-    }
-
-    void addPeriodicVertex(pair<DegreeOfFreedom, DegreeOfFreedom> perVertex, 
-			   BoundaryType bType)
-    {
-      periodicVertices[perVertex] = bType;
-    }
-    
-    void addPeriodicEdge(pair<DofEdge, DofEdge> perEdge, BoundaryType bType)
-    {
-      periodicEdges[perEdge] = bType;
-    }
-
-    void addPeriodicFace(pair<DofFace, DofFace> perFace, BoundaryType bType)
-    {
-      periodicFaces[perFace] = bType;
-    }
-
+    /** \brief
+     * Adds an element to the object database. If the element is part of a periodic
+     * boundary, all information about subobjects of the element on this boundary
+     * are collected.
+     *
+     * \param[in]  elInfo    ElInfo object of the element. 
+     */
+    void addElement(ElInfo *elInfo);
+
+
+    /** \brief
+     * Creates final data of the periodic boundaries. Must be called after all
+     * elements of the mesh are added to the object database. Then this functions
+     * search for interectly connected vertices in periodic boundaries. This is only
+     * the case, if there are more than one boundary conditions. Then, e.g., in 2D, 
+     * all edges of a square are iterectly connected. In 3D, if the macro mesh is a
+     * box, all eight vertex nodes and always four of the 12 edges are iterectly 
+     * connected.
+     */
+    void createPeriodicData();
+
+
+    /** \brief
+     * Create for a filled object database the membership information for all element
+     * objects. An object is owned by a rank, if the rank has the heighest rank
+     * number of all ranks where the object is part of.
+     *
+     * \param[in]  macroElementRankMap   Maps to each macro element of the mesh the
+     *                                   rank that owns this macro element.
+     */
     void createRankData(map<int, int>& macroElementRankMap);
 
 
+    /** \brief
+     * Iterates over all elements for one geometrical index, i.e., over all vertices,
+     * edges or faces in the mesh. The function returns true, if the result is valid.
+     * Otherwise the iterator is at the end position.
+     *
+     * \param[in]  pos   Must be either VERTEX, EDGE or FACE and defines the elements
+     *                   that should be traversed.
+     */
     bool iterate(GeoIndex pos)
     {
+      // CENTER marks the variable "iterGeoPos" to be in an undefined state. I.e.,
+      // there is no iteration that is actually running.
+
       if (iterGeoPos == CENTER) {
 	iterGeoPos = pos;
 	switch (iterGeoPos) {
@@ -221,6 +220,7 @@ namespace AMDiS {
     }
 
 
+    /// Returns the data of the current iterator position.
     map<int, ElementObjectData>& getIterateData()
     {
       switch (iterGeoPos) {
@@ -242,6 +242,7 @@ namespace AMDiS {
     }
 
 
+    /// Returns the rank owner of the current iterator position.
     int getIterateOwner()
     {
       switch (iterGeoPos) {
@@ -263,121 +264,220 @@ namespace AMDiS {
     }
 
 
+    /// Returns the rank owner of a vertex DOF.
     int getOwner(DegreeOfFreedom vertex)
     {
       return vertexOwner[vertex];
     }
 
+    /// Returns the rank owner of an edge.
     int getOwner(DofEdge edge)
     {
       return edgeOwner[edge];
     }
 
+    /// Returns the rank owner of an face.
     int getOwner(DofFace face)
     {
       return faceOwner[face];
     }
 
 
+    /// Checks if a given vertex DOF is in a given rank.
     int isInRank(DegreeOfFreedom vertex, int rank)
     {
       return (vertexInRank[vertex].count(rank));
     }
 
+    /// Checks if a given edge is in a given rank.
     int isInRank(DofEdge edge, int rank)
     {
       return (edgeInRank[edge].count(rank));
     }
 
+    /// Checks if a given face is in a given rank.
     int isInRank(DofFace face, int rank)
     {
       return (faceInRank[face].count(rank));
     }
 
 
+    /// Returns a vector with all macro elements that have a given vertex DOF in common.
     vector<ElementObjectData>& getElements(DegreeOfFreedom vertex)
     {
       return vertexElements[vertex];
     }
 
+    /// Returns a vector with all macro elements that have a given edge in common.
     vector<ElementObjectData>& getElements(DofEdge edge)
     {
       return edgeElements[edge];
     }
 
+    /// Returns a vector with all macro elements that have a given face in common.
     vector<ElementObjectData>& getElements(DofFace face)
     {
       return faceElements[face];
     }
 
-
+    
+    /// Returns a map that maps to each rank all macro elements in this rank that
+    /// have a given vertex DOF in common.
     map<int, ElementObjectData>& getElementsInRank(DegreeOfFreedom vertex)
     {
       return vertexInRank[vertex];
     }
 
+    /// Returns a map that maps to each rank all macro elements in this rank that
+    /// have a given edge in common.
     map<int, ElementObjectData>& getElementsInRank(DofEdge edge)
     {
       return edgeInRank[edge];
     }
 
+    /// Returns a map that maps to each rank all macro elements in this rank that
+    /// have a given face in common.
     map<int, ElementObjectData>& getElementsInRank(DofFace face)
     {
       return faceInRank[face];
     }
 
+    /// Returns to an element object data the appropriate vertex DOF.
     DegreeOfFreedom getVertexLocalMap(ElementObjectData &data)
     {
       return vertexLocalMap[data];
     }
 
+    /// Returns to an element object data the appropriate edge.
     DofEdge getEdgeLocalMap(ElementObjectData &data)
     {
       return edgeLocalMap[data];
     }
 
+    /// Returns to an element object data the appropriate face.
     DofFace getFaceLocalMap(ElementObjectData &data)
     {
       return faceLocalMap[data];
     }
 
+    /// Write the element database to disk.
     void serialize(ostream &out);
-
+    
+    /// Read the element database from disk.
     void deserialize(istream &in);
 
-  private:
+  protected:
+    /// Adds the i-th DOF vertex of an element to the object database.
+    void addVertex(Element *el, int ith)
+    {
+      DegreeOfFreedom vertex = el->getDof(ith, 0);
+      int elIndex = el->getIndex();
+      ElementObjectData elObj(elIndex, ith);
+
+      vertexElements[vertex].push_back(elObj);
+      vertexLocalMap[elObj] = vertex;
+    }
+
+    /// Adds the i-th edge of an element to the object database.
+    void addEdge(Element *el, int ith)
+    {
+      DofEdge edge = el->getEdge(ith);
+      int elIndex = el->getIndex();
+      ElementObjectData elObj(elIndex, ith);
+
+      edgeElements[edge].push_back(elObj);
+      edgeLocalMap[elObj] = edge;
+    }
+
+    /// Adds the i-th face of an element to the object database.
+    void addFace(Element *el, int ith)
+    {
+      DofFace face = el->getFace(ith);
+      int elIndex = el->getIndex();
+      ElementObjectData elObj(elIndex, ith);
+
+      faceElements[face].push_back(elObj);
+      faceLocalMap[elObj] = face;
+    }
+
+
+    /// Some auxiliary function to write the element object database to disk.
     void serialize(ostream &out, vector<ElementObjectData>& elVec);
 
+    /// Some auxiliary function to read the element object database from disk.
     void deserialize(istream &in, vector<ElementObjectData>& elVec);
 
+    /// Some auxiliary function to write the element object database to disk.
     void serialize(ostream &out, map<int, ElementObjectData>& data);
 
+    /// Some auxiliary function to read the element object database from disk.
     void deserialize(istream &in, map<int, ElementObjectData>& data);
 
   private:
+    /// The used FE space.
+    FiniteElemSpace *feSpace;
+
+    /// The mesh that is used to store all its element information in the database.
+    Mesh *mesh;
+
+
+    /// Maps to each vertex DOF all element objects that represent this vertex.
     map<DegreeOfFreedom, vector<ElementObjectData> > vertexElements;
+
+    /// Maps to each edge all element objects that represent this edge.
     map<DofEdge, vector<ElementObjectData> > edgeElements;
-    map<DofFace, vector<ElementObjectData> > faceElements;
 
+    /// Maps to each face all element objects that represent this edge.
+    map<DofFace, vector<ElementObjectData> > faceElements;
 
+    
+    /// Maps to an element object the corresponding vertex DOF.
     map<ElementObjectData, DegreeOfFreedom> vertexLocalMap;
+
+    /// Maps to an element object the corresponding edge.
     map<ElementObjectData, DofEdge> edgeLocalMap;
+
+    /// Maps to an element object the corresponding face.
     map<ElementObjectData, DofFace> faceLocalMap;
 
 
+    /// Defines for all vertex DOFs the rank that ownes this vertex DOF.
     map<DegreeOfFreedom, int> vertexOwner;
+
+    /// Defines for all edges the rank that ownes this edge.
     map<DofEdge, int> edgeOwner;
+
+    /// Defines for all faces the rank that ownes this face.
     map<DofFace, int> faceOwner;
 
 
+    /// Defines to each vertex DOF a map that maps to each rank number the element
+    /// objects that have this vertex DOF in common.
     map<DegreeOfFreedom, map<int, ElementObjectData> > vertexInRank;
+
+    /// Defines to each edge a map that maps to each rank number the element objects
+    /// that have this edge in common.
     map<DofEdge, map<int, ElementObjectData> > edgeInRank;
+
+    /// Defines to each face a map that maps to each rank number the element objects
+    /// that have this face in common.
     map<DofFace, map<int, ElementObjectData> > faceInRank;
 
+
+    /// Vertex iterator to iterate over \ref vertexInRank
     map<DegreeOfFreedom, map<int, ElementObjectData> >::iterator vertexIter;
+
+    /// Edge iterator to iterate over \ref edgeInRank
     map<DofEdge, map<int, ElementObjectData> >::iterator edgeIter;
+
+    /// Face iterator to iterate over \ref faceInRank
     map<DofFace, map<int, ElementObjectData> >::iterator faceIter;
 
+
+    /// Defines the geometrical iteration index of the iterators. I.e., the value
+    /// is either VERTEX, EDGE or FACE and the corresponding element objects are
+    /// traversed. The value CENTER is used to define a not defined states of the
+    /// iterators, i.e., if no iteration is running.
     GeoIndex iterGeoPos;
 
   public:
@@ -385,6 +485,12 @@ namespace AMDiS {
     PerBoundMap<DegreeOfFreedom>::type periodicVertices;
     PerBoundMap<DofEdge>::type periodicEdges;
     PerBoundMap<DofFace>::type periodicFaces;
+
+    // Stores to each vertex all its periodic associations.
+    std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
+
+    // Stores to each edge all its periodic associations.
+    std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
   };
 
 }
diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc
index 4e234d5a..f3490093 100644
--- a/AMDiS/src/parallel/MeshDistributor.cc
+++ b/AMDiS/src/parallel/MeshDistributor.cc
@@ -103,6 +103,8 @@ namespace AMDiS {
     TEST_EXIT(feSpace)("No FE space has been defined for the mesh distributor!\n");
     TEST_EXIT(mesh)("No mesh has been defined for the mesh distributor!\n");
 
+    elObjects.setFeSpace(feSpace);
+
     // If the problem has been already read from a file, we need only to set
     // isRankDofs to all matrices and rhs vector and to remove periodic 
     // boundary conditions (if there are some).
@@ -1265,9 +1267,7 @@ namespace AMDiS {
     FUNCNAME("MeshDistributor::createInteriorBoundaryInfo()");
 
     createMeshElementData();
-
     createBoundaryData();
-
   }
 
 
@@ -1276,7 +1276,6 @@ namespace AMDiS {
     FUNCNAME("MeshDistributor::updateInteriorBoundaryInfo()");
 
     elObjects.createRankData(partitionVec);
-
     createBoundaryData();
   }
 
@@ -1285,12 +1284,6 @@ namespace AMDiS {
   {
     FUNCNAME("MeshDistributor::createMeshElementData()");
 
-    // Stores to each vertex all its periodic associations.
-    std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
-
-    // Stores to each edge all its periodic associations.
-    std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
-
 
    // === Fills macro element data structures. ===
 
@@ -1304,274 +1297,19 @@ namespace AMDiS {
       Element *el = elInfo->getElement();
       macroElIndexMap[el->getIndex()] = el;
       macroElIndexTypeMap[el->getIndex()] = elInfo->getType();
-
-      
+     
       // === Add all sub object of the element to the variable elObjects. ===
+      elObjects.addElement(elInfo);
 
-      elObjects.addElement(el);
-
-
-      // === Get periodic boundary information. === 
-
-      switch (mesh->getDim()) {
-      case 2:
-	for (int i = 0; i < el->getGeo(EDGE); i++) {
-	  if (mesh->isPeriodicAssociation(elInfo->getBoundary(EDGE, i))) {
-	    Element *neigh = elInfo->getNeighbour(i);
-
-	    DofEdge edge1 = el->getEdge(i);
-	    DofEdge edge2 = neigh->getEdge(elInfo->getOppVertex(i));
-	    BoundaryType boundaryType = elInfo->getBoundary(EDGE, i);
-
-	    elObjects.addPeriodicEdge(std::make_pair(edge1, edge2), boundaryType);
-	    periodicEdgeAssoc[edge1].insert(edge2);
-
-	    elObjects.addPeriodicVertex(std::make_pair(edge1.first, edge2.first), boundaryType);
-	    elObjects.addPeriodicVertex(std::make_pair(edge1.second, edge2.second), boundaryType);
-	    periodicDofAssoc[edge1.first].insert(boundaryType);
-	    periodicDofAssoc[edge1.second].insert(boundaryType);
-
-	    TEST_EXIT_DBG(edge1.first == mesh->getPeriodicAssociations(boundaryType)[edge2.first] &&
-			  edge1.second == mesh->getPeriodicAssociations(boundaryType)[edge2.second])
-	      ("Should not happen!\n");
-	  }
-	}
-	break;
-      case 3:
-	for (int i = 0; i < el->getGeo(FACE); i++) {
-	  if (mesh->isPeriodicAssociation(elInfo->getBoundary(FACE, i))) {
-	    Element *neigh = elInfo->getNeighbour(i);
-
-	    DofFace face1 = el->getFace(i);
-	    DofFace face2 = neigh->getFace(elInfo->getOppVertex(i));
-	    BoundaryType boundaryType = elInfo->getBoundary(FACE, i);
-
-	    elObjects.addPeriodicFace(std::make_pair(face1, face2), elInfo->getBoundary(i));
-
-	    elObjects.addPeriodicVertex(std::make_pair(face1.get<0>(), face2.get<0>()), boundaryType);
-	    elObjects.addPeriodicVertex(std::make_pair(face1.get<1>(), face2.get<1>()), boundaryType);
-	    elObjects.addPeriodicVertex(std::make_pair(face1.get<2>(), face2.get<2>()), boundaryType);
-
-	    periodicDofAssoc[face1.get<0>()].insert(boundaryType);
-	    periodicDofAssoc[face1.get<1>()].insert(boundaryType);
-	    periodicDofAssoc[face1.get<2>()].insert(boundaryType);
-
-	    TEST_EXIT_DBG(face1.get<0>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<0>()] &&
-			  face1.get<1>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<1>()] &&
-			  face1.get<2>() == mesh->getPeriodicAssociations(boundaryType)[face2.get<2>()])
-	      ("Should not happen!\n");
-
-
-	    DofEdge elEdge1 = std::make_pair(face1.get<0>(), face1.get<1>());
-	    DofEdge elEdge2 = std::make_pair(face1.get<0>(), face1.get<2>());
-	    DofEdge elEdge3 = std::make_pair(face1.get<1>(), face1.get<2>());
-	    DofEdge neighEdge1 = std::make_pair(face2.get<0>(), face2.get<1>());
-	    DofEdge neighEdge2 = std::make_pair(face2.get<0>(), face2.get<2>());
-	    DofEdge neighEdge3 = std::make_pair(face2.get<1>(), face2.get<2>());
-
-
-	    elObjects.addPeriodicEdge(std::make_pair(elEdge1, neighEdge1), boundaryType);
-	    elObjects.addPeriodicEdge(std::make_pair(elEdge2, neighEdge2), boundaryType);
-	    elObjects.addPeriodicEdge(std::make_pair(elEdge3, neighEdge3), boundaryType);
-
-	    periodicEdgeAssoc[elEdge1].insert(neighEdge1);
-	    periodicEdgeAssoc[elEdge2].insert(neighEdge2);
-	    periodicEdgeAssoc[elEdge3].insert(neighEdge3);
-	  }
-	}
-	break;
-      }
-	
       elInfo = stack.traverseNext(elInfo);
     }
 
+    // === Create periodic data, if there are periodic boundary conditions. ===
+    elObjects.createPeriodicData();
 
-    // === Create mesh element data for this rank. ===
 
+    // === Create mesh element data for this rank. ===
     elObjects.createRankData(partitionVec);
-
-
-    // === Search for interectly connected vertices in periodic boundaries. ===
-
-    if (elObjects.periodicVertices.size() > 0) {
-
-      
-      // === Search for an unsed boundary index. ===
-
-      BoundaryType newPeriodicBoundaryType = 0;
-      for (std::map<BoundaryType, VertexVector*>::iterator it = mesh->getPeriodicAssociations().begin();
-	   it != mesh->getPeriodicAssociations().end(); ++it)
-	newPeriodicBoundaryType = min(newPeriodicBoundaryType, it->first);
-
-      TEST_EXIT_DBG(newPeriodicBoundaryType < 0)("Should not happen!\n");
-      newPeriodicBoundaryType--;
-      mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
-	new VertexVector(feSpace->getAdmin(), "");
-
-
-      // === Get all vertex DOFs that have multiple periodic associations. ===
-
-      std::vector<DegreeOfFreedom> multPeriodicDof2, multPeriodicDof3;
-      for (std::map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin();
-	   it != periodicDofAssoc.end(); ++it) {
-	TEST_EXIT_DBG((mesh->getDim() == 2 && it->second.size() <= 2) ||
-		      (mesh->getDim() == 3 && it->second.size() <= 3))
-	  ("Should not happen!\n");
-	
-	if (it->second.size() == 2)
-	  multPeriodicDof2.push_back(it->first);
-	if (it->second.size() == 3)
-	  multPeriodicDof3.push_back(it->first);
-      }
-
-
-      if (mesh->getDim() == 2) {
-	TEST_EXIT_DBG(multPeriodicDof2.size() == 0 || 
-		      multPeriodicDof2.size() == 4)
-	  ("Should not happen (%d)!\n", multPeriodicDof2.size());
-	TEST_EXIT_DBG(multPeriodicDof3.size() == 0)("Should not happen!\n");
-      }
-      if (mesh->getDim() == 3) {
-	TEST_EXIT_DBG(multPeriodicDof3.size() == 0 || 
-		      multPeriodicDof3.size() == 8)
-	  ("Should not happen (%d)!\n", multPeriodicDof3.size());
-      }
-
-
-      if (multPeriodicDof2.size() > 0) {
-	for (unsigned int i = 0; i < multPeriodicDof2.size(); i++) {
-	  DegreeOfFreedom dof0 = multPeriodicDof2[i];
-	  if (dof0 == -1)
-	    continue;
-
-	  DegreeOfFreedom dof1 = -1;
-	  DegreeOfFreedom dof2 = -1;
-	  BoundaryType type0 = *(periodicDofAssoc[dof0].begin());
-	  BoundaryType type1 = *(++(periodicDofAssoc[dof0].begin()));
-
-	  for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin();
-	       it != elObjects.periodicVertices.end(); ++it) {
-	    if (it->first.first == dof0 && it->second == type0)
-	      dof1 = it->first.second;
-	    if (it->first.first == dof0 && it->second == type1)
-	      dof2 = it->first.second;
-
-	    if (dof1 != -1 && dof2 != -1)
-	      break;
-	  }
-
-	  TEST_EXIT_DBG(dof1 != -1 && dof2 != -1)("Should not happen!\n");
-
-	  DegreeOfFreedom dof3 = -1;
-	  for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin();
-	       it != elObjects.periodicVertices.end(); ++it) {
-	    if (it->first.first == dof1 && it->second == type1) {
-	      dof3 = it->first.second;
-
-	      TEST_EXIT_DBG(elObjects.periodicVertices[std::make_pair(dof2, dof3)] == type0)
-		("Should not happen!\n");
-
-	      break;
-	    }
-	  }
-	  
-	  TEST_EXIT_DBG(dof3 != -1)("Should not happen!\n");
-	  TEST_EXIT_DBG(elObjects.periodicVertices.count(std::make_pair(dof0, dof3)) == 0)
-	    ("Should not happen!\n");
-	  TEST_EXIT_DBG(elObjects.periodicVertices.count(std::make_pair(dof3, dof0)) == 0)
-	    ("Should not happen!\n");
-	  
-	  elObjects.periodicVertices[std::make_pair(dof0, dof3)] = newPeriodicBoundaryType;
-	  elObjects.periodicVertices[std::make_pair(dof3, dof0)] = newPeriodicBoundaryType;
-
-	  for (unsigned int j = i + 1; j < multPeriodicDof2.size(); j++)
-	    if (multPeriodicDof2[j] == dof3)
-	      multPeriodicDof2[j] = -1;
-	}
-      }
-
-      if (multPeriodicDof3.size() > 0) {
-	int nMultPeriodicDofs = multPeriodicDof3.size();
-	for (int i = 0; i < nMultPeriodicDofs; i++) {
-	  for (int j = i + 1; j < nMultPeriodicDofs; j++) {
-	    std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs0 = 
-	      std::make_pair(multPeriodicDof3[i], multPeriodicDof3[j]);
-	    std::pair<DegreeOfFreedom, DegreeOfFreedom> perDofs1 = 
-	      std::make_pair(multPeriodicDof3[j], multPeriodicDof3[i]);
-	    
-	    if (elObjects.periodicVertices.count(perDofs0) == 0) {
-	      TEST_EXIT_DBG(elObjects.periodicVertices.count(perDofs1) == 0)
-		("Should not happen!\n");
-	      
-	      elObjects.periodicVertices[perDofs0] = newPeriodicBoundaryType;
-	      elObjects.periodicVertices[perDofs1] = newPeriodicBoundaryType;
-	      newPeriodicBoundaryType--;
-	      mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
-		new VertexVector(feSpace->getAdmin(), "");
-	    }
-	  }
-	}
-      }
-
-
-      // === Get all edges that have multiple periodic associations (3D only!). ===
-
-      for (std::map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin();
-	   it != periodicEdgeAssoc.end(); ++it) {
-	if (it->second.size() > 1) {
-	  TEST_EXIT_DBG(mesh->getDim() == 3)("Should not happen!\n");
-	  TEST_EXIT_DBG(it->second.size() == 2)("Should not happen!\n");
-
-	  std::pair<DofEdge, DofEdge> perEdge0 =
-	    std::make_pair(*(it->second.begin()), *(++(it->second.begin())));
-	  std::pair<DofEdge, DofEdge> perEdge1 =
-	    std::make_pair(perEdge0.second, perEdge0.first);
-
-	  elObjects.periodicEdges[perEdge0] = newPeriodicBoundaryType;
-	  elObjects.periodicEdges[perEdge1] = newPeriodicBoundaryType;
-	  newPeriodicBoundaryType--;
-	  mesh->getPeriodicAssociations()[newPeriodicBoundaryType] = 
-	    new VertexVector(feSpace->getAdmin(), "");      
-	}
-      }
-
-
-      // === In debug mode we make some tests, if the periodic structures are set ===
-      // === in a symmetric way, i.e., if A -> B for a specific boundary type,    ===
-      // === there must be a mapping B -> A with the same boundary type.          ===
-
-#if (DEBUG != 0)
-      for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.periodicVertices.begin();
-	   it != elObjects.periodicVertices.end(); ++it) {
-	std::pair<DegreeOfFreedom, DegreeOfFreedom> testVertex = 
-	  std::make_pair(it->first.second, it->first.first);
-	
-	TEST_EXIT_DBG(elObjects.periodicVertices.count(testVertex) == 1)("Should not happen!\n");
-	TEST_EXIT_DBG(elObjects.periodicVertices[testVertex] == it->second)("Should not happen!\n");
-      }
-
-      for (PerBoundMap<DofEdge>::iterator it = elObjects.periodicEdges.begin();
-	   it != elObjects.periodicEdges.end(); ++it) {
-	std::pair<DofEdge, DofEdge> testEdge = 
-	  std::make_pair(it->first.second, it->first.first);
-	
-	TEST_EXIT_DBG(elObjects.periodicEdges.count(testEdge) == 1)("Should not happen!\n");
-	TEST_EXIT_DBG(elObjects.periodicEdges[testEdge] == it->second)("Should not happen!\n");
-      }
-
-      for (PerBoundMap<DofFace>::iterator it = elObjects.periodicFaces.begin();
-	   it != elObjects.periodicFaces.end(); ++it) {
-	std::pair<DofFace, DofFace> testFace = 
-	  std::make_pair(it->first.second, it->first.first);
-	
-	TEST_EXIT_DBG(elObjects.periodicFaces.count(testFace) == 1)("Should not happen!\n");
-	TEST_EXIT_DBG(elObjects.periodicFaces[testFace] == it->second)("Should not happen!\n");
-      }
-#endif
-
-
-    }
-
   }
 
 
@@ -1628,13 +1366,8 @@ namespace AMDiS {
 	      bound.neighObj.elType = macroElIndexTypeMap[it2->second.elIndex];
 	      bound.neighObj.subObj = geoIndex;
 	      bound.neighObj.ithObj = it2->second.ithObject;
-	      
-	      TEST_EXIT_DBG(rankBoundEl.boundaryType == it2->second.boundaryType)
-		("Wrong boundary types: %d %d\n",
-		 rankBoundEl.boundaryType,
-		 it2->second.boundaryType);
-	      
-	      bound.type = rankBoundEl.boundaryType;
+
+	      bound.type = INTERIOR;
 	      
 	      AtomicBoundary& b = myIntBoundary.getNewAtomic(it2->first);
 	      b = bound;
@@ -1652,12 +1385,8 @@ namespace AMDiS {
 	    bound.neighObj.elType = -1;
 	    bound.neighObj.subObj = geoIndex;
 	    bound.neighObj.ithObj = ownerBoundEl.ithObject;
-	    
-	    TEST_EXIT_DBG(rankBoundEl.boundaryType == ownerBoundEl.boundaryType)
-	      ("Should not happen: %d %d\n", 
-	       rankBoundEl.boundaryType, ownerBoundEl.boundaryType);
-	    
-	    bound.type = rankBoundEl.boundaryType;
+
+	    bound.type = INTERIOR;
 	    
 	    AtomicBoundary& b = otherIntBoundary.getNewAtomic(owner);
 	    b = bound;	 
-- 
GitLab