Commit a2e978d4 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

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
parent c4f13494
......@@ -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();
}
}
......
......@@ -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());
outputOptions opts(outOpts);
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);
nParcels_ = parcels.size();
// XML (inline)
os_ << "POINTS " << nParcels_ << " float" << nl;
format()
.xmlHeader()
.xmlComment(title)
.beginVTKFile(vtkFileTag::POLY_DATA, "0.1");
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();
}
}
// ************************************************************************* //
......@@ -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);
};
......
......@@ -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();
}
}
}
......
EXE_INC = \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude
......
......@@ -25,51 +25,62 @@ License
#include "foamVtkInternalWriter.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::foamVtkOutput::internalWriter::internalWriter
(
const fvMesh& mesh,
const foamVtkCells& cells,
const fileName& baseName,
const foamVtkOutput::outputOptions outOpts
)
:
mesh_(mesh),
format_(),
vtkCells_(cells),
os_()
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::foamVtkOutput::internalWriter::beginPiece()
{
outputOptions opts(outOpts);
opts.legacy(true); // Legacy only, no append
if (!legacy_)
{
format()
.openTag(vtkFileTag::PIECE)
( "NumberOfPoints", vtkCells_.nFieldPoints() )
( "NumberOfCells", vtkCells_.nFieldCells() )
.closeTag();
}
}
os_.open((baseName + (opts.legacy() ? ".vtk" : ".vtu")).c_str());
format_ = opts.newFormatter(os_);
if (opts.legacy())
void Foam::foamVtkOutput::internalWriter::writePoints()
{
// payload size
const uint64_t payLoad = (vtkCells_.nFieldPoints() * 3 * sizeof(float));
if (legacy_)
{