BUG: foamListTimes does not remove collated directories (fixes #1588)

- also now report any verbosity on stderr

- fix similar collated directories issue for foamRestoreFields
This commit is contained in:
Mark Olesen
2020-02-14 15:44:03 +01:00
parent a65b9fdd7c
commit 79cf72d573
2 changed files with 159 additions and 33 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -39,7 +39,7 @@ Usage
Options: Options:
- \par -processor - \par -processor
List times from processor0/ directory Times from processor0/ directory
- \par -rm - \par -rm
Remove selected time directories Remove selected time directories
@ -58,9 +58,30 @@ Note
#include "profiling.H" #include "profiling.H"
#include "timeSelector.H" #include "timeSelector.H"
#include "TimePaths.H" #include "TimePaths.H"
#include "ListOps.H"
#include "stringOps.H"
using namespace Foam; using namespace Foam;
// Many ways to name processor directories
//
// Uncollated | "processor0", "processor1" ...
// Collated (old) | "processors"
// Collated (new) | "processors<N>"
// Host collated | "processors<N>_<low>-<high>"
const regExp matcher("processors?[0-9]+(_[0-9]+-[0-9]+)?");
bool isProcessorDir(const string& dir)
{
return
(
dir.starts_with("processor")
&& (dir == "processors" || matcher.match(dir))
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -95,7 +116,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
const bool removeFiles(args.found("rm")); const bool removeFiles(args.found("rm"));
const bool verbose(args.found("verbose")); bool verbose(args.found("verbose"));
// Get times list from the master processor and subset based on // Get times list from the master processor and subset based on
@ -116,6 +137,7 @@ int main(int argc, char *argv[])
<< exit(FatalError); << exit(FatalError);
} }
// Obtain time directory names from "processor0/" only
timePaths = autoPtr<TimePaths>::New timePaths = autoPtr<TimePaths>::New
( (
args.rootPath(), args.rootPath(),
@ -140,10 +162,34 @@ int main(int argc, char *argv[])
{ {
if (nProcs) if (nProcs)
{ {
fileNameList procDirs
(
Foam::readDir
(
args.path(),
fileName::DIRECTORY,
false, // No gzip anyhow
false // Do not follow linkts
)
);
inplaceSubsetList(procDirs, isProcessorDir);
// Perhaps not needed
/// Foam::sort(procDirs, stringOps::natural_sort());
if (verbose) if (verbose)
{ {
Info<< "Removing " << nTimes InfoErr
<< " processor time directories" << endl; << "Removing " << nTimes
<< " times in " << procDirs.size()
<< " processor directories" << endl;
}
// No processor directories? - silence verbosity
if (procDirs.empty())
{
verbose = false;
} }
forAllReverse(timeDirs, timei) forAllReverse(timeDirs, timei)
@ -152,25 +198,15 @@ int main(int argc, char *argv[])
if (verbose) if (verbose)
{ {
Info<< " rm " << timeName InfoErr
<< " rm " << timeName
<< " [" << (nTimes - timei) << '/' << nTimes << ']' << " [" << (nTimes - timei) << '/' << nTimes << ']'
<< endl; << endl;
} }
fileName path(args.path()/"processors"/timeName); for (const fileName& procDir : procDirs)
rmDir(path, true);
for (label proci=0; proci<nProcs; ++proci)
{ {
path = rmDir(args.path()/procDir/timeName, true);
(
args.path()
/ ("processor" + Foam::name(proci))
/ timeName
);
rmDir(path, true);
} }
} }
} }
@ -178,7 +214,8 @@ int main(int argc, char *argv[])
{ {
if (verbose) if (verbose)
{ {
Info<< "Removing " << nTimes InfoErr
<< "Removing " << nTimes
<< " time directories" << endl; << " time directories" << endl;
} }
@ -188,7 +225,8 @@ int main(int argc, char *argv[])
if (verbose) if (verbose)
{ {
Info<< " rm " << timeName InfoErr
<< " rm " << timeName
<< " [" << (nTimes - timei) << '/' << nTimes << ']' << " [" << (nTimes - timei) << '/' << nTimes << ']'
<< endl; << endl;
} }
@ -199,6 +237,7 @@ int main(int argc, char *argv[])
} }
else else
{ {
// List times: one per line
for (const instant& t : timeDirs) for (const instant& t : timeDirs)
{ {
Info<< t.name() << nl; Info<< t.name() << nl;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,7 +30,7 @@ Group
grpMiscUtilities grpMiscUtilities
Description Description
Restore field names by removing the ending. Adjust (restore) field names by removing the ending.
The fields are selected automatically or can be specified as optional The fields are selected automatically or can be specified as optional
command arguments. command arguments.
@ -63,9 +63,30 @@ Usage
#include "timeSelector.H" #include "timeSelector.H"
#include "Enum.H" #include "Enum.H"
#include "TimePaths.H" #include "TimePaths.H"
#include "ListOps.H"
#include "stringOps.H"
using namespace Foam; using namespace Foam;
// Many ways to name processor directories
//
// Uncollated | "processor0", "processor1" ...
// Collated (old) | "processors"
// Collated (new) | "processors<N>"
// Host collated | "processors<N>_<low>-<high>"
const regExp matcher("processors?[0-9]+(_[0-9]+-[0-9]+)?");
bool isProcessorDir(const string& dir)
{
return
(
dir.starts_with("processor")
&& (dir == "processors" || matcher.match(dir))
);
}
//- The known and support types of operations //- The known and support types of operations
enum restoreMethod enum restoreMethod
{ {
@ -311,7 +332,6 @@ int main(int argc, char *argv[])
} }
// Obtain time directory names from "processor0/" only // Obtain time directory names from "processor0/" only
timePaths = autoPtr<TimePaths>::New timePaths = autoPtr<TimePaths>::New
( (
args.rootPath(), args.rootPath(),
@ -329,10 +349,77 @@ int main(int argc, char *argv[])
const instantList timeDirs(timeSelector::select(timePaths->times(), args)); const instantList timeDirs(timeSelector::select(timePaths->times(), args));
fileNameList procDirs;
label leadProcIdx = -1;
if (timeDirs.empty()) if (timeDirs.empty())
{ {
Info<< "no times selected" << nl; Info<< "No times selected" << nl;
} }
else if (nProcs)
{
procDirs =
Foam::readDir
(
args.path(),
fileName::DIRECTORY,
false, // No gzip anyhow
false // Do not follow linkts
);
inplaceSubsetList(procDirs, isProcessorDir);
// Perhaps not needed
Foam::sort(procDirs, stringOps::natural_sort());
// Decide who will be the "leading" processor for obtaining names
// - processor0
// - processors<N>
// - processors<N>_0-<high>
// Uncollated
leadProcIdx = procDirs.find("processor0");
if (!procDirs.empty())
{
if (leadProcIdx < 0)
{
// Collated (old)
leadProcIdx = procDirs.find("processors");
}
if (leadProcIdx < 0)
{
// Collated (new)
leadProcIdx = procDirs.find("processors" + Foam::name(nProcs));
}
if (leadProcIdx < 0)
{
// Host-collated
const std::string prefix
(
"processors" + Foam::name(nProcs) + "_0-"
);
forAll(procDirs, idx)
{
if (procDirs[idx].starts_with(prefix))
{
leadProcIdx = idx;
break;
}
}
}
// Just default to anything (safety)
if (leadProcIdx < 0)
{
leadProcIdx = 0;
}
}
}
for (const instant& t : timeDirs) for (const instant& t : timeDirs)
{ {
@ -341,28 +428,28 @@ int main(int argc, char *argv[])
Info<< "\nTime = " << timeName << nl; Info<< "\nTime = " << timeName << nl;
label count = 0; label count = 0;
wordList files;
if (nProcs) if (nProcs)
{ {
const wordHashSet files if (leadProcIdx >= 0)
( {
getFiles(args.path()/"processor0", timeName) files = getFiles(args.path()/procDirs[leadProcIdx], timeName);
); }
for (label proci=0; proci < nProcs; ++proci) for (const fileName& procDir : procDirs)
{ {
count += restoreFields count += restoreFields
( (
method, method,
args.path()/("processor" + Foam::name(proci))/timeName, args.path()/procDir/timeName,
files, wordHashSet(files),
targetNames targetNames
); );
} }
} }
else else
{ {
wordList files;
if (Pstream::master()) if (Pstream::master())
{ {
files = getFiles(args.path(), timeName); files = getFiles(args.path(), timeName);