From 2a72baf29f8979173d262d3a8678814c06be0a74 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Wed, 14 Jun 2017 00:28:58 +0200
Subject: [PATCH] ENH: support direct writing of fields from
 vtk::internalWriter

- eliminates the PtrList requirement (more flexible)

COMP: use tmp intermediate for volPointInterpolation return value

- gcc 4.8.5 had some weird issue of otherwise not binding a const-ref.
  (in foamVtkInternalWriterTemplates.C)
---
 .../vtk/output/foamVtkInternalWriter.H        |  58 ++--
 .../output/foamVtkInternalWriterTemplates.C   | 262 ++++++++++--------
 2 files changed, 182 insertions(+), 138 deletions(-)

diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.H b/src/conversion/vtk/output/foamVtkInternalWriter.H
index 2751cd67859..7fd4aa4f5da 100644
--- a/src/conversion/vtk/output/foamVtkInternalWriter.H
+++ b/src/conversion/vtk/output/foamVtkInternalWriter.H
@@ -153,39 +153,65 @@ public:
         void writeFooter();
 
 
-        //- Write internal fields
+      // Write fields (individually)
+
+        //- Write the internal field
         template<class Type>
+        void write(const DimensionedField<Type, volMesh>& field);
+
+        //- Write the volume field (internal part)
+        template<class Type, template<class> class PatchField>
+        void write(const GeometricField<Type, PatchField, volMesh>& field);
+
+        //- Write the point field
+        //  Interpolate to originating cell centre for decomposed cells.
+        template<class Type, template<class> class PatchField>
         void write
         (
-            const UPtrList
-            <
-                const DimensionedField<Type, volMesh>
-            >& flds
+            const GeometricField<Type, PatchField, pointMesh>& field
         );
 
-        //- Write volFields
-        template<class Type, template<class> class PatchField>
+        //- Write point-interpolated internal field
+        template<class Type>
+        void write
+        (
+            const volPointInterpolation& pInterp,
+            const DimensionedField<Type, volMesh>& vfield
+        );
+
+        //- Write point-interpolated volume field
+        template<class Type>
+        void write
+        (
+            const volPointInterpolation& pInterp,
+            const GeometricField<Type, fvPatchField, volMesh>& vfield
+        );
+
+
+      // Write fields (collectively)
+
+        //- Write multiple internal fields
+        template<class Type>
         void write
         (
             const UPtrList
             <
-                const GeometricField<Type, PatchField, volMesh>
+                const DimensionedField<Type, volMesh>
             >& flds
         );
 
-        //- Write pointFields on all mesh points.
-        //  Interpolate to cell centre for decomposed cell centres.
-        template<class Type, template<class> class PatchField>
+        //- Write multiple volume/point fields
+        template<class Type, template<class> class PatchField, class GeoMesh>
         void write
         (
             const UPtrList
             <
-                const GeometricField<Type, PatchField, pointMesh>
+                const GeometricField<Type, PatchField, GeoMesh>
             >& flds
         );
 
 
-        //- Interpolated internal fields
+        //- Write multiple point-interpolated internal fields
         template<class Type>
         void write
         (
@@ -196,14 +222,14 @@ public:
             >& flds
         );
 
-        //- Interpolated volFields
-        template<class Type, template<class> class PatchField>
+        //- Write multiple point-interpolated volume fields
+        template<class Type>
         void write
         (
             const volPointInterpolation& pInterp,
             const UPtrList
             <
-                const GeometricField<Type, PatchField, volMesh>
+                const GeometricField<Type, fvPatchField, volMesh>
             >& flds
         );
 
diff --git a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C
index c316c36d149..77689e5ec7b 100644
--- a/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C
+++ b/src/conversion/vtk/output/foamVtkInternalWriterTemplates.C
@@ -33,7 +33,7 @@ License
 template<class Type>
 void Foam::vtk::internalWriter::write
 (
-    const UPtrList<const DimensionedField<Type, volMesh>>& flds
+    const DimensionedField<Type, volMesh>& field
 )
 {
     const labelList& cellMap = vtuCells_.cellMap();
@@ -41,27 +41,22 @@ void Foam::vtk::internalWriter::write
     const int nCmpt(pTraits<Type>::nComponents);
     // const uint64_t payLoad(cellMap.size() * nCmpt * sizeof(float));
 
-    forAll(flds, i)
+    if (legacy_)
     {
-        const auto& fld = flds[i];
-
-        if (legacy_)
-        {
-            legacy::floatField(os(), fld.name(), nCmpt, cellMap.size());
-        }
-        else
-        {
-            format().openDataArray<float, nCmpt>(fld.name())
-                .closeTag();
-        }
+        legacy::floatField(os(), field.name(), nCmpt, cellMap.size());
+    }
+    else
+    {
+        format().openDataArray<float, nCmpt>(field.name())
+            .closeTag();
+    }
 
-        // writeField includes payload size
-        vtk::writeField(format(), fld, cellMap);
+    // writeField includes payload size, and flush
+    vtk::writeField(format(), field, cellMap);
 
-        if (!legacy_)
-        {
-            format().endDataArray();
-        }
+    if (!legacy_)
+    {
+        format().endDataArray();
     }
 }
 
