From 1a35a3ef0fbb1830b7540c507d532acafc38b1d0 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Wed, 13 Mar 2019 14:13:04 +0100
Subject: [PATCH] ENH: surface writers now track their own write status

- instead of deciding beforehand if a surface format requires a separate
  geometry file (or if a geometry file should be written if no fields were
  written) now determine afterwards if something was written.

  This improves the overall reliability (consistency) and is more
  convenient for the caller as well.
---
 .../sampledSurfaces/sampledSurfaces.C         | 26 ++++++++---------
 .../sampledSurfaces/sampledSurfaces.H         | 10 +++----
 .../boundaryData/boundaryDataSurfaceWriter.C  |  2 ++
 .../writers/ensight/ensightSurfaceWriter.C    |  1 +
 .../ensight/ensightSurfaceWriterCollated.C    |  5 ++--
 .../ensight/ensightSurfaceWriterUncollated.C  |  2 ++
 src/surfMesh/writers/foam/foamSurfaceWriter.C |  8 ++++++
 .../writers/nastran/nastranSurfaceWriter.C    |  1 +
 .../nastran/nastranSurfaceWriterImpl.C        |  1 +
 src/surfMesh/writers/null/nullSurfaceWriter.C |  7 +++++
 src/surfMesh/writers/null/nullSurfaceWriter.H |  7 +++--
 .../writers/proxy/proxySurfaceWriter.C        |  1 +
 src/surfMesh/writers/raw/rawSurfaceWriter.C   |  1 +
 .../writers/raw/rawSurfaceWriterImpl.C        |  1 +
 .../writers/starcd/starcdSurfaceWriter.C      |  8 ++++++
 src/surfMesh/writers/surfaceWriter.C          | 15 ++++++++++
 src/surfMesh/writers/surfaceWriter.H          | 28 ++++++++++++++-----
 src/surfMesh/writers/vtk/vtkSurfaceWriter.C   |  2 ++
 18 files changed, 96 insertions(+), 30 deletions(-)

diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
index fcfb3478e6b..8af64331726 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
@@ -536,6 +536,7 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
     // Only seems to be needed for VTK legacy
     countFields();
 
+
     // Update writers
 
     forAll(*this, surfi)
@@ -544,7 +545,6 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
 
         if (((request & actions_[surfi]) & ACTION_WRITE) && nFaces_[surfi])
         {
-            // Output writers
             surfaceWriter& outWriter = writers_[surfi];
 
             if (outWriter.needsUpdate())
@@ -556,24 +556,14 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
 
             outWriter.beginTime(obr_.time());
 
-
-            // Write geometry if no fields would otherwise be written
-            if (!outWriter.nFields() || outWriter.separateGeometry())
-            {
-                outWriter.write();
-                continue;
-            }
-
-            // Write original ids - as label or scalar field
-
-            const word fieldName("Ids");
+            // Write original ids
             if (s.hasFaceIds() && !s.interpolate())
             {
                 writeSurface
                 (
                     outWriter,
                     Field<label>(s.originalIds()),
-                    fieldName
+                    "Ids"
                 );
             }
         }
@@ -610,8 +600,16 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
     // Finish this time step
     forAll(writers_, surfi)
     {
-        if ((request & actions_[surfi]) & ACTION_WRITE)
+        if (((request & actions_[surfi]) & ACTION_WRITE) && nFaces_[surfi])
         {
+            // Write geometry if no fields were written so that we still
+            // can have something to look at
+
+            if (!writers_[surfi].wroteData())
+            {
+                writers_[surfi].write();
+            }
+
             writers_[surfi].endTime();
         }
     }
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
index fae2c54f67f..c72fc1034d2 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
@@ -352,19 +352,19 @@ public:
         void verbose(const bool verbosity = true);
 
         //- Read the sampledSurfaces dictionary
-        virtual bool read(const dictionary&);
+        virtual bool read(const dictionary& dict);
 
-        //- Execute, currently does nothing
+        //- Sample and store if the sampleOnExecute is enabled.
         virtual bool execute();
 
         //- Sample and write
         virtual bool write();
 
         //- Update for changes of mesh - expires the surfaces
