diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index fa2b1a57af0c5be246ec8ab7036421d538915378..16f6157a227fc12ecd16473a271184d1cb49e2e5 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -775,7 +775,7 @@ Foam::argList::argList
                 << "    floatTransfer      : " << Pstream::floatTransfer << nl
                 << "    nProcsSimpleSum    : " << Pstream::nProcsSimpleSum << nl
                 << "    commsType          : "
-                << Pstream::commsTypeNames[Pstream::defaultCommsType]
+                << Pstream::commsTypeNames[Pstream::defaultCommsType] << nl
                 << "    polling iterations : " << Pstream::nPollProcInterfaces
                 << endl;
         }
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
index 6da295382602eb93972cba22791f5b69e56d3fcc..b8180a2b3ec086d043fc52e4c1d590f5bbd0ef87 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduAddressing/lduInterfaceFields/lduInterfaceField/lduInterfaceField.H
@@ -60,6 +60,11 @@ class lduInterfaceField
         //- Reference to the coupled patch this field is defined for
         const lduInterface& interface_;
 
+        //- Update index used so that updateInterfaceMatrix is called only once
+        //  during the construction of the matrix
+        bool updatedMatrix_;
+
+
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
@@ -68,12 +73,6 @@ class lduInterfaceField
         //- Disallow default bitwise assignment
         void operator=(const lduInterfaceField&);
 
-protected:
-
-        //- Update index used so that updateInterfaceMatrix is called only once
-        //  during the construction of the matrix
-        bool updatedMatrix_;
-
 public:
 
     //- Runtime type information
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C
index 45654d9731abed335b0b8bd7eb3da6bfda55b963..07260b4a91009fdbdc7265ab6ad6765f75183c40 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixOperations.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -205,7 +205,15 @@ void Foam::lduMatrix::operator+=(const lduMatrix& A)
         if (debug > 1)
         {
             WarningIn("lduMatrix::operator+=(const lduMatrix& A)")
-                << "Unknown matrix type combination"
+                << "Unknown matrix type combination" << nl
+                << "    this :"
+                << " diagonal:" << diagonal()
+                << " symmetric:" << symmetric()
+                << " asymmetric:" << asymmetric() << nl
+                << "    A    :"
+                << " diagonal:" << A.diagonal()
+                << " symmetric:" << A.symmetric()
+                << " asymmetric:" << A.asymmetric()
                 << endl;
         }
     }
