diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/files b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/files
new file mode 100644
index 0000000000..58406b931a
--- /dev/null
+++ b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/files
@@ -0,0 +1,3 @@
+cvMeshBackgroundMesh.C
+
+EXE = $(FOAM_APPBIN)/cvMeshBackgroundMesh
diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/options b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/options
new file mode 100644
index 0000000000..0e2d0c9f0a
--- /dev/null
+++ b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/Make/options
@@ -0,0 +1,31 @@
+/*
+EXE_DEBUG = -DFULLDEBUG -g -O0
+EXE_FROUNDING_MATH = -frounding-math
+EXE_NDEBUG = -DNDEBUG
+*/
+
+include $(GENERAL_RULES)/CGAL
+
+EXE_INC = \
+ ${EXE_FROUNDING_MATH} \
+ ${EXE_NDEBUG} \
+ ${CGAL_INC} \
+ -I../conformalVoronoiMesh/lnInclude \
+ -I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
+ -I$(LIB_SRC)/edgeMesh/lnInclude \
+ -I$(LIB_SRC)/sampling/lnInclude \
+ -I$(LIB_SRC)/triSurface/lnInclude \
+ -I$(LIB_SRC)/finiteVolume/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude \
+ -I$(LIB_SRC)/dynamicMesh/lnInclude
+
+EXE_LIBS = \
+ $(CGAL_LIBS) \
+ -lconformalVoronoiMesh \
+ -ldecompositionMethods /* -L$(FOAM_LIBBIN)/dummy -lscotchDecomp */ \
+ -ledgeMesh \
+ -ltriSurface \
+ -lmeshTools \
+ -ldynamicMesh \
+ -lsampling \
+ -lfiniteVolume
diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/cvMeshBackgroundMesh.C b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/cvMeshBackgroundMesh.C
new file mode 100644
index 0000000000..c2642366a9
--- /dev/null
+++ b/applications/utilities/mesh/generation/cvMesh/cvMeshBackgroundMesh/cvMeshBackgroundMesh.C
@@ -0,0 +1,920 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2012 OpenFOAM Foundation
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+Application
+ cvMeshBackGroundMesh
+
+Description
+ Writes out background mesh as constructed by cvMesh and constructs
+ distanceSurface.
+
+\*---------------------------------------------------------------------------*/
+
+#include "PatchTools.H"
+#include "argList.H"
+#include "Time.H"
+#include "triSurface.H"
+#include "searchableSurfaces.H"
+#include "conformationSurfaces.H"
+#include "cellSizeControlSurfaces.H"
+#include "backgroundMeshDecomposition.H"
+#include "cellShape.H"
+#include "cellModeller.H"
+#include "DynamicField.H"
+#include "isoSurfaceCell.H"
+#include "vtkSurfaceWriter.H"
+#include "syncTools.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Tolerance (as fraction of the bounding box). Needs to be fairly lax since
+// usually meshes get written with limited precision (6 digits)
+static const scalar defaultMergeTol = 1E-6;
+
+// Get merging distance when matching face centres
+scalar getMergeDistance
+(
+ const argList& args,
+ const Time& runTime,
+ const boundBox& bb
+)
+{
+ scalar mergeTol = defaultMergeTol;
+ args.optionReadIfPresent("mergeTol", mergeTol);
+
+ scalar writeTol =
+ Foam::pow(scalar(10.0), -scalar(IOstream::defaultPrecision()));
+
+ Info<< "Merge tolerance : " << mergeTol << nl
+ << "Write tolerance : " << writeTol << endl;
+
+ if (runTime.writeFormat() == IOstream::ASCII && mergeTol < writeTol)
+ {
+ FatalErrorIn("getMergeDistance")
+ << "Your current settings specify ASCII writing with "
+ << IOstream::defaultPrecision() << " digits precision." << endl
+ << "Your merging tolerance (" << mergeTol << ") is finer than this."
+ << endl
+ << "Please change your writeFormat to binary"
+ << " or increase the writePrecision" << endl
+ << "or adjust the merge tolerance (-mergeTol)."
+ << exit(FatalError);
+ }
+
+ scalar mergeDist = mergeTol * bb.mag();
+
+ Info<< "Overall meshes bounding box : " << bb << nl
+ << "Relative tolerance : " << mergeTol << nl
+ << "Absolute matching distance : " << mergeDist << nl
+ << endl;
+
+ return mergeDist;
+}
+
+
+void printMeshData(const polyMesh& mesh)
+{
+ // Collect all data on master
+
+ globalIndex globalCells(mesh.nCells());
+ labelListList patchNeiProcNo(Pstream::nProcs());
+ labelListList patchSize(Pstream::nProcs());
+ const labelList& pPatches = mesh.globalData().processorPatches();
+ patchNeiProcNo[Pstream::myProcNo()].setSize(pPatches.size());
+ patchSize[Pstream::myProcNo()].setSize(pPatches.size());
+ forAll(pPatches, i)
+ {
+ const processorPolyPatch& ppp = refCast
+ (
+ mesh.boundaryMesh()[pPatches[i]]
+ );
+ patchNeiProcNo[Pstream::myProcNo()][i] = ppp.neighbProcNo();
+ patchSize[Pstream::myProcNo()][i] = ppp.size();
+ }
+ Pstream::gatherList(patchNeiProcNo);
+ Pstream::gatherList(patchSize);
+
+
+ // Print stats
+
+ globalIndex globalBoundaryFaces(mesh.nFaces()-mesh.nInternalFaces());
+
+ label maxProcCells = 0;
+ label totProcFaces = 0;
+ label maxProcPatches = 0;
+ label totProcPatches = 0;
+ label maxProcFaces = 0;
+
+ for (label procI = 0; procI < Pstream::nProcs(); procI++)
+ {
+ Info<< endl
+ << "Processor " << procI << nl
+ << " Number of cells = " << globalCells.localSize(procI)
+ << endl;
+
+ label nProcFaces = 0;
+
+ const labelList& nei = patchNeiProcNo[procI];
+
+ forAll(patchNeiProcNo[procI], i)
+ {
+ Info<< " Number of faces shared with processor "
+ << patchNeiProcNo[procI][i] << " = " << patchSize[procI][i]
+ << endl;
+
+ nProcFaces += patchSize[procI][i];
+ }
+
+ Info<< " Number of processor patches = " << nei.size() << nl
+ << " Number of processor faces = " << nProcFaces << nl
+ << " Number of boundary faces = "
+ << globalBoundaryFaces.localSize(procI) << endl;
+
+ maxProcCells = max(maxProcCells, globalCells.localSize(procI));
+ totProcFaces += nProcFaces;
+ totProcPatches += nei.size();
+ maxProcPatches = max(maxProcPatches, nei.size());
+ maxProcFaces = max(maxProcFaces, nProcFaces);
+ }
+
+ // Stats
+
+ scalar avgProcCells = scalar(globalCells.size())/Pstream::nProcs();
+ scalar avgProcPatches = scalar(totProcPatches)/Pstream::nProcs();
+ scalar avgProcFaces = scalar(totProcFaces)/Pstream::nProcs();
+
+ // In case of all faces on one processor. Just to avoid division by 0.
+ if (totProcPatches == 0)
+ {
+ avgProcPatches = 1;
+ }
+ if (totProcFaces == 0)
+ {
+ avgProcFaces = 1;
+ }
+
+ Info<< nl
+ << "Number of processor faces = " << totProcFaces/2 << nl
+ << "Max number of cells = " << maxProcCells
+ << " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
+ << "% above average " << avgProcCells << ")" << nl
+ << "Max number of processor patches = " << maxProcPatches
+ << " (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches
+ << "% above average " << avgProcPatches << ")" << nl
+ << "Max number of faces between processors = " << maxProcFaces
+ << " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
+ << "% above average " << avgProcFaces << ")" << nl
+ << endl;
+}
+
+
+// Return cellID
+label cellLabel
+(
+ const Vector