ENH: multiFieldValue - extended to operate on general function objects

- Previously, the multiFieldValue function object was limited to operate on
  lists of fieldValue function objects.
- Any function objects that generate results can now be used, e.g.

pressureAverage
{
    type    multiFieldValue;
    libs    (fieldFunctionObjects);

    operation   average;

    functions
    {
        inlet
        {
            type            surfaceFieldValue;
            operation       areaAverage;
            regionType      patch;
            name            inlet;
            fields          (p);

            writeFields     no;
            writeToFile     no;
            log             no;
            resultFields    (areaAverage(inlet,p));
        }
        outlet
        {
            type            surfaceFieldValue;
            operation       areaAverage;
            regionType      patch;
            name            outlet;
            fields          (p);

            writeFields     no;
            writeToFile     no;
            log             no;
        }
        average
        {
            type            valueAverage;
            functionObject  testSample1;
            fields          (average(p));

            writeToFile     no;
            log             no;
        }
    }
}

TUT: cavity: add an example for the multiFieldValue function object
This commit is contained in:
Andrew Heather
2022-05-23 20:25:05 +01:00
committed by Sergio Ferraris
parent 34ef9ae342
commit 8d90b16518
8 changed files with 326 additions and 137 deletions

View File

@ -20,7 +20,6 @@ fieldValues/fieldValue/fieldValue.C
fieldValues/fieldValue/fieldValueNew.C
fieldValues/volFieldValue/volFieldValue.C
fieldValues/surfaceFieldValue/surfaceFieldValue.C
fieldValues/multiFieldValue/multiFieldValue.C
heatTransferCoeff/heatTransferCoeff.C
heatTransferCoeff/heatTransferCoeffModels/heatTransferCoeffModel/heatTransferCoeffModel.C
@ -31,6 +30,8 @@ heatTransferCoeff/heatTransferCoeffModels/ReynoldsAnalogy/ReynoldsAnalogy.C
limitFields/limitFields.C
multiFieldValue/multiFieldValue.C
nearWallFields/nearWallFields.C
nearWallFields/findCellParticle.C
nearWallFields/findCellParticleCloud.C

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -63,48 +63,36 @@ Foam::functionObjects::fieldValues::multiFieldValue::operationTypeNames_
void Foam::functionObjects::fieldValues::multiFieldValue::writeFileHeader
(
const wordList& foNames,
const List<wordList>& entries,
const List<wordList>& types,
Ostream& os
) const
{
const wordList& fields0 = functions_[0].fields();
const word groupPrefix("Group");
DynamicList<word> commonFields(fields0.size());
forAll(entries, i)
{
writeCommented(os, groupPrefix + Foam::name(i));
os << nl;
for (const word& fieldName : fields0)
forAll(entries[i], functioni)
{
bool common = true;
for (label functioni=1; functioni < functions_.size(); ++functioni)
{
if (!functions_[functioni].fields().found(fieldName))
{
common = false;
break;
}
}
if (common)
{
commonFields.append(fieldName);
}
}
forAll(functions_, functioni)
{
writeHeaderValue
writeCommented
(
os,
"Source" + Foam::name(functioni),
functions_[functioni].name()
" - " + foNames[functioni] + ":" + entries[i][functioni]
);
os << nl;
}
}
writeHeaderValue(os, "Operation", operationTypeNames_[operation_]);
writeCommented(os, "Time");
for (const word& fieldName : commonFields)
forAll(entries, entryi)
{
os << tab << fieldName;
writeTabbed(os, groupPrefix + Foam::name(entryi));
}
os << endl;
@ -125,10 +113,7 @@ Foam::functionObjects::fieldValues::multiFieldValue::multiFieldValue
operation_(opSubtract),
functions_()
{
if (read(dict))
{
writeFileHeader(file());
}
read(dict);
}
@ -139,8 +124,13 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::read
const dictionary& dict
)
{
if (stateFunctionObject::read(dict) && writeFile::read(dict))
if (!stateFunctionObject::read(dict) || !writeFile::read(dict))
{
return false;
}
operation_ = operationTypeNames_.get("operation", dict);
const dictionary& functionsDict = dict.subDict("functions");
functions_.resize(functionsDict.size());
@ -152,6 +142,8 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::read
return false;
}
resultFields_.resize(functions_.size());
label functioni = 0;
for (const entry& dEntry : functionsDict)
{
@ -167,26 +159,40 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::read
functions_.set
(
functioni,
fieldValue::New
functionObject::New
(
IOobject::scopedName(name(), localDict.dictName()),
time(),
localDict,
false
)
localDict
).ptr()
);
// Deactivate logging for child function objects
//functions_[functioni].log = false;
// Get result field names; not specified implies all
resultFields_[functioni] =
localDict.getOrDefault<wordList>("resultFields", wordList());
Info<< type() << ' ' << name() << ':' << nl;
if (resultFields_[functioni].size())
{
Info<< " " << functions_[functioni].name()
<< " " << resultFields_[functioni];
}
else
{
Info<< " " << functions_[functioni].name()
<< " - using all available entries";
}
Info<< nl << endl;
++functioni;
}
operation_ = operationTypeNames_.get("operation", dict);
return true;
}
return false;
}
bool Foam::functionObjects::fieldValues::multiFieldValue::write()
{
@ -201,19 +207,25 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::write()
wordList entries0;
label nEntries = -1;
wordList names(nFunction);
wordList foNames(nFunction);
List<wordList> entries;
List<wordList> types;
forAll(functions_, functioni)
{
auto& f = functions_[functioni];
names[functioni] = f.name();
foNames[functioni] = f.name();
// Note: results are not available until the call to write()
// Note: replicating functionObjectList execute() and write()
// - results may be written on either
f.execute();
f.write();
const wordList e(objectResultEntries(f.name()));
wordList e = resultFields_[functioni];
if (e.empty())
{
e = objectResultEntries(f.name());
}
if (functioni == 0)
{
@ -237,54 +249,72 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::write()
<< "Inconsistent number of result entries" << nl
<< " " << f0Name << " entries:" << entries0 << nl
<< " " << f.name() << " entries:" << e
<< abort(FatalError);
<< exit(FatalError);
}
forAll(e, entryi)
{
entries[entryi][functioni] = e[entryi];
types[entryi][functioni] = objectResultType(f.name(), e[entryi]);
if (types[entryi][functioni] == word::null)
{
FatalErrorInFunction
<< "Unable to find function object result" << nl
<< " function object : " << f.name() << nl
<< " result name : " << e[entryi] << nl
<< " available results : "
<< objectResultEntries(f.name())
<< exit(FatalError);
}
}
}
if (!writtenHeader_)
{
writeFileHeader(foNames, entries, types, file());
writtenHeader_ = true;
}
writeCurrentTime(file());
forAll(entries, entryi)
forAll(entries, i)
{
const wordList& entriesi = entries[entryi];
const word& t0 = types[entryi][0];
const wordList& typesi = types[entryi];
forAll(typesi, functioni)
{
const word& t = typesi[functioni];
const wordList& entryi = entries[i];
const word& expectedType = types[i][0];
const wordList& foTypes = types[i];
if (t != t0)
forAll(foTypes, functioni)
{
const word& foType = foTypes[functioni];
if (foType != expectedType)
{
FatalErrorInFunction
<< "Inconsistent function result types" << nl
<< " " << functions_[0].name()
<< " result type:" << t0 << nl
<< " result type:" << expectedType << nl
<< " " << functions_[functioni].name()
<< " result type:" << typesi[functioni]
<< abort(FatalError);
<< " result type:" << foType
<< exit(FatalError);
}
}
const bool ok
(
applyOperation<scalar>(t0, names, entriesi)
|| applyOperation<vector>(t0, names, entriesi)
|| applyOperation<sphericalTensor>(t0, names, entriesi)
|| applyOperation<symmTensor>(t0, names, entriesi)
|| applyOperation<tensor>(t0, names, entriesi)
applyOperation<scalar>(expectedType, foNames, entryi)
|| applyOperation<vector>(expectedType, foNames, entryi)
|| applyOperation<sphericalTensor>(expectedType, foNames, entryi)
|| applyOperation<symmTensor>(expectedType, foNames, entryi)
|| applyOperation<tensor>(expectedType, foNames, entryi)
);
if (!ok)
{
Log << "Operation not applied between functions:" << nl
<< flatOutput(names, FlatOutput::BareComma{}) << nl
<< flatOutput(foNames, FlatOutput::BareComma{}) << nl
<< "with result names:" << nl
<< flatOutput(entriesi, FlatOutput::BareComma{})
<< flatOutput(entryi, FlatOutput::BareComma{})
<< endl;
}
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
Copyright (C) 2021-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,10 +30,9 @@ Group
grpFieldFunctionObjects
Description
Computes a selected operation between multiple \c fieldValue function
objects.
Computes a selected operation between multiple function objects.
The operation is applied to all results of each \c fieldValue object.
The operation is applied to all results of each object.
Note
Each object must generate the same number and type of results.
@ -43,11 +42,9 @@ Usage
\verbatim
multiFieldValue1
{
// Mandatory entries (unmodifiable)
// Mandatory entries
type multiFieldValue;
libs (fieldFunctionObjects);
// Mandatory entries (runtime modifiable)
operation average;
// List of fieldValue function objects as dictionaries
@ -56,10 +53,14 @@ Usage
region1
{
...
// Optional
resultFields (field1 field2);
}
region2
{
...
// Optional
resultFields (field1 field2);
}
...
@ -67,41 +68,41 @@ Usage
regionN
{
...
// Optional
resultFields (field1 field2);
}
}
// Optional (inherited) entries
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Req'd | Dflt
Property | Description | Type | Reqd | Deflt
type | Type name: multiFieldValue | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | -
operation | Operation type to apply to values | word | yes | -
functions | List of fieldValue function objects | dict | yes | -
functions | List of function objects | dict | yes | -
\endtable
Options for the \c operation entry:
\plaintable
add | add
subtract | subtract
min | minimum
max | maximum
average | average
sum | Sum of values
add | Add values (same as sum)
subtract | Subtract values from first entry
min | Minimum value
max | Maximum value
average | Average value
\endplaintable
The \c resultFields entry can be used to set the name of the function object
result fields to process. If omitted, all available values are employed.
The inherited entries are elaborated in:
- \link fieldValue.H \endlink
Usage by the \c postProcess utility is not available.
See also
- Foam::functionObject
- Foam::functionObjects::fieldValue
- ExtendedCodeGuide::functionObjects::field::multiFieldValue
- \link stateFunctionObject.H \endlink
- \link writeFile.H \endlink
SourceFiles
multiFieldValue.C
@ -114,7 +115,6 @@ SourceFiles
#include "stateFunctionObject.H"
#include "writeFile.H"
#include "fieldValue.H"
#include "Enum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -161,8 +161,11 @@ private:
//- Operation to apply to values
operationType operation_;
//- List of fieldValue function objects
PtrList<fieldValue> functions_;
//- List of function objects
PtrList<functionObject> functions_;
//- List of result fields per function object
List<wordList> resultFields_;
// Private Member Functions
@ -183,7 +186,13 @@ protected:
// Protected Member Functions
//- Output file header information
virtual void writeFileHeader(Ostream& os) const;
virtual void writeFileHeader
(
const wordList& foNames,
const List<wordList>& entries,
const List<wordList>& types,
Ostream& os
) const;
public:

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -34,7 +34,7 @@ template<class Type>
bool Foam::functionObjects::fieldValues::multiFieldValue::applyOperation
(
const word& resultType,
const wordList& names,
const wordList& foNames,
const wordList& entryNames
)
{
@ -45,10 +45,10 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::applyOperation
Type result = Zero;
Field<Type> values(names.size());
Field<Type> values(foNames.size());
forAll(values, i)
{
values[i] = this->getObjectResult<Type>(names[i], entryNames[i]);
values[i] = this->getObjectResult<Type>(foNames[i], entryNames[i]);
}
const word& opName = operationTypeNames_[operation_];

View File

@ -5,4 +5,6 @@ cd "${0%/*}" || exit # Run from this directory
cleanCase0
rm -rf procs.old
#------------------------------------------------------------------------------

View File

@ -13,4 +13,21 @@ runParallel topoSet
runParallel $(getApplication)
runApplication reconstructPar
latestTime=$(foamListTimes -latestTime)
mv -f "$latestTime" "$latestTime".bak
mkdir procs.old
mv -f processor* procs.old
runParallel -s "decompose" redistributePar -decompose -time 9.5
runParallel -s 2 $(getApplication)
runParallel -s "reconstruct" redistributePar -reconstruct -latestTime
#------------------------------------------------------------------------------

View File

@ -0,0 +1,129 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2112 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
sampleEpsilon1
{
type sets;
libs (sampling);
interpolationScheme cellPointFace;
setFormat raw;
fields ( epsilon );
sets
(
cloud
{
type cloud;
axis xyz;
points
(
(0.0025 0.05 0.005)
);
}
);
}
multiFieldValue_add
{
// Mandatory entries
type multiFieldValue;
libs (fieldFunctionObjects);
operation add;
functions
{
movingWallEpsilon
{
type surfaceFieldValue;
operation areaAverage;
regionType patch;
name movingWall;
fields (epsilon);
writeFields no;
writeToFile no;
log no;
resultFields (areaAverage(movingWall,epsilon));
}
fixedWallsEpsilon
{
type surfaceFieldValue;
operation areaAverage;
regionType patch;
name fixedWalls;
fields (epsilon);
writeFields no;
writeToFile no;
log yes;
}
averageEpsilon
{
type valueAverage;
functionObject sampleEpsilon1;
fields (average(epsilon));
writeToFile no;
log no;
}
}
// Inherited entries
writePrecision 10;
writeToFile true;
useUserTime true;
region region0;
enabled true;
log true;
timeStart 0;
timeEnd 1000;
executeControl timeStep;
executeInterval 1;
writeControl writeTime;
writeInterval -1;
}
multiFieldValue_sum
{
${multiFieldValue_add}
operation sum;
}
multiFieldValue_subtract
{
${multiFieldValue_add}
operation subtract;
}
multiFieldValue_min
{
${multiFieldValue_add}
operation min;
}
multiFieldValue_max
{
${multiFieldValue_add}
operation max;
}
multiFieldValue_average
{
${multiFieldValue_add}
operation average;
}
// ************************************************************************* //

View File

@ -16,7 +16,7 @@ FoamFile
application pisoFoam;
startFrom startTime;
startFrom latestTime;
startTime 0;
@ -68,6 +68,7 @@ functions
#include "FOlog"
#include "FOmag"
#include "FOmagSqr"
#include "FOmultiFieldValue"
#include "FOmultiply"
#include "FOmomentum"
#include "FOnearWallFields"