Commit 7fa8dfca authored by mark's avatar mark

Rework with restarting from a primitive internalField.

parent 7a77ef7e
......@@ -66,6 +66,9 @@ public:
template<class Type, template<class> class PatchField, class GeoMesh>
class BoundaryWriter;
class cloudInfo;
private:
// Private data
......@@ -518,12 +521,141 @@ public:
const BoundaryWriter& adapter
)
{
adapter.object_.writeEntry("boundaryField", os);
adapter.object_.writeEntries(os);
return os;
}
};
//- Helper class for collecting cloud information prior to write
class adiosCoreWrite::cloudInfo
:
public fileName
{
// Private Data
//- Type of the cloud
const word type_;
//- Total number of parcels (sum of nParcels_ list)
label nTotal_;
//- Array containing number of parcels per process (often used list)
List<label> nParcels_;
// Private Member Functions
//- Set the number of parcels and sync across processes
// Return the overall total
void set(label n)
{
// The number of parcels on each process
nParcels_[Pstream::myProcNo()] = n;
Pstream::gatherList(nParcels_);
Pstream::scatterList(nParcels_);
// Sum total number of parcels on all processes
nTotal_ = sum(nParcels_);
}
//- Disallow default bitwise assignment
cloudInfo(const cloudInfo&) = delete;
//- Disallow default bitwise assignment
void operator=(const cloudInfo&) = delete;
public:
//- Construct from cloud regIOobject
explicit cloudInfo(const regIOobject& cloud)
:
fileName
(
adiosCore::cloudPath
(
cloud.db().name(), // = region name
cloud.name() // = cloud name
)
),
type_(cloud.type()),
nTotal_(0),
nParcels_(Pstream::nProcs(), 0)
{}
~cloudInfo()
{}
//- The region name is before the first /
const word regionName() const
{
return substr(0, find('/')); // not designed for failure
}
//- Return the full variable name
inline const fileName& fullName() const
{
return static_cast<const fileName&>(*this);
}
//- Return file name (part beyond last /)
using fileName::name;
//- Return directory path name (part before last /)
using fileName::path;
//- Type of the cloud
const word& type() const
{
return type_;
}
//- Total number of parcels across all processes
label nTotal() const
{
return nTotal_;
}
//- The number of parcels on this process
label nParcels() const
{
return nParcels_[Pstream::myProcNo()];
}
//- Set the number of parcels and sync across processes
// Return the overall total
label nParcels(label n)
{
set(n);
return nTotal_;
}
//- Local process offset within a global array of parcels
label offset() const
{
label off = 0;
for (label prev=0; prev < Pstream::myProcNo(); ++prev)
{
off += nParcels_[prev];
}
return off;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......
......@@ -82,7 +82,7 @@ void Foam::adiosReader::scan(bool verbose)
if (verbose)
{
Info<< "variable: " << vinfo.name() << endl;
vinfo.info(Pout) << endl;
}
}
......@@ -171,7 +171,8 @@ bool Foam::adiosReader::open(const fileName& bpFile, MPI_Comm comm)
if (file)
{
select(adios_selection_writeblock(Pstream::myProcNo()));
scan(false);
// scan(false);
scan(true);
// Info<< "found num-vars: " << file->nvars << endl;
}
......@@ -232,6 +233,7 @@ Foam::adiosReader::getFieldInfo(const word& regName) const
HashTable<fieldInfo> table;
bool hasAux = false;
forAllConstIter(VarContainer, variables, iter)
{
const fileName& varName = iter.key();
......@@ -241,17 +243,65 @@ Foam::adiosReader::getFieldInfo(const word& regName) const
{
// matches regName/field/xxx
fieldInfo info
table.insert
(
varName,
varInfo.sizeOf(),
getStringAttribute(varName/"class")
varName.name(),
fieldInfo
(
varName,
varInfo.sizeOf(),
getStringAttribute(varName/"class")
)
);
}
if (varName.count('/') == 3)
{
hasAux = true;
}
}
// This could be somewhat more efficient, but then it would be less general
if (hasAux)
{
forAllConstIter(VarContainer, variables, iter)
{
const fileName& varName = iter.key();
const VarInfo& varInfo = iter();
table.insert(varName.name(), info);
if (varName.count('/') == 3)
{
const word& parent = varName.path().name();
if (table.found(parent))
{
// matches regName/field/xxx/yyy
table[parent].aux().insert
(
varName.name(),
fieldInfo
(
varName,
varInfo.sizeOf(),
word::null // only parent has this information
)
);
}
else
{
// WARNING?
}
}
}
}
// Info<<"Table ";
// forAllConstIter(HashTable<fieldInfo>, table, iter)
// {
// iter().info(Info);
// }
return table;
}
......
......@@ -139,6 +139,13 @@ public:
inline bool hasVariable(const string& varName) const;
//- True if the specified variable exists
inline const VarInfo& getVariableInfo(const string& varName) const
{
return variables[varName];
}
//- Read integer attribute if it exists
bool readIntAttributeIfPresent
(
......@@ -239,7 +246,6 @@ public:
// On failure the buffer is resized to zero.
template<class T>
size_t getBuffered(const string& varName, DynamicList<T>& buffer) const;
};
......@@ -252,7 +258,7 @@ class adiosReader::VarInfo
label varid_;
enum ADIOS_DATATYPES type_;
label nElem_;
label nElem_;
size_t nBytes_;
......@@ -299,6 +305,9 @@ public:
//- The byte-size for the process local elements
inline size_t sizeOf() const;
//- Output some information
Ostream& info(Ostream& os) const;
};
......@@ -310,6 +319,10 @@ class adiosReader::fieldInfo
word className_;
size_t nBytes_;
//- Can also contain auxiliary field information (eg, field/U/boundaryField)
HashTable<fieldInfo> aux_;
public:
fieldInfo()
......@@ -328,12 +341,13 @@ public:
:
fileName(varName),
className_(className),
nBytes_(nbytes)
nBytes_(nbytes),
aux_()
{}
//- The region name is before the first /
const word regionName() const
inline const word regionName() const
{
return substr(0, find('/')); // not designed for failure
}
......@@ -362,8 +376,45 @@ public:
//- Local size in bytes
inline size_t sizeOf() const
{
return nBytes_;
return nBytes_;
}
inline HashTable<fieldInfo>& aux()
{
return aux_;
}
inline const HashTable<fieldInfo>& aux() const
{
return aux_;
}
//- Output some information
Ostream& info(Ostream& os) const
{
os.beginBlock();
os.writeEntry("name", static_cast<const fileName&>(*this));
if (!className_.empty())
{
os.writeEntry("class", className_);
}
os.writeEntry("sizeof", nBytes_);
forAllConstIter(HashTable<fieldInfo>, aux_, iter)
{
iter().info(os);
}
os.endBlock();
return os;
}
};
......@@ -404,7 +455,7 @@ public:
//- The region name is before the first /
const word regionName() const
inline const word regionName() const
{
return substr(0, find('/')); // not designed for failure
}
......@@ -432,14 +483,14 @@ public:
//- Total number of parcels across all processes
label nTotal() const
inline label nTotal() const
{
return nTotal_;
}
//- The number of parcels on this process
label nParcels() const
inline label nParcels() const
{
return nParcels_;
}
......@@ -467,7 +518,7 @@ public:
//- The parcel encoding information
const ParcelEncoding& encoded() const
inline const ParcelEncoding& encoded() const
{
return encoded_;
}
......
......@@ -74,7 +74,6 @@ size_t Foam::adiosReader::getBuffered
}
template<class StringType>
bool Foam::adiosReader::readStringListAttributeIfPresent
(
......
......@@ -247,4 +247,22 @@ Foam::adiosReader::VarInfo::~VarInfo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::Ostream& Foam::adiosReader::VarInfo::info(Ostream& os) const
{
os.beginBlock();
os.writeEntry("name", name_);
os.writeEntry("varid", varid_);
os.writeEntry("adiosType", label(type_));
os.writeEntry("count", nElem_);
os.writeEntry("sizeof", nBytes_);
os.endBlock();
return os;
}
// ************************************************************************* //
......@@ -41,7 +41,7 @@ then
export ADIOS_EXTRA_COMP="-I$adiosFoam/lnInclude"
export ADIOS_EXTRA_LINK='-L$(FOAM_USER_LIBBIN) -ladiosFoam'
wmake $targetType adiosWrite
wmake $targetType adios
fi
# ----------------------------------------------------------------- end-of-file
read/adiosReadData.C
read/adiosReadField.C
read/adiosReadCloud.C
write/adiosRegion.C
write/adiosWrite.C
write/adiosWriteCloud.C
LIB = $(FOAM_USER_LIBBIN)/libIOadiosWrite
......@@ -34,7 +34,7 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::adiosWrite::readFieldObject
Foam::label Foam::adiosWrite::readFieldObject
(
regIOobject& obj,
const adiosReader& reader,
......@@ -50,15 +50,15 @@ bool Foam::adiosWrite::readFieldObject
Info<<"WARNING mismatch on field " << src
<< " (expected: " << fieldType
<< " but had " << srcType << ")\n";
return false;
return -1;
}
Info<<"read " << obj.name() << " (type " << fieldType << ") from file\n";
Info<<"Read " << obj.name() << " (type " << fieldType << ") from file\n";
// point fields
// Point fields
if (fieldType == pointScalarField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<pointScalarField&>(obj),
reader, src
......@@ -66,7 +66,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == pointVectorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<pointVectorField&>(obj),
reader, src
......@@ -74,7 +74,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == pointSphericalTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<pointSphericalTensorField&>(obj),
reader, src
......@@ -82,7 +82,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == pointSymmTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<pointSymmTensorField&>(obj),
reader, src
......@@ -90,17 +90,17 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == pointTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<pointTensorField&>(obj),
reader, src
);
}
// surface fields
// Surface fields
else if (fieldType == surfaceScalarField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<surfaceScalarField&>(obj),
reader, src
......@@ -108,7 +108,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == surfaceVectorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<surfaceVectorField&>(obj),
reader, src
......@@ -116,7 +116,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == surfaceSphericalTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<surfaceSphericalTensorField&>(obj),
reader, src
......@@ -124,7 +124,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == surfaceSymmTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<surfaceSymmTensorField&>(obj),
reader, src
......@@ -132,17 +132,17 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == surfaceTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<surfaceTensorField&>(obj),
reader, src
);
}
// volume fields
// Volume fields
else if (fieldType == volScalarField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<volScalarField&>(obj),
reader, src
......@@ -150,7 +150,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == volVectorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<volVectorField&>(obj),
reader, src
......@@ -158,7 +158,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == volSphericalTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<volSphericalTensorField&>(obj),
reader, src
......@@ -166,7 +166,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == volSymmTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<volSymmTensorField&>(obj),
reader, src
......@@ -174,7 +174,7 @@ bool Foam::adiosWrite::readFieldObject
}
else if (fieldType == volTensorField::typeName)
{
return fieldRead
return readGeometricField
(
static_cast<volTensorField&>(obj),
reader, src
......@@ -182,10 +182,49 @@ bool Foam::adiosWrite::readFieldObject
}
// TODO: internal volume fields
else
// Internal volume fields
else if (fieldType == volScalarField::Internal::typeName)
{
return false;
return readField
(
static_cast<volScalarField::Internal&>(obj),
reader, src
);
}
else if (fieldType == volVectorField::Internal::typeName)
{
return readField
(
static_cast<volVectorField::Internal&>(obj),
reader, src
);
}
else if (fieldType == volSphericalTensorField::Internal::typeName)
{
return readField
(
static_cast<volSphericalTensorField::Internal&>(obj),
reader, src
);
}
else if (fieldType == volSymmTensorField::Internal::typeName)
{
return readField
(
static_cast<volSymmTensorField::Internal&>(obj),
reader, src
);
}
else if (fieldType == volTensorField::Internal::typeName)
{
return readField
(
static_cast<volTensorField::Internal&>(obj),
reader, src
);
}
return -1;
}
......
......@@ -91,7 +91,7 @@ Foam::label Foam::adiosWrite::writeCloud
typedef OCompactCountStream CloudCountStream;
typedef OCompactBufStream CloudOutputStream;
cloudInfo cInfo(cld);
adiosCoreWrite::cloudInfo cInfo(cld);
// Number of parcels on this process
const label nParcels = cld.size();
......
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "adiosWrite.H"
#include "adiosReader.H"
#include "dictionary.H"
#include "IBufStream.H"
#include "IOstream.H"
#include "IOstreams.H"
#include "Ostream.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type, class SourceType>
Foam::label Foam::adiosWrite::copyList
(
UList<Type>& dst,
const adiosReader& reader,
const fileName& varName
)
{
label sizeRead = -1;
if (reader.hasVariable(varName))
{
const adiosReader::VarInfo& vinfo = reader.getVariableInfo(varName);
transfer_.reserve(vinfo.sizeOf());
size_t nread = reader.getBuffered(varName, transfer_);
sizeRead = (nread / sizeof(SourceType) / pTraits<Type>::nComponents);
// TODO? check sizes
UList<SourceType> src
(
reinterpret_cast<SourceType*>(transfer_.data()),
sizeRead
);
// Component-wise copy
label srcindex = 0;
forAll(dst, i)
{
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; ++cmpt)
{
setComponent(dst[i], cmpt) = src[srcindex++];
}
}
}