diff --git a/AMDiS/src/CoarseningManager3d.cc b/AMDiS/src/CoarseningManager3d.cc
index 96a790e91d338aa2f7ed7c1ef20f78066dc9898a..374f5c69c7cf966a472ebbc0bc88dd1f0163835b 100644
--- a/AMDiS/src/CoarseningManager3d.cc
+++ b/AMDiS/src/CoarseningManager3d.cc
@@ -313,46 +313,70 @@ namespace AMDiS {
     coarsenList.setElement(*n_neigh, neigh);
     coarsenList.setElType(*n_neigh, neigh_info->getType()); 
   
-    int n_vertices = mesh->getGeo(VERTEX);
-    int i, j, k, edge_no;
-			 
+    int nVertices = mesh->getGeo(VERTEX);			 
+
     while (neigh != el) {
-      for (j = 0; j < n_vertices; j++)
+      // === Find the coarsening edge on the current neighbour element. ===
+
+      int i, j, k;
+
+      // === First, try to identify the edge DOFs directly. ===
+
+      for (j = 0; j < nVertices; j++)
 	if (neigh->getDof(j) == edge[0])
 	  break;
-      for (k = 0; k < n_vertices; k++)
+
+      for (k = 0; k < nVertices; k++)
 	if (neigh->getDof(k) == edge[1])
 	  break;
 
-      if (j > 3 || k > 3) {
-	for (j = 0; j < n_vertices; j++)
+      // === If one of the edge DOFs was not found, try to make use of periodic ===
+      // === DOF associations. First, use the direct associations between DOFs. ===
+      // === If this will not work, continue with testing on indirect           ===
+      // === associations.                                                      ===
+
+      if (j >= nVertices) {
+	for (j = 0; j < nVertices; j++)
 	  if (mesh->associated(neigh->getDof(j, 0), edge[0][0]))
 	    break;
-	for (k = 0; k < n_vertices; k++)
+	
+	if (j >= nVertices)
+	  for (j = 0; j < nVertices; j++)
+	    if (mesh->indirectlyAssociated(neigh->getDof(j, 0), edge[0][0]))
+	      break;
+
+	TEST_EXIT_DBG(j < nVertices)
+	  ("Process element %d: DOF %d not found on element %d with nodes (%d %d %d %d)\n", 
+	   el->getIndex(), edge[0][0], neigh->getIndex(), neigh->getDof(0, 0),
+	   neigh->getDof(1, 0), neigh->getDof(2, 0), neigh->getDof(3, 0));
+      }
+      
+      if (k >= nVertices) {
+	for (k = 0; k < nVertices; k++)
 	  if (mesh->associated(neigh->getDof(k, 0), edge[1][0]))
 	    break;
+
+	if (k >= nVertices)
+	  for (k = 0; k < nVertices; k++)
+	    if (mesh->indirectlyAssociated(neigh->getDof(k, 0), edge[1][0]))
+	      break;
      
-	TEST_EXIT_DBG(j < n_vertices)
-	  ("dof %d not found on element %d with nodes (%d %d %d %d)\n", 
-	   edge[0][0], neigh->getIndex(), neigh->getDof(0, 0),
-	   neigh->getDof(1, 0), neigh->getDof(2, 0), neigh->getDof(3, 0));
-	
-	TEST_EXIT_DBG(k < n_vertices)
-	  ("dof %d not found on element %d with nodes (%d %d %d %d)\n", 
-	   edge[1][0], neigh->getIndex(), neigh->getDof(0, 0),
+	TEST_EXIT_DBG(k < nVertices)
+	  ("Process element %d: DOF %d not found on element %d with nodes (%d %d %d %d)\n", 
+	   el->getIndex(), edge[1][0], neigh->getIndex(), neigh->getDof(0, 0),
 	   neigh->getDof(1, 0), neigh->getDof(2, 0), neigh->getDof(3, 0));
       }
-      edge_no = Tetrahedron::edgeOfDofs[j][k];
-      coarsenList.setCoarsePatch(*n_neigh, edge_no == 0);
 
-      /****************************************************************************/
-      /*  get the direction of the next neighbour				    */
-      /****************************************************************************/
+      int edgeNo = Tetrahedron::edgeOfDofs[j][k];
+      coarsenList.setCoarsePatch(*n_neigh, edgeNo == 0);
+
+
+      // === Get the direction of the next neighbour. ===
 
-      if (next_el[edge_no][0] != opp_v)
-	i = next_el[edge_no][0];
+      if (next_el[edgeNo][0] != opp_v)
+	i = next_el[edgeNo][0];
       else
-	i = next_el[edge_no][1];
+	i = next_el[edgeNo][1];
 
       ++*n_neigh;
 
@@ -383,7 +407,7 @@ namespace AMDiS {
     /*  the domain's boundary is reached; loop back to the starting el          */
     /****************************************************************************/
 
-    i = *n_neigh - 1;
+    int i = *n_neigh - 1;
     opp_v = coarsenList.getOppVertex(i, 0);
     do {
       TEST_EXIT_DBG(neigh_info->getNeighbour(opp_v)  &&  i > 0)