-        virtual void updateMesh(const mapPolyMesh&);
+        virtual void updateMesh(const mapPolyMesh& mpm);
 
         //- Update for mesh point-motion - expires the surfaces
-        virtual void movePoints(const polyMesh&);
+        virtual void movePoints(const polyMesh& mesh);
 
         //- Update for changes of mesh due to readUpdate - expires the surfaces
         virtual void readUpdate(const polyMesh::readUpdateState state);
@@ -372,7 +372,7 @@ public:
         //- Get merge tolerance
         static scalar mergeTol();
 
-        //- Set tolerance (and return old tolerance)
+        //- Set tolerance and return old tolerance
         static scalar mergeTol(const scalar tol);
 };
 
diff --git a/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C
index 8b3db9f2f46..fc8482b8141 100644
--- a/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C
+++ b/src/surfMesh/writers/boundaryData/boundaryDataSurfaceWriter.C
@@ -159,6 +159,7 @@ Foam::fileName Foam::surfaceWriters::boundaryDataWriter::write()
         //pts.writeEndDivider(os);
     }
 
+    wroteGeom_ = true;
     return surfaceDir;
 }
 
@@ -264,6 +265,7 @@ Foam::fileName Foam::surfaceWriters::boundaryDataWriter::writeTemplate
         OFstream(outputFile)() << tfield();
     }
 
+    wroteGeom_ = true;
     return surfaceDir;
 }
 
diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriter.C b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C
index 69f2d69e8b2..f1e31b2e669 100644
--- a/src/surfMesh/writers/ensight/ensightSurfaceWriter.C
+++ b/src/surfMesh/writers/ensight/ensightSurfaceWriter.C
@@ -185,6 +185,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::write()
     // {
     //     return writeUncollated();
     // }
+
     return writeUncollated();
 }
 
diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C
index 0b2724ae616..e80fce79991 100644
--- a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C
+++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C
@@ -34,7 +34,8 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated()
     // Geometry:  rootdir/surfaceName/surfaceName.case
     // Geometry:  rootdir/surfaceName/surfaceName.mesh
 
-    return fileName();
+    wroteGeom_ = true;
+    return fileName::null;
 }
 
 
@@ -368,7 +369,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
         }
     }
 
-
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C
index c3cd3a53789..0c89ebf75ac 100644
--- a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C
+++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C
@@ -97,6 +97,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated()
         osGeom << ensPart;
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
@@ -245,6 +246,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
         }
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/foam/foamSurfaceWriter.C b/src/surfMesh/writers/foam/foamSurfaceWriter.C
index 8d72939d696..2f011c7fe24 100644
--- a/src/surfMesh/writers/foam/foamSurfaceWriter.C
+++ b/src/surfMesh/writers/foam/foamSurfaceWriter.C
@@ -142,6 +142,7 @@ Foam::fileName Foam::surfaceWriters::foamWriter::write()
         OFstream(surfaceDir/"faceCentres")() << faceCentres;
     }
 
+    wroteGeom_ = true;
     return surfaceDir;
 }
 
@@ -155,6 +156,12 @@ Foam::fileName Foam::surfaceWriters::foamWriter::writeTemplate
     const Field<Type>& localValues
 )
 {
+    // Separate geometry
+    if (!wroteGeom_)
+    {
+        write();
+    }
+
     checkOpen();
 
     // Geometry should already have been written
@@ -197,6 +204,7 @@ Foam::fileName Foam::surfaceWriters::foamWriter::writeTemplate
         OFstream(outputFile)() << tfield();
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
index da98e638d4b..df5314c2951 100644
--- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
+++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
@@ -437,6 +437,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::write()
             << "ENDDATA" << nl;
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
index a1809c91e61..b507d45a4f5 100644
--- a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
+++ b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
@@ -255,6 +255,7 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
             << "ENDDATA" << endl;
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/null/nullSurfaceWriter.C b/src/surfMesh/writers/null/nullSurfaceWriter.C
index 9e245f91ec1..93ab5ea177f 100644
--- a/src/surfMesh/writers/null/nullSurfaceWriter.C
+++ b/src/surfMesh/writers/null/nullSurfaceWriter.C
@@ -87,6 +87,12 @@ bool Foam::surfaceWriters::nullWriter::needsUpdate() const
 }
 
 
