Commit 2c4b639e authored by Mark Olesen's avatar Mark Olesen
Browse files

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

- support postOperation for volFieldValue as well
parent 18e53c3c
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -109,6 +109,7 @@ const Foam::Enum
Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_
({
{ postOperationType::postOpNone, "none" },
{ postOperationType::postOpMag, "mag" },
{ postOperationType::postOpSqrt, "sqrt" },
});
......@@ -564,6 +565,8 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
os << tab << "Area";
}
// TBD: add in postOperation information?
for (const word& fieldName : fields_)
{
os << tab << operationTypeNames_[operation_]
......@@ -755,6 +758,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
) const
{
// scalar * Area
if (returnReduce(weightField.empty(), andOp<bool>()))
{
// No weight field - revert to unweighted form
......@@ -778,6 +782,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
) const
{
// vector (dot) Area
if (returnReduce(weightField.empty(), andOp<bool>()))
{
// No weight field - revert to unweighted form
......@@ -806,7 +811,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.lookupOrDefault
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
......@@ -839,7 +844,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.lookupOrDefault
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -131,6 +131,13 @@ Usage
absWeightedUniformity | uniformity index using absolute weighting
\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
- The values reported by the areaNormalAverage and areaNormalIntegrate
operations are written as the first component of a field with the same
......@@ -193,7 +200,7 @@ SourceFiles
namespace Foam
{
// Forward declarations
// Forward Declarations
class sampledSurface;
class surfaceWriter;
......@@ -311,7 +318,8 @@ public:
enum postOperationType
{
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
......@@ -526,7 +534,7 @@ protected:
public:
//- Run-time type information
//- Declare type-name, virtual type (with debug switch)
TypeName("surfaceFieldValue");
......@@ -553,7 +561,7 @@ public:
virtual ~surfaceFieldValue() = default;
// Public Member Functions
// Member Functions
//- Return the region type
inline regionTypes regionType() const;
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -407,9 +407,19 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
{
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 - doesn't change the type
// sqrt: component-wise - does not change the type
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
setComponent(result, d)
......@@ -442,6 +452,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
Log << " " << prefix << regionName_ << suffix
<< " of " << fieldName << " = ";
// Operation tagged that it always returns scalar?
const bool alwaysScalar(operation_ & typeScalar);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -70,6 +70,17 @@ Foam::functionObjects::fieldValues::volFieldValue::operationTypeNames_
{ 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 * * * * * * * * * * * //
......@@ -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
{
// 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
(
Ostream& os
......@@ -153,6 +142,8 @@ void Foam::functionObjects::fieldValues::volFieldValue::writeFileHeader
writeCommented(os, "Time");
// TBD: add in postOperation information?
for (const word& fieldName : fields_)
{
os << tab << operationTypeNames_[operation_]
......@@ -209,6 +200,16 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
fieldValue(name, runTime, dict, typeName),
volRegion(fieldValue::mesh_, dict),
operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
postOperationType::postOpNone,
true // Failsafe behaviour
)
),
weightFieldName_("none")
{
read(dict);
......@@ -226,6 +227,16 @@ Foam::functionObjects::fieldValues::volFieldValue::volFieldValue
fieldValue(name, obr, dict, typeName),
volRegion(fieldValue::mesh_, dict),
operation_(operationTypeNames_.get("operation", dict)),
postOperation_
(
postOperationTypeNames_.getOrDefault
(
"postOperation",
dict,
postOperationType::postOpNone,
true // Failsafe behaviour
)
),
weightFieldName_("none")
{
read(dict);
......@@ -240,7 +251,29 @@ bool Foam::functionObjects::fieldValues::volFieldValue::read
)
{
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;
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -71,6 +71,7 @@ Usage
regionType | volRegion type: see below | yes |
name | Name of volRegion if required | no |
operation | Operation to perform | yes |
postOperation | Post-operation to perform | no | none
weightField | Name of field to apply weighting | no |
fields | List of fields to operate on | yes |
\endtable
......@@ -98,6 +99,13 @@ Usage
weightedVolIntegrate | Weighted volume integral
\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
Foam::functionObjects::fieldValues::fieldValue
Foam::functionObjects::volRegion
......@@ -132,16 +140,17 @@ class volFieldValue
public fieldValue,
public volRegion
{
public:
// Public data types
// Public Data Types
//- Bitmask values for operation variants
enum operationVariant
{
typeBase = 0, //!< Base operation
typeScalar = 0x100, //!< Operation returns a scalar
typeWeighted = 0x200, //!< Operation using weighting
typeAbsolute = 0x400, //!< Operation using mag (eg, for weighting)
};
//- Operation type enumeration
......@@ -150,11 +159,11 @@ public:
// Normal operations
opNone = 0, //!< No operation
opMin, //!< Minimum
opMax, //!< Maximum
opSum, //!< Sum
opSumMag, //!< Magnitude of sum
opAverage, //!< Average
opMin, //!< Minimum value
opMax, //!< Maximum value
opSum, //!< Sum of values
opSumMag, //!< Sum of component magnitudes
opAverage, //!< Ensemble average
opVolAverage, //!< Volume average
opVolIntegrate, //!< Volume integral
opCoV, //!< Coefficient of variation
......@@ -172,19 +181,36 @@ public:
//! Weighted volume integral
opWeightedVolIntegrate = (opVolIntegrate | typeWeighted),
// Variants using absolute weighting
};
//- Operation type names
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 data
// Protected Data
//- Operation to apply to values
operationType operation_;
//- Optional post-evaluation operation
postOperationType postOperation_;
//- Weight field name - only used for weighted modes
word weightFieldName_;
......@@ -194,6 +220,9 @@ protected:
//- True if the operation needs the cell-volume
bool usesVol() const;
//- True if the operation variant uses mag
bool usesMag() const;
//- True if the operation variant uses a weight-field
bool usesWeight() const;
......@@ -201,9 +230,6 @@ protected:
// Checks for availability on any processor.
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
template<class Type>
bool validField(const word& fieldName) const;
......@@ -251,7 +277,7 @@ protected:
public:
//- Run-time type information
//- Declare type-name, virtual type (with debug switch)
TypeName("volFieldValue");
......@@ -278,7 +304,7 @@ public:
virtual ~volFieldValue() = default;
// Public Member Functions
// Member Functions
//- Read from dictionary
virtual bool read(const dictionary& dict);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -237,22 +237,83 @@ bool Foam::functionObjects::fieldValues::volFieldValue::writeValues
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
const word& opName = operationTypeNames_[operation_];
word outName = fieldName;
word prefix, suffix;
{
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)
{
outName = this->volRegion::regionName_ + ',' + outName;
regionPrefix = this->volRegion::regionName_ + ',';
}
word resultName = opName + '(' + outName + ')';
file()<< tab << result;
word resultName = prefix + regionPrefix + fieldName + suffix;
Log << " " << prefix << this->volRegion::regionName_ << suffix
<< " of " << fieldName << " = ";
// Operation tagged that it always returns scalar?
const bool alwaysScalar(operation_ & typeScalar);
if (alwaysScalar)
{
const scalar sresult = component(result, 0);
file()<< tab << sresult;
Log << " " << opName
<< '(' << this->volRegion::regionName_ << ") of " << fieldName
<< " = " << result << endl;
Log << sresult << endl;
this->setResult(resultName, result);
this->setResult(resultName, sresult);
}
else
{
file()<< tab << result;
Log << result << endl;
this->setResult(resultName, result);
}
}
}
......
......@@ -96,6 +96,7 @@ functions
log true;
operation volIntegrate;
// postOperation mag;
fields
(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment