diff --git a/src/fileFormats/vtk/core/foamVtkCore.C b/src/fileFormats/vtk/core/foamVtkCore.C index 62612deb57a46b245c1bc909af23f752622bfaa4..6b8ab91b9306fc00b6e40967692fa9ebc0cb872b 100644 --- a/src/fileFormats/vtk/core/foamVtkCore.C +++ b/src/fileFormats/vtk/core/foamVtkCore.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -46,6 +46,7 @@ Foam::vtk::fileTagNames { fileTag::POINT_DATA, "PointData" }, { fileTag::POLY_DATA, "PolyData" }, { fileTag::UNSTRUCTURED_GRID, "UnstructuredGrid" }, + { fileTag::MULTI_BLOCK, "vtkMultiBlockDataSet" }, }; diff --git a/src/fileFormats/vtk/core/foamVtkCore.H b/src/fileFormats/vtk/core/foamVtkCore.H index d209d60c9315ac608c86e34d839dd7f495b23697..8584c9672ceebb8655b6c6403ffcb5ccb85b3d81 100644 --- a/src/fileFormats/vtk/core/foamVtkCore.H +++ b/src/fileFormats/vtk/core/foamVtkCore.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -115,6 +115,7 @@ namespace vtk POINT_DATA, //!< "PointData" POLY_DATA, //!< "PolyData" UNSTRUCTURED_GRID, //!< "UnstructuredGrid" + MULTI_BLOCK, //!< "vtkMultiBlockDataSet" }; //- Strings corresponding to the vtk xml tags diff --git a/src/fileFormats/vtk/output/foamVtkOutput.C b/src/fileFormats/vtk/output/foamVtkOutput.C index 5a54c2241ba43e8ea8d480b0f754b7c3e9993979..2ee7dbd7a57d95061cd1b267e7227d0caa6e4a39 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.C +++ b/src/fileFormats/vtk/output/foamVtkOutput.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -33,6 +33,7 @@ License #include "foamVtkLegacyAsciiFormatter.H" #include "foamVtkLegacyRawFormatter.H" #include "typeInfo.H" +#include "instant.H" // * * * * * * * * * * * * * * * Static Data * * * * * * * * * * * * * * * * // @@ -101,19 +102,52 @@ Foam::vtk::newFormatter } +void Foam::vtk::writeSeries +( + Ostream& os, + const word& prefix, + const word& suffix, + const UList<instant>& series +) +{ + // Begin file-series (JSON) + os << "{\n \"file-series-version\" : \"1.0\",\n \"files\" : [\n"; + + // Track how many entries are remaining + // - trailing commas on all but the final entry (JSON requirement) + label nremain = series.size(); + + // Each entry + // { "name" : "<prefix>name<suffix>", "time" : value } + + for (const instant& inst : series) + { + os << " { \"name\" : \"" + << prefix << inst.name() << suffix + << "\", \"time\" : " << inst.value() << " }"; + + if (--nremain) + { + os << ','; + } + os << nl; + } + + os << " ]\n}\n"; +} + + Foam::label Foam::vtk::writeVtmFile ( std::ostream& os, const UList<fileName>& files ) { - const word& content = "vtkMultiBlockDataSet"; - asciiFormatter vtmFile(os); vtmFile .xmlHeader() - .beginVTKFile(content, "1.0"); + .beginVTKFile(fileTagNames[vtk::fileTag::MULTI_BLOCK], "1.0"); forAll(files, i) { @@ -124,7 +158,7 @@ Foam::label Foam::vtk::writeVtmFile .closeTag(true); } - vtmFile.endTag(content).endVTKFile(); + vtmFile.endTag(fileTagNames[vtk::fileTag::MULTI_BLOCK]).endVTKFile(); return files.size(); } diff --git a/src/fileFormats/vtk/output/foamVtkOutput.H b/src/fileFormats/vtk/output/foamVtkOutput.H index 4a71b5208d310885e04cfcfc5a14e42cd1f99906..55f31cd91fca4baf85ed5a48a3ade1cc5e137f55 100644 --- a/src/fileFormats/vtk/output/foamVtkOutput.H +++ b/src/fileFormats/vtk/output/foamVtkOutput.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -54,6 +54,9 @@ SourceFiles namespace Foam { +// Forward declarations +class instant; + namespace vtk { @@ -73,6 +76,19 @@ namespace vtk ); + //- Write file series (JSON format) for specified time instances + // + // \param prefix before the \c instant.name() + // \param suffix after the \c instant.name() + // \param series the list of name/value entries + void writeSeries + ( + Ostream& os, + const word& prefix, + const word& suffix, + const UList<instant>& series + ); + //- Write vtm datasets for specified files label writeVtmFile(std::ostream& os, const UList<fileName>& files); diff --git a/src/functionObjects/lagrangian/Make/files b/src/functionObjects/lagrangian/Make/files index 93227fe85df0ffb5c1a640e303d548fb87e7e06f..921ca2d707fb5ad2be880af88a27b2b1a6b2941a 100644 --- a/src/functionObjects/lagrangian/Make/files +++ b/src/functionObjects/lagrangian/Make/files @@ -2,4 +2,6 @@ cloudInfo/cloudInfo.C icoUncoupledKinematicCloud/icoUncoupledKinematicCloud.C dsmcFields/dsmcFields.C +vtkCloud/vtkCloud.C + LIB = $(FOAM_LIBBIN)/liblagrangianFunctionObjects diff --git a/src/functionObjects/lagrangian/Make/options b/src/functionObjects/lagrangian/Make/options index 7a7bf38ba33656c867a1948e6553d05e1e249cf4..e54a3f92866dec616395219507a5a4bd0ec7ed80 100644 --- a/src/functionObjects/lagrangian/Make/options +++ b/src/functionObjects/lagrangian/Make/options @@ -2,6 +2,8 @@ EXE_INC = \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/conversion/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \ @@ -12,6 +14,7 @@ EXE_INC = \ LIB_LIBS = \ -lfiniteVolume \ -lincompressibleTransportModels \ + -lconversion \ -lmeshTools \ -llagrangian \ -llagrangianIntermediate \ diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C new file mode 100644 index 0000000000000000000000000000000000000000..cb6f4571ed178a783e3769b790a04328792a1444 --- /dev/null +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.C @@ -0,0 +1,457 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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 "vtkCloud.H" +#include "Cloud.H" +#include "dictionary.H" +#include "fvMesh.H" +#include "foamVtkOutputOptions.H" +#include "addToRunTimeSelectionTable.H" +#include "pointList.H" +#include "stringOps.H" +#include <fstream> + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + defineTypeNameAndDebug(vtkCloud, 0); + addToRunTimeSelectionTable(functionObject, vtkCloud, dictionary); +} +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::functionObjects::vtkCloud::writeVerts +( + autoPtr<vtk::formatter>& format, + const label nParcels +) const +{ + if (Pstream::master()) + { + 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); + } +} + + +bool Foam::functionObjects::vtkCloud::writeCloud +( + const fileName& outputName, + const word& cloudName +) const +{ + const auto* objPtr = mesh_.lookupObjectPtr<cloud>(cloudName); + if (!objPtr) + { + return false; + } + + objectRegistry obrTmp + ( + IOobject + ( + "vtk::vtkCloud::" + cloudName, + mesh_.time().constant(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE, + false + ) + ); + + objPtr->writeObjects(obrTmp); + + const auto* pointsPtr = obrTmp.lookupObjectPtr<vectorField>("position"); + + if (!pointsPtr) + { + // This should be impossible + return false; + } + + // Total number of parcels on all processes + label nTotParcels = pointsPtr->size(); + reduce(nTotParcels, sumOp<label>()); + + if (!nTotParcels) + { + return false; + } + + std::ofstream os; + autoPtr<vtk::formatter> format; + + // Header + if (Pstream::master()) + { + os.open(outputName); + format = writeOpts_.newFormatter(os); + + // XML (inline) + format() + .xmlHeader() + .xmlComment + ( + "cloud=" + cloudName + + " time=" + time_.timeName() + + " index=" + Foam::name(time_.timeIndex()) + ) + .beginVTKFile(vtk::fileTag::POLY_DATA, "0.1"); + + // Begin piece + if (useVerts_) + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, nTotParcels) + .xmlAttr(vtk::fileAttr::NUMBER_OF_VERTS, nTotParcels) + .closeTag(); + } + else + { + format() + .openTag(vtk::fileTag::PIECE) + .xmlAttr(vtk::fileAttr::NUMBER_OF_POINTS, nTotParcels) + .closeTag(); + } + } + + + // Points + if (Pstream::master()) + { + const uint64_t payLoad = (nTotParcels * 3 * sizeof(float)); + + format().tag(vtk::fileTag::POINTS) + .openDataArray<float,3>(vtk::dataArrayAttr::POINTS) + .closeTag(); + + format().writeSize(payLoad); + + // Master + vtk::writeList(format(), *pointsPtr); + + // Slaves - recv + for (int slave=1; slave<Pstream::nProcs(); ++slave) + { + IPstream fromSlave(Pstream::commsTypes::scheduled, slave); + pointList points(fromSlave); + + vtk::writeList(format(), points); + } + + format().flush(); + + format() + .endDataArray() + .endTag(vtk::fileTag::POINTS); + + if (useVerts_) + { + writeVerts(format, nTotParcels); + } + } + else + { + // Slaves - send + + OPstream toMaster + ( + Pstream::commsTypes::scheduled, + Pstream::masterNo() + ); + + toMaster + << *pointsPtr; + } + + + // Prevent any possible conversion of positions as a field + obrTmp.filterKeys + ( + [](const word& k) + { + return k.startsWith("position") + || k.startsWith("coordinate"); + }, + true // prune + ); + + // Restrict to specified fields + if (selectFields_.size()) + { + obrTmp.filterKeys(selectFields_); + } + + + // Write fields + const vtk::fileTag dataType = + ( + useVerts_ + ? vtk::fileTag::CELL_DATA + : vtk::fileTag::POINT_DATA + ); + + if (Pstream::master()) + { + format().tag(dataType); + } + + writeFields<label>(format, obrTmp, nTotParcels); + writeFields<scalar>(format, obrTmp, nTotParcels); + writeFields<vector>(format, obrTmp, nTotParcels); + + if (Pstream::master()) + { + format().endTag(dataType); + } + + // Footer + if (Pstream::master()) + { + // slight cheat. </Piece> too + format().endTag(vtk::fileTag::PIECE); + + format().endTag(vtk::fileTag::POLY_DATA) + .endVTKFile(); + } + + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects::vtkCloud::vtkCloud +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + fvMeshFunctionObject(name, runTime, dict), + writeOpts_(vtk::formatType::INLINE_BASE64), + printf_(), + useTimeName_(false), + useVerts_(false), + selectClouds_(), + selectFields_(), + dirName_("VTK") +{ + if (postProcess) + { + // Disable for post-process mode. + // Emit as FatalError for the try/catch in the caller. + FatalError + << type() << " disabled in post-process mode" + << exit(FatalError); + } + + read(dict); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::vtkCloud::read(const dictionary& dict) +{ + fvMeshFunctionObject::read(dict); + + // + // writer options - default is xml base64. Legacy is not desired. + // + writeOpts_ = vtk::formatType::INLINE_BASE64; + + writeOpts_.ascii + ( + dict.found("format") + && (IOstream::formatEnum(dict.lookup("format")) == IOstream::ASCII) + ); + + writeOpts_.append(false); // No append supported + writeOpts_.legacy(false); // Too messy to support legacy as well + + writeOpts_.precision + ( + dict.lookupOrDefault + ( + "writePrecision", + IOstream::defaultPrecision() + ) + ); + + // Info<< type() << " " << name() << " output-format: " + // << writeOpts_.description() << nl; + + int padWidth = dict.lookupOrDefault<int>("width", 8); + + // Appropriate printf format - Enforce min/max sanity limits + if (padWidth < 1 || padWidth > 31) + { + printf_.clear(); + } + else + { + printf_ = "%0" + std::to_string(padWidth) + "d"; + } + + useTimeName_ = dict.lookupOrDefault<bool>("timeName", false); + + useVerts_ = dict.lookupOrDefault<bool>("cellData", false); + + + // + // other options + // + dict.readIfPresent("directory", dirName_); + + selectClouds_.clear(); + dict.readIfPresent("clouds", selectClouds_); + + if (selectClouds_.empty()) + { + selectClouds_.resize(1); + selectClouds_.first() = + dict.lookupOrDefault<word>("cloud", cloud::defaultName); + } + + selectFields_.clear(); + dict.readIfPresent("fields", selectFields_); + + return true; +} + + +bool Foam::functionObjects::vtkCloud::execute() +{ + return true; +} + + +bool Foam::functionObjects::vtkCloud::write() +{ + const wordList cloudNames(mesh_.sortedNames<cloud>(selectClouds_)); + + if (cloudNames.empty()) + { + return true; // skip - not available + } + + const word timeDesc = + ( + useTimeName_ + ? time_.timeName() + : printf_.empty() + ? Foam::name(time_.timeIndex()) + : word::printf(printf_, time_.timeIndex()) + ); + + fileName vtkDir(dirName_); + vtkDir.expand(); + if (!vtkDir.isAbsolute()) + { + vtkDir = stringOps::expand("<case>")/vtkDir; + } + mkDir(vtkDir); + + Log << name() << " output Time: " << time_.timeName() << nl; + + // Each cloud separately + for (const word& cloudName : cloudNames) + { + const word prefix(cloudName + "_"); + const word suffix(".vtp"); // No legacy supported + + const fileName outputName(vtkDir/prefix + timeDesc + suffix); + + if (writeCloud(outputName, cloudName)) + { + Log << " cloud : " << outputName << endl; + + if (Pstream::master()) + { + // Add to file-series and emit as JSON + // - misbehaves if vtkDir changes during the run, + // but that causes other issues too. + + series_(cloudName).append({time_.value(), timeDesc}); + + OFstream os(vtkDir/cloudName + ".vtp.series", IOstream::ASCII); + + vtk::writeSeries(os, prefix, suffix, series_[cloudName]); + } + } + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H new file mode 100644 index 0000000000000000000000000000000000000000..651e43d81e703026ecfcef92495210439dcade96 --- /dev/null +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloud.H @@ -0,0 +1,213 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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::functionObjects::vtkCloud + +Group + grpUtilitiesFunctionObjects + +Description + This functionObject writes cloud(s) in VTK format. + + Example of function object specification: + \verbatim + vtkCloud1 + { + type vtkCloud; + libs ("liblagrangianFunctionObjects.so"); + writeControl writeTime; + writeInterval 1; + format binary; + + cloud myCloud; + width 12; + fields (U p); + } + \endverbatim + +Usage + \table + Property | Description | Required | Default + type | Type name: vtkCloud | yes | + writeControl | Output control | recommended | timeStep + cloud | | no | defaultCloud + clouds | wordRe list of clouds | no | + fields | wordRe list of fields | no | + cellData | Emit cellData instead of pointData | no | false + directory | The output directory name | no | VTK + width | Padding width for file name | no | 8 + timeName | Use time-name instead of time-index | no | false + format | ascii or binary format | no | binary + writePrecision | write precision in ascii | no | same as IOstream + \endtable + +See also + Foam::functionObjects::ensightWrite + Foam::functionObjects::vtkWrite + Foam::functionObjects::fvMeshFunctionObject + Foam::functionObjects::timeControl + +SourceFiles + vtkCloud.C + vtkCloudTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjects_vtkCloud_H +#define functionObjects_vtkCloud_H + +#include "fvMeshFunctionObject.H" +#include "foamVtkOutputOptions.H" +#include "wordRes.H" +#include "instant.H" +#include "DynamicList.H" +#include "HashTable.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + +/*---------------------------------------------------------------------------*\ + Class vtkCloud Declaration +\*---------------------------------------------------------------------------*/ + +class vtkCloud +: + public fvMeshFunctionObject +{ + // Private data + + //- Writer options + vtk::outputOptions writeOpts_; + + //- The printf format for zero-padding names + string printf_; + + //- Use time-name instead of time-index + bool useTimeName_; + + //- Write lagrangian as cell data (verts) instead of point data + bool useVerts_; + + //- Requested names of clouds to process + wordRes selectClouds_; + + //- Subset of cloud fields to process + wordRes selectFields_; + + //- Output directory name + fileName dirName_; + + //- Per cloud output for file series + HashTable<DynamicList<instant>> series_; + + + // Private Member Functions + + //- Write a cloud + bool writeCloud + ( + const fileName& outputName, + const word& cloudName + ) const; + + //- Write VERTS connectivity + void writeVerts + ( + autoPtr<vtk::formatter>& format, + const label nParcels + ) const; + + + //- Write fields of IOField<Type> + template<class Type> + label writeFields + ( + autoPtr<vtk::formatter>& format, + const objectRegistry& obrTmp, + const label nTotParcels + ) const; + + + //- No copy construct + vtkCloud(const vtkCloud&) = delete; + + //- No copy assignment + void operator=(const vtkCloud&) = delete; + + +public: + + //- Runtime type information + TypeName("vtkCloud"); + + + // Constructors + + //- Construct from Time and dictionary + vtkCloud + ( + const word& name, + const Time& runTime, + const dictionary& dict + ); + + + //- Destructor + virtual ~vtkCloud() = default; + + + // Member Functions + + //- Read the vtkCloud specification + virtual bool read(const dictionary& dict); + + //- Execute, currently does nothing + virtual bool execute(); + + //- Write fields + virtual bool write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace functionObjects +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "vtkCloudTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C b/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..38ad185e00e9bcc73befb7dc575b33fd19d6e22d --- /dev/null +++ b/src/functionObjects/lagrangian/vtkCloud/vtkCloudTemplates.C @@ -0,0 +1,155 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 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 "IOField.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<class Type> +Foam::label Foam::functionObjects::vtkCloud::writeFields +( + autoPtr<vtk::formatter>& format, + const objectRegistry& obrTmp, + const label nTotParcels +) const +{ + const int nCmpt(pTraits<Type>::nComponents); + + const bool useIntField = + std::is_integral<typename pTraits<Type>::cmptType>(); + + // Fields are not always on all processors (eg, multi-component parcels). + // Thus need to resolve names between all processors. + + wordList fieldNames(obrTmp.names<IOField<Type>>()); + Pstream::combineGather(fieldNames, ListOps::uniqueEqOp<word>()); + Pstream::combineScatter(fieldNames); + + // Sort to get identical order of fields on all processors + Foam::sort(fieldNames); + + for (const word& fieldName : fieldNames) + { + const auto* fldPtr = obrTmp.lookupObjectPtr<IOField<Type>>(fieldName); + + if (Pstream::master()) + { + if (useIntField) + { + const uint64_t payLoad(nTotParcels * nCmpt * sizeof(label)); + + format().openDataArray<label, nCmpt>(fieldName) + .closeTag(); + + format().writeSize(payLoad); + + if (fldPtr) + { + // Data on master + const auto& fld = *fldPtr; + + // Ensure consistent output width + for (const Type& val : fld) + { + for (int cmpt=0; cmpt < nCmpt; ++cmpt) + { + format().write(label(component(val, cmpt))); + } + } + } + + // Slaves - recv + for (int slave=1; slave<Pstream::nProcs(); ++slave) + { + IPstream fromSlave(Pstream::commsTypes::scheduled, slave); + Field<Type> recv(fromSlave); + + for (const Type& val : recv) + { + for (int cmpt=0; cmpt < nCmpt; ++cmpt) + { + format().write(label(component(val, cmpt))); + } + } + } + } + else + { + const uint64_t payLoad(nTotParcels * nCmpt * sizeof(float)); + + format().openDataArray<float, nCmpt>(fieldName) + .closeTag(); + + format().writeSize(payLoad); + + if (fldPtr) + { + // Data on master + vtk::writeList(format(), *fldPtr); + } + + // Slaves - recv + for (int slave=1; slave<Pstream::nProcs(); ++slave) + { + IPstream fromSlave(Pstream::commsTypes::scheduled, slave); + Field<Type> recv(fromSlave); + + vtk::writeList(format(), recv); + } + } + + format().flush(); + + format() + .endDataArray(); + } + else + { + // Slaves - send + + OPstream toMaster + ( + Pstream::commsTypes::scheduled, + Pstream::masterNo() + ); + + if (fldPtr) + { + toMaster + << *fldPtr; + } + else + { + toMaster + << Field<Type>(); + } + } + } + + return fieldNames.size(); +} + + +// ************************************************************************* // diff --git a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/controlDict b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/controlDict index 267a92fc5aa3a4482dd95878a2afd529403311a3..973b0b23487a822409d5bc2c8dcfdebf278f6427 100644 --- a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/controlDict +++ b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/controlDict @@ -51,5 +51,9 @@ maxCo 1.0; maxDeltaT 1; +functions +{ + #include "vtkCloud" +} // ************************************************************************* // diff --git a/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/vtkCloud b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/vtkCloud new file mode 100644 index 0000000000000000000000000000000000000000..c134d6cfd2a2fcf09589adaf4d4f245eb7577521 --- /dev/null +++ b/tutorials/lagrangian/coalChemistryFoam/simplifiedSiwek/system/vtkCloud @@ -0,0 +1,31 @@ +// -*- C++ -*- +// Minimal example of using the vtkCloud function object. +vtkCloud +{ + type vtkCloud; + libs ("liblagrangianFunctionObjects.so"); + log true; + + // Cloud name + // cloud coalCloud1; + clouds ( ".*" ); + + // Fields to output (words or regex) + fields ( U T d "Y.*" ); + + //- Output format (ascii | binary) - Default=binary + // format binary; + + // format ascii; + // writePrecision 12; + + //- Output directory name - Default="VTK" + // directory "VTK"; + + //- Write more frequent than fields + writeControl adjustableRunTime; + writeInterval 0.001; +} + + +// ************************************************************************* //