+bool Foam::surfaceWriters::nullWriter::wroteData() const
+{
+    return true;
+}
+
+
 bool Foam::surfaceWriters::nullWriter::enabled() const
 {
     return false;
@@ -116,6 +122,7 @@ void Foam::surfaceWriters::nullWriter::open(const fileName& outputPath)
 
 Foam::fileName Foam::surfaceWriters::nullWriter::write()
 {
+    wroteGeom_ = true;
     return fileName::null;
 }
 
diff --git a/src/surfMesh/writers/null/nullSurfaceWriter.H b/src/surfMesh/writers/null/nullSurfaceWriter.H
index 5ccf8a5f099..809d7976510 100644
--- a/src/surfMesh/writers/null/nullSurfaceWriter.H
+++ b/src/surfMesh/writers/null/nullSurfaceWriter.H
@@ -94,10 +94,13 @@ public:
 
     // Capability
 
-        //- Never needs an update.
+        //- False: never needs an update.
         virtual bool needsUpdate() const;
 
-        //- The null writer is always disabled, which lets the caller
+        //- True: like a /dev/null device.
+        virtual bool wroteData() const;
+
+        //- False: The null writer is never enabled, which lets the caller
         //- skip various (possibly expensive) preparatory operations.
         virtual bool enabled() const;
 
diff --git a/src/surfMesh/writers/proxy/proxySurfaceWriter.C b/src/surfMesh/writers/proxy/proxySurfaceWriter.C
index 77518db6bd2..6bfbe35a2a7 100644
--- a/src/surfMesh/writers/proxy/proxySurfaceWriter.C
+++ b/src/surfMesh/writers/proxy/proxySurfaceWriter.C
@@ -135,6 +135,7 @@ Foam::fileName Foam::surfaceWriters::proxyWriter::write()
         );
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/raw/rawSurfaceWriter.C b/src/surfMesh/writers/raw/rawSurfaceWriter.C
index 2e79256aaa6..73c30f89aed 100644
--- a/src/surfMesh/writers/raw/rawSurfaceWriter.C
+++ b/src/surfMesh/writers/raw/rawSurfaceWriter.C
@@ -178,6 +178,7 @@ Foam::fileName Foam::surfaceWriters::rawWriter::write()
         os  << nl;
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
index 662f24d7b63..98b601cf081 100644
--- a/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
+++ b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
@@ -197,6 +197,7 @@ Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate
         }
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/starcd/starcdSurfaceWriter.C b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C
index 75412a20aec..70a5b5edc90 100644
--- a/src/surfMesh/writers/starcd/starcdSurfaceWriter.C
+++ b/src/surfMesh/writers/starcd/starcdSurfaceWriter.C
@@ -145,6 +145,7 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::write()
         ).write(outputFile, "inp");
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
@@ -158,6 +159,12 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate
     const Field<Type>& localValues
 )
 {
+    // Separate geometry
+    if (!wroteGeom_)
+    {
+        write();
+    }
+
     checkOpen();
 
     // Field:  rootdir/<TIME>/<field>_surfaceName.usr
@@ -206,6 +213,7 @@ Foam::fileName Foam::surfaceWriters::starcdWriter::writeTemplate
         }
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
diff --git a/src/surfMesh/writers/surfaceWriter.C b/src/surfMesh/writers/surfaceWriter.C
index 33ddbb7fb81..d910897c9de 100644
--- a/src/surfMesh/writers/surfaceWriter.C
+++ b/src/surfMesh/writers/surfaceWriter.C
@@ -138,6 +138,7 @@ Foam::surfaceWriter::surfaceWriter()
     surfComp_(),
     useComponents_(false),
     upToDate_(false),
+    wroteGeom_(false),
     parallel_(true),
     useTimeDir_(false),
     isPointData_(false),
