ENH: 'mag' postOperation for surfaceFieldValue (#1622)

- support postOperation for volFieldValue as well
This commit is contained in:
Mark Olesen
2020-03-11 10:51:14 +01:00
parent 18e53c3c06
commit 2c4b639e1f
7 changed files with 210 additions and 65 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -109,6 +109,7 @@ const Foam::Enum
Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_ Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_
({ ({
{ postOperationType::postOpNone, "none" }, { postOperationType::postOpNone, "none" },
{ postOperationType::postOpMag, "mag" },
{ postOperationType::postOpSqrt, "sqrt" }, { postOperationType::postOpSqrt, "sqrt" },
}); });
@ -564,6 +565,8 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
os << tab << "Area"; os << tab << "Area";
} }
// TBD: add in postOperation information?
for (const word& fieldName : fields_) for (const word& fieldName : fields_)
{ {
os << tab << operationTypeNames_[operation_] os << tab << operationTypeNames_[operation_]
@ -755,6 +758,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
) const ) const
{ {
// scalar * Area // scalar * Area
if (returnReduce(weightField.empty(), andOp<bool>())) if (returnReduce(weightField.empty(), andOp<bool>()))
{ {
// No weight field - revert to unweighted form // No weight field - revert to unweighted form
@ -778,6 +782,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
) const ) const
{ {
// vector (dot) Area // vector (dot) Area
if (returnReduce(weightField.empty(), andOp<bool>())) if (returnReduce(weightField.empty(), andOp<bool>()))
{ {
// No weight field - revert to unweighted form // No weight field - revert to unweighted form
@ -806,7 +811,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
operation_(operationTypeNames_.get("operation", dict)), operation_(operationTypeNames_.get("operation", dict)),
postOperation_ postOperation_
( (
postOperationTypeNames_.lookupOrDefault postOperationTypeNames_.getOrDefault
( (
"postOperation", "postOperation",
dict, dict,
@ -839,7 +844,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
operation_(operationTypeNames_.get("operation", dict)), operation_(operationTypeNames_.get("operation", dict)),
postOperation_ postOperation_
( (
postOperationTypeNames_.lookupOrDefault postOperationTypeNames_.getOrDefault
( (
"postOperation", "postOperation",
dict, dict,

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd. Copyright (C) 2015-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -131,6 +131,13 @@ Usage
absWeightedUniformity | uniformity index using absolute weighting absWeightedUniformity | uniformity index using absolute weighting
\endplaintable \endplaintable
The \c postOperation is one of:
\plaintable
none | No additional operation after calculation
mag | Component-wise \c mag() after normal operation
sqrt | Component-wise \c sqrt() after normal operation
\endplaintable
Note Note
- The values reported by the areaNormalAverage and areaNormalIntegrate - The values reported by the areaNormalAverage and areaNormalIntegrate
operations are written as the first component of a field with the same operations are written as the first component of a field with the same
@ -193,7 +200,7 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declarations // Forward Declarations
class sampledSurface; class sampledSurface;
class surfaceWriter; class surfaceWriter;
@ -311,7 +318,8 @@ public:
enum postOperationType enum postOperationType
{ {
postOpNone, //!< No additional operation after calculation postOpNone, //!< No additional operation after calculation
postOpSqrt //!< Perform sqrt after normal operation postOpMag, //!< Component-wise mag after normal operation
postOpSqrt //!< Component-wise sqrt after normal operation
}; };
//- Operation type names //- Operation type names
@ -526,7 +534,7 @@ protected:
public: public:
//- Run-time type information //- Declare type-name, virtual type (with debug switch)
TypeName("surfaceFieldValue"); TypeName("surfaceFieldValue");
@ -553,7 +561,7 @@ public:
virtual ~surfaceFieldValue() = default; virtual ~surfaceFieldValue() = default;
// Public Member Functions // Member Functions
//- Return the region type //- Return the region type
inline regionTypes regionType() const; inline regionTypes regionType() const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd. Copyright (C) 2015-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -407,9 +407,19 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
{ {
break; break;
} }
case postOpMag:
{
// mag: component-wise - does not change the type
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
setComponent(result, d)
= mag(component(result, d));
}
break;
}
case postOpSqrt: case postOpSqrt:
{ {
// sqrt: component-wise - doesn't change the type // sqrt: component-wise - does not change the type
for (direction d=0; d < pTraits<Type>::nComponents; ++d) for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{ {
setComponent(result, d) setComponent(result, d)
@ -442,6 +452,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
Log << " " << prefix << regionName_ << suffix Log << " " << prefix << regionName_ << suffix
<< " of " << fieldName << " = "; << " of " << fieldName << " = ";
// Operation tagged that it always returns scalar? // Operation tagged that it always returns scalar?
const bool alwaysScalar(operation_ & typeScalar); const bool alwaysScalar(operation_ & typeScalar);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd. Copyright (C) 2017-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -70,6 +70,17 @@ Foam::functionObjects::fieldValues::volFieldValue::operationTypeNames_
{ operationType::opWeightedVolIntegrate, "weightedVolIntegrate" }, { operationType::opWeightedVolIntegrate, "weightedVolIntegrate" },
}); });
const Foam::Enum
<
Foam::functionObjects::fieldValues::volFieldValue::postOperationType
>
Foam::functionObjects::fieldValues::volFieldValue::postOperationTypeNames_
({
{ postOperationType::postOpNone, "none" },
{ postOperationType::postOpMag, "mag" },
{ postOperationType::postOpSqrt, "sqrt" },
});
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
@ -91,6 +102,13 @@ bool Foam::functionObjects::fieldValues::volFieldValue::usesVol() const
} }
bool Foam::functionObjects::fieldValues::volFieldValue::usesMag() const
{
// Operation specifically tagged to use mag
return (operation_ & typeAbsolute);
}
bool Foam::functionObjects::fieldValues::volFieldValue::usesWeight() const bool Foam::functionObjects::fieldValues::volFieldValue::usesWeight() const
{ {
// Operation specifically tagged to require a weight field // Operation specifically tagged to require a weight field
@ -111,35 +129,6 @@ bool Foam::functionObjects::fieldValues::volFieldValue::canWeight
} }
void Foam::functionObjects::fieldValues::volFieldValue::initialise
(
const dictionary& dict
)
{
weightFieldName_ = "none";
if (usesWeight())
{
if (dict.readIfPresent("weightField", weightFieldName_))
{
Info<< " weight field = " << weightFieldName_;
}
else
{
// Suggest possible alternative unweighted operation?
FatalIOErrorInFunction(dict)
<< "The '" << operationTypeNames_[operation_]
<< "' operation is missing a weightField." << nl
<< "Either provide the weightField, "
<< "use weightField 'none' to suppress weighting," << nl
<< "or use a different operation."
<< exit(FatalIOError);
}
}
Info<< nl << endl;
}
void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
( (
Ostream& os Ostream& os
@ -153,6 +142,8 @@ void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
writeCommented(os, "Time"); writeCommented(os, "Time");
// TBD: add in postOperation information?
for (const word& fieldName : fields_) for (const word& fieldName : fields_)
{ {
os << tab << operationTypeNames_[operation_] os << tab << operationTypeNames_[operation_]
@ -209,6 +200,16 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
fieldValue(name, runTime, dict, typeName), fieldValue(name, runTime, dict, typeName),
volRegion(fieldValue::mesh_, dict), volRegion(fieldValue::mesh_, dict),
operation_(operationTypeNames_.get("operation", dict)), operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
postOperationType::postOpNone,
true // Failsafe behaviour
)
),
weightFieldName_("none") weightFieldName_("none")
{ {
read(dict); read(dict);
@ -226,6 +227,16 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
fieldValue(name, obr, dict, typeName), fieldValue(name, obr, dict, typeName),
volRegion(fieldValue::mesh_, dict), volRegion(fieldValue::mesh_, dict),
operation_(operationTypeNames_.get("operation", dict)), operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
postOperationType::postOpNone,
true // Failsafe behaviour
)
),
weightFieldName_("none") weightFieldName_("none")
{ {
read(dict); read(dict);
@ -240,7 +251,29 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
) )
{ {
fieldValue::read(dict); fieldValue::read(dict);
initialise(dict);
weightFieldName_ = "none";
if (usesWeight())
{
if (dict.readIfPresent("weightField", weightFieldName_))
{
Info<< " weight field = " << weightFieldName_;
}
else
{
// Suggest possible alternative unweighted operation?
FatalIOErrorInFunction(dict)
<< "The '" << operationTypeNames_[operation_]
<< "' operation is missing a weightField." << nl
<< "Either provide the weightField, "
<< "use weightField 'none' to suppress weighting," << nl
<< "or use a different operation."
<< exit(FatalIOError);
}
}
Info<< nl << endl;
return true; return true;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd. Copyright (C) 2016-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -71,6 +71,7 @@ Usage
regionType | volRegion type: see below | yes | regionType | volRegion type: see below | yes |
name | Name of volRegion if required | no | name | Name of volRegion if required | no |
operation | Operation to perform | yes | operation | Operation to perform | yes |
postOperation | Post-operation to perform | no | none
weightField | Name of field to apply weighting | no | weightField | Name of field to apply weighting | no |
fields | List of fields to operate on | yes | fields | List of fields to operate on | yes |
\endtable \endtable
@ -98,6 +99,13 @@ Usage
weightedVolIntegrate | Weighted volume integral weightedVolIntegrate | Weighted volume integral
\endplaintable \endplaintable
The \c postOperation is one of:
\plaintable
none | No additional operation after calculation
mag | Component-wise \c mag() after normal operation
sqrt | Component-wise \c sqrt() after normal operation
\endplaintable
See also See also
Foam::functionObjects::fieldValues::fieldValue Foam::functionObjects::fieldValues::fieldValue
Foam::functionObjects::volRegion Foam::functionObjects::volRegion
@ -132,16 +140,17 @@ class volFieldValue
public fieldValue, public fieldValue,
public volRegion public volRegion
{ {
public: public:
// Public data types // Public Data Types
//- Bitmask values for operation variants //- Bitmask values for operation variants
enum operationVariant enum operationVariant
{ {
typeBase = 0, //!< Base operation typeBase = 0, //!< Base operation
typeScalar = 0x100, //!< Operation returns a scalar
typeWeighted = 0x200, //!< Operation using weighting typeWeighted = 0x200, //!< Operation using weighting
typeAbsolute = 0x400, //!< Operation using mag (eg, for weighting)
}; };
//- Operation type enumeration //- Operation type enumeration
@ -150,11 +159,11 @@ public:
// Normal operations // Normal operations
opNone = 0, //!< No operation opNone = 0, //!< No operation
opMin, //!< Minimum opMin, //!< Minimum value
opMax, //!< Maximum opMax, //!< Maximum value
opSum, //!< Sum opSum, //!< Sum of values
opSumMag, //!< Magnitude of sum opSumMag, //!< Sum of component magnitudes
opAverage, //!< Average opAverage, //!< Ensemble average
opVolAverage, //!< Volume average opVolAverage, //!< Volume average
opVolIntegrate, //!< Volume integral opVolIntegrate, //!< Volume integral
opCoV, //!< Coefficient of variation opCoV, //!< Coefficient of variation
@ -172,19 +181,36 @@ public:
//! Weighted volume integral //! Weighted volume integral
opWeightedVolIntegrate = (opVolIntegrate | typeWeighted), opWeightedVolIntegrate = (opVolIntegrate | typeWeighted),
// Variants using absolute weighting
}; };
//- Operation type names //- Operation type names
static const Enum<operationType> operationTypeNames_; static const Enum<operationType> operationTypeNames_;
//- Post-operation type enumeration
enum postOperationType
{
postOpNone, //!< No additional operation after calculation
postOpMag, //!< Component-wise mag after normal operation
postOpSqrt //!< Component-wise sqrt after normal operation
};
//- Operation type names
static const Enum<postOperationType> postOperationTypeNames_;
protected: protected:
// Protected data // Protected Data
//- Operation to apply to values //- Operation to apply to values
operationType operation_; operationType operation_;
//- Optional post-evaluation operation
postOperationType postOperation_;
//- Weight field name - only used for weighted modes //- Weight field name - only used for weighted modes
word weightFieldName_; word weightFieldName_;
@ -194,6 +220,9 @@ protected:
//- True if the operation needs the cell-volume //- True if the operation needs the cell-volume
bool usesVol() const; bool usesVol() const;
//- True if the operation variant uses mag
bool usesMag() const;
//- True if the operation variant uses a weight-field //- True if the operation variant uses a weight-field
bool usesWeight() const; bool usesWeight() const;
@ -201,9 +230,6 @@ protected:
// Checks for availability on any processor. // Checks for availability on any processor.
inline bool canWeight(const scalarField& weightField) const; inline bool canWeight(const scalarField& weightField) const;
//- Initialise, e.g. cell addressing
void initialise(const dictionary& dict);
//- Return true if the field name is valid //- Return true if the field name is valid
template<class Type> template<class Type>
bool validField(const word& fieldName) const; bool validField(const word& fieldName) const;
@ -251,7 +277,7 @@ protected:
public: public:
//- Run-time type information //- Declare type-name, virtual type (with debug switch)
TypeName("volFieldValue"); TypeName("volFieldValue");
@ -278,7 +304,7 @@ public:
virtual ~volFieldValue() = default; virtual ~volFieldValue() = default;
// Public Member Functions // Member Functions
//- Read from dictionary //- Read from dictionary
virtual bool read(const dictionary& dict); virtual bool read(const dictionary& dict);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd. Copyright (C) 2015-2020 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -237,22 +237,83 @@ bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
Type result = processValues(values, V, weightField); Type result = processValues(values, V, weightField);
switch (postOperation_)
{
case postOpNone:
{
break;
}
case postOpMag:
{
// mag: component-wise - does not change the type
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
setComponent(result, d)
= mag(component(result, d));
}
break;
}
case postOpSqrt:
{
// sqrt: component-wise - does not change the type
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
setComponent(result, d)
= sqrt(mag(component(result, d)));
}
break;
}
}
// Write state/results information // Write state/results information
const word& opName = operationTypeNames_[operation_]; word prefix, suffix;
word outName = fieldName; {
if (postOperation_ != postOpNone)
{
// Adjust result name to include post-operation
prefix += postOperationTypeNames_[postOperation_];
prefix += '(';
suffix += ')';
}
prefix += operationTypeNames_[operation_];
prefix += '(';
suffix += ')';
}
word regionPrefix;
if (this->volRegion::regionName_ != polyMesh::defaultRegion) if (this->volRegion::regionName_ != polyMesh::defaultRegion)
{ {
outName = this->volRegion::regionName_ + ',' + outName; regionPrefix = this->volRegion::regionName_ + ',';
} }
word resultName = opName + '(' + outName + ')';
file()<< tab << result; word resultName = prefix + regionPrefix + fieldName + suffix;
Log << " " << opName Log << " " << prefix << this->volRegion::regionName_ << suffix
<< '(' << this->volRegion::regionName_ << ") of " << fieldName << " of " << fieldName << " = ";
<< " = " << result << endl;
this->setResult(resultName, result);
// Operation tagged that it always returns scalar?
const bool alwaysScalar(operation_ & typeScalar);
if (alwaysScalar)
{
const scalar sresult = component(result, 0);
file()<< tab << sresult;
Log << sresult << endl;
this->setResult(resultName, sresult);
}
else
{
file()<< tab << result;
Log << result << endl;
this->setResult(resultName, result);
}
} }
} }

View File

@ -96,6 +96,7 @@ functions
log true; log true;
operation volIntegrate; operation volIntegrate;
// postOperation mag;
fields fields
( (