/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 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 . \*---------------------------------------------------------------------------*/ #include "coordSet.H" #include "coordSetWriter.H" #include "fileFormats.H" #include "Time.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { defineTypeNameAndDebug(coordSetWriter, 0); defineRunTimeSelectionTable(coordSetWriter, word); defineRunTimeSelectionTable(coordSetWriter, wordDict); } // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // Foam::word Foam::coordSetWriter::suffix ( const word& fldName, const word& fileExt ) { word result; if (!fldName.empty()) { result += '_' + fldName; } return result.ext(fileExt); } Foam::word Foam::coordSetWriter::suffix ( const wordList& fieldNames, const word& fileExt ) { word result; for (const word& fldName : fieldNames) { if (!fldName.empty()) { result += '_' + fldName; } } return result.ext(fileExt); } Foam::dictionary Foam::coordSetWriter::formatOptions ( const dictionary& dict, const word& formatName, const word& entryName ) { return fileFormats::getFormatOptions(dict, formatName, entryName); } Foam::dictionary Foam::coordSetWriter::formatOptions ( const dictionary& dict, const dictionary& setDict, const word& formatName, const word& entryName ) { return fileFormats::getFormatOptions(dict, setDict, formatName, entryName); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::coordSetWriter::coordSetWriter() : coords_(), trackTimes_(), upToDate_(false), wroteGeom_(false), /// parallel_(true), buffering_(false), useTracks_(false), useTimeDir_(false), verbose_(false), nFields_(0), currTime_(), outputPath_(), geometryScale_(1), geometryCentre_(Zero), geometryTransform_(), fieldLevel_(), fieldScale_() {} Foam::coordSetWriter::coordSetWriter(const dictionary& options) : coordSetWriter() { options.readIfPresent("verbose", verbose_); geometryScale_ = 1; geometryCentre_ = Zero; geometryTransform_.clear(); options.readIfPresent("scale", geometryScale_); // Optional cartesian coordinate system transform const auto* dictptr = options.findDict("transform", keyType::LITERAL); if (dictptr) { dictptr->readIfPresent("rotationCentre", geometryCentre_); // 'origin' is optional within sub-dictionary geometryTransform_ = coordSystem::cartesian(*dictptr, IOobjectOption::LAZY_READ); } fieldLevel_ = options.subOrEmptyDict("fieldLevel"); fieldScale_ = options.subOrEmptyDict("fieldScale"); } // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::coordSetWriter::~coordSetWriter() { close(); } // * * * * * * * * * * * * * * * * * Controls * * * * * * * * * * * * * * * // void Foam::coordSetWriter::setTime(const instant& inst) { currTime_ = inst; } void Foam::coordSetWriter::setTime(scalar timeValue) { currTime_ = instant(timeValue); } void Foam::coordSetWriter::setTime(scalar timeValue, const word& timeName) { currTime_.value() = timeValue; currTime_.name() = timeName; } void Foam::coordSetWriter::unsetTime() { currTime_.value() = 0; currTime_.name().clear(); } void Foam::coordSetWriter::beginTime(const Time& t) { setTime(t.value(), t.timeName()); } void Foam::coordSetWriter::beginTime(const instant& inst) { setTime(inst); } void Foam::coordSetWriter::endTime() { // Flush bufferred data if (nDataColumns()) { writeBuffered(); } clearBuffers(); unsetTime(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::coordSetWriter::open(const fileName& outputPath) { outputPath_ = outputPath; wroteGeom_ = false; } void Foam::coordSetWriter::open ( const coordSet& coords, const fileName& outputPath ) { close(); setCoordinates(coords); open(outputPath); } void Foam::coordSetWriter::open ( const UPtrList& tracks, const fileName& outputPath ) { close(); setTracks(tracks); open(outputPath); } void Foam::coordSetWriter::close(bool force) { if (nDataColumns()) { if (verbose_) Info<< "Flush buffered data:" << nl; writeBuffered(); } clearBuffers(); outputPath_.clear(); wroteGeom_ = false; if (force) { coords_.clear(); trackTimes_.clear(); } } void Foam::coordSetWriter::clear() { close(); expire(); coords_.clear(); trackTimes_.clear(); clearBuffers(); // Reset any buffering } void Foam::coordSetWriter::setCoordinates(const coordSet* coords) { expire(); clearBuffers(); // Reset any buffering if (coords) { coords_.resize(1); coords_.set(0, coords); } else { coords_.clear(); } trackTimes_.clear(); } void Foam::coordSetWriter::setCoordinates(const coordSet& coords) { setCoordinates(&coords); } void Foam::coordSetWriter::setTracks(const UPtrList& tracks) { expire(); clearBuffers(); // Reset any buffering // Shallow copy (pointers) coords_.resize(tracks.size()); forAll(coords_, tracki) { coords_.set(tracki, tracks.get(tracki)); } trackTimes_.clear(); useTracks_ = true; } void Foam::coordSetWriter::setTrackTimes(const UList& times) { if (times.size() == coords_.size()) { trackTimes_ = times; } else { trackTimes_.clear(); } } Foam::label Foam::coordSetWriter::numPoints() const { label nTotal = 0; forAll(coords_, tracki) { const auto* ptr = coords_.get(tracki); if (ptr) nTotal += ptr->size(); } return nTotal; } Foam::label Foam::coordSetWriter::numTracks() const { return coords_.size(); } bool Foam::coordSetWriter::needsUpdate() const { return !upToDate_; } bool Foam::coordSetWriter::wroteData() const { return wroteGeom_; } bool Foam::coordSetWriter::expire() { const bool changed = upToDate_; upToDate_ = false; wroteGeom_ = false; coords_.clear(); trackTimes_.clear(); // Field count (nFields_) is a different type of accounting // and is unaffected by geometry changes return changed; } bool Foam::coordSetWriter::hasCoords() const { return !coords_.empty(); } bool Foam::coordSetWriter::empty() const { return coords_.empty(); } Foam::fileName Foam::coordSetWriter::getExpectedPath ( const word& fileExt ) const { fileName file; if (!outputPath_.empty()) { if (useTimeDir() && !timeName().empty()) { // Splice in time-directory file = outputPath_.path() / timeName() / outputPath_.name(); } else { file = outputPath_; } file.ext(fileExt); // Append extension - can also be empty } return file; } Foam::fileName Foam::coordSetWriter::getFieldPrefixedPath ( const word& fieldName, const word& fileExt ) const { if (outputPath_.empty() || fieldName.empty()) { return getExpectedPath(fileExt); } // Field: rootdir/