ENH: Add simple source code additions

This commit is contained in:
Gregor Weiss 2023-09-25 17:16:45 +02:00
parent bd6f079b52
commit 6fe6145d97
94 changed files with 13215 additions and 3 deletions

View file

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::IFCstream::reader<Type, Foam::fvsPatchField, Foam::surfaceMesh>::read
(
IFCstream& ifs
)
{
ifs.readNonProcessorBoundaryFields<Type>();
// 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<Type>::cmptType cmptType;
const polyMesh& mesh = ifs.coherentMesh_.mesh();
const polyBoundaryMesh& bm = mesh.boundaryMesh();
// Internal field data
UList<Type> internalData;
// Field data in the coherent format holding internal and processor patch
// fields
List<Type> 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<Type>
(
reinterpret_cast<Type*>(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<fvsPatchField, surfaceMesh>();
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<cmptType*>(coherentData.data()),
List<label>({nCmpts*elemOffset}),
List<label>({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<UList<Type> > procPatchData(nAllPatches);
label nProcPatches = 0;
forAll(bm, patchI)
{
const polyPatch& patch = bm[patchI];
if (isA<processorPolyPatch>(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<token::compound> ctPtr =
token::compound::New
(
"List<" + word(pTraits<Type>::typeName) + '>',
patchSize
);
// Store the data pointer for the later mapping
procPatchData[nProcPatches++] =
UList<Type>
(
reinterpret_cast<Type*>(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<processorPolyPatch>(patch))
{
const processorPolyPatch& procPp =
refCast<const processorPolyPatch>(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<processorPolyPatch>(patch))
{
const processorPolyPatch& procPp =
refCast<const processorPolyPatch>(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<class Type>
void Foam::OFCstream<Type, Foam::fvsPatchField, Foam::surfaceMesh>::
combineCoherentInternal()
{
const Offsets& iso = this->coherentMesh_.internalSurfaceFieldOffsets();
const label localCombinedSize = iso.count(Pstream::myProcNo());
this->consolidatedData_.resize(localCombinedSize);
// Internal
const fieldDataEntry* internalFieldDataEntryPtr =
dynamic_cast<const fieldDataEntry*>
(
this->dict_.lookupEntryPtr("internalField", false, false)
);
if (!internalFieldDataEntryPtr)
{
FatalErrorInFunction
<< "Entry 'internalField' not found in dictionary "
<< dict_.name()
<< abort(FatalError);
}
const UList<Type>& internalData =
dynamic_cast<const UList<Type>&>(internalFieldDataEntryPtr->uList());
// Processor patches
const polyBoundaryMesh& bm = coherentMesh_.mesh().boundaryMesh();
const label nPatches = bm.size();
dictionary& bfDict = dict_.subDict("boundaryField");
List<UList<Type> > patchData(nPatches);
List<const fieldDataEntry*> 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<const fieldDataEntry*>
(
ppDict.lookupEntryPtr("value", false, false)
);
patchData[ppI] =
dynamic_cast<const UList<Type>&>
(
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<Type>(consolidatedData_)
);
// Set the new internalField in the dictionary replacing the old one
this->dict_.set(coherentInternal);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::OFCstream<Type, Foam::fvsPatchField, Foam::surfaceMesh>::OFCstream
(
const fileName& pathname,
const objectRegistry& registry,
ios_base::openmode mode,
IOstreamOption streamOpt
)
:
OFCstreamBase(pathname, registry, mode, streamOpt)
{}
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
template<class Type>
Foam::OFCstream<Type, Foam::fvsPatchField, Foam::surfaceMesh>::~OFCstream()
{
combineCoherentInternal();
this->removeProcPatchesFromDict();
this->writeGlobalGeometricField();
}
// ************************************************************************* //

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
#include "List.H"
defineTypeNameAndDebug(Foam::DebugIOListName, 0);

View file

@ -0,0 +1,3 @@
#include "UList.H"
defineTypeNameAndDebug(Foam::DebugIOUListName, 0);

View file

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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;
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<StreamFeatures>& 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();
}

View file

@ -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 <http://www.gnu.org/licenses/>.
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<StreamFeatures> sliceFile_;
virtual void v_access() final;
virtual void v_flush() final;
public:
explicit FileSliceStream(std::unique_ptr<StreamFeatures>&);
};
}
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
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<CoherentMesh&>
(
registry.lookupObject<CoherentMesh>(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<IFCstream&>(*this);
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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 <fstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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 Type, template<class> 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<SliceStream> sliceStreamPtr_;
// Private Member Functions
//- Add field of type processorPolyPatch to dictionary. To be
// specialized by PatchField and GeoMesh types
template<template<class> 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<template<class> class PatchField, class GeoMesh>
label coherentFieldSize();
// Read
//- Find (recursively) all compound tokens in dictionary and
// populate them with data
template<class Type>
void readCompoundTokenData(dictionary& dict, const label size);
//- Find all compound tokens in ITstream and populate them with
// data
template<class Type>
void readCompoundTokenData(ITstream& is, const label localSize);
//- Read field data of all boundary patches that are not of
// processor type
template<class Type>
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<template<class> class PatchField, class GeoMesh>
template
<
class Type,
template<class> 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
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<template<class> class PatchField, class GeoMesh>
void Foam::IFCstream::addProcessorPatchField
(
dictionary& bfDict,
const word& patchName,
const word& fieldTypeName
)
{
NotImplemented;
}
template<template<class> class PatchField, class GeoMesh>
Foam::label Foam::IFCstream::coherentFieldSize()
{
NotImplemented;
return 0;
}
template<class Type>
void Foam::IFCstream::readCompoundTokenData(dictionary& dict, const label size)
{
forAllIter(IDLList<entry>, dict, pIter)
{
entry& pEntry = pIter();
if (pEntry.isDict())
{
readCompoundTokenData<Type>(pEntry.dict(), size);
}
if (debug)
{
Pout<< "Reading primitive entry " << nl << tab << pEntry << endl;
}
ITstream& is = pEntry.stream();
readCompoundTokenData<Type>(is, size);
}
}
template<class Type>
void Foam::IFCstream::readCompoundTokenData
(
ITstream& is,
const label localSize
)
{
typedef typename pTraits<Type>::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<cmptType*>(compToken.data()),
List<label>({nCmpts*elemOffset}),
List<label>({nCmpts*nElems})
);
}
}
}
template<class Type>
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<Type>(patchDict, patch.size());
}
}
}
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::IFCstream::reader<Type, PatchField, GeoMesh>::read
(
IFCstream& ifs
)
{
Info<< "Non-special" << endl;
ITstream& its = ifs.dict_.lookup("internalField");
ifs.readCompoundTokenData<Type>
(
its,
ifs.coherentFieldSize<PatchField, GeoMesh>()
);
ifs.readNonProcessorBoundaryFields<Type>();
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<PatchField, GeoMesh>
(
bfDict, patchName, pTraits<Type>::typeName
);
}
}
// Ensure that the data is read from storage
ifs.sliceStreamPtr_->bufferSync();
return;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::dictionary& Foam::IFCstream::readToDict()
{
// Fill the dictionary with the stream
dict_.read(*this);
reader<Type, PatchField, GeoMesh>::read(*this);
return dict_;
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<fieldDataEntry*>& fieldDataEntries
)
{
forAllIter(IDLList<entry>, dict, iter)
{
entry& e = iter();
if (isA<fieldDataEntry>(e))
{
fieldDataEntry* fde = dynamic_cast<fieldDataEntry*>(&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<CoherentMesh&>
(
registry.lookupObject<CoherentMesh>(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<std::ostringstream&>(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<dictionary*>(currentSubDictPtr_->subDictPtr(name));
return name;
}
void Foam::OFCstreamBase::decrBlock()
{
// Save the data written to stream before
moveStreamBufferToDict();
currentSubDictPtr_ = &const_cast<dictionary&>(currentSubDictPtr_->parent());
}
Foam::Ostream&
Foam::OFCstreamBase::parwrite(std::unique_ptr<uListProxyBase> uListProxyPtr)
{
currentSubDictPtr_->add
(
new fieldDataEntry
(
currentKeyword_,
currentCompoundTokenName_,
uListProxyPtr.release()
)
);
return *this;
}
void Foam::OFCstreamBase::moveStreamBufferToDict()
{
ostream& buf = getStreamBuffer();
std::ostringstream& oss = dynamic_cast<std::ostringstream&>(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<entry>, dict, iter)
{
const entry& e = *iter;
if (isA<dictionaryEntry>(e))
{
os.indent();
os.write(e.keyword());
writeDict(os, e.dict(), true);
}
else if (isA<primitiveEntry>(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<const primitiveEntry>(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<fieldDataEntry*> fieldDataEntries;
gatherFieldDataEntries(dict_, fieldDataEntries);
const label nFields = fieldDataEntries.size();
List<fieldTag> 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<const scalar*>(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);
}
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<fieldDataEntry*>&
);
//- 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<uListProxyBase>);
//- 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 Type, template<class> 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
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<Foam::variableBuffer<Foam::scalar> >
(
ioPtr_.get(),
enginePtr_.get(),
blockId
);
}
Foam::label Foam::SliceStream::getBufferSize
(
const Foam::string& blockId,
const Foam::label* const data
)
{
return pimpl_->readingBuffer<Foam::variableBuffer<Foam::label> >
(
ioPtr_.get(),
enginePtr_.get(),
blockId
);
}
Foam::label Foam::SliceStream::getBufferSize
(
const Foam::string& blockId,
const char* const data
)
{
return pimpl_->readingBuffer<Foam::variableBuffer<char> >
(
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();
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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<typename Container>
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<Impl> 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<adios2::IO> ioPtr_{nullptr};
// Pointer to engine instance
std::shared_ptr<adios2::Engine> 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<class ContainerType>
typename std::enable_if<!std::is_const<ContainerType>::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<class ContainerType>
typename std::enable_if<!std::is_const<ContainerType>::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<typename Container>
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

View file

@ -0,0 +1,207 @@
#include "adios2.h"
#include "SliceStream.H"
#include "variableBuffer.H"
#include "spanBuffer.H"
template<typename BufferType>
std::shared_ptr<Foam::SliceBuffer>
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<BufferType>
(
ioPtr,
enginePtr,
blockId,
start,
count
);
}
else
{
return std::make_shared<BufferType>
(
ioPtr,
enginePtr,
blockId
);
}
}
struct Foam::SliceStream::Impl
{
Impl() = default;
std::shared_ptr<SliceBuffer> bufferPtr_{nullptr};
template<typename BufferType>
label readingBuffer
(
adios2::IO* const ioPtr,
adios2::Engine* const enginePtr,
const Foam::string& blockId,
const labelList& start = {},
const labelList& count = {}
)
{
std::shared_ptr<SliceBuffer> bufferPtr{nullptr};
if (ioPtr && enginePtr)
{
bufferPtr = createInputBuffer<BufferType>
(
ioPtr,
enginePtr,
blockId,
start,
count
);
}
bufferPtr_ = bufferPtr;
return bufferPtr_->size();
}
template<typename BufferType>
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<SliceBuffer> bufferPtr{nullptr};
if (ioPtr && enginePtr)
{
bufferPtr = std::make_shared<BufferType>
(
ioPtr,
enginePtr,
blockId,
shape,
start,
count
);
}
bufferPtr_ = bufferPtr;
}
// Reading local/global array
template<class DataType>
typename std::enable_if<!std::is_const<DataType>::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<variableBuffer<DataType>>
(
ioPtr,
enginePtr,
blockId,
start,
count
);
if (bufferPtr_)
{
bufferPtr_->transfer(enginePtr, data);
}
}
// Reading local/global array
template<class ContainerType>
typename std::enable_if<!std::is_const<ContainerType>::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<variableBuffer<DataType>>
(
ioPtr,
enginePtr,
blockId,
start,
count
);
container.resize(size);
if (bufferPtr_)
{
bufferPtr_->transfer(enginePtr, container.data());
}
}
// Writing local/global array
template<class DataType>
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<variableBuffer<DataType>>
(
ioPtr,
enginePtr,
blockId,
shape,
start,
count
);
bufferPtr_->transfer(enginePtr, data);
}
else
{
writingBuffer<spanBuffer<DataType>>
(
ioPtr,
enginePtr,
blockId,
shape,
start,
count
);
bufferPtr_->transfer(enginePtr, data, mapping, masked);
}
}
};

View file

@ -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_;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
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

View file

@ -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 <http://www.gnu.org/licenses/>.
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<adios2::ADIOS>;
using IO_map_uPtr = std::unique_ptr<Foam::SliceStreamRepo::IO_map>;
using Engine_map_uPtr = std::unique_ptr<Foam::SliceStreamRepo::Engine_map>;
// 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<adios2::IO>&)
{
return pimpl_->ioMap_.get();
}
Foam::SliceStreamRepo::Engine_map*
Foam::SliceStreamRepo::get(const std::shared_ptr<adios2::Engine>&)
{
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();
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
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 <map>
#include <memory>
// 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<Foam::string, std::shared_ptr<adios2::IO>>;
using Engine_map = std::map<Foam::string, std::shared_ptr<adios2::Engine>>;
// Private members
// Forward declaration of bridge to ADIOS2 dependencies
class Impl;
// Bridge instance to ADIOS2 implementation
std::unique_ptr<Impl> pimpl_;
label boundaryCounter_{0};
// Private methods
IO_map* get(const std::shared_ptr<adios2::IO>&);
Engine_map* get(const std::shared_ptr<adios2::Engine>&);
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<typename FeatureType>
void pull(std::shared_ptr<FeatureType>&, const Foam::string&);
// Push of an ADIOS specific feature (IO, Engine, SliceBuffer)
template<typename FeatureType>
void push(const std::shared_ptr<FeatureType>&, 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<typename FeatureType>
void remove(const std::shared_ptr<FeatureType>&, 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

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceStreamRepo
Description
A repository for streaming resources for parallel I/O.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "label.H"
#include <map>
#include <memory>
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
template<typename FeatureType>
void Foam::SliceStreamRepo::pull
(
std::shared_ptr<FeatureType>& featurePtr,
const Foam::string& id
)
{
auto featureMap = get(featurePtr);
if (featureMap->count(id))
{
featurePtr = featureMap->at(id);
}
}
template<typename FeatureType>
void Foam::SliceStreamRepo::push
(
const std::shared_ptr<FeatureType>& featurePtr,
const Foam::string& id
)
{
auto featureMap = get(featurePtr);
if (featureMap->count(id) == 0)
{
featureMap->insert({id, featurePtr});
}
}
template<typename FeatureType>
void Foam::SliceStreamRepo::remove
(
const std::shared_ptr<FeatureType>& featurePtr,
const Foam::string& id
)
{
auto featureMap = get(featurePtr);
if (featureMap->count(id) == 0)
{
featureMap->erase(id);
}
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::UListProxy
Description
A proxy of UList<T> 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<class T>
Foam::UListProxy<T>::UListProxy(UList<T> uList)
:
UList<T>(uList.data(), uList.size())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
void Foam::UListProxy<T>::writeFirstElement
(
Ostream& os,
const char* data
) const
{
if (data)
{
const T* dataT = reinterpret_cast<const T*>(data);
os << *dataT;
}
else
{
FatalErrorInFunction
<< "Given data pointer is nullptr."
<< abort(FatalError);
}
}
#if (OPENFOAM >= 2206)
template<class T>
const char* Foam::UListProxy<T>::cdata_bytes() const
{
return UList<T>::cdata_bytes();
}
template<class T>
char* Foam::UListProxy<T>::data_bytes()
{
return UList<T>::data_bytes();
}
template<class T>
std::streamsize Foam::UListProxy<T>::size_bytes() const
{
return UList<T>::size_bytes();
}
#else
template<class T>
const char* Foam::UListProxy<T>::cdata_bytes() const
{
return reinterpret_cast<const char*>(UList<T>::cdata());
}
template<class T>
char* Foam::UListProxy<T>::data_bytes()
{
return reinterpret_cast<char*>(UList<T>::data());
}
template<class T>
std::streamsize Foam::UListProxy<T>::size_bytes() const
{
return std::streamsize(UList<T>::size())*sizeof(T);
}
#endif
template<class T>
Foam::label Foam::UListProxy<T>::byteSize() const
{
return UList<T>::byteSize();
}
template<class T>
Foam::label Foam::UListProxy<T>::size() const
{
return UList<T>::size();
}
template<class T>
Foam::label Foam::UListProxy<T>::nComponents() const
{
return Foam::nComponentsOf<T>();
}
template<class T>
char* Foam::UListProxy<T>::data()
{
return reinterpret_cast<char*>(UList<T>::data());
}
template<class T>
const char* Foam::UListProxy<T>::cdata() const
{
return reinterpret_cast<const char*>(UList<T>::cdata());
}
template<class T>
Foam::uListProxyBase::uniformity
Foam::UListProxy<T>::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<T>::operator[](i) != UList<T>::operator[](0))
{
u = uListProxyBase::NONUNIFORM;
break;
}
}
return u;
}
else
{
return uListProxyBase::EMPTY;
}
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::UListProxy
Description
A proxy of UList<T> 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 T>
class UListProxy
:
public uListProxyBase,
public UList<T>
{
public:
// Constructors
//- Construct copying UList attributes such as data pointer and size.
UListProxy(UList<T> 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<T>() == 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
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
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
)
{};

View file

@ -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 <http://www.gnu.org/licenses/>.
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 <memory>
#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<typename DataType>
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

View file

@ -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 <http://www.gnu.org/licenses/>.
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 <memory>
#include <numeric>
#include "label.H"
#include "labelList.H"
#include "SliceBuffer.H"
namespace Foam
{
template<typename ForwardIterator>
void check_extent_of_range
(
ForwardIterator iter1,
ForwardIterator iter2,
label extent
)
{
if (std::distance(iter1, iter2)<extent)
{
FatalErrorIn
(
"check_extent_of_range: range does not satsify the required extent."
)
<< abort(FatalError);
}
}
// assumes mapping to be sorted by value (and accordingly sorted input)
template<typename ForwardIterator, typename OutputIterator>
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<typename DataType>
adios2::Variable<DataType>
inquire_define_variable
(
adios2::IO* io,
adios2::Variable<DataType>& variable,
const Foam::string blockId,
const adios2::Dims& shape,
const adios2::Dims& start,
const adios2::Dims& count
)
{
variable = io->InquireVariable<DataType>( blockId );
if ( !variable )
{
variable = io->DefineVariable<DataType>( blockId, shape, start, count );
}
return variable;
}
template<typename DataType>
class spanBuffer
:
public SliceBuffer
{
adios2::Dims shape_;
adios2::Dims start_;
adios2::Dims count_;
label serialization_;
adios2::Variable<DataType> variable_;
typename adios2::Variable<DataType>::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<typename DataType>
Foam::spanBuffer<DataType>::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<label>()
)
}
, variable_
{
inquire_define_variable
(
io,
variable_,
blockId,
shape_,
start_,
count_
)
}
, span_{ engine->Put( variable_ ) }
{}
template<typename DataType>
Foam::label Foam::spanBuffer<DataType>::size()
{
if (!variable_) { return 0; }
return variable_.Count()[0];
}
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
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 <memory>
#include <type_traits>
#include "label.H"
#include "labelList.H"
#include "SliceBuffer.H"
namespace Foam
{
template<typename VariableType, typename DataType>
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<typename VariableType, typename DataType>
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<typename VariableType, typename DataType>
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<count[0]; ++i)
{
span[i] = data[i];
}
}
template<typename DataType>
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<DataType> 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<typename DataType>
Foam::variableBuffer<DataType>::variableBuffer
(
adios2::IO* io,
adios2::Engine* engine,
const Foam::string blockId
)
{
variable_ = io->InquireVariable<DataType>(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<typename DataType>
Foam::variableBuffer<DataType>::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<DataType>(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<typename DataType>
Foam::variableBuffer<DataType>::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<DataType>(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<DataType>
(
blockId,
shape_,
start_,
count_
);
}
}
template<typename DataType>
Foam::label Foam::variableBuffer<DataType>::size()
{
Foam::label count = 0;
if (variable_)
{
count = variable_.Count()[0];
}
return count;
}
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
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<adios2::IO>
Foam::InputFeatures::createIO(adios2::ADIOS* const corePtr)
{
Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
std::shared_ptr<adios2::IO> ioPtr{nullptr};
repo->pull(ioPtr, "read");
if (!ioPtr)
{
ioPtr = std::make_shared<adios2::IO>(corePtr->DeclareIO("read"));
ioPtr->SetEngine("BP5");
repo->push(ioPtr, "read");
}
return ioPtr;
}
std::shared_ptr<adios2::Engine>
Foam::InputFeatures::createEngine
(
adios2::IO* const ioPtr,
const Foam::fileName& path
)
{
Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
std::shared_ptr<adios2::Engine> enginePtr{nullptr};
auto size = path.length();
repo->pull( enginePtr, "read"+path( size ) );
if ( !enginePtr )
{
enginePtr = std::make_shared<adios2::Engine>
(
ioPtr->Open( path, adios2::Mode::ReadRandomAccess )
);
repo->push( enginePtr, "read"+path( size ) );
}
return enginePtr;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
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<adios2::IO>
createIO( adios2::ADIOS* const ) override;
virtual std::shared_ptr<adios2::Engine>
createEngine( adios2::IO* const, const Foam::fileName& ) override;
};
}
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
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<adios2::IO>
Foam::OutputFeatures::createIO(adios2::ADIOS* const corePtr)
{
SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
std::shared_ptr<adios2::IO> ioPtr{nullptr};
repo->pull(ioPtr, "write");
if (!ioPtr)
{
ioPtr = std::make_shared<adios2::IO>(corePtr->DeclareIO("write"));
ioPtr->SetEngine("BP5");
repo->push(ioPtr, "write");
}
return ioPtr;
}
std::shared_ptr<adios2::Engine>
Foam::OutputFeatures::createEngine
(
adios2::IO* const ioPtr,
const Foam::fileName& path
)
{
SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
std::shared_ptr<adios2::Engine> enginePtr{nullptr};
auto size = path.length();
repo->pull(enginePtr, "write" + path(size));
if (!enginePtr)
{
enginePtr = std::make_shared<adios2::Engine>
(
ioPtr->Open(path, adios2::Mode::Append)
);
enginePtr->BeginStep();
repo->push(enginePtr, "write" + path(size));
}
return enginePtr;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::OutputFeatures
Description
Child of SliceFeatures implementing creation of output streaming resources.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
OutputFeatures.C
\*---------------------------------------------------------------------------*/
#ifndef OutputFeatures_H
#define OutputFeatures_H
#include "StreamFeatures.H"
namespace Foam
{
struct OutputFeatures
:
public StreamFeatures
{
virtual std::shared_ptr<adios2::IO>
createIO(adios2::ADIOS* const) override;
virtual std::shared_ptr<adios2::Engine>
createEngine(adios2::IO* const, const fileName&) override;
};
}
#endif

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceReading
Description
Client for input SliceStream creation via the abstract factory
SliceFeatures.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "SliceReading.H"
#include "InputFeatures.H"
#include "FileSliceStream.H"
std::unique_ptr<Foam::SliceStream>
Foam::SliceReading::createStream()
{
std::unique_ptr<Foam::StreamFeatures> file(new Foam::InputFeatures{});
return std::unique_ptr<Foam::FileSliceStream>
(
new Foam::FileSliceStream{file}
);
}

View file

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceReading
Description
Client for input SliceStream creation via the abstract factory
SliceFeatures.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
SliceReading.C
\*---------------------------------------------------------------------------*/
#ifndef SliceReading_H
#define SliceReading_H
#include "SliceStreamCreator.H"
namespace Foam
{
// Forward declaration
class SliceStream;
struct SliceReading
:
public SliceStreamCreator
{
virtual std::unique_ptr<SliceStream> createStream() override;
};
}
#endif

View file

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceStreamCreator
Description
Base client for SliceStream creation via the abstract factory
SliceFeatures.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#ifndef SliceStreamCreator_H
#define SliceStreamCreator_H
#include <memory>
namespace Foam
{
// Forward declaration
class SliceStream;
struct SliceStreamCreator
{
virtual ~SliceStreamCreator() = default;
virtual std::unique_ptr<SliceStream> createStream() = 0;
};
}
#endif

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceWriting
Description
Client for output SliceStream creation via the abstract factory
SliceFeatures.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "SliceWriting.H"
#include "OutputFeatures.H"
#include "FileSliceStream.H"
std::unique_ptr<Foam::SliceStream>
Foam::SliceWriting::createStream()
{
std::unique_ptr<Foam::StreamFeatures> file(new Foam::OutputFeatures{});
return std::unique_ptr<Foam::FileSliceStream>
(
new Foam::FileSliceStream{file}
);
}

View file

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceWriting
Description
Client for output SliceStream creation via the abstract factory
SliceFeatures.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
SliceWriting.C
\*---------------------------------------------------------------------------*/
#ifndef SliceWriting_H
#define SliceWriting_H
#include "SliceStreamCreator.H"
namespace Foam
{
// Forward declaration
class SliceStream;
struct SliceWriting
:
public SliceStreamCreator
{
virtual std::unique_ptr<SliceStream> createStream() override;
};
}
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceFeatures
Description
Abstract factory for creation of streaming resources for parallel I/O
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#ifndef StreamFeatures_H
#define StreamFeatures_H
#include <memory>
namespace adios2
{
class ADIOS;
class IO;
class Engine;
}
namespace Foam
{
// Forward declaration
class fileName;
struct StreamFeatures
{
virtual ~StreamFeatures() = default;
virtual std::shared_ptr<adios2::IO>
createIO(adios2::ADIOS* const) = 0;
virtual std::shared_ptr<adios2::Engine>
createEngine(adios2::IO* const, const fileName&) = 0;
};
}
#endif

View file

@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::fieldDataEntry
Description
Entry class to store field relevant data in a dictionary
Author
Sergey Lesnik, Wikki GmbH
\*---------------------------------------------------------------------------*/
#include "fieldDataEntry.H"
#include "ITstream.H"
static Foam::ITstream dummyITstream_("dummy", Foam::UList<Foam::token>());
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Capture the first element and save as a scalarList
static inline scalarList getFirstElement(const uListProxyBase* uListProxyPtr)
{
if (uListProxyPtr && uListProxyPtr->size())
{
// Could also return a SubList or UList
// Needs reworking for labels etc (should save char data)
const scalar* scalarData =
reinterpret_cast<const scalar*>(uListProxyPtr->cdata_bytes());
const label nCmpts = uListProxyPtr->nComponents();
scalarList list(nCmpts);
for (label i = 0; i < nCmpts; i++)
{
list[i] = scalarData[i];
}
return list;
}
return scalarList();
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldDataEntry::fieldDataEntry
(
const keyType& keyword,
const word& compoundTokenName,
uListProxyBase* uListProxyPtr
)
:
entry(keyword),
name_(),
compoundTokenName_(compoundTokenName),
uListProxyPtr_(uListProxyPtr),
nGlobalElems_(0),
tag_
(
uListProxyPtr->determineUniformity(),
getFirstElement(uListProxyPtr)
)
{}
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::fieldDataEntry::startLineNumber() const
{
return 0;
}
Foam::label Foam::fieldDataEntry::endLineNumber() const
{
return 0;
}
Foam::ITstream& Foam::fieldDataEntry::stream() const
{
FatalErrorInFunction
<< "Attempt to return field data entry " << keyword()
<< " as a primitive"
<< abort(FatalError);
return dummyITstream_;
}
const Foam::dictionary& Foam::fieldDataEntry::dict() const
{
FatalErrorInFunction
<< "Attempt to return primitive entry " << keyword()
<< " as a sub-dictionary"
<< abort(FatalError);
return dictionary::null;
}
Foam::dictionary& Foam::fieldDataEntry::dict()
{
FatalErrorInFunction
<< "Attempt to return primitive entry " << keyword()
<< " as a sub-dictionary"
<< abort(FatalError);
return const_cast<dictionary&>(dictionary::null);
}
void Foam::fieldDataEntry::write(Ostream& os) const
{
// dict uses "::" as a separator - replace it with the fileName standard "/"
fileName fn = name();
fn.replaceAll("::", "/");
os.writeKeyword(fn.name());
if (tag_.uniformityState() == uListProxyBase::UNIFORM)
{
os << "uniform" << token::SPACE;
// If EMPTY, data is nullptr. Thus, use the field tag to provide the
// first element.
uListProxyPtr_->writeFirstElement
(
os,
reinterpret_cast<const char*>(tag_.firstElement().cdata())
);
}
else
{
os << "nonuniform" << token::SPACE << compoundTokenName_
<< token::SPACE << nGlobalElems_ << fn;
}
os << token::END_STATEMENT << endl;
}
// ************************************************************************* //

View file

@ -0,0 +1,207 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::fieldDataEntry
Description
Entry class to store field relevant data in a dictionary
Author
Sergey Lesnik, Wikki GmbH
SourceFiles
fieldDataEntry.C
\*---------------------------------------------------------------------------*/
#ifndef fieldDataEntry_H
#define fieldDataEntry_H
#include "dictionary.H"
#include "fieldTag.H"
#include "uListProxyBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fieldDataEntry Declaration
\*---------------------------------------------------------------------------*/
class fieldDataEntry
:
public entry
{
// Private data
//- Entry name
fileName name_;
//- Name of the compound token associated with the data, i.e. List<...>
const word compoundTokenName_;
const autoPtr<uListProxyBase> uListProxyPtr_;
//- Number of elements summed over all ranks
label nGlobalElems_;
//- Field tag needed for global communication
fieldTag tag_;
public:
// Constructors
fieldDataEntry
(
const keyType& keyword,
const word& compoundTokenName,
uListProxyBase* uListProxyPtr
);
//- Construct on freestore as copy with reference to the
// dictionary the copy belongs to
virtual autoPtr<entry> clone(const dictionary&) const
{
return autoPtr<entry>(new fieldDataEntry(*this));
}
//-Destructor
virtual ~fieldDataEntry()
{}
// Member functions
//- Return the dictionary name
virtual const fileName& name() const
{
return name_;
}
//- Return the dictionary name
virtual fileName& name()
{
return name_;
}
//- Return line number of first token in dictionary
virtual label startLineNumber() const;
//- Return line number of last token in dictionary
virtual label endLineNumber() const;
//- Return true if this entry is a stream
virtual bool isStream() const
{
return false;
}
//- This entry is not a primitive,
// calling this function generates a FatalError
virtual ITstream& stream() const;
//- This entry is not a dictionary,
// calling this function generates a FatalError
virtual const dictionary& dict() const;
//- This entry is not a dictionary,
// calling this function generates a FatalError
virtual dictionary& dict();
//- Write
virtual void write(Ostream&) const;
// Access
//- Return number of bytes
inline const word& compoundTokenName() const
{
return compoundTokenName_;
}
inline fileName id() const
{
fileName id = name_;
id.replaceAll("::", "/");
return id;
}
inline bool uniform() const
{
if (tag_.uniformityState() == uListProxyBase::UNIFORM)
{
return true;
}
return false;
}
//- Set number of elements summed over all ranks
inline label& nGlobalElems()
{
return nGlobalElems_;
}
inline const fieldTag& tag() const
{
return tag_;
}
inline fieldTag& tag()
{
return tag_;
}
inline const uListProxyBase& uList() const
{
return uListProxyPtr_();
}
//- Return uniformity of the data list
inline uListProxyBase::uniformity uniformityState() const
{
return tag_.uniformityState();
}
//- Return access to the uniformity of the data list
inline uListProxyBase::uniformity& uniformityState()
{
return tag_.uniformityState();
}
};
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::fieldTag
Description
Tag class corresponds to a field and contains properties needed for the
decision on the global uniformity of the field
Author
Sergey Lesnik, Wikki GmbH
\*---------------------------------------------------------------------------*/
#include "fieldTag.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::List<Foam::fieldTag>
Foam::fieldTag::uniformityCompareOp
(
const List<fieldTag>& x,
const List<fieldTag>& y
)
{
List<fieldTag> res(x);
forAll(x, i)
{
if
(
x[i].uniformity_ == uListProxyBase::NONUNIFORM
|| y[i].uniformity_ == uListProxyBase::NONUNIFORM
)
{
res[i].uniformity_ = uListProxyBase::NONUNIFORM;
}
else if (x[i].uniformity_ == uListProxyBase::EMPTY)
{
res[i] = y[i];
}
else if
(
x[i].uniformity_ == uListProxyBase::UNIFORM
)
{
if (y[i].uniformity_ == uListProxyBase::UNIFORM)
{
if (x[i].firstElement_ != y[i].firstElement_)
{
res[i].uniformity_ = uListProxyBase::NONUNIFORM;
}
}
else if (y[i].uniformity_ == uListProxyBase::NONUNIFORM)
{
res[i].uniformity_ = uListProxyBase::NONUNIFORM;
}
}
}
return res;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fieldTag::fieldTag()
:
uniformity_(),
firstElement_()
{}
Foam::fieldTag::fieldTag(uListProxyBase::uniformity u, const scalarList& l)
:
uniformity_(u),
firstElement_(l)
{}
Foam::fieldTag::fieldTag(const fieldTag& t)
:
uniformity_(t.uniformity_),
firstElement_(t.firstElement_)
{}
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
bool Foam::fieldTag::operator==(const fieldTag& d) const
{
if (this->uniformity_ != d.uniformity_)
{
return false;
}
else if (this->firstElement_ != d.firstElement_)
{
return false;
}
return true;
}
bool Foam::fieldTag::operator!=(const fieldTag& d) const
{
return !operator==(d);
}
void Foam::fieldTag::operator=(const fieldTag& t)
{
this->uniformity_ = t.uniformity_;
this->firstElement_ = t.firstElement_;
}
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const fieldTag& d
)
{
os << d.firstElement() << d.uniformityState();
return os;
}
Foam::Istream& Foam::operator>>
(
Istream& is,
fieldTag& d
)
{
is >> d.firstElement();
label lfu;
is >> lfu;
d.uniformityState() = static_cast<uListProxyBase::uniformity>(lfu);
return is;
}

View file

@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::fieldTag
Description
Tag class corresponds to a field and contains properties needed for the
decision on the global uniformity of the field
Author
Sergey Lesnik, Wikki GmbH
SourceFiles
fieldTag.C
\*---------------------------------------------------------------------------*/
#ifndef fieldTag_H
#define fieldTag_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "uListProxyBase.H"
#include "scalarList.H"
namespace Foam
{
class fieldTag
{
// Private data
//- Uniformity property of the field
uListProxyBase::uniformity uniformity_;
//- First element of the field
scalarList firstElement_;
public:
// Constructors
fieldTag();
fieldTag(uListProxyBase::uniformity, const scalarList&);
fieldTag(const fieldTag&);
// Member functions
// Static Member Functions
//- Binary operator to be used by reduce function for detecting
// global uniformity
static List<fieldTag>
uniformityCompareOp
(
const List<fieldTag>& x,
const List<fieldTag>& y
);
// Access
inline const scalarList& firstElement() const
{
return firstElement_;
}
inline scalarList& firstElement()
{
return firstElement_;
}
inline uListProxyBase::uniformity uniformityState() const
{
return uniformity_;
}
inline uListProxyBase::uniformity& uniformityState()
{
return uniformity_;
}
// Required by List class
bool operator==(const fieldTag&) const;
bool operator!=(const fieldTag&) const;
void operator=(const fieldTag&);
};
// Required by Pstream
Ostream& operator<<
(
Ostream& os,
const fieldTag& d
);
Istream& operator>>
(
Istream& is,
fieldTag& d
);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::formattingEntry
Description
A dictionary entry writing only contents by default, used to save
formatting symbols for the final output
Author
Sergey Lesnik, Wikki GmbH
\*---------------------------------------------------------------------------*/
#include "formattingEntry.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::formattingEntry::write(Ostream& os) const
{
// os << "This is a formattingEntry\n";
primitiveEntry::write(os, true);
}
// ************************************************************************* //

View file

@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::formattingEntry
Description
A dictionary entry writing only contents by default, used to save
formatting symbols for the final output
Author
Sergey Lesnik, Wikki GmbH
SourceFiles
formattingEntry.C
\*---------------------------------------------------------------------------*/
#ifndef formattingEntry_H
#define formattingEntry_H
#include "primitiveEntry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class formattingEntry Declaration
\*---------------------------------------------------------------------------*/
class formattingEntry
:
public primitiveEntry
{
public:
// Constructors
//- Inherit all constructors from primitiveEntry
using primitiveEntry::primitiveEntry;
virtual autoPtr<entry> clone(const dictionary&) const
{
return autoPtr<entry>(new formattingEntry(*this));
}
// Member functions
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Description
A couple of type traits and compile time constructs required
in some paralle I/O functionalities. (Should probably go somewhere
else in production level, release code)
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#ifndef primitives_traits_H
#define primitives_traits_H
#include "scalar.H"
#include "direction.H"
#include <type_traits> // defines false_type, true_type, enable_if
#include <utility> // defines declval
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// VOID_T
// helper to ignore any number of template parameters
template<typename ...> using Void_T = void;
// IS_RANGE
// primary template
template<typename T, typename = Void_T<>>
struct is_range : std::false_type {};
//partial specialization, maybe SFINAE'd away
template<typename T>
struct is_range
<
T,
Void_T
<
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())
>
>
:
std::true_type
{};
// IS_VECTORSPACE
// primary template
template<typename, typename = Void_T<>>
struct is_vectorspace : std::false_type {};
// partial specialization, maybe SFINAE'd away
template<typename T>
struct is_vectorspace
<
T,
Void_T
<
decltype(std::declval<T>().size()),
decltype
(
std::declval<T>().component(std::declval<direction>())
),
decltype
(
std::declval<T>().replace
(
std::declval<direction>(),
std::declval<T>()[std::declval<direction>()]
)
),
decltype(std::declval<T>()[std::declval<direction>()]),
decltype(std::declval<T>().operator+=(std::declval<T>())),
decltype(std::declval<T>().operator-=(std::declval<T>())),
decltype(std::declval<T>().operator*=(std::declval<scalar>())),
decltype(std::declval<T>().operator/=(std::declval<scalar>()))
>
>
:
std::true_type
{};
// TODO: This should probably go somewhere else. Toward VectorSpace ecosystem?
template<typename T>
typename std::enable_if<is_vectorspace<T>::value, Foam::label>::type
nComponentsOf()
{
return T::nComponents;
}
// This is very generic
template<typename T>
typename std::enable_if<!is_vectorspace<T>::value, Foam::label>::type
nComponentsOf()
{
return 1;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "sliceReadPrimitives.H"
#include "SliceReading.H"
#include "SliceStream.H"
#include "foamString.H"
template<typename T>
void _implReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
T* buf,
const Foam::List<Foam::label>& start,
const Foam::List<Foam::label>& count
)
{
auto sliceStreamPtr = Foam::SliceReading{}.createStream();
sliceStreamPtr->access(type, pathname);
if (start.size()>0 && count.size()>0)
{
sliceStreamPtr->get(blockId, buf, start, count);
}
else
{
sliceStreamPtr->get(blockId, buf);
}
sliceStreamPtr->bufferSync();
}
void Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
Foam::scalar* buf,
const Foam::List<Foam::label>& start,
const Foam::List<Foam::label>& count
)
{
_implReadPrimitives(type, pathname, blockId, buf, start, count);
}
void Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
Foam::label* buf,
const Foam::List<Foam::label>& start,
const Foam::List<Foam::label>& count
)
{
_implReadPrimitives(type, pathname, blockId, buf, start, count);
}
void Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
char* buf,
const Foam::List<Foam::label>& start,
const Foam::List<Foam::label>& count
)
{
_implReadPrimitives(type, pathname, blockId, buf, start, count);
}
// ************************************************************************* //

View file

@ -0,0 +1,194 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
sliceReadPrimitives.C
\*---------------------------------------------------------------------------*/
#ifndef sliceReadPrimitives_H
#define sliceReadPrimitives_H
#include "List.H"
#include "label.H"
#include "scalar.H"
#include "primitives_traits.H"
#include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class string;
void sliceReadPrimitives
(
const string type,
const string pathname,
const string name,
scalar* buf,
const List<label>& start = {},
const List<label>& count = {}
);
void sliceReadPrimitives
(
const string type,
const string pathname,
const string name,
label* buf,
const List<label>& start = {},
const List<label>& count = {}
);
void sliceReadPrimitives
(
const string type,
const string pathname,
const string name,
char* buf,
const List<label>& start = {},
const List<label>& count = {}
);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<typename T>
typename std::enable_if<!Foam::is_vectorspace<T>::value, void>::type
Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
T* buf,
const Foam::List<Foam::label>& start = {},
const Foam::List<Foam::label>& count = {}
)
{
std::cout << "sliceReadPrimitives not implemented for this type.\n";
std::cout << typeid(buf).name() << "\n";
std::cout << name << "\n";
}
template<typename T>
typename std::enable_if<Foam::is_vectorspace<T>::value, void>::type
Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
T* buf,
const Foam::List<Foam::label>& start = {},
const Foam::List<Foam::label>& count = {}
)
{
auto startList = start;
auto countList = count;
if (start.size()>0 && count.size()>0)
{
startList = Foam::List<Foam::label>({start[0], 0});
countList = Foam::List<Foam::label>({count[0], buf[0].size()});
}
Foam::sliceReadPrimitives
(
type,
pathname,
name,
reinterpret_cast<scalar*>( buf ),
startList,
countList
);
}
// if T is arithmetic
template
<
typename T,
typename Integral
>
typename std::enable_if
<
std::is_integral<Integral>::value && std::is_arithmetic<T>::value,
void
>::type
Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
T* buf,
Integral start = -1,
Integral count = -1
)
{
Foam::List<Integral> startList{};
Foam::List<Integral> countList{};
if (start>-1 && count>-1)
{
startList = Foam::List<Foam::label>({start});
countList = Foam::List<Foam::label>({count});
}
Foam::sliceReadPrimitives(type, pathname, name, buf, startList, countList);
}
// if T is vector space
template
<
typename T,
typename Integral
>
typename std::enable_if
<
Foam::is_vectorspace<T>::value && std::is_integral<Integral>::value,
void
>::type
Foam::sliceReadPrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
T* buf,
Integral start = -1,
Integral count = -1
)
{
Foam::List<Integral> startList({start});
Foam::List<Integral> countList({count});
Foam::sliceReadPrimitives(type, pathname, name, buf, startList, countList);
}
#endif
// ************************************************************************* //

View file

@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "sliceWritePrimitives.H"
#include "SliceWriting.H"
#include "SliceStream.H"
#include "foamString.H"
#include "labelList.H"
template< typename T >
void _implWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::labelList& shape,
const Foam::labelList& start,
const Foam::labelList& count,
const T* buf
)
{
auto sliceStreamPtr = Foam::SliceWriting{}.createStream();
sliceStreamPtr->access( type, pathname );
sliceStreamPtr->put( blockId, shape, start, count, buf );
sliceStreamPtr->bufferSync();
}
//- Write local array
void Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::label count,
const Foam::scalar* buf
)
{
_implWritePrimitives
(
type,
pathname,
blockId,
{ count },
{ 0 },
{ count },
buf
);
}
//- Write local array
void Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::label count,
const Foam::label* buf
)
{
_implWritePrimitives
(
type,
pathname,
blockId,
{ count },
{ 0 },
{ count },
buf
);
}
//- Write global n-dimensional array
void Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::List<label> shape,
const Foam::List<label> start,
const Foam::List<label> count,
const Foam::scalar* buf
)
{
_implWritePrimitives
(
type,
pathname,
blockId,
shape,
start,
count,
buf
);
}
//- Write global array
void Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::label shape,
const Foam::label start,
const Foam::label count,
const Foam::scalar* buf
)
{
_implWritePrimitives
(
type,
pathname,
blockId,
{ shape },
{ start },
{ count },
buf
);
}
//- Write global array
void Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string blockId,
const Foam::label shape,
const Foam::label start,
const Foam::label count,
const Foam::label* buf
)
{
_implWritePrimitives
(
type,
pathname,
blockId,
{ shape },
{ start },
{ count },
buf
);
}
// ************************************************************************* //

