diff --git a/applications/utilities/mesh/manipulation/topoSet/topoSetDict b/applications/utilities/mesh/manipulation/topoSet/topoSetDict
index 31fa348e97..00720d2382 100644
--- a/applications/utilities/mesh/manipulation/topoSet/topoSetDict
+++ b/applications/utilities/mesh/manipulation/topoSet/topoSetDict
@@ -226,6 +226,12 @@ FoamFile
// // (regular expressions allowed)
// }
//
+// // All boundary faces
+// source boundaryToFace;
+// sourceInfo
+// {
+// }
+//
// // All faces of faceZone
// source zoneToFace;
// sourceInfo
@@ -359,6 +365,21 @@ FoamFile
// cellSet c0; // name of cellSet of slave side
// }
//
+// // Select based on surface. Orientation from normals on surface
+// {
+// name fz0;
+// type faceZoneSet;
+// action new;
+// source searchableSurfaceToFaceZone;
+// sourceInfo
+// {
+// surface searchableSphere;
+// centre (0.05 0.05 0.005);
+// radius 0.025;
+// }
+// }
+//
+//
//
// pointZoneSet
// ~~~~~~~~~~~~
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 2621adbc23..b35aff1ab4 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -128,6 +128,7 @@ faceZoneSources = sets/faceZoneSources
$(faceZoneSources)/faceZoneToFaceZone/faceZoneToFaceZone.C
$(faceZoneSources)/setsToFaceZone/setsToFaceZone.C
$(faceZoneSources)/setToFaceZone/setToFaceZone.C
+$(faceZoneSources)/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
cellZoneSources = sets/cellZoneSources
$(cellZoneSources)/setToCellZone/setToCellZone.C
diff --git a/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
new file mode 100644
index 0000000000..b91ec33b82
--- /dev/null
+++ b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
@@ -0,0 +1,211 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "searchableSurfaceToFaceZone.H"
+#include "polyMesh.H"
+#include "faceZoneSet.H"
+#include "searchableSurface.H"
+#include "syncTools.H"
+
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ defineTypeNameAndDebug(searchableSurfaceToFaceZone, 0);
+ addToRunTimeSelectionTable
+ (
+ topoSetSource,
+ searchableSurfaceToFaceZone,
+ word
+ );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::searchableSurfaceToFaceZone::usage_
+(
+ searchableSurfaceToFaceZone::typeName,
+ "\n Usage: searchableSurfaceToFaceZone surface\n\n"
+ " Select all faces whose cell-cell centre vector intersects the surface "
+ "\n"
+);
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+// Construct from dictionary
+Foam::searchableSurfaceToFaceZone::searchableSurfaceToFaceZone
+(
+ const polyMesh& mesh,
+ const dictionary& dict
+)
+:
+ topoSetSource(mesh),
+ surfacePtr_
+ (
+ searchableSurface::New
+ (
+ word(dict.lookup("surface")),
+ mesh.objectRegistry::db(),
+ dict
+ )
+ )
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+Foam::searchableSurfaceToFaceZone::~searchableSurfaceToFaceZone()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+void Foam::searchableSurfaceToFaceZone::applyToSet
+(
+ const topoSetSource::setAction action,
+ topoSet& set
+) const
+{
+ if (!isA(set))
+ {
+ WarningIn
+ (
+ "searchableSurfaceToFaceZone::applyToSet"
+ "(const topoSetSource::setAction"
+ ", topoSet"
+ ) << "Operation only allowed on a faceZoneSet." << endl;
+ }
+ else
+ {
+ faceZoneSet& fzSet = refCast(set);
+
+ // Get cell-cell centre vectors
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ pointField start(mesh_.nFaces());
+ pointField end(mesh_.nFaces());
+
+ const pointField& cc = mesh_.cellCentres();
+
+ // Internal faces
+ for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
+ {
+ start[faceI] = cc[mesh_.faceOwner()[faceI]];
+ end[faceI] = cc[mesh_.faceNeighbour()[faceI]];
+ }
+
+ // Boundary faces
+ vectorField nbrCellCentres;
+ syncTools::swapBoundaryCellList(mesh_, cc, nbrCellCentres);
+
+ const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
+
+ forAll(pbm, patchI)
+ {
+ const polyPatch& pp = pbm[patchI];
+
+ if (pp.coupled())
+ {
+ forAll(pp, i)
+ {
+ label faceI = pp.start()+i;
+ start[faceI] = cc[mesh_.faceOwner()[faceI]];
+ end[faceI] = nbrCellCentres[faceI-mesh_.nInternalFaces()];
+ }
+ }
+ else
+ {
+ forAll(pp, i)
+ {
+ label faceI = pp.start()+i;
+ start[faceI] = cc[mesh_.faceOwner()[faceI]];
+ end[faceI] = mesh_.faceCentres()[faceI];
+ }
+ }
+ }
+
+
+ // Do all intersection tests
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ List hits;
+ surfacePtr_().findLine(start, end, hits);
+ pointField normals;
+ surfacePtr_().getNormal(hits, normals);
+
+
+ // Select intersected faces
+ // ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD))
+ {
+ Info<< " Adding all faces from surface "
+ << surfacePtr_().name() << " ..." << endl;
+
+ DynamicList