Commit f8b02a8f authored by mark's avatar mark

Split up GeometricFields into internal and boundary components

- The internalField can be read directly from adios without any
  additional interpretation. The boundaryField remains a byte-stream
  since this is the only way of preserving all of the information.

- Stop worrying about handling the referenceLevel. This user
  convenience is only used on input and will never appear within an
  adios file.
parent af803b85
......@@ -824,6 +824,22 @@ bool Foam::adiosCoreWrite::defineListAttribute
}
bool Foam::adiosCoreWrite::defineDimensionsAttribute
(
const string& varName,
const dimensionSet& dims
)
{
scalarList units(dimensionSet::nDimensions);
forAll(units, i)
{
units[i] = dims[i];
}
return defineListAttribute("dimensions", varName, units);
}
void Foam::adiosCoreWrite::writeVariable
(
const char* name,
......
......@@ -38,6 +38,7 @@ SourceFiles
#include "adiosCore.H"
#include "dictionary.H"
#include "regIOobject.H"
#include "GeometricField.H"
#include "Pstream.H"
#include "DynamicCharList.H"
......@@ -61,6 +62,12 @@ class adiosCoreWrite
:
public adiosCore
{
public:
// Forward declaration of classes
template<class Type, template<class> class PatchField, class GeoMesh>
class BoundaryWriter;
private:
// Private data
//- ADIOS group identifier
......@@ -172,11 +179,12 @@ protected:
);
//- Define/write adios data for field, return adios Id.
template<class FieldType>
int64_t writeField
//- Define/write adios data for GeometricField, return adios Id.
// Writes internalField directly, boundaryField as a byte-stream
template<class Type, template<class> class PatchField, class GeoMesh>
int64_t writeGeometricField
(
const FieldType& field
const GeometricField<Type, PatchField, GeoMesh>&
);
//- Define/write adios data for internal field, return adios Id.
......@@ -186,6 +194,33 @@ protected:
const FieldType& field
);
//- Define/write adios data for field, return adios Id.
template<class Type, class GeoMesh>
int64_t writeField
(
const fileName& varName,
const word& local,
const DimensionedField<Type, GeoMesh>&
);
//- Define/write adios data for field, return adios Id.
template<class Type, class GeoMesh>
int64_t writeField
(
const fileName& varName,
const DimensionedField<Type, GeoMesh>&
);
//- Write an object as a byte-stream.
// Return adios Id.
template<class Type>
int64_t writeStreamVariable
(
const fileName& varName,
const Type& obj
);
// General adios handling
......@@ -275,6 +310,11 @@ protected:
// Return adios Id.
int64_t defineVectorVariable(const string& name, size_t count);
//- Define a nCmpt variable with count elements.
// Return adios Id.
template<class Type>
int64_t defineFieldVariable(const string& name, size_t count);
//- Define a string attribute
void defineAttribute
......@@ -356,6 +396,14 @@ protected:
const stringList& list
);
//- Define an "dimensions" attribute (an array of doubles).
bool defineDimensionsAttribute
(
const string& varName,
const dimensionSet& dims
);
//- Write a variable
void writeVariable
(
......@@ -448,6 +496,41 @@ public:
};
//- Helper class to write boundaryField as dictionary entries
template<class Type, template<class> class PatchField, class GeoMesh>
class adiosCoreWrite::BoundaryWriter
{
const typename GeometricField<Type, PatchField, GeoMesh>::Boundary&
object_;
public:
//- Constructor
BoundaryWriter
(
const typename GeometricField<Type, PatchField, GeoMesh>::Boundary&
boundary
)
:
object_(boundary)
{}
// Ostream operators
friend Ostream& operator<<
(
Ostream& os,
const BoundaryWriter& adapter
)
{
adapter.object_.writeEntry("boundaryField", os);
return os;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
......@@ -455,7 +538,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "adiosCoreWriteFieldTemplates.C"
#include "adiosCoreWriteTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -41,118 +41,118 @@ int64_t Foam::adiosCoreWrite::writeFieldObject
int64_t varid = -1;
const word& fieldType = obj.type();
// point fields
// Point fields
if (fieldType == pointScalarField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const pointScalarField&>(obj)
);
}
else if (fieldType == pointVectorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const pointVectorField&>(obj)
);
}
else if (fieldType == pointSphericalTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const pointSphericalTensorField&>(obj)
);
}
else if (fieldType == pointSymmTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const pointSymmTensorField&>(obj)
);
}
else if (fieldType == pointTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const pointTensorField&>(obj)
);
}
// surface fields
// Surface fields
else if (fieldType == surfaceScalarField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const surfaceScalarField&>(obj)
);
}
else if (fieldType == surfaceVectorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const surfaceVectorField&>(obj)
);
}
else if (fieldType == surfaceSphericalTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const surfaceSphericalTensorField&>(obj)
);
}
else if (fieldType == surfaceSymmTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const surfaceSymmTensorField&>(obj)
);
}
else if (fieldType == surfaceTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const surfaceTensorField&>(obj)
);
}
// volume fields
// Volume fields
else if (fieldType == volScalarField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const volScalarField&>(obj)
);
}
else if (fieldType == volVectorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const volVectorField&>(obj)
);
}
else if (fieldType == volSphericalTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const volSphericalTensorField&>(obj)
);
}
else if (fieldType == volSymmTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const volSymmTensorField&>(obj)
);
}
else if (fieldType == volTensorField::typeName)
{
varid = testOnly ? 1 : writeField
varid = testOnly ? 1 : writeGeometricField
(
static_cast<const volTensorField&>(obj)
);
}
// internal volume fields
// Internal volume fields
else if (fieldType == volScalarField::Internal::typeName)
{
varid = testOnly ? 1 : writeInternalField
......@@ -167,6 +167,27 @@ int64_t Foam::adiosCoreWrite::writeFieldObject
static_cast<const volVectorField::Internal&>(obj)
);
}
else if (fieldType == volSphericalTensorField::Internal::typeName)
{
varid = testOnly ? 1 : writeInternalField
(
static_cast<const volSphericalTensorField::Internal&>(obj)
);
}
else if (fieldType == volSymmTensorField::Internal::typeName)
{
varid = testOnly ? 1 : writeInternalField
(
static_cast<const volSymmTensorField::Internal&>(obj)
);
}
else if (fieldType == volTensorField::Internal::typeName)
{
varid = testOnly ? 1 : writeInternalField
(
static_cast<const volTensorField::Internal&>(obj)
);
}
return varid;
}
......
......@@ -185,23 +185,8 @@ void Foam::adiosCoreWrite::writeMeshFaces(const polyMesh& mesh)
defineIntVariable(varPath/"neighbour", mesh.faceNeighbour().size());
writeVariable(varPath/"neighbour", mesh.faceNeighbour());
// polyMesh/boundary - byte-stream
{
OutputCounter counter(adiosCore::strFormat);
counter << mesh.boundaryMesh();
int64_t varid = defineStreamVariable(varPath/"boundary", counter.size());
// use iobuffer_ to avoid reallocations
// Needs rework?
iobuffer_.reserve(adios_expected_var_size(varid));
OutputBufStreamer os(iobuffer_, adiosCore::strFormat);
os << mesh.boundaryMesh();
writeVariable(varPath/"boundary", iobuffer_);
}
writeStreamVariable(varPath/"boundary", mesh.boundaryMesh());
}
......
......@@ -25,6 +25,7 @@ License
#include "adiosCoreWrite.H"
#include "pTraits.H"
#include "volFields.H"
#include "surfaceFields.H"
......@@ -37,28 +38,99 @@ License
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * * //
template<class FieldType>
int64_t Foam::adiosCoreWrite::writeField
template<class Type>
int64_t Foam::adiosCoreWrite::defineFieldVariable
(
const FieldType& field
const string& name,
size_t count
)
{
const int64_t varid = writeInternalField(field);
const string local =
(
pTraits<Type>::nComponents > 1
? Foam::name(count) + "," + Foam::name(pTraits<Type>::nComponents)
: Foam::name(count)
);
int64_t varid = adios_define_var
(
groupID_,
name.c_str(), // name
nullptr, // path (deprecated)
adiosTraits<typename pTraits<Type>::cmptType>::adiosType, // data-type
local.c_str(), // local dimensions
nullptr, // global dimensions
nullptr // local offsets
);
vars_.insert(name, varid);
return varid;
}
template<class Type>
int64_t Foam::adiosCoreWrite::writeStreamVariable
(
const fileName& varName,
const Type& obj
)
{
if (varName.name() == "boundary")
{
Info<< "have: " << varName << " => " << obj << endl;
}
OutputCounter counter(adiosCore::strFormat);
counter << obj;
int64_t varid = defineStreamVariable(varName, counter.size());
// Use iobuffer_ to avoid too many reallocations - needs some rework?
iobuffer_.reserve(adios_expected_var_size(varid));
OutputBufStreamer os(iobuffer_, adiosCore::strFormat);
os << obj;
// Do the actual write (as stream)
writeVariable(varName, iobuffer_);
return varid;
}
// dimensions, internalField, boundaryField
template<class Type, template<class> class PatchField, class GeoMesh>
int64_t Foam::adiosCoreWrite::writeGeometricField
(
const GeometricField<Type, PatchField, GeoMesh>& field
)
{
const fileName varName = adiosCore::fieldPath
(
field.db().name(), // = region name
field.name() // = field name
);
const typename GeometricField<Type, PatchField, GeoMesh>::Boundary&
bfield = field.boundaryField();
const typename GeoMesh::BoundaryMesh&
bmesh = field.mesh().boundary();
if (Pstream::master())
{
// Attributes are global - only passed via the master
const typename FieldType::Boundary& bfield = field.boundaryField();
const typename FieldType::BoundaryMesh& bmesh = field.mesh().boundary();
defineAttribute("class", varName, field.type());
defineDimensionsAttribute(varName, field.dimensions());
}
// "internalField" as primitive field
const int64_t varid = writeField(varName, field.internalField());
// Independent of how we store fields,
// a quick lookup of field patch types may prove useful
// Independent of storage, provide a quick lookup of field patch types
if (Pstream::master())
{
// Attributes are global - only passed via the master
stringList pTypes(bfield.size());
label nPatches = 0;
forAll(bfield, patchI)
......@@ -81,6 +153,11 @@ int64_t Foam::adiosCoreWrite::writeField
defineListAttribute("patch-types", varName, pTypes);
}
// "boundaryField" as byte stream, but need adapter for dictionary format
BoundaryWriter<Type, PatchField, GeoMesh> adapter(bfield);
writeStreamVariable(varName/"boundaryField", adapter);
return varid;
}
......@@ -100,36 +177,45 @@ int64_t Foam::adiosCoreWrite::writeInternalField
if (Pstream::master())
{
// Attributes are global - only passed via the master
// Could also write field.dimensions() as an attribute (as required)
defineAttribute("class", varName, field.type());
const dimensionSet& dims = field.dimensions();
scalarList units(dimensionSet::nDimensions);
forAll(units, i)
{
units[i] = dims[i];
}
defineListAttribute("dimensions", varName, units);
defineDimensionsAttribute(varName, field.dimensions());
}
return writeField(varName, field);
}
OutputCounter counter(adiosCore::strFormat);
counter << field;
int64_t varid = defineStreamVariable(varName, counter.size());
// Use iobuffer_ to avoid too many reallocations - needs some rework?
iobuffer_.reserve(adios_expected_var_size(varid));
template<class Type, class GeoMesh>
int64_t Foam::adiosCoreWrite::writeField
(
const fileName& varName,
const word& local,
const DimensionedField<Type, GeoMesh>& field
)
{
int64_t varid = defineFieldVariable<Type>
(
varName/local,
size_t(field.size())
);
writeVariable
(
varName/local,
field.field()
);
OutputBufStreamer os(iobuffer_, adiosCore::strFormat);
os << field;
return varid;
}
// Do the actual write (as stream)
writeVariable(varName, iobuffer_);
return varid;
template<class Type, class GeoMesh>
int64_t Foam::adiosCoreWrite::writeField
(
const fileName& varName,
const DimensionedField<Type, GeoMesh>& field
)
{
return writeField(varName, word::null, field);
}
......
......@@ -213,16 +213,17 @@ Foam::label Foam::adiosWrite::writeCloud
// cloud attributes:
// number of parcels (all processes) as an attribute
//
defineAttribute("class", varName, cInfo.type());
defineIntAttribute("nParcels", varName, cInfo.nTotal());
defineIntAttribute("min-size", varName, encoded.length());
defineIntAttribute("max-size", varName, maxParcelLength);
defineListAttribute("names", varName, encoded.names());
defineListAttribute("types", varName, encoded.types());
defineListAttribute("offset", varName, encoded.offsets());
defineListAttribute("byte-size", varName, encoded.sizes());
if (Pstream::master())
{
defineAttribute("class", varName, cInfo.type());
defineIntAttribute("nParcels", varName, cInfo.nTotal());
defineIntAttribute("min-size", varName, encoded.length());
defineIntAttribute("max-size", varName, maxParcelLength);
defineListAttribute("names", varName, encoded.names());
defineListAttribute("types", varName, encoded.types());
defineListAttribute("offset", varName, encoded.offsets());
defineListAttribute("byte-size", varName, encoded.sizes());
}
// Only if we want expansion
if (expandCloud)
......
......@@ -59,18 +59,6 @@ bool Foam::adiosWrite::fieldRead
// could also verify dimensions
field.readField(dict, "internalField");
field.boundaryFieldRef().readField(field, dict.subDict("boundaryField"));
// TODO: adjust for referenceLevel?
//
// if (dict.found("referenceLevel"))
// {
// Type fieldAverage(pTraits<Type>(dict.lookup("referenceLevel")));
// Field<Type>::operator+=(fieldAverage);
// forAll(boundaryField_, patchI)
// {
// boundaryField_[patchI] == boundaryField_[patchI] + fieldAverage;
// }
// }
}
return nread;
......@@ -109,18 +97,6 @@ bool Foam::adiosWrite::fieldRead
// could also verify dimensions
field.readField(dict, "internalField");
field.boundaryFieldRef().readField(field, dict.subDict("boundaryField"));
// TODO: adjust for referenceLevel?
//
// if (dict.found("referenceLevel"))
// {
// Type fieldAverage(pTraits<Type>(dict.lookup("referenceLevel")));
// Field<Type>::operator+=(fieldAverage);
// forAll(boundaryField_, patchI)
// {
// boundaryField_[patchI] == boundaryField_[patchI] + fieldAverage;
// }
// }
}
return nread;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment