From c79544b1974a86f1351eeda63795602752c2be33 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@Germany>
Date: Thu, 11 Aug 2016 13:25:51 +0200
Subject: [PATCH] ENH: mergedSurf helper class (fixes #104)

- For merging meshedSurf content from parallel sources.
  Ensures zoneIds are properly preserved for sampling in parallel.

Current state
~~~~~~~~~~~~~

Current producers of the region information:
 * sampledTriSurfaceMesh

Current consumers of the region information:
 * nastran writer. The zone ids passed through as PSHELL Ids (with offset 1).

Limitations

  The per-face region association is preserved, but the face/element
  sort order gets lost in reconstruction. Would need to attach
  additional information to the sampled surface and use that for
  sorting, but this would also imply that sampled values be written
  indirectly (or resorted) too to match the order. Zone ids are passed
  through, but not their names. After reconstruction, zone ids are no
  longer contiguous. Re-sorting (as mentioned above) would solve this
  too, but again at the cost of more complexity when writing.
---
 .../sampledSurfaces/sampledSurfaces.C         |  34 +----
 .../sampledSurfaces/sampledSurfaces.H         |  25 +---
 .../sampledSurfacesTemplates.C                |  14 +-
 src/surfMesh/Make/files                       |   2 +
 src/surfMesh/mergedSurf/mergedSurf.C          | 122 ++++++++++++++++
 src/surfMesh/mergedSurf/mergedSurf.H          | 133 ++++++++++++++++++
 6 files changed, 272 insertions(+), 58 deletions(-)
 create mode 100644 src/surfMesh/mergedSurf/mergedSurf.C
 create mode 100644 src/surfMesh/mergedSurf/mergedSurf.H

diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
index 37868113d89..f15c61b3631 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
@@ -66,17 +66,13 @@ void Foam::sampledSurfaces::writeGeometry() const
 
         if (Pstream::parRun())
         {
-            if (Pstream::master() && mergeList_[surfI].faces.size())
+            if (Pstream::master() && mergedList_[surfI].size())
             {
                 formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    meshedSurfRef
-                    (
-                        mergeList_[surfI].points,
-                        mergeList_[surfI].faces
-                    )
+                    mergedList_[surfI]
                 );
             }
         }
@@ -104,7 +100,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     if (Pstream::parRun())
@@ -135,7 +131,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     read(dict);
@@ -236,7 +232,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
 
         if (Pstream::parRun())
         {
-            mergeList_.setSize(size());
+            mergedList_.setSize(size());
         }
 
         // Ensure all surfaces and merge information are expired
@@ -326,7 +322,7 @@ bool Foam::sampledSurfaces::expire()
         // Clear merge information
         if (Pstream::parRun())
         {
-            mergeList_[surfI].clear();
+            mergedList_[surfI].clear();
         }
     }
 
@@ -374,24 +370,8 @@ bool Foam::sampledSurfaces::update()
         if (s.update())
         {
             updated = true;
+            mergedList_[surfI].merge(s, mergeDim);
         }
-        else
-        {
-            continue;
-        }
-
-        PatchTools::gatherAndMerge
-        (
-            mergeDim,
-            primitivePatch
-            (
-                SubList<face>(s.faces(), s.faces().size()),
-                s.points()
-            ),
-            mergeList_[surfI].points,
-            mergeList_[surfI].faces,
-            mergeList_[surfI].pointsMap
-        );
     }
 
     return updated;
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
index dffb6589664..1d9c9e730b9 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
@@ -40,6 +40,7 @@ SourceFiles
 #include "regionFunctionObject.H"
 #include "sampledSurface.H"
 #include "surfaceWriter.H"
+#include "mergedSurf.H"
 #include "volFieldsFwd.H"
 #include "surfaceFieldsFwd.H"
 #include "wordReList.H"
@@ -64,26 +65,6 @@ class sampledSurfaces
     public functionObjects::regionFunctionObject,
     public PtrList<sampledSurface>
 {
-    // Private classes
-
-        //- Class used for surface merging information
-        class mergeInfo
-        {
-        public:
-            pointField points;
-            faceList   faces;
-            labelList  pointsMap;
-
-            //- Clear all storage
-            void clear()
-            {
-                points.clear();
-                faces.clear();
-                pointsMap.clear();
-            }
-        };
-
-
     // Static data members
 
         //- Output verbosity
@@ -116,8 +97,8 @@ class sampledSurfaces
 
         // surfaces
 
-            //- Information for merging surfaces
-            List<mergeInfo> mergeList_;
+            //- Merged meshed surfaces (parallel only)
+            List<mergedSurf> mergedList_;
 
 
         // Calculated
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
index db19cb0825d..ba39848aad2 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
@@ -65,25 +65,21 @@ void Foam::sampledSurfaces::writeSurface
             );
 
             // Renumber (point data) to correspond to merged points
