diff --git a/applications/utilities/preProcessing/setFields/setFields.C b/applications/utilities/preProcessing/setFields/setFields.C
index 554f8e1ac9c558553b86751a07a78cee9f6b3828..0e551df0e48efe974508f63d76fd69cb99427f82 100644
--- a/applications/utilities/preProcessing/setFields/setFields.C
+++ b/applications/utilities/preProcessing/setFields/setFields.C
@@ -157,6 +157,12 @@ public:
             selectedCells_(selectedCells)
         {}
 
+        iNew(const fvMesh& mesh, labelList&& selectedCells)
+        :
+            mesh_(mesh),
+            selectedCells_(std::move(selectedCells))
+        {}
+
         autoPtr<setCellField> operator()(Istream& fieldValues) const
         {
             word fieldType(fieldValues);
@@ -348,6 +354,12 @@ public:
             selectedFaces_(selectedFaces)
         {}
 
+        iNew(const fvMesh& mesh, labelList&& selectedFaces)
+        :
+            mesh_(mesh),
+            selectedFaces_(std::move(selectedFaces))
+        {}
+
         autoPtr<setFaceField> operator()(Istream& fieldValues) const
         {
             word fieldType(fieldValues);
@@ -438,7 +450,7 @@ int main(int argc, char *argv[])
             PtrList<setCellField> fieldValues
             (
                 region.dict().lookup("fieldValues"),
-                setCellField::iNew(mesh, selectedCellSet.toc())
+                setCellField::iNew(mesh, selectedCellSet.sortedToc())
             );
         }
         else if (source().setType() == topoSetSource::FACESETSOURCE)
@@ -459,7 +471,7 @@ int main(int argc, char *argv[])
             PtrList<setFaceField> fieldValues
             (
                 region.dict().lookup("fieldValues"),
-                setFaceField::iNew(mesh, selectedFaceSet.toc())
+                setFaceField::iNew(mesh, selectedFaceSet.sortedToc())
             );
         }
     }
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 956a714d9476187347165cf20b3ff56d1d16ad7f..cf53f0e9268186df2c64ee81fa206d68c03436ad 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -136,12 +136,17 @@ searchableSurfaces/triSurfaceMesh/triSurfaceMesh.C
 topoSets = sets/topoSets
 $(topoSets)/cellBitSet.C
 $(topoSets)/cellSet.C
-$(topoSets)/topoSet.C
-$(topoSets)/faceSet.C
-$(topoSets)/pointSet.C
 $(topoSets)/cellZoneSet.C
+$(topoSets)/faceBitSet.C
+$(topoSets)/faceBoolSet.C
+$(topoSets)/faceSet.C
 $(topoSets)/faceZoneSet.C
+$(topoSets)/pointBitSet.C
+$(topoSets)/pointSet.C
 $(topoSets)/pointZoneSet.C
+$(topoSets)/topoBoolSet.C
+$(topoSets)/topoBitSet.C
+$(topoSets)/topoSet.C
 
 sets/topoSetSource/topoSetSource.C
 
@@ -180,16 +185,21 @@ $(faceSources)/normalToFace/normalToFace.C
 $(faceSources)/patchToFace/patchToFace.C
 $(faceSources)/pointToFace/pointToFace.C
 $(faceSources)/regionToFace/regionToFace.C
+$(faceSources)/searchableSurfaceToFace/searchableSurfaceToFace.C
+$(faceSources)/sphereToFace/sphereToFace.C
 $(faceSources)/zoneToFace/zoneToFace.C
 
 pointSources = sets/pointSources
 $(pointSources)/topoSetPointSource/topoSetPointSource.C
 $(pointSources)/boxToPoint/boxToPoint.C
 $(pointSources)/cellToPoint/cellToPoint.C
+$(pointSources)/cylinderToPoint/cylinderToPoint.C
 $(pointSources)/faceToPoint/faceToPoint.C
 $(pointSources)/labelToPoint/labelToPoint.C
 $(pointSources)/nearestToPoint/nearestToPoint.C
 $(pointSources)/pointToPoint/pointToPoint.C
+$(pointSources)/searchableSurfaceToPoint/searchableSurfaceToPoint.C
+$(pointSources)/sphereToPoint/sphereToPoint.C
 $(pointSources)/surfaceToPoint/surfaceToPoint.C
 $(pointSources)/zoneToPoint/zoneToPoint.C
 
diff --git a/src/meshTools/sets/cellSources/boxToCell/boxToCell.C b/src/meshTools/sets/cellSources/boxToCell/boxToCell.C
index d3efca3501933229c8685cf869daa5105510b879..80e1c66df374a549ef98bc8570a56bc03f9efc5d 100644
--- a/src/meshTools/sets/cellSources/boxToCell/boxToCell.C
+++ b/src/meshTools/sets/cellSources/boxToCell/boxToCell.C
@@ -67,13 +67,13 @@ void Foam::boxToCell::combine(topoSet& set, const bool add) const
 {
     const pointField& ctrs = mesh_.cellCentres();
 
-    forAll(ctrs, celli)
+    forAll(ctrs, elemi)
     {
         for (const auto& bb : bbs_)
         {
-            if (bb.contains(ctrs[celli]))
+            if (bb.contains(ctrs[elemi]))
             {
-                addOrDelete(set, celli, add);
+                addOrDelete(set, elemi, add);
                 break;
             }
         }
diff --git a/src/meshTools/sets/cellSources/boxToCell/boxToCell.H b/src/meshTools/sets/cellSources/boxToCell/boxToCell.H
index 6e0520cb185972f55b14b40fd8c92669226b645d..514cbfa266ef7a9f625594072b872ad6c7b16abc 100644
--- a/src/meshTools/sets/cellSources/boxToCell/boxToCell.H
+++ b/src/meshTools/sets/cellSources/boxToCell/boxToCell.H
@@ -37,8 +37,8 @@ Description
     \endtable
 
 Note
-    In the order of highest to lowest precedence, must specify "boxes",
-    "box" or a "min/max" pair (compatibility with searchable box).
+    Must specify "boxes", "box" or a "min/max" pair
+    (compatibility with searchable box) - highest to lowest precedence.
 
 SourceFiles
     boxToCell.C
diff --git a/src/meshTools/sets/cellSources/cellToCell/cellToCell.C b/src/meshTools/sets/cellSources/cellToCell/cellToCell.C
index f061205c8a35a5954330c976f90433c2b5fd62d2..20d11e6732e589114bb678452893018e29b9bfca 100644
--- a/src/meshTools/sets/cellSources/cellToCell/cellToCell.C
+++ b/src/meshTools/sets/cellSources/cellToCell/cellToCell.C
@@ -57,7 +57,7 @@ Foam::cellToCell::cellToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(setName)
+    names_(one(), setName)
 {}
 
 
@@ -67,12 +67,16 @@ Foam::cellToCell::cellToCell
     const dictionary& dict
 )
 :
-    cellToCell
-    (
-        mesh,
-        dict.get<word>("set")
-    )
-{}
+    topoSetCellSource(mesh),
+    names_()
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::cellToCell::cellToCell
@@ -82,7 +86,7 @@ Foam::cellToCell::cellToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(checkIs(is))
+    names_(one(), word(checkIs(is)))
 {}
 
 
@@ -98,27 +102,31 @@ void Foam::cellToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding all elements of cellSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding all elements of cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        cellSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            cellSet loadedSet(mesh_, setName);
 
-        set.addSet(loadedSet);
+            set.addSet(loadedSet);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing all elements of cellSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing all elements of cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        cellSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            cellSet loadedSet(mesh_, setName);
 
-        set.subtractSet(loadedSet);
+            set.subtractSet(loadedSet);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/cellSources/cellToCell/cellToCell.H b/src/meshTools/sets/cellSources/cellToCell/cellToCell.H
index 2b619f12f0d4fd2aaaca14249e9d09fc1bbd6a89..2719090d69e3885371dfa175e4ace8d3359b81c3 100644
--- a/src/meshTools/sets/cellSources/cellToCell/cellToCell.H
+++ b/src/meshTools/sets/cellSources/cellToCell/cellToCell.H
@@ -29,10 +29,14 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        set         | The cell set name                 | yes   |
+        Property    | Description                          | Required | Default
+        sets        | The input cellSet names              | possibly |
+        set         | The input cellSet name               | possibly |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     cellToCell.C
 
@@ -61,8 +65,9 @@ class cellToCell
         //- Add usage string
         static addToUsageTable usage_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
+
 
 public:
 
diff --git a/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.C b/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.C
index 6421182264f048fe57cf39ff7b8c1a872aa10726..72fff8eb2ffdf4f94da786b2b02843a96280227d 100644
--- a/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.C
+++ b/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.C
@@ -76,16 +76,18 @@ Foam::topoSetSource::addToUsageTable Foam::cylinderAnnulusToCell::usage_
 
 void Foam::cylinderAnnulusToCell::combine(topoSet& set, const bool add) const
 {
+    const pointField& ctrs = mesh_.cellCentres();
+
     const vector axis = (point2_ - point1_);
-    const scalar orad2 = sqr(outerRadius_);
-    const scalar irad2 = sqr(innerRadius_);
     const scalar magAxis2 = magSqr(axis);
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
 
-    const pointField& ctrs = mesh_.cellCentres();
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
 
-    forAll(ctrs, celli)
+    forAll(ctrs, elemi)
     {
-        const vector d = ctrs[celli] - point1_;
+        const vector d = ctrs[elemi] - point1_;
         const scalar magD = d & axis;
 
         if ((magD > 0) && (magD < magAxis2))
@@ -93,7 +95,7 @@ void Foam::cylinderAnnulusToCell::combine(topoSet& set, const bool add) const
             const scalar d2 = (d & d) - sqr(magD)/magAxis2;
             if ((d2 < orad2) && (d2 > irad2))
             {
-                addOrDelete(set, celli, add);
+                addOrDelete(set, elemi, add);
             }
         }
     }
@@ -107,14 +109,14 @@ Foam::cylinderAnnulusToCell::cylinderAnnulusToCell
     const polyMesh& mesh,
     const point& point1,
     const point& point2,
-    const scalar outerRadius,
+    const scalar radius,
     const scalar innerRadius
 )
 :
     topoSetCellSource(mesh),
     point1_(point1),
     point2_(point2),
-    outerRadius_(outerRadius),
+    radius_(radius),
     innerRadius_(innerRadius)
 {}
 
@@ -145,7 +147,7 @@ Foam::cylinderAnnulusToCell::cylinderAnnulusToCell
     topoSetCellSource(mesh),
     point1_(checkIs(is)),
     point2_(checkIs(is)),
-    outerRadius_(readScalar(checkIs(is))),
+    radius_(readScalar(checkIs(is))),
     innerRadius_(readScalar(checkIs(is)))
 {}
 
@@ -164,7 +166,7 @@ void Foam::cylinderAnnulusToCell::applyToSet
         {
             Info<< "    Adding cells with centre within cylinder annulus,"
                 << " with p1 = " << point1_ << ", p2 = " << point2_
-                << ", radius = " << outerRadius_
+                << ", radius = " << radius_
                 << ", inner radius = " << innerRadius_
                 << endl;
         }
@@ -177,7 +179,7 @@ void Foam::cylinderAnnulusToCell::applyToSet
         {
             Info<< "    Removing cells with centre within cylinder annulus,"
                 << " with p1 = " << point1_ << ", p2 = " << point2_
-                << ", radius = " << outerRadius_
+                << ", radius = " << radius_
                 << ", inner radius = " << innerRadius_
                 << endl;
         }
diff --git a/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.H b/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.H
index 9c02f64dfd615b9f25fe41be6000eaf8ebcd218d..70a142ff578bb37bc4d847ac4f19d3d726290079 100644
--- a/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.H
+++ b/src/meshTools/sets/cellSources/cylinderAnnulusToCell/cylinderAnnulusToCell.H
@@ -31,10 +31,10 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        p1          | coordinate of endpoint            | yes   |
-        p2          | coordinate of endpoint            | yes   |
-        outerRadius | cylinder outer radius             | yes   |
-        innerRadius | cylinder inner radius             | yes   |
+        p1          | Coordinate of endpoint            | yes   |
+        p2          | Coordinate of endpoint            | yes   |
+        outerRadius | Cylinder outer radius             | yes   |
+        innerRadius | Cylinder inner radius             | yes   |
     \endtable
 
 SourceFiles
@@ -72,10 +72,10 @@ class cylinderAnnulusToCell
         //- Second point on cylinder axis
         point point2_;
 
-        //- Outer Radius
-        scalar outerRadius_;
+        //- Outer radius
+        scalar radius_;
 
-        //- Inner Radius
+        //- Inner radius
         scalar innerRadius_;
 
 
@@ -98,7 +98,7 @@ public:
             const polyMesh& mesh,
             const point& point1,
             const point& point2,
-            const scalar outerRadius,
+            const scalar radius,
             const scalar innerRadius = 0
         );
 
diff --git a/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.C b/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.C
index 9eda86e0f433fd26cc2f1bceb230808bae1214e2..ec66c9f88592053bbbe3a2413c87abfe7d893781 100644
--- a/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.C
+++ b/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.C
@@ -65,23 +65,26 @@ Foam::topoSetSource::addToUsageTable Foam::cylinderToCell::usage_
 
 void Foam::cylinderToCell::combine(topoSet& set, const bool add) const
 {
+    const pointField& ctrs = mesh_.cellCentres();
+
     const vector axis = (point2_ - point1_);
-    const scalar rad2 = sqr(radius_);
     const scalar magAxis2 = magSqr(axis);
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
 
-    const pointField& ctrs = mesh_.cellCentres();
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
 
-    forAll(ctrs, celli)
+    forAll(ctrs, elemi)
     {
-        const vector d = ctrs[celli] - point1_;
+        const vector d = ctrs[elemi] - point1_;
         const scalar magD = d & axis;
 
         if ((magD > 0) && (magD < magAxis2))
         {
             const scalar d2 = (d & d) - sqr(magD)/magAxis2;
-            if (d2 < rad2)
+            if ((d2 < orad2) && (d2 > irad2))
             {
-                addOrDelete(set, celli, add);
+                addOrDelete(set, elemi, add);
             }
         }
     }
@@ -95,13 +98,15 @@ Foam::cylinderToCell::cylinderToCell
     const polyMesh& mesh,
     const point& point1,
     const point& point2,
-    const scalar radius
+    const scalar radius,
+    const scalar innerRadius
 )
 :
     topoSetCellSource(mesh),
     point1_(point1),
     point2_(point2),
-    radius_(radius)
+    radius_(radius),
+    innerRadius_(innerRadius)
 {}
 
 
@@ -116,7 +121,8 @@ Foam::cylinderToCell::cylinderToCell
         mesh,
         dict.get<point>("p1"),
         dict.get<point>("p2"),
-        dict.get<scalar>("radius")
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
     )
 {}
 
@@ -130,7 +136,8 @@ Foam::cylinderToCell::cylinderToCell
     topoSetCellSource(mesh),
     point1_(checkIs(is)),
     point2_(checkIs(is)),
-    radius_(readScalar(checkIs(is)))
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
 {}
 
 
@@ -146,9 +153,16 @@ void Foam::cylinderToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding cells with centre within cylinder, with p1 = "
-                << point1_ << ", p2 = " << point2_ << ", radius = " << radius_
-                << endl;
+            Info<< "    Adding cells with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, true);
@@ -157,9 +171,16 @@ void Foam::cylinderToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Removing cells with centre within cylinder, with p1 = "
-                << point1_ << ", p2 = " << point2_ << ", radius = " << radius_
-                << endl;
+            Info<< "    Removing cells with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, false);
diff --git a/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.H b/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.H
index f87bd7dbdce278932a71dee373055a1e21abf25b..edfe62a7e7a4d89b23145708909a1fadf6dc6b7f 100644
--- a/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.H
+++ b/src/meshTools/sets/cellSources/cylinderToCell/cylinderToCell.H
@@ -29,10 +29,11 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        p1          | coordinate of endpoint            | yes   |
-        p2          | coordinate of endpoint            | yes   |
-        radius      | cylinder radius                   | yes   |
+        Property    | Description                       | Required | Default
+        p1          | Coordinate of endpoint            | yes   |
+        p2          | Coordinate of endpoint            | yes   |
+        radius      | Cylinder (outer) radius           | yes   |
+        innerRadius | Cylinder inner radius             | no    | 0
     \endtable
 
 SourceFiles
@@ -70,9 +71,12 @@ class cylinderToCell
         //- Second point on cylinder axis
         point point2_;
 
-        //- Radius
+        //- Outer radius
         scalar radius_;
 
+        //- Inner radius
+        scalar innerRadius_;
+
 
     // Private Member Functions
 
@@ -93,7 +97,8 @@ public:
             const polyMesh& mesh,
             const point& point1,
             const point& point2,
-            const scalar radius
+            const scalar radius,
+            const scalar innerRadius = 0
         );
 
         //- Construct from dictionary
diff --git a/src/meshTools/sets/cellSources/faceToCell/faceToCell.C b/src/meshTools/sets/cellSources/faceToCell/faceToCell.C
index 508b187dc8908b028e05764293d2d087639c7bca..d423639a2f19d960672d812721c73cce949f813f 100644
--- a/src/meshTools/sets/cellSources/faceToCell/faceToCell.C
+++ b/src/meshTools/sets/cellSources/faceToCell/faceToCell.C
@@ -63,10 +63,15 @@ Foam::faceToCell::faceActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::faceToCell::combine(topoSet& set, const bool add) const
+void Foam::faceToCell::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    faceSet loadedSet(mesh_, setName_);
+    faceSet loadedSet(mesh_, setName);
 
     const labelHashSet& faceLabels = loadedSet;
 
@@ -136,7 +141,7 @@ Foam::faceToCell::faceToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -147,13 +152,17 @@ Foam::faceToCell::faceToCell
     const dictionary& dict
 )
 :
-    faceToCell
-    (
-        mesh,
-        dict.get<word>("set"),
-        faceActionNames_.get("option", dict)
-    )
-{}
+    topoSetCellSource(mesh),
+    names_(),
+    option_(faceActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::faceToCell::faceToCell
@@ -163,7 +172,7 @@ Foam::faceToCell::faceToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(faceActionNames_.read(checkIs(is)))
 {}
 
@@ -180,21 +189,27 @@ void Foam::faceToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding cells according to faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding cells according to faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing cells according to faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing cells according to faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/cellSources/faceToCell/faceToCell.H b/src/meshTools/sets/cellSources/faceToCell/faceToCell.H
index 64e85b381764113ba822ffc6523cb370c57202a3..828f8ced46fbf841f9f3352df703c5ec8096cda6 100644
--- a/src/meshTools/sets/cellSources/faceToCell/faceToCell.H
+++ b/src/meshTools/sets/cellSources/faceToCell/faceToCell.H
@@ -29,11 +29,15 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        set         | The face set name to use          | yes   |
+        Property    | Description                           | Required | Default
+        sets        | The faceSet names to use              | possibly |
+        set         | The faceSet name to use               | possibly |
         option      | Selection type (all/any/owner/neighbour)  | yes   |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     faceToCell.C
 
@@ -76,8 +80,8 @@ private:
         //- Add usage string
         static addToUsageTable usage_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         faceAction option_;
@@ -86,7 +90,7 @@ private:
     // Private Member Functions
 
         //- Depending on face to cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/cellSources/faceZoneToCell/faceZoneToCell.H b/src/meshTools/sets/cellSources/faceZoneToCell/faceZoneToCell.H
index e0821982718371e5d5f7c548b37dc47d0c8a5806..4964a8eab00a3e0b8fffaa671c75a7e119884b58 100644
--- a/src/meshTools/sets/cellSources/faceZoneToCell/faceZoneToCell.H
+++ b/src/meshTools/sets/cellSources/faceZoneToCell/faceZoneToCell.H
@@ -31,13 +31,13 @@ Description
     \table
         Property    | Description                           | Required | Default
         option      | Selection type (master / slave)       | yes   |
-        zone        | The face zone name or regex           | possibly |
         zones       | The face zone names or regexs         | possibly |
+        zone        | The face zone name or regex           | possibly |
         name        | Older specification for 'zone'        | no    |
     \endtable
 
 Note
-    Selection of multiple zones has precedence.
+    Must specify "zones", "zone" or "name" (highest to lowest precedence).
 
 SourceFiles
     faceZoneToCell.C
diff --git a/src/meshTools/sets/cellSources/pointToCell/pointToCell.C b/src/meshTools/sets/cellSources/pointToCell/pointToCell.C
index 8aa5b11704cc3aac9a1624a2c046b8fb7b4f448c..068fcd9e5a7836102f03ad6ebdc67d074556b2b1 100644
--- a/src/meshTools/sets/cellSources/pointToCell/pointToCell.C
+++ b/src/meshTools/sets/cellSources/pointToCell/pointToCell.C
@@ -61,10 +61,15 @@ Foam::pointToCell::pointActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::pointToCell::combine(topoSet& set, const bool add) const
+void Foam::pointToCell::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    pointSet loadedSet(mesh_, setName_);
+    pointSet loadedSet(mesh_, setName);
 
     const labelHashSet& pointLabels = loadedSet;
 
@@ -119,7 +124,7 @@ Foam::pointToCell::pointToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -130,13 +135,17 @@ Foam::pointToCell::pointToCell
     const dictionary& dict
 )
 :
-    pointToCell
-    (
-        mesh,
-        dict.get<word>("set"),
-        pointActionNames_.get("option", dict)
-    )
-{}
+    topoSetCellSource(mesh),
+    names_(),
+    option_(pointActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::pointToCell::pointToCell
@@ -146,7 +155,7 @@ Foam::pointToCell::pointToCell
 )
 :
     topoSetCellSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(pointActionNames_.read(checkIs(is)))
 {}
 
@@ -163,21 +172,27 @@ void Foam::pointToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding cells according to pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding cells according to pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing cells according to pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing cells according to pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/cellSources/pointToCell/pointToCell.H b/src/meshTools/sets/cellSources/pointToCell/pointToCell.H
index c61f8997af37655b1de6f70fc95feba0969cc2ca..a499647b47a10bc5e8452e6bb17ee9f0d121ee1b 100644
--- a/src/meshTools/sets/cellSources/pointToCell/pointToCell.H
+++ b/src/meshTools/sets/cellSources/pointToCell/pointToCell.H
@@ -30,10 +30,14 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        set         | The point set name                | yes   |
-        option      | Selection type (any / edge)       | yes   |
+        sets        | The pointSet names to use         | possibly |
+        set         | The pointSet name to use          | possibly |
+        option      | Selection type (any/edge)         | yes   |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     pointToCell.C
 
@@ -74,8 +78,8 @@ private:
 
         static const Enum<pointAction> pointActionNames_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         pointAction option_;
@@ -84,7 +88,7 @@ private:
     // Private Member Functions
 
         //- Depending on point-to-cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.C b/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.C
index 5a5e529fdb6b81463e7e80768348337acc2607f4..7b2138a508658361ca290f503281f77db5a8b540 100644
--- a/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.C
+++ b/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.C
@@ -47,7 +47,7 @@ namespace Foam
     );
     addNamedToRunTimeSelectionTable
     (
-        topoSetSource,
+        topoSetCellSource,
         searchableSurfaceToCell,
         word,
         surface
@@ -64,6 +64,25 @@ Foam::topoSetSource::addToUsageTable Foam::searchableSurfaceToCell::usage_
 );
 
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::word Foam::searchableSurfaceToCell::getSurfaceName
+(
+    const dictionary& dict,
+    const word& defaultName
+)
+{
+    // Unfortunately cannot get a good default name from the dictionary name.
+    // It could be
+    //     sourceInfo { .. }
+    // But even with something like
+    //     mySurf.stl { .. }
+    // The dictName() method will only return the "stl" ending.
+
+    return dict.lookupOrDefault<word>("surfaceName", defaultName);
+}
+
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 void Foam::searchableSurfaceToCell::combine(topoSet& set, const bool add) const
@@ -72,21 +91,20 @@ void Foam::searchableSurfaceToCell::combine(topoSet& set, const bool add) const
     {
         return;
     }
+    const pointField& ctrs = mesh_.cellCentres();
     const searchableSurface& s = *surf_;
 
-    // Add cells within the enclosing volumes
-
-    const label len = mesh_.nCells();
+    // Cell centres within the enclosing volumes
 
     List<volumeType> volTypes;
+    s.getVolumeType(ctrs, volTypes);
 
-    s.getVolumeType(mesh_.cellCentres(), volTypes);
-
-    for (label celli=0; celli < len; ++celli)
+    const label len = volTypes.size();
+    for (label elemi=0; elemi < len; ++elemi)
     {
-        if (volTypes[celli] == volumeType::INSIDE)
+        if (volTypes[elemi] == volumeType::INSIDE)
         {
-            addOrDelete(set, celli, add);
+            addOrDelete(set, elemi, add);
         }
     }
 }
@@ -109,10 +127,10 @@ Foam::searchableSurfaceToCell::searchableSurfaceToCell
             surfaceType,
             IOobject
             (
-                dict.lookupOrDefault("name", mesh.objectRegistry::db().name()),
-                mesh.time().constant(), // Instance
-                "triSurface",           // Local
-                mesh.time(),            // Registry
+                getSurfaceName(dict, mesh.objectRegistry::db().name()),
+                mesh.time().constant(),     // Instance
+                "triSurface",               // Local
+                mesh.objectRegistry::db(),  // Registry
                 IOobject::MUST_READ,
                 IOobject::NO_WRITE
             ),
@@ -124,8 +142,8 @@ Foam::searchableSurfaceToCell::searchableSurfaceToCell
     if (surf_ && !surf_->hasVolumeType())
     {
         WarningInFunction
-            << nl << "The surface '" << surf_->name() << "' of type '"
-            << surf_->type() << "' appears to be unclosed ... ignoring"
+            << nl << "The surface " << surf_->name() << " (type: "
+            << surf_->type() << ") appears to be unclosed ... ignoring"
             << nl << endl;
 
         surf_.clear();
@@ -141,7 +159,7 @@ Foam::searchableSurfaceToCell::searchableSurfaceToCell
 :
     searchableSurfaceToCell
     (
-        dict.get<word>("surface"),
+        dict.getCompat<word>("surfaceType", {{"surface", 0}}),
         mesh,
         dict
     )
@@ -165,8 +183,9 @@ void Foam::searchableSurfaceToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding cells enclosed by searchableSurface"
-                << "..." << endl;
+            Info<< "    Adding cells enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
         }
 
         combine(set, true);
@@ -175,8 +194,9 @@ void Foam::searchableSurfaceToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Removing cells enclosed by searchableSurface"
-                << "..." << endl;
+            Info<< "    Removing cells enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
         }
 
         combine(set, false);
diff --git a/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.H b/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.H
index bb436d54e5b8a609526a4bfd80e21133283468f7..ffdc0d9efa42539fc06b0b05e630131ca5f5255b 100644
--- a/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.H
+++ b/src/meshTools/sets/cellSources/searchableSurfaceToCell/searchableSurfaceToCell.H
@@ -25,14 +25,15 @@ Class
     Foam::searchableSurfaceToCell
 
 Description
-    A topoSetSource to select cells based on cell centres within a
+    A topoSetCellSource to select cells with centres within a
     searchableSurface.
 
     \heading Dictionary parameters
     \table
         Property    | Description                           | Required | Default
-        surface     | The searchable surface type           | yes   |
-        name        | Name for the IOobject                 | no    | mesh-name
+        surfaceType | The searchable surface type           | yes   |
+        surfaceName | Name for the IOobject                 | no    | mesh-name
+        surface     | Same as 'surfaceType'                 | no    |
     \endtable
 
 SourceFiles
@@ -73,6 +74,18 @@ class searchableSurfaceToCell
         void combine(topoSet& set, const bool add) const;
 
 
+protected:
+
+    // Protected Member Functions
+
+        //- Retrieve surface name from dictionary entry
+        static word getSurfaceName
+        (
+            const dictionary& dict,
+            const word& defaultName
+        );
+
+
 public:
 
     //- Runtime type information
diff --git a/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.C b/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.C
index 072e084dbbf4d1c36c57f86c8e1fd6eae5e67902..6ff053ed39738d38218ce18001b3a4d0de8f1628 100644
--- a/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.C
+++ b/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.C
@@ -67,13 +67,18 @@ void Foam::sphereToCell::combine(topoSet& set, const bool add) const
 {
     const pointField& ctrs = mesh_.cellCentres();
 
-    const scalar rad2 = radius_*radius_;
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
 
-    forAll(ctrs, celli)
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
+
+    forAll(ctrs, elemi)
     {
-        if (magSqr(ctrs[celli] - origin_) <= rad2)
+        const scalar d2 = magSqr(ctrs[elemi] - origin_);
+
+        if ((d2 < orad2) && (d2 > irad2))
         {
-            addOrDelete(set, celli, add);
+            addOrDelete(set, elemi, add);
         }
     }
 }
@@ -85,12 +90,14 @@ Foam::sphereToCell::sphereToCell
 (
     const polyMesh& mesh,
     const point& origin,
-    const scalar radius
+    const scalar radius,
+    const scalar innerRadius
 )
 :
     topoSetCellSource(mesh),
     origin_(origin),
-    radius_(radius)
+    radius_(radius),
+    innerRadius_(innerRadius)
 {}
 
 
@@ -104,7 +111,8 @@ Foam::sphereToCell::sphereToCell
     (
         mesh,
         dict.getCompat<vector>("origin", {{"centre", -1806}}),
-        dict.get<scalar>("radius")
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
     )
 {}
 
@@ -117,7 +125,8 @@ Foam::sphereToCell::sphereToCell
 :
     topoSetCellSource(mesh),
     origin_(checkIs(is)),
-    radius_(readScalar(checkIs(is)))
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
 {}
 
 
@@ -133,8 +142,15 @@ void Foam::sphereToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding cells within a sphere with centre = "
-                << origin_ << " and radius = " << radius_ << endl;
+            Info<< "    Adding cells within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, true);
@@ -143,8 +159,15 @@ void Foam::sphereToCell::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Removing cells within a sphere with centre = "
-                << origin_ << " and radius = " << radius_ << endl;
+            Info<< "    Removing cells within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, false);
diff --git a/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.H b/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.H
index 5ba3a2bd442fd52e60d45aea4f1329ee2d860980..5be512f07bb6662a23e8ec668c68cff6746ac966 100644
--- a/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.H
+++ b/src/meshTools/sets/cellSources/sphereToCell/sphereToCell.H
@@ -31,7 +31,8 @@ Description
     \table
         Property    | Description                           | Required | Default
         origin      | The origin (centre) of the sphere     | yes   |
-        radius      | The (outside) radius of sphere        | yes   |
+        radius      | The (outer) radius of sphere          | yes   |
+        innerRadius | The inner radius of sphere            | no    | 0
         centre      | Alternative for 'origin'              | no    |
     \endtable
 
@@ -70,6 +71,9 @@ class sphereToCell
         //- The outer radius of the sphere
         scalar radius_;
 
+        //- The inner radius of the sphere
+        scalar innerRadius_;
+
 
     // Private Member Functions
 
@@ -89,7 +93,8 @@ public:
         (
             const polyMesh& mesh,
             const point& origin,
-            const scalar radius
+            const scalar radius,
+            const scalar innerRadius = 0
         );
 
         //- Construct from dictionary
diff --git a/src/meshTools/sets/cellSources/topoSetCellSource/topoSetCellSource.H b/src/meshTools/sets/cellSources/topoSetCellSource/topoSetCellSource.H
index f506aaf0c802ec7c07ed0d4fbc8eed850c03fda6..8ecfca13f613e58079d596eb8ba5e2fa56fd09f7 100644
--- a/src/meshTools/sets/cellSources/topoSetCellSource/topoSetCellSource.H
+++ b/src/meshTools/sets/cellSources/topoSetCellSource/topoSetCellSource.H
@@ -89,6 +89,13 @@ public:
         //- Construct from components
         explicit topoSetCellSource(const polyMesh& mesh);
 
+        //- Clone (disallowed)
+        autoPtr<topoSetCellSource> clone() const
+        {
+            NotImplemented;
+            return nullptr;
+        }
+
 
     // Selectors
 
diff --git a/src/meshTools/sets/cellSources/zoneToCell/zoneToCell.H b/src/meshTools/sets/cellSources/zoneToCell/zoneToCell.H
index 15f107782df6ebf62226cbd9beb68589bd775621..3c8d9ce1c0a3dd3a1b184d9f95e8a949373422f3 100644
--- a/src/meshTools/sets/cellSources/zoneToCell/zoneToCell.H
+++ b/src/meshTools/sets/cellSources/zoneToCell/zoneToCell.H
@@ -30,13 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                           | Required | Default
-        zone        | The cell zone name or regex           | possibly |
         zones       | The cell zone names or regexs         | possibly |
+        zone        | The cell zone name or regex           | possibly |
         name        | Older specification for 'zone'        | no    |
     \endtable
 
 Note
-    Selection of multiple zones has precedence.
+    Must specify "zones", "zone" or "name" (highest to lowest precedence).
 
 SourceFiles
     zoneToCell.C
diff --git a/src/meshTools/sets/faceSources/boxToFace/boxToFace.C b/src/meshTools/sets/faceSources/boxToFace/boxToFace.C
index ee6490c6c7d40905aa75cf500f307939843e4e27..c8c1ce45c8ffb4207b716b2b2cb950f7d672edd2 100644
--- a/src/meshTools/sets/faceSources/boxToFace/boxToFace.C
+++ b/src/meshTools/sets/faceSources/boxToFace/boxToFace.C
@@ -67,13 +67,13 @@ void Foam::boxToFace::combine(topoSet& set, const bool add) const
 {
     const pointField& ctrs = mesh_.faceCentres();
 
-    forAll(ctrs, facei)
+    forAll(ctrs, elemi)
     {
         for (const auto& bb : bbs_)
         {
-            if (bb.contains(ctrs[facei]))
+            if (bb.contains(ctrs[elemi]))
             {
-                addOrDelete(set, facei, add);
+                addOrDelete(set, elemi, add);
                 break;
             }
         }
diff --git a/src/meshTools/sets/faceSources/boxToFace/boxToFace.H b/src/meshTools/sets/faceSources/boxToFace/boxToFace.H
index 49aef29b08a4f2ce55964ee262a676236e15d2ab..c56a8e95af3e9cbcacb2cb490cb21e615bb6a542 100644
--- a/src/meshTools/sets/faceSources/boxToFace/boxToFace.H
+++ b/src/meshTools/sets/faceSources/boxToFace/boxToFace.H
@@ -37,8 +37,8 @@ Description
     \endtable
 
 Note
-    In the order of highest to lowest precedence, must specify "boxes",
-    "box" or a "min/max" pair (compatibility with searchable box).
+    Must specify "boxes", "box" or a "min/max" pair
+    (compatibility with searchable box) - highest to lowest precedence.
 
 SourceFiles
     boxToFace.C
diff --git a/src/meshTools/sets/faceSources/cellToFace/cellToFace.C b/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
index a5368ef03a81f4170b371657bdc7be531274220f..e5dd7d1a7306f75dc966c3a93f2f03f1f0899b50 100644
--- a/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
+++ b/src/meshTools/sets/faceSources/cellToFace/cellToFace.C
@@ -63,16 +63,21 @@ Foam::cellToFace::cellActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::cellToFace::combine(topoSet& set, const bool add) const
+void Foam::cellToFace::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    if (!exists(mesh_.time().path()/topoSet::localPath(mesh_, setName_)))
+    if (!exists(mesh_.time().path()/topoSet::localPath(mesh_, setName)))
     {
         SeriousError<< "Cannot load set "
-            << setName_ << endl;
+            << setName << endl;
     }
 
-    cellSet loadedSet(mesh_, setName_);
+    cellSet loadedSet(mesh_, setName);
     const labelHashSet& cellLabels = loadedSet;
 
     if (option_ == ALL)
@@ -156,7 +161,7 @@ Foam::cellToFace::cellToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -167,13 +172,17 @@ Foam::cellToFace::cellToFace
     const dictionary& dict
 )
 :
-    cellToFace
-    (
-        mesh,
-        dict.get<word>("set"),
-        cellActionNames_.get("option", dict)
-    )
-{}
+    topoSetFaceSource(mesh),
+    names_(),
+    option_(cellActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::cellToFace::cellToFace
@@ -183,7 +192,7 @@ Foam::cellToFace::cellToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(cellActionNames_.read(checkIs(is)))
 {}
 
@@ -200,21 +209,27 @@ void Foam::cellToFace::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding faces according to cellSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding faces according to cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing faces according to cellSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing faces according to cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/faceSources/cellToFace/cellToFace.H b/src/meshTools/sets/faceSources/cellToFace/cellToFace.H
index b518d1ebe982f8c5b3fc90d21c439766007f8d4d..42a03ef8866cba6c6ff36c3e24fe6ded2346f9c1 100644
--- a/src/meshTools/sets/faceSources/cellToFace/cellToFace.H
+++ b/src/meshTools/sets/faceSources/cellToFace/cellToFace.H
@@ -33,12 +33,14 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        set         | Name of input cellSet             | yes   |
+        sets        | The cellSet names to use          | possibly |
+        set         | The cellSet name to use           | possibly |
         option      | Selection (all/both)              | yes   |
     \endtable
 
 Note
-    When picking up coupled faces uses cells on neighbouring processors.
+    Must specify "sets" or "set" (highest to lowest precedence).
+    When picking up coupled faces, it uses cells on neighbouring processors.
 
 SourceFiles
     cellToFace.C
@@ -80,8 +82,8 @@ private:
 
         static const Enum<cellAction> cellActionNames_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         cellAction option_;
@@ -90,7 +92,7 @@ private:
     // Private Member Functions
 
         //- Depending on face to cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.C b/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.C
index b3f7ea64de68aff012c958bb376a4a7fba581f3b..967d5ddbcc9db72854665dfa01cdd73365181289 100644
--- a/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.C
+++ b/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.C
@@ -76,16 +76,18 @@ Foam::topoSetSource::addToUsageTable Foam::cylinderAnnulusToFace::usage_
 
 void Foam::cylinderAnnulusToFace::combine(topoSet& set, const bool add) const
 {
+    const pointField& ctrs = mesh_.faceCentres();
+
     const vector axis = (point2_ - point1_);
-    const scalar orad2 = sqr(outerRadius_);
-    const scalar irad2 = sqr(innerRadius_);
     const scalar magAxis2 = magSqr(axis);
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
 
-    const pointField& ctrs = mesh_.faceCentres();
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
 
-    forAll(ctrs, facei)
+    forAll(ctrs, elemi)
     {
-        const vector d = ctrs[facei] - point1_;
+        const vector d = ctrs[elemi] - point1_;
         const scalar magD = d & axis;
 
         if ((magD > 0) && (magD < magAxis2))
@@ -93,7 +95,7 @@ void Foam::cylinderAnnulusToFace::combine(topoSet& set, const bool add) const
             const scalar d2 = (d & d) - sqr(magD)/magAxis2;
             if ((d2 < orad2) && (d2 > irad2))
             {
-                addOrDelete(set, facei, add);
+                addOrDelete(set, elemi, add);
             }
         }
     }
@@ -107,14 +109,14 @@ Foam::cylinderAnnulusToFace::cylinderAnnulusToFace
     const polyMesh& mesh,
     const point& point1,
     const point& point2,
-    const scalar outerRadius,
+    const scalar radius,
     const scalar innerRadius
 )
 :
     topoSetFaceSource(mesh),
     point1_(point1),
     point2_(point2),
-    outerRadius_(outerRadius),
+    radius_(radius),
     innerRadius_(innerRadius)
 {}
 
@@ -145,7 +147,7 @@ Foam::cylinderAnnulusToFace::cylinderAnnulusToFace
     topoSetFaceSource(mesh),
     point1_(checkIs(is)),
     point2_(checkIs(is)),
-    outerRadius_(readScalar(checkIs(is))),
+    radius_(readScalar(checkIs(is))),
     innerRadius_(readScalar(checkIs(is)))
 {}
 
@@ -163,9 +165,8 @@ void Foam::cylinderAnnulusToFace::applyToSet
         if (verbose_)
         {
             Info<< "    Adding faces with centre within cylinder annulus,"
-                << " with p1 = "
-                << point1_ << ", p2 = " << point2_
-                << ", radius = " << outerRadius_
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_
                 << ", inner radius = " << innerRadius_
                 << endl;
         }
@@ -177,9 +178,8 @@ void Foam::cylinderAnnulusToFace::applyToSet
         if (verbose_)
         {
             Info<< "    Removing faces with centre within cylinder annulus,"
-                << " with p1 = "
-                << point1_ << ", p2 = " << point2_
-                << ", radius = " << outerRadius_
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_
                 << ", inner radius = " << innerRadius_
                 << endl;
         }
diff --git a/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.H b/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.H
index 15ec51732c1d7da238030ddfd4e874f5bbb33d4b..60ae429aae44179fb5396fc73954799a42c903e6 100644
--- a/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.H
+++ b/src/meshTools/sets/faceSources/cylinderAnnulusToFace/cylinderAnnulusToFace.H
@@ -31,10 +31,10 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        p1          | coordinate of endpoint            | yes   |
-        p2          | coordinate of endpoint            | yes   |
-        outerRadius | cylinder outer radius             | yes   |
-        innerRadius | cylinder inner radius             | yes   |
+        p1          | Coordinate of endpoint            | yes   |
+        p2          | Coordinate of endpoint            | yes   |
+        outerRadius | Cylinder outer radius             | yes   |
+        innerRadius | Cylinder inner radius             | yes   |
     \endtable
 
 SourceFiles
@@ -72,10 +72,10 @@ class cylinderAnnulusToFace
         //- Second point on cylinder axis
         point point2_;
 
-        //- Outer Radius
-        scalar outerRadius_;
+        //- Outer radius
+        scalar radius_;
 
-        //- Inner Radius
+        //- Inner radius
         scalar innerRadius_;
 
 
@@ -98,8 +98,8 @@ public:
             const polyMesh& mesh,
             const point& point1,
             const point& point2,
-            const scalar outerRadius,
-            const scalar innerRadius
+            const scalar radius,
+            const scalar innerRadius = 0
         );
 
         //- Construct from dictionary
diff --git a/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.C b/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.C
index a4806d99f701912d0eeaf931ac3a64f58420312b..8e0d229f89b9890c925e4dfefdfdd0323dbb4513 100644
--- a/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.C
+++ b/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.C
@@ -65,23 +65,26 @@ Foam::topoSetSource::addToUsageTable Foam::cylinderToFace::usage_
 
 void Foam::cylinderToFace::combine(topoSet& set, const bool add) const
 {
+    const pointField& ctrs = mesh_.faceCentres();
+
     const vector axis = (point2_ - point1_);
-    const scalar rad2 = sqr(radius_);
     const scalar magAxis2 = magSqr(axis);
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
 
-    const pointField& ctrs = mesh_.faceCentres();
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
 
-    forAll(ctrs, facei)
+    forAll(ctrs, elemi)
     {
-        const vector d = ctrs[facei] - point1_;
+        const vector d = ctrs[elemi] - point1_;
         const scalar magD = d & axis;
 
         if ((magD > 0) && (magD < magAxis2))
         {
             const scalar d2 = (d & d) - sqr(magD)/magAxis2;
-            if (d2 < rad2)
+            if ((d2 < orad2) && (d2 > irad2))
             {
-                addOrDelete(set, facei, add);
+                addOrDelete(set, elemi, add);
             }
         }
     }
@@ -95,13 +98,15 @@ Foam::cylinderToFace::cylinderToFace
     const polyMesh& mesh,
     const point& point1,
     const point& point2,
-    const scalar radius
+    const scalar radius,
+    const scalar innerRadius
 )
 :
     topoSetFaceSource(mesh),
     point1_(point1),
     point2_(point2),
-    radius_(radius)
+    radius_(radius),
+    innerRadius_(innerRadius)
 {}
 
 
@@ -116,7 +121,8 @@ Foam::cylinderToFace::cylinderToFace
         mesh,
         dict.get<point>("p1"),
         dict.get<point>("p2"),
-        dict.get<scalar>("radius")
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
     )
 {}
 
@@ -130,7 +136,8 @@ Foam::cylinderToFace::cylinderToFace
     topoSetFaceSource(mesh),
     point1_(checkIs(is)),
     point2_(checkIs(is)),
-    radius_(readScalar(checkIs(is)))
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
 {}
 
 
@@ -146,9 +153,16 @@ void Foam::cylinderToFace::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding faces with centre within cylinder, with  p1 = "
-                << point1_ << ", p2 = " << point2_ << ", radius = " << radius_
-                << endl;
+            Info<< "    Adding faces with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, true);
@@ -157,9 +171,16 @@ void Foam::cylinderToFace::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Removing faces with centre within cylinder, with p1 = "
-                << point1_ << ", p2 = " << point2_ << ", radius = " << radius_
-                << endl;
+            Info<< "    Removing faces with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
         }
 
         combine(set, false);
