From c6acd6861889ed4698c779fa03f12debf5e62874 Mon Sep 17 00:00:00 2001
From: Andrew Heather <a.heather@opencfd.co.uk>
Date: Tue, 29 Nov 2016 14:41:02 +0000
Subject: [PATCH] ENH: Added new regionSplit2D to split 2-D regions based on an
 indicator field

---
 src/meshTools/Make/files                    |   2 +
 src/meshTools/regionSplit2D/regionSplit2D.C | 146 ++++++++++++++++++++
 src/meshTools/regionSplit2D/regionSplit2D.H | 113 +++++++++++++++
 3 files changed, 261 insertions(+)
 create mode 100644 src/meshTools/regionSplit2D/regionSplit2D.C
 create mode 100644 src/meshTools/regionSplit2D/regionSplit2D.H

diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index d6dd0ec9f27..bb5e356a0ea 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -55,6 +55,8 @@ $(meshWave)/FaceCellWaveName.C
 regionSplit/regionSplit.C
 regionSplit/localPointRegion.C
 
+regionSplit2D/regionSplit2D.C
+
 indexedOctree/treeDataEdge.C
 indexedOctree/treeDataFace.C
 indexedOctree/treeDataPoint.C
diff --git a/src/meshTools/regionSplit2D/regionSplit2D.C b/src/meshTools/regionSplit2D/regionSplit2D.C
new file mode 100644
index 00000000000..aca03a82f52
--- /dev/null
+++ b/src/meshTools/regionSplit2D/regionSplit2D.C
@@ -0,0 +1,146 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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 "regionSplit2D.H"
+#include "polyMesh.H"
+#include "PatchEdgeFaceWave.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
+
+Foam::regionSplit2D::regionSplit2D
+(
+    const polyMesh& mesh,
+    const indirectPrimitivePatch& patch,
+    const boolList& blockedFaces,
+    const label offset
+)
+:
+    labelList(patch.size(), -1),
+    nRegions_(0)
+{
+    globalIndex globalFaces(blockedFaces.size());
+    label regionI = globalFaces.toGlobal(0);
+    List<patchEdgeFaceRegion> allEdgeInfo(patch.nEdges());
+    List<patchEdgeFaceRegion> allFaceInfo(patch.size());
+    DynamicList<label> changedEdges;
+    DynamicList<patchEdgeFaceRegion> changedRegions;
+    label nBlockedFaces = 0;
+    forAll(blockedFaces, faceI)
+    {
+        if (blockedFaces[faceI])
+        {
+            const labelList& fEdges = patch.faceEdges()[faceI];
+            forAll(fEdges, feI)
+            {
+                changedEdges.append(fEdges[feI]);
+
+                // Append globally unique value
+                changedRegions.append(regionI);
+            }
+            nBlockedFaces++;
+            regionI++;
+        }
+        else
+        {
+            // Block all non-seeded faces from the walk
+            allFaceInfo[faceI] = -2;
+        }
+    }
+
+    // Early exit if there are no blocked faces
+    if (returnReduce(nBlockedFaces, sumOp<label>()) == 0)
+    {
+        return;
+    }
+
+    PatchEdgeFaceWave
+    <
+        indirectPrimitivePatch,
+        patchEdgeFaceRegion
+    >
+    (
+        mesh,
+        patch,
+        changedEdges,
+        changedRegions,
+        allEdgeInfo,
+        allFaceInfo,
+        returnReduce(patch.nEdges(), sumOp<label>())
+    );
+
+
+    // Map from regions to local compact indexing
+    // - only for regions that originate from this processor
+    Map<label> regionToCompactAddr(changedRegions.size());
+    label compactRegionI = 0;
+    forAll(allFaceInfo, faceI)
+    {
+        label regionI = allFaceInfo[faceI].region();
+        if
+        (
+            globalFaces.isLocal(regionI)
+         && regionToCompactAddr.insert(regionI, compactRegionI)
+        )
+        {
+            compactRegionI++;
+        }
+    }
+
+    // In-place renumber the local regionI to global (compact) regionI
+    globalIndex giCompact(compactRegionI);
+    forAllIter(Map<label>, regionToCompactAddr, iter)
+    {
+        label compactRegionI = iter();
+        iter() = giCompact.toGlobal(compactRegionI);
+    }
+
+    // Ensure regionToCompactAddr consistent across all processors
+    // - not concerned about the op (keys are unique)
+    // - map size will be the number of regions in the set of faces
+    Pstream::mapCombineGather(regionToCompactAddr, minEqOp<label>());
+    Pstream::mapCombineScatter(regionToCompactAddr);
+
+    nRegions_ = regionToCompactAddr.size();
+
+    // Set the region index per face
+    forAll(allFaceInfo, faceI)
+    {
+        label regionI = allFaceInfo[faceI].region();
+        if (regionI >= 0)
+        {
+            this->operator[](faceI) = regionToCompactAddr[regionI] + offset;
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::regionSplit2D::~regionSplit2D()
+{}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/regionSplit2D/regionSplit2D.H b/src/meshTools/regionSplit2D/regionSplit2D.H
new file mode 100644
index 00000000000..b6ef225ffc8
--- /dev/null
+++ b/src/meshTools/regionSplit2D/regionSplit2D.H
@@ -0,0 +1,113 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2015 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::regionSplit2D
+
+Description
+    Splits a patch into regions based on a mask field.  Result is a globally
+    consistent label list of region index per patch face.
+
+SourceFiles
+    regionSplit2D.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef regionSplit2D_H
+#define regionSplit2D_H
+
+#include "DynamicList.H"
+#include "boolList.H"
+#include "labelList.H"
+#include "indirectPrimitivePatch.H"
+#include "patchEdgeFaceRegion.H"
+#include "globalIndex.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class faceZone;
+class polyMesh;
+
+/*---------------------------------------------------------------------------*\
+                        Class regionSplit2D Declaration
+\*---------------------------------------------------------------------------*/
+
+class regionSplit2D
+:
+    public labelList
+{
+    // Private data
+
+        //- Number of regions
+        label nRegions_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        regionSplit2D(const regionSplit2D&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const regionSplit2D&);
+
+
+public:
+
+    // Constructors
+
+        //- Construct from mesh and list of blocked faces
+        regionSplit2D
+        (
+            const polyMesh& mesh,
+            const indirectPrimitivePatch& patch,
+            const boolList& blockedFaces,
+            const label offset = 0
+        );
+
+
+    //- Destructor
+    ~regionSplit2D();
+
+
+    // Member Functions
+
+        //- Return the number of regions
+        label nRegions() const
+        {
+            return nRegions_;
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
-- 
GitLab