@@ -244,6 +245,7 @@ void Foam::surfaceWriter::endTime()
 void Foam::surfaceWriter::open(const fileName& outputPath)
 {
     outputPath_ = outputPath;
+    wroteGeom_ = false;
 }
 
 
@@ -302,6 +304,7 @@ void Foam::surfaceWriter::open
 void Foam::surfaceWriter::close()
 {
     outputPath_.clear();
+    wroteGeom_ = false;
 }
 
 
@@ -369,11 +372,18 @@ bool Foam::surfaceWriter::needsUpdate() const
 }
 
 
+bool Foam::surfaceWriter::wroteData() const
+{
+    return wroteGeom_;
+}
+
+
 bool Foam::surfaceWriter::expire()
 {
     const bool changed = upToDate_;
 
     upToDate_ = false;
+    wroteGeom_ = false;
     nFields_ = 0;
     merged_.clear();
 
@@ -443,6 +453,11 @@ bool Foam::surfaceWriter::merge() const
     }
     upToDate_ = true;
 
+    if (changed)
+    {
+        wroteGeom_ = false;
+    }
+
     return changed;
 }
 
diff --git a/src/surfMesh/writers/surfaceWriter.H b/src/surfMesh/writers/surfaceWriter.H
index 15eb84b8cbc..89772d3f162 100644
--- a/src/surfMesh/writers/surfaceWriter.H
+++ b/src/surfMesh/writers/surfaceWriter.H
@@ -56,10 +56,14 @@ Description
         verbose  | Additional output verbosity             | no  | no
     \endtable
 
+Note
+    For surface formats that require geometry in a separate file,
+    it is the responsibility of the implementation (not the caller)
+    to ensure that this occurs.
+
 SourceFiles
-    sampledWriter.C
-    sampledWriterI.H
-    sampledWriterImpl.C
+    surfaceWriter.C
+    surfaceWriterI.H
 
 \*---------------------------------------------------------------------------*/
 
@@ -83,7 +87,7 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declarations
+// Forward Declarations
 class Time;
 class surfaceWriter;
 
@@ -118,10 +122,13 @@ protected:
         //- The topology/surface is up-to-date?
         mutable bool upToDate_;
 
-        //- Writing in parallel (vai master)
+        //- Track if geometry has been written since the last open
+        mutable bool wroteGeom_;
+
+        //- Writing in parallel (via master)
         bool parallel_;
 
-        //- Writer should do something funny
+        //- Insert additional time sub-directory in the output path
         bool useTimeDir_;
 
         //- Is point vs cell data
@@ -185,13 +192,17 @@ protected:
             const Field<Type>& localValues  //!< Local field values to write
         )
         {
+            if (!wroteGeom_)
+            {
+                return this->write();
+            }
             return fileName::null;
         }
 
 
 public:
 
-    // Public data
+    // Public Data
 
         //- The default merge dimension (1e-8)
         static scalar defaultMergeDim;
@@ -294,6 +305,9 @@ public:
         //- Does the writer need an update (eg, lagging behind surface changes)
         virtual bool needsUpdate() const;
 
+        //- Geometry or fields written since the last open?
+        virtual bool wroteData() const;
+
         //- Mark that surface changed and the writer will need an update,
         //- and set nFields = 0.
         //  May also free up unneeded data.
diff --git a/src/surfMesh/writers/vtk/vtkSurfaceWriter.C b/src/surfMesh/writers/vtk/vtkSurfaceWriter.C
index 39deb3d4d5f..37986a889c1 100644
--- a/src/surfMesh/writers/vtk/vtkSurfaceWriter.C
+++ b/src/surfMesh/writers/vtk/vtkSurfaceWriter.C
@@ -248,6 +248,7 @@ Foam::fileName Foam::surfaceWriters::vtkWriter::write()
         writer_->writeGeometry();
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
@@ -288,6 +289,7 @@ Foam::fileName Foam::surfaceWriters::vtkWriter::writeTemplate
         writer_->write(fieldName, tfield());
     }
 
+    wroteGeom_ = true;
     return outputFile;
 }
 
-- 
GitLab