/*---------------------------------------------------------------------------*\ ========= | \\ / 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 . Class Foam::coordSetWriter Description Base class for writing coordSet(s) and tracks with fields. Example: \verbatim coordSet coords(...); // Construct writer of xmgr type autoPtr writer(coordSetWriter::New("vtk")); writer.open(coords, path/name); writer.write("density", rho); writer.write("velocity", U); \endverbatim SourceFiles coordSetWriterI.H coordSetWriter.C coordSetWriterBuffers.C coordSetWriterNew.C \*---------------------------------------------------------------------------*/ #ifndef Foam_coordSetWriter_H #define Foam_coordSetWriter_H #include "coordSet.H" #include "typeInfo.H" #include "vector.H" #include "tensor.H" #include "fileName.H" #include "wordList.H" #include "Field.H" #include "DynamicList.H" #include "PtrDynList.H" #include "UPtrList.H" #include "instant.H" #include "InfoProxy.H" #include "cartesianCS.H" #include "runTimeSelectionTables.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { // Forward Declarations class coordSetWriter; class Time; Ostream& operator<<(Ostream& os, const InfoProxy&); /*---------------------------------------------------------------------------*\ Class coordSetWriter Declaration \*---------------------------------------------------------------------------*/ class coordSetWriter { protected: // Protected Data //- Reference to coordinate set(s) UPtrList coords_; //- Track times (eg, streamlines), one per coords_ entry List trackTimes_; //- The content is up-to-date? mutable bool upToDate_; //- Track if geometry has been written since the last open mutable bool wroteGeom_; /// //- Writing in parallel (via master) /// bool parallel_; //- Writer with buffering output mutable bool buffering_; //- Prefer tracks to points during single set writing bool useTracks_; //- Insert additional time sub-directory in the output path bool useTimeDir_; //- Additional output verbosity bool verbose_; //- The number of fields label nFields_; //- The current time value/name instant currTime_; //- The full output directory and file (coords) name fileName outputPath_; //- Output geometry scaling after rotate/translate scalar geometryScale_; //- The centre of rotation (untranslate, translate) point geometryCentre_; //- Local coordinate system transformation coordSystem::cartesian geometryTransform_; //- Field level to remove (on output) dictionary fieldLevel_; //- Field scaling (on output) dictionary fieldScale_; // Buffering #undef defineBufferMethod #define defineBufferMethod(Type) \ \ /* Names of Type fields */ \ DynamicList Type##Names_; \ \ /* Values of Type fields */ \ PtrDynList> Type##Fields_; \ \ /* Add named Type field to buffering */ \ void appendField(const word& fieldName, const Field& vals) \ { \ Type##Names_.append(fieldName); \ Type##Fields_.append(vals.clone()); \ } defineBufferMethod(label); defineBufferMethod(scalar); defineBufferMethod(vector); defineBufferMethod(sphericalTensor); defineBufferMethod(symmTensor); defineBufferMethod(tensor); #undef defineBufferMethod // Protected Member Functions // Buffering //- Write line contents (eg, buffered) static void writeLine(Ostream&, const UList&, const char* sep); //- Write line contents (eg, buffered) static void writeLine(Ostream&, const UList&, const char* sep); //- Clear out buffering void clearBuffers(); //- The number of buffer data columns, after splitting into components label nDataColumns() const; //- Write buffered data virtual bool writeBuffered(); //- Write buffered data void writeBufferContents ( Ostream& os, const coordSet& coords, const char* sep ) const; //- Get buffered data line (components) void getBufferLine ( DynamicList& buf, const coordSet& coords, const label pointi ) const; // File Operations //- Get expected (characteristic) output file name - information only fileName getExpectedPath(const word& fileExt = word::null) const; //- Get field-prefixed output file name. // Eg, dir/U_name.raw fileName getFieldPrefixedPath ( const word& fieldName, const word& fileExt = word::null ) const; //- Verify that the outputPath_ has been set or FatalError void checkOpen() const; //- Perform any merging if not already upToDate (parallel) //- or simply mark as being up-to-date virtual bool merge() const; // Helpers template tmp> adjustFieldTemplate ( const word& fieldName, const tmp>& tfield ) const; //- Repackage field into a UPtrList template static UPtrList> repackageFields ( const Field& field ); //- Repackage multiple fields into a UPtrList template static UPtrList> repackageFields ( const UList>& fieldValues ); //- Write coordinates and values template static void writeTable ( Ostream& os, const coordSet& coords, const UList& values, const char* sep ); // Normal write templates //- Dummy templated write operation template fileName writeTemplate ( const word& fieldName, //!< Name of field const Field& values //!< Local field values to write ) { /// if (!wroteGeom_) /// { /// return this->write(); /// } return fileName::null; } //- Dummy templated write operation. Multiple tracks template fileName writeTemplate ( const word& fieldName, const List>& fieldValues ) { return fileName::null; } //- No copy construct coordSetWriter(const coordSetWriter&) = delete; //- No copy assignment void operator=(const coordSetWriter&) = delete; public: //- Runtime type information TypeName("coordSetWriter"); // Declare run-time constructor selection table declareRunTimeSelectionTable ( autoPtr, coordSetWriter, word, (), () ); declareRunTimeSelectionTable ( autoPtr, coordSetWriter, wordDict, ( const dictionary& writeOptions ), (writeOptions) ); // Helpers //- Same as fileFormats::getFormatOptions static dictionary formatOptions ( const dictionary& dict, const word& formatName, const word& entryName = "formatOptions" ); //- Same as fileFormats::getFormatOptions static dictionary formatOptions ( const dictionary& dict, const dictionary& setDict, const word& formatName, const word& entryName = "formatOptions" ); // Selectors //- True if New is likely to succeed for this writeType static bool supportedType(const word& writeType); //- Return a reference to the selected writer static autoPtr New(const word& writeFormat); //- Return a reference to the selected writer // Select with extra write option static autoPtr New ( const word& writeFormat, const dictionary& writeOptions ); // Constructors //- Default construct coordSetWriter(); //- Default construct with specified options explicit coordSetWriter(const dictionary& options); //- Destructor. Calls close() virtual ~coordSetWriter(); // Member Functions // Helpers //- Name suffix based on fieldName (underscore separator) static word suffix ( const word& fldName, const word& fileExt = word::null ); //- Name suffix based on fieldNames (underscore separator) static word suffix ( const wordList& fieldNames, const word& fileExt = word::null ); // Capability //- True if the format uses internal buffering (eg, column output) virtual bool buffering() const; //- Turn internal buffering on/off (only if supported by the writer) virtual bool buffering(const bool on); //- The writer is enabled. If the writer is not enabled, it may be //- possible for the caller to skip various preparatory operations. // This method is primarily useful for the null writer virtual bool enabled() const { return true; } // Bookkeeping //- Does the writer need an update (eg, lagging behind other changes) virtual bool needsUpdate() const; //- Geometry or fields written since the last open? virtual bool wroteData() const; //- Mark that content changed and the writer will need an update, //- and set nFields = 0. // May also free up unneeded data. // Return false if it was previously already expired. virtual bool expire(); //- Close any open output, remove coordSet associations and //- expire the writer. virtual void clear(); // Content Association //- Set coordinates, can also be nullptr virtual void setCoordinates(const coordSet* coords); //- Set coordinates virtual void setCoordinates(const coordSet& coords); //- Set track coordinates virtual void setTracks(const UPtrList& tracks); //- Set track times virtual void setTrackTimes(const UList& times); // Queries, Access //- The number of associated points (local processor) label numPoints() const; //- The number of coordinate tracks label numTracks() const; //- Writer is associated with content bool hasCoords() const; //- Writer is not associated with content bool empty() const; //- Test if outputPath has been set inline bool is_open() const noexcept; //- The number of expected output fields. // Currently only used by the legacy VTK format. inline label nFields() const noexcept; //- Set the number of expected output fields // Currently only used by the legacy VTK format. // \return old value inline label nFields(const label n) noexcept; //- Prefer tracks to points during single set writing inline bool useTracks() const noexcept; //- Enable/disable tracks preference // \return old value inline bool useTracks(const bool on) noexcept; //- Should a time directory be spliced into the output path? inline bool useTimeDir() const noexcept; //- Enable/disable use of spliced output path // \return old value inline bool useTimeDir(const bool on) noexcept; //- Get output verbosity inline bool verbose() const noexcept; //- Enable/disable verbose output // \return old value inline bool verbose(bool on) noexcept; // Time //- True if there is a known time inline bool hasTime() const; //- The current time value/name inline const word& timeName() const; //- The current time value/name inline scalar timeValue() const; //- Set the current time void setTime(const instant& inst); //- Set current time from timeValue, auto generating the name void setTime(scalar timeValue); //- Set current time from timeValue and timeName void setTime(scalar timeValue, const word& timeName); //- Clear the current time void unsetTime(); //- Begin a time-step virtual void beginTime(const Time& t); //- Begin a time-step virtual void beginTime(const instant& inst); //- End a time-step virtual void endTime(); // Output //- Expected (characteristic) output file name - information only. //- Return empty when is_open() is false. virtual fileName path() const = 0; //- Write separate geometry to file. /// TBD: virtual fileName write() = 0; //- Open for output on specified path, using existing content virtual void open(const fileName& outputPath); //- Open from components virtual void open ( const coordSet& coords, const fileName& outputPath ); //- Open from components virtual void open ( const UPtrList& tracks, const fileName& outputPath ); //- Finish output, performing any necessary cleanup // Optional force disassociation with any coordSet(s) virtual void close(bool force = false); // Other //- Return info proxy, //- used to print information to a stream virtual InfoProxy info() const { return *this; } //- Output info proxy friend Ostream& operator<< ( Ostream& os, const InfoProxy& iproxy ); // Write methods #undef declareCoordSetWriterWriteMethod #define declareCoordSetWriterWriteMethod(Type) \ \ /*! \brief Write field of Type (point data) */ \ virtual fileName write \ ( \ const word& fieldName, /*!< Name of field */ \ const Field& field /*!< Field values */ \ ) = 0; \ \ /*! \brief Write track fields of Type (point data) */ \ virtual fileName write \ ( \ const word& fieldName, /*!< Name of field */ \ const List>& fieldValues /*!< Per-track values */ \ ) = 0; declareCoordSetWriterWriteMethod(label); declareCoordSetWriterWriteMethod(scalar); declareCoordSetWriterWriteMethod(vector); declareCoordSetWriterWriteMethod(sphericalTensor); declareCoordSetWriterWriteMethod(symmTensor); declareCoordSetWriterWriteMethod(tensor); #undef declareCoordSetWriterWriteMethod #define declareCoordSetWriterWriteMethod(Type) \ \ /*! \brief Write field of Type (point data) */ \ virtual fileName write \ ( \ const word& fieldName, /*!< Name of field */ \ const Field& values /*!< Field values */ \ ); /* override */ \ \ /*! \brief Write track fields of Type (point data) */ \ virtual fileName write \ ( \ const word& fieldName, /*!< Name of field */ \ const List>& fieldValues /*!< Per-track values */ \ ); /* override */ }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "coordSetWriterI.H" #ifdef NoRepository #include "coordSetWriterTemplates.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* //