mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: parallel and xml output for vtk::lagrangianWriter (issue #926)
This commit is contained in:
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user