From a79eaa2d647f2229a2905649490ed4a8946827ff Mon Sep 17 00:00:00 2001
From: mark <mark@opencfd>
Date: Tue, 25 Oct 2016 15:43:46 +0200
Subject: [PATCH] ENH: provide separate geometry description per region/patch
 (issue #278)

- Also fixed bug noted in issue #269

- Previous implementation had all faces together, which made
  it difficult (impossible) for external applications to
  figure out which geometry was being referred to.

- Provide separate region/patches as follows:

    // Patch: <regionName> <patchName>

  For example,

    // Group: coupleGroup
    // Patch: heater minY
    8( ... )

  The region-name is always present, even if there is only one region.

- This change is a partial reversion to the behaviour in 2.4.x, except
  that we can now also handle multi-region geometries.

  Changing the leading comment from "# " to "// " facilitates parsing
  of the files with OpenFOAM itself if necessary.
---
 .../externalCoupledFunctionObject.C           | 150 +++++++-----------
 .../externalCoupledFunctionObject.H           |   8 +-
 2 files changed, 59 insertions(+), 99 deletions(-)

diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C
index 392502b034e..5aae2c1b462 100644
--- a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.C
@@ -49,7 +49,7 @@ namespace Foam
 
 Foam::word Foam::externalCoupledFunctionObject::lockName = "OpenFOAM";
 
-Foam::string Foam::externalCoupledFunctionObject::patchKey = "# Patch: ";
+Foam::string Foam::externalCoupledFunctionObject::patchKey = "// Patch:";
 
 template<>
 const char* Foam::NamedEnum
@@ -431,11 +431,6 @@ void Foam::externalCoupledFunctionObject::writeGeometry
 
     fileName dir(groupDir(commsDir, compositeName(regionNames), groupName));
 
-    //if (log_)
-    {
-        Info<< typeName << ": writing geometry to " << dir << endl;
-    }
-
     autoPtr<OFstream> osPointsPtr;
     autoPtr<OFstream> osFacesPtr;
     if (Pstream::master())
@@ -443,12 +438,20 @@ void Foam::externalCoupledFunctionObject::writeGeometry
         mkDir(dir);
         osPointsPtr.reset(new OFstream(dir/"patchPoints"));
         osFacesPtr.reset(new OFstream(dir/"patchFaces"));
+
+        osPointsPtr() << "// Group: " << groupName << endl;
+        osFacesPtr()  << "// Group: " << groupName << endl;
+
+        Info<< typeName << ": writing geometry to " << dir << endl;
     }
 
+    // Individual region/patch entries
 
-    DynamicList<face> allMeshesFaces;
-    DynamicField<point> allMeshesPoints;
+    DynamicList<face> allFaces;
+    DynamicField<point> allPoints;
 
+    labelList pointToGlobal;
+    labelList uniquePointIDs;
     forAll(meshes, meshI)
     {
         const fvMesh& mesh = meshes[meshI];
@@ -461,109 +464,66 @@ void Foam::externalCoupledFunctionObject::writeGeometry
             ).sortedToc()
         );
 
-        // Count faces
-        label nFaces = 0;
-        forAll(patchIDs, i)
-        {
-            nFaces += mesh.boundaryMesh()[patchIDs[i]].size();
-        }
-
-        // Collect faces
-        DynamicList<label> allFaceIDs(nFaces);
         forAll(patchIDs, i)
         {
             const polyPatch& p = mesh.boundaryMesh()[patchIDs[i]];
 
-            forAll(p, pI)
-            {
-                allFaceIDs.append(p.start()+pI);
-            }
-        }
-
-        // Construct overall patch
-        indirectPrimitivePatch allPatch
-        (
-            IndirectList<face>(mesh.faces(), allFaceIDs),
-            mesh.points()
-        );
-
-        labelList pointToGlobal;
-        labelList uniquePointIDs;
-        mesh.globalData().mergePoints
-        (
-            allPatch.meshPoints(),
-            allPatch.meshPointMap(),
-            pointToGlobal,
-            uniquePointIDs
-        );
-
-        label procI = Pstream::myProcNo();
-
-        List<pointField> collectedPoints(Pstream::nProcs());
-        collectedPoints[procI] = pointField(mesh.points(), uniquePointIDs);
-        Pstream::gatherList(collectedPoints);
+            mesh.globalData().mergePoints
+            (
+                p.meshPoints(),
+                p.meshPointMap(),
+                pointToGlobal,
+                uniquePointIDs
+            );
 