@@ -69,82 +64,94 @@ void Foam::vtk::internalWriter::write
 template<class Type, template<class> class PatchField>
 void Foam::vtk::internalWriter::write
 (
-    const UPtrList<const GeometricField<Type, PatchField, volMesh>>& flds
+    const GeometricField<Type, PatchField, volMesh>& field
 )
 {
-    const labelList& cellMap = vtuCells_.cellMap();
+    write(field.internalField());
+}
+
+
+template<class Type, template<class> class PatchField>
+void Foam::vtk::internalWriter::write
+(
+    const GeometricField<Type, PatchField, pointMesh>& field
+)
+{
+    const labelList& addPointCellLabels = vtuCells_.addPointCellLabels();
 
     const int nCmpt(pTraits<Type>::nComponents);
-    // const uint64_t payLoad(cellMap.size() * nCmpt * sizeof(float));
+    const label nVals(vtuCells_.nFieldPoints());
 
-    forAll(flds, i)
+    // Only needed for non-legacy
+    const uint64_t payLoad(nVals * nCmpt * sizeof(float));
+
+    if (legacy_)
+    {
+        legacy::floatField(os(), field.name(), nCmpt, nVals);
+    }
+    else
     {
-        const auto& fld = flds[i];
+        format().openDataArray<float, nCmpt>(field.name())
+            .closeTag();
+    }
+
+    format().writeSize(payLoad);
+    vtk::writeList(format(), field);
 
-        if (legacy_)
-        {
-            legacy::floatField(os(), fld.name(), nCmpt, cellMap.size());
-        }
-        else
-        {
-            format().openDataArray<float, nCmpt>(fld.name())
-                .closeTag();
-        }
+    for (const label cellId : addPointCellLabels)
+    {
+        const Type val = interpolatePointToCell(field, cellId);
+        vtk::write(format(), val);
+    }
 
-        // writeField includes payload size
-        vtk::writeField(format(), fld, cellMap);
+    format().flush();
 
-        if (!legacy_)
-        {
-            format().endDataArray();
-        }
+    if (!legacy_)
+    {
+        format().endDataArray();
     }
 }
 
 
-template<class Type, template<class> class PatchField>
+template<class Type>
 void Foam::vtk::internalWriter::write
 (
-    const UPtrList<const GeometricField<Type, PatchField, pointMesh>>& flds
+    const volPointInterpolation& pInterp,
+    const DimensionedField<Type, volMesh>& vfield
 )
 {
+    typedef DimensionedField<Type, pointMesh> PointFieldType;
+
+    // Use tmp intermediate. Compiler sometimes weird otherwise.
+    tmp<PointFieldType> tfield = pInterp.interpolate(vfield);
+    const PointFieldType& pfield = tfield();
+
     const labelList& addPointCellLabels = vtuCells_.addPointCellLabels();
 
     const int nCmpt(pTraits<Type>::nComponents);
-    const int nVals(vtuCells_.nFieldPoints());
+    const label nVals(vtuCells_.nFieldPoints());
 
     // Only needed for non-legacy
     const uint64_t payLoad(nVals * nCmpt * sizeof(float));
 
-    forAll(flds, i)
+    if (legacy_)
     {
-        const auto& fld = flds[i];
-
-        if (legacy_)
-        {
-            legacy::floatField(os(), fld.name(), nCmpt, nVals);
-        }
-        else
-        {
-            format().openDataArray<float, nCmpt>(fld.name())
-                .closeTag();
-        }
-
-        format().writeSize(payLoad);
-        vtk::writeList(format(), fld);
-
-        forAll(addPointCellLabels, i)
-        {
-            const Type val = interpolatePointToCell(fld, addPointCellLabels[i]);
-            vtk::write(format(), val);
-        }
+        legacy::floatField(os(), vfield.name(), nCmpt, nVals);
+    }
+    else
+    {
+        format().openDataArray<float, nCmpt>(vfield.name())
+            .closeTag();
+    }
 
-        format().flush();
+    format().writeSize(payLoad);
+    vtk::writeList(format(), pfield);
+    vtk::writeList(format(), vfield, addPointCellLabels);
+    format().flush();
 
-        if (!legacy_)
-        {
-            format().endDataArray();
-        }
+    if (!legacy_)
+    {
+        format().endDataArray();
     }
 }
 
