diff --git a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.H b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.H index 23a99162a4380ebceac7fa5c0bffb0c10cfbbffa..6e1f8e5df870bfb589e997db6cfc3232155df071 100644 --- a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.H +++ b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.H @@ -93,6 +93,9 @@ SourceFiles namespace Foam { +// Forward Declarations +class dictionary; + /*---------------------------------------------------------------------------*\ Class decomposedBlockData Declaration \*---------------------------------------------------------------------------*/ @@ -177,8 +180,8 @@ public: //- Read object virtual bool read(); - //- Write separated content. Assumes content is the serialised data - // and that the master data contains a header + //- Write separated content (assumes content is the serialised data) + // The serialised master data should also contain a FoamFile header virtual bool writeData(Ostream& os) const; //- Write using stream options @@ -209,7 +212,8 @@ public: const word& objectType, const string& note, const fileName& location, - const word& objectName + const word& objectName, + const dictionary* extraEntries = nullptr ); //- Helper: write FoamFile IOobject header @@ -220,6 +224,14 @@ public: const IOobject& io ); + //- Helper: generate additional entries for FoamFile header + static void writeExtraHeaderContent + ( + dictionary& dict, + IOstreamOption streamOptData, + const IOobject& io + ); + //- Helper: read block of (binary) character data static bool readBlockEntry ( diff --git a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C index b1ccebb7547228002b87cafafb00a9edcad5a98a..51313bc9726b0873e83ed7e572f5bcd7b943cc47 100644 --- a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C +++ b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C @@ -140,7 +140,8 @@ void Foam::decomposedBlockData::writeHeader const word& objectType, const string& note, const fileName& location, - const word& objectName + const word& objectName, + const dictionary* extraEntries ) { if (IOobject::bannerEnabled()) @@ -160,6 +161,11 @@ void Foam::decomposedBlockData::writeHeader objectName ); + if (extraEntries) + { + extraEntries->writeEntries(os); + } + os.endBlock(); if (IOobject::bannerEnabled()) @@ -169,6 +175,25 @@ void Foam::decomposedBlockData::writeHeader } +void Foam::decomposedBlockData::writeExtraHeaderContent +( + dictionary& dict, + IOstreamOption streamOptData, + const IOobject& io +) +{ + dict.set("data.format", streamOptData.format()); + dict.set("data.class", io.type()); + + // Deep-copy of meta-data (if any) + const dictionary* metaDataDict = io.findMetaData(); + if (metaDataDict && !metaDataDict->empty()) + { + dict.add("meta", *metaDataDict); + } +} + + void Foam::decomposedBlockData::writeHeader ( Ostream& os, diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C index 9f76817ed3f8cbbbeb69718215dc697ed1bc5898..28bcfbe0ff368f2fc89945b2a599d9edaff3fc7b 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C @@ -79,18 +79,21 @@ bool Foam::OFstreamCollator::writeFile { Foam::mkDir(fName.path()); osPtr.reset(new OFstream(fName, streamOpt, append)); + auto& os = *osPtr; - // We don't have IOobject so cannot use IOobject::writeHeader if (!append) { + // No IOobject so cannot use IOobject::writeHeader + + // FoamFile decomposedBlockData::writeHeader ( - *osPtr, - streamOpt, // streamOpt for container + os, + streamOpt, // streamOpt for container objectType, - "", // note - "", // location (leave empty instead inaccurate) - fName.name() // object name + "", // note + "", // location (leave empty instead inaccurate) + fName.name() // object name ); } } diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.H b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.H index 4e2393bb984ab4f2535574373860509c7f86aeb6..de34d74a5dabc4ff5cc95a7d8ccec878138dc49a 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.H +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.H @@ -119,7 +119,7 @@ class OFstreamCollator }; - // Private data + // Private Data //- Total amount of storage to use for object stack below const off_t maxBufferSize_; diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C index 267a350eb8f815e05557d3a3c7dd98b77855a18f..977b75c85789f9728281fcd7cc0140398f77f8c2 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C @@ -74,23 +74,6 @@ namespace fileOperations } -// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // - -Foam::labelList Foam::fileOperations::collatedFileOperation::ioRanks() -{ - labelList ioRanks; - - string ioRanksString(Foam::getEnv("FOAM_IORANKS")); - if (!ioRanksString.empty()) - { - IStringStream is(ioRanksString); - is >> ioRanks; - } - - return ioRanks; -} - - // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // void Foam::fileOperations::collatedFileOperation::printBanner @@ -125,20 +108,20 @@ void Foam::fileOperations::collatedFileOperation::printBanner if (printRanks) { // Information about the ranks - stringList ioRanks(Pstream::nProcs()); + stringList hosts(Pstream::nProcs()); if (Pstream::master(comm_)) { // Don't usually need the pid - // ioRanks[Pstream::myProcNo()] = hostName()+"."+name(pid()); - ioRanks[Pstream::myProcNo()] = hostName(); + // hosts[Pstream::myProcNo()] = hostName()+"."+name(pid()); + hosts[Pstream::myProcNo()] = hostName(); } - Pstream::gatherList(ioRanks); + Pstream::gatherList(hosts); DynamicList<label> offsetMaster(Pstream::nProcs()); - forAll(ioRanks, ranki) + forAll(hosts, ranki) { - if (!ioRanks[ranki].empty()) + if (!hosts[ranki].empty()) { offsetMaster.append(ranki); } @@ -157,7 +140,7 @@ void Foam::fileOperations::collatedFileOperation::printBanner const label end = offsetMaster[group]; DetailInfo - << " (" << ioRanks[beg].c_str() << ' ' + << " (" << hosts[beg].c_str() << ' ' << (end-beg) << ')' << nl; } DetailInfo @@ -500,9 +483,6 @@ bool Foam::fileOperations::collatedFileOperation::writeObject useThread ); - // If any of these fail, return - // (leave error handling to Ostream class) - bool ok = os.good(); if (Pstream::master(comm_)) diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H index 85099e541351dc2414a3db520da8cfcf927895dc..6d635ccb1809f699cd7db470a8c16d59c6a208b6 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H @@ -46,7 +46,6 @@ SourceFiles #include "masterUncollatedFileOperation.H" #include "OFstreamCollator.H" -#include "fileOperationInitialise.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -84,9 +83,6 @@ protected: // Protected Member Functions - //- Retrieve list of IO ranks from FOAM_IORANKS env variable - static labelList ioRanks(); - //- Print banner information, optionally with io ranks void printBanner(const bool printRanks = false) const; @@ -198,7 +194,7 @@ public: // Member Functions - //- Needs threading + //- Requires threading for non-zero maxThreadFileBufferSize virtual bool needsThreading() const { return (collatedFileOperation::maxThreadFileBufferSize > 0); diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.C index 57f36a50cfa74f4e411fafff33b7d8dfb1c8c022..55a02996dc575f2896973e96bc7e7f2347cc50a9 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.C @@ -66,21 +66,19 @@ Foam::labelList Foam::fileOperations::hostCollatedFileOperation::subRanks { DynamicList<label> subRanks(64); - string ioRanksString(getEnv("FOAM_IORANKS")); - if (!ioRanksString.empty()) + labelList mainRanks(fileOperation::ioRanks()); + if (!mainRanks.empty()) { - IStringStream is(ioRanksString); - labelList ioRanks(is); - - if (!ioRanks.found(0)) + if (!mainRanks.found(0)) { FatalErrorInFunction << "Rank 0 (master) should be in the IO ranks. Currently " - << ioRanks << exit(FatalError); + << mainRanks << nl + << exit(FatalError); } // The lowest numbered rank is the IO rank - const bitSet isIOrank(n, ioRanks); + const bitSet isIOrank(n, mainRanks); for (label proci = Pstream::myProcNo(); proci >= 0; --proci) { diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C index 700f1e4b897bddb508ed3d713e2ebbcf8e5d18a7..eaac9a90ff238112d6af697f217c2c9add6b0c22 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C @@ -36,6 +36,7 @@ License #include "polyMesh.H" #include "registerSwitch.H" #include "Time.H" +#include "ITstream.H" #include <cerrno> #include <cinttypes> @@ -181,6 +182,20 @@ static bool parseProcsNumRange // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // +Foam::labelList Foam::fileOperation::ioRanks() +{ + labelList ranks; + + ITstream is("ioranks", Foam::getEnv("FOAM_IORANKS")); + if (!is.empty()) + { + is >> ranks; + } + + return ranks; +} + + Foam::instantList Foam::fileOperation::sortTimes ( @@ -241,7 +256,7 @@ Foam::fileOperation::sortTimes } -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // Foam::fileMonitor& Foam::fileOperation::monitor() const { diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H index ac3ce897a75ea3f406134ea77bad7e56d37c150a..0b659cdc71b24cb2bd721386505c09908f344746 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H @@ -47,8 +47,6 @@ Description #include "fileNameList.H" #include "instantList.H" #include "fileMonitor.H" -#include "labelList.H" -#include "Switch.H" #include "refPtr.H" #include "Enum.H" #include "Tuple2.H" @@ -64,13 +62,6 @@ class regIOobject; class objectRegistry; class Time; -// Description of processor directory naming: -// - processor directory naming -// - whether directory contains a range (so differs on different processors) -// - index in range -//typedef Tuple2<fileName, Tuple2<bool, label>> dirIndex; -//typedef List<dirIndex> dirIndexList; - /*---------------------------------------------------------------------------*\ Class fileOperation Declaration \*---------------------------------------------------------------------------*/ @@ -80,28 +71,32 @@ class fileOperation public: //- Enumeration for the location of an IOobject - enum pathType + enum pathType : int { - NOTFOUND, // not found - ABSOLUTE, // instance is absolute directory - OBJECT, // io.objectPath() exists - WRITEOBJECT, // write path exists - PROCUNCOLLATED, // objectPath exists in processor0 - PROCBASEOBJECT, // objectPath exists in specified, constant - // processorsDir (usually 'processorsDDD') - PROCOBJECT, // objectPath exists in locally differing - // processorsDir (e.g. 'processorsDDD_0-1') - PARENTOBJECT, // parent of object path - FINDINSTANCE, // file found in time directory - PROCUNCOLLATEDINSTANCE, // as PROCUNCOLLATED but with instance - PROCBASEINSTANCE, // as PROCBASEOBJECT but with instance - PROCINSTANCE // as PROCOBJECT but with instance + NOTFOUND = 0, //!< Not found + ABSOLUTE, //!< instance is absolute directory + OBJECT, //!< io.objectPath() exists + WRITEOBJECT, //!< write path exists + + // NOTE: increasing precedence (uncollated, collated, rank-collated) + + PROCUNCOLLATED, + //!< objectPath exists in 'processorN' + PROCBASEOBJECT = PROCUNCOLLATED + 1, + //!< objectPath exists in 'processorsNN' + PROCOBJECT = PROCBASEOBJECT + 1, + //!< objectPath exists in 'processorsNN_first-last' + + PARENTOBJECT, //!< parent of object path + FINDINSTANCE, //!< file found in time directory + PROCUNCOLLATEDINSTANCE, //!< as PROCUNCOLLATED but with instance + PROCBASEINSTANCE, //!< as PROCBASEOBJECT but with instance + PROCINSTANCE //!< as PROCOBJECT but with instance }; static const Enum<pathType> pathTypeNames_; - - //- A dirIndex adds the path type and local offset to a fileName - typedef Tuple2<fileName, Tuple2<pathType, label>> dirIndex; + //- Augment fileName with pathType and local offset + typedef Tuple2<fileName, Tuple2<pathType, int>> dirIndex; typedef List<dirIndex> dirIndexList; //- For addressing a range of processors, @@ -131,6 +126,9 @@ protected: //- Get or create fileMonitor singleton fileMonitor& monitor() const; + //- Retrieve list of IO ranks from FOAM_IORANKS env variable + static labelList ioRanks(); + //- Merge two times static void mergeTimes ( @@ -146,7 +144,7 @@ protected: // \return empty fileName if not found. refPtr<dirIndexList> lookupAndCacheProcessorsPath ( - const fileName&, + const fileName& objectPath, const bool syncPar ) const; @@ -158,8 +156,8 @@ protected: const fileName& objectPath ) const; - //- Does ioobject exist. Is either a directory (empty name()) or - // a file + //- Does IOObject exist. + //- Is either a directory (empty name()) or a file bool exists(IOobject& io) const; diff --git a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.C b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.C index cc91eb3b9e24ef4fc817ec3ac00e276ff8631d59..ff83c578452fc443f7fc4a9255f04a365a325ee6 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.C +++ b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017-2018 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "fileOperationInitialise.H" +#include "OSspecific.H" #include "addToRunTimeSelectionTable.H" /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */ @@ -48,7 +49,30 @@ Foam::fileOperations::fileOperationInitialise::fileOperationInitialise int& argc, char**& argv ) -{} +{ + // Filter out commonly known arguments + const string s("-ioRanks"); + + int index = -1; + for (int i=1; i<argc-1; i++) + { + if (argv[i] == s) + { + index = i; + Foam::setEnv("FOAM_IORANKS", argv[i+1], true); + break; + } + } + + if (index > 0) + { + for (int i=index+2; i<argc; i++) + { + argv[i-2] = argv[i]; + } + argc -= 2; + } +} Foam::autoPtr<Foam::fileOperations::fileOperationInitialise> diff --git a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.H b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.H index b07fbb26671a3210734d1f8523283e2b9060c9c7..a5f6d91fe6e723f003a1c080f442abf5377ce7ee 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.H +++ b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.H @@ -26,6 +26,11 @@ License Class Foam::fileOperationInitialise +Description + General fileOperation initialiser. + Handles \c -ioRanks option, using it to set the FOAM_IORANKS environment + variable. + \*---------------------------------------------------------------------------*/ #ifndef fileOperationInitialise_H @@ -54,7 +59,7 @@ public: // Constructors - //- Construct components + //- Construct from components fileOperationInitialise(int& argc, char**& argv); @@ -87,7 +92,7 @@ public: // Member Functions - //- Needs threading + //- Threading required? virtual bool needsThreading() const = 0; }; diff --git a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/unthreadedInitialise.H b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/unthreadedInitialise.H index 0974d818f63b147ce23b5bb4f0c445f074d3a1f5..36baf2b8cf11a0b22479dc61d80c0afe092a7989 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperationInitialise/unthreadedInitialise.H +++ b/src/OpenFOAM/global/fileOperations/fileOperationInitialise/unthreadedInitialise.H @@ -26,6 +26,9 @@ License Class Foam::unthreadedInitialise +Description + A fileOperation initialiser for unthreaded file handlers + \*---------------------------------------------------------------------------*/ #ifndef unthreadedInitialise_H @@ -65,7 +68,7 @@ public: // Member Functions - //- Needs threading + //- No threading required virtual bool needsThreading() const { return false; diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C index 269a43c6f6472e7c8c6f6ca615c5b0c28554ba7d..29d72055a8ea62e771350f05a1d3e9dd05a7a737 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C @@ -32,6 +32,7 @@ License #include "Time.H" #include "instant.H" #include "IFstream.H" +#include "IListStream.H" #include "masterOFstream.H" #include "decomposedBlockData.H" #include "registerSwitch.H" @@ -39,7 +40,6 @@ License #include "SubList.H" #include "unthreadedInitialise.H" #include "bitSet.H" -#include "IListStream.H" /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */ @@ -85,8 +85,9 @@ Foam::labelList Foam::fileOperations::masterUncollatedFileOperation::subRanks const label n ) { - string ioRanksString(getEnv("FOAM_IORANKS")); - if (ioRanksString.empty()) + labelList mainRanks(fileOperation::ioRanks()); + + if (mainRanks.empty()) { return identity(n); } @@ -94,18 +95,16 @@ Foam::labelList Foam::fileOperations::masterUncollatedFileOperation::subRanks { DynamicList<label> subRanks(n); - IStringStream is(ioRanksString); - labelList ioRanks(is); - - if (!ioRanks.found(0)) + if (!mainRanks.found(0)) { FatalErrorInFunction << "Rank 0 (master) should be in the IO ranks. Currently " - << ioRanks << exit(FatalError); + << mainRanks << nl + << exit(FatalError); } // The lowest numbered rank is the IO rank - const bitSet isIOrank(n, ioRanks); + const bitSet isIOrank(n, mainRanks); for (label proci = Pstream::myProcNo(); proci >= 0; --proci) { @@ -810,36 +809,6 @@ masterUncollatedFileOperation } -Foam::fileOperations::masterUncollatedFileOperationInitialise:: -masterUncollatedFileOperationInitialise(int& argc, char**& argv) -: - unthreadedInitialise(argc, argv) -{ - // Filter out any of my arguments - const string s("-ioRanks"); - - int index = -1; - for (int i=1; i<argc-1; i++) - { - if (argv[i] == s) - { - index = i; - Foam::setEnv("FOAM_IORANKS", argv[i+1], true); - break; - } - } - - if (index != -1) - { - for (int i=index+2; i<argc; i++) - { - argv[i-2] = argv[i]; - } - argc -= 2; - } -} - - // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::fileOperations::masterUncollatedFileOperation:: @@ -1754,7 +1723,7 @@ bool Foam::fileOperations::masterUncollatedFileOperation::readHeader { Pout<< "masterUncollatedFileOperation::readHeader :" << endl << " objectPath:" << io.objectPath() << endl - << " fName :" << fName << endl; + << " filePath :" << fName << endl; } // Get filePaths on world master diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H index 661f07759c2ab273cad3d042b84b922487f79dc3..f2b5b3df58bcd52cf3b65531e9aaec775900e16a 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H @@ -65,9 +65,8 @@ Description #include "fileOperation.H" #include "OSspecific.H" #include "HashPtrTable.H" -#include "Switch.H" +#include "List.H" #include "unthreadedInitialise.H" -#include "boolList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -784,7 +783,10 @@ public: // Constructors //- Construct from components - masterUncollatedFileOperationInitialise(int& argc, char**& argv); + masterUncollatedFileOperationInitialise(int& argc, char**& argv) + : + unthreadedInitialise(argc, argv) + {} //- Destructor