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