From 120e4a46bce683c3959e4b532a0b5a0e71a69fb3 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Thu, 28 Oct 2021 16:40:03 +0200
Subject: [PATCH] BUG: face flips lost on foamToVTK faceZone output

- previously used an indirect patch to get the sampling locations,
  but this doesn't take account of the face flips. Now use
  the faceZone intrinsic for generating a properly flipped patch
  and provide the sampling locations separately.

STYLE: adjust compatiblity header for surfaceMeshWriter
---
 .../foamToVTK/convertSurfaceFields.H          | 11 +++----
 .../foamToVTK/writeAreaFields.H               |  2 +-
 .../foamToVTK/writeSurfaceFields.H            |  7 +++--
 .../meshes/polyMesh/zones/cellZone/cellZone.H |  1 +
 .../meshes/polyMesh/zones/faceZone/faceZone.H |  2 +-
 .../polyMesh/zones/pointZone/pointZone.H      |  1 +
 .../meshes/polyMesh/zones/zone/zone.H         | 10 ++++++-
 .../foamVtkGenericPatchGeoFieldsWriter.C      | 19 ++++++++----
 .../foamVtkGenericPatchGeoFieldsWriter.H      | 11 +++++--
 .../vtk/output/foamVtkSurfaceMeshWriter.H     | 29 +++----------------
 src/meshTools/sets/topoSets/faceZoneSet.C     |  2 +-
 src/meshTools/sets/topoSets/faceZoneSet.H     |  1 -
 12 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/convertSurfaceFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/convertSurfaceFields.H
index 0681e103b3a..6803a25d746 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/convertSurfaceFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/convertSurfaceFields.H
@@ -194,11 +194,8 @@ Description
                 continue;
             }
 
-            uindirectPrimitivePatch pp
-            (
-                UIndirectList<face>(mesh.faces(), fz),
-                mesh.points()
-            );
+            // Retrieve as primitiveFacePatch with faces properly flipped
+            const primitiveFacePatch& pp = fz();
 
             vtkWriterType_faceZone writer
             (
@@ -224,11 +221,11 @@ Description
 
             for (const auto& fld : sScalars)
             {
-                writer.write(fld);
+                writer.write(fld, fz.addressing());
             }
             for (const auto& fld : sVectors)
             {
-                writer.write(fld);
+                writer.write(fld, fz.addressing());
             }
 
             fileName outputName(writer.output());
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H
index 9bd2cb8c37c..ca265a25c95 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeAreaFields.H
@@ -28,7 +28,7 @@ InNamespace
 
 Description
     Read finite-area fields from disk
-    and write with vtk::surfaceMeshWriter
+    and write with vtk::uindirectPatchGeoFieldsWriter
 
 SourceFiles
     writeAreaFields.H
diff --git a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeSurfaceFields.H b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeSurfaceFields.H
index ef675278319..b41ce0a8893 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToVTK/writeSurfaceFields.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToVTK/writeSurfaceFields.H
@@ -38,7 +38,8 @@ SourceFiles
 #define writeSurfaceFields_H
 
 #include "readFields.H"
-#include "foamVtkUIndPatchGeoFieldsWriter.H"
+#include "primitiveFacePatch.H"
+#include "foamVtkGenericPatchGeoFieldsWriter.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -46,7 +47,9 @@ namespace Foam
 {
 
 // Writer type for face zones + fields
-typedef vtk::uindirectPatchGeoFieldsWriter vtkWriterType_faceZone;
+typedef
+    vtk::GenericPatchGeoFieldsWriter<primitiveFacePatch>
+    vtkWriterType_faceZone;
 
 } // End namespace Foam
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
index 857e878b215..01be2b30bae 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
@@ -211,6 +211,7 @@ public:
         //- Helper function to re-direct to zone::localID(...)
         label whichCell(const label globalCellID) const;
 
+
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
index 6bdb8c65d48..ea247d84dbf 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
@@ -45,7 +45,6 @@ SourceFiles
 
 #include "zone.H"
 #include "faceZoneMeshFwd.H"
-#include "boolList.H"
 #include "primitiveFacePatch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -323,6 +322,7 @@ public:
             const bool flipMapValue
         );
 
+
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
index 0b883e84130..6702c027d58 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
@@ -214,6 +214,7 @@ public:
         //- Helper function to re-direct to zone::localID(...)
         label whichPoint(const label globalPointID) const;
 
+
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
index d211b3f64c2..f99a63bff42 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
@@ -136,16 +136,24 @@ public:
 
     // Member Functions
 
-        //- Return a reference to the look-up map
+        //- Demand-driven: the look-up map from global to local id
         const Map<label>& lookupMap() const;
 
         //- Lookup local address in zone for given global index.
         //  \return the local address, or -1 if the item is not in the zone
         label localID(const label globalID) const;
 
+
+        //- The addressing used by the zone
+        const labelList& addressing() const noexcept
+        {
+            return static_cast<const labelList&>(*this);
+        }
+
         //- Clear addressing
         virtual void clearAddressing();
 
+
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const = 0;
 
diff --git a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C
index ff8c162b855..2cfcdfb29a1 100644
--- a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C
+++ b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.C
@@ -32,12 +32,20 @@ template<class Type>
 Foam::tmp<Foam::Field<Type>>
 Foam::vtk::GenericPatchGeoFieldsWriter<PatchType>::getFaceField
 (
-    const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
+    const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld,
+    const labelUList& faceAddr
 ) const
 {
-    const polyBoundaryMesh& patches = sfld.mesh().boundaryMesh();
+    if (this->patch().size() != faceAddr.size())
+    {
+        FatalErrorInFunction
+            << "Inconsistent sizing: patch has "
+            << this->patch().size() << " faces, addressing has "
+            << faceAddr.size() << " faces!" << nl
+            << Foam::exit(FatalError);
+    }
 
-    const labelList& faceAddr = this->patch().addressing();
+    const polyBoundaryMesh& patches = sfld.mesh().boundaryMesh();
 
     auto tfld = tmp<Field<Type>>::New(faceAddr.size());
     auto iter = tfld.ref().begin();
@@ -69,13 +77,14 @@ template<class PatchType>
 template<class Type>
 void Foam::vtk::GenericPatchGeoFieldsWriter<PatchType>::write
 (
-    const GeometricField<Type, fvsPatchField, surfaceMesh>& field
+    const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
+    const labelUList& faceAddr
 )
 {
     this->GenericPatchWriter<PatchType>::writeCellData
     (
         field.name(),
-        getFaceField(field)()
+        getFaceField(field, faceAddr)()
     );
 }
 
diff --git a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H
index 0ec42b092c1..b76971eec84 100644
--- a/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H
+++ b/src/conversion/vtk/output/foamVtkGenericPatchGeoFieldsWriter.H
@@ -62,10 +62,12 @@ class GenericPatchGeoFieldsWriter
     // Private Member Functions
 
         //- Get face field (internal face or boundary face)
+        //- at specified face locations
         template<class Type>
         tmp<Field<Type>> getFaceField
         (
-            const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld
+            const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld,
+            const labelUList& faceAddr
         ) const;
 
 
@@ -88,11 +90,14 @@ public:
 
     // Member Functions
 
-        //- Write volume-mesh surface field (CellData)
+        //- Write volume-mesh surface field (CellData) from specified mesh
+        //- faces.
+        //  For an indirect patch this will often simply be its addressing()
         template<class Type>
         void write
         (
-            const GeometricField<Type, fvsPatchField, surfaceMesh>& field
+            const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
+            const labelUList& faceAddr
         );
 
         //- Write area-mesh surface field (CellData)
diff --git a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H
index 4acb3a19ab7..f3aafa77966 100644
--- a/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H
+++ b/src/conversion/vtk/output/foamVtkSurfaceMeshWriter.H
@@ -8,39 +8,20 @@
     Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
+    This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 
 Typedef
     Foam::vtk::surfaceMeshWriter
 
 Description
-    Alias for Foam::vtk::indirectPatchGeoFieldsWriter.
-
-    Write vtp file (or legacy vtk) with support for geometric fields.
-
-See Also
-    Foam::vtk::GenericPatchWriter
+    Older typedef for Foam::vtk::indirectPatchGeoFieldsWriter
 
 \*---------------------------------------------------------------------------*/
 
 #ifndef Foam_vtk_surfaceMeshWriter_H
 #define Foam_vtk_surfaceMeshWriter_H
 
-#include "foamVtkGenericPatchGeoFieldsWriter.H"
-#include "indirectPrimitivePatch.H"
+#include "foamVtkIndPatchGeoFieldsWriter.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -51,9 +32,7 @@ namespace vtk
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-typedef
-    GenericPatchGeoFieldsWriter<indirectPrimitivePatch>
-    surfaceMeshWriter;
+typedef indirectPatchGeoFieldsWriter surfaceMeshWriter;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/meshTools/sets/topoSets/faceZoneSet.C b/src/meshTools/sets/topoSets/faceZoneSet.C
index 753eae1b693..94dae8b7025 100644
--- a/src/meshTools/sets/topoSets/faceZoneSet.C
+++ b/src/meshTools/sets/topoSets/faceZoneSet.C
@@ -86,7 +86,7 @@ Foam::faceZoneSet::faceZoneSet
     )
     {
         const faceZone& fz = faceZones[zoneID];
-        addressing_ = fz;
+        addressing_ = fz.addressing();
         flipMap_ = fz.flipMap();
     }
 
diff --git a/src/meshTools/sets/topoSets/faceZoneSet.H b/src/meshTools/sets/topoSets/faceZoneSet.H
index 8df6e623c65..f5f6c9e6295 100644
--- a/src/meshTools/sets/topoSets/faceZoneSet.H
+++ b/src/meshTools/sets/topoSets/faceZoneSet.H
@@ -39,7 +39,6 @@ SourceFiles
 #define faceZoneSet_H
 
 #include "faceSet.H"
-#include "boolList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-- 
GitLab