diff --git a/etc/controlDict b/etc/controlDict
index 973056f9de..5b1ee397f0 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -307,6 +307,7 @@ DebugSwitches
autoRefineDriver 0;
autoSnapDriver 0;
bC11H10 0;
+ backgroundMeshDecomposition 1;
backward 0;
basePatch 0;
basicKinematicCloud 0;
diff --git a/src/mesh/conformalVoronoiMesh/Make/files b/src/mesh/conformalVoronoiMesh/Make/files
index c013d4685b..21757ef3fa 100644
--- a/src/mesh/conformalVoronoiMesh/Make/files
+++ b/src/mesh/conformalVoronoiMesh/Make/files
@@ -10,6 +10,8 @@ cvControls/cvControls.C
conformationSurfaces/conformationSurfaces.C
+backgroundMeshDecomposition/backgroundMeshDecomposition.C
+
cellSizeControlSurfaces/cellSizeControlSurfaces.C
cellSiseFunctions = cellSizeControlSurfaces/cellSizeFunction
diff --git a/src/mesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C b/src/mesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
new file mode 100644
index 0000000000..4fda7ff5a9
--- /dev/null
+++ b/src/mesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C
@@ -0,0 +1,698 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+License
+ This file is part of OpenFOAM.
+
+ OpenFOAM is free software: you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with OpenFOAM. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "backgroundMeshDecomposition.H"
+#include "zeroGradientFvPatchFields.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+defineTypeNameAndDebug(backgroundMeshDecomposition, 0);
+
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void Foam::backgroundMeshDecomposition::initialRefinement()
+{
+ //Read decomposePar dictionary
+ IOdictionary decomposeDict
+ (
+ IOobject
+ (
+ "decomposeParDict",
+ cvMesh_.time().system(),
+ cvMesh_.time(),
+ IOobject::MUST_READ_IF_MODIFIED,
+ IOobject::NO_WRITE
+ )
+ );
+
+ scalar mergeDist = 1e-6*mesh_.bounds().mag();
+
+ volScalarField cellWeights
+ (
+ IOobject
+ (
+ "cellWeights",
+ mesh_.time().timeName(),
+ mesh_,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh_,
+ dimensionedScalar("one", dimless, 1.0),
+ zeroGradientFvPatchScalarField::typeName
+ );
+
+ const conformationSurfaces& geometry = cvMesh_.geometryToConformTo();
+
+ // Decomposition
+ autoPtr decomposerPtr
+ (
+ decompositionMethod::New(decomposeDict)
+ );
+
+ decompositionMethod& decomposer = decomposerPtr();
+
+ if (!decomposer.parallelAware())
+ {
+ FatalErrorIn
+ (
+ "void Foam::backgroundMeshDecomposition::initialRefinement() const"
+ )
+ << "You have selected decomposition method "
+ << decomposer.typeName
+ << " which is not parallel aware." << endl
+ << exit(FatalError);
+ }
+
+ hexRef8 meshCutter
+ (
+ mesh_,
+ labelList(mesh_.nCells(), 0),
+ labelList(mesh_.nPoints(), 0)
+ );
+
+ // For each cell in the mesh has it been determined if it is fully
+ // inside, outside, or overlaps the surface
+ labelList volumeStatus
+ (
+ mesh_.nCells(),
+ searchableSurface::UNKNOWN
+ );
+
+ // Surface refinement
+ {
+ while (true)
+ {
+ // Determine/update the status of each cell
+ forAll(volumeStatus, cellI)
+ {
+ if (volumeStatus[cellI] == searchableSurface::UNKNOWN)
+ {
+ treeBoundBox cellBb
+ (
+ mesh_.cells()[cellI].points
+ (
+ mesh_.faces(),
+ mesh_.points()
+ )
+ );
+
+ if (geometry.overlaps(cellBb))
+ {
+ volumeStatus[cellI] = searchableSurface::MIXED;
+ }
+ else if (geometry.inside(cellBb.midpoint()))
+ {
+ volumeStatus[cellI] = searchableSurface::INSIDE;
+ }
+ else
+ {
+ volumeStatus[cellI] =
+ searchableSurface::OUTSIDE;
+ }
+ }
+ }
+
+ {
+ labelList refCells = selectRefinementCells
+ (
+ meshCutter,
+ volumeStatus,
+ cellWeights
+ );
+
+ // Maintain 2:1 ratio
+ labelList newCellsToRefine
+ (
+ meshCutter.consistentRefinement
+ (
+ refCells,
+ true // extend set
+ )
+ );
+
+ forAll(newCellsToRefine, nCTRI)
+ {
+ label cellI = newCellsToRefine[nCTRI];
+
+ if (volumeStatus[cellI] == searchableSurface::MIXED)
+ {
+ volumeStatus[cellI] = searchableSurface::UNKNOWN;
+ }
+
+ cellWeights.internalField()[cellI] = max
+ (
+ 1.0,
+ cellWeights.internalField()[cellI]/8.0
+ );
+ }
+
+
+ if
+ (
+ returnReduce(newCellsToRefine.size(), sumOp