diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
index 6b40b2ab5eba9c6509b7ab297b5d027b723c4631..e197b68888c9c3d4a25a2c54a4bc9d21b895084d 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
@@ -524,7 +524,25 @@ addLayersControls
 
 
 
-    // Medial axis analysis
+    // Choice of mesh shrinking algorithm
+
+        // Optional mesh shrinking algorithm (default is displacementMedialAxis)
+        // The displacementMotionSolver is a wrapper around the displacement
+        // motion solvers. It needs specification of the solver to use and
+        // its control dictionary.
+        //meshShrinker displacementMotionSolver;
+        //solver displacementLaplacian;
+        //displacementLaplacianCoeffs
+        //{
+        //    diffusivity quadratic inverseDistance
+        //    (
+        //        sphere.stl_firstSolid
+        //        maxY
+        //    );
+        //}
+
+
+    // Medial axis analysis (for use with default displacementMedialAxis)
 
         // Angle used to pick up medial axis points
         // Note: changed(corrected) w.r.t 17x! 90 degrees corresponds to 130
@@ -552,9 +570,6 @@ addLayersControls
         // Default is false.
         //detectExtrusionIsland true;
 
-
-    // Mesh shrinking
-
         // Optional: at non-patched sides allow mesh to slip if extrusion
         // direction makes angle larger than slipFeatureAngle. Default is
         // 0.5*featureAngle.
@@ -564,6 +579,9 @@ addLayersControls
         // before upon reaching a correct mesh.
         nRelaxIter 5;
 
+
+    // Mesh shrinking
+
         // Create buffer region for new layer terminations, i.e. gradually
         // step down number of layers. Set to <0 to terminate layer in one go.
         nBufferCellsNoExtrude 0;
diff --git a/src/Allwmake b/src/Allwmake
index 35819399ec897ab316136217dda3dea617c06954..5b2a4fdfbc7dbcae3115f8aef9b5e4a4bc1d199d 100755
--- a/src/Allwmake
+++ b/src/Allwmake
@@ -47,10 +47,10 @@ wmake $targetType lagrangian/distributionModels
 wmake $targetType genericPatchFields
 
 wmake $targetType conversion
-wmake $targetType sampling
 wmake $targetType mesh/extrudeModel
 wmake $targetType dynamicMesh
 wmake $targetType dynamicFvMesh
+wmake $targetType sampling
 wmake $targetType topoChangerFvMesh
 
 # Compile scotchDecomp, metisDecomp etc.
diff --git a/src/dynamicMesh/Make/files b/src/dynamicMesh/Make/files
index 96b80d6e3202f710261150d4dfb32352110018d0..ec2ec3418edf4a1bbe9a0c1036fd25fc6ce8b761 100644
--- a/src/dynamicMesh/Make/files
+++ b/src/dynamicMesh/Make/files
@@ -103,6 +103,7 @@ motionSolver/motionSolver/motionSolver.C
 motionSolver/displacement/displacementMotionSolver.C
 motionSolver/componentDisplacement/componentDisplacementMotionSolver.C
 motionSolver/velocity/velocityMotionSolver.C
+motionSolver/velocityDisplacement/velocityDisplacementMotionSolver.C
 motionSolver/componentVelocity/componentVelocityMotionSolver.C
 
 createShellMesh/createShellMesh.C
diff --git a/src/fvMotionSolver/Make/files b/src/fvMotionSolver/Make/files
index 13204042afb597b5c4005b49f21391fb00f1b8df..19475e258b45772839a59aa3e15702d19f8418cf 100644
--- a/src/fvMotionSolver/Make/files
+++ b/src/fvMotionSolver/Make/files
@@ -4,6 +4,7 @@ fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
 fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.C
 fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
 fvMotionSolvers/displacement/layeredSolver/pointEdgeStructuredWalk.C
+fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.C
 
 fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.C
 fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
@@ -22,6 +23,10 @@ motionDiffusivity/file/fileDiffusivity.C
 motionDiffusivity/manipulators/quadratic/quadraticDiffusivity.C
 motionDiffusivity/manipulators/exponential/exponentialDiffusivity.C
 
+motionInterpolation/motionInterpolation/motionInterpolation.C
+motionInterpolation/patchCorrected/patchCorrectedInterpolation.C
+motionInterpolation/patchTransformed/patchTransformedInterpolation.C
+
 fvPatchFields/derived/cellMotion/cellMotionFvPatchFields.C
 fvPatchFields/derived/surfaceSlipDisplacement/surfaceSlipDisplacementFvPatchFields.C
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.C
index 8f90cb8444538f561b40325c94cb858b67876470..e8d3d4eb935b30e311640cdb87f40a973bdfa2d3 100644
--- a/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,11 +24,11 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "displacementComponentLaplacianFvMotionSolver.H"
+#include "motionInterpolation.H"
 #include "motionDiffusivity.H"
 #include "fvmLaplacian.H"
 #include "addToRunTimeSelectionTable.H"
 #include "mapPolyMesh.H"
