From ee0947b6931e4e61251681c6383513b6cf5716af Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Sat, 29 Sep 2018 13:14:50 +0200
Subject: [PATCH] ENH: vtk::fileWriter base class for geometry/field writers
 (issue #926)

- Output formats such as vtp, vtu follow a particular internal data
  structure (HEAD, FIELD_DATA, PIECE, CELL_DATA/POINT_DATA) and other
  output conventions. This writer base tracks these expected output
  states internally to help avoid logic errors in the callers.
---
 src/fileFormats/Make/files                    |   1 +
 src/fileFormats/vtk/file/foamVtkFileWriter.C  | 474 ++++++++++++++++++
 src/fileFormats/vtk/file/foamVtkFileWriter.H  | 289 +++++++++++
 src/fileFormats/vtk/file/foamVtkFileWriterI.H | 108 ++++
 4 files changed, 872 insertions(+)
 create mode 100644 src/fileFormats/vtk/file/foamVtkFileWriter.C
 create mode 100644 src/fileFormats/vtk/file/foamVtkFileWriter.H
 create mode 100644 src/fileFormats/vtk/file/foamVtkFileWriterI.H

diff --git a/src/fileFormats/Make/files b/src/fileFormats/Make/files
index baa36aca051..678c9c418ee 100644
--- a/src/fileFormats/Make/files
+++ b/src/fileFormats/Make/files
@@ -16,6 +16,7 @@ stl/STLAsciiParseFlex.L
 stl/STLAsciiParseManual.C
 stl/STLAsciiParseRagel.C
 
+vtk/file/foamVtkFileWriter.C
 vtk/core/foamVtkCore.C
 vtk/core/foamVtkPTraits.C
 
diff --git a/src/fileFormats/vtk/file/foamVtkFileWriter.C b/src/fileFormats/vtk/file/foamVtkFileWriter.C
new file mode 100644
index 00000000000..b2e5d398045
--- /dev/null
+++ b/src/fileFormats/vtk/file/foamVtkFileWriter.C
@@ -0,0 +1,474 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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 "foamVtkFileWriter.H"
+#include "globalIndex.H"
+#include "OSspecific.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::Enum
+<
+    Foam::vtk::fileWriter::outputState
+>
+Foam::vtk::fileWriter::stateNames
+{
+    { outputState::CLOSED, "closed" },
+    { outputState::OPENED, "opened" },
+    { outputState::DECLARED, "declared" },
+    { outputState::FIELD_DATA, "FieldData" },
+    { outputState::PIECE, "Piece" },
+    { outputState::CELL_DATA, "CellData" },
+    { outputState::POINT_DATA, "PointData" },
+};
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+bool Foam::vtk::fileWriter::enter_Piece()
+{
+    // Finish other output
+    endFieldData();
+
+    if (isState(outputState::OPENED))
+    {
+        beginFile();
+    }
+    if (notState(outputState::DECLARED))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::DECLARED] << ')'
+            << exit(FatalError);
+    }
+    state_ = outputState::PIECE;
+    nCellData_ = nPointData_ = 0;
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::endPiece()
+{
+    // Finish other output
+    endCellData();
+    endPointData();
+
+    if (notState(outputState::PIECE))
+    {
+        // Skip if not in Piece
+        return false;
+    }
+    state_ = outputState::DECLARED; // Mark as having been flushed
+
+    if (format_)
+    {
+        format().endPiece();
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::enter_CellData(label nEntries, label nFields)
+{
+    // Already in CellData?
+    if (isState(outputState::CELL_DATA)) return false;
+
+    // Finish other output
+    endPointData();
+
+    if (notState(outputState::PIECE))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::PIECE] << ')'
+            << exit(FatalError);
+    }
+
+    nCellData_ = 0;
+
+    // Do nothing for legacy when nFields == 0
+    if (legacy() && !nFields) return false;
+
+    state_ = outputState::CELL_DATA;
+
+    if (format_)
+    {
+        if (legacy())
+        {
+            legacy::beginCellData(format(), nEntries, nFields);
+        }
+        else
+        {
+            format().beginCellData();
+        }
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::enter_PointData(label nEntries, label nFields)
+{
+    // Already in PointData?
+    if (isState(outputState::POINT_DATA)) return false;
+
+    // Finish other output
+    endCellData();
+
+    if (notState(outputState::PIECE))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::PIECE] << ')'
+            << exit(FatalError);
+    }
+
+    nPointData_ = 0;
+
+    // Do nothing for legacy when nFields == 0
+    if (legacy() && !nFields) return false;
+
+    state_ = outputState::POINT_DATA;
+
+    if (format_)
+    {
+        if (legacy())
+        {
+            legacy::beginPointData(format(), nEntries, nFields);
+        }
+        else
+        {
+            format().beginPointData();
+        }
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::exit_File()
+{
+    // Finish other output
+    endFieldData();
+    endPiece();
+
+    if (isState(outputState::DECLARED))
+    {
+        if (format_ && !legacy())
+        {
+            format().endTag(contentType_).endVTKFile();
+        }
+        state_ = outputState::OPENED;  // Mark as having been flushed
+    }
+
+    // Must now be in CLOSED or OPENED states only
+
+    if (isState(outputState::CLOSED) || isState(outputState::OPENED))
+    {
+        return true;
+    }
+
+    WarningInFunction
+        << "Bad writer state (" << stateNames[state_]
+        << ") - should be (" << stateNames[outputState::CLOSED]
+        << ") or (" << stateNames[outputState::OPENED]
+        << ") for contentType (" << vtk::fileTagNames[contentType_]
+        << nl << endl;
+
+    return false;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::vtk::fileWriter::fileWriter
+(
+    const vtk::fileTag contentType,
+    const vtk::outputOptions opts
+)
+:
+    contentType_(contentType),
+    opts_(opts),
+    parallel_(false),
+    state_(outputState::CLOSED),
+    nCellData_(0),
+    nPointData_(0),
+    outputFile_(),
+    format_(),
+    os_()
+{
+    // We do not currently support append mode at all
+    opts_.append(false);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::vtk::fileWriter::~fileWriter()
+{
+    close();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::vtk::fileWriter::open(const fileName& file, bool parallel)
+{
+    if (notState(outputState::CLOSED))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::CLOSED] << ')'
+            << exit(FatalError);
+    }
+
+    if (format_)
+    {
+        format_.clear();
+        os_.close();
+    }
+    nCellData_ = nPointData_ = 0;
+    outputFile_ = file;
+
+    if
+    (
+        legacy()
+      ? outputFile_.hasExt(vtk::fileExtension[contentType_])
+      : outputFile_.hasExt(vtk::legacy::fileExtension)
+    )
+    {
+        // Inappropriate extension. Legacy instead of xml, or vice versa.
+
+        outputFile_.removeExt();
+    }
+
+    if (!outputFile_.hasExt(ext()))
+    {
+        // Add extension if required
+        outputFile_.ext(ext());
+    }
+
+
+    // Only set parallel flag if really is a parallel run.
+    parallel_ = parallel && Pstream::parRun();
+
+    // Open a file and attach a formatter
+    // - on master (always)
+    // - on slave if not parallel
+    //
+    // This means we can always check if format_ is defined to know if output
+    // is desired on any particular process.
+
+    if (Pstream::master() || !parallel_)
+    {
+        mkDir(outputFile_.path());
+
+        os_.open(outputFile_);
+
+        format_ = opts_.newFormatter(os_);
+    }
+
+    state_ = outputState::OPENED;
+    return true;
+}
+
+
+void Foam::vtk::fileWriter::close()
+{
+    exit_File();
+
+    if (format_)
+    {
+        format_.clear();
+        os_.close();
+    }
+
+    state_ = outputState::CLOSED;
+    outputFile_.clear();
+    nCellData_ = nPointData_ = 0;
+}
+
+
+bool Foam::vtk::fileWriter::beginFile(std::string title)
+{
+    if (isState(outputState::DECLARED))
+    {
+        // Skip if already emitted
+        return false;
+    }
+    if (notState(outputState::OPENED))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::OPENED] << ')'
+            << exit(FatalError);
+    }
+    state_ = outputState::DECLARED;
+
+    if (format_)
+    {
+        if (legacy())
+        {
+            legacy::fileHeader(format(), title, contentType_);
+        }
+        else
+        {
+            // XML (inline)
+
+            format().xmlHeader();
+
+            if (title.size())
+            {
+                format().xmlComment(title);
+            }
+
+            format().beginVTKFile(contentType_);
+        }
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::beginFieldData(label nFields)
+{
+    // Do nothing for legacy when nFields == 0
+    if (legacy() && !nFields) return false;
+
+    if (isState(outputState::OPENED))
+    {
+        beginFile();
+    }
+    if (notState(outputState::DECLARED))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::DECLARED] << ')'
+            << exit(FatalError);
+    }
+    state_ = outputState::FIELD_DATA;
+
+    if (format_)
+    {
+        if (legacy())
+        {
+            legacy::beginFieldData(format(), nFields);
+        }
+        else
+        {
+            format().beginFieldData();
+        }
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::endFieldData()
+{
+    if (notState(outputState::FIELD_DATA))
+    {
+        // Skip if not in FieldData
+        return false;
+    }
+    state_ = outputState::DECLARED; // Toggle back to DECLARED
+
+    if (format_ && !legacy())
+    {
+        format().endFieldData();
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::endCellData()
+{
+    if (notState(outputState::CELL_DATA))
+    {
+        // Skip if not in CellData
+        return false;
+    }
+    state_ = outputState::PIECE; // Toggle back to PIECE
+
+    if (format_ && !legacy())
+    {
+        format().endCellData();
+    }
+
+    return true;
+}
+
+
+bool Foam::vtk::fileWriter::endPointData()
+{
+    if (notState(outputState::POINT_DATA))
+    {
+        // Skip if not in PointData
+        return false;
+    }
+    state_ = outputState::PIECE; // Toggle back to PIECE
+
+    if (format_ && !legacy())
+    {
+        format().endPointData();
+    }
+
+    return true;
+}
+
+
+void Foam::vtk::fileWriter::writeTimeValue(scalar timeValue)
+{
+    // Convenience - switch to FieldData
+    if (isState(outputState::OPENED) || isState(outputState::DECLARED))
+    {
+        beginFieldData(1);
+    }
+    if (notState(outputState::FIELD_DATA))
+    {
+        FatalErrorInFunction
+            << "Bad writer state (" << stateNames[state_]
+            << ") - should be (" << stateNames[outputState::FIELD_DATA] << ')'
+            << exit(FatalError);
+    }
+
+    // No collectives - can skip on slave processors
+    if (!format_) return;
+
+    if (legacy())
+    {
+        legacy::writeTimeValue(format(), timeValue);
+    }
+    else
+    {
+        format().writeTimeValue(timeValue);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/file/foamVtkFileWriter.H b/src/fileFormats/vtk/file/foamVtkFileWriter.H
new file mode 100644
index 00000000000..e11c5f9091d
--- /dev/null
+++ b/src/fileFormats/vtk/file/foamVtkFileWriter.H
@@ -0,0 +1,289 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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::vtk::fileWriter
+
+Description
+    Base class for VTK output writers that handle geometry and fields
+    (eg, vtp, vtu data).
+    These output formats are structured as DECLARED, FIELD_DATA, PIECE
+    followed by any CELL_DATA or POINT_DATA.
+
+    This writer base tracks these expected output states internally
+    to help avoid logic errors in the callers.
+
+    The FieldData element must be placed prior to writing any geometry
+    Piece. This moves the information to the front of the output file
+    for visibility and simplifies the logic when creating
+    multi-piece geometries.
+
+SourceFiles
+    foamVtkFileWriter.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef foamVtkFileWriter_H
+#define foamVtkFileWriter_H
+
+#include <fstream>
+#include "Enum.H"
+#include "UPstream.H"
+#include "foamVtkOutputOptions.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace vtk
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class vtk::fileWriter Declaration
+\*---------------------------------------------------------------------------*/
+
+class fileWriter
+{
+protected:
+
+    // Protected Member Data
+
+        //- Internal tracking of the output state.
+        enum outputState
+        {
+            CLOSED = 0,     //!< File is closed
+            OPENED,         //!< File is opened
+            DECLARED,       //!< File contents declared (VTKFile header written)
+            FIELD_DATA,     //!< Inside FieldData
+            PIECE,          //!< Inside Piece (after geometry write)
+            CELL_DATA,      //!< Inside CellData
+            POINT_DATA      //!< Inside PointData
+        };
+
+        //- Names for the output state (for messages, not for file output).
+        static const Enum<outputState> stateNames;
+
+
+        //- The content type
+        vtk::fileTag contentType_;
+
+        //- The requested output options
+        outputOptions opts_;
+
+        //- Writing in parallel (via master)
+        bool parallel_;
+
+        //- The output state
+        outputState state_;
+
+        //- The number of CellData written for the Piece thus far.
+        label nCellData_;
+
+        //- The number of PointData written for the Piece thus far.
+        label nPointData_;
+
+        //- The output file name
+        fileName outputFile_;
+
+        //- The VTK formatter in use (master process)
+        autoPtr<vtk::formatter> format_;
+
+        //- The backend ostream in use (master process)
+        std::ofstream os_;
+
+
+    // Protected Member Functions
+
+        //- The backend ostream in use
+        inline std::ofstream& os();
+
+        //- The VTK formatter in use
+        inline vtk::formatter& format();
+
+        //- True if the output state corresponds to the test state.
+        inline bool isState(outputState test) const;
+
+        //- True if the output state does not correspond to the test state.
+        inline bool notState(outputState test) const;
+
+
+        //- Trigger change state to Piece. Resets nCellData_, nPointData_.
+        bool enter_Piece();
+
+        //- Explicitly end Piece output and switch to DECLARED state
+        //  Ignored (no-op) if not currently in the PIECE state.
+        bool endPiece();
+
+        //- Trigger change state to CellData.
+        //  Legacy requires both parameters. XML doesn't require either.
+        //
+        //  \return True if the state changed
+        bool enter_CellData(label nEntries, label nFields);
+
+        //- Trigger change state to PointData
+        //  Legacy requires both parameters. XML doesn't require either.
+        //
+        //  \return True if the state changed
+        bool enter_PointData(label nEntries, label nFields);
+
+        //- Emit file footer (end data, end piece, end file)
+        bool exit_File();
+
+
+        //- No copy construct
+        fileWriter(const fileWriter&) = delete;
+
+        //- No copy assignment
+        void operator=(const fileWriter&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        fileWriter
+        (
+            const vtk::fileTag contentType,
+            const vtk::outputOptions opts
+        );
+
+
+    //- Destructor
+    virtual ~fileWriter();
+
+
+    // Member Functions
+
+        //- The content type
+        inline vtk::fileTag contentType() const;
+
+        //- The output options in use
+        inline vtk::outputOptions opts() const;
+
+        //- File extension for current format type.
+        inline word ext() const;
+
+        //- Commonly used query
+        inline bool legacy() const;
+
+        //- Parallel output requested?
+        inline bool parallel() const;
+
+        //- The output state in printable format
+        inline const word& state() const;
+
+        //- The current output file name
+        inline const fileName& output() const;
+
+
+        //- Open file for writing (creates parent directory).
+        //  The file name is normally without an extension, this will be added
+        //  according to the content-type and the output format (legacy/xml).
+        //  If the file name has an extension, it will be used where if
+        //  appropriate or changed to suit the format (legacy/xml) type.
+        //  \note Expected calling states: (CLOSED).
+        bool open(const fileName& file, bool parallel=Pstream::parRun());
+
+        //- End the file contents and close the file after writing.
+        //  \note Expected calling states: (PIECE | CELL_DATA | POINT_DATA).
+        void close();
+
+
+        //- Write file header (non-collective)
+        //  \note Expected calling states: (OPENED)
+        virtual bool beginFile(std::string title = "");
+
+        //- Begin FieldData output section for specified number of fields.
+        //  \param nFields is for legacy format only.
+        //      When nFields=0, this a no-op for legacy format.
+        //  \note Expected calling states: (OPENED | DECLARED).
+        bool beginFieldData(label nFields = 0);
+
+        //- Write mesh topology.
+        //  Also writes the file header if not previously written.
+        //  \note Must be called prior to writing CellData or PointData
+        virtual bool writeGeometry() = 0;
+
+
+        //- Begin CellData output section for specified number of fields.
+        //  Must be called prior to writing any cell data fields.
+        //  \param nFields is for legacy format only.
+        //      When nFields=0, this a no-op for legacy format.
+        //  \note Expected calling states: (PIECE | POINT_DATA).
+        //
+        //  \return True if the state changed
+        virtual bool beginCellData(label nFields = 0) = 0;
+
+        //- Begin PointData for specified number of fields.
+        //  Must be called prior to writing any point data fields.
+        //  \param nFields is for legacy format only.
+        //      When nFields=0, this a no-op for legacy format.
+        //  \note Expected calling states: (PIECE | CELL_DATA).
+        //
+        //  \return True if the state changed
+        virtual bool beginPointData(label nFields = 0) = 0;
+
+        //- Return the number of CellData written for the Piece thus far.
+        inline label nCellData() const;
+
+        //- Return the number of PointData written for the Piece thus far.
+        inline label nPointData() const;
+
+
+        //- Explicitly end FieldData output and switch to DECLARED state
+        //  Ignored (no-op) if not currently in the FIELD_DATA state.
+        bool endFieldData();
+
+        //- Explicitly end CellData output and switch to PIECE state
+        //  Ignored (no-op) if not currently in the CELL_DATA state.
+        bool endCellData();
+
+        //- Explicitly end PointData output and switch to PIECE state
+        //  Ignored (no-op) if not currently in the POINT_DATA state.
+        bool endPointData();
+
+        //- Write "TimeValue" FieldData (name as per Catalyst output)
+        //  Must be called within the FIELD_DATA state.
+        //  \note As a convenience this can also be called from
+        //      (OPENED | DECLARED) states, in which case it invokes
+        //      beginFieldData(1) internally.
+        void writeTimeValue(scalar timeValue);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace vtk
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "foamVtkFileWriterI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fileFormats/vtk/file/foamVtkFileWriterI.H b/src/fileFormats/vtk/file/foamVtkFileWriterI.H
new file mode 100644
index 00000000000..f50541eced6
--- /dev/null
+++ b/src/fileFormats/vtk/file/foamVtkFileWriterI.H
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+inline std::ofstream& Foam::vtk::fileWriter::os()
+{
+    return os_;
+}
+
+
+inline Foam::vtk::formatter& Foam::vtk::fileWriter::format()
+{
+    return *format_;
+}
+
+
+inline bool Foam::vtk::fileWriter::isState(outputState test) const
+{
+    return (test == state_);
+}
+
+
+inline bool Foam::vtk::fileWriter::notState(outputState test) const
+{
+    return (test != state_);
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline Foam::vtk::fileTag Foam::vtk::fileWriter::contentType() const
+{
+    return contentType_;
+}
+
+
+inline Foam::vtk::outputOptions Foam::vtk::fileWriter::opts() const
+{
+    return opts_;
+}
+
+
+inline Foam::word Foam::vtk::fileWriter::ext() const
+{
+    return opts_.ext(contentType_);
+}
+
+
+inline bool Foam::vtk::fileWriter::legacy() const
+{
+    return opts_.legacy();
+}
+
+
+inline bool Foam::vtk::fileWriter::parallel() const
+{
+    return parallel_;
+}
+
+
+inline const Foam::word& Foam::vtk::fileWriter::state() const
+{
+    return stateNames[state_];
+}
+
+
+inline const Foam::fileName& Foam::vtk::fileWriter::output() const
+{
+    return outputFile_;
+}
+
+
+inline Foam::label Foam::vtk::fileWriter::nCellData() const
+{
+    return nCellData_;
+}
+
+
+inline Foam::label Foam::vtk::fileWriter::nPointData() const
+{
+    return nPointData_;
+}
+
+
+// ************************************************************************* //
-- 
GitLab