/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2021-2022 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 . Application particleTracks Group grpPostProcessingUtilities Description Generate particle tracks for cases that were computed using a tracked-parcel-type cloud. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Cloud.H" #include "IOdictionary.H" #include "fvMesh.H" #include "Time.H" #include "timeSelector.H" #include "coordSetWriter.H" #include "passiveParticleCloud.H" #include "particleTracksSampler.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // using namespace Foam; template void writeTrackFields ( coordSetWriter& writer, HashTable>>& fieldTable ) { for (const word& fieldName : fieldTable.sortedToc()) { // Steal and reshape from List to List auto& input = fieldTable[fieldName]; List> fields(input.size()); forAll(input, tracki) { fields[tracki].transfer(input[tracki]); } writer.write(fieldName, fields); } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { argList::addNote ( "Generate a file of particle tracks for cases that were" " computed using a tracked-parcel-type cloud" ); timeSelector::addOptions(); #include "addRegionOption.H" // Less frequently used - reduce some clutter argList::setAdvanced("decomposeParDict"); argList::addOption ( "dict", "file", "Alternative particleTracksProperties dictionary" ); argList::addOption ( "stride", "int", "Override the sample-frequency" ); argList::addOption ( "fields", "wordRes", "Specify single or multiple fields to write " "(default: all or 'fields' from dictionary)\n" "Eg, 'T' or '( \"U.*\" )'" ); argList::addOption ( "format", "name", "The writer format " "(default: vtk or 'setFormat' from dictionary)" ); argList::addVerboseOption(); #include "setRootCase.H" #include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); #include "createNamedMesh.H" // ------------------------------------------------------------------------ // Control properties #include "createControls.H" args.readListIfPresent("fields", acceptFields); args.readIfPresent("format", setFormat); args.readIfPresent("stride", sampleFrequency); sampleFrequency = max(1, sampleFrequency); // sanity // Setup the writer auto writerPtr = coordSetWriter::New ( setFormat, formatOptions.optionalSubDict(setFormat, keyType::LITERAL) ); writerPtr().useTracks(true); if (args.verbose()) { writerPtr().verbose(true); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // particleTracksSampler trackSampler; Info<< "Scanning times to determine track data for cloud " << cloudName << nl << endl; { labelList maxIds(Pstream::nProcs(), -1); forAll(timeDirs, timei) { runTime.setTime(timeDirs[timei], timei); Info<< "Time = " << runTime.timeName() << endl; passiveParticleCloud myCloud(mesh, cloudName); Info<< " Read " << returnReduce(myCloud.size(), sumOp