diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.C deleted file mode 100644 index cbe2d515bc7d73d301146692382ea10800b7fd40..0000000000000000000000000000000000000000 --- 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 <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(); - } -} - - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriter.H deleted file mode 100644 index 05a9aeb8f7716ce1d0d837f5b7eecfdc18fbb5ac..0000000000000000000000000000000000000000 --- 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 <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 - -// ************************************************************************* // diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C b/applications/utilities/postProcessing/dataConversion/foamToVTK/foamVtkLagrangianWriterTemplates.C deleted file mode 100644 index bd0e7202eade1a428d22febd3d462828fefbd9bf..0000000000000000000000000000000000000000 --- 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 <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(); - } - } -} - - -// ************************************************************************* // diff --git a/src/lagrangian/intermediate/Make/files b/src/lagrangian/intermediate/Make/files index b04a8f0f00face4ff93a439ac4eecc4ac398f7c0..0eb9db55d2495e0abebb486b1e52aec9f20ab571 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 879f3ef6345aae57dc3d43c23b6d4407fc0aba41..c859546735be6ca725ecedb6346f1eaadd24c44d 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 0000000000000000000000000000000000000000..792e3757bd8c2c05bc57b643714d482fd680dc76 --- /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 <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(); + } +} + + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriter.H new file mode 100644 index 0000000000000000000000000000000000000000..519527fb941622612c50585ddd6cd83bd560f8c1 --- /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 <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 + +// ************************************************************************* // diff --git a/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C b/src/lagrangian/intermediate/conversion/vtk/foamVtkLagrangianWriterTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..fda8ea72542fafcade1268d2f1d795c759f45408 --- /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 <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 + ); +} + + +// ************************************************************************* //