@@ -276,7 +284,15 @@ void Foam::lduMatrix::operator-=(const lduMatrix& A)
         if (debug > 1)
         {
             WarningIn("lduMatrix::operator-=(const lduMatrix& A)")
-                << "Unknown matrix type combination"
+                << "Unknown matrix type combination" << nl
+                << "    this :"
+                << " diagonal:" << diagonal()
+                << " symmetric:" << symmetric()
+                << " asymmetric:" << asymmetric() << nl
+                << "    A    :"
+                << " diagonal:" << A.diagonal()
+                << " symmetric:" << A.symmetric()
+                << " asymmetric:" << A.asymmetric()
                 << endl;
         }
     }
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
index c401c3e47764068938556e15bc3762e6cfa900e0..62d00b7626c7c04929f6f69bc18e6562e92dea0f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixUpdateMatrixInterfaces.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -87,7 +87,7 @@ void Foam::lduMatrix::initMatrixInterfaces
     }
     else
     {
-        FatalErrorIn("lduMatrix::initMatrixInterfaces")
+        FatalErrorIn("lduMatrix::initMatrixInterfaces(..)")
             << "Unsuported communications type "
             << Pstream::commsTypeNames[Pstream::defaultCommsType]
             << exit(FatalError);
@@ -104,25 +104,92 @@ void Foam::lduMatrix::updateMatrixInterfaces
     const direction cmpt
 ) const
 {
-    if
-    (
-        Pstream::defaultCommsType == Pstream::blocking
-     || Pstream::defaultCommsType == Pstream::nonBlocking
-    )
+    if (Pstream::defaultCommsType == Pstream::blocking)
     {
-        // Block until all sends/receives have been finished
-        if
-        (
-            Pstream::parRun()
-         && Pstream::defaultCommsType == Pstream::nonBlocking
-        )
+        forAll(interfaces, interfaceI)
         {
-            UPstream::waitRequests();
+            if (interfaces.set(interfaceI))
+            {
+                interfaces[interfaceI].updateInterfaceMatrix
+                (
+                    psiif,
+                    result,
+                    *this,
+                    coupleCoeffs[interfaceI],
+                    cmpt,
+                    Pstream::defaultCommsType
+                );
+            }
+        }
+    }
+    else if (Pstream::defaultCommsType == Pstream::nonBlocking)
+    {
+        // Try and consume interfaces as they become available
+        bool allUpdated = false;
+
+        for (label i = 0; i < UPstream::nPollProcInterfaces; i++)
+        {
+            allUpdated = true;
+
+            forAll(interfaces, interfaceI)
+            {
+                if (interfaces.set(interfaceI))
+                {
+                    if (!interfaces[interfaceI].updatedMatrix())
+                    {
+                        if (interfaces[interfaceI].ready())
+                        {
+                            interfaces[interfaceI].updateInterfaceMatrix
+                            (
+                                psiif,
+                                result,
+                                *this,
+                                coupleCoeffs[interfaceI],
+                                cmpt,
+                                Pstream::defaultCommsType
+                            );
+                        }
+                        else
+                        {
+                            allUpdated = false;
+                        }
+                    }
+                }
+            }
+
+            if (allUpdated)
+            {
+                break;
+            }
+        }
+
+        // Block for everything
+        if (Pstream::parRun())
+        {
+            if (allUpdated)
+            {
+                // All received. Just remove all storage of requests
+                // Note that we don't know what starting number of requests
+                // was before start of sends and receives (since set from
+                // initMatrixInterfaces) so set to 0 and loose any in-flight
+                // requests.
+                UPstream::resetRequests(0);
+            }
+            else
+            {
+                // Block for all requests and remove storage
+                UPstream::waitRequests();
+            }
         }
 
+        // Consume
         forAll(interfaces, interfaceI)
         {
-            if (interfaces.set(interfaceI))
+            if
+            (
+                interfaces.set(interfaceI)
+            && !interfaces[interfaceI].updatedMatrix()
+            )
             {
                 interfaces[interfaceI].updateInterfaceMatrix
                 (
@@ -199,7 +266,7 @@ void Foam::lduMatrix::updateMatrixInterfaces
     }
     else
     {
-        FatalErrorIn("lduMatrix::updateMatrixInterfaces")
+        FatalErrorIn("lduMatrix::updateMatrixInterfaces(..)")
             << "Unsuported communications type "
             << Pstream::commsTypeNames[Pstream::defaultCommsType]
             << exit(FatalError);
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C
index 3b6d1ee026590ef420f99f54137dfe5ff47a4b0f..b8fa744ff6b0673f1174fee7fc22bb43ca95eccd 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -80,11 +80,38 @@ void Foam::processorGAMGInterfaceField::initInterfaceMatrixUpdate
     const Pstream::commsTypes commsType
 ) const
 {
-    procInterface_.compressedSend
-    (
-        commsType,
-        procInterface_.interfaceInternalField(psiInternal)()
-    );
+    procInterface_.interfaceInternalField(psiInternal, scalarSendBuf_);
+
+    if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
+    {
+        // Fast path.
+        scalarReceiveBuf_.setSize(scalarSendBuf_.size());
+        outstandingRecvRequest_ = UPstream::nRequests();
+        IPstream::read
+        (
+            Pstream::nonBlocking,
+            procInterface_.neighbProcNo(),
+            reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
+            scalarReceiveBuf_.byteSize(),
+            procInterface_.tag()
+        );
+
+        outstandingSendRequest_ = UPstream::nRequests();
+        OPstream::write
+        (
+            Pstream::nonBlocking,
+            procInterface_.neighbProcNo(),
+            reinterpret_cast<const char*>(scalarSendBuf_.begin()),
+            scalarSendBuf_.byteSize(),
+            procInterface_.tag()
+        );
+    }
+    else
+    {
+        procInterface_.compressedSend(commsType, scalarSendBuf_);
+    }
+
+    const_cast<processorGAMGInterfaceField&>(*this).updatedMatrix() = false;
 }
 
 
@@ -98,18 +125,54 @@ void Foam::processorGAMGInterfaceField::updateInterfaceMatrix
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf
-    (
-        procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
-    );
-    transformCoupleField(pnf, cmpt);
+    if (updatedMatrix())
+    {
+        return;
+    }
 
     const labelUList& faceCells = procInterface_.faceCells();
 
-    forAll(faceCells, elemI)
+    if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
     {
-        result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+        // Fast path.
+        if
+        (
+            outstandingRecvRequest_ >= 0
+         && outstandingRecvRequest_ < Pstream::nRequests()
+        )
+        {
+            UPstream::waitRequest(outstandingRecvRequest_);
+        }
+        // Recv finished so assume sending finished as well.
+        outstandingSendRequest_ = -1;
+        outstandingRecvRequest_ = -1;
+
+        // Consume straight from scalarReceiveBuf_
+
+        // Transform according to the transformation tensor
+        transformCoupleField(scalarReceiveBuf_, cmpt);
+
+        // Multiply the field by coefficients and add into the result
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI];
+        }
     }
+    else
+    {
+        scalarField pnf
+        (
+            procInterface_.compressedReceive<scalar>(commsType, coeffs.size())
+        );
+        transformCoupleField(pnf, cmpt);
+
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+        }
+    }
+
+    const_cast<processorGAMGInterfaceField&>(*this).updatedMatrix() = true;
 }
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H
index c1bdac02460856c176ab80f4efc3f1ea893c986d..48d64baacf369908a2bec65f6cc88fabe2b669aa 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaceFields/processorGAMGInterfaceField/processorGAMGInterfaceField.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -65,6 +65,22 @@ class processorGAMGInterfaceField
         int rank_;
 
 
