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