/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017-2018 OpenFOAM Foundation Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "decomposedBlockData.H" #include "OPstream.H" #include "IPstream.H" #include "PstreamBuffers.H" #include "Fstream.H" #include "dictionary.H" #include "objectRegistry.H" #include "SubList.H" #include "labelPair.H" #include "masterUncollatedFileOperation.H" #include "IListStream.H" #include "foamVersion.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(decomposedBlockData, 0); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::decomposedBlockData::decomposedBlockData ( const label comm, const IOobject& io, const UPstream::commsTypes commsType ) : regIOobject(io), commsType_(commsType), comm_(comm) { // Temporary warning if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED) { WarningInFunction << "decomposedBlockData " << name() << " constructed with IOobject::MUST_READ_IF_MODIFIED" " but decomposedBlockData does not support automatic rereading." << endl; } if ( ( io.readOpt() == IOobject::MUST_READ || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED ) || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { read(); } } Foam::decomposedBlockData::decomposedBlockData ( const label comm, const IOobject& io, const UList& list, const UPstream::commsTypes commsType ) : regIOobject(io), commsType_(commsType), comm_(comm) { // Temporary warning if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED) { WarningInFunction << "decomposedBlockData " << name() << " constructed with IOobject::MUST_READ_IF_MODIFIED" " but decomposedBlockData does not support automatic rereading." << endl; } if ( ( io.readOpt() == IOobject::MUST_READ || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED ) || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { read(); } else { List::operator=(list); } } Foam::decomposedBlockData::decomposedBlockData ( const label comm, const IOobject& io, List&& list, const UPstream::commsTypes commsType ) : regIOobject(io), commsType_(commsType), comm_(comm) { // Temporary warning if (io.readOpt() == IOobject::MUST_READ_IF_MODIFIED) { WarningInFunction << "decomposedBlockData " << name() << " constructed with IOobject::MUST_READ_IF_MODIFIED" " but decomposedBlockData does not support automatic rereading." << endl; } List::transfer(list); if ( ( io.readOpt() == IOobject::MUST_READ || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED ) || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) ) { read(); } } // * * * * * * * * * * * * * * * Members Functions * * * * * * * * * * * * * // bool Foam::decomposedBlockData::readMasterHeader(IOobject& io, Istream& is) { if (debug) { Pout<< "decomposedBlockData::readMasterHeader:" << " stream:" << is.name() << endl; } // Master-only reading of header is.fatalCheck("read(Istream&)"); List data(is); is.fatalCheck("read(Istream&) : reading entry"); UIListStream headerStream(data); headerStream.name() = is.name(); return io.readHeader(headerStream); } void Foam::decomposedBlockData::writeHeader ( Ostream& os, const IOstream::versionNumber version, const IOstream::streamFormat format, const word& type, const string& note, const fileName& location, const word& name ) { IOobject::writeBanner(os) << "FoamFile\n{\n" << " version " << version << ";\n" << " format " << format << ";\n" << " class " << type << ";\n"; // This may be useful to have as well if (os.format() == IOstream::BINARY) { os << " arch " << foamVersion::buildArch << ";\n"; } if (Pstream::parRun()) { os << " blocks " << Pstream::nProcs() << ";\n"; } if (note.size()) { os << " note " << note << ";\n"; } if (location.size()) { os << " location " << location << ";\n"; } os << " object " << name << ";\n" << "}" << nl; IOobject::writeDivider(os) << nl; } Foam::autoPtr Foam::decomposedBlockData::readBlock ( const label blocki, Istream& is, IOobject& headerIO ) { if (debug) { Pout<< "decomposedBlockData::readBlock:" << " stream:" << is.name() << " attempt to read block " << blocki << endl; } is.fatalCheck("read(Istream&)"); autoPtr realIsPtr; if (blocki == 0) { List data(is); is.fatalCheck("read(Istream&) : reading entry"); realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = is.name(); // Read header if (!headerIO.readHeader(*realIsPtr)) { FatalIOErrorInFunction(*realIsPtr) << "problem while reading header for object " << is.name() << exit(FatalIOError); } } else { // Read master for header List data(is); is.fatalCheck("read(Istream&) : reading entry"); IOstream::versionNumber ver(IOstream::currentVersion); IOstream::streamFormat fmt; unsigned labelByteSize; unsigned scalarByteSize; { UIListStream headerStream(data); // Read header if (!headerIO.readHeader(headerStream)) { FatalIOErrorInFunction(headerStream) << "problem while reading header for object " << is.name() << exit(FatalIOError); } ver = headerStream.version(); fmt = headerStream.format(); labelByteSize = headerStream.labelByteSize(); scalarByteSize = headerStream.scalarByteSize(); } for (label i = 1; i < blocki+1; i++) { // Read and discard data, only retain the last one is >> data; is.fatalCheck("read(Istream&) : reading entry"); } realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = is.name(); // Apply master stream settings to realIsPtr realIsPtr().format(fmt); realIsPtr().version(ver); realIsPtr().setLabelByteSize(labelByteSize); realIsPtr().setScalarByteSize(scalarByteSize); } return realIsPtr; } bool Foam::decomposedBlockData::readBlocks ( const label comm, autoPtr& isPtr, List& data, const UPstream::commsTypes commsType ) { if (debug) { Pout<< "decomposedBlockData::readBlocks:" << " stream:" << (isPtr ? isPtr->name() : "invalid") << " commsType:" << Pstream::commsTypeNames[commsType] << " comm:" << comm << endl; } bool ok = false; if (commsType == UPstream::commsTypes::scheduled) { if (UPstream::master(comm)) { Istream& is = *isPtr; is.fatalCheck("read(Istream&)"); // Read master data { is >> data; is.fatalCheck("read(Istream&) : reading entry"); } // Read slave data for ( label proci = 1; proci < UPstream::nProcs(comm); ++proci ) { List elems(is); is.fatalCheck("read(Istream&) : reading entry"); OPstream os ( UPstream::commsTypes::scheduled, proci, 0, UPstream::msgType(), comm ); os << elems; } ok = is.good(); } else { IPstream is ( UPstream::commsTypes::scheduled, UPstream::masterNo(), 0, UPstream::msgType(), comm ); is >> data; } } else { PstreamBuffers pBufs ( UPstream::commsTypes::nonBlocking, UPstream::msgType(), comm ); if (UPstream::master(comm)) { Istream& is = *isPtr; is.fatalCheck("read(Istream&)"); // Read master data { is >> data; is.fatalCheck("read(Istream&) : reading entry"); } // Read slave data for ( label proci = 1; proci < UPstream::nProcs(comm); ++proci ) { List elems(is); is.fatalCheck("read(Istream&) : reading entry"); UOPstream os(proci, pBufs); os << elems; } } labelList recvSizes; pBufs.finishedSends(recvSizes); if (!UPstream::master(comm)) { UIPstream is(UPstream::masterNo(), pBufs); is >> data; } } Pstream::scatter(ok, Pstream::msgType(), comm); return ok; } Foam::autoPtr Foam::decomposedBlockData::readBlocks ( const label comm, const fileName& fName, autoPtr& isPtr, IOobject& headerIO, const UPstream::commsTypes commsType ) { if (debug) { Pout<< "decomposedBlockData::readBlocks:" << " stream:" << (isPtr ? isPtr->name() : "invalid") << " commsType:" << Pstream::commsTypeNames[commsType] << endl; } bool ok = false; List data; autoPtr realIsPtr; if (commsType == UPstream::commsTypes::scheduled) { if (UPstream::master(comm)) { Istream& is = *isPtr; is.fatalCheck("read(Istream&)"); // Read master data { is >> data; is.fatalCheck("read(Istream&) : reading entry"); realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = fName; // Read header if (!headerIO.readHeader(*realIsPtr)) { FatalIOErrorInFunction(*realIsPtr) << "problem while reading header for object " << is.name() << exit(FatalIOError); } } // Read slave data for ( label proci = 1; proci < UPstream::nProcs(comm); ++proci ) { is >> data; is.fatalCheck("read(Istream&) : reading entry"); OPstream os ( UPstream::commsTypes::scheduled, proci, 0, UPstream::msgType(), comm ); os << data; } ok = is.good(); } else { IPstream is ( UPstream::commsTypes::scheduled, UPstream::masterNo(), 0, UPstream::msgType(), comm ); is >> data; realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = fName; } } else { PstreamBuffers pBufs ( UPstream::commsTypes::nonBlocking, UPstream::msgType(), comm ); if (UPstream::master(comm)) { Istream& is = *isPtr; is.fatalCheck("read(Istream&)"); // Read master data { is >> data; is.fatalCheck("read(Istream&) : reading entry"); realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = fName; // Read header if (!headerIO.readHeader(*realIsPtr)) { FatalIOErrorInFunction(*realIsPtr) << "problem while reading header for object " << is.name() << exit(FatalIOError); } } // Read slave data for ( label proci = 1; proci < UPstream::nProcs(comm); ++proci ) { List elems(is); is.fatalCheck("read(Istream&) : reading entry"); UOPstream os(proci, pBufs); os << elems; } ok = is.good(); } labelList recvSizes; pBufs.finishedSends(recvSizes); if (!UPstream::master(comm)) { UIPstream is(UPstream::masterNo(), pBufs); is >> data; realIsPtr.reset(new IListStream(std::move(data))); realIsPtr->name() = fName; } } Pstream::scatter(ok, Pstream::msgType(), comm); //- Set stream properties from realIsPtr on master // Scatter master header info string versionString; label formatValue; unsigned labelByteSize; unsigned scalarByteSize; if (UPstream::master(comm)) { versionString = realIsPtr().version().str(); formatValue = static_cast