ENH: parallel and xml output for vtk::lagrangianWriter (issue #926)

This commit is contained in:
Mark Olesen 2018-09-17 11:35:17 +02:00
parent 9d8af49c16
commit 6f06ce6e02
8 changed files with 756 additions and 582 deletions

View File

@ -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();
}
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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();
}
}
}
// ************************************************************************* //

View File

@ -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

View File

@ -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

View File

@ -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();
}
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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
);
}
// ************************************************************************* //