diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 2c01641321e1085592aaff8666f44afa72ea0205..321855de69a28a53a8a1dde8ee3da614ff8cc626 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -324,8 +324,14 @@ GAMGProcAgglomerations = $(GAMG)/GAMGProcAgglomerations
 
 GAMGProcAgglomeration = $(GAMGProcAgglomerations)/GAMGProcAgglomeration
 $(GAMGProcAgglomeration)/GAMGProcAgglomeration.C
-masterCoarsest = $(GAMGProcAgglomerations)/masterCoarsest
-$(masterCoarsest)/masterCoarsest.C
+masterCoarsestGAMGProcAgglomeration = $(GAMGProcAgglomerations)/masterCoarsestGAMGProcAgglomeration
+$(masterCoarsestGAMGProcAgglomeration)/masterCoarsestGAMGProcAgglomeration.C
+manualGAMGProcAgglomeration = $(GAMGProcAgglomerations)/manualGAMGProcAgglomeration
+$(manualGAMGProcAgglomeration)/manualGAMGProcAgglomeration.C
+/*
+cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration
+$(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C
+*/
 
 
 meshes/lduMesh/lduMesh.C
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C
index 8832fb81a7b5bf9ac04451750a67f120d0c5283d..324ace4c917d77939f31ab4b84c10d5e6b82ae44 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.C
@@ -38,6 +38,7 @@ namespace Foam
     defineTypeNameAndDebug(GAMGAgglomeration, 0);
     defineRunTimeSelectionTable(GAMGAgglomeration, lduMesh);
     defineRunTimeSelectionTable(GAMGAgglomeration, lduMatrix);
+    defineRunTimeSelectionTable(GAMGAgglomeration, geometry);
 }
 
 
@@ -69,6 +70,24 @@ void Foam::GAMGAgglomeration::compactLevels(const label nCreatedLevels)
 
         procAgglomeratorPtr_().agglomerate();
     }
+
+    if (debug)
+    {
+        for (label levelI = 0; levelI <= size(); levelI++)
+        {
+            if (hasMeshLevel(levelI))
+            {
+                const lduMesh& fineMesh = meshLevel(levelI);
+                Pout<< "Level " << levelI << " fine mesh:"<< nl;
+                Pout<< fineMesh.info() << endl;
+            }
+            else
+            {
+                Pout<< "Level " << levelI << " has no fine mesh:" << nl
+                    << endl;
+            }
+        }
+    }
 }
 
 
@@ -241,20 +260,58 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
 }
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::GAMGAgglomeration::~GAMGAgglomeration()
+Foam::autoPtr<Foam::GAMGAgglomeration> Foam::GAMGAgglomeration::New
+(
+    const lduMesh& mesh,
+    const scalarField& cellVolumes,
+    const vectorField& faceAreas,
+    const dictionary& controlDict
+)
 {
-    forAllReverse(procCommunicator_, i)
+    const word agglomeratorType(controlDict.lookup("agglomerator"));
+
+    const_cast<Time&>(mesh.thisDb().time()).libs().open
+    (
+        controlDict,
+        "geometricGAMGAgglomerationLibs",
+        geometryConstructorTablePtr_
+    );
+
+    geometryConstructorTable::iterator cstrIter =
+        geometryConstructorTablePtr_->find(agglomeratorType);
+
+    if (cstrIter == geometryConstructorTablePtr_->end())
     {
-        if (procCommunicator_[i] != -1)
-        {
-            UPstream::freeCommunicator(procCommunicator_[i]);
-        }
+        FatalErrorIn
+        (
+            "GAMGAgglomeration::New"
+            "(const lduMesh& mesh, const dictionary& controlDict)"
+        )   << "Unknown GAMGAgglomeration type "
+            << agglomeratorType << ".\n"
+            << "Valid geometric GAMGAgglomeration types are :"
+            << geometryConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
     }
+
+    return autoPtr<GAMGAgglomeration>
+    (
+        cstrIter()
+        (
+            mesh,
+            cellVolumes,
+            faceAreas,
+            controlDict
+        )
+    );
 }
 
 
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::GAMGAgglomeration::~GAMGAgglomeration()
+{}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 const Foam::lduMesh& Foam::GAMGAgglomeration::meshLevel
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.H
index faaf62bbc1ed080c5a864fb2e66440c2b37b2638..b3617965c7fce028db2f836952fc06ee168a9b09 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGAgglomerations/GAMGAgglomeration/GAMGAgglomeration.H
@@ -253,6 +253,27 @@ public:
             )
         );
 
