From 8939a55653c636358b22e5ed58acd493560546d7 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Mon, 5 Oct 2020 12:30:41 +0200
Subject: [PATCH] ENH: relocate blockMesh polyMesh generation into library (for
 code reuse)

STYLE: adjust blockMesh advanced/non-advanced options

- make -merge-points "non-advanced" (for better exposure)
- make -write-obj "advanced" (-write-vtk is preferred)
---
 .../mesh/generation/blockMesh/addCellZones.H  |  88 +-----------
 .../mesh/generation/blockMesh/blockMesh.C     |  73 +++-------
 .../blockMesh/handleCyclicPatches.H           |  22 +++
 .../generation/blockMesh/mergePatchPairs.H    |  42 +++---
 src/mesh/blockMesh/blockMesh/blockMesh.C      |  12 +-
 src/mesh/blockMesh/blockMesh/blockMesh.H      |  36 +++--
 .../blockMesh/blockMesh/blockMeshCreate.C     | 128 +++++++++++++++++-
 7 files changed, 225 insertions(+), 176 deletions(-)
 create mode 100644 applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H

diff --git a/applications/utilities/mesh/generation/blockMesh/addCellZones.H b/applications/utilities/mesh/generation/blockMesh/addCellZones.H
index eca57f2ed4a..7cec1b4541d 100644
--- a/applications/utilities/mesh/generation/blockMesh/addCellZones.H
+++ b/applications/utilities/mesh/generation/blockMesh/addCellZones.H
@@ -1,87 +1 @@
-// Set any cellZones
-// Note cell labelling unaffected by previous mergePatchPairs
-
-{
-    const label nZones = blocks.numZonedBlocks();
-    if (nZones)
-    {
-        Info<< nl << "Adding cell zones" << endl;
-
-        // Map from zoneName to cellZone index
-        HashTable<label> zoneMap(nZones);
-
-        // Cells per zone.
-        List<DynamicList<label>> zoneCells(nZones);
-
-        // Running cell counter
-        label celli = 0;
-
-        // Largest zone so far
-        label freeZoneI = 0;
-
-        for (const block& b : blocks)
-        {
-            const word& zoneName = b.zoneName();
-            const label nCellsInBlock = b.cells().size();
-
-            if (zoneName.size())
-            {
-                const auto iter = zoneMap.cfind(zoneName);
-
-                label zonei;
-
-                if (iter.found())
-                {
-                    zonei = *iter;
-                }
-                else
-                {
-                    zonei = freeZoneI++;
-
-                    Info<< "    " << zonei << '\t' << zoneName << endl;
-
-                    zoneMap.insert(zoneName, zonei);
-                }
-
-
-                // Fill with cell ids
-
-                zoneCells[zonei].reserve
-                (
-                    zoneCells[zonei].size() + nCellsInBlock
-                );
-
-                const label endOfFill = celli + nCellsInBlock;
-
-                for (; celli < endOfFill; ++celli)
-                {
-                    zoneCells[zonei].append(celli);
-                }
-            }
-            else
-            {
-                celli += nCellsInBlock;
-            }
-        }
-
-        List<cellZone*> cz(zoneMap.size());
-        forAllConstIters(zoneMap, iter)
-        {
-            const word& zoneName = iter.key();
-            const label zonei = iter.val();
-
-            cz[zonei] = new cellZone
-            (
-                zoneName,
-                zoneCells[zonei].shrink(),
-                zonei,
-                mesh.cellZones()
-            );
-        }
-
-        mesh.pointZones().resize(0);
-        mesh.faceZones().resize(0);
-        mesh.cellZones().resize(0);
-        mesh.addZones(List<pointZone*>(), List<faceZone*>(), cz);
-    }
-}
+#warning File removed - left for old dependency check only
diff --git a/applications/utilities/mesh/generation/blockMesh/blockMesh.C b/applications/utilities/mesh/generation/blockMesh/blockMesh.C
index 0eec9f01b8e..b510d911705 100644
--- a/applications/utilities/mesh/generation/blockMesh/blockMesh.C
+++ b/applications/utilities/mesh/generation/blockMesh/blockMesh.C
@@ -77,7 +77,6 @@ Usage
 #include "foamVtkInternalMeshWriter.H"
 #include "attachPolyTopoChanger.H"
 #include "polyTopoChange.H"
