diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C
deleted file mode 100644
index cbe2d515bc..0000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C
+++ /dev/null
@@ -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 .
-
-\*---------------------------------------------------------------------------*/
-
-#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 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(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(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(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. too
- format().endTag(vtk::fileTag::PIECE);
-
- format().endTag(vtk::fileTag::POLY_DATA)
- .endVTKFile();
- }
-}
-
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H
deleted file mode 100644
index 05a9aeb8f7..0000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H
+++ /dev/null
@@ -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 .
-
-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
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-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 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
- void writeIOField(const wordList& fieldNames);
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace vtk
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
- #include "foamVtkLagrangianWriterTemplates.C"
-#endif
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C
deleted file mode 100644
index bd0e7202ea..0000000000
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C
+++ /dev/null
@@ -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 .
-
-\*---------------------------------------------------------------------------*/
-
-#include "foamVtkLagrangianWriter.H"
-#include "IOField.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-template
-void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames)
-{
- const int nCmpt(pTraits::nComponents);
-
- const bool useIntField =
- std::is_integral::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>(false),
- orOp()
- );
-
- if (!fieldExists)
- {
- continue;
- }
-
- IOField 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(format(), fldName, fld.size());
- }
- else
- {
- format().openDataArray(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(format(), fldName, fld.size());
- }
- else
- {
- format().openDataArray(fldName)
- .closeTag();
- }
-
- format().writeSize(payLoad);
- vtk::writeList(format(), fld);
- }
-
- format().flush();
-
- if (!legacy_)
- {
- format().endDataArray();
- }
- }
-}
-
-
-// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/Make/files b/src/lagrangian/intermediate/Make/files
index b04a8f0f00..0eb9db55d2 100644
--- a/src/lagrangian/intermediate/Make/files
+++ b/src/lagrangian/intermediate/Make/files
@@ -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
diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options
index 879f3ef634..c859546735 100644
--- a/src/lagrangian/intermediate/Make/options
+++ b/src/lagrangian/intermediate/Make/options
@@ -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
diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.C b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.C
new file mode 100644
index 0000000000..792e3757bd
--- /dev/null
+++ b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.C
@@ -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 .
+
+\*---------------------------------------------------------------------------*/
+
+#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 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(nVerts);
+
+
+ format().tag(vtk::fileTag::VERTS);
+
+ //
+ // 'connectivity'
+ // = linear mapping onto points
+ //
+ {
+ format().beginDataArray(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(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());
+ }
+
+
+ // 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(numberOfPoints_);
+
+ format().tag(vtk::fileTag::POINTS)
+ .beginDataArray(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();
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H
new file mode 100644
index 0000000000..519527fb94
--- /dev/null
+++ b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H
@@ -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 .
+
+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 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
+ void write(const IOField& field);
+
+ //- Write IOFields
+ template
+ label writeFields(const wordList& fieldNames, bool verbose=true);
+
+ //- Write IOFields
+ template
+ label writeFields(const IOobjectList& objects, bool verbose=true);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace vtk
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "foamVtkLagrangianWriterTemplates.C"
+#endif
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C
new file mode 100644
index 0000000000..fda8ea7254
--- /dev/null
+++ b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C
@@ -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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "foamVtkLagrangianWriter.H"
+#include "IOobjectList.H"
+#include "IOField.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+void Foam::vtk::lagrangianWriter::write(const IOField& 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::cmptType,label>::value
+ || std::is_floating_point::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::cmptType(), label>::value;
+
+
+ const direction nCmpt(pTraits::nComponents);
+
+ label nVals = field.size();
+
+ if (parallel_)
+ {
+ reduce(nVals, sumOp());
+ }
+
+ if (format_)
+ {
+ // Non-legacy
+
+ if (isLabel)
+ {
+ const uint64_t payLoad = vtk::sizeofData(nVals);
+
+ format().beginDataArray(field.name());
+ format().writeSize(payLoad);
+ }
+ else
+ {
+ const uint64_t payLoad = vtk::sizeofData(nVals);
+
+ format().beginDataArray(field.name());
+ format().writeSize(payLoad);
+ }
+ }
+
+ if (parallel_)
+ {
+ vtk::writeListParallel(format_.ref(), field);
+ }
+ else
+ {
+ vtk::writeList(format(), field);
+ }
+
+
+ if (format_)
+ {
+ format().flush();
+ format().endDataArray();
+ }
+}
+
+
+template
+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>(false),
+ orOp()
+ );
+
+ if (!ok)
+ {
+ continue;
+ }
+
+ if (verbose)
+ {
+ if (!nFields)
+ {
+ Info<< " " << pTraits::typeName << ":";
+ }
+
+ Info<< " " << fieldName;
+ }
+
+ IOField field(io);
+ this->write(field);
+
+ ++nFields;
+ }
+
+ if (verbose && nFields)
+ {
+ Info << endl;
+ }
+
+ return nFields;
+}
+
+
+template
+Foam::label Foam::vtk::lagrangianWriter::writeFields
+(
+ const IOobjectList& objects,
+ const bool verbose
+)
+{
+ return writeFields
+ (
+ objects.allNames>(), // These are in sorted order
+ verbose
+ );
+}
+
+
+// ************************************************************************* //