From eeb050cca44d95e07fc53fd4f26273c35598071d Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 3 Apr 2020 15:00:25 +0200
Subject: [PATCH] ENH: refine geometry and field scaling for nastran and raw
 surfaces (#1600)

- enhancement and potential breaking change.

  Nastran surface writer previously used the keyword 'scale' for
  field scaling, which was applied uniformly to all output fields.

  Change the meaning of 'scale' to be geometric scaling
  (consistent with reading triSurfaceMesh etc).

  New 'fieldScale' entry is an optional dictionary of scaling
  parameters.

  Example,

      nastran
      {
          scale   1000;     // [m] -> [mm]
          fieldScale
          {
             "p.*"   0.01;  // [Pa] -> [mbar]
          }
      }
---
 .../writers/nastran/nastranSurfaceWriter.C    |  8 +++---
 .../writers/nastran/nastranSurfaceWriter.H    | 21 ++++++++++++---
 .../nastran/nastranSurfaceWriterImpl.C        | 11 ++++++--
 src/surfMesh/writers/raw/rawSurfaceWriter.C   | 14 ++++++----
 src/surfMesh/writers/raw/rawSurfaceWriter.H   | 14 ++++++++++
 .../writers/raw/rawSurfaceWriterImpl.C        | 26 +++++++++++++++----
 6 files changed, 75 insertions(+), 19 deletions(-)

diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
index fcfae7d7607..c59436fb1ff 100644
--- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
+++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C
@@ -238,7 +238,7 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry
 
     forAll(points, pointi)
     {
-        writeCoord(os, points[pointi], pointi);
+        writeCoord(os, points[pointi]*geometryScale_, pointi);
     }
 
     // Write faces, with on-the-fly decomposition (triangulation)
@@ -357,7 +357,8 @@ Foam::surfaceWriters::nastranWriter::nastranWriter()
     surfaceWriter(),
     writeFormat_(fieldFormat::SHORT),
     fieldMap_(),
-    scale_(1),
+    geometryScale_(1),
+    fieldScale_(),
     separator_()
 {}
 
@@ -378,7 +379,8 @@ Foam::surfaceWriters::nastranWriter::nastranWriter
         )
     ),
     fieldMap_(),
-    scale_(options.lookupOrDefault<scalar>("scale", 1)),
+    geometryScale_(options.getOrDefault<scalar>("scale", 1)),
+    fieldScale_(options.subOrEmptyDict("fieldScale")),
     separator_()
 {
     if (writeFormat_ == fieldFormat::FREE)
diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H
index e2ddba4ac74..a56169167be 100644
--- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H
+++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H
@@ -35,7 +35,8 @@ Description
         Property | Description                              | Required | Default
         fields   | field pairs for PLOAD2, PLOAD4           | yes   |
         format   | short / long / free                      | no    | long
-        scale    | output scaling                           | no    | 1
+        scale    | output geometry scaling                  | no    | 1
+        fieldScale | output field scaling (dictionary)      | no    | empty
     \endtable
 
     For example,
@@ -50,8 +51,14 @@ Description
                 (pMean  PLOAD2)
                 (p      PLOAD4)
             );
+
             format  free;     // format type
-            scale   2.0;      // output scaling
+
+            scale   1000;     // [m] -> [mm]
+            fieldScale
+            {
+               "p.*"   0.01;  // [Pa] -> [mbar]
+            }
         }
     }
     \endverbatim