+        // Sending and receiving
+
+            //- Outstanding request
+            mutable label outstandingSendRequest_;
+
+            //- Outstanding request
+            mutable label outstandingRecvRequest_;
+
+            //- Scalar send buffer
+            mutable Field<scalar> scalarSendBuf_;
+
+            //- Scalar receive buffer
+            mutable Field<scalar> scalarReceiveBuf_;
+
+
+
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H
index 8f25335415cb61771af91da86573ac6459408a97..ed6c7ca7468009f6849e67e6e5ce173378287585 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterface.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -188,6 +188,14 @@ public:
                 const UList<Type>& internalData
             ) const;
 
+            //- Get the interface internal field of the given field
+            template<class Type>
+            void interfaceInternalField
+            (
+                const UList<Type>& internalData,
+                List<Type>&
+            ) const;
+
             //- Return the values of the given internal data adjacent to
             //  the interface as a field
             virtual tmp<labelField> interfaceInternalField
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C
index 0d42d04cef72ae192b4cddada9dbe19963ecf73e..4890618ab12781c44a18b40239c013386b89dbaf 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/interfaces/GAMGInterface/GAMGInterfaceTemplates.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -34,14 +34,24 @@ Foam::tmp<Foam::Field<Type> > Foam::GAMGInterface::interfaceInternalField
 ) const
 {
     tmp<Field<Type> > tresult(new Field<Type>(size()));
-    Field<Type>& result = tresult();
+    interfaceInternalField(iF, tresult());
+    return tresult;
+}
+
+
+template<class Type>
+void Foam::GAMGInterface::interfaceInternalField
+(
+    const UList<Type>& iF,
+    List<Type>& result
+) const
+{
+    result.setSize(size());
 
     forAll(result, elemI)
     {
         result[elemI] = iF[faceCells_[elemI]];
     }
-
-    return tresult;
 }
 
 
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
index 70bba49de93522744d94af640b129325b7a381aa..a44ea4cc5c9c4f789006e4134a673d201cb53077 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C
@@ -43,7 +43,12 @@ processorFvPatchField<Type>::processorFvPatchField
 )
 :
     coupledFvPatchField<Type>(p, iF),
-    procPatch_(refCast<const processorFvPatch>(p))
+    procPatch_(refCast<const processorFvPatch>(p)),
+    sendBuf_(0),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(0),
+    scalarReceiveBuf_(0)
 {}
 
 
@@ -56,7 +61,12 @@ processorFvPatchField<Type>::processorFvPatchField
 )
 :
     coupledFvPatchField<Type>(p, iF, f),
-    procPatch_(refCast<const processorFvPatch>(p))
+    procPatch_(refCast<const processorFvPatch>(p)),
+    sendBuf_(0),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(0),
+    scalarReceiveBuf_(0)
 {}
 
 
@@ -71,7 +81,12 @@ processorFvPatchField<Type>::processorFvPatchField
 )
 :
     coupledFvPatchField<Type>(ptf, p, iF, mapper),
