ENH: coordSetWriter - brought across field scaling and offsets from surface writers

Example:

    formatOptions
    {
        <writer>
        {
            // 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
            }
        }
    }
This commit is contained in:
Andrew Heather 2023-11-24 16:01:56 +00:00 committed by Mark Olesen
parent 0ba821a96d
commit 3944c7a628
3 changed files with 152 additions and 1 deletions

View File

@ -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");
}

View File

@ -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<class Type>
tmp<Field<Type>> adjustFieldTemplate
(
const word& fieldName,
const tmp<Field<Type>>& tfield
) const;
//- Repackage field into a UPtrList
template<class Type>
static UPtrList<const Field<Type>>

View File

@ -25,8 +25,110 @@ License
\*---------------------------------------------------------------------------*/
#include "transformField.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::coordSetWriter::adjustFieldTemplate
(
const word& fieldName,
const tmp<Field<Type>>& tfield
) const
{
if (verbose_)
{
Info<< "Writing field " << fieldName;
}
tmp<Field<Type>> tadjusted;
// Output scaling for the variable, but not for integer types
// which are typically ids etc.
if (!std::is_integral<Type>::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<Type>::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<Type>::rank != 0 && pTraits<Type>::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<class Type>
Foam::UPtrList<const Foam::Field<Type>>
Foam::coordSetWriter::repackageFields(const Field<Type>& field)