From cf15d299cc901ea9fea8faa78912f73f9530f088 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 8 Dec 2017 12:02:09 +0000
Subject: [PATCH] ENH: remove old proc-addressing when redistributing (issue
 #656)

- after redistribution, the old cellProcAddressing etc files are incorrect
  and potentially troublesome.
---
 .../decomposePar/decomposePar.C               |  72 +++++------
 .../reconstructPar/reconstructPar.C           |  66 ++++-------
 .../redistributePar/redistributePar.C         | 112 +++++++++++-------
 3 files changed, 121 insertions(+), 129 deletions(-)

diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index d1b9b58a7de..37de5137e73 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -275,15 +275,15 @@ int main(int argc, char *argv[])
 
     #include "setRootCase.H"
 
-    bool region                  = args.optionFound("region");
-    bool allRegions              = args.optionFound("allRegions");
-    bool writeCellDist           = args.optionFound("cellDist");
-    bool copyZero                = args.optionFound("copyZero");
-    bool copyUniform             = args.optionFound("copyUniform");
-    bool decomposeFieldsOnly     = args.optionFound("fields");
-    bool decomposeSets           = !args.optionFound("noSets");
-    bool forceOverwrite          = args.optionFound("force");
-    bool ifRequiredDecomposition = args.optionFound("ifRequired");
+    const bool optRegion        = args.optionFound("region");
+    const bool allRegions       = args.optionFound("allRegions");
+    const bool writeCellDist    = args.optionFound("cellDist");
+    const bool copyZero         = args.optionFound("copyZero");
+    const bool copyUniform      = args.optionFound("copyUniform");
+    const bool decomposeSets    = !args.optionFound("noSets");
+    bool decomposeFieldsOnly    = args.optionFound("fields");
+    bool forceOverwrite         = args.optionFound("force");
+    const bool ifRequiredDecomposition = args.optionFound("ifRequired");
 
     // Set time from database
     #include "createTime.H"
@@ -296,44 +296,30 @@ int main(int argc, char *argv[])
     args.optionReadIfPresent("decomposeParDict", decompDictFile);
 
     wordList regionNames;
-    wordList regionDirs;
     if (allRegions)
     {
         Info<< "Decomposing all regions in regionProperties" << nl << endl;
         regionProperties rp(runTime);
-        forAllConstIter(HashTable<wordList>, rp, iter)
+
+        wordHashSet names;
+        forAllConstIters(rp, iter)
         {
-            const wordList& regions = iter();
-            forAll(regions, i)
-            {
-                if (!regionNames.found(regions[i]))
-                {
-                    regionNames.append(regions[i]);
-                }
-            }
+            names.insert(iter.object());
         }
-        regionDirs = regionNames;
+
+        regionNames = names.sortedToc();
     }
     else
     {
-        word regionName;
-        if (args.optionReadIfPresent("region", regionName))
-        {
-            regionNames = wordList(1, regionName);
-            regionDirs = regionNames;
-        }
-        else
-        {
-            regionNames = wordList(1, fvMesh::defaultRegion);
-            regionDirs = wordList(1, word::null);
-        }
+        regionNames = {fvMesh::defaultRegion};
+        args.optionReadIfPresent("region", regionNames[0]);
     }
 
-
     forAll(regionNames, regioni)
     {
         const word& regionName = regionNames[regioni];
-        const word& regionDir = regionDirs[regioni];
+        const word& regionDir =
+            regionName == fvMesh::defaultRegion ? word::null : regionName;
 
         Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
 
@@ -391,7 +377,7 @@ int main(int argc, char *argv[])
                 Info<< "Using existing processor directories" << nl;
             }
 
-            if (region || allRegions)
+            if (allRegions || optRegion)
             {
                 procDirsProblem = false;
                 forceOverwrite = false;
@@ -527,7 +513,7 @@ int main(int argc, char *argv[])
         {
             // Copy the 0 directory into each of the processor directories
             fileName prevTimePath;
-            for (label proci = 0; proci < mesh.nProcs(); proci++)
+            for (label proci = 0; proci < mesh.nProcs(); ++proci)
             {
                 Time processorDb
                 (
@@ -736,13 +722,13 @@ int main(int argc, char *argv[])
 
                 label cloudI = 0;
 
-                forAll(cloudDirs, i)
+                for (const fileName& cloudDir : cloudDirs)
                 {
                     IOobjectList sprayObjs
                     (
                         mesh,
                         runTime.timeName(),
-                        cloud::prefix/cloudDirs[i],
+                        cloud::prefix/cloudDir,
                         IOobject::MUST_READ,
                         IOobject::NO_WRITE,
                         false
@@ -759,7 +745,7 @@ int main(int argc, char *argv[])
                         // ~~~~~~~~~~~~~~~~~~~~~~~~~
 
                         Info<< "Identified lagrangian data set: "
-                            << cloudDirs[i] << endl;
+                            << cloudDir << endl;
 
                         lagrangianPositions.set
                         (
@@ -767,7 +753,7 @@ int main(int argc, char *argv[])
                             new Cloud<indexedParticle>
                             (
                                 mesh,
-                                cloudDirs[i],
+                                cloudDir,
                                 false
                             )
                         );
@@ -944,7 +930,7 @@ int main(int argc, char *argv[])
                 Info<< endl;
 
                 // split the fields over processors
-                for (label proci = 0; proci < mesh.nProcs(); proci++)
+                for (label proci = 0; proci < mesh.nProcs(); ++proci)
                 {
                     Info<< "Processor " << proci << ": field transfer" << endl;
 
@@ -1234,8 +1220,8 @@ int main(int argc, char *argv[])
                     // directory
                     decomposeUniform(copyUniform, mesh, processorDb, regionDir);
 
-                    // For the first region of a multi-region case additionally
-                    // decompose the "uniform" directory in the time directory
+                    // For a multi-region case, also decompose the "uniform"
+                    // directory in the time directory
                     if (regionNames.size() > 1 && regioni == 0)
                     {
                         decomposeUniform(copyUniform, mesh, processorDb);
diff --git a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
index efc5f9b0f35..cabee6ef390 100644
--- a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
+++ b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
@@ -54,14 +54,14 @@ Description
 
 bool haveAllTimes
 (
-    const HashSet<word>& masterTimeDirSet,
+    const wordHashSet& masterTimeDirSet,
     const instantList& timeDirs
 )
 {
     // Loop over all times
-    forAll(timeDirs, timei)
+    for (const instant& t : timeDirs)
     {
-        if (!masterTimeDirSet.found(timeDirs[timei].name()))
+        if (!masterTimeDirSet.found(t.name()))
         {
             return false;
         }
@@ -126,11 +126,8 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
 
-    HashSet<word> selectedFields;
-    if (args.optionFound("fields"))
-    {
-        args.optionLookup("fields")() >> selectedFields;
-    }
+    wordHashSet selectedFields;
+    args.optionReadIfPresent("fields", selectedFields);
 
     const bool noFields = args.optionFound("noFields");
 
@@ -158,8 +155,8 @@ int main(int argc, char *argv[])
     }
 
 
-    HashSet<word> selectedLagrangianFields;
-    if (args.optionFound("lagrangianFields"))
+    wordHashSet selectedLagrangianFields;
+    if (args.optionReadIfPresent("lagrangianFields", selectedLagrangianFields))
     {
         if (noLagrangian)
         {
@@ -168,50 +165,42 @@ int main(int argc, char *argv[])
                 << "options together."
                 << exit(FatalError);
         }
-
-        args.optionLookup("lagrangianFields")() >> selectedLagrangianFields;
     }
 
 
     const bool newTimes   = args.optionFound("newTimes");
     const bool allRegions = args.optionFound("allRegions");
 
-
     wordList regionNames;
     wordList regionDirs;
     if (allRegions)
     {
-        Info<< "Reconstructing for all regions in regionProperties" << nl
-            << endl;
+        Info<< "Reconstructing all regions in regionProperties" << nl << endl;
         regionProperties rp(runTime);
-        forAllConstIter(HashTable<wordList>, rp, iter)
+
+        wordHashSet names;
+        forAllConstIters(rp, iter)
         {
-            const wordList& regions = iter();
-            forAll(regions, i)
-            {
-                if (!regionNames.found(regions[i]))
-                {
-                    regionNames.append(regions[i]);
-                }
-            }
+            names.insert(iter.object());
         }
+
+        regionNames = names.sortedToc();
         regionDirs = regionNames;
     }
     else
     {
-        word regionName;
-        if (args.optionReadIfPresent("region", regionName))
+        regionNames = {fvMesh::defaultRegion};
+        if (args.optionReadIfPresent("region", regionNames[0]))
         {
-            regionNames = wordList(1, regionName);
             regionDirs = regionNames;
         }
         else
         {
-            regionNames = wordList(1, fvMesh::defaultRegion);
-            regionDirs = wordList(1, word::null);
+            regionDirs = {word::null};
         }
     }
 
+
     // Determine the processor count
     label nProcs = fileHandler().nProcs(args.path(), regionDirs[0]);
 
@@ -267,10 +256,10 @@ int main(int argc, char *argv[])
     {
         masterTimeDirs = runTime.times();
     }
-    HashSet<word> masterTimeDirSet(2*masterTimeDirs.size());
-    forAll(masterTimeDirs, i)
+    wordHashSet masterTimeDirSet(2*masterTimeDirs.size());
+    for (const instant& t : masterTimeDirs)
     {
-        masterTimeDirSet.insert(masterTimeDirs[i].name());
+        masterTimeDirSet.insert(t.name());
     }
 
 
@@ -567,21 +556,18 @@ int main(int argc, char *argv[])
                         );
                     }
 
-                    forAll(cloudDirs, i)
+                    for (const fileName& cloudDir : cloudDirs)
                     {
                         // Check if we already have cloud objects for this
                         // cloudname
-                        HashTable<IOobjectList>::const_iterator iter =
-                            cloudObjects.find(cloudDirs[i]);
-
-                        if (iter == cloudObjects.end())
+                        if (!cloudObjects.found(cloudDir))
                         {
                             // Do local scan for valid cloud objects
                             IOobjectList sprayObjs
                             (
                                 procMeshes.meshes()[proci],
                                 databases[proci].timeName(),
-                                cloud::prefix/cloudDirs[i]
+                                cloud::prefix/cloudDir
                             );
 
                             IOobject* positionsPtr =
@@ -591,7 +577,7 @@ int main(int argc, char *argv[])
 
                             if (coordsPtr || positionsPtr)
                             {
-                                cloudObjects.insert(cloudDirs[i], sprayObjs);
+                                cloudObjects.insert(cloudDir, sprayObjs);
                             }
                         }
                     }
@@ -606,7 +592,7 @@ int main(int argc, char *argv[])
                         const word cloudName = word::validate(iter.key());
 
                         // Objects (on arbitrary processor)
-                        const IOobjectList& sprayObjs = iter();
+                        const IOobjectList& sprayObjs = iter.object();
 
                         Info<< "Reconstructing lagrangian fields for cloud "
                             << cloudName << nl << endl;
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index e0ba52f7a7d..f9b1cbed0bf 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -105,7 +105,7 @@ scalar getMergeDistance
     scalar mergeTol = defaultMergeTol;
     args.optionReadIfPresent("mergeTol", mergeTol);
 
-    scalar writeTol =
+    const scalar writeTol =
         Foam::pow(scalar(10.0), -scalar(IOstream::defaultPrecision()));
 
     Info<< "Merge tolerance : " << mergeTol << nl
@@ -236,7 +236,7 @@ void writeDecomposition
 (
     const word& name,
     const fvMesh& mesh,
-    const labelList& decomp
+    const labelUList& decomp
 )
 {
     // Write the decomposition as labelList for use with 'manual'
@@ -388,10 +388,9 @@ void determineDecomposition
 // Write addressing if decomposing (1 to many) or reconstructing (many to 1)
 void writeProcAddressing
 (
-    const bool decompose,
-    const fileName& meshSubDir,
     const fvMesh& mesh,
-    const mapDistributePolyMesh& map
+    const mapDistributePolyMesh& map,
+    const bool decompose
 )
 {
     Info<< "Writing procAddressing files to " << mesh.facesInstance()
@@ -403,7 +402,7 @@ void writeProcAddressing
         (
             "cellProcAddressing",
             mesh.facesInstance(),
-            meshSubDir,
+            polyMesh::meshSubDir,
             mesh,
             IOobject::NO_READ
         ),
@@ -416,7 +415,7 @@ void writeProcAddressing
         (
             "faceProcAddressing",
             mesh.facesInstance(),
-            meshSubDir,
+            polyMesh::meshSubDir,
             mesh,
             IOobject::NO_READ
         ),
@@ -429,7 +428,7 @@ void writeProcAddressing
         (
             "pointProcAddressing",
             mesh.facesInstance(),
-            meshSubDir,
+            polyMesh::meshSubDir,
             mesh,
             IOobject::NO_READ
         ),
@@ -442,7 +441,7 @@ void writeProcAddressing
         (
             "boundaryProcAddressing",
             mesh.facesInstance(),
-            meshSubDir,
+            polyMesh::meshSubDir,
             mesh,
             IOobject::NO_READ
         ),
@@ -545,10 +544,10 @@ void writeProcAddressing
         );
     }
 
-    bool cellOk = cellMap.write();
-    bool faceOk = faceMap.write();
-    bool pointOk = pointMap.write();
-    bool patchOk = patchMap.write();
+    const bool cellOk = cellMap.write();
+    const bool faceOk = faceMap.write();
+    const bool pointOk = pointMap.write();
+    const bool patchOk = patchMap.write();
 
     if (!cellOk || !faceOk || !pointOk || !patchOk)
     {
@@ -562,6 +561,24 @@ void writeProcAddressing
 }
 
 
+// Remove addressing
+void removeProcAddressing(const polyMesh& mesh)
+{
+    for (const auto prefix : {"boundary", "cell", "face", "point"})
+    {
+        IOobject io
+        (
+            prefix + word("ProcAddressing"),
+            mesh.facesInstance(),
+            polyMesh::meshSubDir,
+            mesh
+        );
+
+        const fileName procFile(io.objectPath());
+        rm(procFile);
+    }
+}
+
 
 // Generic mesh-based field reading
 template<class GeoField>
@@ -906,8 +923,8 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
 
         // We don't want to map the decomposition (mapping already tested when
         // mapping the cell centre field)
-        IOobjectList::iterator iter = objects.find("cellDist");
-        if (iter != objects.end())
+        auto iter = objects.find("cellDist");
+        if (iter.found())
         {
             objects.erase(iter);
         }
@@ -1162,7 +1179,7 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
         (
             "procAddressing",
             mesh.facesInstance(),
-            meshSubDir,
+            polyMesh::meshSubDir,
             mesh,
             IOobject::NO_READ,
             IOobject::AUTO_WRITE
@@ -1181,16 +1198,16 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
 
             mesh.write();
             topoSet::removeFiles(mesh);
-            forAll(pointFieldNames, i)
+            for (const word& fieldName : pointFieldNames)
             {
                 IOobject io
                 (
-                    pointFieldNames[i],
+                    fieldName,
                     runTime.timeName(),
                     mesh
                 );
 
-                fileName fieldFile(io.objectPath());
+                const fileName fieldFile(io.objectPath());
                 if (topoSet::debug) DebugVar(fieldFile);
                 rm(fieldFile);
             }
@@ -1204,16 +1221,16 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
     {
         mesh.write();
         topoSet::removeFiles(mesh);
-        forAll(pointFieldNames, i)
+        for (const word& fieldName : pointFieldNames)
         {
             IOobject io
             (
-                pointFieldNames[i],
+                fieldName,
                 runTime.timeName(),
                 mesh
             );
 
-            fileName fieldFile(io.objectPath());
+            const fileName fieldFile(io.objectPath());
             if (topoSet::debug) DebugVar(fieldFile);
             rm(fieldFile);
         }
@@ -1224,7 +1241,16 @@ autoPtr<mapDistributePolyMesh> redistributeAndWrite
 
     if (decompose || nDestProcs == 1)
     {
-        writeProcAddressing(decompose, meshSubDir, mesh, map);
+        // Decompose (1 -> N) or reconstruct (N -> 1)
+        // so {boundary,cell,face,point}ProcAddressing have meaning
+        writeProcAddressing(mesh, map, decompose);
+    }
+    else
+    {
+        // Redistribute (N -> M)
+        // {boundary,cell,face,point}ProcAddressing would be incorrect
+        // - can either remove or redistribute previous
+        removeProcAddressing(mesh);
     }
 
 
@@ -2272,9 +2298,9 @@ int main(int argc, char *argv[])
     Foam::argList args(argc, argv);
     bool decompose = args.optionFound("decompose");
     const bool reconstruct = args.optionFound("reconstruct");
+    const bool writeCellDist = args.optionFound("cellDist");
+    const bool newTimes = args.optionFound("newTimes");
     bool overwrite = args.optionFound("overwrite");
-    bool writeCellDist = args.optionFound("cellDist");
-    bool newTimes = args.optionFound("newTimes");
 
 
     if (Foam::sigFpe::requested())
@@ -2363,8 +2389,7 @@ int main(int argc, char *argv[])
         Info<< "No processor directories; switching on decompose mode"
             << nl << endl;
     }
-    // If master changed to decompose mode make sure all nodes know about
-    // it
+    // If master changed to decompose mode make sure all nodes know about it
     Pstream::scatter(decompose);
 
 
@@ -2382,9 +2407,9 @@ int main(int argc, char *argv[])
             timeDirs = Time::findTimes(args.path(), "constant");
         }
         Pstream::scatter(timeDirs);
-        forAll(timeDirs, i)
+        for (const instant& t : timeDirs)
         {
-            mkDir(args.path()/timeDirs[i].name());
+            mkDir(args.path()/t.name());
         }
     }
 
@@ -2418,9 +2443,9 @@ int main(int argc, char *argv[])
             timeDirs = Time::findTimes(basePath, "constant");
         }
         Pstream::scatter(timeDirs);
-        forAll(timeDirs, i)
+        for (const instant& t : timeDirs)
         {
-            mkDir(basePath/timeDirs[i].name());
+            mkDir(basePath/t.name());
         }
     }
 
@@ -2441,33 +2466,32 @@ int main(int argc, char *argv[])
     if (newTimes)
     {
         instantList baseTimeDirs(baseRunTime.times());
-        forAll(baseTimeDirs, i)
+        for (const instant& t : baseTimeDirs)
         {
-            masterTimeDirSet.insert(baseTimeDirs[i].name());
+            masterTimeDirSet.insert(t.name());
         }
     }
 
 
     // Determine any region
     word regionName = polyMesh::defaultRegion;
-    fileName meshSubDir;
+    fileName meshSubDir = polyMesh::meshSubDir;
     if (args.optionReadIfPresent("region", regionName))
     {
         meshSubDir = regionName/polyMesh::meshSubDir;
     }
-    else
-    {
-        meshSubDir = polyMesh::meshSubDir;
-    }
     Info<< "Using mesh subdirectory " << meshSubDir << nl << endl;
 
 
+    // Allow override of decomposeParDict location
+    fileName decompDictFile;
+    args.optionReadIfPresent("decomposeParDict", decompDictFile);
+
 
     // Demand driven lagrangian mapper
     autoPtr<parLagrangianRedistributor> lagrangianReconstructorPtr;
 
 
-
     if (reconstruct)
     {
         // use the times list from the master processor
@@ -2689,7 +2713,8 @@ int main(int argc, char *argv[])
         // detect points by hand
         if (mesh.pointsInstance() != mesh.facesInstance())
         {
-            Info<< "    Dected initial mesh motion; reconstructing points" << nl
+            Info<< "    Detected initial mesh motion;"
+                << " reconstructing points" << nl
                 << endl;
             fvReconstructorPtr().reconstructPoints();
         }
@@ -2918,11 +2943,6 @@ int main(int argc, char *argv[])
             mesh.bounds()
         );
 
-        // Allow override of decomposeParDict location
-        fileName decompDictFile;
-        args.optionReadIfPresent("decomposeParDict", decompDictFile);
-
-
         // Determine decomposition
         // ~~~~~~~~~~~~~~~~~~~~~~~
 
-- 
GitLab