-#include "volPointInterpolation.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -76,6 +76,12 @@ displacementComponentLaplacianFvMotionSolver
         cellMotionBoundaryTypes<scalar>(pointDisplacement_.boundaryField())
     ),
     pointLocation_(NULL),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
     diffusivityPtr_
     (
         motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
@@ -140,7 +146,7 @@ Foam::displacementComponentLaplacianFvMotionSolver::
 Foam::tmp<Foam::pointField>
 Foam::displacementComponentLaplacianFvMotionSolver::curPoints() const
 {
-    volPointInterpolation::New(fvMesh_).interpolate
+    interpolationPtr_->interpolate
     (
         cellDisplacement_,
         pointDisplacement_
diff --git a/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
index 56a6f932ddee8fb733f4b7a939a06a3261f7dd1a..91575ae99d647a9973b9b55b2e3d73c391a973e2 100644
--- a/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/componentDisplacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,7 @@ namespace Foam
 {
 
 // Forward class declarations
+class motionInterpolation;
 class motionDiffusivity;
 
 /*---------------------------------------------------------------------------*\
@@ -65,6 +66,9 @@ class displacementComponentLaplacianFvMotionSolver
         //  boundary conditions.
         mutable autoPtr<pointVectorField> pointLocation_;
 
+        //- Interpolation used to transfer cell displacement to the points
+        autoPtr<motionInterpolation> interpolationPtr_;
+
         //- Diffusivity used to control the motion
         autoPtr<motionDiffusivity> diffusivityPtr_;
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.C
index 124a679e1543db698307c02efa6d29fad12b6012..aab69c3d8593960d4fe3c663a7bf0bc28186786c 100644
--- a/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,10 +24,10 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "velocityComponentLaplacianFvMotionSolver.H"
+#include "motionInterpolation.H"
 #include "motionDiffusivity.H"
 #include "fvmLaplacian.H"
 #include "addToRunTimeSelectionTable.H"
-#include "volPointInterpolation.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -74,6 +74,12 @@ velocityComponentLaplacianFvMotionSolver
         ),
         cellMotionBoundaryTypes<scalar>(pointMotionU_.boundaryField())
     ),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
     diffusivityPtr_
     (
         motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
@@ -93,7 +99,7 @@ Foam::velocityComponentLaplacianFvMotionSolver::
 Foam::tmp<Foam::pointField>
 Foam::velocityComponentLaplacianFvMotionSolver::curPoints() const
 {
-    volPointInterpolation::New(fvMesh_).interpolate
+    interpolationPtr_->interpolate
     (
         cellMotionU_,
         pointMotionU_
diff --git a/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
index 1f58ddf41467aa41b6a78be323adde2d50816e7e..aee616cb21a50fc143b81e563efad7c5d8b7df9d 100644
--- a/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,7 @@ namespace Foam
 {
 
 // Forward class declarations
+class motionInterpolation;
 class motionDiffusivity;
 
 /*---------------------------------------------------------------------------*\
@@ -61,6 +62,9 @@ class velocityComponentLaplacianFvMotionSolver
         //- Cell-centre motion field
         mutable volScalarField cellMotionU_;
 
+        //- Interpolation used to transfer cell displacement to the points
+        autoPtr<motionInterpolation> interpolationPtr_;
+
         //- Diffusivity used to control the motion
         autoPtr<motionDiffusivity> diffusivityPtr_;
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
index 7aafefc0c52dba4c5e0bfee22bf5c812dd2fca3b..508c5b3be1c9a65d94db532ea8b6d909b96b0847 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "displacementSBRStressFvMotionSolver.H"
+#include "motionInterpolation.H"
 #include "motionDiffusivity.H"
 #include "fvmLaplacian.H"
 #include "addToRunTimeSelectionTable.H"
@@ -32,7 +33,6 @@ License
 #include "surfaceInterpolate.H"
 #include "fvcLaplacian.H"
 #include "mapPolyMesh.H"
-#include "volPointInterpolation.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -46,6 +46,13 @@ namespace Foam
         displacementSBRStressFvMotionSolver,
         dictionary
     );
+
+    addToRunTimeSelectionTable
+    (
+        displacementMotionSolver,
+        displacementSBRStressFvMotionSolver,
+        displacement
+    );
 }
 
 
@@ -78,6 +85,58 @@ Foam::displacementSBRStressFvMotionSolver::displacementSBRStressFvMotionSolver
         ),
         cellMotionBoundaryTypes<vector>(pointDisplacement().boundaryField())
     ),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
+    diffusivityPtr_
+    (
+        motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
+    )
+{}
+
+
+Foam::displacementSBRStressFvMotionSolver::
+displacementSBRStressFvMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict,
+    const pointVectorField& pointDisplacement,
+    const pointIOField& points0
+)
+:
+    displacementMotionSolver(mesh, dict, pointDisplacement, points0, typeName),
+    fvMotionSolverCore(mesh),
+    cellDisplacement_
+    (
+        IOobject
+        (
+            "cellDisplacement",
+            mesh.time().timeName(),
+            mesh,
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        fvMesh_,
+        dimensionedVector
+        (
+            "cellDisplacement",
+            displacementMotionSolver::pointDisplacement().dimensions(),
+            vector::zero
+        ),
+        cellMotionBoundaryTypes<vector>
+        (
+            displacementMotionSolver::pointDisplacement().boundaryField()
+        )
+    ),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
     diffusivityPtr_
     (
         motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
@@ -97,7 +156,7 @@ Foam::displacementSBRStressFvMotionSolver::
 Foam::tmp<Foam::pointField>
 Foam::displacementSBRStressFvMotionSolver::curPoints() const
 {
-    volPointInterpolation::New(fvMesh_).interpolate
+    interpolationPtr_->interpolate
     (
         cellDisplacement_,
         pointDisplacement_
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
index 566a98686bbec5291c9f25b0c57711cf16459401..cb7de0c6d3e57a0a7837ffacf1763d1e440c7ffe 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,7 @@ namespace Foam
 {
 
 // Forward class declarations
+class motionInterpolation;
 class motionDiffusivity;
 
 /*---------------------------------------------------------------------------*\
@@ -61,6 +62,9 @@ class displacementSBRStressFvMotionSolver
         //- Cell-centre motion field
         mutable volVectorField cellDisplacement_;
 
+        //- Interpolation used to transfer cell displacement to the points
+        autoPtr<motionInterpolation> interpolationPtr_;
+
         //- Diffusivity used to control the motion
         autoPtr<motionDiffusivity> diffusivityPtr_;
 
@@ -92,6 +96,15 @@ public:
             const IOdictionary&
         );
 
+        //- Construct from components
+        displacementSBRStressFvMotionSolver
+        (
+            const polyMesh& mesh,
+            const IOdictionary& dict,
+            const pointVectorField& pointDisplacement,
+            const pointIOField& points0
+        );
+
 
     //- Destructor
     ~displacementSBRStressFvMotionSolver();
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.C
index 6029c8383f47c440aa6c35faa39b4b6e5bcfdbbd..349c5d406e0436cfc91af42b785f534c911a2911 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -44,6 +44,13 @@ namespace Foam
         dictionary
     );
 
+    addToRunTimeSelectionTable
+    (
+        displacementMotionSolver,
+        displacementInterpolationMotionSolver,
+        displacement
+    );
+
     template<>
     const word IOList<Tuple2<scalar, vector> >::typeName("scalarVectorTable");
 }
@@ -51,26 +58,20 @@ namespace Foam
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::displacementInterpolationMotionSolver::
-displacementInterpolationMotionSolver
+void Foam::displacementInterpolationMotionSolver::read
 (
-    const polyMesh& mesh,
-    const IOdictionary& dict
+    const dictionary& coeffDict
 )
-:
-    displacementMotionSolver(mesh, dict, typeName)
 {
     // Get zones and their interpolation tables for displacement
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     List<Pair<word> > faceZoneToTable
     (
-        coeffDict().lookup("interpolationTables")
+        coeffDict.lookup("interpolationTables")
     );
 
-    const faceZoneMesh& fZones = mesh.faceZones();
+    const faceZoneMesh& fZones = mesh().faceZones();
 
     times_.setSize(fZones.size());
     displacements_.setSize(fZones.size());
@@ -88,7 +89,7 @@ displacementInterpolationMotionSolver
                 "displacementInterpolationMotionSolver(const polyMesh&,"
                 "Istream&)"
             )   << "Cannot find zone " << zoneName << endl
-                << "Valid zones are " << mesh.faceZones().names()
+                << "Valid zones are " << mesh().faceZones().names()
                 << exit(FatalError);
         }
 
@@ -99,9 +100,9 @@ displacementInterpolationMotionSolver
             IOobject
             (
                 tableName,
-                mesh.time().constant(),
+                mesh().time().constant(),
                 "tables",
-                mesh,
+                mesh(),
                 IOobject::MUST_READ,
                 IOobject::NO_WRITE,
                 false
@@ -299,6 +300,36 @@ displacementInterpolationMotionSolver
 }
 
 
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::displacementInterpolationMotionSolver::
+displacementInterpolationMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict
+)
+:
+    displacementMotionSolver(mesh, dict, typeName)
+{
+    read(coeffDict());
+}
+
+
+Foam::displacementInterpolationMotionSolver::
+displacementInterpolationMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict,
+    const pointVectorField& pointDisplacement,
+    const pointIOField& points0
+)
+:
+    displacementMotionSolver(mesh, dict, pointDisplacement, points0, typeName)
+{
+    read(coeffDict());
+}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::displacementInterpolationMotionSolver::
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.H
index b5da0b5b3b5c629a6ad47d667f990e93e7a6b041..4748cc553dc44639674b92faf58e53a009416605 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -86,6 +86,9 @@ class displacementInterpolationMotionSolver
 
     // Private Member Functions
 
+        //- Read settings
+        void read(const dictionary& coeffDict);
+
         //- Disallow default bitwise copy construct
         displacementInterpolationMotionSolver
         (
@@ -111,6 +114,15 @@ public:
             const IOdictionary& dict
         );
 
+        //- Construct from components
+        displacementInterpolationMotionSolver
+        (
+            const polyMesh& mesh,
+            const IOdictionary& dict,
+            const pointVectorField& pointDisplacement,
+            const pointIOField& points0
+        );
+
 
     //- Destructor
     ~displacementInterpolationMotionSolver();
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
index d4a3ca5a0a7c1f7b3dfdd2fe55eb3879d26a68b9..15e1a4cf8d9568ad6024d91c2db860068b7680a0 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,13 +24,13 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "displacementLaplacianFvMotionSolver.H"
+#include "motionInterpolation.H"
 #include "motionDiffusivity.H"
 #include "fvmLaplacian.H"
 #include "addToRunTimeSelectionTable.H"
 #include "OFstream.H"
 #include "meshTools.H"
 #include "mapPolyMesh.H"
-#include "volPointInterpolation.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -44,6 +44,13 @@ namespace Foam
         displacementLaplacianFvMotionSolver,
         dictionary
     );
+
+    addToRunTimeSelectionTable
+    (
+        displacementMotionSolver,
+        displacementLaplacianFvMotionSolver,
+        displacement
+    );
 }
 
 
@@ -77,6 +84,102 @@ Foam::displacementLaplacianFvMotionSolver::displacementLaplacianFvMotionSolver
         cellMotionBoundaryTypes<vector>(pointDisplacement_.boundaryField())
     ),
     pointLocation_(NULL),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
+    diffusivityPtr_
+    (
+        motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
+    ),
+    frozenPointsZone_
+    (
+        coeffDict().found("frozenPointsZone")
+      ? fvMesh_.pointZones().findZoneID(coeffDict().lookup("frozenPointsZone"))
+      : -1
+    )
+{
+    IOobject io
+    (
+        "pointLocation",
+        fvMesh_.time().timeName(),
+        fvMesh_,
+        IOobject::MUST_READ,
+        IOobject::AUTO_WRITE
+    );
+
+    if (debug)
+    {
+        Info<< "displacementLaplacianFvMotionSolver:" << nl
+            << "    diffusivity       : " << diffusivityPtr_().type() << nl
+            << "    frozenPoints zone : " << frozenPointsZone_ << endl;
+    }
+
+
+    if (io.headerOk())
+    {
+        pointLocation_.reset
+        (
+            new pointVectorField
+            (
+                io,
+                pointMesh::New(fvMesh_)
+            )
+        );
+
+        if (debug)
+        {
+            Info<< "displacementLaplacianFvMotionSolver :"
+                << " Read pointVectorField "
+                << io.name()
+                << " to be used for boundary conditions on points."
+                << nl
+                << "Boundary conditions:"
+                << pointLocation_().boundaryField().types() << endl;
+        }
+    }
+}
+
+
+Foam::displacementLaplacianFvMotionSolver::
+displacementLaplacianFvMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict,
+    const pointVectorField& pointDisplacement,
+    const pointIOField& points0
+)
+:
+    displacementMotionSolver(mesh, dict, pointDisplacement, points0, typeName),
+    fvMotionSolverCore(mesh),
+    cellDisplacement_
+    (
+        IOobject
+        (
+            "cellDisplacement",
+            mesh.time().timeName(),
+            mesh,
+            IOobject::READ_IF_PRESENT,
+            IOobject::AUTO_WRITE
+        ),
+        fvMesh_,
+        dimensionedVector
+        (
+            "cellDisplacement",
+            pointDisplacement_.dimensions(),
+            vector::zero
+        ),
+        cellMotionBoundaryTypes<vector>(pointDisplacement_.boundaryField())
+    ),
+    pointLocation_(NULL),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
     diffusivityPtr_
     (
         motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
@@ -157,7 +260,7 @@ Foam::displacementLaplacianFvMotionSolver::diffusivity()
 Foam::tmp<Foam::pointField>
 Foam::displacementLaplacianFvMotionSolver::curPoints() const
 {
-    volPointInterpolation::New(fvMesh_).interpolate
+    interpolationPtr_->interpolate
     (
         cellDisplacement_,
         pointDisplacement_
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
index 47ad2c672c9a8edd77a53cd1594f6680cb10d46a..bcaa96e16629cf1a81506e13eceb4f7cb417afa6 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,7 @@ namespace Foam
 {
 
 // Forward class declarations
+class motionInterpolation;
 class motionDiffusivity;
 
 /*---------------------------------------------------------------------------*\
@@ -65,6 +66,9 @@ class displacementLaplacianFvMotionSolver
         //  boundary conditions.
         mutable autoPtr<pointVectorField> pointLocation_;
 
+        //- Interpolation used to transfer cell displacement to the points
+        autoPtr<motionInterpolation> interpolationPtr_;
+
         //- Diffusivity used to control the motion
         autoPtr<motionDiffusivity> diffusivityPtr_;
 
@@ -100,6 +104,15 @@ public:
             const IOdictionary&
         );
 
+        //- Construct from components
+        displacementLaplacianFvMotionSolver
+        (
+            const polyMesh& mesh,
+            const IOdictionary& dict,
+            const pointVectorField& pointDisplacement,
+            const pointIOField& points0
+        );
+
 
     //- Destructor
     ~displacementLaplacianFvMotionSolver();
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
index 137283c1ba89785cd517f785e944a2b7eea1ccc4..c31b956d348f98bafaf776d864df6a1d614cdab2 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,13 @@ namespace Foam
         displacementLayeredMotionMotionSolver,
         dictionary
     );
+
+    addToRunTimeSelectionTable
+    (
+        displacementMotionSolver,
+        displacementLayeredMotionMotionSolver,
+        displacement
+    );
 }
 
 
@@ -531,6 +538,19 @@ displacementLayeredMotionMotionSolver
 {}
 
 
+Foam::displacementLayeredMotionMotionSolver::
+displacementLayeredMotionMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict,
+    const pointVectorField& pointDisplacement,
+    const pointIOField& points0
+)
+:
+    displacementMotionSolver(mesh, dict, pointDisplacement, points0, typeName)
+{}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::displacementLayeredMotionMotionSolver::
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
index 1aa7884f52b879d743c4ea30db1828af67dc0777..6b77a8aa609d25a77db543a4f8306bd546000424 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -136,6 +136,16 @@ public:
             const IOdictionary&
         );
 
+        //- Construct from polyMesh, IOdictionary and displacement and
+        //  zero-time fields
+        displacementLayeredMotionMotionSolver
+        (
+            const polyMesh&,
+            const IOdictionary&,
+            const pointVectorField&,
+            const pointIOField&
+        );
+
 
     //- Destructor
     ~displacementLayeredMotionMotionSolver();
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.C
new file mode 100644
index 0000000000000000000000000000000000000000..7af99613e453b82a1e141c48262647a3e9debded
--- /dev/null
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.C
@@ -0,0 +1,422 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "surfaceAlignedSBRStressFvMotionSolver.H"
+#include "addToRunTimeSelectionTable.H"
+#include "pointIndexHit.H"
+#include "fvmLaplacian.H"
+#include "fvcDiv.H"
+#include "surfaceInterpolate.H"
+#include "unitConversion.H"
+#include "motionDiffusivity.H"
+#include "fvcSmooth.H"
+#include "pointMVCWeight.H"
+#include "dimensionedSymmTensor.H"
+#include "quaternion.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(surfaceAlignedSBRStressFvMotionSolver, 0);
+
+    addToRunTimeSelectionTable
+    (
+        motionSolver,
+        surfaceAlignedSBRStressFvMotionSolver,
+        dictionary
+    );
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::surfaceAlignedSBRStressFvMotionSolver::
+surfaceAlignedSBRStressFvMotionSolver
+(
+    const polyMesh& mesh,
+    const IOdictionary& dict
+)
+:
+    displacementSBRStressFvMotionSolver(mesh, dict),
+    surfaceNames_(coeffDict().lookup("surfaces")),
+    surfaceMesh_(surfaceNames_.size()),
+    cellRot_
+    (
+        IOobject
+        (
+            "cellRot",
+            fvMesh_.time().timeName(),
+            fvMesh_,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE
+        ),
+        fvMesh_,
+        dimensionedVector("zero", dimless, vector::zero)
+    ),
+    maxAng_(coeffDict().lookupOrDefault<scalar>("maxAng", 80.0)),
+    minAng_(coeffDict().lookupOrDefault<scalar>("minAng", 20.0)),
+    accFactor_(coeffDict().lookupOrDefault<scalar>("accFactor", 1.0)),
+    smoothFactor_(coeffDict().lookupOrDefault<scalar>("smoothFactor", 0.9)),
+    nNonOrthogonalCorr_(readLabel(coeffDict().lookup("nNonOrthogonalCorr"))),
+    pointDisplacement_(pointDisplacement()),
+    sigmaD_
+    (
+        IOobject
+        (
+            "sigmaD",
+            fvMesh_.time().timeName(),
+            fvMesh_,
+            IOobject::READ_IF_PRESENT,
+            IOobject::NO_WRITE
+        ),
+        fvMesh_,
+        dimensionedSymmTensor("zero", dimless, symmTensor::zero)
+    ),
+    minSigmaDiff_(coeffDict().lookupOrDefault<scalar>("minSigmaDiff", 1e-4))
+{
+    forAll (surfaceNames_, i)
+    {
+        surfaceMesh_.set
+        (
+            i,
+            new triSurfaceMesh
+            (
+                IOobject
+                (
+                    surfaceNames_[i],
+                    mesh.time().constant(),
+                    "triSurface",
+                    mesh.time(),
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE
+                )
+            )
+        );
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::surfaceAlignedSBRStressFvMotionSolver::
+~surfaceAlignedSBRStressFvMotionSolver()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+void Foam::surfaceAlignedSBRStressFvMotionSolver::calculateCellRot()
+{
+    cellRot_.internalField() = vector::zero;
+    pointDisplacement_.internalField() = vector::zero;
+
+    // Find intersections
+    pointField start(fvMesh_.nInternalFaces());
+    pointField end(start.size());
+
+    for (label faceI = 0; faceI < fvMesh_.nInternalFaces(); faceI++)
+    {
+        start[faceI] = fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
+        end[faceI] = fvMesh_.cellCentres()[fvMesh_.faceNeighbour()[faceI]];
+    }
+
+    DynamicList<label> hitCells;
+
+    forAll (surfaceMesh_, surfI)
+    {
+        List<pointIndexHit> hit(start.size());
+        surfaceMesh_[surfI].findLineAny(start, end, hit);
+
+        labelField pointsCount(fvMesh_.nPoints(), 1);
+
+        const vectorField& nf = surfaceMesh_[surfI].faceNormals();
+
+        const vectorField& SfMesh = fvMesh_.faceAreas();
+
+        const vectorField nSfMesh(SfMesh/mag(SfMesh));
+
+        DynamicList<label> cellsHit;
+
+        forAll(hit, faceI)
+        {
+            if (hit[faceI].hit())
+            {
+                label rotCellId(-1);
+                const vector hitPoint = hit[faceI].hitPoint();
+
+                if (fvMesh_.isInternalFace(faceI))
+                {
+                    const vector cCOne =
+                        fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
+
+                    const vector cCTwo =
+                        fvMesh_.cellCentres()[fvMesh_.faceNeighbour()[faceI]];
+
+                    if (mag(cCOne - hitPoint) < mag(cCTwo - hitPoint))
+                    {
+                        rotCellId = fvMesh_.faceOwner()[faceI];
+                    }
+                    else
+                    {
+                        rotCellId = fvMesh_.faceNeighbour()[faceI];
+                    }
+                }
+                else
+                {
+                    label patchI = fvMesh_.boundaryMesh().whichPatch(faceI);
+                    if
+                    (
+                        isA<processorPolyPatch>(fvMesh_.boundaryMesh()[patchI])
+                    )
+                    {
+                        const point& ownCc =
+                            fvMesh_.cellCentres()[fvMesh_.faceOwner()[faceI]];
+
+                        const vector cCentreOne = ownCc - hitPoint;
+
+                        const vector nbrCc =
+                            refCast<const processorPolyPatch>
+                            (
+                                fvMesh_.boundaryMesh()[patchI]
+                            ).neighbFaceCellCentres()[faceI];
+
+                        const vector cCentreTwo = nbrCc - hitPoint;
+
+                        if (cCentreOne < cCentreTwo)
+                        {
+                            rotCellId = fvMesh_.faceOwner()[faceI];
+                        }
+                    }
+                }
+
+// Note: faces on boundaries that get hit are noy included as the
+// pointDisplacement on boundaries is usually zero for this solver.
+
+                // Search for closest direction on faces on mesh
+                // and surface normal.
+                if (rotCellId != -1)
+                {
+                    const labelList& cFaces = fvMesh_.cells()[rotCellId];
+
+                    scalar cosMax(-GREAT);
+                    label faceId(-1);
+                    forAll(cFaces, k)
+                    {
+                        scalar tmp =
+                            mag(nf[hit[faceI].index()] & nSfMesh[cFaces[k]]);
+
+                        if (tmp > cosMax)
+                        {
+                            cosMax = tmp;
+                            faceId = cFaces[k];
+                        }
+                    }
+                    if
+                    (
+                        faceId != -1
+                    &&
+                        (
+                            ::cos(degToRad(minAng_)) > cosMax
+                            || cosMax > ::cos(degToRad(maxAng_))
+
+                        )
+                    )
+                    {
+                        cellRot_[rotCellId] =
+                            nSfMesh[faceId] ^ nf[hit[faceI].index()];
+
+                        const scalar magRot = mag(cellRot_[rotCellId]);
+
+                        if (magRot > 0)
+                        {
+                            const scalar theta = ::asin(magRot);
+                            quaternion q(cellRot_[rotCellId]/magRot, theta);
+                            const tensor R = q.R();
+                            const labelList& cPoints =
+                                fvMesh_.cellPoints(rotCellId);
+
+                            forAll (cPoints, j)
+                            {
+                                const label pointId = cPoints[j];
+
+                                pointsCount[pointId]++;
+
+                                const vector pointPos =
+                                    fvMesh_.points()[pointId];
+
+                                pointDisplacement_[pointId] +=
+                                    (R & (pointPos - hitPoint))
+                                  - (pointPos - hitPoint);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        forAll (pointDisplacement_.internalField(), iPoint)
+        {
+            vector& point = pointDisplacement_.internalField()[iPoint];
+            point /= pointsCount[iPoint];
+        }
+
+
+    }
+}
+
+
+void Foam::surfaceAlignedSBRStressFvMotionSolver::solve()
+{
+    // The points have moved so before interpolation update
+    // the mtionSolver accordingly
+    this->movePoints(fvMesh_.points());
+
+    volVectorField& cellDisp = cellDisplacement();
+
+    diffusivity().correct();
+
+    // Calculate rotations on surface intersection
+    calculateCellRot();
+
+    tmp<volVectorField> tUd
+    (
+        new volVectorField
+        (
+            IOobject
+            (
+                "Ud",
+                fvMesh_.time().timeName(),
+                fvMesh_,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            fvMesh_,
+            dimensionedVector("zero", dimLength, vector::zero),
+            cellMotionBoundaryTypes<vector>
+            (
+                pointDisplacement().boundaryField()
+            )
+        )
+    );
+
+    volVectorField& Ud = tUd();
+
+    const vectorList& C = fvMesh_.C();
+    forAll (Ud, i)
+    {
+        pointMVCWeight pointInter(fvMesh_, C[i], i);
+        Ud[i] = pointInter.interpolate(pointDisplacement_);
+    }
+
+    volScalarField Udx(Ud.component(vector::X));
+    fvc::smooth(Udx, smoothFactor_);
+
+    volScalarField Udy(Ud.component(vector::Y));
+    fvc::smooth(Udy, smoothFactor_);
+
+    volScalarField Udz(Ud.component(vector::Z));
+    fvc::smooth(Udz, smoothFactor_);
+
+    Ud.replace(vector::X, Udx);
+    Ud.replace(vector::Y, Udy);
+    Ud.replace(vector::Z, Udz);
+
+    const volTensorField gradD("gradD", fvc::grad(Ud));
+
+    tmp<volScalarField> tmu
+    (
+        new volScalarField
+        (
+            IOobject
+            (
+                "mu",
+                fvMesh_.time().timeName(),
+                fvMesh_,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE
+            ),
+            fvMesh_,
+            dimensionedScalar("zero", dimless, 0.0)
+        )
+    );
+    volScalarField& mu =  tmu();
+
+    const scalarList& V = fvMesh_.V();
+    mu.internalField() = (1.0/V);
+
+    const volScalarField lambda(-mu);
+
+    const volSymmTensorField newSigmaD
+    (
+        mu*twoSymm(gradD) + (lambda*I)*tr(gradD)
+    );
+
+    const volSymmTensorField magNewSigmaD(sigmaD_ + accFactor_*newSigmaD);
+
+    const scalar diffSigmaD =
+        gSum(mag(sigmaD_.oldTime().internalField()))
+     -  gSum(mag(magNewSigmaD.internalField()));
+
+    if (mag(diffSigmaD) > minSigmaDiff_)
+    {
+        sigmaD_ = magNewSigmaD;
+    }
+
+    const surfaceScalarField Df(diffusivity().operator()());
+    pointDisplacement_.boundaryField().updateCoeffs();
+
+    const volTensorField gradCd(fvc::grad(cellDisp));
+
+    for (int nonOrth=0; nonOrth<=nNonOrthogonalCorr_; nonOrth++)
+    {
+        fvVectorMatrix DEqn
+        (
+            fvm::laplacian
+            (
+                2*Df*fvc::interpolate(mu),
+                cellDisp,
+                "laplacian(diffusivity,cellDisplacement)"
+            )
+          + fvc::div
+            (
+                Df*
+                (
+                    fvc::interpolate(mu)
+                  * (fvMesh_.Sf() & fvc::interpolate(gradCd.T() - gradCd))
+                  - fvc::interpolate(lambda)*fvMesh_.Sf()
+                  * fvc::interpolate(tr(gradCd))
+                )
+            )
+          ==
+            fvc::div(sigmaD_)
+        );
+
+        DEqn.solve();
+    }
+}
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.H
new file mode 100644
index 0000000000000000000000000000000000000000..0088d12f3dcc3373141adcb28bcf990c65127033
--- /dev/null
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/surfaceAlignedSBRStress/surfaceAlignedSBRStressFvMotionSolver.H
@@ -0,0 +1,188 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::surfaceAlignedSBRStressFvMotionSolver
+
+Description
+    Mesh motion solver for an fvMesh.  Based on solving the cell-centre
+    solid-body rotation stress equations for the motion displacement.
+    The model calculates the necessary rotation to align the stl surface
+    with the closest mesh face normals and it calculates the respective source
+    term for the SBRStress equation.
+
+    Input parameters:
+
+    surfaceAlignedSBRStressCoeffs
+    {
+        diffusivity         uniform;
+        surfaces            ("terrain.stl");
+        maxAng              85;
+        minAng              5;
+        nNonOrthogonalCorr  4;
+        accFactor           1.3;
+        smoothFactor        0.9;
+        minSigmaDiff        1e-4;
+    }
+
+    surfaces: name of the stl surfaces to which apply alignment.
+
+    maxAng: Maximum angle (between surface and most aligned mesh face normal)
+            to which rotation is applied. (default 80 degress)
+
+    minAng: Minimum angle (between surface and most aligned mesh face normal)
+            to which rotation is applied (default 20 degress)
+
+    nNonOrthogonalCorr: Non-orthogonal correction of the SBRStress equation
+
+    accFactor: Proportionality constant applied to the source of the stress
+               equation.(default 1)
+
+    smoothFactor: Displacement smooth factor (1 very smooth , 0 no smoothing)
+                (default 0.9)
+
+    minSigmaDiff: Minimum magnitude difference between old and new magnitudes
+                 of the applied stress.
+
+                 If the difference between old and new is smaller than
+                 minSigmaDiff no further addition to the stress source term
+                 will be made (default: 1e-3)
+
+SourceFiles
+    surfaceAlignedSBRStressFvMotionSolver.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef surfaceAlignedSBRStressFvMotionSolver_H
+#define surfaceAlignedSBRStressFvMotionSolver_H
+
+#include "triSurfaceMesh.H"
+#include "vectorList.H"
+#include "displacementSBRStressFvMotionSolver.H"
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+             Class surfaceAlignedSBRStressFvMotionSolver Declaration
+\*---------------------------------------------------------------------------*/
+
+class surfaceAlignedSBRStressFvMotionSolver
+:
+    public displacementSBRStressFvMotionSolver
+{
+    // Private data
+
+        //- Names of the surfaces
+        wordList surfaceNames_;
+
+        //- TriSurfaceMesh
+        PtrList<triSurfaceMesh>  surfaceMesh_;
+
+        //- Rotation vector field
+        volVectorField cellRot_;
+
+        //- Maximum angle (between surface and most aligned mesh face normal)
+        // to which rotation is applied
+        scalar maxAng_;
+
+        //- Minimum angle (between surface and most aligned mesh face normal)
+        // to which rotation is applied
+        scalar minAng_;
+
+        //- Propotional constant applied to the source to accelerate
+        //  convergence
+        scalar accFactor_;
+
+        //- Displacement smooth factor
+        scalar smoothFactor_;
+
+        //- Non-orthogonal correction of the SBRStress equation
+        label nNonOrthogonalCorr_;
+
+        //- Point displacement field
+        pointVectorField& pointDisplacement_;
+
+        //- Stress tensor
+        volSymmTensorField sigmaD_;
+
+        //- Minimum magnitude difference between old and new magntides
+        //  stress applied
+        scalar minSigmaDiff_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        surfaceAlignedSBRStressFvMotionSolver
+        (
+            const surfaceAlignedSBRStressFvMotionSolver&
+        );
+
+        //- Disallow default bitwise assignment
+        void operator=(const surfaceAlignedSBRStressFvMotionSolver&);
+
+        //- Calculate cellRot
+        void calculateCellRot();
+
+
+public:
+
+    //- Runtime type information
+    TypeName("surfaceAlignedSBRStress");
+
+
+    // Constructors
+
+        //- Construct from polyMesh and IOdictionary
+        surfaceAlignedSBRStressFvMotionSolver
+        (
+            const polyMesh&,
+            const IOdictionary&
+        );
+
+
+    //- Destructor
+    ~surfaceAlignedSBRStressFvMotionSolver();
+
+
+    // Member Functions
+
+        //- Solve for motion
+        virtual void solve();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
index ce63274ed9fc8a25dfab738bde02878932a521ba..98c17b74158db4f07094a461c9e57cbe47ac42b3 100644
--- a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,10 +24,10 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "velocityLaplacianFvMotionSolver.H"
+#include "motionInterpolation.H"
 #include "motionDiffusivity.H"
 #include "fvmLaplacian.H"
 #include "addToRunTimeSelectionTable.H"
-#include "volPointInterpolation.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -73,6 +73,12 @@ Foam::velocityLaplacianFvMotionSolver::velocityLaplacianFvMotionSolver
         ),
         cellMotionBoundaryTypes<vector>(pointMotionU_.boundaryField())
     ),
+    interpolationPtr_
+    (
+        coeffDict().found("interpolation")
+      ? motionInterpolation::New(fvMesh_, coeffDict().lookup("interpolation"))
+      : motionInterpolation::New(fvMesh_)
+    ),
     diffusivityPtr_
     (
         motionDiffusivity::New(fvMesh_, coeffDict().lookup("diffusivity"))
@@ -91,7 +97,7 @@ Foam::velocityLaplacianFvMotionSolver::~velocityLaplacianFvMotionSolver()
 Foam::tmp<Foam::pointField>
 Foam::velocityLaplacianFvMotionSolver::curPoints() const
 {
-    volPointInterpolation::New(fvMesh_).interpolate
+    interpolationPtr_->interpolate
     (
         cellMotionU_,
         pointMotionU_
@@ -130,13 +136,6 @@ void Foam::velocityLaplacianFvMotionSolver::solve()
 }
 
 
-//void Foam::velocityLaplacianFvMotionSolver::movePoints(const pointField& p)
-//{
-//    // Movement of pointMesh and volPointInterpolation already
-//    // done by polyMesh,fvMesh
-//}
-
-
 void Foam::velocityLaplacianFvMotionSolver::updateMesh
 (
     const mapPolyMesh& mpm
diff --git a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
index cb187022a29429cb6c5ff8f877572a5c4a124fc8..486266507c205d9c79574edd039b5766bfd25cb0 100644
--- a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
@@ -2,8 +2,8 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+    \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,6 +45,7 @@ namespace Foam
 {
 
 // Forward class declarations
+class motionInterpolation;
 class motionDiffusivity;
 
 /*---------------------------------------------------------------------------*\
@@ -61,6 +62,9 @@ class velocityLaplacianFvMotionSolver
         //- Cell-centre motion field
         mutable volVectorField cellMotionU_;
 
+        //- Interpolation used to transfer cell displacement to the points
+        autoPtr<motionInterpolation> interpolationPtr_;
+
         //- Diffusivity used to control the motion
         autoPtr<motionDiffusivity> diffusivityPtr_;
 
diff --git a/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.C b/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.C
new file mode 100644
index 0000000000000000000000000000000000000000..b293e5f491b16e8f46c843b482e0c70c393da87d
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.C
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "addToRunTimeSelectionTable.H"
+#include "motionInterpolation.H"
+#include "volPointInterpolation.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(motionInterpolation, 0);
+
+    defineRunTimeSelectionTable(motionInterpolation, Istream);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::motionInterpolation::motionInterpolation
+(
+    const fvMesh& mesh
+)
+:
+    mesh_(mesh)
+{}
+
+
+Foam::motionInterpolation::motionInterpolation
+(
+    const fvMesh& mesh,
+    Istream& entry
+)
+:
+    mesh_(mesh)
+{}
+
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::motionInterpolation>
+Foam::motionInterpolation::New(const fvMesh& mesh)
+{
+    return autoPtr<motionInterpolation>(new motionInterpolation(mesh));
+}
+
+
+Foam::autoPtr<Foam::motionInterpolation>
+Foam::motionInterpolation::New(const fvMesh& mesh, Istream& entry)
+{
+    const word type(entry);
+
+    Info<< "Selecting motion interpolation: " << type << endl;
+
+    IstreamConstructorTable::iterator cstrIter =
+        IstreamConstructorTablePtr_->find(type);
+
+    if (cstrIter == IstreamConstructorTablePtr_->end())
+    {
+        FatalErrorIn
+        (
+            "motionInterpolation::New(const fvMesh&, const Istream&)"
+        )   << "Unknown interpolation type "
+            << type << nl << nl
+            << "Valid interpolation types are :" << endl
+            << IstreamConstructorTablePtr_->sortedToc()
+            << exit(FatalError);
+    }
+
+    return autoPtr<motionInterpolation>(cstrIter()(mesh, entry));
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::motionInterpolation::~motionInterpolation()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::motionInterpolation::interpolate
+(
+    const volScalarField& cellDisplacement,
+    pointScalarField& pointDisplacement
+) const
+{
+    volPointInterpolation::New(mesh()).interpolate
+    (
+        cellDisplacement,
+        pointDisplacement
+    );
+}
+
+
+void Foam::motionInterpolation::interpolate
+(
+    const volVectorField& cellDisplacement,
+    pointVectorField& pointDisplacement
+) const
+{
+    volPointInterpolation::New(mesh()).interpolate
+    (
+        cellDisplacement,
+        pointDisplacement
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.H b/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.H
new file mode 100644
index 0000000000000000000000000000000000000000..46cb4b0ecfd7c662a5dc9b830f4ec8c3932fd589
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/motionInterpolation/motionInterpolation.H
@@ -0,0 +1,147 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::motionInterpolation
+
+Description
+    Base class for interpolation of cell displacement fields, generated by
+    fvMotionSolvers, to the points. This base class implements the default
+    method which applies volPointInterpolation only.
+
+SourceFiles
+    motionInterpolation.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef motionInterpolation_H
+#define motionInterpolation_H
+
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class motionInterpolation Declaration
+\*---------------------------------------------------------------------------*/
+
+class motionInterpolation
+{
+    // Private data
+
+        //- Reference to the FV mesh
+        const fvMesh& mesh_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        motionInterpolation(const motionInterpolation&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const motionInterpolation&);
+
+
+public:
+
+    //- Runtime type information
+    TypeName("motionInterpolation");
+
+
+    // Declare run-time constructor selection tables
+
+        declareRunTimeSelectionTable
+        (
+            autoPtr,
+            motionInterpolation,
+            Istream,
+            (
+                const fvMesh& mesh,
+                Istream& entry
+            ),
+            (mesh, entry)
+        );
+
+
+    // Selectors
+
+        //- Select default
+        static autoPtr<motionInterpolation> New(const fvMesh& mesh);
+
+        //- Select from stream
+        static autoPtr<motionInterpolation> New
+        (
+            const fvMesh& mesh,
+            Istream& entry
+        );
+
+
+    // Constructors
+
+        //- Construct from an fvMesh
+        motionInterpolation(const fvMesh& mesh);
+
+        //- Construct from an fvMesh and an Istream
+        motionInterpolation(const fvMesh& mesh, Istream& entry);
+
+
+    //- Destructor
+    virtual ~motionInterpolation();
+
+
+    // Member Functions
+
+        //- Return const-refernce to the mesh
+        const fvMesh& mesh() const
+        {
+            return mesh_;
+        }
+
+        //- Interpolate the given scalar cell displacement
+        virtual void interpolate
+        (
+            const volScalarField&,
+            pointScalarField&
+        ) const;
+
+        //- Interpolate the given vector cell displacement
+        virtual void interpolate
+        (
+            const volVectorField&,
+            pointVectorField&
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.C b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.C
new file mode 100644
index 0000000000000000000000000000000000000000..8d0c6b74fa8bf9428077b23b5241eaf567623497
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.C
@@ -0,0 +1,124 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "addToRunTimeSelectionTable.H"
+#include "patchCorrectedInterpolation.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(patchCorrectedInterpolation, 0);
+
+    addToRunTimeSelectionTable
+    (
+        motionInterpolation,
+        patchCorrectedInterpolation,
+        Istream
+    );
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::labelListList Foam::patchCorrectedInterpolation::getPatchGroups
+(
+    Istream& entry
+) const
+{
+    List<List<word> > patchGroupNames(entry);
+
+    labelListList patchGroups(patchGroupNames.size());
+
+    forAll(patchGroupNames, patchI)
+    {
+        patchGroups[patchI].resize(patchGroupNames[patchI].size());
+
+        forAll(patchGroupNames[patchI], patchJ)
+        {
+            patchGroups[patchI][patchJ] =
+                mesh().boundaryMesh().findPatchID
+                (
+                    patchGroupNames[patchI][patchJ]
+                );
+
+            if (patchGroups[patchI][patchJ] == -1)
+            {
+                FatalErrorIn
+                (
+                    "Foam::patchCorrectedInterpolation::getPatchGroups"
+                    "(Istream&) const"
+                )   << "patch \"" << patchGroupNames[patchI][patchJ]
+                    << "\" not found" << exit(FatalError);
+            }
+        }
+    }
+
+    return patchGroups;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::patchCorrectedInterpolation::patchCorrectedInterpolation
+(
+    const fvMesh& mesh,
+    Istream& entry
+)
+:
+    motionInterpolation(mesh, entry),
+    patchGroups_(getPatchGroups(entry))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::patchCorrectedInterpolation::~patchCorrectedInterpolation()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::patchCorrectedInterpolation::interpolate
+(
+    const volScalarField& cellDisplacement,
+    pointScalarField& pointDisplacement
+) const
+{
+    interpolateType(cellDisplacement, pointDisplacement);
+}
+
+
+void Foam::patchCorrectedInterpolation::interpolate
+(
+    const volVectorField& cellDisplacement,
+    pointVectorField& pointDisplacement
+) const
+{
+    interpolateType(cellDisplacement, pointDisplacement);
+}
+
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.H b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.H
new file mode 100644
index 0000000000000000000000000000000000000000..0c7721dfbf8e990e103f88c806f3c9045a0d665f
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolation.H
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::patchCorrectedInterpolation
+
+Description
+    Interpolation of cell-based displacements to the points with additional
+    correction for interpolation inconsistency on patches.
+
+    The default interpolation method interpolates from the cells to all points
+    except those on boundaries with value boundary conditions. The discrepancy
+    across the boundary cell can cause shearing and inversion if the cells are
+    of very high aspect ratio.
+
+    This method applies the default interpolation to *all* points, including
+    those on value boundaries. The difference between the interpolated value on
+    the boundary and the desired boundary condition is then propagated into the
+    mesh with a wave. Contributions from different patches are inverse-distance
+    weighted, and the result is added to the default interpolation. The result
+    of this is that thin boundary cells are maintained much more accurately for
+    non-uniform patch displacements.
+
+    The user must specify the patch groups from which to propagate the motion.
+    Ideally, these groups will be opposing; i.e. one group with the aerofoil,
+    and one with the far field:
+
+    \verbatim
+        interpolation patchCorrected
+        (
+            (aerofoilUpper aerofoilLower)
+            (farField)
+        );
+    \endverbatim
+
+SourceFiles
+    patchCorrectedInterpolation.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef patchCorrectedInterpolation_H
+#define patchCorrectedInterpolation_H
+
+#include "motionInterpolation.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class patchCorrectedInterpolation Declaration
+\*---------------------------------------------------------------------------*/
+
+class patchCorrectedInterpolation
+:
+    public motionInterpolation
+{
+    // Private data
+
+        //- Patch groups from which to propagate the displacement
+        const labelListList patchGroups_;
+
+
+    // Private member functions
+
+        //- Get patch groups from the input stream
+        labelListList getPatchGroups(Istream& entry) const;
+
+        //- Interpolate the given cell displacement
+        template <class Type>
+        void interpolateType
+        (
+            const GeometricField<Type, fvPatchField, volMesh>&,
+            GeometricField<Type, pointPatchField, pointMesh>&
+        ) const;
+
+        //- Interpolate patch data by inverse distance weighting
+        template <class Type>
+        void interpolateDataFromPatchGroups
+        (
+            GeometricField<Type, pointPatchField, pointMesh>&
+        ) const;
+
+        //- Propagate data from a number of patches into the field
+        template <class Type>
+        void propagateDataFromPatchGroup
+        (
+            const label,
+            pointScalarField&,
+            GeometricField<Type, pointPatchField, pointMesh>&
+        ) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("patchCorrected");
+
+
+    // Constructors
+
+        //- Construct from an fvMesh and an Istream
+        patchCorrectedInterpolation
+        (
+            const fvMesh& mesh,
+            Istream& entry
+        );
+
+
+    //- Destructor
+    virtual ~patchCorrectedInterpolation();
+
+
+    // Member Functions
+
+        //- Interpolate the given scalar cell displacement
+        virtual void interpolate
+        (
+            const volScalarField&,
+            pointScalarField&
+        ) const;
+
+        //- Interpolate the given vector cell displacement
+        virtual void interpolate
+        (
+            const volVectorField&,
+            pointVectorField&
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "patchCorrectedInterpolationTemplates.C"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolationTemplates.C b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolationTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..5881ae7bcfb40050c5da0b4b99248b6299352734
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/patchCorrected/patchCorrectedInterpolationTemplates.C
@@ -0,0 +1,223 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "fixedValuePointPatchField.H"
+#include "PointData.H"
+#include "PointEdgeWave.H"
+#include "volPointInterpolation.H"
+#include "zeroGradientPointPatchField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template <class Type>
+void Foam::patchCorrectedInterpolation::interpolateType
+(
+    const GeometricField<Type, fvPatchField, volMesh>& cellDisplacement,
+    GeometricField<Type, pointPatchField, pointMesh>& pointDisplacement
+) const
+{
+    // Create an uncorrected field
+    GeometricField<Type, pointPatchField, pointMesh>
+        pointUncorrectedDisplacement
+        (
+            IOobject
+            (
+                "pointUncorrectedDisplacement",
+                mesh().time().timeName(),
+                mesh()
+            ),
+            pointDisplacement.mesh(),
+            pointDisplacement.dimensions(),
+            fixedValuePointPatchField<Type>::typeName
+        );
+
+    // Interpolate to the uncorrected field, overwriting the fixed value
+    // boundary conditions
+    pointUncorrectedDisplacement ==
+        volPointInterpolation::New(mesh()).interpolate
+        (
+            cellDisplacement,
+            wordList
+            (
+                pointUncorrectedDisplacement.boundaryField().size(),
+                zeroGradientPointPatchField<Type>::typeName
+            )
+        );
+
+    // Set the point displacement to the uncorrected result everywhere except
+    // for on the boundary
+    pointDisplacement.internalField() =
+        pointUncorrectedDisplacement.internalField();
+    pointDisplacement.correctBoundaryConditions();
+
+    // Set the residual displacement as the difference between the boundary
+    // specification and the uncorrected solution
+    // (this reuses the uncorrected displacement field as the residual)
+    pointUncorrectedDisplacement ==
+        pointDisplacement - pointUncorrectedDisplacement;
+
+    // Interpolate the residual from the boundary into the field
+    interpolateDataFromPatchGroups(pointUncorrectedDisplacement);
+
+    // Add the residual to the point displacement and correct the boundary
+    pointDisplacement += pointUncorrectedDisplacement;
+    pointDisplacement.correctBoundaryConditions();
+}
+
+
+template <class Type>
+void Foam::patchCorrectedInterpolation::interpolateDataFromPatchGroups
+(
+    GeometricField<Type, pointPatchField, pointMesh>& data
+) const
+{
+    // Initialise
+    pointScalarField weight
+    (
+        IOobject
+        (
+            "weight",
+            mesh().time().timeName(),
+            mesh()
+        ),
+        data.mesh(),
+        dimensionedScalar("zero", dimless, 0),
+        zeroGradientPointPatchField<scalar>::typeName
+    );
+    data = dimensioned<Type>("zero", data.dimensions(), pTraits<Type>::zero);
+
+    forAll(patchGroups_, patchGroupI)
+    {
+        // Distance and data for the current group
+        pointScalarField patchDistance
+        (
+            IOobject
+            (
+                "patchDistance",
+                mesh().time().timeName(),
+                mesh()
+            ),
+            data.mesh(),
+            dimensionedScalar("zero", data.dimensions(), 0),
+            zeroGradientPointPatchField<scalar>::typeName
+        );
+        GeometricField<Type, pointPatchField, pointMesh> patchData(data);
+
+        // Wave the data through the mesh
+        propagateDataFromPatchGroup
+        (
+            patchGroupI,
+            patchDistance,
+            patchData
+        );
+
+        // Calculate the weight and add to weighted sum
+        const scalarField patchWeight
+        (
+            1/max(sqr(patchDistance.internalField()), SMALL)
+        );
+        data.internalField() += patchWeight*patchData.internalField();
+        weight.internalField() += patchWeight;
+    }
+
+    // Complete the average
+    data /= weight;
+}
+
+
+template <class Type>
+void Foam::patchCorrectedInterpolation::propagateDataFromPatchGroup
+(
+    const label patchGroupI,
+    pointScalarField& distance,
+    GeometricField<Type, pointPatchField, pointMesh>& data
+) const
+{
+    const labelList& patchGroup(patchGroups_[patchGroupI]);
+
+    // Get the size of the seed info
+    label nSeedInfo(0);
+    forAll(patchGroup, patchGroupI)
+    {
+        const label patchI(patchGroup[patchGroupI]);
+
+        nSeedInfo += data.boundaryField()[patchI].size();
+    }
+
+    // Generate the seed labels and info
+    labelList seedLabels(nSeedInfo);
+    List<PointData<Type> > seedInfo(nSeedInfo);
+    nSeedInfo = 0;
+    forAll(patchGroup, patchGroupI)
+    {
+        const label patchI(patchGroup[patchGroupI]);
+
+        pointPatchField<Type>& patchDataField(data.boundaryField()[patchI]);
+
+        patchDataField.updateCoeffs();
+
+        const pointPatch& patch(patchDataField.patch());
+        const Field<Type> patchData(patchDataField.patchInternalField());
+
+        forAll(patch.meshPoints(), patchPointI)
+        {
+            const label pointI(patch.meshPoints()[patchPointI]);
+
+            seedLabels[nSeedInfo] = pointI;
+
+            seedInfo[nSeedInfo] =
+                PointData<Type>
+                (
+                    mesh().points()[pointI],
+                    0,
+                    patchData[patchPointI]
+                );
+
+            nSeedInfo ++;
+        }
+    }
+
+    // Wave the data through the mesh
+    List<PointData<Type> > allPointInfo(mesh().nPoints());
+    List<PointData<Type> > allEdgeInfo(mesh().nEdges());
+    PointEdgeWave<PointData<Type> >
+    (
+        mesh(),
+        seedLabels,
+        seedInfo,
+        allPointInfo,
+        allEdgeInfo,
+        mesh().globalData().nTotalPoints()
+    );
+
+    // Copy result into the fields
+    forAll(allPointInfo, pointI)
+    {
+        distance[pointI] = sqrt(allPointInfo[pointI].distSqr());
+        data[pointI] = allPointInfo[pointI].data();
+    }
+}
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.C b/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.C
new file mode 100644
index 0000000000000000000000000000000000000000..f99e668cc0348831869ab746b0fb686e6f2a8c08
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.C
@@ -0,0 +1,220 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "addToRunTimeSelectionTable.H"
+#include "patchTransformedInterpolation.H"
+#include "pointFields.H"
+#include "symmTensor2D.H"
+#include "tensor2D.H"
+#include "syncTools.H"
+#include "volPointInterpolation.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(patchTransformedInterpolation, 0);
+
+    addToRunTimeSelectionTable
+    (
+        motionInterpolation,
+        patchTransformedInterpolation,
+        Istream
+    );
+}
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+Foam::labelList Foam::patchTransformedInterpolation::getPatches
+(
+    Istream& entry
+) const
+{
+    wordList patchNames(entry);
+
+    labelList patches(patchNames.size(), -1);
+
+    forAll(patchNames, patchI)
+    {
+        patches[patchI] =
+            mesh().boundaryMesh().findPatchID
+            (
+                patchNames[patchI]
+            );
+
+        if (patches[patchI] == -1)
+        {
+            FatalErrorIn
+            (
+                "Foam::patchTransformedInterpolation::getPatches"
+                "(Istream&) const"
+            )   << "patch \"" << patchNames[patchI]
+                << "\" not found" << exit(FatalError);
+        }
+    }
+
+    return patches;
+}
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::patchTransformedInterpolation::patchTransformedInterpolation
+(
+    const fvMesh& mesh,
+    Istream& entry
+)
+:
+    motionInterpolation(mesh, entry),
+    patches_(getPatches(entry))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::patchTransformedInterpolation::~patchTransformedInterpolation()
+{}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::patchTransformedInterpolation::interpolate
+(
+    const volScalarField&,
+    pointScalarField&
+) const
+{
+    notImplemented
+    (
+        "void Foam::patchTransformedInterpolation::interpolate"
+        "("
+            "const volScalarField&"
+            "pointScalarField&"
+         ")"
+    );
+}
+
+
+void Foam::patchTransformedInterpolation::interpolate
+(
+    const volVectorField& cellDisplacement,
+    pointVectorField& pointDisplacement
+) const
+{
+    const pointField& points(mesh().points());
+    const label nPoints(points.size());
+
+    volPointInterpolation::New(mesh()).interpolate
+    (
+        cellDisplacement,
+        pointDisplacement
+    );
+
+    pointDisplacement.correctBoundaryConditions();
+
+    vectorField pointRotation(nPoints, vector::zero);
+    scalarField pointExpansion(nPoints, scalar(0));
+
+    labelList pointDisplacementNSum(nPoints, 0);
+    vectorField pointDisplacementSum(nPoints, vector::zero);
+
+    forAll(patches_, patchI)
+    {
+        const polyPatch& patch(mesh().boundaryMesh()[patches_[patchI]]);
+
+        forAll(patch, pFaceI)
+        {
+            const face& f(patch[pFaceI]);
+
+            const label cellI(patch.faceCells()[pFaceI]);
+            const cell& c(mesh().cells()[cellI]);
+            const labelList cPoints(c.labels(mesh().faces()));
+
+            // Consider movement around the face centre
+            const point& xOrigin(patch.faceCentres()[pFaceI]);
+
+            // Mean translation
+            const vector uMean(f.average(points, pointDisplacement));
+
+            // Calculate rotation and expansion for each point
+            forAll(f, fPointI)
+            {
+                const label pointI(f[fPointI]);
+                const vector& x(points[pointI]);
+                const vector r(x - xOrigin);
+                const vector u(pointDisplacement[pointI] - uMean);
+
+                pointRotation[pointI] = 2*(r ^ u)/magSqr(r);
+                pointExpansion[pointI] = (r & u)/magSqr(r);
+            }
+
+            // Mean rotation and expansion
+            const vector omegaMean(f.average(points, pointRotation));
+            const scalar divMean(f.average(points, pointExpansion));
+
+            // Apply mean solid body motion to all cell points
+            forAll(cPoints, cPointI)
+            {
+                const label pointI(cPoints[cPointI]);
+                const vector& x(points[pointI]);
+                const vector r(x - xOrigin);
+
+                pointDisplacementNSum[pointI] += 1;
+                pointDisplacementSum[pointI] +=
+                    uMean + (omegaMean ^ r) + (divMean*r);
+            }
+        }
+    }
+
+    syncTools::syncPointList
+    (
+        mesh(),
+        pointDisplacementNSum,
+        plusEqOp<label>(),
+        label(0)
+    );
+
+    syncTools::syncPointList
+    (
+        mesh(),
+        pointDisplacementSum,
+        plusEqOp<vector>(),
+        vector::zero
+    );
+
+    forAll(points, pointI)
+    {
+        if (pointDisplacementNSum[pointI])
+        {
+            pointDisplacement[pointI] =
+                pointDisplacementSum[pointI]/pointDisplacementNSum[pointI];
+        }
+    }
+
+    // Correct the faces
+    pointDisplacement.correctBoundaryConditions();
+}
+
+
+// ************************************************************************* //
diff --git a/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.H b/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.H
new file mode 100644
index 0000000000000000000000000000000000000000..c42948963c4529e277900d345bdf8e1fe620445b
--- /dev/null
+++ b/src/fvMotionSolver/motionInterpolation/patchTransformed/patchTransformedInterpolation.H
@@ -0,0 +1,132 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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::patchTransformedInterpolation
+
+Description
+    Interpolation of cell-based displacements to the points with additional
+    correction of patch-adjacent cells.
+
+    Snappy meshes often have moderately non-orthogonal faces next to patches.
+    If these partches are moved, these already quite distorted faces quickly
+    violate the quality criteria.
+
+    This method corrects patch-adjacent cells are by calculating the average
+    translation, rotation and expansion of points connected to the patch. This
+    transformation is then applied to all the points in the cell that are not
+    on the patch. This does a better job of preserving the cell shape on the
+    patch than pure interpolation, though it can simply move the problem into
+    the next layer of cells.
+
+    The user needs only to specify the patches on which this correction is
+    performed:
+
+    \verbatim
+        interpolation patchTransformed (movingPatch1 movingPatch2);
+    \endverbatim
+
+    Note that this method is not defined for scalar displacement fields.
+
+SourceFiles
+    patchTransformedInterpolation.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef patchTransformedInterpolation_H
+#define patchTransformedInterpolation_H
+
+#include "motionInterpolation.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                  Class patchTransformedInterpolation Declaration
+\*---------------------------------------------------------------------------*/
+
+class patchTransformedInterpolation
+:
+    public motionInterpolation
+{
+    // Private data
+
+        //- Patches on which to enforce transformation on adjacent cells
+        const labelList patches_;
+
+
+    // Private member functions
+
+        //- Get patches from the input stream
+        labelList getPatches(Istream& entry) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("patchTransformed");
+
+
+    // Constructors
+
+        //- Construct from an fvMesh and an Istream
+        patchTransformedInterpolation
+        (
+            const fvMesh& mesh,
+            Istream& entry
+        );
+
+
+    //- Destructor
+    virtual ~patchTransformedInterpolation();
+
+
+    // Member Functions
+
+        //- Interpolate the given scalar cell displacement
+        virtual void interpolate
+        (
+            const volScalarField&,
+            pointScalarField&
+        ) const;
+
+        //- Interpolate the given vector cell displacement
+        virtual void interpolate
+        (
+            const volVectorField&,
+            pointVectorField&
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C b/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
index 0891b067bc8472964d7b177754c28ae7ff91fbf5..f58ea3306f14ccdfceb79b5bf07d4ad4d5125dc2 100644
--- a/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
+++ b/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
@@ -295,10 +295,7 @@ bool Foam::displacementMotionSolverMeshMover::move
 }
 
 
-void Foam::displacementMotionSolverMeshMover::movePoints
-(
-    const pointField& p
-)
+void Foam::displacementMotionSolverMeshMover::movePoints(const pointField& p)
 {
     externalDisplacementMeshMover::movePoints(p);
 
diff --git a/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.H b/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.H
index 73acb7a8261266cf6f3ebbe3eb5114d1a79e2d37..dd30d29c0186d691b74fd9d301f2a47b59a6e45b 100644
--- a/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.H
+++ b/src/mesh/autoMesh/autoHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.H
@@ -34,7 +34,7 @@ Description
     solver displacementLaplacian;
     displacementLaplacianCoeffs
     {
-        diffusivity  quadratic inverseDistance 1(wall);
+        diffusivity quadratic inverseDistance 1(wall);
     }
     \endverbatim
 
diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSchemes b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSchemes
index 3d8c60dc1ff32824fa2355a50a281069741bdb47..e6fece1e34e8557e4dd321ee429c5982272f759a 100644
--- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSchemes
+++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSchemes
@@ -41,6 +41,7 @@ divSchemes
 laplacianSchemes
 {
     default         Gauss linear limited corrected 0.333;
+    laplacian(diffusivity,cellDisplacement) Gauss linear corrected;
 }
 
 interpolationSchemes
diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSolution b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSolution
index 627615c534bed3dab1b2f02f3a01f3cbef507916..d8a2ae38706baf154f0e22d9ca1720935f97701b 100644
--- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSolution
+++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/fvSolution
@@ -32,6 +32,12 @@ solvers
         tolerance       1e-07;
         relTol          0.1;
     }
+
+    cellDisplacement
+    {
+        $p_rgh;
+        relTol          0;
+    }
 }
 
 SIMPLE
diff --git a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
index 710ce54571f6f02327826bb2aa36c1c2d905033c..157e4d2f4eb871b8c218c36dd8bed26c528928bd 100644
--- a/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
+++ b/tutorials/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges/system/snappyHexMeshDict
@@ -294,7 +294,7 @@ addLayersControls
     // cannot be above minThickness do not add layer.
     // Relative to undistorted size of cell outside layer.
     // See relativeSizes parameter.
-    minThickness 0.25;
+    minThickness 0.05;
 
     // If points get not extruded do nGrow layers of connected faces that are
     // also not grown. This helps convergence of the layer addition process
@@ -313,30 +313,29 @@ addLayersControls
     // before upon reaching a correct mesh.
     nRelaxIter 5;
 
-    // Number of smoothing iterations of surface normals
-    nSmoothSurfaceNormals 1;
-
-    // Number of smoothing iterations of interior mesh movement direction
-    nSmoothNormals 3;
+    // Stop layer growth on highly warped cells
+    maxFaceThicknessRatio 0.5;
 
     // Smooth layer thickness over surface patches
     nSmoothThickness 10;
 
-    // Stop layer growth on highly warped cells
-    maxFaceThicknessRatio 0.5;
 
-    // Reduce layer growth where ratio thickness to medial
-    // distance is large
-    maxThicknessToMedialRatio 0.3;
 
-    // Angle used to pick up medial axis points
-    // Note: changed(corrected) w.r.t 16x! 90 degrees corresponds to 130 in 16x.
-    minMedianAxisAngle 90;
+    //- Use displacementMotionSolver to shrink mesh
+    meshShrinker displacementMotionSolver;
+
+    //- Use laplacian for shrinking
+    solver displacementLaplacian;
+
+    displacementLaplacianCoeffs
+    {
+        diffusivity quadratic inverseDistance ("two.*" igloo);
+    }
+
 
     // Create buffer region for new layer terminations
     nBufferCellsNoExtrude 0;
 
-
     // Overall max number of layer addition iterations. The mesher will exit
     // if it reaches this number of iterations; possibly with an illegal
     // mesh.