-#include "emptyPolyPatch.H"
 #include "cyclicPolyPatch.H"
 #include "cellSet.H"
 
@@ -85,7 +84,7 @@ Usage
 #include "OSspecific.H"
 #include "OFstream.H"
 
-#include "Pair.H"
+#include "wordPair.H"
 #include "slidingInterface.H"
 
 using namespace Foam;
@@ -122,7 +121,8 @@ int main(int argc, char *argv[])
     argList::addBoolOption
     (
         "write-obj",
-        "Write block edges and centres as obj files and exit"
+        "Write block edges and centres as obj files and exit",
+        true  // (old) mark as advanced option. -write-vtk is preferred
     );
     argList::addOptionCompat("write-obj", {"blockTopology", 1912});
 
@@ -135,9 +135,9 @@ int main(int argc, char *argv[])
     argList::addBoolOption
     (
         "merge-points",
-        "Geometric (point) merging instead of topological merging "
-        "(slower, fails with high-aspect cells. default for 1912 and earlier)",
-        true  // mark as an advanced option
+        "Geometric point merging instead of topological merging"
+        " [default for 1912 and earlier]."
+        // NOTE: " Slower, fails with high-aspect cells."
     );
     argList::addBoolOption
     (
@@ -164,6 +164,9 @@ int main(int argc, char *argv[])
     // Remove old files, unless disabled
     const bool removeOldFiles = !args.found("noClean");
 
+    // Write cellSets
+    const bool writeCellSets = args.found("sets");
+
     // Default merge (topology), unless otherwise specified
     blockMesh::mergeStrategy strategy(blockMesh::DEFAULT_MERGE);
 
@@ -329,56 +332,22 @@ int main(int argc, char *argv[])
     }
 
 
-    Info<< nl << "Creating polyMesh from blockMesh" << endl;
+    // Ensure we get information messages, even if turned off in dictionary
+    blocks.verbose(true);
 
-    polyMesh mesh
-    (
-        IOobject
+    autoPtr<polyMesh> meshPtr =
+        blocks.mesh
         (
-            regionName,
-            meshInstance,
-            runTime
-        ),
-        pointField(blocks.points()),  // Copy, could we re-use space?
-        blocks.cells(),
-        blocks.patches(),
-        blocks.patchNames(),
-        blocks.patchDicts(),
-        "defaultFaces",               // Default patch name
-        emptyPolyPatch::typeName      // Default patch type
-    );
+            IOobject(regionName, meshInstance, runTime)
+        );
 
+    polyMesh& mesh = *meshPtr;
 
-    // Handle merging of patch pairs. Dictionary entry "mergePatchPairs"
+    // Merge patch pairs (dictionary entry "mergePatchPairs")
     #include "mergePatchPairs.H"
 
-    // Set any cellZones
-    #include "addCellZones.H"
-
-
-    // Detect any cyclic patches and force re-ordering of the faces
-    {
-        bool hasCyclic = false;
-        for (const polyPatch& pp : mesh.boundaryMesh())
-        {
-            if (isA<cyclicPolyPatch>(pp))
-            {
-                hasCyclic = true;
-                break;
-            }
-        }
-
-        if (hasCyclic)
-        {
-            Info<< nl << "Detected cyclic patches; ordering boundary faces"
-                << endl;
-            const word oldInstance = mesh.instance();
-            polyTopoChange meshMod(mesh);
-            meshMod.changeMesh(mesh, false);
-            mesh.setInstance(oldInstance);
-        }
-    }
-
+    // Handle cyclic patches
+    #include "handleCyclicPatches.H"
 
     // Set the precision of the points data to 10
     IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
@@ -386,7 +355,7 @@ int main(int argc, char *argv[])
     Info<< nl << "Writing polyMesh with "
         << mesh.cellZones().size() << " cellZones";
 