-    procPatch_(refCast<const processorFvPatch>(p))
+    procPatch_(refCast<const processorFvPatch>(p)),
+    sendBuf_(0),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(0),
+    scalarReceiveBuf_(0)
 {
     if (!isA<processorFvPatch>(this->patch()))
     {
@@ -91,6 +106,12 @@ processorFvPatchField<Type>::processorFvPatchField
             << " in file " << this->dimensionedInternalField().objectPath()
             << exit(FatalIOError);
     }
+    if (debug && !ptf.ready())
+    {
+        FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)")
+            << "On patch " << procPatch_.name() << " outstanding request."
+            << abort(FatalError);
+    }
 }
 
 
@@ -103,7 +124,12 @@ processorFvPatchField<Type>::processorFvPatchField
 )
 :
     coupledFvPatchField<Type>(p, iF, dict),
-    procPatch_(refCast<const processorFvPatch>(p))
+    procPatch_(refCast<const processorFvPatch>(p)),
+    sendBuf_(0),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(0),
+    scalarReceiveBuf_(0)
 {
     if (!isA<processorFvPatch>(p))
     {
@@ -134,8 +160,20 @@ processorFvPatchField<Type>::processorFvPatchField
 :
     processorLduInterfaceField(),
     coupledFvPatchField<Type>(ptf),
-    procPatch_(refCast<const processorFvPatch>(ptf.patch()))
-{}
+    procPatch_(refCast<const processorFvPatch>(ptf.patch())),
+    sendBuf_(ptf.sendBuf_.xfer()),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(ptf.scalarSendBuf_.xfer()),
+    scalarReceiveBuf_(ptf.scalarReceiveBuf_.xfer())
+{
+    if (debug && !ptf.ready())
+    {
+        FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)")
+            << "On patch " << procPatch_.name() << " outstanding request."
+            << abort(FatalError);
+    }
+}
 
 
 template<class Type>
@@ -146,8 +184,20 @@ processorFvPatchField<Type>::processorFvPatchField
 )
 :
     coupledFvPatchField<Type>(ptf, iF),
-    procPatch_(refCast<const processorFvPatch>(ptf.patch()))
-{}
+    procPatch_(refCast<const processorFvPatch>(ptf.patch())),
+    sendBuf_(0),
+    outstandingSendRequest_(-1),
+    outstandingRecvRequest_(-1),
+    scalarSendBuf_(0),
+    scalarReceiveBuf_(0)
+{
+    if (debug && !ptf.ready())
+    {
+        FatalErrorIn("processorFvPatchField<Type>::processorFvPatchField(..)")
+            << "On patch " << procPatch_.name() << " outstanding request."
+            << abort(FatalError);
+    }
+}
 
 
 // * * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * //
@@ -162,6 +212,13 @@ processorFvPatchField<Type>::~processorFvPatchField()
 template<class Type>
 tmp<Field<Type> > processorFvPatchField<Type>::patchNeighbourField() const
 {
+    if (debug && !this->ready())
+    {
+        FatalErrorIn("processorFvPatchField<Type>::patchNeighbourField()")
+            << "On patch " << procPatch_.name()
+            << " outstanding request."
+            << abort(FatalError);
+    }
     return *this;
 }
 
@@ -174,7 +231,36 @@ void processorFvPatchField<Type>::initEvaluate
 {
     if (Pstream::parRun())
     {
-        procPatch_.compressedSend(commsType, this->patchInternalField()());
+        this->patchInternalField(sendBuf_);
+
+        if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
+        {
+            // Fast path. Receive into *this
+            this->setSize(sendBuf_.size());
+            outstandingRecvRequest_ = UPstream::nRequests();
+            IPstream::read
+            (
+                Pstream::nonBlocking,
+                procPatch_.neighbProcNo(),
+                reinterpret_cast<char*>(this->begin()),
+                this->byteSize(),
+                procPatch_.tag()
+            );
+
+            outstandingSendRequest_ = UPstream::nRequests();
+            OPstream::write
+            (
+                Pstream::nonBlocking,
+                procPatch_.neighbProcNo(),
+                reinterpret_cast<const char*>(sendBuf_.begin()),
+                this->byteSize(),
+                procPatch_.tag()
+            );
+        }
+        else
+        {
+            procPatch_.compressedSend(commsType, sendBuf_);
+        }
     }
 }
 
