BUG: processorMeshes removeFiles does not remove collated (fixes #2607)
ENH: extend rmDir to handle removal of empty directories only - recursively remove directories that only contain other directories but no other contents. Treats dead links as non-content.
This commit is contained in:
parent
779a2ca084
commit
d5cdc60a54
@ -48,6 +48,14 @@ Description
|
|||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
|
// Create named file with some dummy content
|
||||||
|
void touchFileContent(const fileName& file)
|
||||||
|
{
|
||||||
|
std::ofstream os(file);
|
||||||
|
os << "file=<" << file << ">" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
unsigned testClean(std::initializer_list<Pair<std::string>> tests)
|
unsigned testClean(std::initializer_list<Pair<std::string>> tests)
|
||||||
@ -587,14 +595,54 @@ int main(int argc, char *argv[])
|
|||||||
if (args.found("system"))
|
if (args.found("system"))
|
||||||
{
|
{
|
||||||
const fileName dirA("dirA");
|
const fileName dirA("dirA");
|
||||||
|
const fileName dirB("dirB");
|
||||||
|
const fileName dirC("dirC");
|
||||||
|
const fileName dirD("dirD");
|
||||||
const fileName lnA("lnA");
|
const fileName lnA("lnA");
|
||||||
const fileName lnB("lnB");
|
const fileName lnB("lnB");
|
||||||
const fileName dirB("dirB");
|
|
||||||
|
|
||||||
Foam::rmDir(dirA);
|
// Purge anything existing
|
||||||
|
Foam::rmDir(dirA, true);
|
||||||
|
Foam::rmDir(dirB, true);
|
||||||
|
Foam::rmDir(dirC, true);
|
||||||
|
Foam::rmDir(dirD, true);
|
||||||
Foam::rm(lnA);
|
Foam::rm(lnA);
|
||||||
Foam::rm(lnB);
|
Foam::rm(lnB);
|
||||||
Foam::rmDir(dirB);
|
|
||||||
|
{
|
||||||
|
fileName name(dirA/dirB/dirC/"abc");
|
||||||
|
Foam::mkDir(name.path());
|
||||||
|
touchFileContent(name); // Create real file
|
||||||
|
|
||||||
|
Foam::mkDir(dirB/dirB/dirB/dirB);
|
||||||
|
Foam::ln("test", dirB/"linkB"); // Create dead link
|
||||||
|
|
||||||
|
Foam::mkDir(dirC);
|
||||||
|
Foam::ln("../dirD", dirC/"linkC"); // Create real link
|
||||||
|
|
||||||
|
Foam::mkDir(dirD);
|
||||||
|
|
||||||
|
for (const fileName& d : { dirA, dirB, dirC, dirD })
|
||||||
|
{
|
||||||
|
Info<< "Directory: " << d << " = "
|
||||||
|
<< readDir(d, fileName::UNDEFINED, false, false) << nl;
|
||||||
|
|
||||||
|
if (Foam::rmDir(d, false, true))
|
||||||
|
{
|
||||||
|
Info<< " Removed empty dir" << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< " Could not remove empty dir" << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force removal before continuing
|
||||||
|
Foam::rmDir(dirA, true);
|
||||||
|
Foam::rmDir(dirB, true);
|
||||||
|
Foam::rmDir(dirC, true);
|
||||||
|
Foam::rmDir(dirD, true);
|
||||||
|
}
|
||||||
|
|
||||||
Info<< nl << "=========================" << nl
|
Info<< nl << "=========================" << nl
|
||||||
<< "Test some copying and deletion" << endl;
|
<< "Test some copying and deletion" << endl;
|
||||||
@ -618,9 +666,7 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
Info<<" create: " << file << endl;
|
Info<<" create: " << file << endl;
|
||||||
|
touchFileContent(file);
|
||||||
std::ofstream os(file);
|
|
||||||
os << "file=<" << file << ">" << nl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int oldDebug = POSIX::debug;
|
const int oldDebug = POSIX::debug;
|
||||||
|
@ -69,7 +69,7 @@ Foam::boolList Foam::haveMeshFile
|
|||||||
|
|
||||||
void Foam::removeProcAddressing(const faMesh& mesh)
|
void Foam::removeProcAddressing(const faMesh& mesh)
|
||||||
{
|
{
|
||||||
IOobject ioAddr
|
IOobject io
|
||||||
(
|
(
|
||||||
"procAddressing",
|
"procAddressing",
|
||||||
mesh.facesInstance(),
|
mesh.facesInstance(),
|
||||||
@ -79,9 +79,9 @@ void Foam::removeProcAddressing(const faMesh& mesh)
|
|||||||
|
|
||||||
for (const auto prefix : {"boundary", "edge", "face", "point"})
|
for (const auto prefix : {"boundary", "edge", "face", "point"})
|
||||||
{
|
{
|
||||||
ioAddr.rename(prefix + word("ProcAddressing"));
|
io.rename(prefix + word("ProcAddressing"));
|
||||||
|
|
||||||
const fileName procFile(ioAddr.objectPath());
|
const fileName procFile(io.objectPath());
|
||||||
Foam::rm(procFile);
|
Foam::rm(procFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ void Foam::removeProcAddressing(const faMesh& mesh)
|
|||||||
|
|
||||||
void Foam::removeProcAddressing(const polyMesh& mesh)
|
void Foam::removeProcAddressing(const polyMesh& mesh)
|
||||||
{
|
{
|
||||||
IOobject ioAddr
|
IOobject io
|
||||||
(
|
(
|
||||||
"procAddressing",
|
"procAddressing",
|
||||||
mesh.facesInstance(),
|
mesh.facesInstance(),
|
||||||
@ -99,89 +99,18 @@ void Foam::removeProcAddressing(const polyMesh& mesh)
|
|||||||
|
|
||||||
for (const auto prefix : {"boundary", "cell", "face", "point"})
|
for (const auto prefix : {"boundary", "cell", "face", "point"})
|
||||||
{
|
{
|
||||||
ioAddr.rename(prefix + word("ProcAddressing"));
|
io.rename(prefix + word("ProcAddressing"));
|
||||||
|
|
||||||
const fileName procFile(ioAddr.objectPath());
|
const fileName procFile(io.objectPath());
|
||||||
Foam::rm(procFile);
|
Foam::rm(procFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::removeEmptyDir(const fileName& path)
|
void Foam::removeEmptyDir(const fileName& path)
|
||||||
{
|
{
|
||||||
// Return true if empty directory. Note bypass of fileHandler to be
|
// Remove directory: silent, emptyOnly
|
||||||
// consistent with polyMesh.removeFiles for now.
|
Foam::rmDir(path, true, true);
|
||||||
|
|
||||||
{
|
|
||||||
fileNameList files
|
|
||||||
(
|
|
||||||
Foam::readDir
|
|
||||||
(
|
|
||||||
path,
|
|
||||||
fileName::FILE,
|
|
||||||
false, // filterGz
|
|
||||||
false // followLink
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (files.size())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
fileNameList dirs
|
|
||||||
(
|
|
||||||
Foam::readDir
|
|
||||||
(
|
|
||||||
path,
|
|
||||||
fileName::DIRECTORY,
|
|
||||||
false, // filterGz
|
|
||||||
false // followLink
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (dirs.size())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
fileNameList links
|
|
||||||
(
|
|
||||||
Foam::readDir
|
|
||||||
(
|
|
||||||
path,
|
|
||||||
fileName::SYMLINK,
|
|
||||||
false, // filterGz
|
|
||||||
false // followLink
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (links.size())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
fileNameList other
|
|
||||||
(
|
|
||||||
Foam::readDir
|
|
||||||
(
|
|
||||||
path,
|
|
||||||
fileName::UNDEFINED,
|
|
||||||
false, // filterGz
|
|
||||||
false // followLink
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (other.size())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid checking success of deletion since initial path might not
|
|
||||||
// exist (e.g. contain 'region0'). Will stop when trying to delete
|
|
||||||
// parent directory anyway since now not empty.
|
|
||||||
Foam::rm(path);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ void removeProcAddressing(const faMesh& mesh);
|
|||||||
//- Remove procAddressing
|
//- Remove procAddressing
|
||||||
void removeProcAddressing(const polyMesh& mesh);
|
void removeProcAddressing(const polyMesh& mesh);
|
||||||
|
|
||||||
//- Remove empty directory. Return true if removed.
|
//- Remove empty directory
|
||||||
bool removeEmptyDir(const fileName& path);
|
void removeEmptyDir(const fileName& path);
|
||||||
|
|
||||||
//- Remove empty directories from bottom up
|
//- Remove empty directories from bottom up
|
||||||
void removeEmptyDirs(const fileName& path);
|
void removeEmptyDirs(const fileName& path);
|
||||||
|
@ -1187,7 +1187,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
if (decompose)
|
if (decompose)
|
||||||
{
|
{
|
||||||
Info<< "Removing existing processor directory" << procDir << endl;
|
Info<< "Removing existing processor directory:"
|
||||||
|
<< args.relativePath(procDir) << endl;
|
||||||
fileHandler().rmDir(procDir);
|
fileHandler().rmDir(procDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2348,6 +2349,8 @@ int main(int argc, char *argv[])
|
|||||||
// Remove any left-over empty processor directories created
|
// Remove any left-over empty processor directories created
|
||||||
// by loadOrCreateMesh to get around the collated start-up
|
// by loadOrCreateMesh to get around the collated start-up
|
||||||
// problems
|
// problems
|
||||||
|
Info<< "Removing left-over empty processor directories" << nl;
|
||||||
|
|
||||||
if (Pstream::master()) //fileHandler().comm()))
|
if (Pstream::master()) //fileHandler().comm()))
|
||||||
{
|
{
|
||||||
const auto myProci = UPstream::myProcNo(); //comm()
|
const auto myProci = UPstream::myProcNo(); //comm()
|
||||||
@ -2364,9 +2367,7 @@ int main(int argc, char *argv[])
|
|||||||
&& volMeshDir[proci] != volMeshDir[myProci]
|
&& volMeshDir[proci] != volMeshDir[myProci]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Info<< "Deleting mesh dir:"
|
Foam::rmDir(volMeshDir[proci], true); // silent
|
||||||
<< volMeshDir[proci] << endl;
|
|
||||||
Foam::rmDir(volMeshDir[proci]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if
|
if
|
||||||
@ -2375,9 +2376,18 @@ int main(int argc, char *argv[])
|
|||||||
&& areaMeshDir[proci] != areaMeshDir[myProci]
|
&& areaMeshDir[proci] != areaMeshDir[myProci]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Info<< "Deleting mesh dir:"
|
Foam::rmDir(areaMeshDir[proci], true); // silent
|
||||||
<< areaMeshDir[proci] << endl;
|
}
|
||||||
Foam::rmDir(areaMeshDir[proci]);
|
|
||||||
|
// Remove empty processor directories
|
||||||
|
// Eg, <path-name>/processorN/constant/polyMesh
|
||||||
|
// to <path-name>/processorN
|
||||||
|
if (proci != myProci)
|
||||||
|
{
|
||||||
|
removeEmptyDir
|
||||||
|
(
|
||||||
|
volMeshDir[proci].path().path()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2441,7 +2451,8 @@ int main(int argc, char *argv[])
|
|||||||
// Remove dummy mesh created by loadOrCreateMesh
|
// Remove dummy mesh created by loadOrCreateMesh
|
||||||
const bool oldParRun = Pstream::parRun(false);
|
const bool oldParRun = Pstream::parRun(false);
|
||||||
mesh.removeFiles();
|
mesh.removeFiles();
|
||||||
Foam::rmDir(mesh.objectRegistry::objectPath());
|
// Silent rmdir
|
||||||
|
Foam::rmDir(mesh.objectRegistry::objectPath(), true);
|
||||||
Pstream::parRun(oldParRun); // Restore parallel state
|
Pstream::parRun(oldParRun); // Restore parallel state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,9 +723,6 @@ Foam::fileNameList Foam::readDir
|
|||||||
// also used as increment if initial size found to be insufficient
|
// also used as increment if initial size found to be insufficient
|
||||||
static constexpr int maxNnames = 100;
|
static constexpr int maxNnames = 100;
|
||||||
|
|
||||||
// Basic sanity: cannot strip '.gz' from directory names
|
|
||||||
const bool stripgz = filtergz && (type != fileName::DIRECTORY);
|
|
||||||
|
|
||||||
fileNameList dirEntries;
|
fileNameList dirEntries;
|
||||||
|
|
||||||
// Iterate contents (ignores an empty directory name)
|
// Iterate contents (ignores an empty directory name)
|
||||||
@ -768,22 +765,30 @@ Foam::fileNameList Foam::readDir
|
|||||||
}
|
}
|
||||||
else if
|
else if
|
||||||
(
|
(
|
||||||
(type == fileName::DIRECTORY)
|
(type == fileName::Type::DIRECTORY)
|
||||||
|| (type == fileName::FILE && !fileName::isBackup(name))
|
|| (type == fileName::Type::FILE && !fileName::isBackup(name))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((directory/name).type() == type)
|
fileName::Type detected = (directory/name).type();
|
||||||
|
|
||||||
|
if (detected == type)
|
||||||
{
|
{
|
||||||
|
// Only strip '.gz' from non-directory names
|
||||||
|
if
|
||||||
|
(
|
||||||
|
filtergz
|
||||||
|
&& (detected != fileName::Type::DIRECTORY)
|
||||||
|
&& name.has_ext("gz")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
name.remove_ext();
|
||||||
|
}
|
||||||
|
|
||||||
if (nEntries >= dirEntries.size())
|
if (nEntries >= dirEntries.size())
|
||||||
{
|
{
|
||||||
dirEntries.resize(dirEntries.size() + maxNnames);
|
dirEntries.resize(dirEntries.size() + maxNnames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stripgz && name.has_ext("gz"))
|
|
||||||
{
|
|
||||||
name.remove_ext();
|
|
||||||
}
|
|
||||||
|
|
||||||
dirEntries[nEntries] = std::move(name);
|
dirEntries[nEntries] = std::move(name);
|
||||||
++nEntries;
|
++nEntries;
|
||||||
}
|
}
|
||||||
@ -1031,20 +1036,31 @@ bool Foam::rm(const fileName& file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::rmDir(const fileName& directory, const bool silent)
|
bool Foam::rmDir
|
||||||
|
(
|
||||||
|
const fileName& directory,
|
||||||
|
const bool silent,
|
||||||
|
const bool emptyOnly
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
if (directory.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate contents (ignores an empty directory name)
|
// Iterate contents (ignores an empty directory name)
|
||||||
// Also retain hidden files/dirs for removal
|
// Also retain hidden files/dirs for removal
|
||||||
|
|
||||||
MSwindows::directoryIterator dirIter(directory, true);
|
MSwindows::directoryIterator dirIter(directory, true);
|
||||||
|
|
||||||
if (!dirIter.exists())
|
if (!dirIter.exists())
|
||||||
{
|
{
|
||||||
if (!silent)
|
if (!silent && !emptyOnly)
|
||||||
{
|
{
|
||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "cannot open directory " << directory << endl;
|
<< "Cannot open directory " << directory << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MSwindows::debug)
|
if (MSwindows::debug)
|
||||||
@ -1053,9 +1069,8 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
<< " : removing directory " << directory << endl;
|
<< " : removing directory " << directory << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Process each directory entry, counting any errors encountered
|
// Process each directory entry, counting any errors encountered
|
||||||
label nErrors = 0;
|
int nErrors = 0;
|
||||||
|
|
||||||
for (/*nil*/; dirIter; ++dirIter)
|
for (/*nil*/; dirIter; ++dirIter)
|
||||||
{
|
{
|
||||||
@ -1067,13 +1082,23 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
|
|
||||||
const fileName path(fileName::concat(directory, item));
|
const fileName path(fileName::concat(directory, item));
|
||||||
|
|
||||||
if (path.type(false) == fileName::DIRECTORY)
|
fileName::Type detected = path.type(false); // No followLink
|
||||||
|
|
||||||
|
if (detected == fileName::DIRECTORY)
|
||||||
{
|
{
|
||||||
if (!rmDir(path, true)) // Only report errors at the top-level
|
// Call silently for lower levels
|
||||||
|
if (!rmDir(path, true, emptyOnly))
|
||||||
{
|
{
|
||||||
++nErrors;
|
++nErrors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (emptyOnly)
|
||||||
|
{
|
||||||
|
// Only remove empty directories (not files)
|
||||||
|
++nErrors;
|
||||||
|
|
||||||
|
// POSIX has extra handling for dead symlinks...
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!rm(path))
|
if (!rm(path))
|
||||||
@ -1083,29 +1108,28 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nErrors)
|
if (nErrors == 0)
|
||||||
{
|
|
||||||
if (!silent)
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "failed to remove directory " << directory << nl
|
|
||||||
<< "could not remove " << nErrors << " sub-entries" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// No errors encountered - try to remove the top-level
|
||||||
|
|
||||||
if (!::RemoveDirectory(directory.c_str()))
|
if (!::RemoveDirectory(directory.c_str()))
|
||||||
{
|
{
|
||||||
++nErrors;
|
nErrors = -1; // A top-level error
|
||||||
if (!silent)
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "failed to remove directory " << directory << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !nErrors;
|
if (nErrors && !silent && !emptyOnly)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Failed to remove directory " << directory << endl;
|
||||||
|
|
||||||
|
if (nErrors > 0)
|
||||||
|
{
|
||||||
|
Info<< "could not remove " << nErrors << " sub-entries" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (nErrors == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -899,9 +899,6 @@ Foam::fileNameList Foam::readDir
|
|||||||
// Initial filename list size and the increment when resizing the list
|
// Initial filename list size and the increment when resizing the list
|
||||||
constexpr int maxNnames = 100;
|
constexpr int maxNnames = 100;
|
||||||
|
|
||||||
// Basic sanity: cannot strip '.gz' from directory names
|
|
||||||
const bool stripgz = filtergz && (type != fileName::DIRECTORY);
|
|
||||||
|
|
||||||
fileNameList dirEntries;
|
fileNameList dirEntries;
|
||||||
|
|
||||||
// Iterate contents (ignores an empty directory name)
|
// Iterate contents (ignores an empty directory name)
|
||||||
@ -947,22 +944,30 @@ Foam::fileNameList Foam::readDir
|
|||||||
}
|
}
|
||||||
else if
|
else if
|
||||||
(
|
(
|
||||||
(type == fileName::DIRECTORY)
|
(type == fileName::Type::DIRECTORY)
|
||||||
|| (type == fileName::FILE && !fileName::isBackup(name))
|
|| (type == fileName::Type::FILE && !fileName::isBackup(name))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if ((directory/name).type(followLink) == type)
|
fileName::Type detected = (directory/name).type(followLink);
|
||||||
|
|
||||||
|
if (detected == type)
|
||||||
{
|
{
|
||||||
|
// Only strip '.gz' from non-directory names
|
||||||
|
if
|
||||||
|
(
|
||||||
|
filtergz
|
||||||
|
&& (detected != fileName::Type::DIRECTORY)
|
||||||
|
&& name.has_ext("gz")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
name.remove_ext();
|
||||||
|
}
|
||||||
|
|
||||||
if (nEntries >= dirEntries.size())
|
if (nEntries >= dirEntries.size())
|
||||||
{
|
{
|
||||||
dirEntries.resize(dirEntries.size() + maxNnames);
|
dirEntries.resize(dirEntries.size() + maxNnames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stripgz && name.has_ext("gz"))
|
|
||||||
{
|
|
||||||
name.remove_ext();
|
|
||||||
}
|
|
||||||
|
|
||||||
dirEntries[nEntries] = std::move(name);
|
dirEntries[nEntries] = std::move(name);
|
||||||
++nEntries;
|
++nEntries;
|
||||||
}
|
}
|
||||||
@ -1319,18 +1324,28 @@ bool Foam::rm(const fileName& file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::rmDir(const fileName& directory, const bool silent)
|
bool Foam::rmDir
|
||||||
|
(
|
||||||
|
const fileName& directory,
|
||||||
|
const bool silent,
|
||||||
|
const bool emptyOnly
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
if (directory.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate contents (ignores an empty directory name)
|
// Iterate contents (ignores an empty directory name)
|
||||||
// Also retain hidden files/dirs for removal
|
// Also retain hidden files/dirs for removal
|
||||||
|
|
||||||
POSIX::directoryIterator dirIter(directory, true);
|
POSIX::directoryIterator dirIter(directory, true);
|
||||||
if (!dirIter.exists())
|
if (!dirIter.exists())
|
||||||
{
|
{
|
||||||
if (!silent)
|
if (!silent && !emptyOnly)
|
||||||
{
|
{
|
||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "cannot open directory " << directory << endl;
|
<< "Cannot open directory " << directory << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1347,7 +1362,7 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process each directory entry, counting any errors encountered
|
// Process each directory entry, counting any errors encountered
|
||||||
label nErrors = 0;
|
int nErrors = 0;
|
||||||
|
|
||||||
for (/*nil*/; dirIter; ++dirIter)
|
for (/*nil*/; dirIter; ++dirIter)
|
||||||
{
|
{
|
||||||
@ -1359,13 +1374,37 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
|
|
||||||
const fileName path(fileName::concat(directory, item));
|
const fileName path(fileName::concat(directory, item));
|
||||||
|
|
||||||
if (path.type(false) == fileName::DIRECTORY)
|
fileName::Type detected = path.type(false); // No followLink
|
||||||
|
|
||||||
|
if (detected == fileName::Type::DIRECTORY)
|
||||||
{
|
{
|
||||||
if (!rmDir(path, true)) // Only report errors at the top-level
|
// Call silently for lower levels
|
||||||
|
if (!rmDir(path, true, emptyOnly))
|
||||||
{
|
{
|
||||||
++nErrors;
|
++nErrors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (emptyOnly)
|
||||||
|
{
|
||||||
|
// Only remove empty directories (not files)
|
||||||
|
++nErrors;
|
||||||
|
|
||||||
|
// Check for dead symlinks
|
||||||
|
if (detected == fileName::Type::SYMLINK)
|
||||||
|
{
|
||||||
|
detected = path.type(true); // followLink
|
||||||
|
|
||||||
|
if (detected == fileName::Type::UNDEFINED)
|
||||||
|
{
|
||||||
|
--nErrors;
|
||||||
|
|
||||||
|
if (!rm(path))
|
||||||
|
{
|
||||||
|
++nErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!rm(path))
|
if (!rm(path))
|
||||||
@ -1375,30 +1414,28 @@ bool Foam::rmDir(const fileName& directory, const bool silent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nErrors)
|
if (nErrors == 0)
|
||||||
{
|
|
||||||
if (!silent)
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "failed to remove directory " << directory << nl
|
|
||||||
<< "could not remove " << nErrors << " sub-entries" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// No errors encountered - try to remove the top-level
|
||||||
|
|
||||||
if (!rm(directory))
|
if (!rm(directory))
|
||||||
{
|
{
|
||||||
++nErrors;
|
nErrors = -1; // A top-level error
|
||||||
if (!silent)
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "failed to remove directory " << directory << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
if (nErrors && !silent && !emptyOnly)
|
||||||
return !nErrors;
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Failed to remove directory " << directory << endl;
|
||||||
|
|
||||||
|
if (nErrors > 0)
|
||||||
|
{
|
||||||
|
Info<< "could not remove " << nErrors << " sub-entries" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (nErrors == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -357,11 +357,14 @@ public:
|
|||||||
virtual bool rm(const fileName&) const = 0;
|
virtual bool rm(const fileName&) const = 0;
|
||||||
|
|
||||||
//- Remove a directory and its contents
|
//- Remove a directory and its contents
|
||||||
|
// \param dir the directory to remove
|
||||||
// \param silent do not report missing directory
|
// \param silent do not report missing directory
|
||||||
|
// \param emptyOnly only remove empty directories (recursive)
|
||||||
virtual bool rmDir
|
virtual bool rmDir
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const bool silent = false
|
const bool silent = false,
|
||||||
|
const bool emptyOnly = false
|
||||||
) const = 0;
|
) const = 0;
|
||||||
|
|
||||||
// //- Open a shared library. Return handle to library. Print error
|
// //- Open a shared library. Return handle to library. Print error
|
||||||
|
@ -1018,13 +1018,14 @@ bool Foam::fileOperations::masterUncollatedFileOperation::rm
|
|||||||
bool Foam::fileOperations::masterUncollatedFileOperation::rmDir
|
bool Foam::fileOperations::masterUncollatedFileOperation::rmDir
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const bool silent
|
const bool silent,
|
||||||
|
const bool emptyOnly
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return masterOp<bool>
|
return masterOp<bool>
|
||||||
(
|
(
|
||||||
dir,
|
dir,
|
||||||
rmDirOp(silent),
|
rmDirOp(silent, emptyOnly),
|
||||||
Pstream::msgType(),
|
Pstream::msgType(),
|
||||||
comm_
|
comm_
|
||||||
);
|
);
|
||||||
|
@ -283,15 +283,17 @@ protected:
|
|||||||
class rmDirOp
|
class rmDirOp
|
||||||
{
|
{
|
||||||
bool silent_;
|
bool silent_;
|
||||||
|
bool emptyOnly_;
|
||||||
public:
|
public:
|
||||||
rmDirOp(const bool silent=false)
|
rmDirOp(bool silent=false, bool emptyOnly=false)
|
||||||
:
|
:
|
||||||
silent_(silent)
|
silent_(silent),
|
||||||
|
emptyOnly_(emptyOnly)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool operator()(const fileName& f) const
|
bool operator()(const fileName& f) const
|
||||||
{
|
{
|
||||||
return Foam::rmDir(f, silent_);
|
return Foam::rmDir(f, silent_, emptyOnly_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -603,11 +605,14 @@ public:
|
|||||||
virtual bool rm(const fileName&) const;
|
virtual bool rm(const fileName&) const;
|
||||||
|
|
||||||
//- Remove a directory and its contents
|
//- Remove a directory and its contents
|
||||||
|
// \param dir the directory to remove
|
||||||
// \param silent do not report missing directory
|
// \param silent do not report missing directory
|
||||||
|
// \param emptyOnly only remove empty directories (recursive)
|
||||||
virtual bool rmDir
|
virtual bool rmDir
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const bool silent = false
|
const bool silent = false,
|
||||||
|
const bool emptyOnly = false
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// //- Open a shared library. Return handle to library. Print error
|
// //- Open a shared library. Return handle to library. Print error
|
||||||
|
@ -317,10 +317,11 @@ bool Foam::fileOperations::uncollatedFileOperation::rm
|
|||||||
bool Foam::fileOperations::uncollatedFileOperation::rmDir
|
bool Foam::fileOperations::uncollatedFileOperation::rmDir
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const bool silent
|
const bool silent,
|
||||||
|
const bool emptyOnly
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return Foam::rmDir(dir, silent);
|
return Foam::rmDir(dir, silent, emptyOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,10 +205,14 @@ public:
|
|||||||
virtual bool rm(const fileName&) const;
|
virtual bool rm(const fileName&) const;
|
||||||
|
|
||||||
//- Remove a directory and its contents
|
//- Remove a directory and its contents
|
||||||
|
// \param dir the directory to remove
|
||||||
|
// \param silent do not report missing directory
|
||||||
|
// \param emptyOnly only remove empty directories (recursive)
|
||||||
virtual bool rmDir
|
virtual bool rmDir
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const bool silent = false
|
const bool silent = false,
|
||||||
|
const bool emptyOnly = false
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// //- Open a shared library. Return handle to library. Print error
|
// //- Open a shared library. Return handle to library. Print error
|
||||||
|
@ -178,10 +178,14 @@ double highResLastModified(const fileName&, const bool followLink=true);
|
|||||||
// Using an empty directory name returns an empty list.
|
// Using an empty directory name returns an empty list.
|
||||||
fileNameList readDir
|
fileNameList readDir
|
||||||
(
|
(
|
||||||
|
//! The directory name to scan
|
||||||
const fileName& directory,
|
const fileName& directory,
|
||||||
const fileName::Type type=fileName::FILE,
|
//! The content type (eg, FILE | DIRECTORY)
|
||||||
const bool filtergz=true,
|
const fileName::Type type = fileName::Type::FILE,
|
||||||
const bool followLink=true
|
//! Trim '.gz' from file names
|
||||||
|
const bool filtergz = true,
|
||||||
|
//! Check what the symlink points to, not the symlink itself
|
||||||
|
const bool followLink = true
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Copy the source to the destination (recursively if necessary).
|
//- Copy the source to the destination (recursively if necessary).
|
||||||
@ -211,10 +215,18 @@ bool mvBak(const fileName& src, const std::string& ext = "bak");
|
|||||||
// An empty name is a no-op that always returns false.
|
// An empty name is a no-op that always returns false.
|
||||||
bool rm(const fileName& file);
|
bool rm(const fileName& file);
|
||||||
|
|
||||||
//- Remove a directory and its contents (optionally silencing warnings)
|
//- Remove a directory and its contents recursively,
|
||||||
// An empty directory name is a no-op that always returns false,
|
// returning true if successful.
|
||||||
// but also produces a warning.
|
// An empty directory name is a no-op that always returns false (silently)
|
||||||
bool rmDir(const fileName& directory, const bool silent=false);
|
bool rmDir
|
||||||
|
(
|
||||||
|
//! The directory name to remove
|
||||||
|
const fileName& directory,
|
||||||
|
//! Silence warnings
|
||||||
|
const bool silent = false,
|
||||||
|
//! Only remove empty directories (recursive)
|
||||||
|
const bool emptyOnly = false
|
||||||
|
);
|
||||||
|
|
||||||
//- Sleep for the specified number of seconds
|
//- Sleep for the specified number of seconds
|
||||||
unsigned int sleep(const unsigned int sec);
|
unsigned int sleep(const unsigned int sec);
|
||||||
|
@ -98,35 +98,32 @@ Foam::processorFaMeshes::processorFaMeshes
|
|||||||
|
|
||||||
void Foam::processorFaMeshes::removeFiles(const faMesh& mesh)
|
void Foam::processorFaMeshes::removeFiles(const faMesh& mesh)
|
||||||
{
|
{
|
||||||
IOobject ioAddr
|
IOobject io
|
||||||
(
|
(
|
||||||
"procAddressing",
|
"procAddressing",
|
||||||
mesh.facesInstance(),
|
mesh.facesInstance(),
|
||||||
faMesh::meshSubDir,
|
faMesh::meshSubDir,
|
||||||
mesh.thisDb(),
|
mesh.thisDb()
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // not registered
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// procAddressing
|
// procAddressing
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// pointProcAddressing
|
// pointProcAddressing
|
||||||
ioAddr.rename("pointProcAddressing");
|
io.rename("pointProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// edgeProcAddressing
|
// edgeProcAddressing
|
||||||
ioAddr.rename("edgeProcAddressing");
|
io.rename("edgeProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// faceProcAddressing
|
// faceProcAddressing
|
||||||
ioAddr.rename("faceProcAddressing");
|
io.rename("faceProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// boundaryProcAddressing
|
// boundaryProcAddressing
|
||||||
ioAddr.rename("boundaryProcAddressing");
|
io.rename("boundaryProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ void Foam::processorMeshes::reconstructPoints(fvMesh& mesh)
|
|||||||
meshes_[proci].thisDb(),
|
meshes_[proci].thisDb(),
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false // not registered
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -230,35 +230,32 @@ void Foam::processorMeshes::reconstructPoints(fvMesh& mesh)
|
|||||||
|
|
||||||
void Foam::processorMeshes::removeFiles(const polyMesh& mesh)
|
void Foam::processorMeshes::removeFiles(const polyMesh& mesh)
|
||||||
{
|
{
|
||||||
IOobject ioAddr
|
IOobject io
|
||||||
(
|
(
|
||||||
"procAddressing",
|
"procAddressing",
|
||||||
mesh.facesInstance(),
|
mesh.facesInstance(),
|
||||||
polyMesh::meshSubDir,
|
polyMesh::meshSubDir,
|
||||||
mesh.thisDb(),
|
mesh.thisDb()
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // not registered
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// procAddressing
|
// procAddressing
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// pointProcAddressing
|
// pointProcAddressing
|
||||||
ioAddr.rename("pointProcAddressing");
|
io.rename("pointProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// faceProcAddressing
|
// faceProcAddressing
|
||||||
ioAddr.rename("faceProcAddressing");
|
io.rename("faceProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// cellProcAddressing
|
// cellProcAddressing
|
||||||
ioAddr.rename("cellProcAddressing");
|
io.rename("cellProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
|
|
||||||
// boundaryProcAddressing
|
// boundaryProcAddressing
|
||||||
ioAddr.rename("boundaryProcAddressing");
|
io.rename("boundaryProcAddressing");
|
||||||
rm(ioAddr.objectPath());
|
fileHandler().rm(fileHandler().filePath(io.objectPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,18 +2,22 @@
|
|||||||
cd "${0%/*}" || exit # Run from this directory
|
cd "${0%/*}" || exit # Run from this directory
|
||||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
fileHandler="-fileHandler collated"
|
||||||
|
decomp16="-decomposeParDict system/decomposeParDict.16"
|
||||||
|
|
||||||
runApplication blockMesh
|
runApplication blockMesh
|
||||||
|
|
||||||
##- Serial run
|
##- Serial run
|
||||||
#runApplication snappyHexMesh
|
#runApplication snappyHexMesh -overwrite $fileHandler
|
||||||
#runApplication checkMesh -allTopology -allGeometry
|
#runApplication checkMesh -allTopology -allGeometry
|
||||||
|
|
||||||
#- Parallel run
|
#- Parallel run
|
||||||
runApplication decomposePar
|
runParallel -s decompose redistributePar -decompose -constant $fileHandler
|
||||||
runParallel snappyHexMesh
|
runParallel snappyHexMesh -overwrite $fileHandler
|
||||||
runParallel checkMesh -allTopology -allGeometry
|
runParallel checkMesh -allTopology -allGeometry $fileHandler
|
||||||
|
|
||||||
#runApplication reconstructParMesh -constant
|
# runParallel -s redistrib $decomp16 redistributePar -constant $fileHandler
|
||||||
|
|
||||||
|
#runApplication reconstructParMesh -constant $fileHandler
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
@ -10,18 +10,15 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
note "mesh decomposition control dictionary";
|
|
||||||
object decomposeParDict;
|
object decomposeParDict;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- The total number of domains (mandatory)
|
|
||||||
numberOfSubdomains 8;
|
numberOfSubdomains 8;
|
||||||
|
|
||||||
//- The decomposition method (mandatory)
|
|
||||||
method hierarchical;
|
method hierarchical;
|
||||||
|
|
||||||
hierarchicalCoeffs
|
coeffs
|
||||||
{
|
{
|
||||||
n (2 2 2);
|
n (2 2 2);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2206 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object decomposeParDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
numberOfSubdomains 16;
|
||||||
|
|
||||||
|
method scotch;
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user