diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
index 3313726b9f0643512a56dcb919837454d9f2ae05..e1f9707cd4b74db25547d3a7f25776bd6c9afeda 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
@@ -1087,28 +1087,6 @@ int main(int argc, char *argv[])
     }
 
 
-    // Optionally read directional refinement shells
-    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    const dictionary dirRefDict
-    (
-        refineDict.subOrEmptyDict("directionalRefinementRegions")
-    );
-
-    if (!dirRefDict.empty())
-    {
-        Info<< "Reading directional refinement shells." << endl;
-    }
-
-    shellSurfaces dirShells(allGeometry, dirRefDict);
-
-    if (!dirRefDict.empty())
-    {
-        Info<< "Read directional refinement shells in = "
-            << mesh.time().cpuTimeIncrement() << " s" << nl << endl;
-    }
-
-
 
     // Read feature meshes
     // ~~~~~~~~~~~~~~~~~~~
@@ -1141,7 +1119,6 @@ int main(int argc, char *argv[])
         surfaces,           // for surface intersection refinement
         features,           // for feature edges/point based refinement
         shells,             // for volume (inside/outside) refinement
-        dirShells,          // vol volume directional refinement
         limitShells         // limit of volume refinement
     );
     Info<< "Calculated surface intersections in = "
diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
index 640aaa97901772df20da333685d1f4c240008d88..ef6b70f4249036ac62e9bcae624580eedd2b70c4 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict
@@ -50,7 +50,7 @@ geometry
     }
 
     // Shell for directional refinement
-    refinementBox
+    wakeBox
     {
         type searchableBox;
         min (1.5 1 -0.5);
@@ -265,8 +265,8 @@ castellatedMeshControls
         //    mode inside;
         //    levels ((1.0 4));
         //    // Optional override of uniform refinement level such
-        //    //  that in small gaps we're getting more cells.
-        //    //  The specification is
+        //    // that in small gaps we're getting more cells.
+        //    // The specification is
         //    //  - numGapCells : minimum number of cells in the gap
         //    //                  (usually >3; lower than this might not
         //    //                   resolve correctly)
@@ -283,20 +283,29 @@ castellatedMeshControls
         //    //           whilst doing the gap-level refinement.
         //    //gapMode inside;  // inside/outside/mixed
         //}
-    }
-
 
-    directionalRefinementRegions
-    {
-        refinementBox       // Closed surface
-        {
-            mode inside;
-            levelIncrement  // Specification of additional refinement
-            (
-                (0 (1 0 0)) // For level 0 cells: add one level refinement in x
-                (1 (1 0 0)) // For level 1 cells: add one level refinement in x
-            );
-        }
+        //wakeBox
+        //{
+        //    mode        inside;
+        //    // Dummy base level
+        //    levels      ((10000 0));
+        //
+        //    // Optional directional refinement (after all other refinement)
+        //    // Directional refinement
+        //    // for all cells according to 'mode' ('inside' or 'outside';
+        //    // 'distance' not supported) and within certain range. E.g.
+        //    //  - for all cells with level 2-5
+        //    //  - do one split in x direction
+        //    levelIncrement  (2 5 (1 0 0));
+        //
+        //    // Note
+        //    // - ignores 'levels' and gap* settings.
+        //    // - the cellLevel/pointLevels files are no longer consistent
+        //    //   with the mesh, the resulting mesh is no longer compatible
+        //    //   with e.g. dynamic refinement/unrefinement.
+        //    // - cellLevel will include any directional refinement
+        //    //   (i.e. it will be the maximum of all three directions)
+        //}
     }
 
 
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
index 8cfe94a498d35bdb51dceecab69158f929ae4ef4..98a26202310e22ab913f9061737e3abc6f956a36 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
@@ -1222,7 +1222,6 @@ Foam::meshRefinement::meshRefinement
     const refinementSurfaces& surfaces,
     const refinementFeatures& features,
     const shellSurfaces& shells,
-    const shellSurfaces& dirShells,
     const shellSurfaces& limitShells
 )
 :
@@ -1233,7 +1232,6 @@ Foam::meshRefinement::meshRefinement
     surfaces_(surfaces),
     features_(features),
     shells_(shells),
-    dirShells_(dirShells),
     limitShells_(limitShells),
     meshCutter_
     (
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
index e7c88838888093c8ccd19f4c3e898345e5674ff5..1d9e724825508a7c804887dca607a366ffd9b037 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
@@ -161,9 +161,6 @@ private:
         //- All shell-refinement interaction
         const shellSurfaces& shells_;
 
-        //- All directional shell-refinement interaction
-        const shellSurfaces& dirShells_;
-
         //- All limit-refinement interaction
         const shellSurfaces& limitShells_;
 
@@ -811,7 +808,6 @@ public:
             const refinementSurfaces&,
             const refinementFeatures&,
             const shellSurfaces&,   // omnidirectional refinement
-            const shellSurfaces&,   // directional refinement
             const shellSurfaces&    // limit refinement
         );
 
@@ -865,12 +861,6 @@ public:
                 return shells_;
             }
 
-            //- Reference to directional shell-refinement shells
-            const shellSurfaces& dirShells() const
-            {
-                return dirShells_;
-            }
-
             //- Reference to meshcutting engine
             const hexRef8& meshCutter() const
             {
diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C
index b984ef4f10ddbdee3ebcf2dc278b57290f08e970..d6e2cba492337260d2d53e77c741c0204086813e 100644
--- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C
+++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C
@@ -619,8 +619,29 @@ Foam::shellSurfaces::shellSurfaces
             // Directional refinement
             // ~~~~~~~~~~~~~~~~~~~~~~
 
-            if (dict.readIfPresent("levelIncrement", dirLevels_[shellI]))
+            dirLevels_[shellI] = Tuple2<labelPair,labelVector>
+            (
+                labelPair(labelMax, labelMin),
+                labelVector::zero
+            );
+            const entry* levelPtr = dict.lookupEntryPtr
+            (
+                "levelIncrement",
+                false,
+                true
+            );
+            if (levelPtr)
             {
+                // Do reading ourselves since using labelPair would require
+                // additional bracket pair
+                Istream& is = levelPtr->stream();
+
+                is.readBegin("levelIncrement");
+                is  >> dirLevels_[shellI].first().first()
+                    >> dirLevels_[shellI].first().second()
+                    >> dirLevels_[shellI].second();
+                is.readEnd("levelIncrement");
+
                 if (modes_[shellI] == INSIDE)
                 {
                     Info<< "Additional directional refinement level"
@@ -771,6 +792,17 @@ Foam::labelList Foam::shellSurfaces::maxGapLevel() const
 }
 
 
+Foam::labelPairList Foam::shellSurfaces::directionalSelectLevel() const
+{
+    labelPairList levels(dirLevels_.size());
+    forAll(dirLevels_, shelli)
+    {
+        levels[shelli] = dirLevels_[shelli].first();
+    }
+    return levels;
+}
+
+
 void Foam::shellSurfaces::findHigherLevel
 (
     const pointField& pt,
@@ -871,33 +903,31 @@ void Foam::shellSurfaces::findDirectionalLevel
     {
         if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
         {
-            const LevelAndDirList& shellLevels = dirLevels_[shelli];
+            const labelPair& selectLevels = dirLevels_[shelli].first();
+            const label addLevel = dirLevels_[shelli].second()[dir];
 
             // Collect the cells that are of the right original level
             candidateMap.clear();
             forAll(ptLevel, celli)
             {
                 label level = ptLevel[celli];
-                forAll(shellLevels, leveli)
-                {
-                    label selectLevel = shellLevels[leveli].first();
-                    label addLevel = shellLevels[leveli].second()[dir];
 
-                    if
-                    (
-                        level == selectLevel
-                     && dirLevel[celli] < level+addLevel
-                    )
-                    {
-                        candidateMap.append(celli);
-                        break;
-                    }
+                if
+                (
+                    level >= selectLevels.first()
+                 && level <= selectLevels.second()
+                 && dirLevel[celli] < level+addLevel
+                )
+                {
+                    candidateMap.append(celli);
                 }
             }
 
+            // Do geometric test
             pointField candidatePt(pt, candidateMap);
             allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
 
+            // Extract selected cells
             forAll(candidateMap, i)
             {
                 if
diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H
index 647a18b2bcbae9e3da10e1a32fe8f92694130d5d..de3edb7c02fb754e1e0cbe13c099dd7fcc2f256e 100644
--- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H
+++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H
@@ -46,10 +46,6 @@ SourceFiles
 namespace Foam
 {
 
-typedef Tuple2<label,labelVector> LevelAndDir;
-typedef List<LevelAndDir> LevelAndDirList;
-typedef List<LevelAndDirList> LevelAndDirListList;
-
 class searchableSurfaces;
 
 /*---------------------------------------------------------------------------*\
@@ -90,8 +86,8 @@ private:
         //- Per shell per distance the refinement level
         labelListList levels_;
 
-        //- Per shell, per refinement level additional directional refinement
-        LevelAndDirListList dirLevels_;
+        //- Per shell any additional directional refinement
+        List<Tuple2<labelPair,labelVector>> dirLevels_;
 
 
         // Gap level refinement
@@ -179,14 +175,6 @@ public:
                 return shells_;
             }
 
-            //- Raw access to directional refinement
-            //  Per shell a list of (level + additional level)
-            const LevelAndDirListList& dirLevels() const
-            {
-                return dirLevels_;
-            }
-
-
         // Query
 
             //- Highest shell level
@@ -195,6 +183,9 @@ public:
             //- Highest shell gap level
             labelList maxGapLevel() const;
 
+            //- Min and max cell level for directional refinement
+            labelPairList directionalSelectLevel() const;
+
             //- Find shell level higher than ptLevel
             void findHigherLevel
             (
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
index d6846f68fb2644d355634682dba95269eff649db..cd08d209fd39042dd9f8d754701ddecceda45304 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyRefineDriver.C
@@ -1766,7 +1766,7 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
 {
     addProfiling(shell, "snappyHexMesh::refine::directionalShell");
     const fvMesh& mesh = meshRefiner_.mesh();
-    const shellSurfaces& shells = meshRefiner_.dirShells();
+    const shellSurfaces& shells = meshRefiner_.shells();
 
     labelList& cellLevel =
         const_cast<labelIOList&>(meshRefiner_.meshCutter().cellLevel());
@@ -1774,19 +1774,13 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
 
     // Determine the minimum and maximum cell levels that are candidates for
     // directional refinement
+    const labelPairList dirSelect(shells.directionalSelectLevel());
     label overallMinLevel = labelMax;
     label overallMaxLevel = labelMin;
+    forAll(dirSelect, shelli)
     {
-        const LevelAndDirListList& dirLevels = shells.dirLevels();
-        forAll(dirLevels, shelli)
-        {
-            const LevelAndDirList& dirLevel = dirLevels[shelli];
-            forAll(dirLevel, i)
-            {
-                overallMinLevel = min(dirLevel[i].first(), overallMinLevel);
-                overallMaxLevel = max(dirLevel[i].first(), overallMaxLevel);
-            }
-        }
+        overallMinLevel = min(dirSelect[shelli].first(), overallMinLevel);
+        overallMaxLevel = max(dirSelect[shelli].second(), overallMaxLevel);
     }
 
     if (overallMinLevel > overallMaxLevel)
@@ -1889,43 +1883,45 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
             // iterations and not enough cells to refine.
             if (nCellsToRefine == 0)
             {
-                Info<< "Not refining direction " << dir
-                    << " since too few cells selected."
-                    << nl << endl;
-                break;
+                //Info<< "Not refining direction " << dir
+                //    << " since too few cells selected." << nl << endl;
             }
-
-
-            if (debug)
+            else
             {
-                const_cast<Time&>(mesh.time())++;
-            }
+                if (debug)
+                {
+                    const_cast<Time&>(mesh.time())++;
+                }
 
-            PackedBoolList isRefineCell(mesh.nCells());
-            isRefineCell.set(cellsToRefine);
+                PackedBoolList isRefineCell(mesh.nCells());
+                isRefineCell.set(cellsToRefine);
 
-            autoPtr<mapPolyMesh> map
-            (
-                meshRefiner_.directionalRefine
+                autoPtr<mapPolyMesh> map
                 (
-                    "directional refinement iteration " + name(iter),
-                    dir,
-                    cellsToRefine
-                )
-            );
+                    meshRefiner_.directionalRefine
+                    (
+                        "directional refinement iteration " + name(iter),
+                        dir,
+                        cellsToRefine
+                    )
+                );
 
-            meshRefinement::updateList
-            (
-                map().cellMap(),
-                labelVector(0, 0, 0),
-                dirCellLevel
-            );
+                Info<< "Refined mesh in = "
+                    << mesh.time().cpuTimeIncrement() << " s" << endl;
 
-            forAll(map().cellMap(), celli)
-            {
-                if (isRefineCell[map().cellMap()[celli]])
+                meshRefinement::updateList
+                (
+                    map().cellMap(),
+                    labelVector(0, 0, 0),
+                    dirCellLevel
+                );
+
+                forAll(map().cellMap(), celli)
                 {
-                    dirCellLevel[celli][dir]++;
+                    if (isRefineCell[map().cellMap()[celli]])
+                    {
+                        dirCellLevel[celli][dir]++;
+                    }
                 }
             }
         }
@@ -1946,8 +1942,8 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
 
         if (debug&meshRefinement::MESH)
         {
-            Pout<< "Writing directional refinement iteration " + name(iter)
-                << " mesh to time " << meshRefiner_.timeName() << endl;
+            Pout<< "Writing directional refinement iteration "
+                << iter << " mesh to time " << meshRefiner_.timeName() << endl;
             meshRefiner_.write
             (
                 meshRefinement::debugType(debug),
@@ -1961,8 +1957,16 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
         }
     }
 
-    // Adjust cellLevel from dirLevel?
-    // Is cellLevel the max of dirLevel? Or the min?
+    // Adjust cellLevel from dirLevel? As max? Or the min?
+    // For now: use max. The idea is that if there is a wall
+    // any directional refinement is likely to be aligned with
+    // the wall (wall layers) so any snapping/layering would probably
+    // want to use this highest refinement level.
+
+    forAll(cellLevel, celli)
+    {
+        cellLevel[celli] = cmptMax(dirCellLevel[celli]);
+    }
 
     return iter;
 }