@@ -81,6 +88,9 @@ Description
             `-- surfaceName1.{nas}
     \endverbatim
 
+Note
+    Output variable scaling does not apply to integer types such as Ids.
+
 SourceFiles
     nastranSurfaceWriter.C
     nastranSurfaceWriterImpl.C
@@ -128,8 +138,11 @@ private:
         //- Mapping from field name to data format enumeration
         HashTable<loadFormat> fieldMap_;
 
-        //- Scale to apply to values (default = 1.0)
-        scalar scale_;
+        //- Output geometry scaling
+        const scalar geometryScale_;
+
+        //- Output field scaling
+        const dictionary fieldScale_;
 
         //- Separator used for free format
         word separator_;
diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
index 56fee262501..bcffc522e30 100644
--- a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
+++ b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C
@@ -171,8 +171,15 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate
     outputFile.ext("nas");
 
 
-    // Currently the same scaling for all variables
-    const scalar varScale = scale_;
+    // Output scaling for the variable, but not for integer types.
+    // could also solve with clever templating
+
+    const scalar varScale =
+    (
+        std::is_integral<Type>::value
+      ? scalar(1)
+      : fieldScale_.getOrDefault<scalar>(fieldName, 1)
+    );
 
     if (verbose_)
     {
diff --git a/src/surfMesh/writers/raw/rawSurfaceWriter.C b/src/surfMesh/writers/raw/rawSurfaceWriter.C
index 93b6f34d644..d9df17180e7 100644
--- a/src/surfMesh/writers/raw/rawSurfaceWriter.C
+++ b/src/surfMesh/writers/raw/rawSurfaceWriter.C
@@ -47,7 +47,7 @@ namespace surfaceWriters
 
 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-namespace Foam
+namespace
 {
     // Emit x,y,z
     static inline void writePoint(Foam::Ostream& os, const Foam::point& p)
@@ -55,7 +55,7 @@ namespace Foam
         os << p.x() << ' ' << p.y() << ' ' << p.z();
     }
 
-} // End namespace Foam
+} // End anonymous namespace
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -72,7 +72,9 @@ defineSurfaceWriterWriteFields(Foam::surfaceWriters::rawWriter);
 Foam::surfaceWriters::rawWriter::rawWriter()
 :
     surfaceWriter(),
-    streamOpt_()
+    streamOpt_(),
+    geometryScale_(1),
+    fieldScale_()
 {}
 
 
@@ -86,7 +88,9 @@ Foam::surfaceWriters::rawWriter::rawWriter
     (
         IOstream::ASCII,
         IOstream::compressionEnum("compression", options)
-    )
+    ),
+    geometryScale_(options.getOrDefault<scalar>("scale", 1)),
+    fieldScale_(options.subOrEmptyDict("fieldScale"))
 {}
 
 
@@ -164,7 +168,7 @@ Foam::fileName Foam::surfaceWriters::rawWriter::write()
         // Write faces centres
         for (const face& f : faces)
         {
-            writePoint(os, f.centre(points));
+            writePoint(os, f.centre(points)*geometryScale_);
             os << nl;
         }
 
diff --git a/src/surfMesh/writers/raw/rawSurfaceWriter.H b/src/surfMesh/writers/raw/rawSurfaceWriter.H
index a3a8f128981..0672acdd62c 100644
--- a/src/surfMesh/writers/raw/rawSurfaceWriter.H
+++ b/src/surfMesh/writers/raw/rawSurfaceWriter.H
@@ -34,6 +34,8 @@ Description
     \table
         Property    | Description                           | Required | Default
         compression | Use file compression                  | no  | false
+        scale       | output geometry scaling               | no  | 1
+        fieldScale  | output field scaling (dictionary)     | no  | empty
     \endtable
 
     For example,
@@ -43,6 +45,12 @@ Description
         raw
         {
             compression on;
+
+            scale   1000;     // [m] -> [mm]
+            fieldScale
+            {
+               "p.*"   0.01;  // [Pa] -> [mbar]
+            }
         }
     }
     \endverbatim
@@ -97,6 +105,12 @@ class rawWriter
         //- Output stream option
         IOstreamOption streamOpt_;
 
+        //- Output geometry scaling
+        const scalar geometryScale_;
+
+        //- Output field scaling
+        const dictionary fieldScale_;
+
 
     // Private Member Functions
 
diff --git a/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
index 57df22a775e..c6d1a8175c1 100644
--- a/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
+++ b/src/surfMesh/writers/raw/rawSurfaceWriterImpl.C
@@ -130,9 +130,25 @@ Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate
     outputFile /= fieldName + '_' + outputPath_.name();
     outputFile.ext("raw");
 
+
+    // Output scaling for the variable, but not for integer types.
+    // could also solve with clever templating
+
+    const scalar varScale =
+    (
+        std::is_integral<Type>::value
+      ? scalar(1)
+      : fieldScale_.getOrDefault<scalar>(fieldName, 1)
+    );
+
     if (verbose_)
     {
-        Info<< "Writing field " << fieldName << " to " << outputFile << endl;
+        Info<< "Writing field " << fieldName;
+        if (!equal(varScale, 1))
+        {
+            Info<< " (scaling " << varScale << ')';
+        }
+        Info<< " to " << outputFile << endl;
     }
 
 
@@ -177,8 +193,8 @@ Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate
             // Node values
             forAll(values, elemi)
             {
-                writePoint(os, points[elemi]);
-                writeData(os, values[elemi]);
+                writePoint(os, points[elemi]*geometryScale_);
+                writeData(os, values[elemi]*varScale);
             }
         }
         else
@@ -186,8 +202,8 @@ Foam::fileName Foam::surfaceWriters::rawWriter::writeTemplate
             // Face values
             forAll(values, elemi)
             {
-                writePoint(os, faces[elemi].centre(points));
-                writeData(os,  values[elemi]);
+                writePoint(os, faces[elemi].centre(points)*geometryScale_);
+                writeData(os,  values[elemi]*varScale);
             }
         }
     }
-- 
GitLab