diff --git a/src/OpenFOAM/db/Time/Time.C b/src/OpenFOAM/db/Time/Time.C
index dd0c02ddbc90fa3523d83e916aa8dfb783ffb148..8e18dc786115461aa752148dfd340ca64ed90ddc 100644
--- a/src/OpenFOAM/db/Time/Time.C
+++ b/src/OpenFOAM/db/Time/Time.C
@@ -519,6 +519,10 @@ bool Foam::Time::loop()
     if (running)
     {
         operator++();
+
+        // Check update the "running" status following the "++" operation
+        // to take into account possible side-effects from functionObjects
+        running = run();
     }
 
     return running;
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
index b96925a91bb69e439439a487ebc5b2f83074713e..860a593b83333aa083c759f6da3a7e0a183bede1 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
@@ -210,6 +210,16 @@ public:
             void print() const;
 
 
+        // Friend functions
+
+            //- Return the element-wise maximum of two solverPerformances
+            friend solverPerformance max
+            (
+                const solverPerformance&,
+                const solverPerformance&
+            );
+
+
         // Ostream Operator
 
             friend Ostream& operator<<(Ostream&, const solverPerformance&);
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTests.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTests.C
index c1fafc95ec9d123333aed55bd6e745fff254fcf5..c4c8774098e3836a770b489f98662f969b804a4f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTests.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixTests.C
@@ -118,6 +118,25 @@ void Foam::lduMatrix::solverPerformance::print() const
 }
 
 
+Foam::lduMatrix::solverPerformance::solverPerformance Foam::max
+(
+    const lduMatrix::solverPerformance& sp1,
+    const lduMatrix::solverPerformance& sp2
+)
+{
+    return lduMatrix::solverPerformance
+    (
+        sp1.solverName(),
+        sp1.fieldName_,
+        max(sp1.initialResidual(), sp2.initialResidual()),
+        max(sp1.finalResidual(), sp2.finalResidual()),
+        max(sp1.nIterations(), sp2.nIterations()),
+        sp1.converged() && sp2.converged(),
+        sp1.singular() || sp2.singular()
+    );
+}
+
+
 Foam::Ostream& Foam::operator<<
 (
     Ostream& os,
@@ -137,4 +156,5 @@ Foam::Ostream& Foam::operator<<
     return os;
 }
 
+
 // ************************************************************************* //
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
index aa3fe8dd3f98795a66e88d72e3a9088ec0eae27f..e1984ef87892f5a5f837c79207206303148efba8 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
@@ -149,14 +149,7 @@ Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
 
         solverPerf.print();
 
-        if
-        (
-            solverPerf.initialResidual() > solverPerfVec.initialResidual()
-         && !solverPerf.singular()
-        )
-        {
-            solverPerfVec = solverPerf;
-        }
+        solverPerfVec = max(solverPerfVec, solverPerf);
 
         psi.internalField().replace(cmpt, psiCmpt);
         diag() = saveDiag;
diff --git a/src/postProcessing/functionObjects/Allwmake b/src/postProcessing/functionObjects/Allwmake
index 6c642dfe7b6333d4e71ab8c22f4458da73294503..980a308557a4498f50ff19b7721f07f2a7787ab9 100755
--- a/src/postProcessing/functionObjects/Allwmake
+++ b/src/postProcessing/functionObjects/Allwmake
@@ -6,6 +6,7 @@ wmake libso field
 wmake libso forces
 wmake libso IO
 wmake libso utilities
+wmake libso residualControl
 wmake libso systemCall
 
 # ----------------------------------------------------------------- end-of-file
diff --git a/src/postProcessing/functionObjects/residualControl/IOresidualControl.H b/src/postProcessing/functionObjects/residualControl/IOresidualControl.H
new file mode 100644
index 0000000000000000000000000000000000000000..8a2b3bfed1396a2479cec1eae61113ba61fc14fb
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/IOresidualControl.H
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     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/>.
+
+Typedef
+    Foam::IOresidualControl
+
+Description
+    Instance of the generic IOOutputFilter for residualControl.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IOresidualControl_H
+#define IOresidualControl_H
+
+#include "residualControl.H"
+#include "IOOutputFilter.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef IOOutputFilter<residualControl> IOresidualControl;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/residualControl/Make/files b/src/postProcessing/functionObjects/residualControl/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..c3bc44fe41247be7af01c274dd93ee76656c2db3
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/Make/files
@@ -0,0 +1,4 @@
+residualControl.C
+residualControlFunctionObject.C
+
+LIB = $(FOAM_LIBBIN)/libresidualControl
diff --git a/src/postProcessing/functionObjects/residualControl/Make/options b/src/postProcessing/functionObjects/residualControl/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..5166bcc9e32f547f48a5f87c9c60d7210409967f
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/Make/options
@@ -0,0 +1,9 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/sampling/lnInclude
+
+LIB_LIBS = \
+    -lfiniteVolume \
+    -lmeshTools \
+    -lsampling
diff --git a/src/postProcessing/functionObjects/residualControl/controlDict b/src/postProcessing/functionObjects/residualControl/controlDict
new file mode 100644
index 0000000000000000000000000000000000000000..0af8ff7c9a3151c36e963a8d800f17d9f94b8ff7
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/controlDict
@@ -0,0 +1,67 @@
+*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  1.6                                   |
+|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    location    "system";
+    object      controlDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+application     icoFoam;
+
+startFrom       startTime;
+
+startTime       0;
+
+stopAt          endTime;
+
+endTime         0.5;
+
+deltaT          0.005;
+
+writeControl    timeStep;
+
+writeInterval   20;
+
+purgeWrite      0;
+
+writeFormat     ascii;
+
+writePrecision  6;
+
+writeCompression uncompressed;
+
+timeFormat      general;
+
+timePrecision   6;
+
+runTimeModifiable yes;
+
+
+functions
+(
+    convergenceChecks
+    {
+        type           residualControl;
+        functionObjectLibs ( "libresidualControl.so" );
+        outputControl  timeStep;
+        outputInterval 1;
+
+        maxResiduals
+        (
+            (p          5e-4)
+            (U          1e-3)
+        );
+    }
+);
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/residualControl/residualControl.C b/src/postProcessing/functionObjects/residualControl/residualControl.C
new file mode 100644
index 0000000000000000000000000000000000000000..aed8e38dc1eab32608bf6a7f7cd67a8a8c6c6369
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/residualControl.C
@@ -0,0 +1,174 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     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 "residualControl.H"
+#include "dictionary.H"
+#include "fvMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(residualControl, 0);
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+bool Foam::residualControl::checkCriteria(const bool output) const
+{
+    bool achieved = true;
+    const fvMesh& mesh = static_cast<const fvMesh&>(obr_);
+    const dictionary& solverDict = mesh.solverPerformanceDict();
+    forAll(maxResiduals_, i)
+    {
+        const word& variableName = maxResiduals_[i].first();
+        if (solverDict.found(variableName))
+        {
+            const scalar maxResidual = maxResiduals_[i].second();
+
+            const lduMatrix::solverPerformance
+                sp(solverDict.lookup(variableName));
+
+            const scalar eqnResidual = sp.initialResidual();
+
+            achieved = achieved && (eqnResidual < maxResidual);
+
+            if (output)
+            {
+                Info<< "    " << variableName
+                    << ": requested max residual = " << maxResidual
+                    << ", eqn residual = " << eqnResidual << nl;
+            }
+        }
+    }
+
+    return achieved;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::residualControl::residualControl
+(
+    const word& name,
+    const objectRegistry& obr,
+    const dictionary& dict,
+    const bool
+)
+:
+    name_(name),
+    obr_(obr),
+    active_(true),
+    maxResiduals_(),
+    criteriaSatisfied_(false)
+{
+    // Only active if a fvMesh is available
+    if (isA<fvMesh>(obr_))
+    {
+        read(dict);
+    }
+    else
+    {
+        active_ = false;
+        WarningIn
+        (
+            "residualControl::residualControl"
+            "("
+                "const word&, "
+                "const objectRegistry&, "
+                "const dictionary&, "
+                "const bool"
+            ")"
+        )   << "No fvMesh available, deactivating."
+            << nl << endl;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::residualControl::~residualControl()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::residualControl::read(const dictionary& dict)
+{
+    if (active_)
+    {
+        dict.lookup("maxResiduals") >> maxResiduals_;
+    }
+}
+
+
+void Foam::residualControl::execute()
+{
+    if (active_)
+    {
+        criteriaSatisfied_ = checkCriteria(false);
+
+        if (criteriaSatisfied_)
+        {
+            Info<< "Convergence criteria satisfied - finalising run" << nl
+                << endl;
+
+            checkCriteria(true);
+
+            Info<< endl;
+
+            const fvMesh& mesh = static_cast<const fvMesh&>(obr_);
+            Time& time = const_cast<Time&>(mesh.time());
+            time.writeAndEnd();
+        }
+    }
+}
+
+
+void Foam::residualControl::end()
+{
+    if (active_)
+    {
+        if (criteriaSatisfied_)
+        {
+            Info<< "Residual control criteria satisfied" << nl;
+        }
+        else
+        {
+            Info<< "Residual control criteria not satisfied" << nl;
+        }
+    }
+}
+
+
+void Foam::residualControl::write()
+{
+    // do nothing
+}
+
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/residualControl/residualControl.H b/src/postProcessing/functionObjects/residualControl/residualControl.H
new file mode 100644
index 0000000000000000000000000000000000000000..c222019298da39645340b65c440a54f3a94e7249
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/residualControl.H
@@ -0,0 +1,152 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     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::residualControl
+
+Description
+    Function object that allows users to set target convergence criteria, and
+    stop the run if the conditions are satisfied.
+
+SourceFiles
+    residualControl.C
+    IOresidualControl.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef residualControl_H
+#define residualControl_H
+
+#include "pointFieldFwd.H"
+#include "Tuple2.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class objectRegistry;
+class dictionary;
+class mapPolyMesh;
+
+/*---------------------------------------------------------------------------*\
+                       Class residualControl Declaration
+\*---------------------------------------------------------------------------*/
+
+class residualControl
+{
+protected:
+
+    // Private data
+
+        //- Name of this object
+        word name_;
+
+        //- Reference to object registry
+        const objectRegistry& obr_;
+
+        //- On/off switch - on if obr_ is an fvMesh object
+        bool active_;
+
+        //- List of variable name vs max residual
+        List<Tuple2<word, scalar> > maxResiduals_;
+
+        //- Flag to indicate whether convergence criteria have been met
+        bool criteriaSatisfied_;
+
+
+    // Protected Member Functions
+
+        //- Perform residual control checks
+        bool checkCriteria(const bool output) const;
+
+        //- Disallow default bitwise copy construct
+        residualControl(const residualControl&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const residualControl&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("residualControl");
+
+
+    // Constructors
+
+        //- Construct for given objectRegistry and dictionary.
+        //  Allow the possibility to load fields from files
+        residualControl
+        (
+            const word& name,
+            const objectRegistry& obr,
+            const dictionary& dict,
+            const bool loadFromFilesUnused = false
+        );
+
+
+    //- Destructor
+    virtual ~residualControl();
+
+
+    // Member Functions
+
+        //- Return name of the system call set
+        virtual const word& name() const
+        {
+            return name_;
+        }
+
+        //- Read the system calls
+        virtual void read(const dictionary&);
+
+        //- Execute the "executeCalls" at each time-step
+        virtual void execute();
+
+        //- Execute the "endCalls" at the final time-loop
+        virtual void end();
+
+        //- Write, execute the "writeCalls"
+        virtual void write();
+
+        //- Update for changes of mesh
+        virtual void updateMesh(const mapPolyMesh&)
+        {}
+
+        //- Update for changes of mesh
+        virtual void movePoints(const pointField&)
+        {}
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.C b/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.C
new file mode 100644
index 0000000000000000000000000000000000000000..1813e2063ea5c42f7747c1c7f4802a6e7bc27c73
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.C
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     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 "residualControlFunctionObject.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineNamedTemplateTypeNameAndDebug(residualControlFunctionObject, 0);
+
+    addToRunTimeSelectionTable
+    (
+        functionObject,
+        residualControlFunctionObject,
+        dictionary
+    );
+}
+
+// ************************************************************************* //
diff --git a/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.H b/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.H
new file mode 100644
index 0000000000000000000000000000000000000000..19981b40f618657a94041fc189c07c2760a55180
--- /dev/null
+++ b/src/postProcessing/functionObjects/residualControl/residualControlFunctionObject.H
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
+     \\/     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/>.
+
+Typedef
+    Foam::residualControlFunctionObject
+
+Description
+    FunctionObject wrapper around residualControl to allow them to be created
+    via the functions entry within controlDict.
+
+SourceFiles
+    residualControlFunctionObject.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef residualControlFunctionObject_H
+#define residualControlFunctionObject_H
+
+#include "residualControl.H"
+#include "OutputFilterFunctionObject.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    typedef OutputFilterFunctionObject<residualControl>
+        residualControlFunctionObject;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //