diff --git a/src/finiteVolume/fields/surfaceFields/surfaceFieldsI.H b/src/finiteVolume/fields/surfaceFields/surfaceFieldsI.H
new file mode 100644
index 000000000..4731c5e91
--- /dev/null
+++ b/src/finiteVolume/fields/surfaceFields/surfaceFieldsI.H
@@ -0,0 +1,426 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+template
+void Foam::IFCstream::reader::read
+(
+ IFCstream& ifs
+)
+{
+ ifs.readNonProcessorBoundaryFields();
+
+ // Take care internal and processor fields. Internal surface field in
+ // coherent format includes processor boundaries. If it is uniform, the
+ // processor patches need to be created with the same uniform entry.
+ // Otherwise, the coherent internal field needs to be mapped to FOAM's
+ // internal and processor fields.
+
+ typedef typename pTraits::cmptType cmptType;
+ const polyMesh& mesh = ifs.coherentMesh_.mesh();
+ const polyBoundaryMesh& bm = mesh.boundaryMesh();
+
+ // Internal field data
+ UList internalData;
+
+ // Field data in the coherent format holding internal and processor patch
+ // fields
+ List coherentData;
+
+ ITstream& its = ifs.dict_.lookup("internalField");
+ dictionary& bfDict = ifs.dict_.subDict("boundaryField");
+
+ // Traverse the tokens of the internal field entry
+ while (true)
+ {
+ if (its.eof())
+ {
+ FatalErrorInFunction
+ << "Expected 'uniform' or compoundToken in " << its
+ << nl << " in file " << ifs.pathname_
+ << abort(FatalError);
+ }
+
+ token currToken(its);
+
+ if (currToken.isCompound()) // non-uniform
+ {
+ // Resize the compoundToken according to the mesh of the proc
+ token::compound& compToken = currToken.compoundToken();
+ compToken.resize(mesh.nInternalFaces());
+
+ // Store the data pointer in a UList for convenience
+ internalData = UList
+ (
+ reinterpret_cast(compToken.data()),
+ mesh.nInternalFaces()
+ );
+
+ // Current token index points to the token after the compound
+ // ToDoIO Get rid of globalSize?
+ const label globalSize = its[its.tokenIndex()++].labelToken();
+ const string id = its[its.tokenIndex()++].stringToken();
+ if (false)
+ {
+ Info<< globalSize;
+ } // Silence compiler warning
+
+ // Internal surface field in coherent format includes processor
+ // boundaries. Thus, find out the corresponding size.
+ const label localSize =
+ ifs.coherentFieldSize();
+ const globalIndex gi(localSize);
+ const label elemOffset = gi.offset(Pstream::myProcNo());
+ const label nElems = gi.localSize();
+ const label nCmpts = compToken.nComponents();
+
+ coherentData.resize(localSize);
+
+ ifs.sliceStreamPtr_->access("fields", ifs.pathname_.path());
+ ifs.sliceStreamPtr_->get
+ (
+ id,
+ reinterpret_cast(coherentData.data()),
+ List({nCmpts*elemOffset}),
+ List({nCmpts*nElems})
+ );
+
+ // Syncronizing IO engine ensures that the data is read from storage
+ ifs.sliceStreamPtr_->bufferSync();
+
+ break;
+ }
+ else if (currToken.isWord() && currToken.wordToken() == "uniform")
+ {
+ // Create processor patch fields with the same uniform entry as the
+ // internal field.
+
+ forAll(bm, i)
+ {
+ const polyPatch& patch = bm[i];
+ const word& patchName = patch.name();
+
+ // ToDoIO Make all the if(ppPatch) conditions consistent
+ if (patch.type() == processorPolyPatch::typeName)
+ {
+ dictionary dict;
+ dict.add("type", "processor");
+ dict.add("value", its);
+ bfDict.add(patchName, dict);
+ }
+ }
+
+ // Closing the IO engine ensures that the data is read from storage
+ ifs.sliceStreamPtr_->bufferSync();
+
+ return;
+ }
+ }
+
+
+ // The internal coherent field is non-uniform.
+
+ // Create dictionary entries for the processor patch fields with the
+ // correctly sized compound tokens.
+
+ const label nAllPatches = bm.size();
+ // ToDoIO Make it work with any type
+ List > procPatchData(nAllPatches);
+ label nProcPatches = 0;
+
+ forAll(bm, patchI)
+ {
+ const polyPatch& patch = bm[patchI];
+
+ if (isA(patch))
+ {
+ const label patchSize = patch.size();
+
+ tokenList entryTokens(2);
+ entryTokens[0] = word("nonuniform");
+
+ // Create a compound token for the patch, resize and store in a list
+ autoPtr ctPtr =
+ token::compound::New
+ (
+ "List<" + word(pTraits::typeName) + '>',
+ patchSize
+ );
+
+ // Store the data pointer for the later mapping
+ procPatchData[nProcPatches++] =
+ UList
+ (
+ reinterpret_cast(ctPtr().data()),
+ patchSize
+ );
+
+ // autoPtr is invalid after calling ptr()
+ entryTokens[1] = ctPtr.ptr();
+ dictionary dict;
+ dict.add("type", "processor");
+ // Xfer needed here, calls the corresponding primitiveEntry
+ // constructor
+ dict.add("value", entryTokens.xfer());
+ // No Xfer implemented for adding dictionary but copying is
+ // accomplished by cloning the pointers of the hash table and
+ // IDLList
+ bfDict.add(patch.name(), dict);
+ }
+ }
+
+
+ // Map from the coherent format to the internal and processor patch fields
+
+ procPatchData.resize(nProcPatches);
+ const label nNonProcPatches = nAllPatches - nProcPatches;
+
+ // processorFaces
+ const labelList& pf = ifs.coherentMesh_.internalFaceIDsFromBoundaries();
+
+ // processorFacesPatchIds
+ const labelList& pfpi = ifs.coherentMesh_.boundryIDsFromInternalFaces();
+
+ labelList patchFaceI(nProcPatches, 0);
+ label internalFaceI = 0;
+ label pfI = 0;
+
+ // Closing the IO engine ensures that the data is read from disk
+ ifs.sliceStreamPtr_->bufferSync();
+
+ if (pf.empty())
+ {
+ // Use explicit assign(). An assignment operator would trigger a
+ // shallow copy by setting internalData data pointer to that of
+ // coherentData. But the latter is destroyed after returning and the
+ // data pointer would not be valid anymore.
+ internalData.assign(coherentData);
+ }
+ else
+ {
+ forAll(coherentData, i)
+ {
+ if (pfI < pf.size() && i == pf[pfI]) // Processor field
+ {
+ const label patchI = pfpi[pfI++] - nNonProcPatches;
+ procPatchData[patchI][patchFaceI[patchI]++] = coherentData[i];
+ }
+ else // Internal field
+ {
+ internalData[internalFaceI++] = coherentData[i];
+ }
+ }
+ }
+
+ // In coherent format only the lower neighbour procs have the processor
+ // faces and the corresponding fields. Get their values to the procs
+ // above.
+
+ // Send
+ forAll(bm, patchI)
+ {
+ const polyPatch& patch = bm[patchI];
+
+ if (isA(patch))
+ {
+ const processorPolyPatch& procPp =
+ refCast(patch);
+
+ if (procPp.neighbProcNo() > procPp.myProcNo())
+ {
+ OPstream toProcNbr(Pstream::blocking, procPp.neighbProcNo());
+ toProcNbr << procPatchData[patchI - nNonProcPatches];
+ }
+ }
+ }
+
+ // Receive
+ forAll(bm, patchI)
+ {
+ const polyPatch& patch = bm[patchI];
+
+ if (isA(patch))
+ {
+ const processorPolyPatch& procPp =
+ refCast(patch);
+
+ if (procPp.neighbProcNo() < procPp.myProcNo())
+ {
+ const label patchDataI = patchI - nNonProcPatches;
+ IPstream fromProcNbr(Pstream::blocking, procPp.neighbProcNo());
+ fromProcNbr >> procPatchData[patchDataI];
+
+ // Flip the sign since the faces are oriented in the opposite
+ // direction
+ forAll(procPatchData[patchDataI], faceI)
+ {
+ procPatchData[patchDataI][faceI] *= -1;
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+
+template
+void Foam::OFCstream::
+combineCoherentInternal()
+{
+
+ const Offsets& iso = this->coherentMesh_.internalSurfaceFieldOffsets();
+ const label localCombinedSize = iso.count(Pstream::myProcNo());
+
+ this->consolidatedData_.resize(localCombinedSize);
+
+ // Internal
+ const fieldDataEntry* internalFieldDataEntryPtr =
+ dynamic_cast
+ (
+ this->dict_.lookupEntryPtr("internalField", false, false)
+ );
+
+ if (!internalFieldDataEntryPtr)
+ {
+ FatalErrorInFunction
+ << "Entry 'internalField' not found in dictionary "
+ << dict_.name()
+ << abort(FatalError);
+ }
+
+ const UList& internalData =
+ dynamic_cast&>(internalFieldDataEntryPtr->uList());
+
+
+ // Processor patches
+ const polyBoundaryMesh& bm = coherentMesh_.mesh().boundaryMesh();
+ const label nPatches = bm.size();
+ dictionary& bfDict = dict_.subDict("boundaryField");
+ List > patchData(nPatches);
+ List procPatchFDEPtrs(nPatches);
+
+ label ppI = 0;
+ forAll(bm, i)
+ {
+ const polyPatch& patch = bm[i];
+ const word& patchName = patch.name();
+
+ if (patch.type() == processorPolyPatch::typeName)
+ {
+ const dictionary& ppDict = bfDict.subDict(patchName);
+ procPatchFDEPtrs[ppI] =
+ dynamic_cast
+ (
+ ppDict.lookupEntryPtr("value", false, false)
+ );
+ patchData[ppI] =
+ dynamic_cast&>
+ (
+ procPatchFDEPtrs[ppI]->uList()
+ );
+ ppI++;
+ }
+ }
+
+ const label nProcPatches = ppI;
+ patchData.resize(nProcPatches);
+ procPatchFDEPtrs.resize(nProcPatches);
+ const label nNonProcPatches = nPatches - nProcPatches;
+
+ // processorFaces
+ const labelList& pf = this->coherentMesh_.internalFaceIDsFromBoundaries();
+ const label nProcFaces = pf.size();
+
+ // processorFacesPatchIds
+ const labelList& pfpi = this->coherentMesh_.boundryIDsFromInternalFaces();
+
+ label internalFaceI = 0;
+ label pfI = 0;
+ labelList patchFaceI(nProcPatches, 0);
+ if (pf.empty())
+ {
+ this->consolidatedData_ = internalData;
+ }
+ else
+ {
+ for (label i = 0; i < this->consolidatedData_.size(); i++)
+ {
+ if (pfI < nProcFaces && i == pf[pfI]) // Processor field
+ {
+ const label patchI = pfpi[pfI++] - nNonProcPatches;
+ this->consolidatedData_[i] =
+ patchData[patchI][patchFaceI[patchI]++];
+ }
+ else // Internal field
+ {
+ this->consolidatedData_[i] = internalData[internalFaceI++];
+ }
+ }
+ }
+
+ // Create new entry for the consolidated internalField
+ fieldDataEntry* coherentInternal =
+ new fieldDataEntry
+ (
+ "internalField",
+ internalFieldDataEntryPtr->compoundTokenName(),
+ new UListProxy(consolidatedData_)
+ );
+
+ // Set the new internalField in the dictionary replacing the old one
+ this->dict_.set(coherentInternal);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::OFCstream::OFCstream
+(
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode,
+ IOstreamOption streamOpt
+)
+:
+ OFCstreamBase(pathname, registry, mode, streamOpt)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
+
+template
+Foam::OFCstream::~OFCstream()
+{
+ combineCoherentInternal();
+ this->removeProcPatchesFromDict();
+ this->writeGlobalGeometricField();
+}
+
+
+// ************************************************************************* //
diff --git a/src/foam/Make/files b/src/foam/Make/files
index c982c574d..f16b7e312 100644
--- a/src/foam/Make/files
+++ b/src/foam/Make/files
@@ -159,6 +159,26 @@ $(Pstreams)/OPstream.C
$(Pstreams)/IPread.C
$(Pstreams)/OPwrite.C
+SliceStreams = $(Streams)/SliceStreams
+$(SliceStreams)/sliceWritePrimitives.C
+$(SliceStreams)/sliceReadPrimitives.C
+
+$(SliceStreams)/SliceStreamPaths.C
+$(SliceStreams)/SliceStreamRepo.C
+$(SliceStreams)/SliceStream.C
+$(SliceStreams)/FileSliceStream.C
+$(SliceStreams)/create/OutputFeatures.C
+$(SliceStreams)/create/InputFeatures.C
+$(SliceStreams)/create/SliceWriting.C
+$(SliceStreams)/create/SliceReading.C
+$(SliceStreams)/buffer/SliceBuffer.C
+$(SliceStreams)/fieldDataEntry.C
+$(SliceStreams)/formattingEntry.C
+$(SliceStreams)/fieldTag.C
+$(SliceStreams)/IFCstream.C
+$(SliceStreams)/OFCstream.C
+
+
dictionary = db/dictionary
$(dictionary)/dictionary.C
$(dictionary)/dictionaryIO.C
@@ -465,6 +485,29 @@ pointZone = $(polyMesh)/zones/pointZone
$(pointZone)/pointZone.C
$(pointZone)/newPointZone.C
+CoherentMesh = $(polyMesh)/CoherentMesh
+$(CoherentMesh)/Offsets.C
+$(CoherentMesh)/sliceMap.C
+$(CoherentMesh)/Slice.C
+$(CoherentMesh)/CoherentMesh.C
+$(CoherentMesh)/SlicePermutation.C
+$(CoherentMesh)/FragmentPermutation.C
+$(CoherentMesh)/sliceMeshHelper.C
+$(CoherentMesh)/ProcessorPatch.C
+$(CoherentMesh)/nonblockConsensus.C
+
+CoherenceComposite = $(CoherentMesh)/CoherenceComposite
+$(CoherenceComposite)/DataComponent.C
+$(CoherenceComposite)/IndexComponent.C
+$(CoherenceComposite)/DataComponentFree.C
+
+CoherenceStrategies = $(CoherenceComposite)/strategies
+$(CoherenceStrategies)/InitStrategies.C
+$(CoherenceStrategies)/OffsetStrategies.C
+
+CoherenceDecorators = $(CoherenceComposite)/decorators
+$(CoherenceDecorators)/SliceDecorator.C
+
$(polyMesh)/polyMesh.C
$(polyMesh)/polyMeshFromShapeMesh.C
$(polyMesh)/polyMeshIO.C
diff --git a/src/foam/Make/options b/src/foam/Make/options
index cfdd1d8ea..2be86f4aa 100644
--- a/src/foam/Make/options
+++ b/src/foam/Make/options
@@ -1,7 +1,11 @@
include $(RULES)/mplib$(WM_MPLIB)
EXE_INC = $(PFLAGS) $(PINC) \
- -I$(WM_THIRD_PARTY_DIR)/zlib-1.2.3
+ -I$(WM_THIRD_PARTY_DIR)/zlib-1.2.3 \
+ $(ADIOS2_FLAGS) \
+ -I$(ADIOS2_INCLUDE_DIR) \
+ -I$(ADIOS2_INCLUDE_CXX11_DIR) \
+ -I$(ADIOS2_INCLUDE_COMMON_DIR)
#if defined(mingw)
@@ -12,13 +16,17 @@ LIB_LIBS = $(PLIBS)\
-ldl \
-lpsapi \
-lpthread \
- -lws2_32
+ -lws2_32 \
+ $(ADIOS2_LIBS) \
+ -L$(ADIOS2_LIB_DIR)
#else
LIB_LIBS = $(PLIBS)\
$(FOAM_LIBBIN)/libOSspecific.o \
- -lz
+ -lz \
+ $(ADIOS2_LIBS) \
+ -L$(ADIOS2_LIB_DIR)
#endif
diff --git a/src/foam/containers/Lists/List/DebugIOList.C b/src/foam/containers/Lists/List/DebugIOList.C
new file mode 100644
index 000000000..a6f4e15cf
--- /dev/null
+++ b/src/foam/containers/Lists/List/DebugIOList.C
@@ -0,0 +1,3 @@
+#include "List.H"
+
+defineTypeNameAndDebug(Foam::DebugIOListName, 0);
\ No newline at end of file
diff --git a/src/foam/containers/Lists/UList/DebugIOUList.C b/src/foam/containers/Lists/UList/DebugIOUList.C
new file mode 100644
index 000000000..5b76f6bd4
--- /dev/null
+++ b/src/foam/containers/Lists/UList/DebugIOUList.C
@@ -0,0 +1,3 @@
+#include "UList.H"
+
+defineTypeNameAndDebug(Foam::DebugIOUListName, 0);
\ No newline at end of file
diff --git a/src/foam/db/IOstreams/IOstreams/IOstreamOption.C b/src/foam/db/IOstreams/IOstreams/IOstreamOption.C
new file mode 100644
index 000000000..d4dd23b0a
--- /dev/null
+++ b/src/foam/db/IOstreams/IOstreams/IOstreamOption.C
@@ -0,0 +1,168 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "IOstreamOption.H"
+#include "messageStream.H"
+#include "Switch.H"
+
+// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
+
+Foam::IOstreamOption::streamFormat
+Foam::IOstreamOption::formatEnum(const word& format)
+{
+ if (format == "ascii")
+ {
+ return IOstreamOption::ASCII;
+ }
+ else if (format == "binary")
+ {
+ return IOstreamOption::BINARY;
+ }
+ else if (format == "coherent")
+ {
+ return IOstreamOption::COHERENT;
+ }
+ else
+ {
+ WarningIn("IOstreamOption::formatEnum(const word&)")
+ << "bad format specifier '" << format << "', using 'ascii'"
+ << endl;
+
+ return IOstreamOption::ASCII;
+ }
+}
+
+
+Foam::IOstreamOption::compressionType
+Foam::IOstreamOption::compressionEnum(const word& compression)
+{
+ // get Switch (bool) value, but allow it to fail
+ Switch sw(compression, true);
+
+ if (sw.valid())
+ {
+ return sw ? IOstreamOption::COMPRESSED : IOstreamOption::UNCOMPRESSED;
+ }
+ else if (compression == "uncompressed")
+ {
+ return IOstreamOption::UNCOMPRESSED;
+ }
+ else if (compression == "compressed")
+ {
+ return IOstreamOption::COMPRESSED;
+ }
+ else
+ {
+ WarningIn("IOstreamOption::compressionEnum(const word&)")
+ << "bad compression specifier '" << compression
+ << "', using 'uncompressed'"
+ << endl;
+
+ return IOstreamOption::UNCOMPRESSED;
+ }
+}
+
+
+Foam::IOstreamOption::streamMode
+Foam::IOstreamOption::modeEnum(const word& mode)
+{
+ if (mode == "sync")
+ {
+ return IOstreamOption::SYNC;
+ }
+ else if (mode == "deferred")
+ {
+ return IOstreamOption::DEFERRED;
+ }
+ else
+ {
+ WarningInFunction
+ << "bad mode specifier '" << mode << "', using 'sync'"
+ << endl;
+
+ return IOstreamOption::SYNC;
+ }
+}
+
+
+Foam::IOstreamOption::dataDestination
+Foam::IOstreamOption::destinationEnum(const word& destination)
+{
+ if (destination == "time")
+ {
+ return IOstreamOption::TIME;
+ }
+ else if (destination == "case")
+ {
+ return IOstreamOption::CASE;
+ }
+ else
+ {
+ WarningInFunction
+ << "bad data specifier '" << destination << "', using 'sync'"
+ << endl;
+
+ return IOstreamOption::TIME;
+ }
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<
+(
+ Ostream& os,
+ const IOstreamOption::streamFormat& sf
+)
+{
+ if (sf == IOstreamOption::ASCII)
+ {
+ os << "ascii";
+ }
+ else if (sf == IOstreamOption::BINARY)
+ {
+ os << "binary";
+ }
+ else if (sf == IOstreamOption::COHERENT)
+ {
+ os << "coherent";
+ }
+
+ return os;
+}
+
+
+Foam::Ostream& Foam::operator<<
+(
+ Ostream& os,
+ const IOstreamOption::versionNumber& vn
+)
+{
+ os << vn.str().c_str();
+ return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/IOstreams/IOstreamOption.H b/src/foam/db/IOstreams/IOstreams/IOstreamOption.H
new file mode 100644
index 000000000..d875d92d7
--- /dev/null
+++ b/src/foam/db/IOstreams/IOstreams/IOstreamOption.H
@@ -0,0 +1,375 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::IOstreamOption
+
+Description
+ A simple container for options IOstream can normally have.
+
+SourceFiles
+ IOstreamOption.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IOstreamOption_H
+#define IOstreamOption_H
+
+#include "char.H"
+#include "bool.H"
+#include "label.H"
+#include "uLabel.H"
+#include "scalar.H"
+#include "word.H"
+#include "infoSwitch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class IOstreamOption Declaration
+\*---------------------------------------------------------------------------*/
+
+class IOstreamOption
+{
+
+public:
+
+ // Public data types
+
+ //- Enumeration for the format of data in the stream
+ enum streamFormat : char
+ {
+ ASCII,
+ BINARY,
+ COHERENT
+ };
+
+ //- Enumeration for the format of data in the stream
+ enum compressionType : char
+ {
+ UNCOMPRESSED,
+ COMPRESSED
+ };
+
+ //- Enumeration for the I/O mode of the stream
+ enum streamMode : char
+ {
+ SYNC,
+ DEFERRED
+ };
+
+ //- Enumeration for the destination of heavy data files (data.bp)
+ enum dataDestination : char
+ {
+ TIME,
+ CASE
+ };
+
+ //- Ostream operator
+ friend Ostream& operator<<(Ostream& os, const streamFormat& sf);
+
+ //- Version number type
+ class versionNumber
+ {
+ //- The version number
+ scalar versionNumber_;
+
+ //- The version number as an integer
+ int index_;
+
+
+ public:
+
+ // Constructors
+
+ //- Construct from number
+ versionNumber(const scalar num)
+ :
+ versionNumber_(num),
+ index_(numberToIndex(num))
+ {}
+
+ //- Construct from Istream
+ versionNumber(Istream& is)
+ :
+ versionNumber_(readScalar(is)),
+ index_(numberToIndex(versionNumber_))
+ {}
+
+
+ // Member functions
+
+ //- Convert a version number into an index
+ int numberToIndex(const scalar num) const
+ {
+ return int(10*num + SMALL);
+ }
+
+ //- Return major version
+ int majorVersion() const
+ {
+ return int(versionNumber_);
+ }
+
+ //- Return minor version
+ int minorVersion() const
+ {
+ return int(10.0*(versionNumber_ - majorVersion()));
+ }
+
+ //- Return the versionNumber as a character string
+ string str() const;
+
+
+ // Member operators
+
+ //- Are these versionNumbers the same?
+ bool operator==(const versionNumber& vn)
+ {
+ return index_ == vn.index_;
+ }
+
+ //- Are these versionNumbers different?
+ bool operator!=(const versionNumber& vn)
+ {
+ return index_ != vn.index_;
+ }
+
+ //- Is this version older than the one given
+ bool operator<(const versionNumber& vn)
+ {
+ return index_ < vn.index_;
+ }
+
+ //- Is this version the same as or older than the one given
+ bool operator<=(const versionNumber& vn)
+ {
+ return index_ <= vn.index_;
+ }
+
+ //- Is this version newer than the one given
+ bool operator>(const versionNumber& vn)
+ {
+ return index_ > vn.index_;
+ }
+
+ //- this version the same as or newer than the one given
+ bool operator>=(const versionNumber& vn)
+ {
+ return index_ >= vn.index_;
+ }
+
+
+ //- Ostream operator
+ friend Ostream& operator<<(Ostream& os, const versionNumber& vn);
+ };
+
+
+ // Public static data
+
+ //- Original version number
+ static const versionNumber originalVersion;
+
+ //- Current version number
+ static const versionNumber currentVersion;
+
+
+private:
+
+ // Private data
+
+ //- Format: (ascii | binary)
+ streamFormat format_;
+
+ //- Stream version number (e.g., 2.0)
+ versionNumber version_;
+
+ //- Compression: (uncompressed | compressed)
+ compressionType compression_;
+
+ //- I/O stream mode (sync | deferred)
+ streamMode mode_;
+
+ //- Heavy data file (data.bp) destination (time | case)
+ dataDestination destination_;
+
+public:
+
+ // Constructors
+
+ //- Default construct
+ IOstreamOption
+ (
+ streamFormat format = streamFormat::ASCII,
+ versionNumber version = versionNumber(2.0),
+ compressionType compression = compressionType::UNCOMPRESSED,
+ streamMode mode = streamMode::SYNC,
+ dataDestination destination = dataDestination::TIME
+ )
+ :
+ format_(format),
+ version_(version),
+ compression_(compression),
+ mode_(mode),
+ destination_(destination)
+ {}
+
+
+ // Static Member Functions
+
+ //- Return stream mode of given mode name
+ static streamMode modeEnum(const word&);
+
+ static dataDestination destinationEnum(const word&);
+
+
+ // Member Functions
+
+ //- Return stream format of given format name
+ static streamFormat formatEnum(const word&);
+
+ //- Return current stream format
+ streamFormat format() const
+ {
+ return format_;
+ }
+
+ //- Set the stream format
+ streamFormat format(const streamFormat fmt)
+ {
+ streamFormat fmt0 = format_;
+ format_ = fmt;
+ return fmt0;
+ }
+
+ //- Set the stream format from word
+ streamFormat format(const word& fmt)
+ {
+ streamFormat fmt0 = format_;
+ format_ = formatEnum(fmt);
+ return fmt0;
+ }
+
+ //- Return the stream version
+ versionNumber version() const
+ {
+ return version_;
+ }
+
+ //- Set the stream version
+ versionNumber version(const versionNumber ver)
+ {
+ versionNumber ver0 = version_;
+ version_ = ver;
+ return ver0;
+ }
+
+ //- Return compression of given compression name
+ static compressionType compressionEnum(const word&);
+
+ //- Return the stream compression
+ compressionType compression() const
+ {
+ return compression_;
+ }
+
+ //- Set the stream compression
+ compressionType compression(const compressionType cmp)
+ {
+ compressionType cmp0 = compression_;
+ compression_ = cmp;
+ return cmp0;
+ }
+
+ //- Set the stream compression from word
+ compressionType compression(const word& cmp)
+ {
+ compressionType cmp0 = compression_;
+ compression_ = compressionEnum(cmp);
+ return cmp0;
+ }
+
+ //- Return current stream mode
+ streamMode mode() const
+ {
+ return mode_;
+ }
+
+ //- Set the stream mode
+ streamMode mode(const streamMode md)
+ {
+ streamMode md0 = mode_;
+ mode_ = md;
+ return md0;
+ }
+
+ //- Set the stream mode from word
+ streamMode mode(const word& md)
+ {
+ streamMode md0 = mode_;
+ mode_ = modeEnum(md);
+ return md0;
+ }
+
+ //- Return current stream mode
+ dataDestination destination() const
+ {
+ return destination_;
+ }
+
+ //- Set the data destination
+ dataDestination destination(const dataDestination dest)
+ {
+ dataDestination dest0 = destination_;
+ destination_ = dest;
+ return dest0;
+ }
+
+ //- Set the data destination from word
+ dataDestination destination(const word& dest)
+ {
+ dataDestination dest0 = destination_;
+ destination_ = destinationEnum(dest);
+ return dest0;
+ }
+};
+
+
+// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
+
+Ostream& operator<<(Ostream& os, const IOstreamOption::streamFormat& sf);
+Ostream& operator<<(Ostream& os, const IOstreamOption::versionNumber& vn);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/FileSliceStream.C b/src/foam/db/IOstreams/SliceStreams/FileSliceStream.C
new file mode 100644
index 000000000..e5b5c82ac
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/FileSliceStream.C
@@ -0,0 +1,66 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::FileSliceStream
+
+Description
+ Child class from SliceStream implementing the parallel I/O streaming
+ into a file
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "FileSliceStream.H"
+#include "StreamFeatures.H"
+
+#include "SliceStreamImpl.H"
+
+#include "foamString.H"
+
+
+Foam::FileSliceStream::FileSliceStream
+(
+ std::unique_ptr& fileFeatures
+)
+:
+ sliceFile_{std::move(fileFeatures)}
+{}
+
+
+void Foam::FileSliceStream::v_access()
+{
+ Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ ioPtr_ = sliceFile_->createIO(repo->pullADIOS());
+ enginePtr_ = sliceFile_->createEngine(ioPtr_.get(), paths_.getPathName());
+}
+
+
+void Foam::FileSliceStream::v_flush()
+{
+ Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ repo->close();
+ v_access();
+}
diff --git a/src/foam/db/IOstreams/SliceStreams/FileSliceStream.H b/src/foam/db/IOstreams/SliceStreams/FileSliceStream.H
new file mode 100644
index 000000000..1eebbab81
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/FileSliceStream.H
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::FileSliceStream
+
+Description
+ Child class from SliceStream implementing the parallel I/O streaming
+ into a file
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ FileSliceStream.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef FileSliceStream_H
+#define FileSliceStream_H
+
+#include "SliceStream.H"
+
+namespace Foam
+{
+
+// Forward declarations
+class string;
+class StreamFeatures;
+
+class FileSliceStream
+:
+ public SliceStream
+{
+
+ std::unique_ptr sliceFile_;
+
+ virtual void v_access() final;
+
+ virtual void v_flush() final;
+
+public:
+
+ explicit FileSliceStream(std::unique_ptr&);
+
+};
+
+}
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/IFCstream.C b/src/foam/db/IOstreams/SliceStreams/IFCstream.C
new file mode 100644
index 000000000..47f702f9f
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/IFCstream.C
@@ -0,0 +1,316 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::IFCstream
+
+Description
+ Input from file stream and ADIOS for the coherent format. The stream builds
+ a dictionary and alters its entries afterwards, filling the compound tokens
+ (i.e. lists) and creating processorPatchFields since these are not present
+ in the coherent format. GeometricField constructor obtains the ready-to-use
+ dictionary.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+\*---------------------------------------------------------------------------*/
+
+#include "IFCstream.H"
+#include "IOstream.H"
+#include "OSspecific.H"
+#include "debug.H"
+#include "gzstream.h"
+#include "IStringStream.H"
+#include "fileName.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ defineTypeNameAndDebug(IFCstream, 0);
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// ToDoIO Remove the allocator. Since ifPtr_ is always std::istringstream all
+// the functionality may be moved to the IFCstream constructor
+Foam::IFCstreamAllocator::IFCstreamAllocator
+(
+ const fileName& pathname,
+ IOstream::streamFormat format
+)
+:
+ ifPtr_(nullptr),
+ bufStr_(),
+ compression_(IOstream::UNCOMPRESSED)
+{
+ if (pathname.empty())
+ {
+ if (IFCstream::debug)
+ {
+ InfoInFunction
+ << "cannot open null file " << endl;
+ }
+ }
+
+ if (format != IOstream::COHERENT)
+ {
+ FatalErrorInFunction
+ << "IO Format is not COHERENT"
+ << exit(FatalError);
+ }
+
+ ifPtr_ = new std::istringstream();
+
+ // The metadata is read only on master and then broadcasted to slaves.
+ if (Pstream::master())
+ {
+ if (IFCstream::debug)
+ {
+ InfoInFunction
+ << "Reading ASCII file " << pathname << endl;
+ }
+
+ std::istream* iPtr = new std::ifstream(pathname.c_str());
+
+ // If the file is compressed, decompress it before reading.
+ if (!iPtr->good() && isFile(pathname + ".gz", false))
+ {
+ delete iPtr;
+
+ iPtr = new igzstream((pathname + ".gz").c_str());
+
+ if (iPtr->good())
+ {
+ compression_ = IOstream::COMPRESSED;
+ }
+ }
+
+ // Read to buffer
+ if (iPtr->good())
+ {
+ iPtr->seekg(0, std::ios::end);
+ size_t size = iPtr->tellg();
+ bufStr_.resize(size);
+ iPtr->seekg(0);
+ iPtr->read(&bufStr_[0], size);
+ }
+
+ if (!iPtr->good())
+ {
+ // Invalidate stream if the variable is not found
+ ifPtr_->setstate(std::ios::failbit);
+ }
+ }
+
+ Pstream::scatter(bufStr_);
+
+ // Assign the buffer of string bufStr_ to the buffer of the stream
+ ifPtr_->rdbuf()->pubsetbuf(&bufStr_[0], bufStr_.size());
+}
+
+
+Foam::IFCstreamAllocator::~IFCstreamAllocator()
+{
+ delete ifPtr_;
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
+
+void Foam::IFCstream::readWordToken(token& t)
+{
+ word* wPtr = new word;
+
+ if (read(*wPtr).bad())
+ {
+ delete wPtr;
+ t.setBad();
+ }
+ else if (token::compound::isCompound(*wPtr))
+ {
+ if (debug)
+ {
+ Pout<< "Start constructing coherent compound token " << *wPtr
+ << endl;
+ }
+
+ t = token::compound::New(*wPtr, 0).ptr();
+
+ if (debug)
+ {
+ Pout<< "End constructing coherent compound token " << *wPtr << endl;
+ }
+
+ delete wPtr;
+ }
+ else
+ {
+ t = wPtr;
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::IFCstream::IFCstream
+(
+ const fileName& pathname,
+ const objectRegistry& registry,
+ streamFormat format,
+ versionNumber version
+)
+:
+ IFCstreamAllocator(pathname, format),
+ ISstream
+ (
+ *ifPtr_,
+ "IFCstream.sourceFile_",
+ format,
+ version,
+ IFCstreamAllocator::compression_
+ ),
+ pathname_(pathname),
+ coherentMesh_
+ (
+ const_cast
+ (
+ registry.lookupObject(CoherentMesh::typeName)
+ )
+ ),
+ tmpIssPtr_(nullptr),
+ sliceStreamPtr_(SliceReading{}.createStream())
+{
+ setClosed();
+
+ setState(ifPtr_->rdstate());
+
+ if (!good())
+ {
+ if (debug)
+ {
+ InfoInFunction
+ << "Could not open file for input"
+ << endl << info() << endl;
+ }
+
+ setBad();
+ }
+ else
+ {
+ setOpened();
+ }
+
+ lineNumber_ = 1;
+}
+
+
+// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
+
+Foam::IFCstream::~IFCstream()
+{
+ if (debug)
+ {
+ InfoInFunction
+ << "Destructing stream" << endl;
+ }
+
+ if (tmpIssPtr_)
+ {
+ delete tmpIssPtr_;
+ }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+std::istream& Foam::IFCstream::stdStream()
+{
+ if (!ifPtr_)
+ {
+ FatalErrorIn("IFCstream::stdStream()")
+ << "No stream allocated" << abort(FatalError);
+ }
+ return *ifPtr_;
+}
+
+
+const std::istream& Foam::IFCstream::stdStream() const
+{
+ if (!ifPtr_)
+ {
+ FatalErrorIn("IFCstream::stdStream() const")
+ << "No stream allocated" << abort(FatalError);
+ }
+ return *ifPtr_;
+}
+
+
+void Foam::IFCstream::print(Ostream& os) const
+{
+ // Print File data
+ os << "IFCstream: ";
+ ISstream::print(os);
+}
+
+
+Foam::Istream& Foam::IFCstream::readToStringStream(string& id)
+{
+ if (tmpIssPtr_)
+ {
+
+ }
+ tmpIssPtr_ = new IStringStream(tmpIssBuf_);
+ return *tmpIssPtr_;
+}
+
+
+// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
+
+Foam::IFCstream&
+Foam::IFCstream::operator()() const
+{
+ if (!good())
+ {
+ // also checks .gz file
+ if (isFile(pathname_, true))
+ {
+ check("IFCstream::operator()");
+ FatalIOError.exit();
+ }
+ else
+ {
+ FatalIOErrorIn("IFCstream::operator()", *this)
+ << "file " << pathname_ << " does not exist"
+ << exit(FatalIOError);
+ }
+ }
+
+ return const_cast(*this);
+}
+
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/IFCstream.H b/src/foam/db/IOstreams/SliceStreams/IFCstream.H
new file mode 100644
index 000000000..29d5b02af
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/IFCstream.H
@@ -0,0 +1,278 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::IFCstream
+
+Description
+ Input from file stream and ADIOS for the coherent format. The stream builds
+ a dictionary and alters its entries afterwards, filling the compound tokens
+ (i.e. lists) and creating processorPatchFields since these are not present
+ in the coherent format. GeometricField constructor obtains the ready-to-use
+ dictionary.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+SourceFiles
+ IFCstream.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IFCstream_H
+#define IFCstream_H
+
+#include "ISstream.H"
+#include "fileName.H"
+#include "className.H"
+#include "gzstream.h"
+#include "SliceStream.H"
+#include "CoherentMesh.H"
+#include "processorPolyPatch.H"
+
+#include
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class IFCstreamAllocator Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A std::istream with ability to handle compressed files
+class IFCstreamAllocator
+{
+ friend class IFCstream;
+
+ // Private data
+
+ istream* ifPtr_;
+
+ //- String serves as buffer for file contents which are read only on
+ // master
+ string bufStr_;
+
+ //- Compression, e.g. ".gz"
+ IOstream::compressionType compression_;
+
+
+ // Constructors
+
+ //- Construct from pathname
+ IFCstreamAllocator
+ (
+ const fileName& pathname,
+ const IOstream::streamFormat format
+ );
+
+
+ //- Destructor
+ ~IFCstreamAllocator();
+
+ // Member functions
+
+ //- Allocate ADIOS object if not already present
+ void allocateAdios();
+};
+
+
+/*---------------------------------------------------------------------------*\
+ Class IFCstream Declaration
+\*---------------------------------------------------------------------------*/
+
+class IFCstream
+:
+ public IFCstreamAllocator,
+ public ISstream
+{
+ // Private classes
+
+ //- Helper to enable partial template specialization for reading on
+ // specialized geometric field and mesh but templated Type of the
+ // geometric field.
+ template class PatchField, class GeoMesh>
+ class reader
+ {
+
+ public:
+
+ static void read(IFCstream&);
+ };
+
+
+ // Private data
+
+ fileName pathname_;
+ CoherentMesh& coherentMesh_;
+ Istream* tmpIssPtr_;
+ string tmpIssBuf_;
+
+ //- Field dictionary populated by stream
+ dictionary dict_;
+
+ //- Pointer to the IO engine
+ std::unique_ptr sliceStreamPtr_;
+
+
+ // Private Member Functions
+
+ //- Add field of type processorPolyPatch to dictionary. To be
+ // specialized by PatchField and GeoMesh types
+ template class PatchField, class GeoMesh>
+ void addProcessorPatchField
+ (
+ dictionary& bfDict,
+ const word& patchName,
+ const word& fieldTypeName
+ );
+
+ //- Get the field size from the corresponding mesh entity. To be
+ // specialized by PatchField and GeoMesh types
+ template class PatchField, class GeoMesh>
+ label coherentFieldSize();
+
+ // Read
+
+ //- Find (recursively) all compound tokens in dictionary and
+ // populate them with data
+ template
+ void readCompoundTokenData(dictionary& dict, const label size);
+
+ //- Find all compound tokens in ITstream and populate them with
+ // data
+ template
+ void readCompoundTokenData(ITstream& is, const label localSize);
+
+ //- Read field data of all boundary patches that are not of
+ // processor type
+ template
+ void readNonProcessorBoundaryFields();
+
+
+protected:
+
+ // Protected Member Functions
+
+ //- Read a word token, identify and handle compound tokens if
+ // discovered
+ virtual void readWordToken(token&);
+
+
+public:
+
+ // Static data members
+
+ //- Runtime type information
+ TypeName("IFCstream");
+
+
+ // Constructors
+
+ //- Construct from pathname and registry
+ IFCstream
+ (
+ const fileName& pathname,
+ const objectRegistry& registry,
+ streamFormat format = COHERENT,
+ versionNumber version = currentVersion
+ );
+
+
+ //- Destructor
+ ~IFCstream();
+
+
+ // Public Member Functions
+
+ // Access
+
+ //- Return the name of the stream
+ const fileName& name() const
+ {
+ return pathname_;
+ }
+
+ //- Return non-const access to the name of the stream
+ fileName& name()
+ {
+ return pathname_;
+ }
+
+
+ // Read functions
+
+ //- Read to dictionary and add the missing subFields (e.g.
+ // processor patch fields).
+ // template class PatchField, class GeoMesh>
+ template
+ <
+ class Type,
+ template class PatchField,
+ class GeoMesh
+ >
+ dictionary& readToDict();
+
+
+ // STL stream
+
+ //- Access to underlying std::istream
+ virtual istream& stdStream();
+
+ //- Const access to underlying std::istream
+ virtual const istream& stdStream() const;
+
+
+ // Print
+
+ //- Print description of IOstream to Ostream
+ virtual void print(Ostream&) const;
+
+ // ToDoIO Function used for reading of non-contiguous lists.
+ // As is, it works only in serial. Reconsider.
+ virtual Istream& readToStringStream(string&);
+
+
+ // Member operators
+
+ //- Return a non-const reference to const IFCstream
+ // Needed for read-constructors where the stream argument is temporary:
+ // e.g. thing thisThing(IFCstream("thingFileName")());
+ IFCstream& operator()() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "IFCstreamI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/IFCstreamI.H b/src/foam/db/IOstreams/SliceStreams/IFCstreamI.H
new file mode 100644
index 000000000..c44c1c8b1
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/IFCstreamI.H
@@ -0,0 +1,248 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::IFCstream
+
+Description
+ Input from file stream and ADIOS for the coherent format. The stream builds
+ a dictionary and alters its entries afterwards, filling the compound tokens
+ (i.e. lists) and creating processorPatchFields since these are not present
+ in the coherent format. GeometricField constructor obtains the ready-to-use
+ dictionary.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+template class PatchField, class GeoMesh>
+void Foam::IFCstream::addProcessorPatchField
+(
+ dictionary& bfDict,
+ const word& patchName,
+ const word& fieldTypeName
+)
+{
+ NotImplemented;
+}
+
+
+template class PatchField, class GeoMesh>
+Foam::label Foam::IFCstream::coherentFieldSize()
+{
+ NotImplemented;
+
+ return 0;
+}
+
+
+template
+void Foam::IFCstream::readCompoundTokenData(dictionary& dict, const label size)
+{
+ forAllIter(IDLList, dict, pIter)
+ {
+ entry& pEntry = pIter();
+
+ if (pEntry.isDict())
+ {
+ readCompoundTokenData(pEntry.dict(), size);
+ }
+
+ if (debug)
+ {
+ Pout<< "Reading primitive entry " << nl << tab << pEntry << endl;
+ }
+
+ ITstream& is = pEntry.stream();
+ readCompoundTokenData(is, size);
+ }
+}
+
+
+template
+void Foam::IFCstream::readCompoundTokenData
+(
+ ITstream& is,
+ const label localSize
+)
+{
+ typedef typename pTraits::cmptType cmptType;
+
+ // Traverse the tokens. If the current token is a compound token, resize
+ // the compound token with the correct size. The id is stored in the next
+ // token.
+ while (!is.eof())
+ {
+ token currToken(is);
+
+ // Resize the compoundTokens according to mesh of the proc and read the
+ // corresponding slice of the data.
+ if (currToken.isCompound())
+ {
+ token::compound& compToken = currToken.compoundToken();
+
+ // Current token index points to the token after the compound
+ // ToDoIO Get rid of globalSize?
+ const label coherentStartI = is.tokenIndex();
+ const label globalSize = is[coherentStartI].labelToken();
+ const string id = is[coherentStartI + 1].stringToken();
+
+ // Delete the coherent format tokens by resizing the tokenList
+ is.resize(coherentStartI);
+
+ // ToDoIO Get proper offsets directly from coherentMesh_
+ // elemOffset has to be int64
+ //
+ // By now:
+ // // Internal field
+ // const label elemOffset = coherentMesh_.cellOffsets().front();
+ // const label nElems = coherentMesh_.cellOffsets().size();
+ // const label nCmpts = compToken.nComponents();
+ //
+ // // Patches - doesn't work (set doReduce flag?)
+ // Offsets patchOffsets(patch.size());
+ // const label elemOffset = patchOffsets.front();
+ // const label nElems = patchOffsets.size();
+
+ const globalIndex gi(localSize);
+ const label elemOffset = gi.offset(Pstream::myProcNo());
+ const label nElems = gi.localSize();
+ const label nCmpts = compToken.nComponents();
+
+ compToken.resize(nElems);
+
+ if (debug)
+ {
+ Pout
+ << "void Foam::IFCstream::readCompoundTokenData" << nl
+ << "(" << nl
+ << " ITstream& is," << nl
+ << " const label localSize" << nl
+ << ")" << nl
+ << "Reading compoundToken" << nl
+ << " ITstream name = " << is.name() << nl
+ << " ITstream globalSize = " << globalSize << nl
+ << " ITstream id = " << id << nl
+ << " elemOffset = " << elemOffset << nl
+ << " nElems = " << nElems << nl
+ << " compoundToken nComponents = " << nCmpts << nl
+ << " ITstream tokens info:"
+ << endl;
+
+ forAll(is, i)
+ {
+ Pout<< tab << tab << is[i].info() << endl;
+ }
+ }
+
+ // ToDoIO Provide a better interface from SliceStream for reading
+ // of fields.
+ sliceStreamPtr_->access("fields", pathname_.path());
+ sliceStreamPtr_->get
+ (
+ id,
+ reinterpret_cast(compToken.data()),
+ List({nCmpts*elemOffset}),
+ List({nCmpts*nElems})
+ );
+ }
+ }
+}
+
+
+template
+void Foam::IFCstream::readNonProcessorBoundaryFields()
+{
+ const polyMesh& mesh = coherentMesh_.mesh();
+ const polyBoundaryMesh& bm = mesh.boundaryMesh();
+ dictionary& bfDict = dict_.subDict("boundaryField");
+
+ forAll(bm, i)
+ {
+ const polyPatch& patch = bm[i];
+ if (patch.type() != processorPolyPatch::typeName)
+ {
+ dictionary& patchDict = bfDict.subDict(patch.name());
+ readCompoundTokenData(patchDict, patch.size());
+ }
+ }
+}
+
+
+template class PatchField, class GeoMesh>
+void Foam::IFCstream::reader::read
+(
+ IFCstream& ifs
+)
+{
+ Info<< "Non-special" << endl;
+ ITstream& its = ifs.dict_.lookup("internalField");
+ ifs.readCompoundTokenData
+ (
+ its,
+ ifs.coherentFieldSize()
+ );
+
+ ifs.readNonProcessorBoundaryFields();
+
+ dictionary& bfDict = ifs.dict_.subDict("boundaryField");
+
+ forAll(ifs.coherentMesh_.mesh().boundaryMesh(), i)
+ {
+ const polyPatch& patch = ifs.coherentMesh_.mesh().boundaryMesh()[i];
+ const word& patchName = patch.name();
+
+ if (patch.type() == processorPolyPatch::typeName)
+ {
+ ifs.addProcessorPatchField
+ (
+ bfDict, patchName, pTraits::typeName
+ );
+ }
+ }
+
+ // Ensure that the data is read from storage
+ ifs.sliceStreamPtr_->bufferSync();
+
+ return;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template class PatchField, class GeoMesh>
+Foam::dictionary& Foam::IFCstream::readToDict()
+{
+ // Fill the dictionary with the stream
+ dict_.read(*this);
+
+ reader::read(*this);
+
+ return dict_;
+}
+
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/OFCstream.C b/src/foam/db/IOstreams/SliceStreams/OFCstream.C
new file mode 100644
index 000000000..5025e9c43
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/OFCstream.C
@@ -0,0 +1,402 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::OFCstream
+
+Description
+ Output to file stream for coherent mesh and fields.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+\*---------------------------------------------------------------------------*/
+
+#include "OFCstream.H"
+#include "dictionaryEntry.H"
+#include "formattingEntry.H"
+
+#include "SliceStream.H"
+#include "processorPolyPatch.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// defineTypeNameAndDebug(Foam::OFCstreamBase, 0);
+
+// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
+
+void Foam::OFCstreamBase::gatherFieldDataEntries
+(
+ dictionary& dict,
+ DynamicList& fieldDataEntries
+)
+{
+ forAllIter(IDLList, dict, iter)
+ {
+ entry& e = iter();
+
+ if (isA(e))
+ {
+ fieldDataEntry* fde = dynamic_cast(&e);
+ fieldDataEntries.append(fde);
+ }
+ else if (e.isDict())
+ {
+ string name = e.name();
+ gatherFieldDataEntries(e.dict(), fieldDataEntries);
+ }
+ }
+}
+
+
+void Foam::OFCstreamBase::removeProcPatchesFromDict()
+{
+ const polyBoundaryMesh& bm = coherentMesh_.mesh().boundaryMesh();
+ dictionary& bfDict = dict_.subDict("boundaryField");
+
+ forAll(bm, i)
+ {
+ const polyPatch& patch = bm[i];
+
+ if (patch.type() == processorPolyPatch::typeName)
+ {
+ bfDict.remove(patch.name());
+ }
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::OFCstreamBase::OFCstreamBase
+(
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode,
+ IOstreamOption streamOpt
+)
+:
+ OFstream(pathname, mode, streamOpt),
+ pathname_(pathname),
+ coherentMesh_
+ (
+ const_cast
+ (
+ registry.lookupObject(CoherentMesh::typeName)
+ )
+ ),
+ dict_(pathname.name()),
+ currentSubDictPtr_(&dict_),
+ currentKeyword_(),
+ currentEntryI_(0)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
+
+Foam::OFCstreamBase::~OFCstreamBase()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+Foam::string
+Foam::OFCstreamBase::getBlockId() const
+{
+ return getGlobalId();
+}
+
+
+Foam::string
+Foam::OFCstreamBase::getGlobalId() const
+{
+ const fileName id = OFstream::getBlockId();
+ const wordList cmpts = id.components();
+ fileName globalId;
+
+ forAll(cmpts, i)
+ {
+ if (cmpts[i].find("processor") == std::string::npos)
+ {
+ globalId = globalId/cmpts[i];
+ }
+ }
+
+ return globalId;
+}
+
+
+Foam::Ostream&
+Foam::OFCstreamBase::writeKeyword(const keyType& kw)
+{
+ currentKeyword_ = kw;
+ moveStreamBufferToDict();
+
+ return *this;
+}
+
+
+Foam::Ostream&
+Foam::OFCstreamBase::write(const token& t)
+{
+ if (t.isPunctuation())
+ {
+ if (t.pToken() == token::punctuationToken::END_STATEMENT)
+ {
+ ostream& buf = getStreamBuffer();
+ std::ostringstream& oss = dynamic_cast(buf);
+ const word str = oss.str();
+ currentSubDictPtr_->add(currentKeyword_, str);
+ oss.str(string());
+ }
+ }
+
+ return *this;
+}
+
+
+Foam::Ostream&
+Foam::OFCstreamBase::write(const word& str)
+{
+ if (token::compound::isCompound(str))
+ {
+ currentCompoundTokenName_ = str;
+
+ return *this;
+ }
+
+ return OSstream::write(str);
+}
+
+
+Foam::word Foam::OFCstreamBase::incrBlock(const word name)
+{
+ // Save the data written to stream before
+ moveStreamBufferToDict();
+
+ const dictionary subDict(name);
+ currentSubDictPtr_->add(name, subDict);
+ currentSubDictPtr_ =
+ const_cast(currentSubDictPtr_->subDictPtr(name));
+
+ return name;
+}
+
+
+void Foam::OFCstreamBase::decrBlock()
+{
+ // Save the data written to stream before
+ moveStreamBufferToDict();
+
+ currentSubDictPtr_ = &const_cast(currentSubDictPtr_->parent());
+}
+
+
+Foam::Ostream&
+Foam::OFCstreamBase::parwrite(std::unique_ptr uListProxyPtr)
+{
+ currentSubDictPtr_->add
+ (
+ new fieldDataEntry
+ (
+ currentKeyword_,
+ currentCompoundTokenName_,
+ uListProxyPtr.release()
+ )
+ );
+
+ return *this;
+}
+
+
+void Foam::OFCstreamBase::moveStreamBufferToDict()
+{
+ ostream& buf = getStreamBuffer();
+ std::ostringstream& oss = dynamic_cast(buf);
+ const string str = oss.str();
+ if (!str.empty())
+ {
+ token t = str;
+ t.type() = token::WORD;
+ const word cei = "ASCII_F" + std::to_string(currentEntryI_);
+ currentSubDictPtr_->add(new formattingEntry(cei, t));
+ currentEntryI_++;
+ oss.str(string());
+ }
+}
+
+
+void Foam::OFCstreamBase::writeDict
+(
+ Ostream& os,
+ const dictionary& dict,
+ bool subDict
+)
+const
+{
+ if (subDict)
+ {
+ os << nl;
+ os.indent();
+ os << token::BEGIN_BLOCK;
+ os.incrIndent();
+ os << nl;
+ }
+
+ forAllConstIter(IDLList, dict, iter)
+ {
+ const entry& e = *iter;
+
+ if (isA(e))
+ {
+ os.indent();
+ os.write(e.keyword());
+ writeDict(os, e.dict(), true);
+ }
+ else if (isA(e))
+ {
+ const keyType& key = e.keyword();
+
+ // ToDoIO Better identification of formatting entries?
+ if (regExp("ASCII_F.*").match(key))
+ {
+ os << e;
+ }
+ else
+ {
+ // Write without new lines which are handled by
+ // formattingEntries
+ const primitiveEntry& pe = dynamicCast(e);
+ os.writeKeyword(key);
+ pe.write(os, true);
+ // ToDoIO Let formattingEntry take care over semicolon?
+ // os << token::END_STATEMENT;
+ }
+ }
+ else // fieldDataEntry
+ {
+ os << e;
+ }
+
+ // Check stream before going to next entry.
+ if (!os.good())
+ {
+ WarningInFunction
+ << "Can't write entry " << iter().keyword()
+ << " for dictionary " << dict.name()
+ << nl;
+ }
+ }
+
+ if (subDict)
+ {
+ os.decrIndent();
+ os.indent();
+ os << token::END_BLOCK << nl;
+ }
+}
+
+
+void Foam::OFCstreamBase::writeGlobalGeometricField()
+{
+ DynamicList fieldDataEntries;
+ gatherFieldDataEntries(dict_, fieldDataEntries);
+
+ const label nFields = fieldDataEntries.size();
+ List globalUniformity(nFields);
+
+ // Prepare list with field tags for global reduce
+ forAll(fieldDataEntries, i)
+ {
+ globalUniformity[i] = fieldDataEntries[i]->tag();
+ }
+
+ globalUniformity =
+ returnReduce(globalUniformity, fieldTag::uniformityCompareOp);
+
+ auto sliceStreamPtr = Foam::SliceWriting{}.createStream();
+ fileName path = pathname_.path();
+ if (destination() == CASE)
+ {
+ path = path.path();
+ }
+ sliceStreamPtr->access("fields", path);
+
+ forAll(fieldDataEntries, i)
+ {
+ fieldDataEntry& fde = *(fieldDataEntries[i]);
+ fde.tag() = globalUniformity[i];
+
+ // ToDoIO Check whether the fde field size equals the size of the
+ // corresponding mesh entity on each rank. Allreduce this info using
+ // the uniformityCompareOp infrastructure because the field size may
+ // accidentally equal the size of the mesh entity. If it's not equal on
+ // all ranks, do not agglomerate and write to ADIOS with prefixed
+ // processorXX.
+ if (!fde.uniform())
+ {
+ const label nElems = fde.uList().size(); //nElems();
+ const label nCmpts = fde.uList().nComponents();
+
+ const globalIndex bgi(nElems);
+ const label nGlobalElems = bgi.size();
+ const label elemOffset = bgi.offset(Pstream::myProcNo());
+
+ // Write to engine
+ sliceStreamPtr->put
+ (
+ fde.id(),
+ {nCmpts*nGlobalElems},
+ {nCmpts*elemOffset},
+ {nCmpts*nElems},
+ reinterpret_cast(fde.uList().cdata())
+ );
+
+ fde.nGlobalElems() = nGlobalElems;
+ }
+ }
+ sliceStreamPtr->bufferSync();
+
+ if (mode() == SYNC)
+ {
+ sliceStreamPtr->flush();
+ }
+
+ if (Pstream::master())
+ {
+ OFstream of
+ (
+ name(),
+ ios_base::out|ios_base::trunc,
+ streamFormat::ASCII
+ );
+
+ moveStreamBufferToDict();
+
+ // ToDoIO keep formattingEntry?
+ // dict_.write(of, false);
+ writeDict(of, dict_, false);
+ }
+}
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/OFCstream.H b/src/foam/db/IOstreams/SliceStreams/OFCstream.H
new file mode 100644
index 000000000..4e9942ae5
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/OFCstream.H
@@ -0,0 +1,222 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::OFCstream
+
+Description
+ Output to file stream for coherent mesh and fields.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+SourceFiles
+ OFCstream.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef OFCstream_H
+#define OFCstream_H
+
+#include "OFstream.H"
+#include "CoherentMesh.H"
+#include "dictionary.H"
+#include "fieldDataEntry.H"
+#include "uListProxyBase.H"
+#include "IOstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class OFCstreamBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class OFCstreamBase
+:
+ public OFstream
+{
+
+protected:
+
+ // Protected data
+
+ fileName pathname_;
+ CoherentMesh& coherentMesh_;
+
+ //- Dictionary holding both entries for the ASCII file and pointer,
+ // size data for the BLOBs.
+ dictionary dict_;
+
+ //- Pointer to the (sub-)dictionary the ofstream currently writes to
+ dictionary* currentSubDictPtr_;
+
+ //- The last keyword seen on the stream
+ keyType currentKeyword_;
+
+ //- Entry counter used for the formatting entries
+ label currentEntryI_;
+
+ //- The last compound token seen on the stream
+ word currentCompoundTokenName_;
+
+
+ // Protected member functions
+
+ //- Gather all objects of type fieldDataEntry from a dictionary
+ virtual void gatherFieldDataEntries
+ (
+ dictionary&,
+ DynamicList&
+ );
+
+ //- Remove processor patches from the dictionary
+ virtual void removeProcPatchesFromDict();
+
+public:
+
+ // Declare name of the class and its debug switch
+ // TypeName("OFCstreamBase");
+
+
+ // Constructors
+
+ //- Default construct
+ OFCstreamBase
+ (
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode = ios_base::out|ios_base::trunc,
+ IOstreamOption streamOpt = IOstreamOption()
+ );
+
+ //- Construct from pathname
+ OFCstreamBase
+ (
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode,
+ streamFormat format = ASCII,
+ versionNumber version = currentVersion,
+ compressionType compression = UNCOMPRESSED
+ )
+ :
+ OFCstreamBase
+ (
+ pathname,
+ registry,
+ mode,
+ IOstreamOption(format, version, compression)
+ )
+ {}
+
+
+ //- Destructor
+ virtual ~OFCstreamBase();
+
+
+ // Member functions
+
+ //- Get variable id without "processor.*" if writing a global field
+ virtual string getBlockId() const;
+
+ //- Get variable id without "processor.*"
+ string getGlobalId() const;
+
+ virtual Ostream& writeKeyword(const keyType&);
+ virtual Ostream& write(const token&);
+ virtual Ostream& write(const word&);
+ virtual word incrBlock(const word);
+ virtual void decrBlock();
+ virtual Ostream& parwrite(std::unique_ptr);
+
+ //- Put current stream buffer to a dictionary as an entry
+ void moveStreamBufferToDict();
+
+ //- Write the dictionary with correct formatting
+ void writeDict(Ostream& os, const dictionary& dict, bool subDict) const;
+
+ //- Write data with the specified engine and dictionary by master
+ void writeGlobalGeometricField();
+};
+
+template class PatchField, class GeoMesh>
+class OFCstream
+:
+public OFCstreamBase
+{
+
+public:
+
+ // Constructors
+
+ //- Default construct
+ OFCstream
+ (
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode = ios_base::out|ios_base::trunc,
+ IOstreamOption streamOpt = IOstreamOption()
+ )
+ :
+ OFCstreamBase(pathname, registry, mode, streamOpt)
+ {}
+
+ //- Construct given path and registry
+ OFCstream
+ (
+ const fileName& pathname,
+ const objectRegistry& registry,
+ ios_base::openmode mode,
+ IOstream::streamFormat format = IOstream::ASCII,
+ IOstream::versionNumber version = IOstream::currentVersion,
+ IOstream::compressionType compression = IOstream::UNCOMPRESSED
+ )
+ :
+ OFCstream
+ (
+ pathname,
+ registry,
+ mode,
+ IOstreamOption(format, version, compression)
+ )
+ {}
+
+
+ //- Destructor
+ virtual ~OFCstream()
+ {
+ this->removeProcPatchesFromDict();
+ this->writeGlobalGeometricField();
+ }
+};
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStream.C b/src/foam/db/IOstreams/SliceStreams/SliceStream.C
new file mode 100644
index 000000000..a5006170b
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStream.C
@@ -0,0 +1,303 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStream
+
+Description
+ A parallel I/O streaming class for contiguous data access patterns
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "SliceStream.H"
+
+#include "SliceStreamImpl.H"
+
+// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * //
+
+Foam::SliceStream::SliceStream()
+:
+ pimpl_{new Impl()},
+ paths_{},
+ type_{},
+ ioPtr_{nullptr},
+ enginePtr_{nullptr}
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
+
+Foam::SliceStream::~SliceStream() = default;
+
+
+std::string Foam::SliceStreamType(const std::string& id)
+{
+ std::string type = "fields";
+ if (id.find("polyMesh") != std::string::npos
+ ||
+ id.find("region") != std::string::npos)
+ {
+ type = "mesh";
+ }
+ return type;
+}
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void
+Foam::SliceStream::setPath(const Foam::string& type, const Foam::string& path)
+{
+ if (type == "mesh")
+ {
+ paths_.setPathName(paths_.meshPathname(path));
+ }
+ else if (type == "fields")
+ {
+ paths_.setPathName(paths_.dataPathname(path));
+ }
+}
+
+// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+void Foam::SliceStream::access(const Foam::string& type, const Foam::string& path)
+{
+ type_ = type;
+ setPath(type, path);
+ v_access();
+}
+
+
+void Foam::SliceStream::bufferSync()
+{
+ if (enginePtr_)
+ {
+ if
+ (
+ enginePtr_->OpenMode() == adios2::Mode::Read
+ || enginePtr_->OpenMode() == adios2::Mode::ReadRandomAccess
+ )
+ {
+ enginePtr_->PerformGets();
+ }
+ else
+ {
+ enginePtr_->PerformPuts();
+ }
+ }
+}
+
+
+Foam::label Foam::SliceStream::getBufferSize
+(
+ const Foam::string& blockId,
+ const Foam::scalar* const data
+)
+{
+ return pimpl_->readingBuffer >
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId
+ );
+}
+
+
+Foam::label Foam::SliceStream::getBufferSize
+(
+ const Foam::string& blockId,
+ const Foam::label* const data
+)
+{
+ return pimpl_->readingBuffer >
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId
+ );
+}
+
+
+Foam::label Foam::SliceStream::getBufferSize
+(
+ const Foam::string& blockId,
+ const char* const data
+)
+{
+ return pimpl_->readingBuffer >
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId
+ );
+}
+
+
+// Reading
+void Foam::SliceStream::get
+(
+ const Foam::string& blockId,
+ scalar* data,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ pimpl_->get
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ data,
+ start,
+ count
+ );
+}
+
+
+void Foam::SliceStream::get
+(
+ const Foam::string& blockId,
+ label* data,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ pimpl_->get
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ data,
+ start,
+ count
+ );
+}
+
+
+void Foam::SliceStream::get
+(
+ const Foam::string& blockId,
+ char* data,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ pimpl_->get
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ data,
+ start,
+ count
+ );
+}
+
+
+// Writing
+void Foam::SliceStream::put
+(
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const scalar* data,
+ const Foam::labelList& mapping,
+ const bool masked
+)
+{
+ pimpl_->put
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ shape,
+ start,
+ count,
+ data,
+ mapping,
+ masked
+ );
+}
+
+
+void Foam::SliceStream::put
+(
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const label* data,
+ const Foam::labelList& mapping,
+ const bool masked
+)
+{
+ pimpl_->put
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ shape,
+ start,
+ count,
+ data,
+ mapping,
+ masked
+ );
+}
+
+
+void Foam::SliceStream::put
+(
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const char* data,
+ const Foam::labelList& mapping,
+ const bool masked
+)
+{
+ pimpl_->put
+ (
+ ioPtr_.get(),
+ enginePtr_.get(),
+ blockId,
+ shape,
+ start,
+ count,
+ data,
+ mapping,
+ masked
+ );
+}
+
+
+void Foam::SliceStream::flush()
+{
+ v_flush();
+}
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStream.H b/src/foam/db/IOstreams/SliceStreams/SliceStream.H
new file mode 100644
index 000000000..0d8de4538
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStream.H
@@ -0,0 +1,240 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStream
+
+Description
+ A parallel I/O streaming class for contiguous data access patterns
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ SliceStream.C
+ SliceStreamImpl.C (include in SliceStream.C)
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SliceStream_H
+#define SliceStream_H
+
+#include "labelList.H"
+
+#include "SliceStreamRepo.H"
+
+#include "SliceStreamPaths.H"
+
+#include "SliceWriting.H"
+#include "SliceReading.H"
+
+namespace Foam
+{
+
+// Determine whether mesh or field data I/O is triggered
+std::string SliceStreamType(const std::string& id);
+
+
+template
+void sliceReadToContainer
+(
+ const Foam::string& type,
+ const Foam::string& pathname,
+ const Foam::string& blockId,
+ Container& container,
+ const labelList& start = {},
+ const labelList& count = {}
+);
+
+
+class SliceStream
+{
+ virtual void v_access() = 0;
+
+ virtual void v_flush() = 0;
+
+protected:
+
+ // Forward declaration of bridge to implementation
+ class Impl;
+
+ // Bridge instance to implementation
+ std::unique_ptr pimpl_;
+
+ // Instance on file name manager
+ SliceStreamPaths paths_{};
+
+ // Type of I/O data; field or mesh
+ Foam::string type_{};
+
+ // Pointer to io instance
+ std::shared_ptr ioPtr_{nullptr};
+
+ // Pointer to engine instance
+ std::shared_ptr enginePtr_{nullptr};
+
+ // Setter for bp file name and path
+ void setPath(const Foam::string& type, const Foam::string& path = "");
+
+public:
+
+ // Default constructor
+ SliceStream();
+
+ // Destructor
+ virtual ~SliceStream();
+
+ // Open engine according to mesh or field data and path
+ void access(const Foam::string& type, const Foam::string& path = "");
+
+ // Reading local/global scalar array
+ void get
+ (
+ const string& blockId,
+ scalar* data,
+ const labelList& start = {},
+ const labelList& count = {}
+ );
+
+ // Reading local/global label array
+ void get
+ (
+ const string& blockId,
+ label* data,
+ const labelList& start = {},
+ const labelList& count = {}
+ );
+
+ // Reading local/global char array
+ void get
+ (
+ const string& blockId,
+ char* data,
+ const labelList& start = {},
+ const labelList& count = {}
+ );
+
+ // Reading local/global array
+ template
+ typename std::enable_if::value, void>::type
+ get
+ (
+ const string& blockId,
+ ContainerType& data,
+ const labelList& start = {},
+ const labelList& count = {}
+ );
+
+ label getBufferSize(const Foam::string& blockId, const scalar* const data);
+
+ label getBufferSize(const Foam::string& blockId, const label* const data);
+
+ label getBufferSize(const Foam::string& blockId, const char* const data);
+
+ // Writing local/global scalar array
+ void put
+ (
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const scalar* buf,
+ const labelList& mapping = {},
+ const bool masked = false
+ );
+
+ // Writing local/global label array
+ void put
+ (
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const label* buf,
+ const labelList& mapping = {},
+ const bool masked = false
+ );
+
+ void put
+ (
+ const Foam::string& blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count,
+ const char* buf,
+ const labelList& mapping = {},
+ const bool masked = false
+ );
+
+ void bufferSync();
+
+ void flush();
+
+};
+
+}
+
+
+// Reading local/global array
+template
+typename std::enable_if::value, void>::type
+Foam::SliceStream::get
+(
+ const Foam::string& blockId,
+ ContainerType& container,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ if (start.empty() && count.empty())
+ {
+ auto size = getBufferSize(blockId, container.data());
+ container.resize(size);
+ }
+ else
+ {
+ container.resize(count[0]);
+ }
+ get(blockId, container.data(), start, count);
+}
+
+
+template
+void Foam::sliceReadToContainer
+(
+ const Foam::string& type,
+ const Foam::string& pathname,
+ const Foam::string& blockId,
+ Container& container,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ auto SliceStreamPtr = SliceReading{}.createStream();
+ SliceStreamPtr->access(type, pathname);
+ SliceStreamPtr->get(blockId, container, start, count);
+ SliceStreamPtr->bufferSync();
+}
+
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamImpl.H b/src/foam/db/IOstreams/SliceStreams/SliceStreamImpl.H
new file mode 100644
index 000000000..c998f307b
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamImpl.H
@@ -0,0 +1,207 @@
+
+#include "adios2.h"
+
+#include "SliceStream.H"
+
+#include "variableBuffer.H"
+#include "spanBuffer.H"
+
+
+template
+std::shared_ptr
+createInputBuffer
+(
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+{
+ if (!start.empty() && !count.empty())
+ {
+ return std::make_shared
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ start,
+ count
+ );
+ }
+ else
+ {
+ return std::make_shared
+ (
+ ioPtr,
+ enginePtr,
+ blockId
+ );
+ }
+}
+
+
+struct Foam::SliceStream::Impl
+{
+
+ Impl() = default;
+
+ std::shared_ptr bufferPtr_{nullptr};
+
+ template
+ label readingBuffer
+ (
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ const labelList& start = {},
+ const labelList& count = {}
+ )
+ {
+ std::shared_ptr bufferPtr{nullptr};
+ if (ioPtr && enginePtr)
+ {
+ bufferPtr = createInputBuffer
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ start,
+ count
+ );
+ }
+ bufferPtr_ = bufferPtr;
+ return bufferPtr_->size();
+ }
+
+
+ template
+ void writingBuffer
+ (
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ const labelList& shape,
+ const labelList& start,
+ const labelList& count
+ )
+ {
+ std::shared_ptr bufferPtr{nullptr};
+ if (ioPtr && enginePtr)
+ {
+ bufferPtr = std::make_shared
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ shape,
+ start,
+ count
+ );
+ }
+ bufferPtr_ = bufferPtr;
+ }
+
+
+ // Reading local/global array
+ template
+ typename std::enable_if::value, void>::type
+ get
+ (
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ DataType* data,
+ const labelList& start,
+ const labelList& count
+ )
+ {
+ readingBuffer>
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ start,
+ count
+ );
+ if (bufferPtr_)
+ {
+ bufferPtr_->transfer(enginePtr, data);
+ }
+ }
+
+
+ // Reading local/global array
+ template
+ typename std::enable_if::value, void>::type
+ get
+ (
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ ContainerType& container,
+ const labelList& start,
+ const labelList& count
+ )
+ {
+ typedef typename ContainerType::value_type DataType;
+ auto size = readingBuffer>
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ start,
+ count
+ );
+ container.resize(size);
+ if (bufferPtr_)
+ {
+ bufferPtr_->transfer(enginePtr, container.data());
+ }
+ }
+
+
+ // Writing local/global array
+ template
+ void put
+ (
+ adios2::IO* const ioPtr,
+ adios2::Engine* const enginePtr,
+ const Foam::string& blockId,
+ const labelList& shape,
+ const labelList& start,
+ const labelList& count,
+ const DataType* data,
+ const labelList& mapping = {},
+ const bool masked = false
+ )
+ {
+ if (mapping.empty())
+ {
+ writingBuffer>
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ shape,
+ start,
+ count
+ );
+ bufferPtr_->transfer(enginePtr, data);
+ }
+ else
+ {
+ writingBuffer>
+ (
+ ioPtr,
+ enginePtr,
+ blockId,
+ shape,
+ start,
+ count
+ );
+ bufferPtr_->transfer(enginePtr, data, mapping, masked);
+ }
+ }
+};
+
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.C b/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.C
new file mode 100644
index 000000000..debd4cf5a
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.C
@@ -0,0 +1,54 @@
+
+#include "SliceStreamPaths.H"
+
+#include "OSspecific.H" // isDir
+
+
+void Foam::SliceStreamPaths::checkFiles()
+{
+ if (!filesChecked_)
+ {
+ dataPresent_ = isDir(dataPathname_);
+ meshPresent_ = isDir(meshPathname_);
+ filesChecked_ = true;
+ }
+}
+
+
+void Foam::SliceStreamPaths::setPathName(const Foam::fileName& pathname)
+{
+ pathname_ = pathname;
+}
+
+
+const Foam::fileName& Foam::SliceStreamPaths::getPathName() const
+{
+ return pathname_;
+}
+
+
+Foam::fileName Foam::SliceStreamPaths::meshPathname(const Foam::fileName& path)
+{
+ return path / meshPathname_;
+}
+
+
+Foam::fileName Foam::SliceStreamPaths::dataPathname(const Foam::fileName& path)
+{
+ return path / dataPathname_;
+}
+
+
+bool Foam::SliceStreamPaths::dataPresent()
+{
+ checkFiles();
+ return dataPresent_;
+}
+
+
+bool Foam::SliceStreamPaths::meshPresent()
+{
+ checkFiles();
+ return meshPresent_;
+}
+
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.H b/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.H
new file mode 100644
index 000000000..568398c26
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamPaths.H
@@ -0,0 +1,91 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStreamPaths
+
+Description
+ Class to manage and fix file naming for ADIOS2 files
+
+SourceFiles
+ SliceStreamPaths.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SliceStreamPaths_H
+#define SliceStreamPaths_H
+
+#include "fileName.H"
+
+namespace Foam
+{
+
+class SliceStreamPaths
+{
+
+ // Mesh data file name
+ const Foam::fileName meshPathname_{"data.bp"};
+
+ // Field data file name
+ const Foam::fileName dataPathname_{"data.bp"};
+
+ // State like member that keeps the current file name
+ Foam::fileName pathname_{"data.bp"};
+
+ // State whether method checkFiles() was called before
+ bool filesChecked_{false};
+
+ // State if field data file is present
+ bool dataPresent_{false};
+
+ // State if mesh data file is present
+ bool meshPresent_{false};
+
+ // Check mesh and field files
+ void checkFiles();
+
+public:
+
+ // Set the state of pathname_
+ void setPathName(const fileName&);
+
+ // Get the state of pathname_
+ const fileName& getPathName() const;
+
+ // Return mesh data file name
+ fileName meshPathname(const fileName& path = "");
+
+ // Return field data file name
+ fileName dataPathname(const fileName& path = "");
+
+ // Check if field data file is present
+ bool dataPresent();
+
+ // Check if mesh data file is present
+ bool meshPresent();
+
+};
+
+}
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.C b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.C
new file mode 100644
index 000000000..ef17fe046
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.C
@@ -0,0 +1,180 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStreamRepo
+
+Description
+ A repository for streaming resources for parallel I/O.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "SliceStreamRepo.H"
+
+#include "adios2.h"
+
+#include "Pstream.H"
+#include "foamString.H"
+
+Foam::SliceStreamRepo* Foam::SliceStreamRepo::repoInstance_ = nullptr;
+
+struct Foam::SliceStreamRepo::Impl
+{
+
+ using ADIOS_uPtr = std::unique_ptr;
+ using IO_map_uPtr = std::unique_ptr;
+ using Engine_map_uPtr = std::unique_ptr;
+
+
+ // Default constructor
+ Impl()
+ :
+ adiosPtr_{nullptr},
+ ioMap_{new Foam::SliceStreamRepo::IO_map()},
+ engineMap_{new Foam::SliceStreamRepo::Engine_map()}
+ {
+ if (!adiosPtr_)
+ {
+ if (Pstream::parRun())
+ {
+ adiosPtr_.reset
+ (
+ new adios2::ADIOS
+ (
+ "system/config.xml",
+ MPI_COMM_WORLD
+ )
+ );
+ }
+ else
+ {
+ adiosPtr_.reset(new adios2::ADIOS("system/config.xml"));
+ }
+ }
+ }
+
+
+ ADIOS_uPtr adiosPtr_{};
+
+ IO_map_uPtr ioMap_{};
+
+ Engine_map_uPtr engineMap_{};
+};
+
+
+Foam::SliceStreamRepo::SliceStreamRepo()
+:
+ pimpl_{new Foam::SliceStreamRepo::Impl{}},
+ boundaryCounter_{0}
+{}
+
+
+Foam::SliceStreamRepo::~SliceStreamRepo() = default;
+
+
+Foam::SliceStreamRepo* Foam::SliceStreamRepo::instance()
+{
+ if (!repoInstance_)
+ {
+ repoInstance_ = new Foam::SliceStreamRepo();
+ }
+ return repoInstance_;
+}
+
+
+adios2::ADIOS*
+Foam::SliceStreamRepo::pullADIOS()
+{
+ return pimpl_->adiosPtr_.get();
+}
+
+
+Foam::SliceStreamRepo::IO_map*
+Foam::SliceStreamRepo::get(const std::shared_ptr&)
+{
+ return pimpl_->ioMap_.get();
+}
+
+
+Foam::SliceStreamRepo::Engine_map*
+Foam::SliceStreamRepo::get(const std::shared_ptr&)
+{
+ return pimpl_->engineMap_.get();
+}
+
+
+void Foam::SliceStreamRepo::push(const Foam::label& input)
+{
+ boundaryCounter_ = input;
+}
+
+
+void Foam::SliceStreamRepo::open(const bool atScale)
+{
+ for (const auto& enginePair: *(pimpl_->engineMap_))
+ {
+ if (*(enginePair.second))
+ {
+ if (enginePair.second->OpenMode() != adios2::Mode::ReadRandomAccess)
+ {
+ enginePair.second->BeginStep();
+ }
+ }
+ }
+}
+
+void Foam::SliceStreamRepo::close(const bool atScale)
+{
+ for (const auto& enginePair: *(pimpl_->engineMap_))
+ {
+ if (*(enginePair.second))
+ {
+ if (enginePair.second->OpenMode() != adios2::Mode::ReadRandomAccess)
+ {
+ enginePair.second->EndStep();
+ }
+ if (!atScale)
+ {
+ enginePair.second->Close();
+ }
+ }
+ }
+
+ if (!atScale)
+ {
+ pimpl_->engineMap_->clear();
+ }
+}
+
+void Foam::SliceStreamRepo::clear()
+{
+ close();
+ pimpl_->adiosPtr_->FlushAll();
+ for (const auto& ioPair: *(pimpl_->ioMap_))
+ {
+ ioPair.second->RemoveAllVariables();
+ }
+}
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.H b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.H
new file mode 100644
index 000000000..1834fcb0a
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepo.H
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStreamRepo
+
+Description
+ A repository for streaming resources for parallel I/O.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ SliceStreamRepo.C
+ SliceStreamRepoI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SliceStreamRepo_H
+#define SliceStreamRepo_H
+
+#include "label.H"
+
+#include
+#include
+
+// Forward declaration
+namespace adios2
+{
+class ADIOS;
+class IO;
+class Engine;
+}
+
+namespace Foam
+{
+
+// Forward declaration
+class string;
+
+
+class SliceStreamRepo
+{
+ // Singelton instance
+ static SliceStreamRepo* repoInstance_;
+
+ // Private default constructor in singelton
+ SliceStreamRepo();
+
+ using IO_map = std::map>;
+ using Engine_map = std::map>;
+
+ // Private members
+
+ // Forward declaration of bridge to ADIOS2 dependencies
+ class Impl;
+
+ // Bridge instance to ADIOS2 implementation
+ std::unique_ptr pimpl_;
+
+ label boundaryCounter_{0};
+
+ // Private methods
+ IO_map* get(const std::shared_ptr&);
+
+ Engine_map* get(const std::shared_ptr&);
+
+public:
+
+ // Getter to singelton instance
+ static SliceStreamRepo* instance();
+
+ // Destructor
+ ~SliceStreamRepo();
+
+ // Deleted copy constructor
+ SliceStreamRepo(SliceStreamRepo& other) = delete;
+
+ // Deleted copy assignment operator
+ SliceStreamRepo& operator=(const SliceStreamRepo& other) = delete;
+
+ // Getter for the ADIOS instance
+ adios2::ADIOS* pullADIOS();
+
+ // Pull of an ADIOS specific feature (IO, Engine, SliceBuffer)
+ template
+ void pull(std::shared_ptr&, const Foam::string&);
+
+ // Push of an ADIOS specific feature (IO, Engine, SliceBuffer)
+ template
+ void push(const std::shared_ptr&, const Foam::string&);
+
+ // Setter to boundaryCounter_
+ // TODO: Not the responsibility of SliceStreamRepo. Can this be removed?
+ void push(const label&);
+
+ // Removal of an ADIOS specific feature (IO, Engine, SliceBuffer)
+ template
+ void remove(const std::shared_ptr&, const Foam::string&);
+
+ // Initiating engines with Engine::BeginStep
+ void open(const bool atScale = false);
+
+ // Closing all engines and clear the engine map
+ void close(const bool atScale = false);
+
+ void clear();
+
+};
+
+}
+
+#include "SliceStreamRepoI.H"
+
+#endif
+
diff --git a/src/foam/db/IOstreams/SliceStreams/SliceStreamRepoI.H b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepoI.H
new file mode 100644
index 000000000..e37bd80d6
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/SliceStreamRepoI.H
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceStreamRepo
+
+Description
+ A repository for streaming resources for parallel I/O.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "label.H"
+
+#include
+#include
+
+// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
+
+template
+void Foam::SliceStreamRepo::pull
+(
+ std::shared_ptr& featurePtr,
+ const Foam::string& id
+)
+{
+ auto featureMap = get(featurePtr);
+ if (featureMap->count(id))
+ {
+ featurePtr = featureMap->at(id);
+ }
+}
+
+
+template
+void Foam::SliceStreamRepo::push
+(
+ const std::shared_ptr& featurePtr,
+ const Foam::string& id
+)
+{
+ auto featureMap = get(featurePtr);
+ if (featureMap->count(id) == 0)
+ {
+ featureMap->insert({id, featurePtr});
+ }
+}
+
+
+template
+void Foam::SliceStreamRepo::remove
+(
+ const std::shared_ptr& featurePtr,
+ const Foam::string& id
+)
+{
+ auto featureMap = get(featurePtr);
+ if (featureMap->count(id) == 0)
+ {
+ featureMap->erase(id);
+ }
+}
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/UListProxy.C b/src/foam/db/IOstreams/SliceStreams/UListProxy.C
new file mode 100644
index 000000000..26832de95
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/UListProxy.C
@@ -0,0 +1,181 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::UListProxy
+
+Description
+ A proxy of UList containing type T. It inheriting from UList and
+ provides additional functionality such as determination of uniformity.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+\*---------------------------------------------------------------------------*/
+
+#include "UListProxy.H"
+#include "primitives_traits.H"
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+template
+Foam::UListProxy::UListProxy(UList uList)
+:
+ UList(uList.data(), uList.size())
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+void Foam::UListProxy::writeFirstElement
+(
+ Ostream& os,
+ const char* data
+) const
+{
+ if (data)
+ {
+ const T* dataT = reinterpret_cast(data);
+ os << *dataT;
+ }
+ else
+ {
+ FatalErrorInFunction
+ << "Given data pointer is nullptr."
+ << abort(FatalError);
+ }
+}
+
+
+#if (OPENFOAM >= 2206)
+
+template
+const char* Foam::UListProxy::cdata_bytes() const
+{
+ return UList::cdata_bytes();
+}
+
+
+template
+char* Foam::UListProxy::data_bytes()
+{
+ return UList::data_bytes();
+}
+
+
+template
+std::streamsize Foam::UListProxy::size_bytes() const
+{
+ return UList::size_bytes();
+}
+
+#else
+
+template
+const char* Foam::UListProxy::cdata_bytes() const
+{
+ return reinterpret_cast(UList::cdata());
+}
+
+
+template
+char* Foam::UListProxy::data_bytes()
+{
+ return reinterpret_cast(UList::data());
+}
+
+
+template
+std::streamsize Foam::UListProxy::size_bytes() const
+{
+ return std::streamsize(UList::size())*sizeof(T);
+}
+
+#endif
+
+
+template
+Foam::label Foam::UListProxy::byteSize() const
+{
+ return UList::byteSize();
+}
+
+
+template
+Foam::label Foam::UListProxy::size() const
+{
+ return UList::size();
+}
+
+
+template
+Foam::label Foam::UListProxy::nComponents() const
+{
+ return Foam::nComponentsOf();
+}
+
+
+template
+char* Foam::UListProxy::data()
+{
+ return reinterpret_cast(UList::data());
+}
+
+
+template
+const char* Foam::UListProxy::cdata() const
+{
+ return reinterpret_cast(UList::cdata());
+}
+
+
+template
+Foam::uListProxyBase::uniformity
+Foam::UListProxy::determineUniformity() const
+{
+ label nElems = size();
+
+ if (nElems > 0)
+ {
+ uListProxyBase::uniformity u = uListProxyBase::UNIFORM;
+
+ // Skip comparison of the first element with itself
+ for (label i = 1; i < nElems; i++)
+ {
+ if (UList::operator[](i) != UList::operator[](0))
+ {
+ u = uListProxyBase::NONUNIFORM;
+ break;
+ }
+ }
+
+ return u;
+ }
+ else
+ {
+ return uListProxyBase::EMPTY;
+ }
+}
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/UListProxy.H b/src/foam/db/IOstreams/SliceStreams/UListProxy.H
new file mode 100644
index 000000000..537c72dbf
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/UListProxy.H
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::UListProxy
+
+Description
+ A proxy of UList containing type T. It inheriting from UList and
+ provides additional functionality such as determination of uniformity.
+
+Author
+ Sergey Lesnik, Wikki GmbH
+
+SourceFiles
+ UListProxy.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UListProxy_H
+#define UListProxy_H
+
+#include "uListProxyBase.H"
+#include "UList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class UListProxy Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class UListProxy
+:
+ public uListProxyBase,
+ public UList
+{
+public:
+
+ // Constructors
+
+ //- Construct copying UList attributes such as data pointer and size.
+ UListProxy(UList uList);
+
+
+ //- Destructor
+ virtual ~UListProxy()
+ {}
+
+
+ // Member Functions
+
+ //- Write the first element of UList.
+ virtual void writeFirstElement
+ (
+ Ostream& os,
+ const char* data
+ ) const override;
+
+
+ // Byte-wise Access
+
+ //- Return pointer to the underlying array serving as data storage,
+ // reinterpreted as byte data
+ // \note Only meaningful for contiguous data
+ virtual inline const char* cdata_bytes() const override;
+
+ //- Return pointer to the underlying array serving as data storage,
+ // reinterpreted as byte data
+ // \note Only meaningful for contiguous data
+ virtual inline char* data_bytes() override;
+
+ //- Number of contiguous bytes for the List data.
+ // \note Only meaningful for contiguous data
+ virtual inline std::streamsize size_bytes() const override;
+
+
+ // Access
+
+ //- Return the binary size in number of characters of the UList
+ // if the element is a primitive type
+ // i.e. contiguous() == true
+ virtual label byteSize() const override;
+
+ //- Return the number of elements in the UList.
+ virtual label size() const override;
+
+ //- Return the number of components per element.
+ virtual label nComponents() const override;
+
+ //- Return a pointer to the data casted to scalar
+ virtual inline char* data() override;
+
+ //- Return a const pointer to the data casted to scalar
+ virtual inline const char* cdata() const override;
+
+ //- Determine whether the underlying list is UNIFORM, NONUNIFORM or
+ // EMPTY.
+ virtual uListProxyBase::uniformity
+ determineUniformity() const override;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+# include "UListProxy.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.C b/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.C
new file mode 100644
index 000000000..c2977c382
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.C
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceBuffer
+
+Description
+ Writing the output for parallel I/O into buffers for deferred output.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "SliceBuffer.H"
+
+
+adios2::Dims Foam::toDims(const Foam::labelList& list)
+{
+ adios2::Dims dims(list.size());
+ std::copy(list.begin(), list.end(), dims.begin());
+ return dims;
+}
+
+
+void Foam::SliceBuffer::v_transfer
+(
+ adios2::Engine* engine,
+ const char* data,
+ const labelList& mapping,
+ const bool masked
+)
+{};
diff --git a/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.H b/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.H
new file mode 100644
index 000000000..bdbf930c3
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/buffer/SliceBuffer.H
@@ -0,0 +1,146 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::SliceBuffer
+
+Description
+ Reading and writing the data for parallel I/O into buffers for
+ deferred I/O.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ SliceBuffer.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef SliceBuffer_H
+#define SliceBuffer_H
+
+#include "adios2.h"
+
+#include
+
+#include "label.H"
+#include "labelList.H"
+#include "vector.H"
+#include "messageStream.H" // FatalError()
+
+namespace Foam
+{
+
+// Convert Foam::labelList to adios2::Dims
+adios2::Dims toDims(const Foam::labelList& list);
+
+class SliceBuffer
+{
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ const char*,
+ const labelList& = {},
+ const bool = false
+ );
+
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ char*,
+ const labelList& = {},
+ const bool = false
+ ) {};
+
+
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ const label*,
+ const labelList& = {},
+ const bool = false
+ ) {};
+
+
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ label*,
+ const labelList& = {},
+ const bool = false
+ ) {};
+
+
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ const scalar*,
+ const labelList& = {},
+ const bool = false
+ ) {};
+
+
+ virtual void v_transfer
+ (
+ adios2::Engine*,
+ scalar*,
+ const labelList& = {},
+ const bool = false
+ ) {};
+
+public:
+
+ SliceBuffer() = default;
+
+ virtual ~SliceBuffer() = default;
+
+ virtual label size() = 0;
+
+
+ // Note: constness is included in with type deduction of DataType
+ template
+ void transfer
+ (
+ adios2::Engine* engine,
+ DataType* const data,
+ const labelList& mapping = {},
+ const bool masked = false
+ )
+ {
+ if (!engine)
+ {
+ FatalErrorInFunction
+ << "Engine is nullptr" << abort(FatalError);
+ }
+ if (!data && size() > 0)
+ {
+ FatalErrorInFunction
+ << "Data is nullptr" << abort(FatalError);
+ }
+ v_transfer(engine, data, mapping, masked);
+ }
+};
+
+}
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/buffer/spanBuffer.H b/src/foam/db/IOstreams/SliceStreams/buffer/spanBuffer.H
new file mode 100644
index 000000000..a060656b9
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/buffer/spanBuffer.H
@@ -0,0 +1,259 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::spanBuffer
+
+Description
+ Child of SliceBuffer implementing ADIOS2 I/O with adios2::Span.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ spanBuffer.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef spanBuffer_H
+#define spanBuffer_H
+
+#include
+#include
+
+#include "label.H"
+#include "labelList.H"
+
+#include "SliceBuffer.H"
+
+namespace Foam
+{
+
+template
+void check_extent_of_range
+(
+ ForwardIterator iter1,
+ ForwardIterator iter2,
+ label extent
+)
+{
+ if (std::distance(iter1, iter2)
+void mapped_copy
+(
+ ForwardIterator input_iter,
+ const ForwardIterator input_end,
+ OutputIterator output_iter,
+ const OutputIterator output_end,
+ const labelList& mapping,
+ const label serialization = 1,
+ const bool masked = false
+)
+{
+ // first, check if the maximum index in mapping
+ // actually fits to the output range.
+ auto max_index = *std::max_element(mapping.begin(), mapping.end());
+ check_extent_of_range(output_iter, output_end, max_index);
+
+ // second map or mask loop
+ auto output_begin = output_iter;
+ for (const auto& next_pos: mapping)
+ {
+ auto cur_pos = std::distance(output_begin, output_iter) / serialization;
+ auto n = next_pos - cur_pos;
+
+ // advance to mapped position (no advancement if masked)
+ auto n_mapped = n * (1 - masked); // masked ? 0 : n
+ std::advance(output_iter, n_mapped * serialization);
+ // copy and advance one element (n elements if masked)
+ auto n_copy = 1 + (n - 1) * masked; // masked ? n : 1
+ std::copy_n(input_iter, n_copy * serialization, output_iter);
+ std::advance(input_iter, n_copy * serialization);
+ std::advance(output_iter, n_copy * serialization);
+ // advance over masked element (only if masked)
+ std::advance(output_iter, masked * serialization);
+ }
+
+ // masked ? "finite value" : 0
+ auto remaining_extent = std::distance(output_iter, output_end) * masked;
+ // third, copy remaining elements if masking was turned on
+ check_extent_of_range(input_iter, input_end, remaining_extent);
+ std::copy(input_iter, input_end, output_iter);
+}
+
+
+template
+adios2::Variable
+inquire_define_variable
+(
+ adios2::IO* io,
+ adios2::Variable& variable,
+ const Foam::string blockId,
+ const adios2::Dims& shape,
+ const adios2::Dims& start,
+ const adios2::Dims& count
+)
+{
+ variable = io->InquireVariable( blockId );
+ if ( !variable )
+ {
+ variable = io->DefineVariable( blockId, shape, start, count );
+ }
+ return variable;
+}
+
+template
+class spanBuffer
+:
+ public SliceBuffer
+{
+
+ adios2::Dims shape_;
+
+ adios2::Dims start_;
+
+ adios2::Dims count_;
+
+ label serialization_;
+
+ adios2::Variable variable_;
+
+ typename adios2::Variable::Span span_;
+
+ // Reading
+ void v_transfer
+ (
+ adios2::Engine* engine,
+ DataType* data,
+ const labelList& mapping = {},
+ const bool masked = false
+ ) final
+ {
+ FatalErrorIn
+ (
+ "spanBuffer is only for output transfers. Reading through transfer( adios2::Engine*, DataType* const ) is disabled."
+ )
+ << abort(FatalError);
+ }
+
+
+ // Writing
+ void v_transfer
+ (
+ adios2::Engine* engine,
+ const DataType* data,
+ const labelList& mapping = {},
+ const bool masked = false
+ ) final
+ {
+ const DataType* data_end = data + count_[0] * serialization_ + 1;
+ mapped_copy
+ (
+ data,
+ data_end,
+ span_.begin(),
+ span_.end(),
+ mapping,
+ serialization_,
+ masked
+ );
+ }
+
+
+public:
+
+ spanBuffer
+ (
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+ );
+
+ ~spanBuffer() = default;
+
+ label size() final;
+};
+}
+
+template
+Foam::spanBuffer::spanBuffer
+(
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+ : shape_{ toDims( shape ) }
+ , start_{ toDims( start ) }
+ , count_{ toDims( count ) }
+ , serialization_
+ {
+ std::accumulate
+ (
+ count_.begin() + 1,
+ count_.end(),
+ 1,
+ std::multiplies()
+ )
+ }
+ , variable_
+ {
+ inquire_define_variable
+ (
+ io,
+ variable_,
+ blockId,
+ shape_,
+ start_,
+ count_
+ )
+ }
+ , span_{ engine->Put( variable_ ) }
+{}
+
+
+template
+Foam::label Foam::spanBuffer::size()
+{
+ if (!variable_) { return 0; }
+ return variable_.Count()[0];
+}
+
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/buffer/variableBuffer.H b/src/foam/db/IOstreams/SliceStreams/buffer/variableBuffer.H
new file mode 100644
index 000000000..7cb5e1940
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/buffer/variableBuffer.H
@@ -0,0 +1,278 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::variableBuffer
+
+Description
+ Child of SliceBuffer implementing ADIOS2 I/O.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ variableBuffer.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef variableBuffer_H
+#define variableBuffer_H
+
+#include
+#include
+
+#include "label.H"
+#include "labelList.H"
+
+#include "SliceBuffer.H"
+
+namespace Foam
+{
+
+template
+void transferFromVariable
+(
+ adios2::Engine* const engine,
+ VariableType& variable,
+ adios2::Dims& shape,
+ adios2::Dims& start,
+ adios2::Dims& count,
+ DataType* data
+)
+{
+ if (variable)
+ {
+ engine->Get(variable, data, adios2::Mode::Deferred);
+ }
+}
+
+
+template
+void transferToVariable
+(
+ adios2::Engine* const engine,
+ VariableType& variable,
+ adios2::Dims& shape,
+ adios2::Dims& start,
+ adios2::Dims& count,
+ DataType* data
+)
+{
+ engine->Put(variable, data, adios2::Mode::Deferred);
+}
+
+
+template
+void transferToSpan
+(
+ adios2::Engine* const engine,
+ VariableType& variable,
+ adios2::Dims& shape,
+ adios2::Dims& start,
+ adios2::Dims& count,
+ DataType* data
+)
+{
+ auto span = engine->Put(variable);
+ for (Foam::label i = 0; i
+class variableBuffer
+:
+ public SliceBuffer
+{
+ // Global shape of I/O data array in variable
+ adios2::Dims shape_;
+
+ // Local start of I/O data array in variable
+ adios2::Dims start_;
+
+ // Local count of I/O data array in variable
+ adios2::Dims count_;
+
+ // ADIOS2 variable defining I/O data layout
+ adios2::Variable variable_;
+
+ // Reading
+ void v_transfer
+ (
+ adios2::Engine* engine,
+ DataType* data,
+ const labelList& mapping = {},
+ const bool masked = false
+ ) final
+ {
+ transferFromVariable(engine, variable_, shape_, start_, count_, data);
+ }
+
+ // Writing
+ void v_transfer
+ (
+ adios2::Engine* engine,
+ const DataType* data,
+ const labelList& mapping = {},
+ const bool masked = false
+ ) final
+ {
+ transferToVariable(engine, variable_, shape_, start_, count_, data);
+ }
+
+
+public:
+
+ variableBuffer() = default;
+
+ ~variableBuffer() = default;
+
+ variableBuffer
+ (
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId
+ );
+
+ variableBuffer
+ (
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+ );
+
+ variableBuffer
+ (
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+ );
+
+ label size() final;
+};
+}
+
+
+template
+Foam::variableBuffer::variableBuffer
+(
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId
+)
+{
+ variable_ = io->InquireVariable(blockId);
+ if (variable_)
+ {
+ // Set to last step by default
+ auto step = variable_.Steps() - 1;
+ variable_.SetStepSelection({step, 1});
+ shape_ = variable_.Shape();
+ start_ = variable_.Start();
+ count_ = variable_.Count();
+ }
+}
+
+
+template
+Foam::variableBuffer::variableBuffer
+(
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+:
+ start_{toDims(start)},
+ count_{toDims(count)}
+{
+ variable_ = io->InquireVariable(blockId);
+ if (variable_)
+ {
+ // Set to last step by default
+ auto step = variable_.Steps() - 1;
+ variable_.SetStepSelection({step, 1});
+ variable_.SetSelection({start_, count_});
+ shape_ = variable_.Shape();
+ }
+}
+
+
+template
+Foam::variableBuffer::variableBuffer
+(
+ adios2::IO* io,
+ adios2::Engine* engine,
+ const Foam::string blockId,
+ const Foam::labelList& shape,
+ const Foam::labelList& start,
+ const Foam::labelList& count
+)
+:
+ shape_{toDims(shape)},
+ start_{toDims(start)},
+ count_{toDims(count)}
+{
+ variable_ = io->InquireVariable(blockId);
+ if (variable_)
+ {
+ // Set to last step by default
+ auto step = variable_.Steps() - 1;
+ variable_.SetStepSelection({step, 1});
+ variable_.SetSelection({start_, count_});
+ shape_ = variable_.Shape();
+ }
+ else if (!variable_)
+ {
+ variable_ = io->DefineVariable
+ (
+ blockId,
+ shape_,
+ start_,
+ count_
+ );
+ }
+}
+
+
+template
+Foam::label Foam::variableBuffer::size()
+{
+ Foam::label count = 0;
+ if (variable_)
+ {
+ count = variable_.Count()[0];
+ }
+ return count;
+}
+
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.C b/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.C
new file mode 100644
index 000000000..1c87f53cc
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.C
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::InputFeatures
+
+Description
+ Child of SliceFeatures implementing creation of input streaming resources.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ InputFeatures.C
+
+\*---------------------------------------------------------------------------*/
+
+#include "InputFeatures.H"
+
+#include "adios2.h"
+#include "IO.h"
+#include "Engine.h"
+
+#include "SliceStreamRepo.H"
+
+#include "fileName.H"
+
+
+std::shared_ptr
+Foam::InputFeatures::createIO(adios2::ADIOS* const corePtr)
+{
+ Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ std::shared_ptr ioPtr{nullptr};
+ repo->pull(ioPtr, "read");
+ if (!ioPtr)
+ {
+ ioPtr = std::make_shared(corePtr->DeclareIO("read"));
+ ioPtr->SetEngine("BP5");
+ repo->push(ioPtr, "read");
+ }
+ return ioPtr;
+}
+
+
+std::shared_ptr
+Foam::InputFeatures::createEngine
+(
+ adios2::IO* const ioPtr,
+ const Foam::fileName& path
+)
+{
+ Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ std::shared_ptr enginePtr{nullptr};
+ auto size = path.length();
+ repo->pull( enginePtr, "read"+path( size ) );
+ if ( !enginePtr )
+ {
+ enginePtr = std::make_shared
+ (
+ ioPtr->Open( path, adios2::Mode::ReadRandomAccess )
+ );
+ repo->push( enginePtr, "read"+path( size ) );
+ }
+ return enginePtr;
+}
+
diff --git a/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.H b/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.H
new file mode 100644
index 000000000..5d3bf6a5f
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/create/InputFeatures.H
@@ -0,0 +1,59 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::InputFeatures
+
+Description
+ Child of SliceFeatures implementing creation of input streaming resources.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+SourceFiles
+ InputFeatures.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef InputFeatures_H
+#define InputFeatures_H
+
+#include "StreamFeatures.H"
+
+namespace Foam
+{
+
+struct InputFeatures
+:
+ public StreamFeatures
+{
+ virtual std::shared_ptr
+ createIO( adios2::ADIOS* const ) override;
+
+ virtual std::shared_ptr
+ createEngine( adios2::IO* const, const Foam::fileName& ) override;
+};
+
+}
+
+#endif
diff --git a/src/foam/db/IOstreams/SliceStreams/create/OutputFeatures.C b/src/foam/db/IOstreams/SliceStreams/create/OutputFeatures.C
new file mode 100644
index 000000000..5f4c28ca1
--- /dev/null
+++ b/src/foam/db/IOstreams/SliceStreams/create/OutputFeatures.C
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ Foam::OutputFeatures
+
+Description
+ Child of SliceFeatures implementing creation of output streaming resources.
+
+Author
+ Gregor Weiss, HLRS University of Stuttgart
+
+\*---------------------------------------------------------------------------*/
+
+#include "OutputFeatures.H"
+
+#include "adios2.h"
+#include "IO.h"
+#include "Engine.h"
+
+#include "SliceStreamRepo.H"
+
+#include "fileName.H"
+
+
+std::shared_ptr
+Foam::OutputFeatures::createIO(adios2::ADIOS* const corePtr)
+{
+ SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ std::shared_ptr ioPtr{nullptr};
+ repo->pull(ioPtr, "write");
+ if (!ioPtr)
+ {
+ ioPtr = std::make_shared(corePtr->DeclareIO("write"));
+ ioPtr->SetEngine("BP5");
+ repo->push(ioPtr, "write");
+ }
+ return ioPtr;
+}
+
+
+std::shared_ptr
+Foam::OutputFeatures::createEngine
+(
+ adios2::IO* const ioPtr,
+ const Foam::fileName& path
+)
+{
+ SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
+ std::shared_ptr enginePtr{nullptr};
+ auto size = path.length();
+ repo->pull(enginePtr, "write" + path(size));
+ if (!enginePtr)
+ {
+ enginePtr = std::make_shared