ENH: parallel and xml output for vtk::lagrangianWriter (issue #926)
This commit is contained in:
parent
9d8af49c16
commit
6f06ce6e02
@ -1,286 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "foamVtkLagrangianWriter.H"
|
||||
#include "Cloud.H"
|
||||
#include "passiveParticle.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::vtk::lagrangianWriter::beginPiece()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
if (useVerts_)
|
||||
{
|
||||
format()
|
||||
.openTag(vtk::fileTag::PIECE)
|
||||
.xmlAttr(fileAttr::NUMBER_OF_POINTS, nParcels_)
|
||||
.xmlAttr(fileAttr::NUMBER_OF_VERTS, nParcels_)
|
||||
.closeTag();
|
||||
}
|
||||
else
|
||||
{
|
||||
format()
|
||||
.openTag(vtk::fileTag::PIECE)
|
||||
.xmlAttr(fileAttr::NUMBER_OF_POINTS, nParcels_)
|
||||
.closeTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::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 begin piece in here
|
||||
if (!nParcels_) return; // No parcels? ... skip everything else
|
||||
|
||||
format().tag(vtk::fileTag::POINTS)
|
||||
.openDataArray<float,3>(vtk::dataArrayAttr::POINTS)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
|
||||
forAllConstIters(parcels, iter)
|
||||
{
|
||||
const point pt(iter().position());
|
||||
|
||||
vtk::write(format(), pt);
|
||||
}
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format()
|
||||
.endDataArray()
|
||||
.endTag(vtk::fileTag::POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::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(label(1)); // Number of vertices for this cell (==1)
|
||||
format().write(i);
|
||||
}
|
||||
format().flush();
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::lagrangianWriter::writeVerts()
|
||||
{
|
||||
format().tag(vtk::fileTag::VERTS);
|
||||
|
||||
// Same payload throughout
|
||||
const uint64_t payLoad = (nParcels_ * sizeof(label));
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
// = linear mapping onto points
|
||||
//
|
||||
{
|
||||
format().openDataArray<label>(vtk::dataArrayAttr::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>(vtk::dataArrayAttr::OFFSETS)
|
||||
.closeTag();
|
||||
|
||||
format().writeSize(payLoad);
|
||||
for (label i=0; i < nParcels_; ++i)
|
||||
{
|
||||
format().write(i+1);
|
||||
}
|
||||
format().flush();
|
||||
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
format().endTag(vtk::fileTag::VERTS);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::vtk::lagrangianWriter::lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const fileName& baseName,
|
||||
const vtk::outputOptions outOpts,
|
||||
const bool dummyCloud
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
legacy_(outOpts.legacy()),
|
||||
useVerts_(false),
|
||||
format_(),
|
||||
cloudName_(cloudName),
|
||||
os_(),
|
||||
nParcels_(0)
|
||||
{
|
||||
|
||||
outputOptions opts(outOpts);
|
||||
opts.append(false); // No append supported
|
||||
|
||||
os_.open((baseName + (legacy_ ? ".vtk" : ".vtp")).c_str());
|
||||
format_ = opts.newFormatter(os_);
|
||||
|
||||
const auto& title = mesh_.time().caseName();
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::fileHeader(format(), title, vtk::fileTag::POLY_DATA);
|
||||
|
||||
if (dummyCloud)
|
||||
{
|
||||
legacy::beginPoints(os_, nParcels_);
|
||||
}
|
||||
else
|
||||
{
|
||||
writePoints();
|
||||
if (useVerts_) writeVertsLegacy();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// XML (inline)
|
||||
|
||||
format()
|
||||
.xmlHeader()
|
||||
.xmlComment(title)
|
||||
.beginVTKFile(vtk::fileTag::POLY_DATA, "0.1");
|
||||
|
||||
if (dummyCloud)
|
||||
{
|
||||
beginPiece();
|
||||
}
|
||||
else
|
||||
{
|
||||
writePoints();
|
||||
if (useVerts_) writeVerts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::vtk::lagrangianWriter::beginParcelData(label nFields)
|
||||
{
|
||||
if (!nParcels_) return; // Skip if there are no parcels
|
||||
|
||||
if (useVerts_)
|
||||
{
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::beginCellData(format(), nParcels_, nFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().beginCellData();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::beginPointData(format(), nParcels_, nFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
format().beginPointData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::lagrangianWriter::endParcelData()
|
||||
{
|
||||
if (!nParcels_) return; // Skip if there are no parcels
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
|
||||
if (useVerts_)
|
||||
{
|
||||
format().endCellData();
|
||||
}
|
||||
else
|
||||
{
|
||||
format().endPointData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::lagrangianWriter::writeFooter()
|
||||
{
|
||||
if (!legacy_)
|
||||
{
|
||||
// slight cheat. </Piece> too
|
||||
format().endTag(vtk::fileTag::PIECE);
|
||||
|
||||
format().endTag(vtk::fileTag::POLY_DATA)
|
||||
.endVTKFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -1,168 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Class
|
||||
Foam::vtk::lagrangianWriter
|
||||
|
||||
Description
|
||||
Write lagrangian positions and fields (clouds).
|
||||
|
||||
SourceFiles
|
||||
lagrangianWriter.C
|
||||
lagrangianWriterTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef foamVtkLagrangianWriter_H
|
||||
#define foamVtkLagrangianWriter_H
|
||||
|
||||
#include "Cloud.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "foamVtkOutputOptions.H"
|
||||
#include <fstream>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
class volPointInterpolation;
|
||||
|
||||
namespace vtk
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class lagrangianWriter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class lagrangianWriter
|
||||
{
|
||||
// Private Member Data
|
||||
|
||||
//- Reference to the OpenFOAM mesh (or subset)
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- Commonly used query
|
||||
const bool legacy_;
|
||||
|
||||
//- Write lagrangian as cell data (verts) or point data?
|
||||
const bool useVerts_;
|
||||
|
||||
autoPtr<vtk::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();
|
||||
|
||||
|
||||
//- No copy construct
|
||||
lagrangianWriter(const lagrangianWriter&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const lagrangianWriter&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const fileName& baseName,
|
||||
const vtk::outputOptions outOpts,
|
||||
const bool dummyCloud = false
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~lagrangianWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
inline std::ofstream& os()
|
||||
{
|
||||
return os_;
|
||||
}
|
||||
|
||||
inline vtk::formatter& format()
|
||||
{
|
||||
return *format_;
|
||||
}
|
||||
|
||||
inline label nParcels() const
|
||||
{
|
||||
return nParcels_;
|
||||
}
|
||||
|
||||
//- Begin parcel data (point data).
|
||||
// The nFields parameter is only needed for legacy format.
|
||||
void beginParcelData(label nFields);
|
||||
void endParcelData();
|
||||
|
||||
//- Write file footer
|
||||
void writeFooter();
|
||||
|
||||
//- Write IOFields
|
||||
template<class Type>
|
||||
void writeIOField(const wordList& fieldNames);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace vtk
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "foamVtkLagrangianWriterTemplates.C"
|
||||
#endif
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -1,128 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "foamVtkLagrangianWriter.H"
|
||||
#include "IOField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
|
||||
const bool useIntField =
|
||||
std::is_integral<typename pTraits<Type>::cmptType>();
|
||||
|
||||
const fileName cloudDir(cloud::prefix/cloudName_);
|
||||
|
||||
for (const word& fldName : fieldNames)
|
||||
{
|
||||
// Globally the field is expected to exist (MUST_READ), but can
|
||||
// be missing on a local processor.
|
||||
//
|
||||
// However, constructing IOField with MUST_READ and valid=false fails.
|
||||
// Workaround: READ_IF_PRESENT and verify the header globally
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
fldName,
|
||||
mesh_.time().timeName(),
|
||||
cloudDir,
|
||||
mesh_,
|
||||
IOobject::READ_IF_PRESENT
|
||||
);
|
||||
|
||||
// Check global existence - could make an error
|
||||
const bool fieldExists =
|
||||
returnReduce
|
||||
(
|
||||
fieldObject.typeHeaderOk<IOField<Type>>(false),
|
||||
orOp<bool>()
|
||||
);
|
||||
|
||||
if (!fieldExists)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IOField<Type> fld(fieldObject);
|
||||
|
||||
// NOTE: Could skip if there are no local parcels...
|
||||
|
||||
if (useIntField)
|
||||
{
|
||||
const uint64_t payLoad(fld.size() * nCmpt * sizeof(label));
|
||||
|
||||
if (legacy_)
|
||||
{
|
||||
legacy::intField<nCmpt>(format(), fldName, 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<nCmpt>(format(), fldName, fld.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
format().openDataArray<float, nCmpt>(fldName)
|
||||
.closeTag();
|
||||
}
|
||||
|
||||
format().writeSize(payLoad);
|
||||
vtk::writeList(format(), fld);
|
||||
}
|
||||
|
||||
format().flush();
|
||||
|
||||
if (!legacy_)
|
||||
{
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -118,5 +118,8 @@ clouds/Templates/KinematicCloud/cloudSolution/cloudSolution.C
|
||||
/* averaging methods */
|
||||
submodels/MPPIC/AveragingMethods/makeAveragingMethods.C
|
||||
|
||||
/* conversion methods */
|
||||
conversion/vtk/foamVtkLagrangianWriter.C
|
||||
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/liblagrangianIntermediate
|
||||
|
@ -16,6 +16,7 @@ EXE_INC = \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
@ -35,4 +36,5 @@ LIB_LIBS = \
|
||||
-ldynamicFvMesh \
|
||||
-lsampling \
|
||||
-lfiniteVolume \
|
||||
-lfileFormats \
|
||||
-lmeshTools
|
||||
|
@ -0,0 +1,306 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016-2018 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 "foamVtkLagrangianWriter.H"
|
||||
#include "Cloud.H"
|
||||
#include "passiveParticle.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::fileName Foam::vtk::lagrangianWriter::cloudDir() const
|
||||
{
|
||||
return (cloud::prefix/cloudName_);
|
||||
}
|
||||
|
||||
|
||||
Foam::pointField Foam::vtk::lagrangianWriter::positions() const
|
||||
{
|
||||
Cloud<passiveParticle> parcels(mesh_, cloudName_, false);
|
||||
|
||||
pointField pts(parcels.size());
|
||||
|
||||
auto outIter = pts.begin();
|
||||
|
||||
forAllConstIters(parcels, iter)
|
||||
{
|
||||
*outIter = iter().position();
|
||||
++outIter;
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtk::lagrangianWriter::writeVerts()
|
||||
{
|
||||
// No collectives - can skip on slave processors
|
||||
if (!format_) return;
|
||||
|
||||
const label nVerts = numberOfPoints_;
|
||||
|
||||
// Same payload for connectivity and offsets
|
||||
const uint64_t payLoad = vtk::sizeofData<label>(nVerts);
|
||||
|
||||
|
||||
format().tag(vtk::fileTag::VERTS);
|
||||
|
||||
//
|
||||
// 'connectivity'
|
||||
// = linear mapping onto points
|
||||
//
|
||||
{
|
||||
format().beginDataArray<label>(vtk::dataArrayAttr::CONNECTIVITY);
|
||||
format().writeSize(payLoad);
|
||||
|
||||
for (label i=0; i < nVerts; ++i)
|
||||
{
|
||||
format().write(i);
|
||||
}
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
//
|
||||
// 'offsets' (connectivity offsets)
|
||||
// = linear mapping onto points (with 1 offset)
|
||||
//
|
||||
{
|
||||
format().beginDataArray<label>(vtk::dataArrayAttr::OFFSETS);
|
||||
format().writeSize(payLoad);
|
||||
|
||||
for (label i=0; i < nVerts; ++i)
|
||||
{
|
||||
format().write(i+1);
|
||||
}
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
}
|
||||
|
||||
format().endTag(vtk::fileTag::VERTS);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::beginCellData(label nFields)
|
||||
{
|
||||
return enter_CellData(numberOfPoints_, nFields);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::beginPointData(label nFields)
|
||||
{
|
||||
return enter_PointData(numberOfPoints_, nFields);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::vtk::lagrangianWriter::lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const vtk::outputOptions opts,
|
||||
bool useVerts
|
||||
)
|
||||
:
|
||||
vtk::fileWriter(vtk::fileTag::POLY_DATA, opts),
|
||||
mesh_(mesh),
|
||||
cloudName_(cloudName),
|
||||
numberOfPoints_(0),
|
||||
useVerts_(useVerts)
|
||||
{
|
||||
opts_.append(false); // No append mode (horrible for streaming)
|
||||
opts_.legacy(false); // Disallow legacy (see notes)
|
||||
}
|
||||
|
||||
|
||||
Foam::vtk::lagrangianWriter::lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const fileName& file,
|
||||
bool parallel
|
||||
)
|
||||
:
|
||||
lagrangianWriter(mesh, cloudName)
|
||||
{
|
||||
open(file, parallel);
|
||||
}
|
||||
|
||||
|
||||
Foam::vtk::lagrangianWriter::lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const vtk::outputOptions opts,
|
||||
const fileName& file,
|
||||
bool parallel
|
||||
)
|
||||
:
|
||||
lagrangianWriter(mesh, cloudName, opts)
|
||||
{
|
||||
open(file, parallel);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::beginFile(std::string title)
|
||||
{
|
||||
if (title.size())
|
||||
{
|
||||
return vtk::fileWriter::beginFile(title);
|
||||
}
|
||||
|
||||
// Provide default title
|
||||
|
||||
// XML (inline)
|
||||
|
||||
return vtk::fileWriter::beginFile
|
||||
(
|
||||
"case='" + mesh_.time().globalCaseName()
|
||||
+ "' cloud='" + cloudName_
|
||||
+ "' time='" + mesh_.time().timeName()
|
||||
+ "' index='" + Foam::name(mesh_.time().timeIndex())
|
||||
+ "'"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::writeGeometry()
|
||||
{
|
||||
enter_Piece();
|
||||
|
||||
if (isState(outputState::CELL_DATA))
|
||||
{
|
||||
++nCellData_;
|
||||
}
|
||||
else if (isState(outputState::POINT_DATA))
|
||||
{
|
||||
++nPointData_;
|
||||
}
|
||||
|
||||
// Transcribe cloud into pointField
|
||||
pointField cloudPoints(positions());
|
||||
|
||||
numberOfPoints_ = cloudPoints.size();
|
||||
|
||||
if (parallel_)
|
||||
{
|
||||
reduce(numberOfPoints_, sumOp<label>());
|
||||
}
|
||||
|
||||
|
||||
// beginPiece()
|
||||
if (format_)
|
||||
{
|
||||
if (useVerts_)
|
||||
{
|
||||
format()
|
||||
.tag
|
||||
(
|
||||
vtk::fileTag::PIECE,
|
||||
fileAttr::NUMBER_OF_POINTS, numberOfPoints_,
|
||||
fileAttr::NUMBER_OF_VERTS, numberOfPoints_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
format()
|
||||
.tag
|
||||
(
|
||||
vtk::fileTag::PIECE,
|
||||
fileAttr::NUMBER_OF_POINTS, numberOfPoints_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// writePoints()
|
||||
{
|
||||
if (format_)
|
||||
{
|
||||
const uint64_t payLoad =
|
||||
vtk::sizeofData<float,3>(numberOfPoints_);
|
||||
|
||||
format().tag(vtk::fileTag::POINTS)
|
||||
.beginDataArray<float,3>(vtk::dataArrayAttr::POINTS);
|
||||
|
||||
format().writeSize(payLoad);
|
||||
}
|
||||
|
||||
if (parallel_)
|
||||
{
|
||||
vtk::writeListParallel(format_.ref(), cloudPoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtk::writeList(format(), cloudPoints);
|
||||
}
|
||||
|
||||
|
||||
if (format_)
|
||||
{
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
|
||||
// Non-legacy
|
||||
format()
|
||||
.endTag(vtk::fileTag::POINTS);
|
||||
}
|
||||
}
|
||||
|
||||
if (useVerts_) writeVerts();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::beginParcelData()
|
||||
{
|
||||
if (useVerts_)
|
||||
{
|
||||
return beginCellData();
|
||||
}
|
||||
else
|
||||
{
|
||||
return beginPointData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::vtk::lagrangianWriter::endParcelData()
|
||||
{
|
||||
if (useVerts_)
|
||||
{
|
||||
return endCellData();
|
||||
}
|
||||
else
|
||||
{
|
||||
return endPointData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016-2018 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/>.
|
||||
|
||||
Class
|
||||
Foam::vtk::lagrangianWriter
|
||||
|
||||
Description
|
||||
Write lagrangian (cloud) positions and fields (as PointData) in
|
||||
VTP format. Legacy VTK format is intentionally not supported since
|
||||
the VTP format provides much better field selection in ParaView, and for
|
||||
consistency with the Foam::functionObjects::vtkCloud function object.
|
||||
|
||||
The file output states are managed by the Foam::vtk::fileWriter class.
|
||||
FieldData (eg, TimeValue) must appear before any geometry pieces.
|
||||
|
||||
Note
|
||||
If fields should be CellData instead of PointData (default), this
|
||||
must be decided at contruction time.
|
||||
|
||||
SourceFiles
|
||||
lagrangianWriter.C
|
||||
lagrangianWriterTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef foamVtkLagrangianWriter_H
|
||||
#define foamVtkLagrangianWriter_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
#include "pointField.H"
|
||||
#include "foamVtkFileWriter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class IOobjectList;
|
||||
template<class Type> class IOField;
|
||||
|
||||
namespace vtk
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class vtk::lagrangianWriter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class lagrangianWriter
|
||||
:
|
||||
public vtk::fileWriter
|
||||
{
|
||||
// Private Member Data
|
||||
|
||||
//- Reference to the OpenFOAM mesh (or subset)
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- The cloud name
|
||||
const word cloudName_;
|
||||
|
||||
//- The numer of field points for the current Piece
|
||||
label numberOfPoints_;
|
||||
|
||||
//- Write as CellData (verts) instead of as PointData.
|
||||
const bool useVerts_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- The cloud directory for the current cloud name.
|
||||
fileName cloudDir() const;
|
||||
|
||||
//- Transcribe the cloud into pointField
|
||||
pointField positions() const;
|
||||
|
||||
//- Write vertex (cells)
|
||||
void writeVerts();
|
||||
|
||||
|
||||
//- No copy construct
|
||||
lagrangianWriter(const lagrangianWriter&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const lagrangianWriter&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Begin CellData output section for specified number of fields.
|
||||
// Must be called prior to writing any cell data fields.
|
||||
// \param nFields is the number of fields, which is required for
|
||||
// legacy format.
|
||||
// \note Expected calling states: (PIECE | POINT_DATA).
|
||||
//
|
||||
// \return True if the state changed
|
||||
virtual bool beginCellData(label nFields=0);
|
||||
|
||||
//- Begin PointData for specified number of fields.
|
||||
// Must be called prior to writing any point data fields.
|
||||
// \param nFields is the number of fields, which is required for
|
||||
// legacy format.
|
||||
// \note Expected calling states: (PIECE | CELL_DATA).
|
||||
//
|
||||
// \return True if the state changed
|
||||
virtual bool beginPointData(label nFields=0);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components (default format INLINE_BASE64)
|
||||
// \param useVerts Define VERTS and use CellData instead of PointData.
|
||||
lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const vtk::outputOptions opts = vtk::formatType::INLINE_BASE64,
|
||||
bool useVerts = false
|
||||
);
|
||||
|
||||
//- Construct from components (default format INLINE_BASE64),
|
||||
//- and open the file for writing.
|
||||
// The file name is with/without an extension.
|
||||
lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const fileName& file,
|
||||
bool parallel = Pstream::parRun()
|
||||
);
|
||||
|
||||
//- Construct from components and open the file for writing.
|
||||
// The file name is with/without an extension.
|
||||
lagrangianWriter
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& cloudName,
|
||||
const vtk::outputOptions opts,
|
||||
const fileName& file,
|
||||
bool parallel = Pstream::parRun()
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~lagrangianWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- File extension for current format type.
|
||||
using vtk::fileWriter::ext;
|
||||
|
||||
//- File extension for given output type. Always ".vtp"
|
||||
inline static word ext(vtk::outputOptions)
|
||||
{
|
||||
// No legacy
|
||||
return vtk::fileExtension[vtk::fileTag::POLY_DATA];
|
||||
}
|
||||
|
||||
|
||||
//- Write file header (non-collective)
|
||||
// \note Expected calling states: (OPENED).
|
||||
virtual bool beginFile(std::string title = "");
|
||||
|
||||
//- Write cloud positions
|
||||
// Also writes the file header if not previously written.
|
||||
// \note Must be called prior to writing CellData or PointData
|
||||
virtual bool writeGeometry();
|
||||
|
||||
|
||||
//- Begin parcel (PointData) output section
|
||||
// Must be called prior to writing data fields.
|
||||
// \note Expected calling states: (PIECE).
|
||||
//
|
||||
// \return True if the state changed
|
||||
bool beginParcelData();
|
||||
|
||||
//- Explicitly end parcel (PointData) output and switch to PIECE state
|
||||
// Ignored (no-op) if not currently in the parcel state.
|
||||
bool endParcelData();
|
||||
|
||||
|
||||
// Write
|
||||
|
||||
//- Write the IOField
|
||||
template<class Type>
|
||||
void write(const IOField<Type>& field);
|
||||
|
||||
//- Write IOFields
|
||||
template<class Type>
|
||||
label writeFields(const wordList& fieldNames, bool verbose=true);
|
||||
|
||||
//- Write IOFields
|
||||
template<class Type>
|
||||
label writeFields(const IOobjectList& objects, bool verbose=true);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace vtk
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "foamVtkLagrangianWriterTemplates.C"
|
||||
#endif
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,207 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2016-2018 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 "foamVtkLagrangianWriter.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "IOField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::vtk::lagrangianWriter::write(const IOField<Type>& field)
|
||||
{
|
||||
if (isState(outputState::CELL_DATA))
|
||||
{
|
||||
++nCellData_;
|
||||
}
|
||||
else if (isState(outputState::POINT_DATA))
|
||||
{
|
||||
++nPointData_;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Bad writer state (" << stateNames[state_]
|
||||
<< ") - should be (" << stateNames[outputState::CELL_DATA]
|
||||
<< ") or (" << stateNames[outputState::POINT_DATA]
|
||||
<< ") for field " << field.name() << nl << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
static_assert
|
||||
(
|
||||
(
|
||||
std::is_same<typename pTraits<Type>::cmptType,label>::value
|
||||
|| std::is_floating_point<typename pTraits<Type>::cmptType>::value
|
||||
),
|
||||
"Label and Floating-point vector space only"
|
||||
);
|
||||
|
||||
|
||||
// Other integral types (eg, bool etc) would need cast/convert to label.
|
||||
// Similarly for labelVector etc.
|
||||
|
||||
// // Ensure consistent output width
|
||||
// for (const Type& val : field)
|
||||
// {
|
||||
// for (int cmpt=0; cmpt < nCmpt; ++cmpt)
|
||||
// {
|
||||
// format().write(label(component(val, cmpt)));
|
||||
// }
|
||||
// }
|
||||
|
||||
const bool isLabel =
|
||||
std::is_same<typename pTraits<Type>::cmptType(), label>::value;
|
||||
|
||||
|
||||
const direction nCmpt(pTraits<Type>::nComponents);
|
||||
|
||||
label nVals = field.size();
|
||||
|
||||
if (parallel_)
|
||||
{
|
||||
reduce(nVals, sumOp<label>());
|
||||
}
|
||||
|
||||
if (format_)
|
||||
{
|
||||
// Non-legacy
|
||||
|
||||
if (isLabel)
|
||||
{
|
||||
const uint64_t payLoad = vtk::sizeofData<label, nCmpt>(nVals);
|
||||
|
||||
format().beginDataArray<label, nCmpt>(field.name());
|
||||
format().writeSize(payLoad);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint64_t payLoad = vtk::sizeofData<float, nCmpt>(nVals);
|
||||
|
||||
format().beginDataArray<float, nCmpt>(field.name());
|
||||
format().writeSize(payLoad);
|
||||
}
|
||||
}
|
||||
|
||||
if (parallel_)
|
||||
{
|
||||
vtk::writeListParallel(format_.ref(), field);
|
||||
}
|
||||
else
|
||||
{
|
||||
vtk::writeList(format(), field);
|
||||
}
|
||||
|
||||
|
||||
if (format_)
|
||||
{
|
||||
format().flush();
|
||||
format().endDataArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::label Foam::vtk::lagrangianWriter::writeFields
|
||||
(
|
||||
const wordList& fieldNames,
|
||||
bool verbose
|
||||
)
|
||||
{
|
||||
const fileName localDir(cloudDir());
|
||||
|
||||
label nFields = 0;
|
||||
|
||||
for (const word& fieldName : fieldNames)
|
||||
{
|
||||
// Globally the field is expected to exist (MUST_READ), but can
|
||||
// be missing on a local processor.
|
||||
//
|
||||
// However, constructing IOField with MUST_READ and valid=false fails.
|
||||
// Workaround: READ_IF_PRESENT and verify the header globally
|
||||
|
||||
IOobject io
|
||||
(
|
||||
fieldName,
|
||||
mesh_.time().timeName(),
|
||||
localDir,
|
||||
mesh_,
|
||||
IOobject::READ_IF_PRESENT
|
||||
);
|
||||
|
||||
// Check global existence to avoid any errors
|
||||
const bool ok =
|
||||
returnReduce
|
||||
(
|
||||
io.typeHeaderOk<IOField<Type>>(false),
|
||||
orOp<bool>()
|
||||
);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
if (!nFields)
|
||||
{
|
||||
Info<< " " << pTraits<Type>::typeName << ":";
|
||||
}
|
||||
|
||||
Info<< " " << fieldName;
|
||||
}
|
||||
|
||||
IOField<Type> field(io);
|
||||
this->write<Type>(field);
|
||||
|
||||
++nFields;
|
||||
}
|
||||
|
||||
if (verbose && nFields)
|
||||
{
|
||||
Info << endl;
|
||||
}
|
||||
|
||||
return nFields;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::label Foam::vtk::lagrangianWriter::writeFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const bool verbose
|
||||
)
|
||||
{
|
||||
return writeFields<Type>
|
||||
(
|
||||
objects.allNames<IOField<Type>>(), // These are in sorted order
|
||||
verbose
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user