-    if (args.found("sets") && !mesh.cellZones().empty())
+    if (writeCellSets && !mesh.cellZones().empty())
     {
         Info<< " (written as cellSets too)";
     }
@@ -400,7 +369,7 @@ int main(int argc, char *argv[])
             << exit(FatalError);
     }
 
-    if (args.found("sets"))
+    if (writeCellSets)
     {
         for (const cellZone& cz : mesh.cellZones())
         {
diff --git a/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H b/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H
new file mode 100644
index 00000000000..eb79d02de20
--- /dev/null
+++ b/applications/utilities/mesh/generation/blockMesh/handleCyclicPatches.H
@@ -0,0 +1,22 @@
+// Detect any cyclic patches and force re-ordering of the faces
+{
+    bool hasCyclic = false;
+    for (const polyPatch& pp : mesh.boundaryMesh())
+    {
+        if (isA<cyclicPolyPatch>(pp))
+        {
+            hasCyclic = true;
+            break;
+        }
+    }
+
+    if (hasCyclic)
+    {
+        Info<< nl << "Detected cyclic patches; ordering boundary faces" << endl;
+
+        const word oldInstance = mesh.instance();
+        polyTopoChange meshMod(mesh);
+        meshMod.changeMesh(mesh, false);
+        mesh.setInstance(oldInstance);
+    }
+}
diff --git a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
index 2c94bcc0fa6..be551d01f60 100644
--- a/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
+++ b/applications/utilities/mesh/generation/blockMesh/mergePatchPairs.H
@@ -1,6 +1,6 @@
 // Handle merging of patch pairs
 {
-    List<Pair<word>> mergePatchPairs;
+    wordPairList mergePatchPairs;
 
     // Read in a list of dictionaries for the merge patch pairs
     if
@@ -14,19 +14,19 @@
         // Create and add point and face zones and mesh modifiers
         List<pointZone*> pz(mergePatchPairs.size());
         List<faceZone*> fz(3*mergePatchPairs.size());
-        List<cellZone*> cz(0);
+        List<cellZone*> cz;
 
-        forAll(mergePatchPairs, pairI)
+        forAll(mergePatchPairs, pairi)
         {
             const word mergeName
             (
-                mergePatchPairs[pairI].first()
-              + mergePatchPairs[pairI].second()
-              + name(pairI)
+                mergePatchPairs[pairi].first()
+              + mergePatchPairs[pairi].second()
+              + name(pairi)
             );
 
             // An empty zone for cut points
-            pz[pairI] = new pointZone
+            pz[pairi] = new pointZone
             (
                 mergeName + "CutPointZone",
                 0,
@@ -34,11 +34,11 @@
             );
 
             // Master patch
-            const word masterPatchName(mergePatchPairs[pairI].first());
+            const word masterPatchName(mergePatchPairs[pairi].first());
             const polyPatch& masterPatch =
                 mesh.boundaryMesh()[masterPatchName];
 
-            fz[3*pairI] = new faceZone
+            fz[3*pairi] = new faceZone
             (
                 mergeName + "MasterZone",
                 identity(masterPatch.size(), masterPatch.start()),
@@ -48,11 +48,11 @@
             );
 
             // Slave patch
-            const word slavePatchName(mergePatchPairs[pairI].second());
+            const word slavePatchName(mergePatchPairs[pairi].second());
             const polyPatch& slavePatch =
                 mesh.boundaryMesh()[slavePatchName];
 
-            fz[3*pairI + 1] = new faceZone
+            fz[3*pairi + 1] = new faceZone
             (
                 mergeName + "SlaveZone",
                 identity(slavePatch.size(), slavePatch.start()),
@@ -62,7 +62,7 @@
             );
 
             // An empty zone for cut faces
-            fz[3*pairI + 2] = new faceZone
+            fz[3*pairi + 2] = new faceZone
             (
                 mergeName + "CutFaceZone",
                 2,
@@ -78,30 +78,30 @@
         attachPolyTopoChanger polyMeshAttacher(mesh);
         polyMeshAttacher.setSize(mergePatchPairs.size());
 
-        forAll(mergePatchPairs, pairI)
+        forAll(mergePatchPairs, pairi)
         {
             const word mergeName
             (
-                mergePatchPairs[pairI].first()
-              + mergePatchPairs[pairI].second()
-              + name(pairI)
+                mergePatchPairs[pairi].first()
+              + mergePatchPairs[pairi].second()
+              + name(pairi)
             );
 
             // Add the sliding interface mesh modifier
             polyMeshAttacher.set
             (
-                pairI,
+                pairi,
                 new slidingInterface
                 (
-                    "couple" + name(pairI),
-                    pairI,
+                    "couple" + name(pairi),
+                    pairi,
                     polyMeshAttacher,
                     mergeName + "MasterZone",
                     mergeName + "SlaveZone",
                     mergeName + "CutPointZone",
                     mergeName + "CutFaceZone",
-                    mergePatchPairs[pairI].first(),
-                    mergePatchPairs[pairI].second(),
+                    mergePatchPairs[pairi].first(),
+                    mergePatchPairs[pairi].second(),
                     slidingInterface::INTEGRAL, // always integral
                     false,
                     intersection::VISIBLE
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.C b/src/mesh/blockMesh/blockMesh/blockMesh.C
index 3df87de8d24..04db49d80c6 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.C
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.C
@@ -109,15 +109,23 @@ Foam::blockMesh::blockMesh
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-bool Foam::blockMesh::valid() const
+bool Foam::blockMesh::valid() const noexcept
 {
     return bool(topologyPtr_);
 }
 
 
-void Foam::blockMesh::verbose(const bool on)
+bool Foam::blockMesh::verbose() const noexcept
 {
+    return verboseOutput;
+}
+
+
+bool Foam::blockMesh::verbose(const bool on) noexcept
+{
+    bool old(verboseOutput);
     verboseOutput = on;
+    return old;
 }
 
 
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.H b/src/mesh/blockMesh/blockMesh/blockMesh.H
index 4227b3de067..d08a4755859 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.H
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.H
@@ -226,10 +226,10 @@ public:
 
         //- Construct from IOdictionary for given region
         //  Default is topological merging.
-        blockMesh
+        explicit blockMesh
         (
             const IOdictionary& dict,
-            const word& regionName,
+            const word& regionName = polyMesh::defaultRegion,
             mergeStrategy strategy = mergeStrategy::DEFAULT_MERGE
         );
 
@@ -255,10 +255,10 @@ public:
             }
 
             //- True if the blockMesh topology exists
-            bool valid() const;
+            bool valid() const noexcept;
 
-            //- Reference to point field defining the blockMesh
-            //  these points have not been scaled by scaleFactor
+            //- Reference to point field defining the blockMesh.
+            //  These points are \b not scaled by scaleFactor
             const pointField& vertices() const;
 
             //- Return the blockMesh topology as a polyMesh
@@ -279,8 +279,8 @@ public:
             //- The scaling factor used to convert to metres
             scalar scaleFactor() const;
 
-            //- The points for the entire mesh
-            //  these points have been scaled by scaleFactor
+            //- The points for the entire mesh.
+            //  These points \b are scaled by scaleFactor
             const pointField& points() const;
 
             //- Return cell shapes list
@@ -299,16 +299,26 @@ public:
             label numZonedBlocks() const;
 
 
-        // Edit
+    // Verbosity
 
-            //- Enable/disable verbose information about the progress
-            void verbose(const bool on=true);
+        //- Verbose information?
+        bool verbose() const noexcept;
 
+        //- Enable/disable verbose information about the progress
+        //  \return old value
+        bool verbose(const bool on) noexcept;
 
-        // Write
 
-            //- Writes edges of blockMesh in OBJ format.
-            void writeTopology(Ostream&) const;
+    // Mesh Generation
+
+        //- Create polyMesh, with cell zones
+        autoPtr<polyMesh> mesh(const IOobject& io) const;
+
+
+    // Write
+
+        //- Writes edges of blockMesh in OBJ format.
+        void writeTopology(Ostream& os) const;
 };
 
 
diff --git a/src/mesh/blockMesh/blockMesh/blockMeshCreate.C b/src/mesh/blockMesh/blockMesh/blockMeshCreate.C
index 4e8dad0cc6f..8d93b69b872 100644
--- a/src/mesh/blockMesh/blockMesh/blockMeshCreate.C
+++ b/src/mesh/blockMesh/blockMesh/blockMeshCreate.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,6 +28,7 @@ License
 
 #include "blockMesh.H"
 #include "cellModel.H"
+#include "emptyPolyPatch.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -270,4 +271,129 @@ void Foam::blockMesh::createPatches() const
 }
 
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::autoPtr<Foam::polyMesh>
+Foam::blockMesh::mesh(const IOobject& io) const
+{
+    const blockMesh& blkMesh = *this;
+
+    if (verboseOutput)
+    {
+        Info<< nl << "Creating polyMesh from blockMesh" << endl;
+    }
+
+    auto meshPtr = autoPtr<polyMesh>::New
+    (
+        io,
+        pointField(blkMesh.points()),   // Copy, could we re-use space?
+        blkMesh.cells(),
+        blkMesh.patches(),
+        blkMesh.patchNames(),
+        blkMesh.patchDicts(),
+        "defaultFaces",                 // Default patch name
+        emptyPolyPatch::typeName        // Default patch type
+    );
+
+
+    // Set any cellZones
+    const label nZones = blkMesh.numZonedBlocks();
+
+    if (nZones)
+    {
+        polyMesh& pmesh = *meshPtr;
+
+        if (verboseOutput)
+        {
+            Info<< "Adding cell zones" << endl;
+        }
+
+        // Map from zoneName to cellZone index
+        HashTable<label> zoneMap(2*nZones);
+
+        // Cells per zone
+        List<DynamicList<label>> zoneCells(nZones);
+
+        // Running cell counter
+        label celli = 0;
+
+        // Largest zone so far
+        label freeZonei = 0;
+
+        for (const block& b : blkMesh)
+        {
+            const word& zoneName = b.zoneName();
+            const label nCellsInBlock = b.cells().size();
+
+            if (zoneName.size())
+            {
+                const auto iter = zoneMap.cfind(zoneName);
+
+                label zonei = freeZonei;
+
+                if (iter.found())
+                {
+                    zonei = *iter;
+                }
+                else
+                {
+                    zoneMap.insert(zoneName, zonei);
+                    ++freeZonei;
+
+                    if (verboseOutput)
+                    {
+                        Info<< "    " << zonei << '\t' << zoneName << endl;
+                    }
+                }
+
+
+                // Fill with cell ids
+
+                zoneCells[zonei].reserve
+                (
+                    zoneCells[zonei].size() + nCellsInBlock
+                );
+
+                const label endOfFill = celli + nCellsInBlock;
+
+                for (; celli < endOfFill; ++celli)
+                {
+                    zoneCells[zonei].append(celli);
+                }
+            }
+            else
+            {
+                celli += nCellsInBlock;
+            }
+        }
+
+        List<cellZone*> cz(zoneMap.size());
+        forAllConstIters(zoneMap, iter)
+        {
+            const word& zoneName = iter.key();
+            const label zonei = iter.val();
+
+            cz[zonei] = new cellZone
+            (
+                zoneName,
+                zoneCells[zonei].shrink(),
+                zonei,
+                pmesh.cellZones()
+            );
+        }
+
+        pmesh.pointZones().resize(0);
+        pmesh.faceZones().resize(0);
+        pmesh.cellZones().resize(0);
+        pmesh.addZones(List<pointZone*>(), List<faceZone*>(), cz);
+    }
+
+
+    // Merge patch pairs, cyclic must be done elsewhere
+    // - requires libdynamicMesh
+
+    return meshPtr;
+}
+
+
 // ************************************************************************* //
-- 
GitLab