@@ -187,7 +273,25 @@ void processorFvPatchField<Type>::evaluate
 {
     if (Pstream::parRun())
     {
-        procPatch_.compressedReceive<Type>(commsType, *this);
+        if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
+        {
+            // Fast path. Received into *this
+
+            if
+            (
+                outstandingRecvRequest_ >= 0
+             && outstandingRecvRequest_ < Pstream::nRequests()
+            )
+            {
+                UPstream::waitRequest(outstandingRecvRequest_);
+            }
+            outstandingSendRequest_ = -1;
+            outstandingRecvRequest_ = -1;
+        }
+        else
+        {
+            procPatch_.compressedReceive<Type>(commsType, *this);
+        }
 
         if (doTransform())
         {
@@ -215,18 +319,49 @@ void processorFvPatchField<Type>::initInterfaceMatrixUpdate
     const Pstream::commsTypes commsType
 ) const
 {
-    procPatch_.compressedSend
-    (
-        commsType,
-        this->patch().patchInternalField(psiInternal)()
-    );
-}
+    this->patch().patchInternalField(psiInternal, scalarSendBuf_);
 
+    if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
+    {
+        // Fast path.
+        if (debug && !this->ready())
+        {
+            FatalErrorIn
+            (
+                "processorFvPatchField<Type>::initInterfaceMatrixUpdate(..)"
+            )   << "On patch " << procPatch_.name()
+                << " outstanding request."
+                << abort(FatalError);
+        }
 
-template<class Type>
-bool processorFvPatchField<Type>::ready() const
-{
-    return true;
+
+        scalarReceiveBuf_.setSize(scalarSendBuf_.size());
+        outstandingRecvRequest_ = UPstream::nRequests();
+        IPstream::read
+        (
+            Pstream::nonBlocking,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
+            scalarReceiveBuf_.byteSize(),
+            procPatch_.tag()
+        );
+
+        outstandingSendRequest_ = UPstream::nRequests();
+        OPstream::write
+        (
+            Pstream::nonBlocking,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<const char*>(scalarSendBuf_.begin()),
+            scalarSendBuf_.byteSize(),
+            procPatch_.tag()
+        );
+    }
+    else
+    {
+        procPatch_.compressedSend(commsType, scalarSendBuf_);
+    }
+
+    const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
 }
 
 
@@ -241,22 +376,92 @@ void processorFvPatchField<Type>::updateInterfaceMatrix
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf
-    (
-        procPatch_.compressedReceive<scalar>(commsType, this->size())()
-    );
+    if (this->updatedMatrix())
+    {
+        return;
+    }
+
+    const labelUList& faceCells = this->patch().faceCells();
 
-    // Transform according to the transformation tensor
-    transformCoupleField(pnf, cmpt);
+    if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
+    {
+        // Fast path.
+        if
+        (
+            outstandingRecvRequest_ >= 0
+         && outstandingRecvRequest_ < Pstream::nRequests()
+        )
+        {
+            UPstream::waitRequest(outstandingRecvRequest_);
+        }
+        // Recv finished so assume sending finished as well.
+        outstandingSendRequest_ = -1;
+        outstandingRecvRequest_ = -1;
 
-    // Multiply the field by coefficients and add into the result
+        // Consume straight from scalarReceiveBuf_
+
+        // Transform according to the transformation tensor
+        transformCoupleField(scalarReceiveBuf_, cmpt);
+
+        // Multiply the field by coefficients and add into the result
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI];
+        }
+    }
+    else
+    {
+        scalarField pnf
+        (
+            procPatch_.compressedReceive<scalar>(commsType, this->size())()
+        );
+
+        // Transform according to the transformation tensor
+        transformCoupleField(pnf, cmpt);
+
+        // Multiply the field by coefficients and add into the result
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+        }
+    }
+
+    const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
+}
 
-    const labelUList& faceCells = this->patch().faceCells();
 
-    forAll(faceCells, elemI)
+template<class Type>
+bool processorFvPatchField<Type>::ready() const
+{
+    if
+    (
+        outstandingSendRequest_ >= 0
+     && outstandingSendRequest_ < Pstream::nRequests()
+    )
     {
-        result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+        bool finished = UPstream::finishedRequest(outstandingSendRequest_);
+        if (!finished)
+        {
+            return false;
+        }
     }
+    outstandingSendRequest_ = -1;
+
+    if
+    (
+        outstandingRecvRequest_ >= 0
+     && outstandingRecvRequest_ < Pstream::nRequests()
+    )
+    {
+        bool finished = UPstream::finishedRequest(outstandingRecvRequest_);
+        if (!finished)
+        {
+            return false;
+        }
+    }
+    outstandingRecvRequest_ = -1;
+
+    return true;
 }
 
 
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
index 1ed07e42384ea45a6efb66fa7f6f251c412c1840..9541e80ea56a3f040837f5092cddee9e90320412 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H
@@ -59,6 +59,22 @@ class processorFvPatchField
         //- Local reference cast into the processor patch
         const processorFvPatch& procPatch_;
 
+        // Sending and receiving
+
+            //- Send buffer.
+            mutable Field<Type> sendBuf_;
+
+            //- Outstanding request
+            mutable label outstandingSendRequest_;
+
+            //- Outstanding request
+            mutable label outstandingRecvRequest_;
+
+            //- Scalar send buffer
+            mutable Field<scalar> scalarSendBuf_;
+
+            //- Scalar receive buffer
+            mutable Field<scalar> scalarReceiveBuf_;
 
 public:
 
diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C
index b94e8049f9872ed4011cb56ebdcc6d9168491366..c15b1c1be7f8950c9354099b2913704bb2c41840 100644
--- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.C
+++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchScalarField.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) 2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -43,11 +43,53 @@ void processorFvPatchField<scalar>::initInterfaceMatrixUpdate
     const Pstream::commsTypes commsType
 ) const
 {
-    procPatch_.compressedSend
+    this->patch().patchInternalField(psiInternal, scalarSendBuf_);
+
+    if
     (
-        commsType,
-        patch().patchInternalField(psiInternal)()
-    );
+        Pstream::defaultCommsType == Pstream::nonBlocking
+    && !Pstream::floatTransfer
+    )
+    {
+        // Fast path.
+        if (debug && !this->ready())
+        {
+            FatalErrorIn
+            (
+                "processorFvPatchField<scalar>::initInterfaceMatrixUpdate(..)"
+            )   << "On patch " << procPatch_.name()
+                << " outstanding request."
+                << abort(FatalError);
+        }
+
+
+        scalarReceiveBuf_.setSize(scalarSendBuf_.size());
+        outstandingRecvRequest_ = UPstream::nRequests();
+        IPstream::read
+        (
+            Pstream::nonBlocking,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
+            scalarReceiveBuf_.byteSize(),
+            procPatch_.tag()
+        );
+
+        outstandingSendRequest_ = UPstream::nRequests();
+        OPstream::write
+        (
+            Pstream::nonBlocking,
+            procPatch_.neighbProcNo(),
+            reinterpret_cast<const char*>(scalarSendBuf_.begin()),
+            scalarSendBuf_.byteSize(),
+            procPatch_.tag()
+        );
+    }
+    else
+    {
+        procPatch_.compressedSend(commsType, scalarSendBuf_);
+    }
+
+    const_cast<processorFvPatchField<scalar>&>(*this).updatedMatrix() = false;
 }
 
 
@@ -62,17 +104,48 @@ void processorFvPatchField<scalar>::updateInterfaceMatrix
     const Pstream::commsTypes commsType
 ) const
 {
-    scalarField pnf
-    (
-        procPatch_.compressedReceive<scalar>(commsType, this->size())()
-    );
+    if (this->updatedMatrix())
+    {
+        return;
+    }
 
-    const labelUList& faceCells = patch().faceCells();
+    const labelUList& faceCells = this->patch().faceCells();
 
-    forAll(faceCells, facei)
+    if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
     {
-        result[faceCells[facei]] -= coeffs[facei]*pnf[facei];
+        // Fast path.
+        if
+        (
+            outstandingRecvRequest_ >= 0
+         && outstandingRecvRequest_ < Pstream::nRequests()
+        )
+        {
+            UPstream::waitRequest(outstandingRecvRequest_);
+        }
+        outstandingSendRequest_ = -1;
+        outstandingRecvRequest_ = -1;
+
+
+        // Consume straight from scalarReceiveBuf_
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI];
+        }
     }
+    else
+    {
+        scalarField pnf
+        (
+            procPatch_.compressedReceive<scalar>(commsType, this->size())()
+        );
+
+        forAll(faceCells, elemI)
+        {
+            result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
+        }
+    }
+
+    const_cast<processorFvPatchField<scalar>&>(*this).updatedMatrix() = true;
 }