-            if (mergeList_[surfI].pointsMap.size() == allValues.size())
+            if (mergedList_[surfI].pointsMap().size() == allValues.size())
             {
-                inplaceReorder(mergeList_[surfI].pointsMap, allValues);
-                allValues.setSize(mergeList_[surfI].points.size());
+                inplaceReorder(mergedList_[surfI].pointsMap(), allValues);
+                allValues.setSize(mergedList_[surfI].points().size());
             }
 
             // Write to time directory under outputPath_
             // skip surface without faces (eg, a failed cut-plane)
-            if (mergeList_[surfI].faces.size())
+            if (mergedList_[surfI].size())
             {
                 sampleFile = formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    meshedSurfRef
-                    (
-                        mergeList_[surfI].points,
-                        mergeList_[surfI].faces
-                    ),
+                    mergedList_[surfI],
                     fieldName,
                     allValues,
                     s.interpolate()
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index f8602431044..5e19af86136 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -10,6 +10,8 @@ UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
 
 MeshedSurfaceProxy/MeshedSurfaceProxyCore.C
 
+mergedSurf/mergedSurf.C
+
 surfaceRegistry/surfaceRegistry.C
 surfMesh/surfMesh.C
 surfMesh/surfMeshClear.C
diff --git a/src/surfMesh/mergedSurf/mergedSurf.C b/src/surfMesh/mergedSurf/mergedSurf.C
new file mode 100644
index 00000000000..d5c5f3dc8e8
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.C
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 "mergedSurf.H"
+#include "PatchTools.H"
+#include "ListListOps.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::mergedSurf()
+:
+    points_(),
+    faces_(),
+    zones_(),
+    pointsMap_()
+{}
+
+
+Foam::mergedSurf::mergedSurf
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+:
+    mergedSurf()
+{
+    merge(surf, mergeDim);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::~mergedSurf()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::mergedSurf::use()
+{
+    return Pstream::parRun();
+}
+
+
+void Foam::mergedSurf::clear()
+{
+    points_.clear();
+    faces_.clear();
+    zones_.clear();
+    pointsMap_.clear();
+}
+
+
+bool Foam::mergedSurf::merge
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+{
+    // needed for extra safety?
+    // clear();
+
+    if (!use())
+    {
+        return false;
+    }
+
+    PatchTools::gatherAndMerge
+    (
+        mergeDim,
+        primitivePatch
+        (
+            SubList<face>(surf.faces(), surf.faces().size()),
+            surf.points()
+        ),
+        points_,
+        faces_,
+        pointsMap_
+    );
+
+    // Now handle zone/region information
+    List<labelList> allZones(Pstream::nProcs());
+    allZones[Pstream::myProcNo()] = surf.zoneIds();
+    Pstream::gatherList(allZones);
+
+    if (Pstream::master())
+    {
+        zones_ = ListListOps::combine<labelList>
+        (
+            allZones,
+            accessOp<labelList>()
+        );
+    }
+    allZones.clear();
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/mergedSurf/mergedSurf.H b/src/surfMesh/mergedSurf/mergedSurf.H
new file mode 100644
index 00000000000..dae03660ee9
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.H
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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::mergedSurf
+
+Description
+    Simple class to manage surface merging information
+
+SourceFiles
+    mergedSurf.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef mergedSurf_H
+#define mergedSurf_H
+
+#include "meshedSurf.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class mergedSurf Declaration
+\*---------------------------------------------------------------------------*/
+
+class mergedSurf
+:
+    public meshedSurf
+{
+    pointField points_;
+    faceList   faces_;
+    labelList  zones_;
+    labelList  pointsMap_;
+
+    //- Disallow default bitwise copy construct
+    mergedSurf(const mergedSurf&) = delete;
+
+    // Assignment is needed for lists
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        mergedSurf();
+
+        //- Construct and merge meshed surfaces immediately (in parallel only).
+        mergedSurf(const meshedSurf&, const scalar mergeDim);
+
+
+    //- Destructor
+    virtual ~mergedSurf();
+
+
+    // Access Member Functions
+
+        //- Can use (parallel only)
+        static bool use();
+
+        //- Number of faces
+        label size() const
+        {
+            return faces_.size();
+        }
+
+        //- Const access to (global) points used for the surface
+        virtual const pointField& points() const
+        {
+            return points_;
+        }
+
+        //- Const access to the surface faces
+        virtual const faceList& faces() const
+        {
+            return faces_;
+        }
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return zones_;
+        }
+
+        //- Map for reordered points (old-to-new)
+        const labelList& pointsMap() const
+        {
+            return pointsMap_;
+        }
+
+
+    // Edit
+
+        //- Clear all storage
+        void clear();
+
+        //- Merge meshed surfaces (in parallel only).
+        bool merge(const meshedSurf&, const scalar mergeDim);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
-- 
GitLab