View file

@ -0,0 +1,186 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
sliceWritePrimitives.C
\*---------------------------------------------------------------------------*/
#ifndef sliceWritePrimitives_H
#define sliceWritePrimitives_H
#include "label.H"
#include "scalar.H"
#include "primitives_traits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class string;
template<typename T> class List;
//- Write local array
void sliceWritePrimitives
(
const string type,
const string pathname,
const string blockId,
const label count,
const scalar* buf
);
//- Write local array
void sliceWritePrimitives
(
const string type,
const string pathname,
const string blockId,
const label count,
const label* buf
);
//- Write global n-dimensional array
void sliceWritePrimitives
(
const string type,
const string pathname,
const string blockId,
const List<label> shape,
const List<label> start,
const List<label> count,
const scalar* buf
);
//- Write global array
void sliceWritePrimitives
(
const string type,
const string pathname,
const string blockId,
const label shape,
const label start,
const label count,
const scalar* buf
);
//- Write global array
void sliceWritePrimitives
(
const string type,
const string pathname,
const string blockId,
const label shape,
const label start,
const label count,
const label* buf
);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<typename T>
typename std::enable_if<!Foam::is_vectorspace<T>::value, void>::type
Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
const Foam::label count,
const T* buf
)
{
std::cout << "sliceWritePrimitives not implemented for this type.\n";
std::cout << typeid(buf).name() << "\n";
std::cout << name << "\n";
}
//- Write local array
template<typename T>
typename std::enable_if<Foam::is_vectorspace<T>::value, void>::type
Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
const Foam::label count,
const T* buf
)
{
Foam::List<Foam::label> shapeList({count, buf[0].size()});
Foam::List<Foam::label> startList({0, 0});
Foam::List<Foam::label> countList{shapeList};
sliceWritePrimitives
(
type,
pathname,
name,
shapeList,
startList,
countList,
reinterpret_cast<const Foam::scalar*>( buf )
);
}
//- Write global array
template<typename T>
typename std::enable_if<Foam::is_vectorspace<T>::value, void>::type
Foam::sliceWritePrimitives
(
const Foam::string type,
const Foam::string pathname,
const Foam::string name,
const Foam::label shape,
const Foam::label start,
const Foam::label count,
const T* buf
)
{
Foam::List<Foam::label> shapeList({shape, buf[0].size()});
Foam::List<Foam::label> startList({start, 0});
Foam::List<Foam::label> countList({count, buf[0].size()});
sliceWritePrimitives
(
type,
pathname,
name,
shapeList,
startList,
countList,
reinterpret_cast<const Foam::scalar*>( buf )
);
}
#endif
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::uListProxyBase
Description
Interface to UList<T> abstracting type T.
Author
Sergey Lesnik, Wikki GmbH
SourceFiles
uListProxyBase.C
\*---------------------------------------------------------------------------*/
#ifndef uListProxyBase_H
#define uListProxyBase_H
#include "label.H"
#include "scalar.H"
#include <ios> // std::streamsize
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class Ostream;
/*---------------------------------------------------------------------------*\
Class uListProxyBase Declaration
\*---------------------------------------------------------------------------*/
class uListProxyBase
{
public:
// Public types
enum uniformity
{
EMPTY,
UNIFORM,
NONUNIFORM
};
// Constructors
//- Default construct
uListProxyBase()
{}
//- Destructor
virtual ~uListProxyBase()
{}
// Member Functions
//- Write the first element of UList.
virtual void writeFirstElement(Ostream&, const char*) const = 0;
// 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 = 0;
//- 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() = 0;
//- Number of contiguous bytes for the List data.
// \note Only meaningful for contiguous data
virtual inline std::streamsize size_bytes() const = 0;
// Access
//- Return the binary size in number of characters of the UList
// if the element is a primitive type
// i.e. contiguous<T>() == true
virtual label byteSize() const = 0;
//- Return the number of elements in the UList.
virtual label size() const = 0;
//- Return the number of components per element.
virtual label nComponents() const = 0;
//- Return a pointer to the data casted to char from the actual
// data type.
virtual inline char* data() = 0;
//- Return a const pointer to the first data element casted to char.
virtual inline const char* cdata() const = 0;
//- Determine whether the underlying list is UNIFORM, NONUNIFORM or
// EMPTY.
virtual uniformity determineUniformity() const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,3 @@
#include "DimensionedField.H"
defineTypeNameAndDebug(Foam::DebugIODimensionedFieldName, 0);

View file

@ -0,0 +1,3 @@
#include "Field.H"
defineTypeNameAndDebug(Foam::DebugIOFieldName, 0);

View file

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::DataComponent
Description
Foam::DataComponent
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "DataComponent.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::DataComponent::DataComponent
(
const Foam::string type,
const Foam::string name,
Foam::DataComponent* const parent_component
)
:
type_{type},
name_{name},
parent_component_{parent_component}
{}
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
Foam::string
Foam::DataComponent::parent_name() const
{
return parent_component_ ? parent_component_->name() : Foam::string{};
}
Foam::string
Foam::DataComponent::name() const
{
return name_;
}
Foam::string
Foam::DataComponent::type() const
{
return type_;
}
Foam::DataComponentPtr
Foam::DataComponent::add(const Foam::DataComponentPtr& component)
{
_v_add_(component);
return component;
}
void Foam::DataComponent::initialize()
{
_v_initialize_();
}
Foam::DataComponentPtr
Foam::DataComponent::node(const Foam::string& by_name)
{
Foam::DataComponentPtr ret{nullptr};
if (by_name.compare("") == 0)
{
return ret;
}
pull_node(by_name, ret);
return ret;
}
void Foam::DataComponent::pull_node
(
const Foam::string& by_name,
Foam::DataComponentPtr& output
)
{
_v_pull_node_(by_name, output);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// if parent is the head node,
// parent_component will be set to this
Foam::DataComponent*
Foam::DataComponent::parent_component_of
(
const Foam::DataComponentPtr& component
)
{
Foam::DataComponent* parent_component = node
(
component->parent_name()
).get();
return !parent_component ? this : parent_component;
}
// ************************************************************************* //

View file

@ -0,0 +1,182 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::DataComponent
Description
Foam::DataComponent
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
DataComponent.C
DataComponentI.H
\*---------------------------------------------------------------------------*/
#ifndef DataComponent_H
#define DataComponent_H
#include "labelList.H"
#include "scalarField.H"
#include "vectorField.H"
#include "Offsets.H"
#include "Slice.H"
#include "InitStrategies.H"
#include <memory>
#include <map>
namespace Foam
{
// Forward declarations
struct DataComponent;
class IndexComponent;
using DataComponentPtr = std::shared_ptr<DataComponent>;
// used as strategy in construction of components and decorators
using OffsetStrategy = std::function<Foam::label(const DataComponent&)>;
struct DataComponent
{
// used as data container for IndexComponent
using index_container = labelList;
using index_iterator = index_container::iterator;
using index_citerator = index_container::const_iterator;
using base_raw_ptr = DataComponent*;
using base_ptr = std::shared_ptr<DataComponent>;
DataComponent() = default;
DataComponent
(
const Foam::string type,
const Foam::string name,
base_raw_ptr const parent_component = nullptr
);
DataComponent(const DataComponent& other) = default;
DataComponent(DataComponent&& other) = default;
DataComponent& operator=(const DataComponent& other) = default;
DataComponent& operator=(DataComponent&& other) = default;
virtual ~DataComponent() = default;
Foam::string parent_name() const;
Foam::string name() const;
Foam::string type() const;
base_ptr add(const base_ptr& component);
void initialize();
base_ptr node(const Foam::string& by_name);
void pull_node(const Foam::string& by_name, base_ptr& output);
template<typename ComponentType = IndexComponent>
base_ptr add
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
OffsetStrategy calc_start = nullptr,
OffsetStrategy calc_count = nullptr
);
template<typename DecoratorType, typename... Args>
base_ptr decorate(const Foam::string name, Args... args);
template<class DataType>
void extract(DataType& output);
virtual label accept(const OffsetStrategy& offset_strategy) const
{
return !offset_strategy ? -1 : offset_strategy(*this);
}
virtual index_citerator begin() const { return index_container{}.begin(); }
virtual index_citerator end() const { return index_container{}.end(); }
virtual label front() const { return {}; }
virtual label back() const { return {}; }
virtual label size() const { return {}; }
private:
Foam::string type_{};
Foam::string name_{};
virtual void _v_add_(base_ptr) = 0;
virtual void _v_initialize_() = 0;
virtual void
_v_pull_node_(const Foam::string& by_name, base_ptr& output) = 0;
virtual void _v_extract_(index_container& output) {}
virtual void _v_extract_(std::vector<label>& output) {}
virtual void _v_extract_(Foam::scalarField& output) {}
virtual void _v_extract_(Foam::vectorField& output) {}
virtual void _v_extract_(Foam::Offsets& output) {}
virtual void _v_extract_(Foam::Slice& output) {}
protected:
DataComponent* parent_component_{nullptr};
base_raw_ptr parent_component_of(const base_ptr& component);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
#include "DataComponentI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::DataComponentFree
Description
Free functions for composite pattern of DataComponent
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "DataComponentFree.H"
#include "DataComponent.H"
bool Foam::head_of_composition(const Foam::DataComponent& component)
{
return component.type().empty() || component.name().empty();
}
// ************************************************************************* //

View file

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::DataComponentFree
Description
Free functions for composite pattern of DataComponent
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
DataComponentFree.C
\*---------------------------------------------------------------------------*/
#ifndef DataComponentFree_H
#define DataComponentFree_H
#include "DataComponent.H"
namespace Foam
{
// Forward declarations
class DataComponent;
class InitStrategy;
bool head_of_composition(const DataComponent& component);
} // End namespace Foam
#endif

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::DataComponent
Description
Foam::DataComponent
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<typename ComponentType = Foam::IndexComponent>
Foam::DataComponentPtr Foam::DataComponent::add
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
Foam::OffsetStrategy calc_start,
Foam::OffsetStrategy calc_count
)
{
auto component = std::make_shared<ComponentType>
(
type,
name,
std::move(init_strategy),
calc_start,
calc_count,
this
);
_v_add_(component);
return component;
}
template<typename DecoratorType, typename... Args>
Foam::DataComponentPtr
Foam::DataComponent::decorate(const Foam::string name, Args... args)
{
DataComponentPtr component = node(name);
auto parent_component = parent_component_of(component);
component = std::make_shared<DecoratorType>
(
std::move(component),
parent_component,
args...
);
parent_component->add(component);
return component;
}
template<class DataType>
void Foam::DataComponent::extract(DataType& output)
{
_v_extract_(output);
};
// ************************************************************************* //

View file

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::FieldComponent
Description
Foam::FieldComponent
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
FieldComponentI.H
\*---------------------------------------------------------------------------*/
#ifndef FieldComponent_H
#define FieldComponent_H
#include "DataComponent.H"
#include "InitStrategies.H"
namespace Foam
{
template<typename FieldType>
class FieldComponent
:
public DataComponent
{
FieldType data_;
std::unique_ptr<InitStrategy> init_strategy_{nullptr};
OffsetStrategy calc_start_{nullptr};
OffsetStrategy calc_count_{nullptr};
bool initialized_{false};
// Core initialization for field component
void init();
// Adding and pulling components render redundant
// because a field component acts as leaf component.
// Hence, they are only dummy functions of the pure
// virtual functions from base.
void _v_add_(base_ptr input) final {}
void _v_pull_node_(const Foam::string& by_name, base_ptr& output) final {}
// Initialize this field component
void _v_initialize_() final;
// Method to retrieve field data_
// TODO: could/should be replaced by iterator pattern and
// corresponding free functions with std::copy
void _v_extract_(FieldType& output) final;
public:
FieldComponent
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
OffsetStrategy calc_start = nullptr,
OffsetStrategy calc_count = nullptr,
base_raw_ptr const parent_component = nullptr
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "FieldComponentI.H"
#endif
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::FieldComponent
Description
Foam::FieldComponent
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<typename FieldType>
Foam::FieldComponent<FieldType>::FieldComponent
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
Foam::OffsetStrategy calc_start,
Foam::OffsetStrategy calc_count,
Foam::DataComponent* const parent_component
)
:
Foam::DataComponent(type, name, parent_component),
data_{},
init_strategy_{std::move(init_strategy)},
calc_start_{calc_start},
calc_count_{calc_count},
initialized_{false}
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<typename FieldType>
void Foam::FieldComponent<FieldType>::init()
{
// FieldComponent (as leaf) must be attached to a IndexComponent (as node)
auto parent = parent_component_;
Foam::InitStrategy::labelPair start_count
(
parent->accept(calc_start_),
parent->accept(calc_count_)
);
init_strategy_->operator()(data_, start_count);
initialized_ = true;
}
template<typename FieldType>
void Foam::FieldComponent<FieldType>::_v_initialize_()
{
if (!initialized_)
{
init();
}
}
template<typename FieldType>
void Foam::FieldComponent<FieldType>::_v_extract_(FieldType& output)
{
output = std::move(data_);
data_.clear();
initialized_ = false;
}
// ************************************************************************* //

View file

@ -0,0 +1,214 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::IndexComponent
Description
Foam::IndexComponent
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "IndexComponent.H"
#include "DataComponentFree.H"
#include <utility>
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::IndexComponent::IndexComponent
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
Foam::OffsetStrategy calc_start,
Foam::OffsetStrategy calc_count,
Foam::DataComponent* const parent_component
)
:
DataComponent(type, name, parent_component),
components_map_{},
data_{},
init_strategy_{std::move(init_strategy)},
calc_start_{calc_start},
calc_count_{calc_count},
initialized_{false}
{}
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
Foam::label
Foam::IndexComponent::accept(const Foam::OffsetStrategy& offset_strategy) const
{
return !offset_strategy ? -1 : offset_strategy(*this);
}
Foam::DataComponent::index_citerator
Foam::IndexComponent::begin() const
{
return data_.begin();
}
Foam::DataComponent::index_citerator
Foam::IndexComponent::end() const
{
return data_.end();
}
Foam::label
Foam::IndexComponent::front() const
{
return *data_.begin();
}
Foam::label
Foam::IndexComponent::back() const
{
return *data_.rbegin();
}
Foam::label
Foam::IndexComponent::size() const
{
return data_.size();
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::IndexComponent::init()
{
auto parent = !parent_component_ ? this : parent_component_;
Foam::InitStrategy::labelPair start_count
(
parent->accept(calc_start_),
parent->accept(calc_count_)
);
init_strategy_->operator()(data_, start_count);
initialized_ = true;
}
void Foam::IndexComponent::init_children()
{
using std::begin;
using std::end;
std::for_each
(
begin(components_map_),
end(components_map_),
[]
(
const std::pair
<
std::string,
Foam::DataComponent::base_ptr
>& named_component
)
{
named_component.second->initialize();
}
);
}
void Foam::IndexComponent::_v_add_(base_ptr input)
{
auto name_of_input = input->name();
if (components_map_.count(name_of_input) == 1)
{
components_map_[name_of_input] = input;
}
else
{
components_map_.emplace(std::make_pair(name_of_input, input));
}
}
void Foam::IndexComponent::_v_initialize_()
{
if (!initialized_ && !head_of_composition(*this))
{
init();
}
init_children();
}
void Foam::IndexComponent::_v_pull_node_
(
const Foam::string& by_name,
base_ptr& output
)
{
if (output) { return; }
auto pulled_component = components_map_.find(by_name);
if (pulled_component != components_map_.end())
{
output = pulled_component->second;
return;
}
for (const auto& named_component: components_map_)
{
named_component.second->pull_node(by_name, output);
}
}
void
Foam::IndexComponent::_v_extract_(Foam::DataComponent::index_container& output)
{
output = std::move(data_);
data_.clear();
initialized_ = false;
}
void Foam::IndexComponent::_v_extract_(std::vector<label>& output)
{
output.resize(data_.size());
std::move(data_.begin(), data_.end(), output.begin());
data_.clear();
initialized_ = false;
}
void Foam::IndexComponent::_v_extract_(Foam::Offsets& output)
{
if (type() != "offsets") { return; }
if (!initialized_) { return; }
output = init_strategy_->offsets();
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::IndexComponent
Description
Foam::IndexComponent
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
IndexComponent.C
\*---------------------------------------------------------------------------*/
#ifndef IndexComponent_H
#define IndexComponent_H
#include "DataComponent.H"
#include "InitStrategies.H"
namespace Foam
{
class IndexComponent
:
public DataComponent
{
std::map<std::string, base_ptr> components_map_{};
index_container data_{};
std::unique_ptr<InitStrategy> init_strategy_{nullptr};
OffsetStrategy calc_start_{nullptr};
OffsetStrategy calc_count_{nullptr};
bool initialized_{false};
// Core initialization for this index component
// with given initialization strategy:
// 1) data from ADIOS or
// 2) or offsets based on parent
void init();
// Core initialization for children
void init_children();
// Adds a component into component_map_
void _v_add_(base_ptr input) final;
// Initialize this index component and
// its children in components_map_
void _v_initialize_() final;
// Search for node by name and copy it to the output pointer
void _v_pull_node_(const Foam::string& by_name, base_ptr& output) final;
// Different methods to retrieve data_
// TODO: could/should be replaced by iterator pattern and
// corresponding free functions with std::copy
void _v_extract_(index_container& output) final;
void _v_extract_(std::vector<label>& output) final;
void _v_extract_(Foam::Offsets& output) final;
public:
IndexComponent() = default;
IndexComponent
(
const Foam::string type,
const Foam::string name,
std::unique_ptr<InitStrategy> init_strategy,
OffsetStrategy calc_start = nullptr,
OffsetStrategy calc_count = nullptr,
base_raw_ptr const parent_component = nullptr
);
// Key feature to determine coherents between a
// component and its parent:
//
// Takes a function to calculate an offset integer.
// This is used by an index component to determine
// its offsets by the data of its parent component.
label accept(const OffsetStrategy& offset_strategy) const final;
// Returning begin iterator to internal data_
index_citerator begin() const final;
// Returning end iterator to internal data_
index_citerator end() const final;
// Returns the first value
// contained in data_
label front() const final;
// Returns the last value
// contained in data_
label back() const final;
// Returns the size of data_
label size() const final;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::ComponentDecorator
Description
Foam::ComponentDecorator
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#ifndef ComponentDecorator_H
#define ComponentDecorator_H
#include "DataComponent.H"
namespace Foam
{
struct ComponentDecorator
:
public DataComponent
{
ComponentDecorator
(
DataComponentPtr&& component,
base_raw_ptr const parent_component
)
:
DataComponent{component->type(), component->name(), parent_component},
component_{std::move(component)}
{}
protected:
DataComponentPtr component_{nullptr};
private:
void _v_add_(base_ptr input) final
{
component_->add(input);
}
virtual void _v_pull_node_
(
const Foam::string& by_name,
base_ptr& output
)
{
output = component_->node(by_name);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
}// End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::OffsetDecorator
Description
Foam::OffsetDecorator
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#ifndef OffsetDecorator_H
#define OffsetDecorator_H
#include "ComponentDecorator.H"
namespace Foam
{
// Only for IndexComponents
class OffsetDecorator
:
public ComponentDecorator
{
Foam::Offsets offsets_{};
OffsetStrategy offset_strategy_{nullptr};
bool accumulate_{false};
bool initialized_{false};
void _v_extract_(Foam::Offsets& output) final
{
output = offsets_;
}
void _v_extract_(index_container& output) final
{
component_->extract(output);
}
void _v_initialize_() final
{
component_->initialize();
if (!initialized_)
{
offsets_.set(offset_strategy_(*component_.get()), accumulate_);
initialized_ = true;
}
}
public:
OffsetDecorator
(
DataComponentPtr&& component,
base_raw_ptr const parent_component,
OffsetStrategy offset_strategy,
bool accumulate = false
)
:
ComponentDecorator{std::move(component), parent_component},
offsets_{},
offset_strategy_{offset_strategy},
accumulate_{accumulate},
initialized_{false}
{}
label accept(const OffsetStrategy& determine_offset) const final
{
if (!determine_offset)
{
return {};
}
return determine_offset(*this);
}
label front() const final
{
return offsets_.front();
}
label back() const final
{
return offsets_.back();
}
label size() const final
{
return offsets_.size();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceDecorator
Description
Foam::SliceDecorator
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "SliceDecorator.H"
#include "Offsets.H"
#include "Slice.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::SliceDecorator::_v_initialize_()
{
component_->initialize();
if (!initialized_)
{
Foam::Offsets offsets{};
component_->extract(offsets);
slice_ = Foam::Slice{Pstream::myProcNo(), offsets};
initialized_ = true;
}
}
void Foam::SliceDecorator::_v_extract_(Foam::Slice& output)
{
output = slice_;
}
void Foam::SliceDecorator::_v_extract_(Foam::Offsets& output)
{
component_->extract(output);
}
void
Foam::SliceDecorator::_v_extract_(Foam::DataComponent::index_container& output)
{
component_->extract(output);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::SliceDecorator::SliceDecorator
(
Foam::DataComponentPtr&& component,
Foam::DataComponent* const parent_component
)
:
ComponentDecorator{std::move(component), parent_component},
slice_{},
initialized_{false}
{}
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
Foam::DataComponent::index_citerator
Foam::SliceDecorator::begin() const
{
return component_->begin();
}
Foam::DataComponent::index_citerator
Foam::SliceDecorator::end() const
{
return component_->end();
}
Foam::label
Foam::SliceDecorator::front() const
{
return component_->front();
}
Foam::label
Foam::SliceDecorator::back() const
{
return component_->back();
}
Foam::label
Foam::SliceDecorator::size() const
{
return component_->size();
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::SliceDecorator
Description
Foam::SliceDecorator
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
SliceDecorator.C
\*---------------------------------------------------------------------------*/
#ifndef SliceDecorator_H
#define SliceDecorator_H
#include "ComponentDecorator.H"
namespace Foam
{
// Only for IndexComponents decorated by OffsetDecorator
class SliceDecorator
:
public ComponentDecorator
{
Foam::Slice slice_{};
bool initialized_{false};
void _v_initialize_() final;
void _v_extract_(Foam::Slice& output) final;
void _v_extract_(Foam::Offsets& output) final;
void _v_extract_(index_container& output) final;
public:
SliceDecorator
(
DataComponentPtr&& component,
base_raw_ptr const parent_component
);
index_citerator begin() const final;
index_citerator end() const final;
label front() const final;
label back() const final;
label size() const final;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Class
Foam::InitStrategies
Description
Foam::InitStrategies
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "InitStrategies.H"
#include "SliceStream.H"
void Foam::InitOffsets::execute
(
Foam::InitStrategy::index_container& data,
Foam::InitStrategy::labelPair& start_count
)
{
auto value = !accumulate_ ?
start_count.first :
start_count.second;
offsets_.set(value, accumulate_);
data = Foam::labelList
(
{
offsets_.lowerBound(Pstream::myProcNo()),
offsets_.upperBound(Pstream::myProcNo())
}
);
}
// ************************************************************************* //

View file

@ -0,0 +1,282 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::InitStrategies
Description
Foam::InitStrategies
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
InitStrategies.C
\*---------------------------------------------------------------------------*/
#ifndef InitStrategies_H
#define InitStrategies_H
#include "Offsets.H"
#include "SliceStream.H"
#include "sliceReadPrimitives.H"
#include "labelList.H"
#include "scalarField.H"
#include "vectorField.H"
#include <utility>
namespace Foam
{
struct InitStrategy
{
virtual ~InitStrategy() = default;
using index_container = labelList;
using labelPair = std::pair<Foam::label, Foam::label>;
template<typename Container>
void operator()(Container& data, labelPair& start_count)
{
execute(data, start_count);
}
virtual Foam::Offsets offsets() { return {}; }
private:
virtual void execute(index_container& data, labelPair& start_count) {}
virtual void execute(Foam::scalarField& data, labelPair& start_count) {}
virtual void execute(Foam::vectorField& data, labelPair& start_count) {}
};
template<typename FieldType = InitStrategy::index_container>
struct InitFromADIOS
:
public InitStrategy
{
InitFromADIOS() = default;
explicit InitFromADIOS
(
const Foam::string& type,
const Foam::string& pathname,
const Foam::string& name
)
:
type_{type},
pathname_{pathname},
name_{name}
{}
label size() const
{
auto sliceStreamPtr = SliceReading{}.createStream();
sliceStreamPtr->access(type_, pathname_);
FieldType dummy{};
return sliceStreamPtr->getBufferSize(name_, dummy.data());
}
explicit operator bool() const
{
return this->size();
}
private:
void execute
(
FieldType& data,
Foam::InitStrategy::labelPair& start_count
) final
{
auto start = (start_count.first != -1) ?
labelList({start_count.first}) :
labelList({});
auto count = (start_count.second != -1) ?
labelList({start_count.second}) :
labelList({});
Foam::sliceReadToContainer
(
type_,
pathname_,
name_,
data,
start,
count
);
}
Foam::string type_{};
Foam::string pathname_{};
Foam::string name_{};
};
struct InitOffsets
:
public InitStrategy
{
InitOffsets() = default;
explicit InitOffsets(const bool accumulate) : accumulate_{accumulate} {}
Foam::Offsets offsets() { return offsets_; }
private:
void execute(index_container&, labelPair&) final;
Foam::Offsets offsets_{};
bool accumulate_{};
};
template<typename FieldType = InitStrategy::index_container>
struct InitPrimitivesFromADIOS
:
public InitStrategy
{
InitPrimitivesFromADIOS() = default;
explicit InitPrimitivesFromADIOS
(
const Foam::string& type,
const Foam::string& pathname,
const Foam::string& name
)
:
type_{type},
pathname_{pathname},
name_{name}
{}
private:
void execute
(
FieldType& data,
Foam::InitStrategy::labelPair& start_count
) final
{
auto start = (start_count.first != -1) ?
labelList({start_count.first}) :
labelList({});
auto count = (start_count.second != -1) ?
labelList({start_count.second}) :
labelList({});
data.resize(count[0]);
Foam::sliceReadPrimitives
(
type_,
pathname_,
name_,
data.data(),
start,
count
);
}
Foam::string type_{};
Foam::string pathname_{};
Foam::string name_{};
};
template<typename FieldType = InitStrategy::index_container>
struct NaivePartitioningFromADIOS
:
public InitStrategy
{
NaivePartitioningFromADIOS() = default;
explicit NaivePartitioningFromADIOS
(
const Foam::string& type,
const Foam::string& pathname,
const Foam::string& name
)
:
type_{type},
pathname_{pathname},
name_{name}
{}
private:
void execute
(
FieldType& data,
Foam::InitStrategy::labelPair& start_count
) final
{
auto sliceStreamPtr = SliceReading{}.createStream();
sliceStreamPtr->access(type_, pathname_);
// Naive partitioning based on total size of input data
label total_size = sliceStreamPtr->getBufferSize(name_, data.data());
total_size--;
label partition_size = total_size / Pstream::nProcs();
labelList start(1, partition_size * Pstream::myProcNo());
labelList count = (Pstream::myProcNo() == Pstream::nProcs()-1) ?
labelList({total_size - start[0]}) :
labelList({partition_size});
count[0] += 1;
data.resize(count[0]);
sliceStreamPtr->get(name_, data, start, count);
sliceStreamPtr->bufferSync();
}
Foam::string type_{};
Foam::string pathname_{};
Foam::string name_{};
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::OffsetStrategies
Description
Foam::OffsetStrategies
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "OffsetStrategies.H"
#include "DataComponent.H"
#include <iterator>
Foam::label Foam::count_geq::operator()(const Foam::DataComponent& input)
{
using std::begin;
using std::end;
using value_type = decltype(*begin(input));
return std::count_if
(
begin(input),
end(input),
[this](const value_type& val)
{
return val>=value_;
}
);
}
Foam::label Foam::count_eq::operator()(const Foam::DataComponent& input)
{
using std::begin;
using std::end;
using value_type = decltype(*begin(input));
return std::count_if
(
begin(input),
end(input),
[this](const value_type& val)
{
return val == value_;
}
);
}
Foam::label
Foam::offset_by_max_plus_one(const Foam::DataComponent& input)
{
return *std::max_element(input.begin(), input.end()) + 1;
}
Foam::label
Foam::offset_by_size_minus_one(const Foam::DataComponent& input)
{
return input.size() - 1;
}
Foam::label
Foam::start_from_myProcNo(const Foam::DataComponent& dummy)
{
return Pstream::myProcNo();
}
Foam::label
Foam::count_two(const Foam::DataComponent& dummy)
{
return 2;
}
Foam::label
Foam::start_from_front(const Foam::DataComponent& input)
{
return input.front();
}
Foam::label
Foam::count_from_front(const Foam::DataComponent& input)
{
return input.back() - input.front();
}
Foam::label
Foam::count_from_size(const Foam::DataComponent& input)
{
return input.size();
}
Foam::label
Foam::count_from_front_plus_one(const Foam::DataComponent& input)
{
return count_from_front(input) + 1;
}
Foam::label
Foam::start_from_max(const Foam::DataComponent& input)
{
Foam::Offsets offsets(*std::max_element(input.begin(), input.end()) + 1);
return offsets.lowerBound(Pstream::myProcNo());
}
Foam::label
Foam::count_from_max(const Foam::DataComponent& input)
{
Foam::Offsets offsets(*std::max_element(input.begin(), input.end()) + 1);
return offsets.count(Pstream::myProcNo());
}
// ************************************************************************* //

View file

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::OffsetStrategies
Description
Foam::OffsetStrategies
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
OffsetStrategies.C
\*---------------------------------------------------------------------------*/
#ifndef OffsetStrategies_H
#define OffsetStrategies_H
#include "DataComponent.H"
#include <algorithm>
namespace Foam
{
struct count_geq
{
explicit count_geq(const label value) : value_{value} {}
label operator()(const DataComponent&);
private:
label value_{};
};
struct count_eq
{
explicit count_eq(const label value) : value_{value} {}
label operator()(const DataComponent&);
private:
label value_{};
};
label offset_by_max_plus_one(const DataComponent&);
label offset_by_size_minus_one(const DataComponent&);
label start_from_myProcNo(const DataComponent&);
label count_two(const DataComponent&);
label start_from_front(const DataComponent&);
label count_from_front(const DataComponent&);
label count_from_size(const DataComponent&);
label count_from_front_plus_one(const DataComponent&);
label start_from_max(const DataComponent&);
label count_from_max(const DataComponent&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,838 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::CoherentMesh
Description
Foam::CoherentMesh
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "CoherentMesh.H"
#include "sliceMeshHelper.H"
#include "nonblockConsensus.H"
#include "processorPolyPatch.H"
#include "DataComponent.H"
#include "OffsetStrategies.H"
#include "FieldComponent.H"
#include "SliceDecorator.H"
#include <numeric>
#include <cmath>
#include <functional> // std::bind, std::placeholders
#include <chrono>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::CoherentMesh, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::CoherentMesh::readMesh(const fileName& pathname)
{
using InitStrategyPtr = std::unique_ptr<InitStrategy>;
using InitIndexComp = InitFromADIOS<labelList>;
using PartitionIndexComp = NaivePartitioningFromADIOS<labelList>;
IndexComponent coherenceTree{};
if (Pstream::parRun())
{
std::unique_ptr<InitIndexComp> init_partitionStarts
(
new InitIndexComp("mesh", pathname, "partitionStarts")
);
if (init_partitionStarts->size() == Pstream::nProcs()+1)
{
coherenceTree.add
(
"mesh",
"partitionStarts",
std::move(init_partitionStarts),
Foam::start_from_myProcNo,
Foam::count_two
);
InitStrategyPtr init_ownerStarts
(
new InitIndexComp("mesh", pathname, "ownerStarts")
);
coherenceTree.node("partitionStarts")->add
(
"mesh",
"ownerStarts",
std::move(init_ownerStarts),
Foam::start_from_front,
Foam::count_from_front_plus_one
);
}
else
{
InitStrategyPtr init_ownerStarts
(
new PartitionIndexComp("mesh", pathname, "ownerStarts")
);
coherenceTree.add("mesh", "ownerStarts", std::move(init_ownerStarts));
}
}
else
{
InitStrategyPtr init_ownerStarts
(
new InitIndexComp("mesh", pathname, "ownerStarts")
);
coherenceTree.add("mesh", "ownerStarts", std::move(init_ownerStarts));
}
InitStrategyPtr init_cellOffsets(new InitOffsets(true));
coherenceTree.node("ownerStarts")->add
(
"offsets",
"cellOffsets",
std::move(init_cellOffsets),
nullptr,
Foam::offset_by_size_minus_one
);
coherenceTree.decorate<Foam::SliceDecorator>("cellOffsets");
InitStrategyPtr init_neighbours
(
new InitIndexComp("mesh", pathname, "neighbours")
);
coherenceTree.node("ownerStarts")->add
(
"mesh",
"neighbours",
std::move(init_neighbours),
Foam::start_from_front,
Foam::count_from_front
);
InitStrategyPtr init_faceOffsets(new InitOffsets(true));
coherenceTree.node("neighbours")->add
(
"offsets",
"faceOffsets",
std::move(init_faceOffsets),
nullptr,
Foam::count_from_size
);
InitStrategyPtr init_internalFaceOffsets(new InitOffsets(true));
coherenceTree.node("neighbours")->add
(
"offsets",
"internalFaceOffsets",
std::move(init_internalFaceOffsets),
nullptr,
Foam::count_geq(0)
);
InitStrategyPtr init_faceStarts
(
new InitIndexComp("mesh", pathname, "faceStarts")
);
coherenceTree.node("ownerStarts")->add
(
"mesh",
"faceStarts",
std::move(init_faceStarts),
Foam::start_from_front,
Foam::count_from_front_plus_one
);
InitStrategyPtr init_faces
(
new InitIndexComp("mesh", pathname, "faces")
);
coherenceTree.node("faceStarts")->add
(
"mesh",
"faces",
std::move(init_faces),
Foam::start_from_front,
Foam::count_from_front
);
InitStrategyPtr init_pointOffsets(new InitOffsets(false));
coherenceTree.node("faces")->add
(
"offsets",
"pointOffsets",
std::move(init_pointOffsets),
Foam::offset_by_max_plus_one,
nullptr
);
coherenceTree.decorate<Foam::SliceDecorator>("pointOffsets");
InitStrategyPtr init_points
(
new InitPrimitivesFromADIOS<pointField>("mesh", pathname, "points")
);
coherenceTree.node("pointOffsets")->add<FieldComponent<pointField>>
(
"mesh",
"points",
std::move(init_points),
Foam::start_from_front,
Foam::count_from_front
);
coherenceTree.initialize();
std::vector<Foam::label> ownerStarts;
coherenceTree.node("ownerStarts")->extract(ownerStarts);
serializeOwner(ownerStarts); // TODO: has side-effects: filling member localOwner_
ownerStarts.clear();
std::vector<Foam::label> faceStarts;
std::vector<Foam::label> linearizedFaces;
coherenceTree.node("faceStarts")->extract(faceStarts);
coherenceTree.node("faces")->extract(linearizedFaces);
deserializeFaces(faceStarts, linearizedFaces); // TODO: has side-effects: filling member globalFaces_
linearizedFaces.clear();
faceStarts.clear();
coherenceTree.node("points")->extract(allPoints_);
numBoundaries_ = *std::min_element
(
coherenceTree.node("neighbours")->begin(),
coherenceTree.node("neighbours")->end()
);
numBoundaries_ = Foam::decodeSlicePatchId( numBoundaries_ ) + 1;
Foam::reduce(numBoundaries_, maxOp<label>());
boundaryGlobalIndex_.resize(numBoundaries_);
for (Foam::label patchi = 0; patchi<numBoundaries_; ++patchi)
{
auto slicePatchId = Foam::encodeSlicePatchId(patchi);
InitStrategyPtr init_boundaryFaceOffsets(new InitOffsets(true));
coherenceTree.node("neighbours")->add
(
"offsets",
"boundaryFaceOffsets" + std::to_string(patchi),
std::move(init_boundaryFaceOffsets),
nullptr,
Foam::count_eq(slicePatchId)
);
}
coherenceTree.node("neighbours")->initialize();
coherenceTree.node("neighbours")->extract(globalNeighbours_);
coherenceTree.node("cellOffsets")->extract(cellOffsets_);
coherenceTree.node("faceOffsets")->extract(faceOffsets_);
coherenceTree.node("internalFaceOffsets")
->extract(internalSurfaceFieldOffsets_);
for (Foam::label patchi = 0; patchi<numBoundaries_; ++patchi)
{
Foam::Offsets patchOffsets;
coherenceTree.node("boundaryFaceOffsets" + std::to_string(patchi))
->extract(patchOffsets);
boundarySurfacePatchOffsets_.push_back(patchOffsets);
}
coherenceTree.node("pointOffsets")->extract(pointOffsets_);
coherenceTree.node("cellOffsets")->extract(cellSlice_);
coherenceTree.node("pointOffsets")->extract(pointSlice_);
if (Pstream::parRun())
{
initializeSurfaceFieldMappings();
auto start = std::chrono::steady_clock::now();
commSlicePatches();
commSharedPoints();
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
double elapsed_time = static_cast<double>(elapsed_seconds.count());
Foam::reduce(elapsed_time, maxOp<double>());
Info << "elapsed time: " << elapsed_time << "s\n";
renumberFaces();
}
splintedPermutation_ = FragmentPermutation(globalNeighbours_);
}
void Foam::CoherentMesh::sendSliceFaces
(
std::pair<Foam::label, Foam::label> sendPair
)
{
Foam::label myProcNo = Pstream::myProcNo();
Foam::label partition = sendPair.first;
Foam::OPstream toPartition(Pstream::blocking, partition, 0, 0);
Foam::Slice slice(partition, cellOffsets_);
Foam::ProcessorPatch procPatch(slice, globalNeighbours_, numBoundaries_);
// Face Stuff
auto sendFaces = procPatch.extractFaces(globalFaces_);
toPartition << sendFaces;
procPatch.determinePointIDs(sendFaces, pointOffsets_.lowerBound(myProcNo));
sendFaces.clear();
// Owner Stuff
auto sendNeighbours = procPatch.extractFaces(globalNeighbours_);
toPartition << sendNeighbours;
sendNeighbours.clear();
// Point Stuff
auto sendPoints = procPatch.extractPoints(allPoints_);
toPartition << sendPoints;
sendPoints.clear();
// procBoundary Stuff: Track face swapping indices for processor boundaries;
procPatch.encodePatch(globalNeighbours_);
slicePatches_.push_back(procPatch);
}
void Foam::CoherentMesh::recvSliceFaces
(
std::pair<Foam::label, Foam::label> recvPair
)
{
label partition = recvPair.first;
label numberOfPartitionFaces = recvPair.second;
IPstream fromPartition(Pstream::blocking, partition, 0, 0);
// Face Communication
auto oldNumFaces = globalFaces_.size();
globalFaces_.resize(oldNumFaces + numberOfPartitionFaces);
SubList<face> recvFaces(globalFaces_, numberOfPartitionFaces, oldNumFaces);
fromPartition >> recvFaces;
std::transform
(
recvFaces.begin(),
recvFaces.end(),
recvFaces.begin(),
[](Foam::face& input)
{
return input.reverseFace();
}
);
// Owner Communication
localOwner_.resize(oldNumFaces + numberOfPartitionFaces);
SubList<label> recvOwner(localOwner_, numberOfPartitionFaces, oldNumFaces);
fromPartition >> recvOwner;
std::transform
(
recvOwner.begin(),
recvOwner.end(),
recvOwner.begin(),
[this](const Foam::label& id)
{
return cellSlice_.convert(id);
}
);
// Identify points from slice/partition that associate with the received faces
Foam::Slice recvPointSlice(partition, pointOffsets_);
std::set<Foam::label> pointIDs{};
Foam::subset
(
globalFaces_.end() - numberOfPartitionFaces,
globalFaces_.end(),
std::inserter(pointIDs, pointIDs.end()),
recvPointSlice
);
// Append new point IDs to point mapping
// TODO: Create proper state behaviour in Slice
pointSlice_.append(pointIDs);
// Point Communication
auto oldNumPoints = allPoints_.size();
allPoints_.resize(oldNumPoints + pointIDs.size());
SubField<point> recvPoints(allPoints_, pointIDs.size(), oldNumPoints);
fromPartition >> recvPoints;
// ProcBoundary Stuff
Foam::Slice recvCellSlice(partition, cellOffsets_);
ProcessorPatch procPatch(recvCellSlice, globalNeighbours_, numBoundaries_);
procPatch.encodePatch(globalNeighbours_, numberOfPartitionFaces);
slicePatches_.push_back(procPatch);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::CoherentMesh::deserializeFaces
(
const std::vector<Foam::label>& faceStarts,
const std::vector<Foam::label>& linearizedFaces
)
{
globalFaces_.setSize(faceStarts.size() - 1);
for (size_t i = 0; i<globalFaces_.size(); ++i)
{
globalFaces_[i].resize(faceStarts[i + 1] - faceStarts[i]);
std::move
(
linearizedFaces.begin() + (faceStarts[i] - faceStarts[0]),
linearizedFaces.begin() + (faceStarts[i + 1] - faceStarts[0]),
globalFaces_[i].begin()
);
}
}
void Foam::CoherentMesh::serializeOwner
(
const std::vector<Foam::label>& ownerStarts
)
{
Foam::label ownerCellID = 0;
localOwner_.setSize(ownerStarts.back() - ownerStarts.front());
for (size_t i = 0; i<ownerStarts.size() - 1; ++i)
{
std::fill
(
localOwner_.begin() + ownerStarts[i] - ownerStarts.front(),
localOwner_.begin() + ownerStarts[i + 1] - ownerStarts.front(),
ownerCellID
);
++ownerCellID;
}
}
void Foam::CoherentMesh::commSlicePatches()
{
Foam::label myProcNo = Pstream::myProcNo();
Foam::label nProcs = Pstream::nProcs();
//TODO : move to tree (decoration)
std::vector<Slice> slices(nProcs - (myProcNo+1));
Foam::label partition = myProcNo;
std::transform
(
cellOffsets_.begin() + myProcNo + 1,
cellOffsets_.end(),
std::back_inserter(slices),
[&partition](const std::pair<Foam::label, Foam::label> offset) mutable
{
++partition;
return Foam::Slice(partition, offset.first, offset.second);
}
);
std::map<Foam::label, Foam::label> sendNumPartitionFaces{};
for (auto& slice : slices)
{
std::vector<Foam::label> sharedIDs{};
Foam::subset
(
globalNeighbours_.begin(),
globalNeighbours_.end(),
std::back_inserter(sharedIDs),
slice
);
if (!sharedIDs.empty())
{
sendNumPartitionFaces[slice.partition()] = sharedIDs.size();
}
}
auto recvNumPartitionFaces = Foam::nonblockConsensus(sendNumPartitionFaces);
slicePatches_.clear();
for (const auto& sendPair: sendNumPartitionFaces)
{
sendSliceFaces(sendPair);
}
for (const auto& recvPair: recvNumPartitionFaces)
{
recvSliceFaces(recvPair);
}
}
void Foam::CoherentMesh::commSharedPoints()
{
auto myProcNo = Pstream::myProcNo();
std::set<label> missingPointIDs{};
Foam::subset
(
globalFaces_.begin(),
globalFaces_.end(),
std::inserter(missingPointIDs, missingPointIDs.end()),
[this] (const Foam::label& id)
{
return !pointSlice_.exist(id);
}
);
//TODO : move to tree (decoration)
std::vector<Slice> slices(myProcNo);
Foam::label partition = -1;
std::transform
(
pointOffsets_.begin(),
pointOffsets_.begin() + myProcNo,
std::back_inserter(slices),
[&partition](const std::pair<Foam::label, Foam::label> offset) mutable
{
++partition;
return Foam::Slice(partition, offset.first, offset.second);
}
);
std::map<Foam::label, std::vector<Foam::label>> sendPointIDs{};
for (auto& slice : slices)
{
std::vector<Foam::label> sharedIDs{};
Foam::subset
(
missingPointIDs.begin(),
missingPointIDs.end(),
std::back_inserter(sharedIDs),
slice
);
if (!sharedIDs.empty())
{
sendPointIDs[slice.partition()] = sharedIDs;
}
}
auto recvPointIDs = Foam::nonblockConsensus(sendPointIDs, MPI_LONG);
for (const auto& commPair: recvPointIDs)
{
auto partition = commPair.first;
auto sharedPoints = commPair.second;
pointSlice_.convert(sharedPoints);
pointField pointBuf = Foam::extractor(allPoints_, sharedPoints);
OPstream::write
(
Pstream::blocking,
partition,
reinterpret_cast<const char*>(pointBuf.data()),
pointBuf.size() * 3 * sizeof(scalar)
);
}
for (const auto& commPair: sendPointIDs)
{
auto partition = commPair.first;
auto sharedPoints = commPair.second;
label count = sharedPoints.size();
pointField pointBuf;
pointBuf.resize(count);
IPstream::read
(
Pstream::blocking,
partition,
reinterpret_cast<char*>( pointBuf.data()),
count * 3 * sizeof(scalar)
);
for (const auto& point: pointBuf)
{
allPoints_.append(point);
}
pointSlice_.append(sharedPoints);
}
}
void Foam::CoherentMesh::renumberFaces()
{
for (auto& face: globalFaces_)
{
std::transform
(
face.begin(),
face.end(),
face.begin(),
[this](const Foam::label& id)
{
return pointSlice_.convert(id);
}
);
}
}
void Foam::CoherentMesh::initializeSurfaceFieldMappings()
{
// permute before processor boundaries have been identified
auto permutation = FragmentPermutation(globalNeighbours_);
Foam::labelList neighbours{};
permutation.retrieveNeighbours(neighbours);
// Identify neighbouring processor and number of shared faces
Foam::label myProcNo = Pstream::myProcNo();
Foam::label nProcs = Pstream::nProcs();
// TODO : move to tree (decoration)
std::vector<Slice> slices(nProcs - (myProcNo+1));
Foam::label partition = myProcNo;
std::transform
(
cellOffsets_.begin() + myProcNo + 1,
cellOffsets_.end(),
std::back_inserter(slices),
[&partition](const std::pair<Foam::label, Foam::label> offset) mutable
{
++partition;
return Foam::Slice(partition, offset.first, offset.second);
}
);
std::map<Foam::label, Foam::label> procPatchIDsAndSizes{};
for (auto& slice : slices)
{
std::vector<Foam::label> sharedIDs{};
Foam::subset
(
neighbours.begin(),
neighbours.end(),
std::back_inserter(sharedIDs),
slice
);
if (!sharedIDs.empty())
{
procPatchIDsAndSizes[slice.partition()] = sharedIDs.size();
}
}
using pair_type = std::pair<Foam::label, Foam::label>;
Foam::label totalSize = std::accumulate
(
procPatchIDsAndSizes.begin(),
procPatchIDsAndSizes.end(),
0,
[](label size, pair_type pair)
{
return std::move(size) + pair.second;
}
);
// Resize container for internal face and boundary indices
internalFaceIDs_.resize(totalSize);
procBoundaryIDs_.resize(totalSize);
// Loop and fill internal face and boundary indices
auto internalFaceIDsIter = internalFaceIDs_.begin();
auto procBoundaryIDsIter = procBoundaryIDs_.begin();
slicePatches_.reserve(procPatchIDsAndSizes.size());
for (const auto& procPatchIdAndSize: procPatchIDsAndSizes)
{
// Identify processor boundaries in neighbour list
Foam::Slice slice(procPatchIdAndSize.first, cellOffsets_);
Foam::ProcessorPatch owningProcPatch(slice, neighbours, numBoundaries_);
slicePatches_.push_back(owningProcPatch);
// Copy the index to internal face list
std::copy
(
owningProcPatch.begin(),
owningProcPatch.end(),
internalFaceIDsIter
);
internalFaceIDsIter += owningProcPatch.size();
// Copy the boundary index to the corresponding faces
std::fill_n
(
procBoundaryIDsIter,
owningProcPatch.size(),
decodeSlicePatchId(owningProcPatch.id())
);
procBoundaryIDsIter += owningProcPatch.size();
}
// Sort the face indices to the internal list and
// permute the processor boundary indices accordingly
auto sortedPermutation = permutationOfSorted(internalFaceIDs_);
applyPermutation(internalFaceIDs_, sortedPermutation);
applyPermutation(procBoundaryIDs_, sortedPermutation);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::CoherentMesh::CoherentMesh(const Foam::polyMesh& pm)
:
MeshObject<polyMesh, CoherentMesh>(pm)
{
Foam::fileName path = pm.pointsInstance()/pm.meshDir();
readMesh(path);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::CoherentMesh::polyNeighbours(Foam::labelList& neighbours)
{
splintedPermutation_.retrieveNeighbours(neighbours);
cellSlice_.convert(neighbours);
}
void Foam::CoherentMesh::polyOwner(Foam::labelList& owner)
{
owner = localOwner_;
splintedPermutation_.permute(owner);
}
void Foam::CoherentMesh::polyFaces(Foam::faceList& faces)
{
faces = globalFaces_;
splintedPermutation_.permute(faces);
}
void Foam::CoherentMesh::polyPoints(Foam::pointField& points)
{
points = allPoints_;
}
std::vector<Foam::label> Foam::CoherentMesh::polyPatches()
{
std::vector<label> patches{};
splintedPermutation_.retrievePatches(patches);
return patches;
}
std::vector<Foam::ProcessorPatch> Foam::CoherentMesh::procPatches()
{
return slicePatches_;
}
Foam::List<Foam::polyPatch*>
Foam::CoherentMesh::polyPatches(polyBoundaryMesh& boundary)
{
// Retrieve list of patch IDs for boundary patch faces
std::vector<label> patches = polyPatches();
Foam::label numInternalFaces = globalNeighbours_.size() - patches.size();
// Read (on master) and distribute ASCII entries for boundaries
PtrList<entry> patchEntries{};
if (Pstream::master())
{
Istream& is = boundary.readStream("polyBoundaryMesh");
patchEntries = PtrList<entry>(is);
}
Pstream::scatter(patchEntries);
// Start filling modelled/physical boundary patches
Foam::List<Foam::polyPatch*> boundaryPatches
(
patchEntries.size() +
slicePatches_.size(),
reinterpret_cast<Foam::polyPatch*>(0)
);
Foam::label nthPatch = 0;
Foam::label nextPatchStart = numInternalFaces;
for (label patchi = 0; patchi<patchEntries.size(); ++patchi)
{
// Determine local start and size of boundary patches
Foam::label patchStart{nextPatchStart};
Foam::label patchSize{0};
Foam::label slicePatchId = Foam::encodeSlicePatchId(patchi);
auto patchStartIt =
std::find(patches.begin(), patches.end(), slicePatchId);
if (patchStartIt != patches.end())
{
patchStart =
numInternalFaces + std::distance(patches.begin(), patchStartIt);
patchSize = std::count(patchStartIt, patches.end(), slicePatchId);
}
// Replace new values into patch entries and create the polyPatch.
patchEntries[nthPatch].dict().set("startFace", patchStart);
patchEntries[nthPatch].dict().set("nFaces", patchSize);
boundaryPatches[nthPatch] =
Foam::polyPatch::New
(
patchEntries[nthPatch].keyword(),
patchEntries[nthPatch].dict(),
nthPatch,
boundary
).ptr();
nextPatchStart = patchStart + patchSize;
++nthPatch;
}
if (Pstream::parRun())
{
// Fill processor boundary patches
for (label patchi = 0; patchi<slicePatches_.size(); ++patchi)
{
// Determine start and size of processor boundary patch
Foam::label ProcessorPatchId = slicePatches_[patchi].id();
auto patchStartIt =
std::find(patches.begin(), patches.end(), ProcessorPatchId);
Foam::label patchStart =
numInternalFaces + std::distance(patches.begin(), patchStartIt);
Foam::label patchSize =
std::count(patchStartIt, patches.end(), ProcessorPatchId);
// Create and store the processorPolyPatch
boundaryPatches[nthPatch] =
new Foam::processorPolyPatch
(
slicePatches_[patchi].name(),
patchSize,
patchStart,
nthPatch,
boundary,
Pstream::myProcNo(),
slicePatches_[patchi].partner()
);
++nthPatch;
}
}
return boundaryPatches;
}
const Foam::globalIndex&
Foam::CoherentMesh::boundaryGlobalIndex(label patchId)
{
if (!boundaryGlobalIndex_.set(patchId))
{
boundaryGlobalIndex_.set
(
patchId,
new globalIndex
(
mesh().boundaryMesh()[patchId].size()
)
);
}
return boundaryGlobalIndex_[patchId];
}
// ************************************************************************* //

View file

@ -0,0 +1,219 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::CoherentMesh
Description
Foam::CoherentMesh
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
CoherentMesh.C
\*---------------------------------------------------------------------------*/
#ifndef CoherentMesh_H
#define CoherentMesh_H
#include "Offsets.H"
#include "Slice.H"
#include "ProcessorPatch.H"
#include "FragmentPermutation.H"
#include "polyMesh.H"
#include "MeshObject.H"
#include "globalIndex.H"
#include "IndexComponent.H"
#include <vector>
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class CoherentMesh Declaration
\*---------------------------------------------------------------------------*/
class CoherentMesh
:
public MeshObject<polyMesh, CoherentMesh>
{
IndexComponent tree_{};
label numBoundaries_{};
labelList globalNeighbours_{};
labelList localOwner_{};
faceList globalFaces_{};
pointField allPoints_{};
Offsets cellOffsets_{};
Offsets faceOffsets_{};
Offsets internalSurfaceFieldOffsets_{};
std::vector<Offsets> boundarySurfacePatchOffsets_{};
Offsets pointOffsets_{};
Slice cellSlice_{};
Slice pointSlice_{};
std::vector<ProcessorPatch> slicePatches_{};
FragmentPermutation splintedPermutation_{};
PtrList<globalIndex> boundaryGlobalIndex_{};
// Internal face indices
// in processor boundaries
Foam::labelList internalFaceIDs_;
// Processor boundary indices of internal faces
// participating in a processor boundary
Foam::labelList procBoundaryIDs_;
// Private Member Functions
void readMesh(const fileName&);
void sendSliceFaces(std::pair<label, label> sendPair);
void recvSliceFaces(std::pair<label, label> recvPair);
// De-serialize faces
void deserializeFaces(const std::vector<label>&, const std::vector<label>&);
// Serialize owner list
void serializeOwner(const std::vector<label>&);
// TODO: lengthy functions that must be refactored
// (structure and design still pending)
void initializeSurfaceFieldMappings();
void commSlicePatches();
void commSharedPoints();
void renumberFaces();
public:
TypeName("CoherentMesh");
// Constructors
CoherentMesh() = default;
CoherentMesh(const polyMesh&);
// Destructor
~CoherentMesh() = default;
// Member Functions
// Access
inline const Offsets& cellOffsets() const
{
return cellOffsets_;
}
inline const Offsets& internalSurfaceFieldOffsets() const
{
return internalSurfaceFieldOffsets_;
}
inline const labelList& internalFaceIDsFromBoundaries() const
{
return internalFaceIDs_;
}
inline const labelList& boundryIDsFromInternalFaces() const
{
return procBoundaryIDs_;
}
void polyNeighbours(labelList&);
void polyOwner(labelList&);
void polyFaces(faceList&);
void polyPoints(pointField&);
std::vector<label> polyPatches();
std::vector<ProcessorPatch> procPatches();
List<polyPatch*> polyPatches(polyBoundaryMesh&);
// Compulsory overloads resulting from the inheritance from MeshObject
virtual bool movePoints() const
{
// ToDoIO
FatalErrorInFunction
<< "not implemented"
<< abort(FatalError);
return true;
}
virtual bool updateMesh(const mapPolyMesh&) const
{
// ToDoIO
FatalErrorInFunction
<< "not implemented"
<< abort(FatalError);
return true;
}
// Field infrastructure
const globalIndex& boundaryGlobalIndex(label patchId);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::FragmentPermutation
Description
Permuting from coherent and sliceable to fragmented data layout
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "FragmentPermutation.H"
#include <numeric>
#include <cmath>
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::pairVector<Foam::label, Foam::label>
Foam::FragmentPermutation::createPolyNeighbourPermutation
(
const Foam::labelList& sliceNeighbours
)
{
auto polySlicePairs{generateIndexedPairs(sliceNeighbours)};
partitionByFirst(polySlicePairs);
return polySlicePairs;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::FragmentPermutation::FragmentPermutation(const Foam::labelList& sliceNeighbours)
:
polyNeighboursPermutation_{createPolyNeighbourPermutation(sliceNeighbours)},
polyNeighboursAndPatches_
{
extractNth
(
polyNeighboursPermutation_,
[](const std::pair<Foam::label, Foam::label>& inputPair)
{
return inputPair.first;
}
)
},
facePermutation_
{
extractNth
(
polyNeighboursPermutation_,
[](const std::pair<Foam::label, Foam::label>& inputPair)
{
return inputPair.second;
}
)
}
{
polyNeighboursPermutation_.clear();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Transformations to FragmentPermutation
Foam::label Foam::FragmentPermutation::permute(const Foam::label& id)
{
return facePermutation_[id];
}
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::FragmentPermutation
Description
Permuting from coherent and sliceable to fragmented data layout
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
FragmentPermutation.C
FragmentPermutationI.H
\*---------------------------------------------------------------------------*/
#ifndef FragmentPermutation_H
#define FragmentPermutation_H
#include "sliceMeshHelper.H"
#include "polyMesh.H"
#include <vector>
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration
class pointMesh;
/*---------------------------------------------------------------------------*\
Class FragmentPermutation Declaration
\*---------------------------------------------------------------------------*/
class FragmentPermutation
{
pairVector<label, label> polyNeighboursPermutation_{};
std::vector<label> polyNeighboursAndPatches_{};
// Permutation from sliceable layout to
// fragmented layout for face-ordered lists
std::vector<label> facePermutation_{};
//
pairVector<label, label>
createPolyNeighbourPermutation(const labelList&);
template<typename IterType>
void resetNextPatch
(
IterType& patchBegin,
IterType& patchEnd,
polyPatch& patch,
const label& patchId
)
{
findValueExtend
(
patchBegin,
patchEnd,
polyNeighboursAndPatches_.end(),
encodeSlicePatchId(patchId)
);
patch.resetPatch
(
std::distance(patchBegin, patchEnd),
std::distance(polyNeighboursAndPatches_.begin(), patchBegin)
);
}
auto findPatchBegin() -> decltype(polyNeighboursAndPatches_.begin())
{
return std::find_if
(
polyNeighboursAndPatches_.begin(),
polyNeighboursAndPatches_.end(),
[](const Foam::label& id)
{
return id < 0;
}
);
}
public:
// Constructors
//- Default constructor
FragmentPermutation() = default;
//- Construct FragmentPermutation from neighbour
explicit FragmentPermutation(const labelList&);
// Member Functions
//
// Transformations to FragmentPermutation
template<typename Container>
void permute(Container&);
label permute(const label&);
template<typename Container>
void retrieveNeighbours(Container&);
template<typename Container>
void retrievePatches(Container&);
};
#include "FragmentPermutationI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::FragmentPermutation
Description
Permuting from coherent and sliceable to fragmented data layout
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<typename Container>
void Foam::FragmentPermutation::permute(Container &input)
{
applyPermutation(input, facePermutation_);
}
template<typename Container>
void Foam::FragmentPermutation::retrieveNeighbours(Container &neighbours)
{
const auto polyNeighboursBegin = polyNeighboursAndPatches_.begin();
const auto polyPatchBegin = findPatchBegin();
neighbours.resize(std::distance(polyNeighboursBegin, polyPatchBegin));
std::copy(polyNeighboursBegin, polyPatchBegin, neighbours.begin());
}
template<typename Container>
void Foam::FragmentPermutation::retrievePatches(Container &patches)
{
const auto polyPatchBegin = findPatchBegin();
const auto polyPatchEnd = polyNeighboursAndPatches_.end();
patches.resize(std::distance(polyPatchBegin, polyPatchEnd));
std::copy(polyPatchBegin, polyPatchEnd, patches.begin());
}
// ************************************************************************* //

View file

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::Offsets
Description
Foam::Offsets
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "Offsets.H"
#include "globalIndex.H"
Foam::Offsets::Offsets(label value, bool reduce)
{
set(value, reduce);
}
void Foam::Offsets::set(Foam::label value, bool reduce)
{
Foam::globalIndex offsets(value, reduce);
// Guarantee monotonically increasing values
offset_pairs_[0].second = offsets.offset(1);
for (label proc = 1; proc < Foam::Pstream::nProcs(); ++proc)
{
offset_pairs_[proc].second = offsets.offset(proc+1);
if (offset_pairs_[proc].second < offset_pairs_[proc-1].second)
{
offset_pairs_[proc].second = offset_pairs_[proc-1].second;
}
}
// Translate offsets through lower bound -- first in pair
for (auto it = offset_pairs_.begin(); it < offset_pairs_.end()-1; ++it)
{
(it+1)->first = it->second;
}
}
Foam::label Foam::Offsets::lowerBound(Foam::label myProcNo) const
{
return offset_pairs_[myProcNo].first;
}
Foam::label Foam::Offsets::upperBound(Foam::label myProcNo) const
{
return offset_pairs_[myProcNo].second;
}
Foam::label Foam::Offsets::count(Foam::label myProcNo) const
{
return upperBound(myProcNo) - lowerBound(myProcNo);
}
Foam::label Foam::Offsets::size() const
{
return count(Pstream::myProcNo());
}
Foam::Offsets::iterator Foam::Offsets::begin()
{
return offset_pairs_.begin();
}
Foam::Offsets::iterator Foam::Offsets::end()
{
return offset_pairs_.end();
}
std::pair<Foam::label, Foam::label>
Foam::Offsets::operator[](label i) const
{
return offset_pairs_[i];
}

View file

@ -0,0 +1,109 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::Offsets
Description
Foam::Offsets
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
Offsets.C
\*---------------------------------------------------------------------------*/
#ifndef Offsets_H
#define Offsets_H
#include "Pstream.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class Offsets Declaration
\*---------------------------------------------------------------------------*/
class Offsets
{
using pair_container = List<std::pair<label,label>>;
//labelList offsets_{labelList(Pstream::nProcs(), 0)};
pair_container offset_pairs_
{
pair_container
(
Pstream::nProcs(),
std::pair<label, label>(0,0)
)
};
public:
using iterator = pair_container::iterator;
// Default constructor
Offsets() = default;
// Construct from value
explicit Offsets
(
label value,
bool reduce = false
);
// Setting gather-scatter of values across processors
void set(label value, bool reduce = false);
// Return offset to processor below
label lowerBound(label) const;
// Return offset to processor above
label upperBound(label) const;
// Return the difference between lower and upper bound
label count(label) const;
label size() const;
iterator begin();
iterator end();
std::pair<label, label> operator[](label) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,276 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::ProcessorPatch
Description
Required for processor patch construction on coherent mesh layout.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "ProcessorPatch.H"
#include "Offsets.H"
#include <set>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::label Foam::ProcessorPatch::instanceCount_ = 0;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ProcessorPatch::ProcessorPatch
(
const Foam::Slice& slice,
const Foam::labelList& neighbours,
const Foam::label& numBoundaries
)
:
numNonProcPatches_{numBoundaries},
slice_{slice},
localFaceIDs_
{
labelList
(
std::count_if
(
neighbours.begin(),
neighbours.end(),
slice
)
)
},
procBoundaryName_
{
word("procBoundary") +
Foam::name(Pstream::myProcNo()) +
word("to") +
Foam::name(slice_.partition())
}
{
determineFaceIDs(neighbours);
++instanceCount_;
id_ = Foam::encodeSlicePatchId((numNonProcPatches_ - 1) + instanceCount_);
}
// Copy constructor
Foam::ProcessorPatch::ProcessorPatch(const ProcessorPatch& other)
:
id_{other.id_},
slice_{other.slice_},
localFaceIDs_{other.localFaceIDs_.begin(), other.localFaceIDs_.end()},
localPointIDs_{other.localPointIDs_.begin(), other.localPointIDs_.end()},
procBoundaryName_{other.procBoundaryName_}
{
++instanceCount_;
}
//TODO: Must not be copyable because of instanceCount_ consider move semantics only
Foam::ProcessorPatch&
Foam::ProcessorPatch::operator=(Foam::ProcessorPatch const& other)
{
Foam::ProcessorPatch tmp(other);
swap(tmp);
return *this;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
Foam::ProcessorPatch::~ProcessorPatch()
{
--instanceCount_;
}
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
void Foam::ProcessorPatch::swap(Foam::ProcessorPatch& other) noexcept
{
using std::swap;
swap( id_, other.id_ );
swap( instanceCount_, other.instanceCount_ );
swap( slice_, other.slice_ );
swap( localFaceIDs_, other.localFaceIDs_ );
swap( localPointIDs_, other.localPointIDs_ );
swap( procBoundaryName_, other.procBoundaryName_ );
}
Foam::label Foam::ProcessorPatch::id() const
{
return id_;
}
Foam::word Foam::ProcessorPatch::name() const
{
return procBoundaryName_;
}
Foam::label Foam::ProcessorPatch::partner() const
{
return slice_.partition();
}
void Foam::ProcessorPatch::determineFaceIDs(const Foam::labelList& neighbours)
{
auto faceIdIter = localFaceIDs_.begin();
for
(
auto neighboursIter = std::begin(neighbours);
neighboursIter != std::end(neighbours);
++neighboursIter
)
{
if (slice_(*neighboursIter))
{
*faceIdIter = std::distance(neighbours.begin(), neighboursIter);
++faceIdIter;
}
}
}
void Foam::ProcessorPatch::determinePointIDs
(
const Foam::faceList& faces,
const Foam::label& bottomPointId
)
{
auto pred = [bottomPointId](const Foam::label& id)
{
return bottomPointId<=id;
};
std::set<Foam::label> pointIDs{};
Foam::subset
(
faces.begin(),
faces.end(),
std::inserter(pointIDs, pointIDs.end()),
pred
);
localPointIDs_.resize(pointIDs.size());
std::transform
(
pointIDs.begin(),
pointIDs.end(),
localPointIDs_.begin(),
[&bottomPointId](const Foam::label& id)
{
return id - bottomPointId;
}
);
}
void Foam::ProcessorPatch::appendOwner
(
Foam::labelList& owner,
Foam::labelList& recvOwner
)
{
std::transform
(
recvOwner.begin(),
recvOwner.end(),
recvOwner.begin(),
[this](const Foam::label& id)
{
return slice_.convert(id);
}
);
owner.append(recvOwner);
}
void Foam::ProcessorPatch::encodePatch(Foam::labelList& neighbours)
{
std::transform
(
std::begin(neighbours),
std::end(neighbours),
std::begin(neighbours),
[this](const Foam::label& cellId)
{
return slice_(cellId) ? id_ : cellId;
}
);
}
void Foam::ProcessorPatch::encodePatch
(
std::vector<Foam::label>& neighbours,
const Foam::label& numPatchFaces
)
{
std::fill_n(std::back_inserter(neighbours), numPatchFaces, id_);
}
void Foam::ProcessorPatch::encodePatch
(
Foam::labelList& neighbours,
const Foam::label& numPatchFaces
)
{
auto curr_size = neighbours.size();
neighbours.resize(curr_size + numPatchFaces);
std::fill_n(neighbours.begin() + curr_size, numPatchFaces, id_);
}
Foam::pointField
Foam::ProcessorPatch::extractPoints(const Foam::pointField& input)
{
Foam::pointField output;
output.resize(localPointIDs_.size());
std::transform
(
std::begin(localPointIDs_),
std::end(localPointIDs_),
std::begin(output),
[&input](const Foam::label& id)
{
return input[id];
}
);
return output;
}
void Foam::swap(Foam::ProcessorPatch& a, Foam::ProcessorPatch& b) noexcept
{
a.swap( b );
}
// ************************************************************************* //

View file

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::ProcessorPatch
Description
Required for processor patch construction on coherent mesh layout.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
ProcessorPatch.C
ProcessorPatchI.H
\*---------------------------------------------------------------------------*/
#ifndef ProcessorPatch_H
#define ProcessorPatch_H
#include "labelList.H"
#include "faceList.H"
#include "Slice.H"
#include <vector>
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<typename SomeList, typename IndexList>
SomeList extractor(const SomeList& input, const IndexList& extractorList);
// Forward declaration
class Offsets;
/*---------------------------------------------------------------------------* \
Class ProcessorPatch Declaration
\*---------------------------------------------------------------------------*/
class ProcessorPatch
{
using index_container = labelList;
using iterator = index_container::iterator;
// Counting the number of local processor patches
static label instanceCount_;
// ID of the processor patch
label id_{};
// Number of physical boundary patches
label numNonProcPatches_{};
// Cell slice
Slice slice_{};
// Indices in face ordered list that constitute the processor patch
index_container localFaceIDs_{};
// Indices in point ordered list that constitute the processor patch
index_container localPointIDs_{};
// Name of the processor patch
word procBoundaryName_{};
public:
// Constructors
//- Construct based on slice and neighbour list
ProcessorPatch
(
const Foam::Slice&,
const Foam::labelList&,
const Foam::label&
);
// Copy constructor
ProcessorPatch(const ProcessorPatch&);
// Copy assignment operator
ProcessorPatch& operator=(const ProcessorPatch&);
// Destructor
~ProcessorPatch();
// Copy-and-swap idiom
void swap(ProcessorPatch&) noexcept;
// Return the processor patch id
label id() const;
// Return the processor patch name
word name() const;
// Return the neighbouring processor
label partner() const;
// Extract faces IDs from the neighbour list in sliceable data layout
void determineFaceIDs(const labelList&);
// Extract point IDs from the face list in sliceable data layout
void determinePointIDs(const faceList&, const label&);
// Append owners from received processor patch to owner list
void appendOwner(Foam::labelList&, Foam::labelList&);
// Encode patch IDs in input neighbour list
void encodePatch(labelList&);
// Append patch IDs to neighbour list
void encodePatch(std::vector<label>&, const label&);
// Append patch IDs to neighbour list
void encodePatch(labelList&, const label&);
// Extract face IDs of processor patch from input list
template<typename FaceList>
FaceList extractFaces(const FaceList& input);
// Extract point IDs of processor patch from input list
pointField extractPoints(const pointField& input);
// Return begin iterator of local face IDs
iterator begin() { return localFaceIDs_.begin(); }
// Return end iterator of local face IDs
iterator end() { return localFaceIDs_.end(); }
// Return size of face ID list
label size() const { return localFaceIDs_.size(); }
};
void swap(ProcessorPatch&, ProcessorPatch&) noexcept;
}
#include "ProcessorPatchI.H"
#endif

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::ProcessorPatch
Description
Required for processor patch construction on coherent mesh layout.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * Free Functions * * * * * * * * * * * * * * //
template<typename SomeList, typename IndexList>
SomeList Foam::extractor(const SomeList& input, const IndexList& extractorList)
{
typedef typename IndexList::value_type index_type;
SomeList output;
output.resize(extractorList.size());
std::transform
(
std::begin(extractorList),
std::end(extractorList),
std::begin(output),
[&input](const index_type& id)
{
return input[id];
}
);
return output;
}
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
template<typename FaceList>
FaceList Foam::ProcessorPatch::extractFaces(const FaceList& input)
{
return Foam::extractor(input, localFaceIDs_);
}
// ************************************************************************* //

View file

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::Slice
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "Slice.H"
#include "Offsets.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::Slice::Slice
(
const Foam::label& partition,
const Foam::Offsets& offsets
)
:
Slice
(
partition,
offsets.lowerBound(partition),
offsets.upperBound(partition)
)
{}
Foam::Slice::Slice
(
const Foam::label& bottom,
const Foam::label& top
)
:
Slice(-1, bottom, top)
{}
Foam::Slice::Slice
(
const Foam::label& partition,
const Foam::label& bottom,
const Foam::label& top
)
:
partition_{partition},
bottom_{bottom},
top_{top},
mapping_{std::make_shared<Foam::sliceMap>(top_-bottom_)}
{}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
Foam::label Foam::Slice::shift(const Foam::label& id) const
{
return id - bottom_;
}
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
Foam::label Foam::Slice::partition() const
{
return partition_;
}
bool Foam::Slice::operator()(const Foam::label& id) const
{
return (bottom_<=id && id<top_);
}
bool Foam::Slice::exist(const Foam::label& id) const
{
return (mapping_->exist(id)) || (this->operator()(id));
}
Foam::label Foam::Slice::convert(const Foam::label& id) const
{
return this->operator()(id) ? shift(id) : mapping_->operator[](id);
}
// ************************************************************************* //

View file

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::Slice
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
Slice.C
SliceI.H
\*---------------------------------------------------------------------------*/
#ifndef Slice_H
#define Slice_H
#include "label.H"
#include "faceList.H" //required for appendFaces
#include <functional>
#include <algorithm>
#include <utility> // std::declval
#include "primitives_traits.H"
#include "sliceMap.H"
#include "sliceMeshHelper.H"
namespace Foam
{
// Forward declaration
class Offsets;
class Slice;
template<typename Container>
label numCellsFromSlice(const Container&, const Slice&);
template<typename Container, typename Operator>
void appendTransformed(Container& ret, Container& input, Operator operation);
/*---------------------------------------------------------------------------* \
Class Slice Declaration
\*---------------------------------------------------------------------------*/
class Slice
{
// Partition Id
label partition_{};
// Smallest index on slice; renders an offset to partition below
label bottom_{};
// Largest index on slice; renders an offset to partition above
label top_{};
// Explicit mapping of IDs from processor patches
std::shared_ptr<sliceMap> mapping_{};
// Shift id based on bottom_ offset
label shift(const label& id) const;
public:
// Constructors
Slice() = default;
// Construct based on partition id and offsets
Slice(const label&, const Foam::Offsets&);
// Construct based on two labels for upper and lower bound
Slice(const label&, const label&);
// Construct based on three labels for partition, upper, and lower bound
Slice(const label&, const label&, const label&);
// Return partition id
label partition() const;
// Check if input id natively belongs to slice
bool operator()(const label& id) const;
// Check if input id belongs to slice including mapping_
bool exist(const label& id) const;
// Convert from global to local id
label convert(const label& id) const;
// Convert container content from global to local IDs
template<typename Container>
typename std::enable_if<is_range<Container>::value, Container>::type
convert(Container& list) const;
// Append content of Container to mapping_
template<typename Container>
void append(const Container&);
};
}
#include "SliceI.H"
#endif

View file

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::Slice
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * Free Functions * * * * * * * * * * * * * * //
template<typename Container>
Foam::label Foam::numCellsFromSlice
(
const Container& neighbours,
const Foam::Slice& slice
)
{
return std::count_if
(
std::begin(neighbours),
std::end(neighbours),
slice
);
}
template<typename Container, typename Operator>
void Foam::appendTransformed
(
Container& ret,
Container& input,
Operator operation
)
{
std::transform
(
std::begin(input),
std::end(input),
std::begin(input),
operation
);
ret.append(input);
}
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
template<typename Container>
typename std::enable_if<Foam::is_range<Container>::value, Container>::type
Foam::Slice::convert(Container& list) const
{
typedef typename Container::value_type index_type;
std::transform
(
std::begin(list),
std::end(list),
std::begin(list),
[this](const index_type& id)
{
return convert(id);
}
);
return list;
}
template<typename Container>
void Foam::Slice::append(const Container& list)
{
mapping_->append(list);
}
// ************************************************************************* //

View file

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SlicePermutation
Description
Permuting fragmented data structure to coherent and sliceable data layout
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "SlicePermutation.H"
#include <numeric>
#include <cmath>
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::SlicePermutation::createPointPermutation
(
Foam::faceList& faces,
const Foam::label& nPoints
)
{
permutationToPolyPoint_.resize(nPoints, -1);
permutationToSlicePoint_.resize(nPoints, -1);
Foam::label slicePointId = 0;
for (const auto& face: faces)
{
for (const auto& polyPointId: face)
{
if (permutationToPolyPoint_[polyPointId] == -1)
{
permutationToPolyPoint_[polyPointId] = slicePointId;
permutationToSlicePoint_[slicePointId] = polyPointId;
++slicePointId;
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::SlicePermutation::SlicePermutation(const polyMesh& mesh)
:
SlicePermutation(mesh.faceOwner(), mesh.allFaces(), mesh.nPoints())
{}
Foam::SlicePermutation::SlicePermutation
(
const Foam::labelList& faceOwner,
const Foam::faceList& allFaces,
const Foam::label& nPoints
)
:
permutationToSlice_(faceOwner.size()),
faces_{allFaces.begin(), allFaces.end()}
{
permutationOfSorted
(
permutationToSlice_.begin(),
permutationToSlice_.end(),
faceOwner
);
permute(faces_);
createPointPermutation(faces_, nPoints);
renumberFaces(faces_, permutationToPolyPoint_);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Transformations to SlicePermutation
void Foam::SlicePermutation::permute(Foam::pointField& allPoints)
{
applyPermutation(allPoints, permutationToSlicePoint_);
}
void Foam::SlicePermutation::apply(Foam::faceList& allFaces)
{
permute(allFaces);
renumberFaces(allFaces, permutationToPolyPoint_);
}
Foam::faceList Foam::SlicePermutation::retrieveFaces()
{
return faces_;
}
void Foam::SlicePermutation::retrieveNeighbours
(
Foam::labelList& sliceNeighbours,
const Foam::polyMesh& mesh
)
{
sliceNeighbours.resize(permutationToSlice_.size());
std::transform
(
permutationToSlice_.begin(),
permutationToSlice_.end(),
sliceNeighbours.begin(),
[&mesh](const Foam::label& fragFaceId)
{
auto patchId = mesh.boundaryMesh().whichPatch(fragFaceId);
return (patchId != -1) ? encodeSlicePatchId(patchId)
: mesh.faceNeighbour()[fragFaceId];
}
);
}
// ************************************************************************* //

View file

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SlicePermutation
Description
Permuting fragmented data structure to coherent and sliceable data layout
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
SlicePermutation.C
SlicePermutationI.H
\*---------------------------------------------------------------------------*/
#ifndef SlicePermutation_H
#define SlicePermutation_H
#include "sliceMeshHelper.H"
#include "polyMesh.H"
#include <vector>
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration
class pointMesh;
/*---------------------------------------------------------------------------*\
Class SlicePermutation Declaration
\*---------------------------------------------------------------------------*/
class SlicePermutation
{
// Permutation from fragmented layout to
// sliceable layout for face-ordered lists
std::vector<label> permutationToSlice_{};
// Permutation from fragmented layout
// to sliceable layout for point-ordered lists
std::vector<label> permutationToSlicePoint_{};
// Permutation from sliceable layout
// sliceable layout for point-ordered lists
std::vector<label> permutationToPolyPoint_{};
// Readily permuted faces
faceList faces_{};
// Create the point permutation from fragmented to sliceable data layout
void createPointPermutation(faceList&, const label&);
public:
// Constructors
//- Default construct
SlicePermutation() = default;
//- Construct from polyMesh
explicit SlicePermutation(const polyMesh&);
//- Construct from faces, owners and number of points
SlicePermutation(const labelList&, const faceList&, const label&);
// Member Functions
//
// Transformations to SlicePermutation
template<typename Container>
void permute(Container&);
void permute(pointField&);
template<typename MeshElement>
void apply(MeshElement&);
void apply(faceList&);
Foam::faceList retrieveFaces();
// Generate 'sliced' neighbours
void retrieveNeighbours(labelList&, const polyMesh&);
};
#include "SlicePermutationI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::SlicePermutation
Description
Permuting fragmented data structure to coherent and sliceable data layout
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<typename Container>
void Foam::SlicePermutation::permute(Container &input)
{
applyPermutation(input, permutationToSlice_);
}
template<typename MeshElement>
void Foam::SlicePermutation::apply(MeshElement &input)
{
permute(input);
}
// ************************************************************************* //

View file

@ -0,0 +1,126 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Function
Foam::nonblockConsensus
Description
Implements the nonblocking concensus exchange algorithm.
@article
{
doi = {10.1145/1837853.1693476},
author = {Hoefler, Torsten and Siebert, Christian and Lumsdaine, Andrew},
title = {Scalable Communication Protocols for Dynamic Sparse Data Exchange},
year = {2010},
volume = {45},
number = {5},
journal = {SIGPLAN Not.},
pages = {159168}
}
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "nonblockConsensus.H"
#include "Offsets.H"
#include "Slice.H"
std::map<Foam::label, Foam::label>
Foam::nonblockConsensus(const std::map<Foam::label, Foam::label>& data)
{
int tag = 314159;
bool barrier_activated = false;
MPI_Barrier(MPI_COMM_WORLD);
std::vector<MPI_Request> issRequests{};
for (const auto& msg: data)
{
MPI_Request request;
MPI_Issend
(
&(msg.second),
1,
MPI_INT,
msg.first,
tag,
MPI_COMM_WORLD,
&request
);
issRequests.push_back(request);
}
std::map<Foam::label, Foam::label> recvBuffer{};
MPI_Request barrier = MPI_REQUEST_NULL;
int done = 0;
while (!done)
{
int flag = 0;
int count = 0;
MPI_Status status;
MPI_Iprobe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &flag, &status);
if (flag)
{
MPI_Get_count(&status, MPI_INT, &count);
Foam::label numberOfPartitionFaces{};
MPI_Recv
(
&numberOfPartitionFaces,
count,
MPI_INT,
status.MPI_SOURCE,
tag,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
recvBuffer[status.MPI_SOURCE] = numberOfPartitionFaces;
}
if (barrier_activated)
{
MPI_Test(&barrier, &done, MPI_STATUS_IGNORE);
}
else
{
int sent;
MPI_Testall
(
issRequests.size(),
issRequests.data(),
&sent,
MPI_STATUSES_IGNORE
);
if (sent)
{
MPI_Ibarrier(MPI_COMM_WORLD, &barrier);
barrier_activated = true;
}
}
}
return recvBuffer;
}
// ************************************************************************* //

View file

@ -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 <http://www.gnu.org/licenses/>.
Function
Foam::nonblockConsensus
Description
Implements the nonblocking concensus exchange algorithm.
@article
{
doi = {10.1145/1837853.1693476},
author = {Hoefler, Torsten and Siebert, Christian and Lumsdaine, Andrew},
title = {Scalable Communication Protocols for Dynamic Sparse Data Exchange},
year = {2010},
volume = {45},
number = {5},
journal = {SIGPLAN Not.},
pages = {159168}
}
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
nonblockConsensus.C
nonblockConsensusI.H
\*---------------------------------------------------------------------------*/
#ifndef nonblockConsensus_H
#define nonblockConsensus_H
#include "label.H"
#include "labelList.H"
#include <vector>
#include <map>
#include "mpi.h"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class Offsets;
template<class Type>
std::map<label, std::vector<Type>>
nonblockConsensus(const std::map<label, std::vector<Type>>&, MPI_Datatype);
std::map<label, label> nonblockConsensus(const std::map<label, label>&);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "nonblockConsensusI.H"
#endif
// ************************************************************************* //

View file

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Function
Foam::nonblockConsensus
Description
Implements the nonblocking concensus exchange algorithm.
@article
{
doi = {10.1145/1837853.1693476},
author = {Hoefler, Torsten and Siebert, Christian and Lumsdaine, Andrew},
title = {Scalable Communication Protocols for Dynamic Sparse Data Exchange},
year = {2010},
volume = {45},
number = {5},
journal = {SIGPLAN Not.},
pages = {159168}
}
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
template<class Type>
std::map<Foam::label, std::vector<Type>>
Foam::nonblockConsensus
(
const std::map<Foam::label,
std::vector<Type>>& data,
MPI_Datatype dtype
)
{
int tag = 314159;
bool barrier_activated = false;
MPI_Barrier(MPI_COMM_WORLD);
std::vector<MPI_Request> issRequests{};
for (const auto& msg: data)
{
MPI_Request request;
MPI_Issend
(
&(msg.second[0]),
msg.second.size(),
dtype,
msg.first,
tag,
MPI_COMM_WORLD,
&request
);
issRequests.push_back(request);
}
std::map<Foam::label, std::vector<Type>> recvBuffer{};
MPI_Request barrier = MPI_REQUEST_NULL;
int done = 0;
while (!done)
{
int flag = 0;
int count = 0;
MPI_Status status;
MPI_Iprobe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &flag, &status);
if (flag)
{
MPI_Get_count(&status, dtype, &count);
std::vector<Type> recvMessage(count);
MPI_Recv
(
&(recvMessage[0]),
count,
dtype,
status.MPI_SOURCE,
tag,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
recvBuffer[status.MPI_SOURCE] = std::move(recvMessage);
}
if (barrier_activated)
{
MPI_Test(&barrier, &done, MPI_STATUS_IGNORE);
}
else
{
int sent;
MPI_Testall
(
issRequests.size(),
issRequests.data(),
&sent,
MPI_STATUSES_IGNORE
);
if (sent)
{
MPI_Ibarrier(MPI_COMM_WORLD, &barrier);
barrier_activated = true;
}
}
}
return recvBuffer;
}

View file

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::sliceMap
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "sliceMap.H"
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * //
Foam::sliceMap::sliceMap(const Foam::label& numNativeEntities)
:
mapping_{},
numNativeEntities_{numNativeEntities}
{}
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
Foam::label Foam::sliceMap::operator[](const Foam::label& id)
{
return mapping_[id];
}
bool Foam::sliceMap::exist(const Foam::label& id)
{
return mapping_.count(id) == 1;
};
// ************************************************************************* //

View file

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::sliceMap
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
sliceMap.C
sliceMapI.H
\*---------------------------------------------------------------------------*/
#ifndef sliceMap_H
#define sliceMap_H
#include "label.H"
#include <map>
namespace Foam
{
class sliceMap
{
std::map<label, label> mapping_{};
const label numNativeEntities_{};
public:
// Constructor
sliceMap() = default;
// Construct with an offset in mapped IDs
sliceMap(const label&);
// Append a list of IDs to the map
template<typename Container>
void append(const Container&);
// Return mapped Id
label operator[](const label&);
// Check if input Id is mapped
bool exist(const label&);
};
}
#include "sliceMapI.H"
#endif

View file

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::sliceMap
Description
Defining a mesh slice of a cell/face/point list.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include <algorithm>
template<typename Container>
void Foam::sliceMap::append(const Container& list)
{
typedef typename Container::value_type index_type;
Foam::label currId = numNativeEntities_ + mapping_.size();
std::transform
(
std::begin(list),
std::end(list),
std::inserter(mapping_, std::end(mapping_)),
[&currId](const index_type& id) mutable
{
auto ret = std::pair<label, label>({id, currId});
++currId;
return ret;
}
);
}

View file

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Free functions
Description
The free functions in this file render algorithms to create the coherent
data layout.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "sliceMeshHelper.H"
// * * * * * * * * * * * * * * Free Functions * * * * * * * * * * * * * * * //
Foam::label Foam::encodeSlicePatchId(const Foam::label& Id)
{
return -(Id + 1);
}
Foam::label Foam::decodeSlicePatchId(const Foam::label& encodedId)
{
return -(encodedId + 1);
}
void Foam::partitionByFirst(Foam::pairVector<Foam::label, Foam::label>& input)
{
std::stable_partition
(
input.begin(),
input.end(),
[](const std::pair<Foam::label, Foam::label>& n)
{
return n.first>0;
}
);
std::stable_sort
(
std::partition_point
(
input.begin(),
input.end(),
[](const std::pair<Foam::label, Foam::label>& n)
{
return n.first>0;
}
),
input.end(),
[]
(
const std::pair<Foam::label, Foam::label>& n,
const std::pair<Foam::label, Foam::label>& m
)
{
return n.first>m.first;
}
);
}
void
Foam::renumberFaces(Foam::faceList& faces, const std::vector<Foam::label>& map)
{
std::for_each
(
faces.begin(),
faces.end(),
[&map](Foam::face& input)
{
std::transform
(
input.begin(),
input.end(),
input.begin(),
[&map](const Foam::label& id)
{
return map[id];
}
);
}
);
}
std::vector<Foam::label>
Foam::permutationOfSorted(const Foam::labelList& input)
{
std::vector<Foam::label> indices{};
indexIota(indices, input.size(), 0);
indexSort(indices, input);
return indices;
}
// ************************************************************************* //

View file

@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Free functions
Description
The free functions in this file render algorithms to create the coherent
data layout.
Author
Gregor Weiss, HLRS University of Stuttgart
SourceFiles
sliceMeshHelper.C
sliceMeshHelperI.H
\*---------------------------------------------------------------------------*/
#ifndef sliceMeshHelper_H
#define sliceMeshHelper_H
#include "label.H"
#include "faceList.H"
#include <set>
#include <vector>
#include <algorithm>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<typename Type1, typename Type2>
using pairVector = std::vector<std::pair<Type1, Type2>>;
/*---------------------------------------------------------------------------*\
Helper Functions Declaration
\*---------------------------------------------------------------------------*/
// Encoding a patch Id to differentiate from internal face IDs
label encodeSlicePatchId(const label&);
// Decoding an encoded patch Id to receive an indexing Id for face-ordered lists
label decodeSlicePatchId(const label&);
// Partition and sort negative key indices (std::pair::first)
// (creates the permutation from sliceable to fragmented data layout)
void partitionByFirst(pairVector<label, label>&);
// Renumber point indices in faces by point mapping
void renumberFaces(faceList& faces, const std::vector<label>& map);
// Return the permutation that sorts the input list
// (creates the permutation from fragmented to sliceable data layout)
std::vector<label> permutationOfSorted(const labelList& input);
/*---------------------------------------------------------------------------*\
Helper Template Functions Declaration
\*---------------------------------------------------------------------------*/
// Create a list of pairs storing the explicit index with the input data
template<typename Container>
pairVector<label, label> generateIndexedPairs(const Container&);
// Create index list with given size and starting index
template<typename Container>
void
indexIota(Container&, const size_t&, const typename Container::value_type&);
// Permute input index list based on sorting of input data
template<typename IndexContainer, typename DataContainer>
void indexSort(IndexContainer&, const DataContainer&);
// Zip-combine two containers of equal length
template<typename Container1, typename Container2>
pairVector<typename Container1::value_type, typename Container2::value_type>
zip(const Container1&, const Container2&);
// Extract values from input that satisfy the unary condition
template<typename ValueType, typename UnaryOperation>
std::vector<Foam::label>
extractNth(const std::vector<ValueType>&, UnaryOperation);
// Determine extend of repeating value sequence in list
template<typename IterType, typename ValType>
void findValueExtend(IterType&, IterType&, const IterType&, const ValType&);
// Permute input data according to the input index list
template<typename Container, typename IndexContainer>
void applyPermutation(Container&, const IndexContainer&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "sliceMeshHelperI.H"
#endif
// ************************************************************************* //

View file

@ -0,0 +1,276 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Free functions
Description
The free functions in this file render algorithms to create the coherent
data layout.
Author
Gregor Weiss, HLRS University of Stuttgart
\*---------------------------------------------------------------------------*/
#include "sliceMeshHelper.H"
#include "Slice.H"
#include <numeric>
template<typename Container>
Foam::pairVector<Foam::label, Foam::label>
Foam::generateIndexedPairs(const Container& input)
{
std::vector<Foam::label> indices{};
indexIota(indices, input.size(), 0);
Foam::pairVector<Foam::label, Foam::label> indexedPairs{};
indexedPairs.reserve(input.size());
std::transform
(
input.begin(),
input.end(),
indices.begin(),
std::back_inserter(indexedPairs),
[](const Foam::label& inputId, const Foam::label& index)
{
return std::make_pair(inputId, index);
}
);
return indexedPairs;
}
template<typename Container>
void Foam::indexIota
(
Container& input,
const size_t& size,
const typename Container::value_type& start
)
{
input.resize(size);
std::iota(input.begin(), input.end(), start);
}
template<typename Container1, typename Container2>
Foam::pairVector
<
typename Container1::value_type,
typename Container2::value_type
>
Foam::zip(const Container1& container1, const Container2& container2)
{
typedef typename Container1::value_type type1;
typedef typename Container2::value_type type2;
pairVector<type1, type2> zipped{};
std::transform
(
container1.begin(),
container1.end(),
container2.begin(),
std::back_inserter(zipped),
[](const type1& value1, const type2& value2)
{
return std::pair<type1, type2>{ value1, value2 };
}
);
return zipped;
}
template<typename IndexContainer, typename DataContainer>
void Foam::indexSort(IndexContainer& indices, const DataContainer& data)
{
typedef typename IndexContainer::value_type index_type;
std::stable_sort
(
indices.begin(),
indices.end(),
[&data](const index_type& i, const index_type& j)
{
return data[i]<data[j];
}
);
}
template<typename InputIterator, typename Container>
void Foam::permutationOfSorted
(
InputIterator begin,
InputIterator end,
const Container& data
)
{
std::iota(begin, end, 0);
std::stable_sort
(
begin,
end,
[&data] (const label& i, const label& j)
{
return data[i] < data[j];
}
);
}
template<typename ValueType, typename UnaryOperation>
std::vector<Foam::label> Foam::extractNth
(
const std::vector<ValueType>& input,
UnaryOperation unary_op
)
{
std::vector<Foam::label> indices; // Only takes containers of labels! TODO
indices.reserve(input.size());
std::transform
(
input.begin(),
input.end(),
std::back_inserter(indices),
unary_op
);
return indices;
}
template<typename IterType, typename ValType>
void Foam::findValueExtend
(
IterType& begin,
IterType& end,
const IterType& fin,
const ValType& value
)
{
begin = std::find_if
(
begin,
fin,
[value](const ValType& element)
{
return element == value;
}
);
end = std::find_if
(
begin,
fin,
[value](const ValType& element)
{
return element != value;
}
);
}
#include <cassert>
template<typename Container, typename IndexContainer>
void Foam::applyPermutation(Container& data, const IndexContainer& permutation)
{
Container output(permutation.size());
for (Foam::label i = 0; i<permutation.size(); ++i)
{
output[i] = std::move(data[permutation[i]]);
}
std::move
(
output.begin(),
output.end(),
data.begin()
);
}
// this only recursively binds to (non-range) arithmetic types, currently.
template
<
typename ForwardIterator,
typename OutputIterator,
typename UnaryPredicate
>
typename std::enable_if
<
std::is_arithmetic
<
typename std::iterator_traits<ForwardIterator>::value_type
>::value,
void
>::type
Foam::subset
(
ForwardIterator input_iter,
const ForwardIterator input_end,
OutputIterator output_iter,
UnaryPredicate unary_predicate
)
{
std::copy_if
(
input_iter,
input_end,
output_iter,
unary_predicate
);
}
template
<
typename ForwardIterator,
typename OutputIterator,
typename UnaryPredicate
>
typename std::enable_if
<
Foam::is_range
<
typename std::iterator_traits<ForwardIterator>::value_type
>::value,
void
>::type
Foam::subset
(
ForwardIterator input_iter,
const ForwardIterator input_end,
OutputIterator output_iter,
UnaryPredicate unary_predicate
)
{
while(input_iter != input_end)
{
Foam::subset
(
input_iter->begin(),
input_iter->end(),
output_iter,
unary_predicate
);
++input_iter;
}
}
// ***************************************************************** //