ENH: improve findInstance handling for optional files

- previously would always return "constant" as the instance for
  an optional dir/file that wasn't found.
  However, this meant retesting to screen out false positives.
  Now support an additional parameter
      'bool constant_fallback = ...'
  to return "constant" or an empty word.

  The method signature changes slightly with a new optional bool
  parameter:

      //! Return \c "constant" instead of \c "" if the search failed
      const bool constant_fallback = true

ENH: code consolidation for findInstancePath

- relocate from Time to TimePaths and provide an additional static
  version that is reused in fileOperations

BUG: distributedTriSurfaceMesh:::findLocalInstance broken (#3135)

- was not checking the parent at all.

COMP: remove unused findInstancePath(const fileName&, ..) method
This commit is contained in:
Mark Olesen
2024-04-08 15:19:58 +02:00
parent 85771c8985
commit d578d48a4f
12 changed files with 197 additions and 180 deletions

View File

@ -53,46 +53,37 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
fileName coherentInst; word coherentInst;
coherentInst = coherentInst =
( (
runTime.findInstance runTime.findInstance
( (
polyMesh::meshSubDir, polyMesh::meshSubDir,
"coherent", "coherent",
IOobject::READ_IF_PRESENT IOobject::READ_IF_PRESENT,
word::null, // No stop instance
false // No "constant" fallback (word::null instead)
) )
); );
// Unfortunately with READ_IF_PRESENT, cannot tell if the file Info<< "Found coherent \"" << coherentInst << '"' << nl;
// was actually found or not
Info<< "check: " << (coherentInst/polyMesh::meshSubDir/"coherent") << nl;
if (!Foam::isFile(coherentInst/polyMesh::meshSubDir/"coherent"))
{
coherentInst.clear();
}
Info<< "found coherent: " << coherentInst << nl;
PtrList<entry> entries; PtrList<entry> entries;
if (!coherentInst.empty()) if (!coherentInst.empty())
{ {
IOdictionary coherent dictionary coherent =
( IOdictionary::readContents
IOobject
( (
"coherent", IOobject
coherentInst, (
polyMesh::meshSubDir, "coherent",
runTime, coherentInst,
IOobject::MUST_READ, polyMesh::meshSubDir,
IOobject::NO_WRITE, runTime,
IOobject::NO_REGISTER IOobject::MUST_READ
) )
); );
ITstream& is = coherent.lookup("boundary"); ITstream& is = coherent.lookup("boundary");
is >> entries; is >> entries;
@ -105,7 +96,7 @@ int main(int argc, char *argv[])
Info<< "size: " << polyBoundaryMeshEntries::patchSizes(entries) << nl; Info<< "size: " << polyBoundaryMeshEntries::patchSizes(entries) << nl;
Info<< nl; Info<< nl;
fileName boundaryInst; word boundaryInst;
boundaryInst = boundaryInst =
( (
runTime.findInstance runTime.findInstance
@ -116,7 +107,7 @@ int main(int argc, char *argv[])
) )
); );
Info<< "found boundary: " << boundaryInst << nl; Info<< "Found boundary: \"" << boundaryInst << '"' << nl;
polyBoundaryMeshEntries pbm polyBoundaryMeshEntries pbm
( (

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-2023 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -314,11 +314,7 @@ boundBox procBounds
{ {
fileName pointsInstance fileName pointsInstance
( (
procDb.findInstance procDb.findInstance(polyMesh::meshDir(regionName), "points")
(
polyMesh::meshDir(regionName),
"points"
)
); );
if (pointsInstance != procDb.timeName()) if (pointsInstance != procDb.timeName())
@ -343,11 +339,7 @@ boundBox procBounds
IOobject IOobject
( (
"points", "points",
procDb.findInstance pointsInstance,
(
polyMesh::meshDir(regionName),
"points"
),
polyMesh::meshDir(regionName), polyMesh::meshDir(regionName),
procDb, procDb,
IOobject::MUST_READ, IOobject::MUST_READ,

View File

@ -730,14 +730,15 @@ Foam::word Foam::Time::timeName(const scalar t, const int precision)
Foam::word Foam::Time::findInstance Foam::word Foam::Time::findInstance
( (
const fileName& dir, const fileName& directory,
const word& name, const word& name,
IOobjectOption::readOption rOpt, IOobjectOption::readOption rOpt,
const word& stopInstance const word& stopInstance,
const bool constant_fallback
) const ) const
{ {
// Note: name might be empty! // Note: name can empty (ie, search for directory only)
IOobject startIO(name, timeName(), dir, *this, rOpt); IOobject startIO(name, timeName(), directory, *this, rOpt);
IOobject io IOobject io
( (
@ -745,48 +746,14 @@ Foam::word Foam::Time::findInstance
( (
startIO, startIO,
timeOutputValue(), timeOutputValue(),
stopInstance stopInstance,
constant_fallback
) )
); );
return io.instance(); return io.instance();
} }
Foam::word Foam::Time::findInstancePath
(
const fileName& directory,
const instant& t
) const
{
// Simplified version: use findTimes (readDir + sort). The expensive
// bit is the readDir, not the sorting. Tbd: avoid calling findInstancePath
// from filePath.
instantList timeDirs = findTimes(path(), constant());
// Note:
// - times will include constant (with value 0) as first element.
// For backwards compatibility make sure to find 0 in preference
// to constant.
// - list is sorted so could use binary search
forAllReverse(timeDirs, i)
{
if (t.equal(timeDirs[i].value()))
{
return timeDirs[i].name();
}
}
return word::null;
}
Foam::word Foam::Time::findInstancePath(const instant& t) const
{
return findInstancePath(path(), t);
}
Foam::label Foam::Time::startTimeIndex() const Foam::label Foam::Time::startTimeIndex() const
{ {
return startTimeIndex_; return startTimeIndex_;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2019 OpenFOAM Foundation Copyright (C) 2011-2019 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -34,7 +34,7 @@ Description
SourceFiles SourceFiles
Time.C Time.C
TimeIO.C TimeIO.C
findInstance.C TimeNew.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -482,35 +482,31 @@ public:
// Searching // Searching
//- Return time instance (location) of \em dir that contains //- Return time instance (location) of \c directory containing
//- the file \em name (eg, used in reading mesh data). //- the file \c name (eg, used in reading mesh data).
// When \em is empty, searches for directory \em dir only. //- When \c name is empty, searches for \c directory only.
// Does not search beyond stopInstance (if set) or \em constant. //- Does not search beyond \c stopInstance (if set) or \c constant.
// //
// \note If the instance cannot be found, returns the // If the instance cannot be found:
// stopInstance (if set and reached) or \em constant. // - FatalError when readOpt is MUST_READ or READ_MODIFIED
// FatalError if it cannot be found and readOpt is // - return \c stopInstance (if set and reached)
// (MUST_READ or READ_MODIFIED). // - return \c constant if constant_fallback is true
// - return an empty word if constant_fallback is false
// .
word findInstance word findInstance
( (
const fileName& dir, //! The subdirectory (local) for the search
const word& name = word::null,
IOobjectOption::readOption rOpt = IOobjectOption::MUST_READ,
const word& stopInstance = word::null
) const;
//- Search the case for the time directory path
//- corresponding to the given instance
word findInstancePath
(
const fileName& directory, const fileName& directory,
const instant& t //! The filename for the search. If empty, only search for directory
const word& name = word::null,
//! The search type : generally MUST_READ or READ_IF_PRESENT
IOobjectOption::readOption rOpt = IOobjectOption::MUST_READ,
//! The search stop instance
const word& stopInstance = word::null,
//! Return \c "constant" instead of \c "" if the search failed
const bool constant_fallback = true
) const; ) const;
//- Search the case for the time directory path
//- corresponding to the given instance
word findInstancePath(const instant& t) const;
// Member Functions // Member Functions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -128,9 +128,60 @@ Foam::instantList Foam::TimePaths::times() const
} }
Foam::word Foam::TimePaths::findInstancePath
(
const UList<instant>& timeDirs,
const instant& t
)
{
// Note:
// - timeDirs will include constant (with value 0) as first element.
// For backwards compatibility make sure to find 0 in preference
// to constant.
// - list is sorted so could use binary search
forAllReverse(timeDirs, i)
{
if (t.equal(timeDirs[i].value()))
{
return timeDirs[i].name();
}
}
return word();
}
// Foam::word Foam::Time::findInstancePath
// (
// const fileName& directory,
// const instant& t
// ) const
// {
// // Simplified version: use findTimes (readDir + sort).
// // The expensive bit is the readDir, not the sorting.
// // TBD: avoid calling findInstancePath from filePath.
//
// instantList timeDirs = findTimes(directory, constant());
//
// return findInstancePath(timeDirs, i);
// }
Foam::word Foam::TimePaths::findInstancePath(const instant& t) const
{
// Simplified version: use findTimes (readDir + sort).
// The expensive bit is the readDir, not the sorting.
// TBD: avoid calling findInstancePath from filePath.
instantList timeDirs = findTimes(path(), constant());
return findInstancePath(timeDirs, t);
}
Foam::label Foam::TimePaths::findClosestTimeIndex Foam::label Foam::TimePaths::findClosestTimeIndex
( (
const instantList& timeDirs, const UList<instant>& timeDirs,
const scalar t, const scalar t,
const word& constantDirName const word& constantDirName
) )

View File

@ -53,7 +53,6 @@ class argList;
Class TimePaths Declaration Class TimePaths Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class TimePaths class TimePaths
{ {
// Private Data // Private Data
@ -187,16 +186,28 @@ public:
//- Search instantList for the time index closest to the specified time //- Search instantList for the time index closest to the specified time
static label findClosestTimeIndex static label findClosestTimeIndex
( (
const instantList& timeDirs, const UList<instant>& timeDirs,
const scalar t, const scalar t,
const word& constantDirName = "constant" const word& constantDirName = "constant"
); );
//- Search instantList for matching time value,
//- return the instance name or word::null if nothing is equal.
static word findInstancePath
(
const UList<instant>& timeDirs,
const instant& t
);
//- Search the case for valid time directories //- Search the case for valid time directories
instantList times() const; instantList times() const;
//- Search the case for the time closest to the given time //- Search the case for the time closest to the given time
instant findClosestTime(const scalar t) const; instant findClosestTime(const scalar t) const;
//- Search the case for the time directory path
//- corresponding to the given instance
word findInstancePath(const instant& t) const;
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017-2018 OpenFOAM Foundation Copyright (C) 2017-2018 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1078,7 +1078,8 @@ Foam::IOobject Foam::fileOperation::findInstance
( (
const IOobject& startIO, const IOobject& startIO,
const scalar startValue, const scalar startValue,
const word& stopInstance const word& stopInstance,
const bool constant_fallback
) const ) const
{ {
const Time& time = startIO.time(); const Time& time = startIO.time();
@ -1158,6 +1159,7 @@ Foam::IOobject Foam::fileOperation::findInstance
} }
else else
{ {
// At the stopInstance
return io; return io;
} }
break; break;
@ -1198,11 +1200,23 @@ Foam::IOobject Foam::fileOperation::findInstance
} }
if (!failed && exitIfMissing) if (!failed)
{ {
failed = failureCodes::FAILED_CONSTINST; if (exitIfMissing)
{
failed = failureCodes::FAILED_CONSTINST;
}
else if (constant_fallback)
{
io.instance() = time.constant();
}
else
{
io.instance().clear();
}
} }
// Handle failures // Handle failures
// ~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~
@ -1225,7 +1239,7 @@ Foam::IOobject Foam::fileOperation::findInstance
{ {
FatalError << stopInstance; FatalError << stopInstance;
} }
else else // FAILED_CONSTINST
{ {
FatalError << "constant"; FatalError << "constant";
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2020-2023 OpenCFD Ltd. Copyright (C) 2020-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -870,15 +870,24 @@ public:
//- Get sorted list of times //- Get sorted list of times
virtual instantList findTimes(const fileName&, const word&) const; virtual instantList findTimes(const fileName&, const word&) const;
//- Find instance where IOobject is. //- Find time instance where IOobject is located.
// FatalError if it cannot be found and readOpt is //- The name of the IOobject can be empty, in which case only the
// (MUST_READ or MUST_READ_IF_MODIFIED). //- IOobject::local() is checked.
// Otherwise it returns the stopInstance. //- Does not search beyond \c stopInstance (if set) or \c constant.
// If the instance cannot be found:
// - FatalError when readOpt is (MUST_READ or READ_MODIFIED)
// - returns the \c stopInstance (if set and reached)
// - return \c constant if constant_fallback is true.
// - return an empty word if constant_fallback is false.
// .
virtual IOobject findInstance virtual IOobject findInstance
( (
const IOobject& io, const IOobject& io,
const scalar startValue, const scalar startValue,
const word& stopInstance //! The search stop instance
const word& stopInstance,
//! Return \c "constant" instead of \c "" if the search failed
const bool constant_fallback = true
) const; ) const;
//- Callback for time change //- Callback for time change

View File

@ -85,31 +85,6 @@ namespace fileOperations
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::word
Foam::fileOperations::masterUncollatedFileOperation::findInstancePath
(
const instantList& timeDirs,
const instant& t
)
{
// Note:
// - times will include constant (with value 0) as first element.
// For backwards compatibility make sure to find 0 in preference
// to constant.
// - list is sorted so could use binary search
forAllReverse(timeDirs, i)
{
if (t.equal(timeDirs[i].value()))
{
return timeDirs[i].name();
}
}
return word();
}
Foam::fileName Foam::fileName
Foam::fileOperations::masterUncollatedFileOperation::filePathInfo Foam::fileOperations::masterUncollatedFileOperation::filePathInfo
( (
@ -216,11 +191,12 @@ Foam::fileOperations::masterUncollatedFileOperation::filePathInfo
if (search && pathFnd.good()) if (search && pathFnd.good())
{ {
newInstancePath = findInstancePath newInstancePath =
( Time::findInstancePath
*pathFnd(), (
instant(io.instance()) *pathFnd(),
); instant(io.instance())
);
if (newInstancePath.size() && newInstancePath != io.instance()) if (newInstancePath.size() && newInstancePath != io.instance())
{ {
@ -1423,7 +1399,8 @@ Foam::fileOperations::masterUncollatedFileOperation::findInstance
( (
const IOobject& startIO, const IOobject& startIO,
const scalar startValue, const scalar startValue,
const word& stopInstance const word& stopInstance,
const bool constant_fallback
) const ) const
{ {
if (debug) if (debug)
@ -1549,6 +1526,7 @@ Foam::fileOperations::masterUncollatedFileOperation::findInstance
} }
else else
{ {
// At the stopInstance
foundInstance = io.instance(); foundInstance = io.instance();
} }
break; break;
@ -1600,10 +1578,14 @@ Foam::fileOperations::masterUncollatedFileOperation::findInstance
{ {
failed = failureCodes::FAILED_CONSTINST; failed = failureCodes::FAILED_CONSTINST;
} }
else else if (constant_fallback)
{ {
foundInstance = time.constant(); foundInstance = time.constant();
} }
else
{
foundInstance.clear();
}
} }
const_cast<masterUncollatedFileOperation&>(*this).nProcs(oldNProcs); const_cast<masterUncollatedFileOperation&>(*this).nProcs(oldNProcs);
@ -1637,7 +1619,7 @@ Foam::fileOperations::masterUncollatedFileOperation::findInstance
{ {
FatalError << stopInstance; FatalError << stopInstance;
} }
else else // FAILED_CONSTINST
{ {
FatalError << "constant"; FatalError << "constant";
} }
@ -1698,8 +1680,7 @@ Foam::fileOperations::masterUncollatedFileOperation::readObjects
// Find similar time // Find similar time
// Copy of Time::findInstancePath. We want to avoid the // Copy of Time::findInstancePath. We want to avoid the
// parallel call to findTimes. Alternative is to have // parallel call to findTimes.
// version of findInstancePath that takes instantList ...
const instantList timeDirs const instantList timeDirs
( (
fileOperation::findTimes fileOperation::findTimes
@ -1709,20 +1690,20 @@ Foam::fileOperations::masterUncollatedFileOperation::readObjects
) )
); );
const instant t(instance); fileName foundInst
forAllReverse(timeDirs, i) (
Time::findInstancePath(timeDirs, instant(instance))
);
if (!foundInst.empty())
{ {
if (t.equal(timeDirs[i].value())) objectNames = fileOperation::readObjects
{ (
objectNames = fileOperation::readObjects db,
( foundInst, // newly found time
db, local,
timeDirs[i].name(), // newly found time newInstance
local, );
newInstance
);
break;
}
} }
} }

View File

@ -409,13 +409,6 @@ protected:
const label comm const label comm
) const; ) const;
//- Equivalent of Time::findInstance
static word findInstancePath
(
const instantList& timeDirs,
const instant& t
);
//- Search (locally!) for object; return info on how it was found. //- Search (locally!) for object; return info on how it was found.
// Does not do any parallel communication. // Does not do any parallel communication.
// checkGlobal : also check undecomposed case // checkGlobal : also check undecomposed case
@ -754,15 +747,24 @@ public:
//- Get sorted list of times //- Get sorted list of times
virtual instantList findTimes(const fileName&, const word&) const; virtual instantList findTimes(const fileName&, const word&) const;
//- Find instance where IOobject is. //- Find time instance where IOobject is located.
// FatalError if it cannot be found and readOpt is //- The name of the IOobject can be empty, in which case only the
// (MUST_READ or MUST_READ_IF_MODIFIED). //- IOobject::local() is checked.
// Otherwise it returns the stopInstance. //- Does not search beyond \c stopInstance (if set) or \c constant.
// If the instance cannot be found:
// - FatalError when readOpt is (MUST_READ or READ_MODIFIED)
// - returns the \c stopInstance (if set and reached)
// - return \c constant if constant_fallback is true.
// - return an empty word if constant_fallback is false.
// .
virtual IOobject findInstance virtual IOobject findInstance
( (
const IOobject& io, const IOobject& io,
const scalar startValue, const scalar startValue,
const word& stopInstance //! The search stop instance
const word& stopInstance,
//! Return \c "constant" instead of \c "" if the search failed
const bool constant_fallback = true
) const; ) const;
//- Callback for time change //- Callback for time change

View File

@ -537,7 +537,8 @@ Foam::fileNameList Foam::fileOperations::uncollatedFileOperation::readObjects
if (newInstance.empty()) if (newInstance.empty())
{ {
// Find similar time // Find similar time
fileName newInst = db.time().findInstancePath(instant(instance)); word newInst = db.time().findInstancePath(instant(instance));
if (!newInst.empty() && newInst != instance) if (!newInst.empty() && newInst != instance)
{ {
// Try with new time // Try with new time

View File

@ -236,7 +236,9 @@ Foam::word Foam::distributedTriSurfaceMesh::findLocalInstance
( (
io.local(), io.local(),
word::null, word::null,
IOobject::READ_IF_PRESENT IOobject::READ_IF_PRESENT,
word::null, // No stop instance
false // No "constant" fallback (word::null instead)
) )
); );