-        List<faceList> collectedFaces(Pstream::nProcs());
-        faceList& patchFaces = collectedFaces[procI];
-        patchFaces = allPatch.localFaces();
-        forAll(patchFaces, faceI)
-        {
-            inplaceRenumber(pointToGlobal, patchFaces[faceI]);
-        }
-        Pstream::gatherList(collectedFaces);
+            label procI = Pstream::myProcNo();
 
-        if (Pstream::master())
-        {
-            // Append and renumber
-            label nPoints = allMeshesPoints.size();
+            List<pointField> collectedPoints(Pstream::nProcs());
+            collectedPoints[procI] = pointField(mesh.points(), uniquePointIDs);
+            Pstream::gatherList(collectedPoints);
 
-            forAll(collectedPoints, procI)
+            List<faceList> collectedFaces(Pstream::nProcs());
+            faceList& patchFaces = collectedFaces[procI];
+            patchFaces = p.localFaces();
+            forAll(patchFaces, faceI)
             {
-                allMeshesPoints.append(collectedPoints[procI]);
-
+                inplaceRenumber(pointToGlobal, patchFaces[faceI]);
             }
-            face newFace;
-            forAll(collectedFaces, procI)
+            Pstream::gatherList(collectedFaces);
+
+            if (Pstream::master())
             {
-                const faceList& procFaces = collectedFaces[procI];
+                allPoints.clear();
+                allFaces.clear();
 
-                forAll(procFaces, faceI)
+                for (label procI=0; procI < Pstream::nProcs(); ++procI)
                 {
-                    const face& f = procFaces[faceI];
-
-                    newFace.setSize(f.size());
-                    forAll(f, fp)
-                    {
-                        newFace[fp] = f[fp]+nPoints;
-                    }
-                    allMeshesFaces.append(newFace);
+                    allPoints.append(collectedPoints[procI]);
+                    allFaces.append(collectedFaces[procI]);
                 }
 
-                nPoints += collectedPoints[procI].size();
+                Info<< typeName << ": mesh " << mesh.name()
+                    << ", patch " << p.name()
+                    << ": writing " << allPoints.size() << " points to "
+                    << osPointsPtr().name() << nl
+                    << typeName << ": mesh " << mesh.name()
+                    << ", patch " << p.name()
+                    << ": writing " << allFaces.size() << " faces to "
+                    << osFacesPtr().name() << endl;
+
+                // The entry name (region / patch)
+                const string entryHeader =
+                    patchKey + ' ' + mesh.name() + ' ' + p.name();
+
+                // Write points
+                osPointsPtr()
+                    << entryHeader.c_str() << nl << allPoints << nl << endl;
+
+                // Write faces
+                osFacesPtr()
+                    << entryHeader.c_str() << nl << allFaces << nl << endl;
             }
         }
-
-        //if (log_)
-        {
-            Info<< typeName << ": for mesh " << mesh.name()
-                << " writing " << allMeshesPoints.size() << " points to "
-                << osPointsPtr().name() << endl;
-            Info<< typeName << ": for mesh " << mesh.name()
-                << " writing " << allMeshesFaces.size() << " faces to "
-                << osFacesPtr().name() << endl;
-        }
-    }
-
-    // Write points
-    if (osPointsPtr.valid())
-    {
-        osPointsPtr() << allMeshesPoints << endl;
-    }
-
-    // Write faces
-    if (osFacesPtr.valid())
-    {
-        osFacesPtr() << allMeshesFaces << endl;
     }
 }
 
diff --git a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H
index 777abcebe19..d24ac43a600 100644
--- a/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H
+++ b/src/postProcessing/functionObjects/jobControl/externalCoupled/externalCoupledFunctionObject.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2015 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2015-2016 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -319,10 +319,10 @@ public:
     //- Runtime type information
     TypeName("externalCoupled");
 
-    //- Name of lock file
+    //- Name of lock file (normally 'OpenFOAM.lock')
     static word lockName;
 
-    //- Name of patch key, e.g. '# Patch:' when looking for start of patch data
+    //- Name of patch key, e.g. '// Patch:' when looking for start of patch data
     static string patchKey;
 
 
@@ -391,7 +391,7 @@ public:
             //  separated by '_'
             static word compositeName(const wordList&);
 
-            //- Write geometry for the group/patch
+            //- Write geometry for the group as region/patch
             static void writeGeometry
             (
                 const UPtrList<const fvMesh>& meshes,
-- 
GitLab