diff --git a/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.H b/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.H
index e159302afed2c2e1cb0905915de13b86378d2f7e..cc83cec998f0288613cc8ea2dabf6a11fac933b2 100644
--- a/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.H
+++ b/src/meshTools/sets/faceSources/cylinderToFace/cylinderToFace.H
@@ -29,10 +29,11 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        p1          | coordinate of endpoint            | yes   |
-        p2          | coordinate of endpoint            | yes   |
-        radius      | cylinder radius                   | yes   |
+        Property    | Description                       | Required | Default
+        p1          | Coordinate of endpoint            | yes   |
+        p2          | Coordinate of endpoint            | yes   |
+        radius      | Cylinder (outer) radius           | yes   |
+        innerRadius | Cylinder inner radius             | no    | 0
     \endtable
 
 SourceFiles
@@ -70,9 +71,12 @@ class cylinderToFace
         //- Second point on cylinder axis
         point point2_;
 
-        //- Radius
+        //- Outer radius
         scalar radius_;
 
+        //- Inner radius
+        scalar innerRadius_;
+
 
     // Private Member Functions
 
@@ -93,7 +97,8 @@ public:
             const polyMesh& mesh,
             const point& point1,
             const point& point2,
-            const scalar radius
+            const scalar radius,
+            const scalar innerRadius = 0
         );
 
         //- Construct from dictionary
diff --git a/src/meshTools/sets/faceSources/faceToFace/faceToFace.C b/src/meshTools/sets/faceSources/faceToFace/faceToFace.C
index c94a4be4da2efb30a51e94309a5eb985ec089507..f6cb5db8dc4d5b5f43b5817bd6db3dc8c884706c 100644
--- a/src/meshTools/sets/faceSources/faceToFace/faceToFace.C
+++ b/src/meshTools/sets/faceSources/faceToFace/faceToFace.C
@@ -57,7 +57,7 @@ Foam::faceToFace::faceToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(setName)
+    names_(one(), setName)
 {}
 
 
@@ -67,12 +67,16 @@ Foam::faceToFace::faceToFace
     const dictionary& dict
 )
 :
-    faceToFace
-    (
-        mesh,
-        dict.get<word>("set")
-    )
-{}
+    topoSetFaceSource(mesh),
+    names_()
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::faceToFace::faceToFace
@@ -82,7 +86,7 @@ Foam::faceToFace::faceToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(checkIs(is))
+    names_(one(), word(checkIs(is)))
 {}
 
 
@@ -98,27 +102,31 @@ void Foam::faceToFace::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding all faces from faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding all elements of faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        faceSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            faceSet loadedSet(mesh_, setName);
 
-        set.addSet(loadedSet);
+            set.addSet(loadedSet);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing all faces from faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing all elements of faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        faceSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            faceSet loadedSet(mesh_, setName);
 
-        set.subtractSet(loadedSet);
+            set.subtractSet(loadedSet);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/faceSources/faceToFace/faceToFace.H b/src/meshTools/sets/faceSources/faceToFace/faceToFace.H
index 452d21df0c34b5f53602b18b1d48723eed380e1a..486ee3edde623069c3acaaf6f0f45de99fffe842 100644
--- a/src/meshTools/sets/faceSources/faceToFace/faceToFace.H
+++ b/src/meshTools/sets/faceSources/faceToFace/faceToFace.H
@@ -30,9 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        set         | Name of the input faceSet         | yes   |
+        sets        | The input faceSet names           | possibly |
+        set         | The input faceSet name            | possibly |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     faceToFace.C
 
@@ -61,8 +65,9 @@ class faceToFace
         //- Add usage string
         static addToUsageTable usage_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
+
 
 public:
 
diff --git a/src/meshTools/sets/faceSources/patchToFace/patchToFace.H b/src/meshTools/sets/faceSources/patchToFace/patchToFace.H
index f30657e494033d1ac73d24b5cc6012740dcd99f6..7534f752ca213ba50a707bd2088a1cbcb8049545 100644
--- a/src/meshTools/sets/faceSources/patchToFace/patchToFace.H
+++ b/src/meshTools/sets/faceSources/patchToFace/patchToFace.H
@@ -30,13 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                           | Required | Default
-        patch       | The face zone name or regex           | possibly |
         patches     | The face zone names or regexs         | possibly |
+        patch       | The face zone name or regex           | possibly |
         name        | Older specification for 'patch'       | no    |
     \endtable
 
 Note
-    Selection of multiple patches has precedence.
+    Must specify "patches", "patch" or "name" (highest to lowest precedence).
 
 SourceFiles
     patchToFace.C
diff --git a/src/meshTools/sets/faceSources/pointToFace/pointToFace.C b/src/meshTools/sets/faceSources/pointToFace/pointToFace.C
index ba32284bdec457854cb8e78c4362a98f4e552ae4..f3fe6f9e970e4ad56d4291f6608174b1513752f1 100644
--- a/src/meshTools/sets/faceSources/pointToFace/pointToFace.C
+++ b/src/meshTools/sets/faceSources/pointToFace/pointToFace.C
@@ -78,10 +78,15 @@ Foam::pointToFace::pointActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::pointToFace::combine(topoSet& set, const bool add) const
+void Foam::pointToFace::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    pointSet loadedSet(mesh_, setName_);
+    pointSet loadedSet(mesh_, setName);
 
     const labelHashSet& pointLabels = loadedSet;
 
@@ -164,7 +169,7 @@ Foam::pointToFace::pointToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -175,13 +180,17 @@ Foam::pointToFace::pointToFace
     const dictionary& dict
 )
 :
-    pointToFace
-    (
-        mesh,
-        dict.get<word>("set"),
-        pointActionNames_.get("option", dict)
-    )
-{}
+    topoSetFaceSource(mesh),
+    names_(),
+    option_(pointActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::pointToFace::pointToFace
@@ -191,7 +200,7 @@ Foam::pointToFace::pointToFace
 )
 :
     topoSetFaceSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(pointActionNames_.read(checkIs(is)))
 {}
 
@@ -208,21 +217,27 @@ void Foam::pointToFace::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding faces according to pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding faces according to pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing faces according to pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing faces according to pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/faceSources/pointToFace/pointToFace.H b/src/meshTools/sets/faceSources/pointToFace/pointToFace.H
index 584e27bcb5d2f3163ab3044a21e86125e8ca6607..3085675f9b0b17e57c5f997031272699ff45df2e 100644
--- a/src/meshTools/sets/faceSources/pointToFace/pointToFace.H
+++ b/src/meshTools/sets/faceSources/pointToFace/pointToFace.H
@@ -29,11 +29,15 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        set         | The point set name to use         | yes   |
+        Property    | Description                       | Required | Default
+        sets        | The pointSet names to use         | possibly |
+        set         | The pointSet name to use          | possibly |
         option      | Selection type (all/any/edge)     | yes   |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     pointToFace.C
 
@@ -77,8 +81,8 @@ private:
 
         static const Enum<pointAction> pointActionNames_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         pointAction option_;
@@ -87,7 +91,7 @@ private:
     // Private Member Functions
 
         //- Depending on face to cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.C b/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.C
new file mode 100644
index 0000000000000000000000000000000000000000..1d6497e1c203eb8c56c02eb4ea9ee759e24c77c7
--- /dev/null
+++ b/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.C
@@ -0,0 +1,207 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "searchableSurfaceToFace.H"
+#include "polyMesh.H"
+#include "Time.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(searchableSurfaceToFace, 0);
+    addToRunTimeSelectionTable
+    (
+        topoSetSource,
+        searchableSurfaceToFace,
+        word
+    );
+    addToRunTimeSelectionTable
+    (
+        topoSetFaceSource,
+        searchableSurfaceToFace,
+        word
+    );
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetFaceSource,
+        searchableSurfaceToFace,
+        word,
+        surface
+    );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::searchableSurfaceToFace::usage_
+(
+    searchableSurfaceToFace::typeName,
+    "\n    Usage: searchableSurfaceToFace surface\n\n"
+    "    Select faces with centre enclosed by the surface"
+    "\n"
+);
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::word Foam::searchableSurfaceToFace::getSurfaceName
+(
+    const dictionary& dict,
+    const word& defaultName
+)
+{
+    // Unfortunately cannot get a good default name from the dictionary name.
+    // It could be
+    //     sourceInfo { .. }
+    // But even with something like
+    //     mySurf.stl { .. }
+    // The dictName() method will only return the "stl" ending.
+
+    return dict.lookupOrDefault<word>("surfaceName", defaultName);
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::searchableSurfaceToFace::combine(topoSet& set, const bool add) const
+{
+    if (!surf_)
+    {
+        return;
+    }
+    const pointField& ctrs = mesh_.faceCentres();
+    const searchableSurface& s = *surf_;
+
+    // Face centres within the enclosing volumes
+
+    List<volumeType> volTypes;
+    s.getVolumeType(ctrs, volTypes);
+
+    const label len = volTypes.size();
+    for (label elemi=0; elemi < len; ++elemi)
+    {
+        if (volTypes[elemi] == volumeType::INSIDE)
+        {
+            addOrDelete(set, elemi, add);
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::searchableSurfaceToFace::searchableSurfaceToFace
+(
+    const word& surfaceType,
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    topoSetFaceSource(mesh),
+    surf_
+    (
+        searchableSurface::New
+        (
+            surfaceType,
+            IOobject
+            (
+                getSurfaceName(dict, mesh.objectRegistry::db().name()),
+                mesh.time().constant(),     // Instance
+                "triSurface",               // Local
+                mesh.objectRegistry::db(),  // Registry
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE
+            ),
+            dict
+        )
+    )
+{
+    // Check/warn for non-enclosed
+    if (surf_ && !surf_->hasVolumeType())
+    {
+        WarningInFunction
+            << nl << "The surface " << surf_->name() << " (type: "
+            << surf_->type() << ") appears to be unclosed ... ignoring"
+            << nl << endl;
+
+        surf_.clear();
+    }
+}
+
+
+Foam::searchableSurfaceToFace::searchableSurfaceToFace
+(
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    searchableSurfaceToFace
+    (
+        dict.getCompat<word>("surfaceType", {{"surface", 0}}),
+        mesh,
+        dict
+    )
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::searchableSurfaceToFace::applyToSet
+(
+    const topoSetSource::setAction action,
+    topoSet& set
+) const
+{
+    if (!surf_ || !surf_->hasVolumeType())
+    {
+        return;
+    }
+
+    if (action == topoSetSource::ADD || action == topoSetSource::NEW)
+    {
+        if (verbose_)
+        {
+            Info<< "    Adding faces enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
+        }
+
+        combine(set, true);
+    }
+    else if (action == topoSetSource::SUBTRACT)
+    {
+        if (verbose_)
+        {
+            Info<< "    Removing faces enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
+        }
+
+        combine(set, false);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.H b/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.H
new file mode 100644
index 0000000000000000000000000000000000000000..bea834f28725d528a468f8be146748dd8e6a34a4
--- /dev/null
+++ b/src/meshTools/sets/faceSources/searchableSurfaceToFace/searchableSurfaceToFace.H
@@ -0,0 +1,135 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::searchableSurfaceToFace
+
+Description
+    A topoSetFaceSource to select faces with centres within a
+    searchableSurface.
+
+    \heading Dictionary parameters
+    \table
+        Property    | Description                           | Required | Default
+        surfaceType | The searchable surface type           | yes   |
+        surfaceName | Name for the IOobject                 | no    | mesh-name
+        surface     | Same as 'surfaceType'                 | no    |
+    \endtable
+
+SourceFiles
+    searchableSurfaceToFace.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef searchableSurfaceToFace_H
+#define searchableSurfaceToFace_H
+
+#include "topoSetFaceSource.H"
+#include "searchableSurface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class searchableSurfaceToFace Declaration
+\*---------------------------------------------------------------------------*/
+
+class searchableSurfaceToFace
+:
+    public topoSetFaceSource
+{
+    // Private Data
+
+        //- Add usage string
+        static addToUsageTable usage_;
+
+        //- The searchableSurface
+        autoPtr<searchableSurface> surf_;
+
+
+    // Private Member Functions
+
+        void combine(topoSet& set, const bool add) const;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Retrieve surface name from dictionary entry
+        static word getSurfaceName
+        (
+            const dictionary& dict,
+            const word& defaultName
+        );
+
+
+public:
+
+    //- Runtime type information
+    TypeName("searchableSurfaceToFace");
+
+
+    // Constructors
+
+        //- Construct surface-type from dictionary
+        searchableSurfaceToFace
+        (
+            const word& surfaceType,
+            const polyMesh& mesh,
+            const dictionary& dict
+        );
+
+        //- Construct from dictionary
+        searchableSurfaceToFace
+        (
+            const polyMesh& mesh,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~searchableSurfaceToFace() = default;
+
+
+    // Member Functions
+
+        virtual void applyToSet
+        (
+            const topoSetSource::setAction action,
+            topoSet& set
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.C b/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.C
new file mode 100644
index 0000000000000000000000000000000000000000..4909b974852c032457226e0cd10852f66f689040
--- /dev/null
+++ b/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.C
@@ -0,0 +1,178 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sphereToFace.H"
+#include "polyMesh.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(sphereToFace, 0);
+    addToRunTimeSelectionTable(topoSetSource, sphereToFace, word);
+    addToRunTimeSelectionTable(topoSetSource, sphereToFace, istream);
+    addToRunTimeSelectionTable(topoSetFaceSource, sphereToFace, word);
+    addToRunTimeSelectionTable(topoSetFaceSource, sphereToFace, istream);
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetFaceSource,
+        sphereToFace,
+        word,
+        sphere
+    );
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetFaceSource,
+        sphereToFace,
+        istream,
+        sphere
+    );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::sphereToFace::usage_
+(
+    sphereToFace::typeName,
+    "\n    Usage: sphereToFace (centreX centreY centreZ) radius\n\n"
+    "    Select all faces with faceCentre within bounding sphere\n\n"
+);
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sphereToFace::combine(topoSet& set, const bool add) const
+{
+    const pointField& ctrs = mesh_.faceCentres();
+
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
+
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
+
+    forAll(ctrs, elemi)
+    {
+        const scalar d2 = magSqr(ctrs[elemi] - origin_);
+
+        if ((d2 < orad2) && (d2 > irad2))
+        {
+            addOrDelete(set, elemi, add);
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sphereToFace::sphereToFace
+(
+    const polyMesh& mesh,
+    const point& origin,
+    const scalar radius,
+    const scalar innerRadius
+)
+:
+    topoSetFaceSource(mesh),
+    origin_(origin),
+    radius_(radius),
+    innerRadius_(innerRadius)
+{}
+
+
+Foam::sphereToFace::sphereToFace
+(
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    sphereToFace
+    (
+        mesh,
+        dict.getCompat<vector>("origin", {{"centre", -1806}}),
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
+    )
+{}
+
+
+Foam::sphereToFace::sphereToFace
+(
+    const polyMesh& mesh,
+    Istream& is
+)
+:
+    topoSetFaceSource(mesh),
+    origin_(checkIs(is)),
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sphereToFace::applyToSet
+(
+    const topoSetSource::setAction action,
+    topoSet& set
+) const
+{
+    if (action == topoSetSource::ADD || action == topoSetSource::NEW)
+    {
+        if (verbose_)
+        {
+            Info<< "    Adding faces within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, true);
+    }
+    else if (action == topoSetSource::SUBTRACT)
+    {
+        if (verbose_)
+        {
+            Info<< "    Removing faces within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, false);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.H b/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.H
new file mode 100644
index 0000000000000000000000000000000000000000..b7fb8d55c05f38921293639d43dd31d316d2fc54
--- /dev/null
+++ b/src/meshTools/sets/faceSources/sphereToFace/sphereToFace.H
@@ -0,0 +1,130 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sphereToFace
+
+Description
+    A topoSetFaceSource to select faces based on faces centres inside sphere.
+
+    \heading Dictionary parameters
+    \table
+        Property    | Description                           | Required | Default
+        origin      | The origin (centre) of the sphere     | yes   |
+        radius      | The (outer) radius of sphere          | yes   |
+        innerRadius | The inner radius of sphere            | no    | 0
+        centre      | Alternative for 'origin'              | no    |
+    \endtable
+
+SourceFiles
+    sphereToFace.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sphereToFace_H
+#define sphereToFace_H
+
+#include "topoSetFaceSource.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class sphereToFace Declaration
+\*---------------------------------------------------------------------------*/
+
+class sphereToFace
+:
+    public topoSetFaceSource
+{
+
+    // Private data
+
+        //- Add usage string
+        static addToUsageTable usage_;
+
+        //- Centre point of the sphere
+        point origin_;
+
+        //- The outer radius of the sphere
+        scalar radius_;
+
+        //- The inner radius of the sphere
+        scalar innerRadius_;
+
+
+    // Private Member Functions
+
+        void combine(topoSet& set, const bool add) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("sphereToFace");
+
+
+    // Constructors
+
+        //- Construct from components
+        sphereToFace
+        (
+            const polyMesh& mesh,
+            const point& origin,
+            const scalar radius,
+            const scalar innerRadius = 0
+        );
+
+        //- Construct from dictionary
+        sphereToFace(const polyMesh& mesh, const dictionary& dict);
+
+        //- Construct from Istream
+        sphereToFace(const polyMesh& mesh, Istream& is);
+
+
+    //- Destructor
+    virtual ~sphereToFace() = default;
+
+
+    // Member Functions
+
+        virtual void applyToSet
+        (
+            const topoSetSource::setAction action,
+            topoSet& set
+        ) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/faceSources/topoSetFaceSource/topoSetFaceSource.H b/src/meshTools/sets/faceSources/topoSetFaceSource/topoSetFaceSource.H
index 018275ff59ca89b8ba8d37ad562237f8c5500abe..9f1e3624cf5b0893d7e5b49f9626469b253905bb 100644
--- a/src/meshTools/sets/faceSources/topoSetFaceSource/topoSetFaceSource.H
+++ b/src/meshTools/sets/faceSources/topoSetFaceSource/topoSetFaceSource.H
@@ -89,6 +89,13 @@ public:
         //- Construct from components
         explicit topoSetFaceSource(const polyMesh& mesh);
 
+        //- Clone (disallowed)
+        autoPtr<topoSetFaceSource> clone() const
+        {
+            NotImplemented;
+            return nullptr;
+        }
+
 
     // Selectors
 
diff --git a/src/meshTools/sets/faceSources/zoneToFace/zoneToFace.H b/src/meshTools/sets/faceSources/zoneToFace/zoneToFace.H
index 4c20ee4d96c077193771edf67cfecec18baf8d99..b580bc0620213ed7e0deef74dd58b695825ab927 100644
--- a/src/meshTools/sets/faceSources/zoneToFace/zoneToFace.H
+++ b/src/meshTools/sets/faceSources/zoneToFace/zoneToFace.H
@@ -30,13 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                           | Required | Default
-        zone        | The face zone name or regex           | possibly |
         zones       | The face zone names or regexs         | possibly |
+        zone        | The face zone name or regex           | possibly |
         name        | Older specification for 'zone'        | no    |
     \endtable
 
 Note
-    Selection of multiple zones has precedence.
+    Must specify "zones", "zone" or "name" (highest to lowest precedence).
 
 SourceFiles
     zoneToFace.C
diff --git a/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
index 71c983befe041c42edeafe30053c1743110b1526..a87429e65ad31165569110a47850af00231d15cd 100644
--- a/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
+++ b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.C
@@ -54,6 +54,32 @@ Foam::topoSetSource::addToUsageTable Foam::searchableSurfaceToFaceZone::usage_
 );
 
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::word Foam::searchableSurfaceToFaceZone::getSurfaceName
+(
+    const dictionary& dict,
+    const word& defaultName
+)
+{
+    // Unfortunately cannot get a good default name from the dictionary name.
+    // It could be
+    //     sourceInfo { .. }
+    // But even with something like
+    //     mySurf.stl { .. }
+    // The dictName() method will only return the "stl" ending.
+
+
+    return
+        dict.lookupOrDefaultCompat<word>
+        (
+            "surfaceName",
+            {{"name", 1806}},
+            defaultName
+        );
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::searchableSurfaceToFaceZone::searchableSurfaceToFaceZone
@@ -71,10 +97,10 @@ Foam::searchableSurfaceToFaceZone::searchableSurfaceToFaceZone
             surfaceType,
             IOobject
             (
-                dict.lookupOrDefault("name", mesh.objectRegistry::db().name()),
-                mesh.time().constant(),
-                "triSurface",
-                mesh.objectRegistry::db(),
+                getSurfaceName(dict, mesh.objectRegistry::db().name()),
+                mesh.time().constant(),     // Instance
+                "triSurface",               // Local
+                mesh.objectRegistry::db(),  // Registry
                 IOobject::MUST_READ,
                 IOobject::NO_WRITE
             ),
@@ -92,19 +118,13 @@ Foam::searchableSurfaceToFaceZone::searchableSurfaceToFaceZone
 :
     searchableSurfaceToFaceZone
     (
-        dict.get<word>("surface"),
+        dict.getCompat<word>("surfaceType", {{"surface", 0}}),
         mesh,
         dict
     )
 {}
 
 
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-
-Foam::searchableSurfaceToFaceZone::~searchableSurfaceToFaceZone()
-{}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 void Foam::searchableSurfaceToFaceZone::applyToSet
diff --git a/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.H b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.H
index 100c481eef56cb1461a792d66e7685639bec0829..b08f3094c034e25a98cd4f97e7757d2576d9a34e 100644
--- a/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.H
+++ b/src/meshTools/sets/faceZoneSources/searchableSurfaceToFaceZone/searchableSurfaceToFaceZone.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2012 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -30,9 +30,11 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                        | Required  | Default
-        surface     | The searchable surface type        | yes   |
-        name        | Name for the IOobject              | no    | mesh-name
+        Property    | Description                           | Required | Default
+        surfaceType | The searchable surface type           | yes   |
+        surfaceName | Name for the IOobject                 | no    | mesh-name
+        surface     | Same as 'surfaceType'                 | no    |
+        name        | Older specification for 'surfaceName' | no    |
     \endtable
 
 SourceFiles
@@ -68,6 +70,19 @@ class searchableSurfaceToFaceZone
         //- Surface
         autoPtr<searchableSurface> surfacePtr_;
 
+
+protected:
+
+    // Protected Member Functions
+
+        //- Retrieve surface name from dictionary entry
+        static word getSurfaceName
+        (
+            const dictionary& dict,
+            const word& defaultName
+        );
+
+
 public:
 
     //- Runtime type information
@@ -93,7 +108,7 @@ public:
 
 
     //- Destructor
-    virtual ~searchableSurfaceToFaceZone();
+    virtual ~searchableSurfaceToFaceZone() = default;
 
 
     // Member Functions
diff --git a/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.C b/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.C
index d88292294de62bcb051ee732c5600f7541230d75..fb1797342620e1cd40f37b5e22036f899dc83810 100644
--- a/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.C
+++ b/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.C
@@ -65,15 +65,15 @@ Foam::topoSetSource::addToUsageTable Foam::boxToPoint::usage_
 
 void Foam::boxToPoint::combine(topoSet& set, const bool add) const
 {
-    const pointField& pts = mesh_.points();
+    const pointField& ctrs = mesh_.points();
 
-    forAll(pts, pointi)
+    forAll(ctrs, elemi)
     {
         for (const auto& bb : bbs_)
         {
-            if (bb.contains(pts[pointi]))
+            if (bb.contains(ctrs[elemi]))
             {
-                addOrDelete(set, pointi, add);
+                addOrDelete(set, elemi, add);
                 break;
             }
         }
diff --git a/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.H b/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.H
index d4d007362751d368f80a62fc2d26f976d0d8bf29..abc70aa5dc4314040af0f263327b8894f0418516 100644
--- a/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.H
+++ b/src/meshTools/sets/pointSources/boxToPoint/boxToPoint.H
@@ -37,8 +37,8 @@ Description
     \endtable
 
 Note
-    In the order of highest to lowest precedence, must specify "boxes",
-    "box" or a "min/max" pair (compatibility with searchable box).
+    Must specify "boxes", "box" or a "min/max" pair
+    (compatibility with searchable box) - highest to lowest precedence.
 
 SourceFiles
     boxToPoint.C
diff --git a/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.C b/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.C
index 3bc3ff3a719a7baa8fef586b60e86e5bd7ab88bc..c305346679bba06f32a3b648fe05380df2926424 100644
--- a/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.C
+++ b/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.C
@@ -59,10 +59,15 @@ Foam::cellToPoint::cellActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::cellToPoint::combine(topoSet& set, const bool add) const
+void Foam::cellToPoint::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    cellSet loadedSet(mesh_, setName_);
+    cellSet loadedSet(mesh_, setName);
     const labelHashSet& cellLabels = loadedSet;
 
     // Add all point from cells in loadedSet
@@ -93,7 +98,7 @@ Foam::cellToPoint::cellToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -104,13 +109,17 @@ Foam::cellToPoint::cellToPoint
     const dictionary& dict
 )
 :
-    cellToPoint
-    (
-        mesh,
-        dict.get<word>("set"),
-        cellActionNames_.get("option", dict)
-    )
-{}
+    topoSetPointSource(mesh),
+    names_(),
+    option_(cellActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::cellToPoint::cellToPoint
@@ -120,7 +129,7 @@ Foam::cellToPoint::cellToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(cellActionNames_.read(checkIs(is)))
 {}
 
@@ -137,21 +146,27 @@ void Foam::cellToPoint::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding from " << setName_
-                << " ..." << endl;
+            Info<< "    Adding points in cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing from " << setName_
-                << " ..." << endl;
+            Info<< "    Removing points in cellSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.H b/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.H
index f00c71aa39eefba57ce0af0516b05aa28a5f8106..f0170fd1d10d512dce7c5808d99e9b5a4e1e9ab7 100644
--- a/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.H
+++ b/src/meshTools/sets/pointSources/cellToPoint/cellToPoint.H
@@ -30,10 +30,14 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        name        | The input cellSet name            | yes   |
+        sets        | The cellSet names to use          | possibly |
+        set         | The cellSet name to use           | possibly |
         option      | Selection type (all)              | yes   |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     cellToPoint.C
 
@@ -73,8 +77,8 @@ private:
 
         static const Enum<cellAction> cellActionNames_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         cellAction option_;
@@ -83,7 +87,7 @@ private:
     // Private Member Functions
 
         //- Depending on face to cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.C b/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.C
new file mode 100644
index 0000000000000000000000000000000000000000..ea9322077c19c7ad0159e073fcc19dac523b71cb
--- /dev/null
+++ b/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.C
@@ -0,0 +1,191 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2018 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 "cylinderToPoint.H"
+#include "polyMesh.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(cylinderToPoint, 0);
+    addToRunTimeSelectionTable(topoSetSource, cylinderToPoint, word);
+    addToRunTimeSelectionTable(topoSetSource, cylinderToPoint, istream);
+    addToRunTimeSelectionTable(topoSetPointSource, cylinderToPoint, word);
+    addToRunTimeSelectionTable(topoSetPointSource, cylinderToPoint, istream);
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        cylinderToPoint,
+        word,
+        cylinder
+    );
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        cylinderToPoint,
+        istream,
+        cylinder
+    );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::cylinderToPoint::usage_
+(
+    cylinderToPoint::typeName,
+    "\n    Usage: cylinderToPoint (p1X p1Y p1Z) (p2X p2Y p2Z) radius\n\n"
+    "    Select points within bounding cylinder\n\n"
+);
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::cylinderToPoint::combine(topoSet& set, const bool add) const
+{
+    const pointField& ctrs = mesh_.points();
+
+    const vector axis = (point2_ - point1_);
+    const scalar magAxis2 = magSqr(axis);
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
+
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
+
+    forAll(ctrs, elemi)
+    {
+        const vector d = ctrs[elemi] - point1_;
+        const scalar magD = d & axis;
+
+        if ((magD > 0) && (magD < magAxis2))
+        {
+            const scalar d2 = (d & d) - sqr(magD)/magAxis2;
+            if ((d2 < orad2) && (d2 > irad2))
+            {
+                addOrDelete(set, elemi, add);
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::cylinderToPoint::cylinderToPoint
+(
+    const polyMesh& mesh,
+    const point& point1,
+    const point& point2,
+    const scalar radius,
+    const scalar innerRadius
+)
+:
+    topoSetPointSource(mesh),
+    point1_(point1),
+    point2_(point2),
+    radius_(radius),
+    innerRadius_(innerRadius)
+{}
+
+
+Foam::cylinderToPoint::cylinderToPoint
+(
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    cylinderToPoint
+    (
+        mesh,
+        dict.get<point>("p1"),
+        dict.get<point>("p2"),
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
+    )
+{}
+
+
+Foam::cylinderToPoint::cylinderToPoint
+(
+    const polyMesh& mesh,
+    Istream& is
+)
+:
+    topoSetPointSource(mesh),
+    point1_(checkIs(is)),
+    point2_(checkIs(is)),
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::cylinderToPoint::applyToSet
+(
+    const topoSetSource::setAction action,
+    topoSet& set
+) const
+{
+    if (action == topoSetSource::ADD || action == topoSetSource::NEW)
+    {
+        if (verbose_)
+        {
+            Info<< "    Adding faces with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, true);
+    }
+    else if (action == topoSetSource::SUBTRACT)
+    {
+        if (verbose_)
+        {
+            Info<< "    Removing faces with centre within cylinder,"
+                << " with p1 = " << point1_ << ", p2 = " << point2_
+                << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, false);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.H b/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.H
new file mode 100644
index 0000000000000000000000000000000000000000..e0110b48973de98545b278820a6d88109db256de
--- /dev/null
+++ b/src/meshTools/sets/pointSources/cylinderToPoint/cylinderToPoint.H
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2018 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::cylinderToPoint
+
+Description
+    A topoSetPointSource to select points inside a cylinder.
+
+    \heading Dictionary parameters
+    \table
+        Property    | Description                       | Required | Default
+        p1          | Coordinate of endpoint            | yes   |
+        p2          | Coordinate of endpoint            | yes   |
+        radius      | Cylinder (outer) radius           | yes   |
+        innerRadius | Cylinder inner radius             | no    | 0
+    \endtable
+
+SourceFiles
+    cylinderToPoint.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef cylinderToPoint_H
+#define cylinderToPoint_H
+
+#include "topoSetPointSource.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class cylinderToPoint Declaration
+\*---------------------------------------------------------------------------*/
+
+class cylinderToPoint
+:
+    public topoSetPointSource
+{
+
+    // Private data
+
+        //- Add usage string
+        static addToUsageTable usage_;
+
+        //- First point on cylinder axis
+        point point1_;
+
+        //- Second point on cylinder axis
+        point point2_;
+
+        //- Outer radius
+        scalar radius_;
+
+        //- Inner radius
+        scalar innerRadius_;
+
+
+    // Private Member Functions
+
+        void combine(topoSet& set, const bool add) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("cylinderToPoint");
+
+
+    // Constructors
+
+        //- Construct from components
+        cylinderToPoint
+        (
+            const polyMesh& mesh,
+            const point& point1,
+            const point& point2,
+            const scalar radius,
+            const scalar innerRadius = 0
+        );
+
+        //- Construct from dictionary
+        cylinderToPoint(const polyMesh& mesh, const dictionary& dict);
+
+        //- Construct from Istream
+        cylinderToPoint(const polyMesh& mesh, Istream& is);
+
+
+    //- Destructor
+    virtual ~cylinderToPoint() = default;
+
+
+    // Member Functions
+
+        virtual void applyToSet
+        (
+            const topoSetSource::setAction action,
+            topoSet& set
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.C b/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.C
index 3351a14ad6616401b6bb99a9597114513e596dcb..42a5654374a135255b9701e217c63fa0c8d5dfaa 100644
--- a/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.C
+++ b/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.C
@@ -58,10 +58,15 @@ Foam::faceToPoint::faceActionNames_
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::faceToPoint::combine(topoSet& set, const bool add) const
+void Foam::faceToPoint::combine
+(
+    topoSet& set,
+    const bool add,
+    const word& setName
+) const
 {
     // Load the set
-    faceSet loadedSet(mesh_, setName_);
+    faceSet loadedSet(mesh_, setName);
     const labelHashSet& faceLabels = loadedSet;
 
     // Add all points from faces in loadedSet
@@ -87,7 +92,7 @@ Foam::faceToPoint::faceToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(setName),
+    names_(one(), setName),
     option_(option)
 {}
 
@@ -98,13 +103,17 @@ Foam::faceToPoint::faceToPoint
     const dictionary& dict
 )
 :
-    faceToPoint
-    (
-        mesh,
-        dict.get<word>("set"),
-        faceActionNames_.get("option", dict)
-    )
-{}
+    topoSetPointSource(mesh),
+    names_(),
+    option_(faceActionNames_.get("option", dict))
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::faceToPoint::faceToPoint
@@ -114,7 +123,7 @@ Foam::faceToPoint::faceToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(checkIs(is)),
+    names_(one(), word(checkIs(is))),
     option_(faceActionNames_.read(checkIs(is)))
 {}
 
@@ -131,21 +140,27 @@ void Foam::faceToPoint::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding points from face in faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding points from face in faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, true);
+        for (const word& setName : names_)
+        {
+            combine(set, true, setName);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing points from face in faceSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing points from face in faceSet "
+                << flatOutput(names_) << nl;
         }
 
-        combine(set, false);
+        for (const word& setName : names_)
+        {
+            combine(set, false, setName);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.H b/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.H
index 375a08dd6fed682ebf600bb74a3127666026935f..1362420e6ee8666d7457748497ff2499bef576a9 100644
--- a/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.H
+++ b/src/meshTools/sets/pointSources/faceToPoint/faceToPoint.H
@@ -29,11 +29,15 @@ Description
 
     \heading Dictionary parameters
     \table
-        Property    | Description                       | Required  | Default
-        name        | The input faceSet name            | yes   |
+        Property    | Description                       | Required | Default
+        sets        | The faceSet names to use          | possibly |
+        set         | The faceSet name to use           | possibly |
         option      | Selection type (all)              | yes   |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     faceToPoint.C
 
@@ -73,8 +77,8 @@ private:
 
         static const Enum<faceAction> faceActionNames_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
 
         //- Option
         faceAction option_;
@@ -83,7 +87,7 @@ private:
     // Private Member Functions
 
         //- Depending on face to cell option add to or delete from cellSet.
-        void combine(topoSet& set, const bool add) const;
+        void combine(topoSet& set, const bool add, const word& setName) const;
 
 
 public:
diff --git a/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.C b/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.C
index 5ede16171a831044789b67b962823196f6ae0f97..4986ac7e907cdc024651a57a4c2ba6ff63a1726d 100644
--- a/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.C
+++ b/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.C
@@ -57,7 +57,7 @@ Foam::pointToPoint::pointToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(setName)
+    names_(one(), setName)
 {}
 
 
@@ -67,8 +67,16 @@ Foam::pointToPoint::pointToPoint
     const dictionary& dict
 )
 :
-    pointToPoint(mesh, dict.get<word>("set"))
-{}
+    topoSetPointSource(mesh),
+    names_()
+{
+    // Look for 'sets' or 'set'
+    if (!dict.readIfPresent("sets", names_))
+    {
+        names_.resize(1);
+        dict.readEntry("set", names_.first());
+    }
+}
 
 
 Foam::pointToPoint::pointToPoint
@@ -78,7 +86,7 @@ Foam::pointToPoint::pointToPoint
 )
 :
     topoSetPointSource(mesh),
-    setName_(checkIs(is))
+    names_(one(), word(checkIs(is)))
 {}
 
 
@@ -94,27 +102,31 @@ void Foam::pointToPoint::applyToSet
     {
         if (verbose_)
         {
-            Info<< "    Adding all from pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Adding all elements of pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        pointSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            pointSet loadedSet(mesh_, setName);
 
-        set.addSet(loadedSet);
+            set.addSet(loadedSet);
+        }
     }
     else if (action == topoSetSource::SUBTRACT)
     {
         if (verbose_)
         {
-            Info<< "    Removing all from pointSet " << setName_
-                << " ..." << endl;
+            Info<< "    Removing all elements of pointSet "
+                << flatOutput(names_) << nl;
         }
 
-        // Load the set
-        pointSet loadedSet(mesh_, setName_);
+        for (const word& setName : names_)
+        {
+            pointSet loadedSet(mesh_, setName);
 
-        set.subtractSet(loadedSet);
+            set.subtractSet(loadedSet);
+        }
     }
 }
 
diff --git a/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.H b/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.H
index 5f1286672e37e21e8ac90e7b300bc4d772e55191..02dd61a95b36bb9fa7f8658944d9f7988eff28ee 100644
--- a/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.H
+++ b/src/meshTools/sets/pointSources/pointToPoint/pointToPoint.H
@@ -30,9 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                       | Required  | Default
-        set         | The point set name                | yes   |
+        sets        | The input pointSet names          | possibly |
+        set         | The input pointSet name           | possibly |
     \endtable
 
+Note
+    Must specify "sets" or "set" (highest to lowest precedence).
+
 SourceFiles
     pointToPoint.C
 
@@ -61,8 +65,9 @@ class pointToPoint
         //- Add usage string
         static addToUsageTable usage_;
 
-        //- Name of set to use
-        word setName_;
+        //- Names of sets to use
+        wordList names_;
+
 
 public:
 
@@ -72,11 +77,7 @@ public:
     // Constructors
 
         //- Construct from components
-        pointToPoint
-        (
-            const polyMesh& mesh,
-            const word& setName
-        );
+        pointToPoint(const polyMesh& mesh, const word& setName);
 
         //- Construct from dictionary
         pointToPoint(const polyMesh& mesh, const dictionary& dict);
diff --git a/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.C b/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.C
new file mode 100644
index 0000000000000000000000000000000000000000..8a044317c4a97ac9aadb280d5581b2b48816b20d
--- /dev/null
+++ b/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.C
@@ -0,0 +1,206 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "searchableSurfaceToPoint.H"
+#include "polyMesh.H"
+#include "Time.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(searchableSurfaceToPoint, 0);
+    addToRunTimeSelectionTable
+    (
+        topoSetSource,
+        searchableSurfaceToPoint,
+        word
+    );
+    addToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        searchableSurfaceToPoint,
+        word
+    );
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        searchableSurfaceToPoint,
+        word,
+        surface
+    );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::searchableSurfaceToPoint::usage_
+(
+    searchableSurfaceToPoint::typeName,
+    "\n    Usage: searchableSurfaceToPoint surface\n\n"
+    "    Select points enclosed by the surface"
+    "\n"
+);
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::word Foam::searchableSurfaceToPoint::getSurfaceName
+(
+    const dictionary& dict,
+    const word& defaultName
+)
+{
+    // Unfortunately cannot get a good default name from the dictionary name.
+    // It could be
+    //     sourceInfo { .. }
+    // But even with something like
+    //     mySurf.stl { .. }
+    // The dictName() method will only return the "stl" ending.
+
+    return dict.lookupOrDefault<word>("surfaceName", defaultName);
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::searchableSurfaceToPoint::combine(topoSet& set, const bool add) const
+{
+    if (!surf_)
+    {
+        return;
+    }
+    const searchableSurface& s = *surf_;
+
+    // Mesh points within the enclosing volumes
+
+    List<volumeType> volTypes;
+    s.getVolumeType(mesh_.points(), volTypes);
+
+    const label len = volTypes.size();
+    for (label id=0; id < len; ++id)
+    {
+        if (volTypes[id] == volumeType::INSIDE)
+        {
+            addOrDelete(set, id, add);
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::searchableSurfaceToPoint::searchableSurfaceToPoint
+(
+    const word& surfaceType,
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    topoSetPointSource(mesh),
+    surf_
+    (
+        searchableSurface::New
+        (
+            surfaceType,
+            IOobject
+            (
+                getSurfaceName(dict, mesh.objectRegistry::db().name()),
+                mesh.time().constant(),     // Instance
+                "triSurface",               // Local
+                mesh.objectRegistry::db(),  // Registry
+                IOobject::MUST_READ,
+                IOobject::NO_WRITE
+            ),
+            dict
+        )
+    )
+{
+    // Check/warn for non-enclosed
+    if (surf_ && !surf_->hasVolumeType())
+    {
+        WarningInFunction
+            << nl << "The surface " << surf_->name() << " (type: "
+            << surf_->type() << ") appears to be unclosed ... ignoring"
+            << nl << endl;
+
+        surf_.clear();
+    }
+}
+
+
+Foam::searchableSurfaceToPoint::searchableSurfaceToPoint
+(
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    searchableSurfaceToPoint
+    (
+        dict.getCompat<word>("surfaceType", {{"surface", 0}}),
+        mesh,
+        dict
+    )
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::searchableSurfaceToPoint::applyToSet
+(
+    const topoSetSource::setAction action,
+    topoSet& set
+) const
+{
+    if (!surf_ || !surf_->hasVolumeType())
+    {
+        return;
+    }
+
+    if (action == topoSetSource::ADD || action == topoSetSource::NEW)
+    {
+        if (verbose_)
+        {
+            Info<< "    Adding points enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
+        }
+
+        combine(set, true);
+    }
+    else if (action == topoSetSource::SUBTRACT)
+    {
+        if (verbose_)
+        {
+            Info<< "    Removing points enclosed by surface '"
+                << surf_->name() << "' (type: " << surf_->type() << ") ..."
+                << endl;
+        }
+
+        combine(set, false);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.H b/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.H
new file mode 100644
index 0000000000000000000000000000000000000000..2d371a036d901c176cd9fd49f61cd6947049c70a
--- /dev/null
+++ b/src/meshTools/sets/pointSources/searchableSurfaceToPoint/searchableSurfaceToPoint.H
@@ -0,0 +1,134 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::searchableSurfaceToPoint
+
+Description
+    A topoSetPointSource to select mesh points within a searchableSurface.
+
+    \heading Dictionary parameters
+    \table
+        Property    | Description                           | Required | Default
+        surfaceType | The searchable surface type           | yes   |
+        surfaceName | Name for the IOobject                 | no    | mesh-name
+        surface     | Same as 'surfaceType'                 | no    |
+    \endtable
+
+SourceFiles
+    searchableSurfaceToPoint.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef searchableSurfaceToPoint_H
+#define searchableSurfaceToPoint_H
+
+#include "topoSetPointSource.H"
+#include "searchableSurface.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class searchableSurfaceToPoint Declaration
+\*---------------------------------------------------------------------------*/
+
+class searchableSurfaceToPoint
+:
+    public topoSetPointSource
+{
+    // Private Data
+
+        //- Add usage string
+        static addToUsageTable usage_;
+
+        //- The searchableSurface
+        autoPtr<searchableSurface> surf_;
+
+
+    // Private Member Functions
+
+        void combine(topoSet& set, const bool add) const;
+
+
+protected:
+
+    // Protected Member Functions
+
+        //- Retrieve surface name from dictionary entry
+        static word getSurfaceName
+        (
+            const dictionary& dict,
+            const word& defaultName
+        );
+
+
+public:
+
+    //- Runtime type information
+    TypeName("searchableSurfaceToPoint");
+
+
+    // Constructors
+
+        //- Construct surface-type from dictionary
+        searchableSurfaceToPoint
+        (
+            const word& surfaceType,
+            const polyMesh& mesh,
+            const dictionary& dict
+        );
+
+        //- Construct from dictionary
+        searchableSurfaceToPoint
+        (
+            const polyMesh& mesh,
+            const dictionary& dict
+        );
+
+
+    //- Destructor
+    virtual ~searchableSurfaceToPoint() = default;
+
+
+    // Member Functions
+
+        virtual void applyToSet
+        (
+            const topoSetSource::setAction action,
+            topoSet& set
+        ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.C b/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.C
new file mode 100644
index 0000000000000000000000000000000000000000..97875e82d612e6c2df402961f5d2763f6454f6a4
--- /dev/null
+++ b/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.C
@@ -0,0 +1,178 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "sphereToPoint.H"
+#include "polyMesh.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(sphereToPoint, 0);
+    addToRunTimeSelectionTable(topoSetSource, sphereToPoint, word);
+    addToRunTimeSelectionTable(topoSetSource, sphereToPoint, istream);
+    addToRunTimeSelectionTable(topoSetPointSource, sphereToPoint, word);
+    addToRunTimeSelectionTable(topoSetPointSource, sphereToPoint, istream);
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        sphereToPoint,
+        word,
+        sphere
+    );
+    addNamedToRunTimeSelectionTable
+    (
+        topoSetPointSource,
+        sphereToPoint,
+        istream,
+        sphere
+    );
+}
+
+
+Foam::topoSetSource::addToUsageTable Foam::sphereToPoint::usage_
+(
+    sphereToPoint::typeName,
+    "\n    Usage: sphereToPoint (centreX centreY centreZ) radius\n\n"
+    "    Select all points within bounding sphere\n\n"
+);
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::sphereToPoint::combine(topoSet& set, const bool add) const
+{
+    const pointField& ctrs = mesh_.points();
+
+    const scalar orad2 = sqr(radius_);
+    const scalar irad2 = innerRadius_ > 0 ? sqr(innerRadius_) : -1;
+
+    // Treat innerRadius == 0 like unspecified innerRadius (always accept)
+
+    forAll(ctrs, elemi)
+    {
+        const scalar d2 = magSqr(ctrs[elemi] - origin_);
+
+        if ((d2 < orad2) && (d2 > irad2))
+        {
+            addOrDelete(set, elemi, add);
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::sphereToPoint::sphereToPoint
+(
+    const polyMesh& mesh,
+    const point& origin,
+    const scalar radius,
+    const scalar innerRadius
+)
+:
+    topoSetPointSource(mesh),
+    origin_(origin),
+    radius_(radius),
+    innerRadius_(innerRadius)
+{}
+
+
+Foam::sphereToPoint::sphereToPoint
+(
+    const polyMesh& mesh,
+    const dictionary& dict
+)
+:
+    sphereToPoint
+    (
+        mesh,
+        dict.getCompat<vector>("origin", {{"centre", -1806}}),
+        dict.get<scalar>("radius"),
+        dict.lookupOrDefault<scalar>("innerRadius", 0)
+    )
+{}
+
+
+Foam::sphereToPoint::sphereToPoint
+(
+    const polyMesh& mesh,
+    Istream& is
+)
+:
+    topoSetPointSource(mesh),
+    origin_(checkIs(is)),
+    radius_(readScalar(checkIs(is))),
+    innerRadius_(0)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::sphereToPoint::applyToSet
+(
+    const topoSetSource::setAction action,
+    topoSet& set
+) const
+{
+    if (action == topoSetSource::ADD || action == topoSetSource::NEW)
+    {
+        if (verbose_)
+        {
+            Info<< "    Adding points within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, true);
+    }
+    else if (action == topoSetSource::SUBTRACT)
+    {
+        if (verbose_)
+        {
+            Info<< "    Removing points within sphere,"
+                << " origin = " << origin_ << ", radius = " << radius_;
+
+            if (innerRadius_ > 0)
+            {
+                Info<< ", innerRadius = " << innerRadius_;
+            }
+
+            Info<< endl;
+        }
+
+        combine(set, false);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.H b/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.H
new file mode 100644
index 0000000000000000000000000000000000000000..a2579275483accf269c0b250d5fcb733e39aa491
--- /dev/null
+++ b/src/meshTools/sets/pointSources/sphereToPoint/sphereToPoint.H
@@ -0,0 +1,130 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::sphereToPoint
+
+Description
+    A topoSetPointSource to select based on mesh points inside sphere.
+
+    \heading Dictionary parameters
+    \table
+        Property    | Description                           | Required | Default
+        origin      | The origin (centre) of the sphere     | yes   |
+        radius      | The (outer) radius of sphere          | yes   |
+        innerRadius | The inner radius of sphere            | no    | 0
+        centre      | Alternative for 'origin'              | no    |
+    \endtable
+
+SourceFiles
+    sphereToPoint.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef sphereToPoint_H
+#define sphereToPoint_H
+
+#include "topoSetPointSource.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class sphereToPoint Declaration
+\*---------------------------------------------------------------------------*/
+
+class sphereToPoint
+:
+    public topoSetPointSource
+{
+
+    // Private data
+
+        //- Add usage string
+        static addToUsageTable usage_;
+
+        //- Centre point of the sphere
+        point origin_;
+
+        //- The outer radius of the sphere
+        scalar radius_;
+
+        //- The inner radius of the sphere
+        scalar innerRadius_;
+
+
+    // Private Member Functions
+
+        void combine(topoSet& set, const bool add) const;
+
+
+public:
+
+    //- Runtime type information
+    TypeName("sphereToPoint");
+
+
+    // Constructors
+
+        //- Construct from components
+        sphereToPoint
+        (
+            const polyMesh& mesh,
+            const point& origin,
+            const scalar radius,
+            const scalar innerRadius = 0
+        );
+
+        //- Construct from dictionary
+        sphereToPoint(const polyMesh& mesh, const dictionary& dict);
+
+        //- Construct from Istream
+        sphereToPoint(const polyMesh& mesh, Istream& is);
+
+
+    //- Destructor
+    virtual ~sphereToPoint() = default;
+
+
+    // Member Functions
+
+        virtual void applyToSet
+        (
+            const topoSetSource::setAction action,
+            topoSet& set
+        ) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/pointSources/topoSetPointSource/topoSetPointSource.H b/src/meshTools/sets/pointSources/topoSetPointSource/topoSetPointSource.H
index 627b0621ed29fca4da82c5820db8eb6c4acec4bd..5f9fa545cccaa3cee3f2e2b4309120ef6fa2fd07 100644
--- a/src/meshTools/sets/pointSources/topoSetPointSource/topoSetPointSource.H
+++ b/src/meshTools/sets/pointSources/topoSetPointSource/topoSetPointSource.H
@@ -89,6 +89,13 @@ public:
         //- Construct from components
         explicit topoSetPointSource(const polyMesh& mesh);
 
+        //- Clone (disallowed)
+        autoPtr<topoSetPointSource> clone() const
+        {
+            NotImplemented;
+            return nullptr;
+        }
+
 
     // Selectors
 
diff --git a/src/meshTools/sets/pointSources/zoneToPoint/zoneToPoint.H b/src/meshTools/sets/pointSources/zoneToPoint/zoneToPoint.H
index 536a5797208e9ea36c643163ed4e23010667bfda..6f426c8ba4e455af55bb9ca1312ea8ebf4e6d48c 100644
--- a/src/meshTools/sets/pointSources/zoneToPoint/zoneToPoint.H
+++ b/src/meshTools/sets/pointSources/zoneToPoint/zoneToPoint.H
@@ -30,13 +30,13 @@ Description
     \heading Dictionary parameters
     \table
         Property    | Description                           | Required | Default
-        zone        | The point zone name or regex          | possibly |
         zones       | The point zone names or regexs        | possibly |
+        zone        | The point zone name or regex          | possibly |
         name        | Older specification for 'zone'        | no    |
     \endtable
 
 Note
-    Selection of multiple zones has precedence.
+    Must specify "zones", "zone" or "name" (highest to lowest precedence).
 
 SourceFiles
     zoneToPoint.C
diff --git a/src/meshTools/sets/topoSets/cellBitSet.C b/src/meshTools/sets/topoSets/cellBitSet.C
index 4838b13a6096ce2150f7f175436dd509e9095a22..af53a5a42f6743b0d9b3528d10a08fc8b189216b 100644
--- a/src/meshTools/sets/topoSets/cellBitSet.C
+++ b/src/meshTools/sets/topoSets/cellBitSet.C
@@ -25,7 +25,6 @@ License
 
 #include "cellBitSet.H"
 #include "polyMesh.H"
-#include "Time.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -45,119 +44,31 @@ Foam::cellBitSet::cellBitSet(const polyMesh& mesh)
 
 Foam::cellBitSet::cellBitSet(const polyMesh& mesh, const bool val)
 :
-    topoSet
-    (
-        IOobject
-        (
-            "cellBitSet",
-            mesh.time().constant(),
-            mesh,
-            IOobject::NO_READ,
-            IOobject::NO_WRITE,
-            false
-        ),
-        0  // zero-sized (unallocated) labelHashSet
-    ),
-    selected_(mesh.nCells(), val)
+    topoBitSet(mesh, "cellBitSet", mesh.nCells(), val)
 {}
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-bool Foam::cellBitSet::found(const label id) const
-{
-    return selected_.test(id);
-}
-
-
-bool Foam::cellBitSet::set(const label id)
-{
-    return selected_.set(id);
-}
-
-
-bool Foam::cellBitSet::unset(const label id)
-{
-    return selected_.unset(id);
-}
-
-
-void Foam::cellBitSet::set(const labelUList& labels)
-{
-    selected_.set(labels);
-}
-
-
-void Foam::cellBitSet::unset(const labelUList& labels)
-{
-    selected_.unset(labels);
-}
-
-
-void Foam::cellBitSet::invert(const label maxLen)
-{
-    selected_.resize(maxLen);
-    selected_.flip();
-}
-
-
-void Foam::cellBitSet::subset(const topoSet& set)
-{
-    // Only retain entries found in both sets
-    if (isA<cellBitSet>(set))
-    {
-        selected_ &= refCast<const cellBitSet>(set).selected_;
-    }
-    else if (set.empty())
-    {
-        selected_.reset();
-    }
-    else
-    {
-        for (const label id : selected_)
-        {
-            if (!set.found(id))
-            {
-                selected_.unset(id);
-            }
-        }
-    }
-}
-
+Foam::cellBitSet::cellBitSet
+(
+    const polyMesh& mesh,
+    const bitSet& bits
+)
+:
+    topoBitSet(mesh, "cellBitSet", mesh.nCells(), bits)
+{}
 
-void Foam::cellBitSet::addSet(const topoSet& set)
-{
-    // Add entries to the set
-    if (isA<cellBitSet>(set))
-    {
-        selected_ |= refCast<const cellBitSet>(set).selected_;
-    }
-    else
-    {
-        for (const label id : set)
-        {
-            selected_.set(id);
-        }
-    }
-}
 
+Foam::cellBitSet::cellBitSet
+(
+    const polyMesh& mesh,
+    bitSet&& bits
+)
+:
+    topoBitSet(mesh, "cellBitSet", mesh.nCells(), std::move(bits))
+{}
 
-void Foam::cellBitSet::subtractSet(const topoSet& set)
-{
-    // Subtract entries from the set
-    if (isA<cellBitSet>(set))
-    {
-        selected_ -= refCast<const cellBitSet>(set).selected_;
-    }
-    else
-    {
-        for (const label id : set)
-        {
-            selected_.unset(id);
-        }
-    }
-}
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 Foam::label Foam::cellBitSet::maxSize(const polyMesh& mesh) const
 {
diff --git a/src/meshTools/sets/topoSets/cellBitSet.H b/src/meshTools/sets/topoSets/cellBitSet.H
index ba64b40595dffa4bfd347fcdb563ad41bc4363bc..d59a6157520644b9885ab843521491d2a524d86b 100644
--- a/src/meshTools/sets/topoSets/cellBitSet.H
+++ b/src/meshTools/sets/topoSets/cellBitSet.H
@@ -36,8 +36,7 @@ SourceFiles
 #ifndef cellBitSet_H
 #define cellBitSet_H
 
-#include "topoSet.H"
-#include "bitSet.H"
+#include "topoBitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -50,12 +49,8 @@ namespace Foam
 
 class cellBitSet
 :
-    public topoSet
+    public topoBitSet
 {
-    // Private data
-
-        bitSet selected_;
-
 public:
 
     //- Runtime type information
@@ -70,6 +65,12 @@ public:
         //- Construct with nCells elements, using initial val
         cellBitSet(const polyMesh& mesh, const bool val);
 
+        //- Copy construct from bitset, resizing to nCells elements as required
+        cellBitSet(const polyMesh& mesh, const bitSet& bits);
+
+        //- Move construct from bitset, resizing to nCells elements as required
+        cellBitSet(const polyMesh& mesh, bitSet&& bits);
+
 
     //- Destructor
     virtual ~cellBitSet() = default;
@@ -77,52 +78,6 @@ public:
 
     // Member Functions
 
-        //- Return the bitSet
-        const bitSet& addressing() const
-        {
-            return selected_;
-        }
-
-        //- Access the bitSet
-        bitSet& addressing()
-        {
-            return selected_;
-        }
-
-        //- Set values to false, leaving the size untouched
-        void reset()
-        {
-            selected_.reset();
-        }
-
-        //- Has the given index?
-        virtual bool found(const label id) const;
-
-        //- Set an index
-        virtual bool set(const label id);
-
-        //- Unset an index
-        virtual bool unset(const label id);
-
-        //- Set multiple indices
-        virtual void set(const labelUList& labels);
-
-        //- Unset multiple indices
-        virtual void unset(const labelUList& labels);
-
-        //- Invert contents.
-        //  Insert all members [0,maxLen) which were not in set.
-        virtual void invert(const label maxLen);
-
-        //- Subset contents. Only elements present in both sets remain.
-        virtual void subset(const topoSet& set);
-
-        //- Add elements present in set.
-        virtual void addSet(const topoSet& set);
-
-        //- Subtract elements present in set.
-        virtual void subtractSet(const topoSet& set);
-
         //- Sync cellBitSet across coupled patches.
         virtual void sync(const polyMesh& mesh)
         {}
diff --git a/src/meshTools/sets/topoSets/faceBitSet.C b/src/meshTools/sets/topoSets/faceBitSet.C
new file mode 100644
index 0000000000000000000000000000000000000000..12718c69bb53623c67fa6157df4f479e51a0236f
--- /dev/null
+++ b/src/meshTools/sets/topoSets/faceBitSet.C
@@ -0,0 +1,90 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "faceBitSet.H"
+#include "polyMesh.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(faceBitSet, 0);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::faceBitSet::faceBitSet(const polyMesh& mesh)
+:
+    faceBitSet(mesh, false)
+{}
+
+
+Foam::faceBitSet::faceBitSet(const polyMesh& mesh, const bool val)
+:
+    topoBitSet(mesh, "faceBitSet", mesh.nFaces(), val)
+{}
+
+
+Foam::faceBitSet::faceBitSet
+(
+    const polyMesh& mesh,
+    const bitSet& bits
+)
+:
+    topoBitSet(mesh, "faceBitSet", mesh.nFaces(), bits)
+{}
+
+
+Foam::faceBitSet::faceBitSet
+(
+    const polyMesh& mesh,
+    bitSet&& bits
+)
+:
+    topoBitSet(mesh, "faceBitSet", mesh.nFaces(), std::move(bits))
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::faceBitSet::maxSize(const polyMesh& mesh) const
+{
+    return mesh.nFaces();
+}
+
+
+void Foam::faceBitSet::writeDebug
+(
+    Ostream& os,
+    const primitiveMesh& mesh,
+    const label maxLen
+) const
+{
+    topoSet::writeDebug(os, mesh.faceCentres(), maxLen);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/faceBitSet.H b/src/meshTools/sets/topoSets/faceBitSet.H
new file mode 100644
index 0000000000000000000000000000000000000000..5c978862942b2816b2bdb77446d8786145973025
--- /dev/null
+++ b/src/meshTools/sets/topoSets/faceBitSet.H
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::faceBitSet
+
+Description
+    A special purpose topoSet with the face labels stored as a bitSet.
+    It does not correspond to a faceSet either (no associated IOobject).
+
+SourceFiles
+    faceBitSet.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef faceBitSet_H
+#define faceBitSet_H
+
+#include "topoBitSet.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class faceBitSet Declaration
+\*---------------------------------------------------------------------------*/
+
+class faceBitSet
+:
+    public topoBitSet
+{
+public:
+
+    //- Runtime type information
+    TypeName("faceBitSet");
+
+
+    // Constructors
+
+        //- Construct with nFaces elements, all elements unset
+        explicit faceBitSet(const polyMesh& mesh);
+
+        //- Construct with nFaces elements, using initial val
+        faceBitSet(const polyMesh& mesh, const bool val);
+
+        //- Copy construct from bitset, resizing to nFaces elements as required
+        faceBitSet(const polyMesh& mesh, const bitSet& bits);
+
+        //- Move construct from bitset, resizing to nFaces elements as required
+        faceBitSet(const polyMesh& mesh, bitSet&& bits);
+
+
+    //- Destructor
+    virtual ~faceBitSet() = default;
+
+
+    // Member Functions
+
+        //- Sync faceBitSet across coupled patches.
+        virtual void sync(const polyMesh& mesh)
+        {}
+
+        //- Return max index+1.
+        virtual label maxSize(const polyMesh& mesh) const;
+
+        //- Update any stored data for new labels.
+        virtual void updateMesh(const mapPolyMesh& morphMap)
+        {}
+
+        //- Update any stored data for mesh redistribution.
+        virtual void distribute(const mapDistributePolyMesh& map)
+        {}
+
+        //- Write maxLen items with label and coordinates.
+        virtual void writeDebug
+        (
+            Ostream& os,
+            const primitiveMesh& mesh,
+            const label maxLen
+        ) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/faceBoolSet.C b/src/meshTools/sets/topoSets/faceBoolSet.C
new file mode 100644
index 0000000000000000000000000000000000000000..8ad806e424944546fd71b8efe1af17456f64ba31
--- /dev/null
+++ b/src/meshTools/sets/topoSets/faceBoolSet.C
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "faceBoolSet.H"
+#include "polyMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(faceBoolSet, 0);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::faceBoolSet::faceBoolSet(const polyMesh& mesh)
+:
+    faceBoolSet(mesh, false)
+{}
+
+
+Foam::faceBoolSet::faceBoolSet(const polyMesh& mesh, const bool val)
+:
+    topoBoolSet(mesh, "faceBoolSet", mesh.nFaces(), val)
+{}
+
+
+Foam::faceBoolSet::faceBoolSet
+(
+    const polyMesh& mesh,
+    const boolList& bools
+)
+:
+    topoBoolSet(mesh, "faceBoolSet", mesh.nFaces(), bools)
+{}
+
+
+Foam::faceBoolSet::faceBoolSet
+(
+    const polyMesh& mesh,
+    boolList&& bools
+)
+:
+    topoBoolSet(mesh, "faceBoolSet", mesh.nFaces(), std::move(bools))
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::label Foam::faceBoolSet::maxSize(const polyMesh& mesh) const
+{
+    return mesh.nFaces();
+}
+
+
+void Foam::faceBoolSet::writeDebug
+(
+    Ostream& os,
+    const primitiveMesh& mesh,
+    const label maxLen
+) const
+{
+    topoSet::writeDebug(os, mesh.faceCentres(), maxLen);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/faceBoolSet.H b/src/meshTools/sets/topoSets/faceBoolSet.H
new file mode 100644
index 0000000000000000000000000000000000000000..e4cf69997d02b6343fdfe14d6a83559c1790c7ca
--- /dev/null
+++ b/src/meshTools/sets/topoSets/faceBoolSet.H
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::faceBoolSet
+
+Description
+    A special purpose topoSet with the face labels stored as a boolList.
+    It does not correspond to a faceSet either (no associated IOobject).
+
+SourceFiles
+    faceBoolSet.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef faceBoolSet_H
+#define faceBoolSet_H
+
+#include "topoBoolSet.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class faceBoolSet Declaration
+\*---------------------------------------------------------------------------*/
+
+class faceBoolSet
+:
+    public topoBoolSet
+{
+public:
+
+    //- Runtime type information
+    TypeName("faceBoolSet");
+
+
+    // Constructors
+
+        //- Construct with nFaces elements, all elements unset
+        explicit faceBoolSet(const polyMesh& mesh);
+
+        //- Construct with nFaces elements, using initial val
+        faceBoolSet(const polyMesh& mesh, const bool val);
+
+        //- Copy construct from list, resizing to nFaces elements as required
+        faceBoolSet(const polyMesh& mesh, const boolList& bools);
+
+        //- Move construct from list, resizing to nFaces elements as required
+        faceBoolSet(const polyMesh& mesh, boolList&& bools);
+
+
+    //- Destructor
+    virtual ~faceBoolSet() = default;
+
+
+    // Member Functions
+
+        //- Sync faceBoolSet across coupled patches.
+        virtual void sync(const polyMesh& mesh)
+        {}
+
+        //- Return max index+1.
+        virtual label maxSize(const polyMesh& mesh) const;
+
+        //- Update any stored data for new labels.
+        virtual void updateMesh(const mapPolyMesh& morphMap)
+        {}
+
+        //- Update any stored data for mesh redistribution.
+        virtual void distribute(const mapDistributePolyMesh& map)
+        {}
+
+        //- Write maxLen items with label and coordinates.
+        virtual void writeDebug
+        (
+            Ostream& os,
+            const primitiveMesh& mesh,
+            const label maxLen
+        ) const;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/topoBitSet.C b/src/meshTools/sets/topoSets/topoBitSet.C
new file mode 100644
index 0000000000000000000000000000000000000000..a90d9d02f1e45dc8df1a67ab033afc3136f61b44
--- /dev/null
+++ b/src/meshTools/sets/topoSets/topoBitSet.C
@@ -0,0 +1,196 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "topoBitSet.H"
+#include "polyMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::topoBitSet::topoBitSet
+(
+    const polyMesh& mesh,
+    const word& setName
+)
+:
+    topoSet
+    (
+        IOobject
+        (
+            setName,
+            mesh.time().constant(),
+            mesh,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            false
+        ),
+        0  // zero-sized (unallocated) labelHashSet
+    ),
+    selected_()
+{}
+
+
+Foam::topoBitSet::topoBitSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    const bool val
+)
+:
+    topoBitSet(mesh, setName)
+{
+    selected_.resize(size, val);
+}
+
+
+Foam::topoBitSet::topoBitSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    const bitSet& bits
+)
+:
+    topoBitSet(mesh, setName)
+{
+    selected_ = bits;
+    selected_.resize(size);
+}
+
+
+Foam::topoBitSet::topoBitSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    bitSet&& bits
+)
+:
+    topoBitSet(mesh, setName)
+{
+    selected_ = std::move(bits);
+    selected_.resize(size);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::topoBitSet::found(const label id) const
+{
+    return selected_.test(id);
+}
+
+
+bool Foam::topoBitSet::set(const label id)
+{
+    return selected_.set(id);
+}
+
+
+bool Foam::topoBitSet::unset(const label id)
+{
+    return selected_.unset(id);
+}
+
+
+void Foam::topoBitSet::set(const labelUList& labels)
+{
+    selected_.set(labels);
+}
+
+
+void Foam::topoBitSet::unset(const labelUList& labels)
+{
+    selected_.unset(labels);
+}
+
+
+void Foam::topoBitSet::invert(const label maxLen)
+{
+    selected_.resize(maxLen);
+    selected_.flip();
+}
+
+
+void Foam::topoBitSet::subset(const topoSet& set)
+{
+    // Only retain entries found in both sets
+    if (isA<topoBitSet>(set))
+    {
+        selected_ &= refCast<const topoBitSet>(set).selected_;
+    }
+    else if (set.empty())
+    {
+        selected_.reset();
+    }
+    else
+    {
+        for (const label id : selected_)
+        {
+            if (!set.found(id))
+            {
+                selected_.unset(id);
+            }
+        }
+    }
+}
+
+
+void Foam::topoBitSet::addSet(const topoSet& set)
+{
+    // Add entries to the set
+    if (isA<topoBitSet>(set))
+    {
+        selected_ |= refCast<const topoBitSet>(set).selected_;
+    }
+    else
+    {
+        for (const label id : set)
+        {
+            selected_.set(id);
+        }
+    }
+}
+
+
+void Foam::topoBitSet::subtractSet(const topoSet& set)
+{
+    // Subtract entries from the set
+    if (isA<topoBitSet>(set))
+    {
+        selected_ -= refCast<const topoBitSet>(set).selected_;
+    }
+    else
+    {
+        for (const label id : set)
+        {
+            selected_.unset(id);
+        }
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/topoBitSet.H b/src/meshTools/sets/topoSets/topoBitSet.H
new file mode 100644
index 0000000000000000000000000000000000000000..e73b4621e90768ce4bfce5ba1f404d48c9a2bd54
--- /dev/null
+++ b/src/meshTools/sets/topoSets/topoBitSet.H
@@ -0,0 +1,159 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::topoBitSet
+
+Description
+    Base for a special purpose topoSet using labels stored as a bitSet.
+
+SourceFiles
+    topoBitSet.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef topoBitSet_H
+#define topoBitSet_H
+
+#include "topoSet.H"
+#include "bitSet.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class topoBitSet Declaration
+\*---------------------------------------------------------------------------*/
+
+class topoBitSet
+:
+    public topoSet
+{
+protected:
+
+    // Protected data
+
+        bitSet selected_;
+
+
+    // Protected Member Functions
+
+        //- Construct with empty selection
+        topoBitSet(const polyMesh& mesh, const word& setName);
+
+        //- Construct with size elements
+        topoBitSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            const bool val
+        );
+
+        //- Copy construct with bitset values, size elements
+        topoBitSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            const bitSet& bits
+        );
+
+        //- Move construct with bitset values, size elements
+        topoBitSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            bitSet&& bits
+        );
+
+
+public:
+
+    //- Destructor
+    virtual ~topoBitSet() = default;
+
+
+    // Member Functions
+
+        //- Return the bitSet
+        const bitSet& addressing() const
+        {
+            return selected_;
+        }
+
+        //- Access the bitSet
+        bitSet& addressing()
+        {
+            return selected_;
+        }
+
+        //- Set values to false, leaving the size untouched
+        void reset()
+        {
+            selected_.reset();
+        }
+
+        //- Has the given index?
+        virtual bool found(const label id) const;
+
+        //- Set an index
+        virtual bool set(const label id);
+
+        //- Unset an index
+        virtual bool unset(const label id);
+
+        //- Set multiple indices
+        virtual void set(const labelUList& labels);
+
+        //- Unset multiple indices
+        virtual void unset(const labelUList& labels);
+
+        //- Invert contents.
+        //  Insert all members [0,maxLen) which were not in set.
+        virtual void invert(const label maxLen);
+
+        //- Subset contents. Only elements present in both sets remain.
+        virtual void subset(const topoSet& set);
+
+        //- Add elements present in set.
+        virtual void addSet(const topoSet& set);
+
+        //- Subtract elements present in set.
+        virtual void subtractSet(const topoSet& set);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/topoBoolSet.C b/src/meshTools/sets/topoSets/topoBoolSet.C
new file mode 100644
index 0000000000000000000000000000000000000000..bc08fdb3dd9342aeca52ed9d378ce0a52158a928
--- /dev/null
+++ b/src/meshTools/sets/topoSets/topoBoolSet.C
@@ -0,0 +1,184 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "topoBoolSet.H"
+#include "polyMesh.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::topoBoolSet::topoBoolSet
+(
+    const polyMesh& mesh,
+    const word& setName
+)
+:
+    topoSet
+    (
+        IOobject
+        (
+            setName,
+            mesh.time().constant(),
+            mesh,
+            IOobject::NO_READ,
+            IOobject::NO_WRITE,
+            false
+        ),
+        0  // zero-sized (unallocated) labelHashSet
+    ),
+    selected_()
+{}
+
+
+Foam::topoBoolSet::topoBoolSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    const bool val
+)
+:
+    topoBoolSet(mesh, setName)
+{
+    selected_.resize(size, val);
+}
+
+
+Foam::topoBoolSet::topoBoolSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    const boolList& bools
+)
+:
+    topoBoolSet(mesh, setName)
+{
+    selected_ = bools;
+    selected_.resize(size);
+}
+
+
+Foam::topoBoolSet::topoBoolSet
+(
+    const polyMesh& mesh,
+    const word& setName,
+    const label size,
+    boolList&& bools
+)
+:
+    topoBoolSet(mesh, setName)
+{
+    selected_ = std::move(bools);
+    selected_.resize(size);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::topoBoolSet::found(const label id) const
+{
+    return selected_.test(id);
+}
+
+
+bool Foam::topoBoolSet::set(const label id)
+{
+    return selected_.set(id);
+}
+
+
+bool Foam::topoBoolSet::unset(const label id)
+{
+    return selected_.unset(id);
+}
+
+
+void Foam::topoBoolSet::set(const labelUList& labels)
+{
+    for (const label id : labels)
+    {
+        selected_[id] = true;
+    }
+}
+
+
+void Foam::topoBoolSet::unset(const labelUList& labels)
+{
+    for (const label id : labels)
+    {
+        selected_.unset(id);
+    }
+}
+
+
+void Foam::topoBoolSet::invert(const label maxLen)
+{
+    selected_.resize(maxLen);
+    for (bool& b : selected_)
+    {
+        b = !b;
+    }
+}
+
+
+void Foam::topoBoolSet::subset(const topoSet& set)
+{
+    // Only retain entries found in both sets
+    if (set.empty())
+    {
+        selected_ = false;
+    }
+    else
+    {
+        forAll(selected_, i)
+        {
+            selected_[i] = (selected_[i] && set.found(i));
+        }
+    }
+}
+
+
+void Foam::topoBoolSet::addSet(const topoSet& set)
+{
+    // Add entries to the set
+    for (const label id : set)
+    {
+        selected_[id] = true;
+    }
+}
+
+
+void Foam::topoBoolSet::subtractSet(const topoSet& set)
+{
+    // Subtract entries from the set
+    for (const label id : set)
+    {
+        selected_.unset(id);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/sets/topoSets/topoBoolSet.H b/src/meshTools/sets/topoSets/topoBoolSet.H
new file mode 100644
index 0000000000000000000000000000000000000000..d7b93c4f2f19fe343d8a686c0bb0dd85cde04ee6
--- /dev/null
+++ b/src/meshTools/sets/topoSets/topoBoolSet.H
@@ -0,0 +1,159 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::topoBoolSet
+
+Description
+    Base for a special purpose topoSet using labels stored as a boolList.
+
+SourceFiles
+    topoBoolSet.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef topoBoolSet_H
+#define topoBoolSet_H
+
+#include "topoSet.H"
+#include "boolList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                           Class topoBoolSet Declaration
+\*---------------------------------------------------------------------------*/
+
+class topoBoolSet
+:
+    public topoSet
+{
+protected:
+
+    // Protected data
+
+        boolList selected_;
+
+
+    // Protected Member Functions
+
+        //- Construct with empty selection
+        topoBoolSet(const polyMesh& mesh, const word& setName);
+
+        //- Construct with size elements
+        topoBoolSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            const bool val
+        );
+
+        //- Copy construct with list values, size elements
+        topoBoolSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            const boolList& bools
+        );
+
+        //- Move construct with list values, size elements
+        topoBoolSet
+        (
+            const polyMesh& mesh,
+            const word& setName,
+            const label size,
+            boolList&& bools
+        );
+
+
+public:
+
+    //- Destructor
+    virtual ~topoBoolSet() = default;
+
+
+    // Member Functions
+
+        //- Return the boolList
+        const boolList& addressing() const
+        {
+            return selected_;
+        }
+
+        //- Access the boolList
+        boolList& addressing()
+        {
+            return selected_;
+        }
+
+        //- Set values to false, leaving the size untouched
+        void reset()
+        {
+            selected_ = false;
+        }
+
+        //- Has the given index?
+        virtual bool found(const label id) const;
+
+        //- Set an index
+        virtual bool set(const label id);
+
+        //- Unset an index
+        virtual bool unset(const label id);
+
+        //- Set multiple indices
+        virtual void set(const labelUList& labels);
+
+        //- Unset multiple indices
+        virtual void unset(const labelUList& labels);
+
+        //- Invert contents.
+        //  Insert all members [0,maxLen) which were not in set.
+        virtual void invert(const label maxLen);
+
+        //- Subset contents. Only elements present in both sets remain.
+        virtual void subset(const topoSet& set);
+
+        //- Add elements present in set.
+        virtual void addSet(const topoSet& set);
+
+        //- Subtract elements present in set.
+        virtual void subtractSet(const topoSet& set);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //