ENH: add VTP, VTU output for most vtk writers (insitu only)

- with the xml append format it is possible to write raw binary
  (instead of base64), but the writer becomes more complicated.
  Either needs two passes to create, or need to allocate a block
  of space for the header information (like VTK itself does) and
  write later.

    * internalWriter
    * patchWriter
    * surfaceMeshWriter
    * lagrangianWriter

 Also these special purpose ones:
    * foamVtkWriteSurfFields
This commit is contained in:
Mark Olesen
2017-06-01 18:28:40 +02:00
parent c4f1349496
commit a2e978d43e
25 changed files with 1762 additions and 435 deletions

View File

@ -28,7 +28,7 @@ Group
grpPostProcessingUtilities
Description
Legacy VTK file format writer.
VTK file format writer.
- Handles volFields, pointFields, surfaceScalarField, surfaceVectorField
fields.
@ -46,6 +46,9 @@ Usage
- \par -ascii
Write VTK data in ASCII format instead of binary.
- \par -xml
Write VTK data in XML format instead of legacy format
- \par -mesh \<name\>
Use a different mesh name (instead of -region)
@ -243,6 +246,11 @@ foamVtkOutput::outputOptions getOutputOptions(const argList& args)
{
foamVtkOutput::outputOptions opts;
if (args.optionFound("xml"))
{
opts.ascii(args.optionFound("ascii"));
}
else
{
opts.legacy(true);
@ -335,6 +343,11 @@ int main(int argc, char *argv[])
"write in ASCII format instead of binary"
);
argList::addBoolOption
(
"xml",
"write VTK xml instead of legacy format"
);
argList::addBoolOption
(
"poly",
"write polyhedral cells without tet/pyramid decomposition"
@ -902,6 +915,8 @@ int main(int argc, char *argv[])
writer.endPointData();
}
writer.writeFooter();
}
//---------------------------------------------------------------------
@ -1041,6 +1056,8 @@ int main(int argc, char *argv[])
writer.endPointData();
}
writer.writeFooter();
}
else
{
@ -1118,6 +1135,8 @@ int main(int argc, char *argv[])
writer.endPointData();
}
}
writer.writeFooter();
}
}
@ -1190,6 +1209,8 @@ int main(int argc, char *argv[])
writer.write(sVectorFld);
writer.endCellData();
writer.writeFooter();
}
}
@ -1288,6 +1309,8 @@ int main(int argc, char *argv[])
writer.writeIOField<tensor>(tensorNames);
writer.endParcelData();
writer.writeFooter();
}
else
{
@ -1304,6 +1327,8 @@ int main(int argc, char *argv[])
writer.beginParcelData(0);
writer.endParcelData();
writer.writeFooter();
}
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,6 +27,134 @@ License
#include "Cloud.H"
#include "passiveParticle.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::foamVtkOutput::lagrangianWriter::beginPiece()
{
if (!legacy_)
{
if (useVerts_)
{
format()
.openTag(vtkFileTag::PIECE)
( "NumberOfPoints", nParcels_ )
( "NumberOfVerts", nParcels_ )
.closeTag();
}
else
{
format()
.openTag(vtkFileTag::PIECE)
( "NumberOfPoints", nParcels_ )
.closeTag();
}
}
}
void Foam::foamVtkOutput::lagrangianWriter::writePoints()
{
Cloud<passiveParticle> parcels(mesh_, cloudName_, false);
nParcels_ = parcels.size();
const uint64_t payLoad = (nParcels_ * 3 * sizeof(float));
if (legacy_)
{
legacy::beginPoints(os_, nParcels_);
}
else
{
beginPiece(); // Tricky - hide in here
format().tag(vtkFileTag::POINTS)
.openDataArray<float,3>(vtkFileTag::POINTS)
.closeTag();
}
format().writeSize(payLoad);
forAllConstIters(parcels, iter)
{
const point& pt = iter().position();
foamVtkOutput::write(format(), pt);
}
format().flush();
if (!legacy_)
{
format()
.endDataArray()
.endTag(vtkFileTag::POINTS);
}
}
void Foam::foamVtkOutput::lagrangianWriter::writeVertsLegacy()
{
os_ << "VERTICES " << nParcels_ << ' ' << 2*nParcels_ << nl;
// legacy has cells + connectivity together
// count the number of vertices referenced
for (label i=0; i < nParcels_; ++i)
{
format().write(1); // Number of vertices for this cell (==1)
format().write(i);
}
format().flush();
}
void Foam::foamVtkOutput::lagrangianWriter::writeVerts()
{
format().tag(vtkFileTag::VERTS);
// Same payload throughout
const uint64_t payLoad = (nParcels_ * sizeof(label));
//
// 'connectivity'
// = linear mapping onto points
//
{
format().openDataArray<label>("connectivity")
.closeTag();
format().writeSize(payLoad);
for (label i=0; i < nParcels_; ++i)
{
format().write(i);
}
format().flush();
format().endDataArray();
}
//
// 'offsets' (connectivity offsets)
// = linear mapping onto points (with 1 offset)
//
{
format().openDataArray<label>("offsets")
.closeTag();
format().writeSize(payLoad);
for (label i=0; i < nParcels_; ++i)
{
format().write(i+1);
}
format().flush();
format().endDataArray();
}
format().endTag(vtkFileTag::VERTS);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::foamVtkOutput::lagrangianWriter::lagrangianWriter
@ -39,43 +167,54 @@ Foam::foamVtkOutput::lagrangianWriter::lagrangianWriter
)
:
mesh_(mesh),
legacy_(outOpts.legacy()),
useVerts_(false),
format_(),
cloudName_(cloudName),
os_(),
nParcels_(0)
{
outputOptions opts(outOpts);
opts.legacy(true); // Legacy only, no append
os_.open((baseName + (opts.legacy() ? ".vtk" : ".vtp")).c_str());
opts.append(false); // No append supported
os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str());
format_ = opts.newFormatter(os_);
if (opts.legacy())
{
foamVtkOutput::legacy::fileHeader(format(), mesh_.time().caseName())
<< "DATASET POLYDATA" << nl;
}
const auto& title = mesh_.time().caseName();
if (dummyCloud)
if (legacy_)
{
os_ << "POINTS " << nParcels_ << " float" << nl;
legacy::fileHeader(format(), title, vtkFileTag::POLY_DATA);
if (dummyCloud)
{
legacy::beginPoints(os_, nParcels_);
}
else
{
writePoints();
if (useVerts_) writeVertsLegacy();
}
}
else
{
Cloud<passiveParticle> parcels(mesh, cloudName_, false);
// XML (inline)
nParcels_ = parcels.size();
format()
.xmlHeader()
.xmlComment(title)
.beginVTKFile(vtkFileTag::POLY_DATA, "0.1");
os_ << "POINTS " << nParcels_ << " float" << nl;
forAllConstIters(parcels, iter)
if (dummyCloud)
{
const point& pt = iter().position();
foamVtkOutput::write(format(), pt);
beginPiece();
}
else
{
writePoints();
if (useVerts_) writeVerts();
}
format().flush();
}
}
@ -88,17 +227,53 @@ Foam::foamVtkOutput::lagrangianWriter::~lagrangianWriter()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::foamVtkOutput::lagrangianWriter::beginParcelData
(
const label nFields
)
void Foam::foamVtkOutput::lagrangianWriter::beginParcelData(label nFields)
{
foamVtkOutput::legacy::pointDataHeader(os_, nParcels_, nFields);
const vtkFileTag dataType =
(
useVerts_
? vtkFileTag::CELL_DATA
: vtkFileTag::POINT_DATA
);
if (legacy_)
{
legacy::dataHeader(os_, dataType, nParcels_, nFields);
}
else
{
format().tag(dataType);
}
}
void Foam::foamVtkOutput::lagrangianWriter::endParcelData()
{}
{
const vtkFileTag dataType =
(
useVerts_
? vtkFileTag::CELL_DATA
: vtkFileTag::POINT_DATA
);
if (!legacy_)
{
format().endTag(dataType);
}
}
void Foam::foamVtkOutput::lagrangianWriter::writeFooter()
{
if (!legacy_)
{
// slight cheat. </Piece> too
format().endTag(vtkFileTag::PIECE);
format().endTag(vtkFileTag::POLY_DATA)
.endVTKFile();
}
}
// ************************************************************************* //

View File

@ -52,20 +52,51 @@ namespace foamVtkOutput
{
/*---------------------------------------------------------------------------*\
Class lagrangianWriter Declaration
Class lagrangianWriter Declaration
\*---------------------------------------------------------------------------*/
class lagrangianWriter
{
const fvMesh& mesh_;
// Private Member Data
autoPtr<foamVtkOutput::formatter> format_;
//- Reference to the OpenFOAM mesh (or subset)
const fvMesh& mesh_;
const word cloudName_;
//- Commonly used query
const bool legacy_;
std::ofstream os_;
//- Write lagrangian as cell data (verts) or point data?
const bool useVerts_;
label nParcels_;
autoPtr<foamVtkOutput::formatter> format_;
const word cloudName_;
std::ofstream os_;
label nParcels_;
// Private Member Functions
//- Begin piece
void beginPiece();
//- Write positions
void writePoints();
//- Write vertex (cells)
void writeVertsLegacy();
//- Write vertex (cells)
void writeVerts();
//- Disallow default bitwise copy construct
lagrangianWriter(const lagrangianWriter&) = delete;
//- Disallow default bitwise assignment
void operator=(const lagrangianWriter&) = delete;
public:
@ -104,13 +135,15 @@ public:
return nParcels_;
}
void beginParcelData(const label nFields);
void beginParcelData(label nFields);
void endParcelData();
//- Write file footer
void writeFooter();
//- Write IOField
template<class Type>
void writeIOField(const wordList&);
void writeIOField(const wordList& objectNames);
};

View File

@ -31,33 +31,78 @@ License
template<class Type>
void Foam::foamVtkOutput::lagrangianWriter::writeIOField
(
const wordList& objects
const wordList& objectNames
)
{
forAll(objects, i)
{
const word& object = objects[i];
const int nCmpt(pTraits<Type>::nComponents);
const bool useIntField =
std::is_integral<typename pTraits<Type>::cmptType>();
for (const word& fldName : objectNames)
{
IOobject header
(
object,
fldName,
mesh_.time().timeName(),
cloud::prefix/cloudName_,
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
false // no register
);
IOField<Type> fld(header);
// Legacy
os()<< object << ' '
<< int(pTraits<Type>::nComponents) << ' '
<< fld.size() << " float" << nl;
if (useIntField)
{
const uint64_t payLoad(fld.size() * nCmpt * sizeof(label));
if (legacy_)
{
legacy::intField(os(), fldName, nCmpt, fld.size());
}
else
{
format().openDataArray<label, nCmpt>(fldName)
.closeTag();
}
format().writeSize(payLoad);
// Ensure consistent output width
for (const Type& val : fld)
{
for (int cmpt=0; cmpt < nCmpt; ++cmpt)
{
format().write(label(component(val, cmpt)));
}
}
}
else
{
const uint64_t payLoad(fld.size() * nCmpt * sizeof(float));
if (legacy_)
{
legacy::floatField(os(), fldName, nCmpt, fld.size());
}
else
{
format().openDataArray<float, nCmpt>(fldName)
.closeTag();
}
format().writeSize(payLoad);
foamVtkOutput::writeList(format(), fld);
}
foamVtkOutput::writeList(format(), fld);
format().flush();
if (!legacy_)
{
format().endDataArray();
}
}
}