diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
index 256956faff92446069518f612ff9d1db9521d746..e5e640f6f810380215419bf6de4a5ce1b928a7af 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/processorGAMGInterface/processorGAMGInterface.C
@@ -25,7 +25,8 @@ License
 
 #include "processorGAMGInterface.H"
 #include "addToRunTimeSelectionTable.H"
-#include "Map.H"
+#include "HashTable.H"
+#include "labelPair.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -62,171 +63,65 @@ Foam::processorGAMGInterface::processorGAMGInterface
     ),
     fineProcInterface_(refCast<const processorLduInterface>(fineInterface))
 {
-    // Make a lookup table of entries for owner/neighbour
-    Map<SLList<label> > neighboursTable
+    // From coarse face to coarse cell
+    DynamicList<label> dynFaceCells(localRestrictAddressing.size());
+    // From fine face to coarse face
+    DynamicList<label> dynFaceRestrictAddressing
     (
         localRestrictAddressing.size()
     );
 
-    // Table of face-sets to be agglomerated
-    Map<SLList<SLList<label> > > faceFaceTable
+    // From coarse cell pair to coarse face
+    HashTable<label, labelPair, labelPair::Hash<> > cellsToCoarseFace
     (
-        localRestrictAddressing.size()
+        2*localRestrictAddressing.size()
     );
 
-    label nCoarseFaces = 0;
-
     forAll(localRestrictAddressing, ffi)
     {
-        label curMaster = -1;
-        label curSlave = -1;
+        labelPair cellPair;
 
         // Do switching on master/slave indexes based on the owner/neighbour of
         // the processor index such that both sides get the same answer.
         if (myProcNo() < neighbProcNo())
         {
             // Master side
-            curMaster = localRestrictAddressing[ffi];
-            curSlave = neighbourRestrictAddressing[ffi];
+            cellPair = labelPair
+            (
+                localRestrictAddressing[ffi],
+                neighbourRestrictAddressing[ffi]
+            );
         }
         else
         {
             // Slave side
-            curMaster = neighbourRestrictAddressing[ffi];
-            curSlave = localRestrictAddressing[ffi];
-        }
-
-        // Look for the master cell.  If it has already got a face,
-        // add the coefficient to the face.  If not, create a new face.
-        if (neighboursTable.found(curMaster))
-        {
-            // Check all current neighbours to see if the current slave already
-            // exists and if so, add the fine face to the agglomeration.
-
-            SLList<label>& curNbrs = neighboursTable.find(curMaster)();
-
-            SLList<SLList<label> >& curFaceFaces =
-                faceFaceTable.find(curMaster)();
-
-            bool nbrFound = false;
-
-            SLList<label>::iterator nbrsIter = curNbrs.begin();
-
-            SLList<SLList<label> >::iterator faceFacesIter =
-                curFaceFaces.begin();
-
-            for
+            cellPair = labelPair
             (
-                ;
-                nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
-                ++nbrsIter, ++faceFacesIter
-            )
-            {
-                if (nbrsIter() == curSlave)
-                {
-                    nbrFound = true;
-                    faceFacesIter().append(ffi);
-                    break;
-                }
-            }
-
-            if (!nbrFound)
-            {
-                curNbrs.append(curSlave);
-                curFaceFaces.append(ffi);
-
-                // New coarse face created
-                nCoarseFaces++;
-            }
-        }
-        else
-        {
-            // This master has got no neighbours yet.  Add a neighbour
-            // and a coefficient, thus creating a new face
-            neighboursTable.insert(curMaster, SLList<label>(curSlave));
-            faceFaceTable.insert(curMaster, SLList<SLList<label> >(ffi));
-
-            // New coarse face created
-            nCoarseFaces++;
+                neighbourRestrictAddressing[ffi],
+                localRestrictAddressing[ffi]
+            );
         }
-    } // end for all fine faces
-
-
-
-    faceCells_.setSize(nCoarseFaces, -1);
-    faceRestrictAddressing_.setSize(localRestrictAddressing.size());
 
-    labelList contents = neighboursTable.toc();
+        HashTable<label, labelPair, labelPair::Hash<> >::const_iterator fnd =
+            cellsToCoarseFace.find(cellPair);
 
-    // Reset face counter for re-use
-    nCoarseFaces = 0;
-
-    if (myProcNo() < neighbProcNo())
-    {
-        // On master side, the owner addressing is stored in table of contents
-        forAll(contents, masterI)
+        if (fnd == cellsToCoarseFace.end())
         {
-            SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
-
-            SLList<SLList<label> >& curFaceFaces =
-                faceFaceTable.find(contents[masterI])();
-
-            SLList<label>::iterator nbrsIter = curNbrs.begin();
-
-            SLList<SLList<label> >::iterator faceFacesIter =
-                curFaceFaces.begin();
-
-            for
-            (
-                ;
-                nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
-                ++nbrsIter, ++faceFacesIter
-            )
-            {
-                faceCells_[nCoarseFaces] = contents[masterI];
-
-                forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
-                {
-                    faceRestrictAddressing_[facesIter()] = nCoarseFaces;
-                }
-
-                nCoarseFaces++;
-            }
+            // New coarse face
+            label coarseI = dynFaceCells.size();
+            dynFaceRestrictAddressing.append(coarseI);
+            dynFaceCells.append(localRestrictAddressing[ffi]);
+            cellsToCoarseFace.insert(cellPair, coarseI);
         }
-    }
-    else
-    {
-        // On slave side, the owner addressing is stored in linked lists
-        forAll(contents, masterI)
+        else
         {
-            SLList<label>& curNbrs = neighboursTable.find(contents[masterI])();
-
-            SLList<SLList<label> >& curFaceFaces =
-                faceFaceTable.find(contents[masterI])();
-
-            SLList<label>::iterator nbrsIter = curNbrs.begin();
-
-            SLList<SLList<label> >::iterator faceFacesIter =
-                curFaceFaces.begin();
-
-            for
-            (
-                ;
-                nbrsIter != curNbrs.end(), faceFacesIter != curFaceFaces.end();
-                ++nbrsIter, ++faceFacesIter
-            )
-            {
-                faceCells_[nCoarseFaces] = nbrsIter();
-
-                forAllConstIter(SLList<label>, faceFacesIter(), facesIter)
-                {
-                    faceRestrictAddressing_[facesIter()] = nCoarseFaces;
-                }
-
-                nCoarseFaces++;
-            }
+            // Already have coarse face
+            dynFaceRestrictAddressing.append(fnd());
         }
     }
+
+    faceCells_.transfer(dynFaceCells);
+    faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
 }