@@ -153,84 +160,95 @@ template<class Type>
 void Foam::vtk::internalWriter::write
 (
     const volPointInterpolation& pInterp,
-    const UPtrList<const DimensionedField<Type, volMesh>>& flds
+    const GeometricField<Type, fvPatchField, volMesh>& vfield
 )
 {
+    typedef GeometricField<Type, pointPatchField, pointMesh> PointFieldType;
+
+    // Use tmp intermediate. Compiler sometimes weird otherwise.
+    tmp<PointFieldType> tfield = pInterp.interpolate(vfield);
+    const PointFieldType& pfield = tfield();
+
     const labelList& addPointCellLabels = vtuCells_.addPointCellLabels();
 
     const int nCmpt(pTraits<Type>::nComponents);
-    const int nVals(vtuCells_.nFieldPoints());
+    const label nVals(vtuCells_.nFieldPoints());
 
     // Only needed for non-legacy
     const uint64_t payLoad(nVals * nCmpt * sizeof(float));
 
-    forAll(flds, i)
+    if (legacy_)
     {
-        const auto& vfield = flds[i];
-        const auto& pfield = pInterp.interpolate(vfield)();
+        legacy::floatField(os(), vfield.name(), nCmpt, nVals);
+    }
+    else
+    {
+        format().openDataArray<float, nCmpt>(vfield.name())
+            .closeTag();
+    }
 
-        if (legacy_)
-        {
-            legacy::floatField(os(), vfield.name(), nCmpt, nVals);
-        }
-        else
-        {
-            format().openDataArray<float, nCmpt>(vfield.name())
-                .closeTag();
-        }
+    format().writeSize(payLoad);
+    vtk::writeList(format(), pfield);
+    vtk::writeList(format(), vfield, addPointCellLabels);
+    format().flush();
 
-        format().writeSize(payLoad);
-        vtk::writeList(format(), pfield);
-        vtk::writeList(format(), vfield, addPointCellLabels);
-        format().flush();
+    if (!legacy_)
+    {
+        format().endDataArray();
+    }
+}
 
-        if (!legacy_)
-        {
-            format().endDataArray();
-        }
+
+template<class Type>
+void Foam::vtk::internalWriter::write
+(
+    const UPtrList<const DimensionedField<Type, volMesh>>& flds
+)
+{
+    for (const auto& field : flds)
+    {
+        write(field);
     }
 }
 
 
-template<class Type, template<class> class PatchField>
+template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::vtk::internalWriter::write
 (
-    const volPointInterpolation& pInterp,
-    const UPtrList<const GeometricField<Type, PatchField, volMesh>>& flds
+    const UPtrList<const GeometricField<Type, PatchField, GeoMesh>>& flds
 )
 {
-    const labelList& addPointCellLabels = vtuCells_.addPointCellLabels();
+    for (const auto& field : flds)
+    {
+        write(field);
+    }
+}
 
-    const int nCmpt(pTraits<Type>::nComponents);
-    const int nVals(vtuCells_.nFieldPoints());
 
-    // Only needed for non-legacy
-    const uint64_t payLoad(nVals * nCmpt * sizeof(float));
+template<class Type>
+void Foam::vtk::internalWriter::write
+(
+    const volPointInterpolation& pInterp,
+    const UPtrList<const DimensionedField<Type, volMesh>>& flds
+)
+{
+    for (const auto& field : flds)
+    {
+        write(pInterp, field);
+    }
+}
+
 
-    forAll(flds, i)
-    {
-        const auto& vfield = flds[i];
-        const auto& pfield = pInterp.interpolate(vfield)();
-
-        if (legacy_)
-        {
-            legacy::floatField(os(), vfield.name(), nCmpt, nVals);
-        }
-        else
-        {
-            format().openDataArray<float, nCmpt>(vfield.name())
-                .closeTag();
-        }
-
-        format().writeSize(payLoad);
-        vtk::writeList(format(), pfield);
-        vtk::writeList(format(), vfield, addPointCellLabels);
-        format().flush();
-
-        if (!legacy_)
-        {
-            format().endDataArray();
-        }
+template<class Type>
+void Foam::vtk::internalWriter::write
+(
+    const volPointInterpolation& pInterp,
+    const UPtrList<const GeometricField<Type, fvPatchField, volMesh>>& flds
+)
+{
+    for (const auto& field : flds)
+    {
+        write(pInterp, field);
     }
 }
 
-- 
GitLab