+        //- Runtime selection table for matrix or mixed geometric/matrix
+        //  agglomerators
+        declareRunTimeSelectionTable
+        (
+            autoPtr,
+            GAMGAgglomeration,
+            geometry,
+            (
+                const lduMesh& mesh,
+                const scalarField& cellVolumes,
+                const vectorField& faceAreas,
+                const dictionary& controlDict
+            ),
+            (
+                mesh,
+                cellVolumes,
+                faceAreas,
+                controlDict
+            )
+        );
+
 
     // Constructors
 
@@ -280,6 +301,15 @@ public:
             const dictionary& controlDict
         );
 
+        //- Return the selected geometric agglomerator
+        static autoPtr<GAMGAgglomeration> New
+        (
+            const lduMesh& mesh,
+            const scalarField& cellVolumes,
+            const vectorField& faceAreas,
+            const dictionary& controlDict
+        );
+
 
     //- Destructor
     ~GAMGAgglomeration();
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/GAMGProcAgglomeration/GAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/GAMGProcAgglomeration/GAMGProcAgglomeration.C
index b8a1e59a74522138ccb6cff6815c0c81f66b03c3..f825ca769d0a10fda208d2d53bc21b5166075b60 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/GAMGProcAgglomeration/GAMGProcAgglomeration.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/GAMGProcAgglomeration/GAMGProcAgglomeration.C
@@ -47,36 +47,11 @@ void Foam::GAMGProcAgglomeration::printStats
     {
         if (agglom.hasMeshLevel(levelI))
         {
-            const lduMesh& fineMesh = agglom.meshLevel(levelI);
-            const lduInterfacePtrsList& interfaces =
-                agglom.interfaceLevel(levelI);
-
-            os  << "Level " << levelI << " fine mesh:"<< nl
-                << "    nCells:"
-                << fineMesh.lduAddr().size() << nl
-                << "    nFaces:"
-                << fineMesh.lduAddr().lowerAddr().size() << nl
-                << "    nInterfaces:" << interfaces.size()
-                << endl;
-
-            forAll(interfaces, i)
-            {
-                if (interfaces.set(i))
-                {
-                    os  << "        " << i
-                        << "\tsize:" << interfaces[i].faceCells().size()
-                        << endl;
-                }
-            }
-
-            os  << fineMesh.info() << endl;
-
-            os  << endl;
+            os  << agglom.meshLevel(levelI).info() << endl;
         }
         else
         {
-            os  << "Level " << levelI << " has no fine mesh:" << nl
-                << endl;
+            os  << "Level " << levelI << " has no fine mesh:" << endl;
         }
 
         if
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C
new file mode 100644
index 0000000000000000000000000000000000000000..9e0439c578f5db795e24cef96acc522d776cd6ee
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.C
@@ -0,0 +1,170 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "manualGAMGProcAgglomeration.H"
+#include "addToRunTimeSelectionTable.H"
+#include "GAMGAgglomeration.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(manualGAMGProcAgglomeration, 0);
+
+    addToRunTimeSelectionTable
+    (
+        GAMGProcAgglomeration,
+        manualGAMGProcAgglomeration,
+        GAMGAgglomeration
+    );
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::manualGAMGProcAgglomeration::manualGAMGProcAgglomeration
+(
+    GAMGAgglomeration& agglom,
+    const dictionary& controlDict
+)
+:
+    GAMGProcAgglomeration(agglom, controlDict),
+    procAgglomMaps_(controlDict.lookup("processorAgglomeration"))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::manualGAMGProcAgglomeration::
+~manualGAMGProcAgglomeration()
+{
+    forAllReverse(comms_, i)
+    {
+        if (comms_[i] != -1)
+        {
+            UPstream::freeCommunicator(comms_[i]);
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::manualGAMGProcAgglomeration::agglomerate()
+{
+    if (debug)
+    {
+        Pout<< nl << "Starting mesh overview" << endl;
+        printStats(Pout, agglom_);
+    }
+
+    if (agglom_.size() >= 1)
+    {
+        forAll(procAgglomMaps_, i)
+        {
+            const label fineLevelIndex = procAgglomMaps_[i].first();
+
+            if (fineLevelIndex >= agglom_.size())
+            {
+                WarningIn("manualGAMGProcAgglomeration::agglomerate()")
+                    << "Ignoring specification for level " << fineLevelIndex
+                    << " since outside agglomeration." << endl;
+
+                continue;
+            }
+
+
+            if (agglom_.hasMeshLevel(fineLevelIndex))
+            {
+                const labelList& procAgglomMap = procAgglomMaps_[i].second();
+                // Get the fine mesh
+                const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
+
+
+                if (procAgglomMap.size() != Pstream::nProcs(levelMesh.comm()))
+                {
+                    FatalErrorIn("manualGAMGProcAgglomeration::agglomerate()")
+                        << "At level " << fineLevelIndex
+                        << "The fine-to-coarse agglomeration map size "
+                        << procAgglomMap.size() << " differs from the"
+                        << " number of processors "
+                        << Pstream::nProcs(levelMesh.comm())
+                        << exit(FatalError);
+                }
+
+                // Master processor
+                labelList masterProcs;
+                // Local processors that agglomerate. agglomProcIDs[0] is in
+                // masterProc.
+                List<int> agglomProcIDs;
+                GAMGAgglomeration::calculateRegionMaster
+                (
+                    levelMesh.comm(),
+                    procAgglomMap,
+                    masterProcs,
+                    agglomProcIDs
+                );
+
+                // Allocate a communicator for the processor-agglomerated matrix
+                comms_.append
+                (
+                    UPstream::allocateCommunicator
+                    (
+                        levelMesh.comm(),
+                        masterProcs
+                    )
+                );
+
+                // Use procesor agglomeration maps to do the actual collecting.
+                if (Pstream::myProcNo(levelMesh.comm()) != -1)
+                {
+                    GAMGProcAgglomeration::agglomerate
+                    (
+                        fineLevelIndex,
+                        procAgglomMap,
+                        masterProcs,
+                        agglomProcIDs,
+                        comms_.last()
+                    );
+                }
+            }
+        }
+
+        // Print a bit
+        if (debug)
+        {
+            Pout<< nl << "Agglomerated mesh overview" << endl;
+            printStats(Pout, agglom_);
+        }
+    }
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H
new file mode 100644
index 0000000000000000000000000000000000000000..914518f3bdac4b702bebbc958934b025e9a0622d
--- /dev/null
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/manualGAMGProcAgglomeration/manualGAMGProcAgglomeration.H
@@ -0,0 +1,114 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::manualGAMGProcAgglomeration
+
+Description
+    Manual processor agglomeration of GAMGAgglomerations.
+
+SourceFiles
+    manualGAMGProcAgglomeration.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef manualGAMGProcAgglomeration_H
+#define manualGAMGProcAgglomeration_H
+
+#include "GAMGProcAgglomeration.H"
+#include "DynamicList.H"
+#include "Tuple2.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class GAMGAgglomeration;
+
+/*---------------------------------------------------------------------------*\
+              Class manualGAMGProcAgglomeration Declaration
+\*---------------------------------------------------------------------------*/
+
+class manualGAMGProcAgglomeration
+:
+    public GAMGProcAgglomeration
+{
+    // Private data
+
+        //- Per level the agglomeration map
+        const List<Tuple2<label, labelList> > procAgglomMaps_;
+
+        //- Any allocated communicators
+        DynamicList<label> comms_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        manualGAMGProcAgglomeration
+        (
+            const manualGAMGProcAgglomeration&
+        );
+
+        //- Disallow default bitwise assignment
+        void operator=(const manualGAMGProcAgglomeration&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("manual");
+
+
+    // Constructors
+
+        //- Construct given agglomerator and controls
+        manualGAMGProcAgglomeration
+        (
+            GAMGAgglomeration& agglom,
+            const dictionary& controlDict
+        );
+
+
+    //- Destructor
+    virtual ~manualGAMGProcAgglomeration();
+
+
+    // Member Functions
+
+       //- Modify agglomeration. Return true if modified
+        virtual bool agglomerate();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C
similarity index 57%
rename from src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.C
rename to src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C
index 6a88ef4112a9993411bfbd89c4e459982f8caf28..8f3552c9ff12ce82200a1510005441febb0fdfd7 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.C
@@ -23,7 +23,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "masterCoarsest.H"
+#include "masterCoarsestGAMGProcAgglomeration.H"
 #include "addToRunTimeSelectionTable.H"
 #include "GAMGAgglomeration.H"
 
@@ -31,12 +31,12 @@ License
 
 namespace Foam
 {
-    defineTypeNameAndDebug(masterCoarsest, 0);
+    defineTypeNameAndDebug(masterCoarsestGAMGProcAgglomeration, 0);
 
     addToRunTimeSelectionTable
     (
         GAMGProcAgglomeration,
-        masterCoarsest,
+        masterCoarsestGAMGProcAgglomeration,
         GAMGAgglomeration
     );
 }
@@ -47,7 +47,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::masterCoarsest::masterCoarsest
+Foam::masterCoarsestGAMGProcAgglomeration::masterCoarsestGAMGProcAgglomeration
 (
     GAMGAgglomeration& agglom,
     const dictionary& controlDict
@@ -59,10 +59,22 @@ Foam::masterCoarsest::masterCoarsest
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
+Foam::masterCoarsestGAMGProcAgglomeration::
+~masterCoarsestGAMGProcAgglomeration()
+{
+    forAllReverse(comms_, i)
+    {
+        if (comms_[i] != -1)
+        {
+            UPstream::freeCommunicator(comms_[i]);
+        }
+    }
+}
+
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::masterCoarsest::agglomerate()
+bool Foam::masterCoarsestGAMGProcAgglomeration::agglomerate()
 {
     if (debug)
     {
@@ -76,60 +88,50 @@ bool Foam::masterCoarsest::agglomerate()
         // restrictAddressing)
         label fineLevelIndex = agglom_.size()-1;
 
-        // Get the coarse mesh
-        const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex-1);
-        label levelComm = levelMesh.comm();
-
-        // Processor restriction map: per processor the coarse processor
-        labelList procAgglomMap(UPstream::nProcs(levelComm));
-        //{
-        //    label half = (procAgglomMap.size()+1)/2;
-        //    for (label i = 0; i < half; i++)
-        //    {
-        //        procAgglomMap[i] = 0;
-        //    }
-        //    for (label i = half; i < procAgglomMap.size(); i++)
-        //    {
-        //        procAgglomMap[i] = 1;
-        //    }
-        //}
-        procAgglomMap = 0;
-
-        // Master processor
-        labelList masterProcs;
-        // Local processors that agglomerate. agglomProcIDs[0] is in
-        // masterProc.
-        List<int> agglomProcIDs;
-        GAMGAgglomeration::calculateRegionMaster
-        (
-            levelComm,
-            procAgglomMap,
-            masterProcs,
-            agglomProcIDs
-        );
-
-        // Allocate a communicator for the processor-agglomerated matrix
-        label procAgglomComm = UPstream::allocateCommunicator
-        (
-            levelComm,
-            masterProcs
-        );
-
-
-        // Above should really be determined by a procesor-agglomeration
-        // engine. Use procesor agglomeration maps to do the actual
-        // collecting.
-
-        if (Pstream::myProcNo(levelComm) != -1)
+        if (agglom_.hasMeshLevel(fineLevelIndex))
         {
-            GAMGProcAgglomeration::agglomerate
+            // Get the fine mesh
+            const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
+            label levelComm = levelMesh.comm();
+
+            // Processor restriction map: per processor the coarse processor
+            labelList procAgglomMap(UPstream::nProcs(levelComm), 0);
+
+            // Master processor
+            labelList masterProcs;
+            // Local processors that agglomerate. agglomProcIDs[0] is in
+            // masterProc.
+            List<int> agglomProcIDs;
+            GAMGAgglomeration::calculateRegionMaster
             (
-                fineLevelIndex,
+                levelComm,
                 procAgglomMap,
                 masterProcs,
-                agglomProcIDs,
-                procAgglomComm
+                agglomProcIDs
             );
+
+            // Allocate a communicator for the processor-agglomerated matrix
+            comms_.append
+            (
+                UPstream::allocateCommunicator
+                (
+                    levelComm,
+                    masterProcs
+                )
+            );
+
+            // Use procesor agglomeration maps to do the actual collecting.
+            if (Pstream::myProcNo(levelComm) != -1)
+            {
+                GAMGProcAgglomeration::agglomerate
+                (
+                    fineLevelIndex,
+                    procAgglomMap,
+                    masterProcs,
+                    agglomProcIDs,
+                    comms_.last()
+                );
+            }
         }
     }
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.H
similarity index 79%
rename from src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.H
rename to src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.H
index 1b7828612cadba6cdb646a21b91256129c0c94b4..fef6b3519c8f8a5035109cdc4859132453d065f0 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsest/masterCoarsest.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGProcAgglomerations/masterCoarsestGAMGProcAgglomeration/masterCoarsestGAMGProcAgglomeration.H
@@ -22,20 +22,21 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::masterCoarsest
+    Foam::masterCoarsestGAMGProcAgglomeration
 
 Description
     Processor agglomeration of GAMGAgglomerations.
 
 SourceFiles
-    masterCoarsest.C
+    masterCoarsestGAMGProcAgglomeration.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef masterCoarsest_H
-#define masterCoarsest_H
+#ifndef masterCoarsestGAMGProcAgglomeration_H
+#define masterCoarsestGAMGProcAgglomeration_H
 
 #include "GAMGProcAgglomeration.H"
+#include "DynamicList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -45,22 +46,27 @@ namespace Foam
 class GAMGAgglomeration;
 
 /*---------------------------------------------------------------------------*\
-                    Class masterCoarsest Declaration
+              Class masterCoarsestGAMGProcAgglomeration Declaration
 \*---------------------------------------------------------------------------*/
 
-class masterCoarsest
+class masterCoarsestGAMGProcAgglomeration
 :
     public GAMGProcAgglomeration
 {
     // Private data
 
+        DynamicList<label> comms_;
+
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        masterCoarsest(const masterCoarsest&);
+        masterCoarsestGAMGProcAgglomeration
+        (
+            const masterCoarsestGAMGProcAgglomeration&
+        );
 
         //- Disallow default bitwise assignment
-        void operator=(const masterCoarsest&);
+        void operator=(const masterCoarsestGAMGProcAgglomeration&);
 
 
 public:
@@ -72,7 +78,7 @@ public:
     // Constructors
 
         //- Construct given agglomerator and controls
-        masterCoarsest
+        masterCoarsestGAMGProcAgglomeration
         (
             GAMGAgglomeration& agglom,
             const dictionary& controlDict
@@ -80,8 +86,7 @@ public:
 
 
     //- Destructor
-    virtual ~masterCoarsest()
-    {}
+    virtual ~masterCoarsestGAMGProcAgglomeration();
 
 
     // Member Functions
@@ -98,12 +103,6 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-//#ifdef NoRepository
-//#   include "masterCoarsestTemplates.C"
-//#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H
index c29e735542308e38e2118f9d6c8ac710073a7fdc..02dd25e22935ace84ad5fb6ccbdf93a52148e3c9 100644
--- a/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H
+++ b/src/OpenFOAM/meshes/lduMesh/lduPrimitiveMesh.H
@@ -96,10 +96,6 @@ class lduPrimitiveMesh
             const labelUList& u
         );
 
-        //- Get non-scheduled send/receive schedule
-        template<class ProcPatch>
-        static lduSchedule nonBlockingSchedule(const lduInterfacePtrsList&);
-
         //- Disallow default bitwise copy construct
         lduPrimitiveMesh(const lduPrimitiveMesh&);
 
@@ -271,6 +267,11 @@ public:
                 const labelList& procIDs,
                 PtrList<lduMesh>& otherMeshes
             );
+
+            //- Get non-scheduled send/receive schedule
+            template<class ProcPatch>
+            static lduSchedule nonBlockingSchedule(const lduInterfacePtrsList&);
+
 };
 
 
diff --git a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C
index b163d3b2dfbc21cf7b6f66815111a5e319e442ec..9bfcda020cb7667a93a0100736f326c434d04b5e 100644
--- a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C
+++ b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -40,6 +40,13 @@ namespace Foam
         faceAreaPairGAMGAgglomeration,
         lduMesh
     );
+
+    addToRunTimeSelectionTable
+    (
+        GAMGAgglomeration,
+        faceAreaPairGAMGAgglomeration,
+        geometry
+    );
 }
 
 
@@ -73,4 +80,33 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
 }
 
 
+Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
+(
+    const lduMesh& mesh,
+    const scalarField& cellVolumes,
+    const vectorField& faceAreas,
+    const dictionary& controlDict
+)
+:
+    pairGAMGAgglomeration(mesh, controlDict)
+{
+    vectorField n(faceAreas/mag(faceAreas));
+
+    //agglomerate(mesh, sqrt(mag(faceAreas)));
+    agglomerate
+    (
+        mesh,
+        mag
+        (
+            cmptMultiply
+            (
+                n,
+                vector(1, 1.01, 1.02)
+                //vector::one
+            )
+        )
+    );
+}
+
+
 // ************************************************************************* //
diff --git a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.H b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.H
index f07598ec8b5fc3b2d3f2b1a7dabb2152770a4df2..b4fa5766d9a1179220fdc623bdd3574a8467a93a 100644
--- a/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.H
+++ b/src/finiteVolume/fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -65,6 +65,15 @@ public:
             const lduMesh& mesh,
             const dictionary& controlDict
         );
+
+        //- Construct given mesh and controls
+        faceAreaPairGAMGAgglomeration
+        (
+            const lduMesh& mesh,
+            const scalarField& cellVolumes,
+            const vectorField& faceAreas,
+            const dictionary& controlDict
+        );
 };