From 3944c7a628e3e55668d44f7071ea9f60bc26b3f1 Mon Sep 17 00:00:00 2001 From: Andrew Heather <> Date: Fri, 24 Nov 2023 16:01:56 +0000 Subject: [PATCH 1/3] ENH: coordSetWriter - brought across field scaling and offsets from surface writers Example: formatOptions { { // Apply offsets to field values fieldLevel { T 273.15; // Convert from K to C by subtracting 273.15 } // Note: scale applied after application of field level fieldScale { p 0.001; // Convert pressure from Pa to kPa by scaling by 0.001 } } } --- .../coordSet/writers/common/coordSetWriter.C | 28 ++++- .../coordSet/writers/common/coordSetWriter.H | 23 ++++ .../writers/common/coordSetWriterTemplates.C | 102 ++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) diff --git a/src/meshTools/coordSet/writers/common/coordSetWriter.C b/src/meshTools/coordSet/writers/common/coordSetWriter.C index d3e7c5cae4..9ea4cd5775 100644 --- a/src/meshTools/coordSet/writers/common/coordSetWriter.C +++ b/src/meshTools/coordSet/writers/common/coordSetWriter.C @@ -117,7 +117,12 @@ Foam::coordSetWriter::coordSetWriter() verbose_(false), nFields_(0), currTime_(), - outputPath_() + outputPath_(), + geometryScale_(1), + geometryCentre_(Zero), + geometryTransform_(), + fieldLevel_(), + fieldScale_() {} @@ -126,6 +131,27 @@ Foam::coordSetWriter::coordSetWriter(const dictionary& options) coordSetWriter() { options.readIfPresent("verbose", verbose_); + + geometryScale_ = 1; + geometryCentre_ = Zero; + geometryTransform_.clear(); + + options.readIfPresent("scale", geometryScale_); + + // Optional cartesian coordinate system transform + const auto* dictptr = options.findDict("transform", keyType::LITERAL); + + if (dictptr) + { + dictptr->readIfPresent("rotationCentre", geometryCentre_); + + // 'origin' is optional within sub-dictionary + geometryTransform_ = + coordSystem::cartesian(*dictptr, IOobjectOption::LAZY_READ); + } + + fieldLevel_ = options.subOrEmptyDict("fieldLevel"); + fieldScale_ = options.subOrEmptyDict("fieldScale"); } diff --git a/src/meshTools/coordSet/writers/common/coordSetWriter.H b/src/meshTools/coordSet/writers/common/coordSetWriter.H index f98cf887b1..8069fadb7f 100644 --- a/src/meshTools/coordSet/writers/common/coordSetWriter.H +++ b/src/meshTools/coordSet/writers/common/coordSetWriter.H @@ -66,6 +66,7 @@ SourceFiles #include "UPtrList.H" #include "instant.H" #include "InfoProxy.H" +#include "cartesianCS.H" #include "runTimeSelectionTables.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -125,6 +126,21 @@ protected: //- The full output directory and file (coords) name fileName outputPath_; + //- Output geometry scaling after rotate/translate + scalar geometryScale_; + + //- The centre of rotation (untranslate, translate) + point geometryCentre_; + + //- Local coordinate system transformation + coordSystem::cartesian geometryTransform_; + + //- Field level to remove (on output) + dictionary fieldLevel_; + + //- Field scaling (on output) + dictionary fieldScale_; + // Buffering @@ -212,6 +228,13 @@ protected: // Helpers + template + tmp> adjustFieldTemplate + ( + const word& fieldName, + const tmp>& tfield + ) const; + //- Repackage field into a UPtrList template static UPtrList> diff --git a/src/meshTools/coordSet/writers/common/coordSetWriterTemplates.C b/src/meshTools/coordSet/writers/common/coordSetWriterTemplates.C index 84c5b0c336..28e8f08de5 100644 --- a/src/meshTools/coordSet/writers/common/coordSetWriterTemplates.C +++ b/src/meshTools/coordSet/writers/common/coordSetWriterTemplates.C @@ -25,8 +25,110 @@ License \*---------------------------------------------------------------------------*/ +#include "transformField.H" + // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // +template +Foam::tmp> Foam::coordSetWriter::adjustFieldTemplate +( + const word& fieldName, + const tmp>& tfield +) const +{ + if (verbose_) + { + Info<< "Writing field " << fieldName; + } + + tmp> tadjusted; + + // Output scaling for the variable, but not for integer types + // which are typically ids etc. + if (!std::is_integral::value) + { + scalar value; + + // Remove *uniform* reference level + if + ( + fieldLevel_.readIfPresent(fieldName, value, keyType::REGEX) + && !equal(value, 0) + ) + { + // Could also detect brackets (...) and read accordingly + // or automatically scale by 1/sqrt(nComponents) instead ... + + Type refLevel; + for (direction cmpt = 0; cmpt < pTraits::nComponents; ++cmpt) + { + setComponent(refLevel, cmpt) = value; + } + + if (verbose_) + { + Info<< " [level " << refLevel << ']'; + } + + if (!tadjusted) + { + // Steal or clone + tadjusted.reset(tfield.ptr()); + } + + // Remove offset level + tadjusted.ref() -= refLevel; + } + + // Apply scaling + if + ( + fieldScale_.readIfPresent(fieldName, value, keyType::REGEX) + && !equal(value, 1) + ) + { + if (verbose_) + { + Info<< " [scaling " << value << ']'; + } + + if (!tadjusted) + { + // Steal or clone + tadjusted.reset(tfield.ptr()); + } + + // Apply scaling + tadjusted.ref() *= value; + } + + // Rotate fields (vector and non-spherical tensors) + if + ( + (pTraits::rank != 0 && pTraits::nComponents > 1) + && geometryTransform_.valid() + && !geometryTransform_.R().is_identity() + ) + { + if (!tadjusted) + { + // Steal or clone + tadjusted.reset(tfield.ptr()); + } + + Foam::transform + ( + tadjusted.ref(), + geometryTransform_.R(), + tadjusted() + ); + } + } + + return (tadjusted ? tadjusted : tfield); +} + + template Foam::UPtrList> Foam::coordSetWriter::repackageFields(const Field& field) From d3b3a5a41e9b59b0b5d2c7c8276106ff1fadf0ef Mon Sep 17 00:00:00 2001 From: Andrew Heather <> Date: Fri, 24 Nov 2023 16:02:40 +0000 Subject: [PATCH 2/3] ENH: Added new abaqus coordSet writer Write coordSet(s) as Abaqus point fields Example usage T { type sets; setFormat abaqus; fields (T); sets { ... } } \endverbatim Optional format options \verbatim formatOptions { abaqus { format ascii; // Optional entries // Custom header: $ entries are substituions header ( "** OpenFOAM abaqus output" "** Project $FOAM_CASE" "** File $FILE_NAME" "** $FIELD_NAME Time t=$TIME" ); // Write geometry in addition to field data writeGeometry yes; // Null value when sample value is not found // Default is scalar::min nullValue 0; // Insert additional time sub-directory in the output path // - yes : postProcessing//