From ea12bfdb0f0d42eadccdf03badb542bfc734fe64 Mon Sep 17 00:00:00 2001 From: Andrew Heather <> Date: Mon, 17 May 2021 21:08:38 +0100 Subject: [PATCH] ENH: new multiFieldValue function object Computes a selected operation between multiple \c fieldValue function objects. The operation is applied to all results of each \c fieldValue object. Note Each object must generate the same number and type of results. Usage Minimal example by using \c system/controlDict.functions: multiFieldValue1 { // Mandatory entries (unmodifiable) type multiFieldValue; libs (fieldFunctionObjects); // Mandatory entries (runtime modifiable) operation subtract; // List of fieldValue function objects as dictionaries functions { region1 { ... } region2 { ... } ... regionN { ... } } // Optional (inherited) entries ... } where the entries mean: Property | Description | Type | Req'd | Dflt 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 | - \endtable Options for the \c operation entry: add | add subtract | subtract min | minimum max | maximum average | average Deprecated fieldValueDelta - The fieldValueDelta function object was originally written to compute the difference between two fieldValue-type function objects. The multiFieldValue object name better describes its purpose whilst being able to operate on an arbitrary number of fieldValue-type objects. --- .../pressure/pressureDifference.cfg | 25 +- src/functionObjects/field/Make/files | 2 +- .../field/fieldValues/fieldValue/fieldValue.C | 26 +- .../field/fieldValues/fieldValue/fieldValue.H | 10 +- .../fieldValues/fieldValue/fieldValueNew.C | 9 +- .../fieldValueDelta/fieldValueDelta.C | 227 ------------- .../multiFieldValue/multiFieldValue.C | 306 ++++++++++++++++++ .../multiFieldValue.H} | 118 ++++--- .../multiFieldValueTemplates.C} | 44 +-- .../surfaceFieldValue/surfaceFieldValue.C | 2 +- .../fieldValues/volFieldValue/volFieldValue.C | 4 +- .../filter/system/controlDict | 3 +- .../filter/system/pressureDifference | 40 +++ 13 files changed, 480 insertions(+), 336 deletions(-) delete mode 100644 src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C create mode 100644 src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.C rename src/functionObjects/field/fieldValues/{fieldValueDelta/fieldValueDelta.H => multiFieldValue/multiFieldValue.H} (63%) rename src/functionObjects/field/fieldValues/{fieldValueDelta/fieldValueDeltaTemplates.C => multiFieldValue/multiFieldValueTemplates.C} (74%) create mode 100644 tutorials/lagrangian/reactingParcelFoam/filter/system/pressureDifference diff --git a/etc/caseDicts/postProcessing/pressure/pressureDifference.cfg b/etc/caseDicts/postProcessing/pressure/pressureDifference.cfg index b601f5b97b6..b8f8e057c52 100644 --- a/etc/caseDicts/postProcessing/pressure/pressureDifference.cfg +++ b/etc/caseDicts/postProcessing/pressure/pressureDifference.cfg @@ -6,7 +6,7 @@ \\/ M anipulation | \*---------------------------------------------------------------------------*/ -type fieldValueDelta; +type multiFieldValue; libs ("libfieldFunctionObjects.so"); operation subtract; @@ -15,17 +15,20 @@ writeControl timeStep; writeInterval 1; log false; -region1 +functions { - #includeEtc "caseDicts/postProcessing/surfaceFieldValue/surfaceRegion.cfg" - operation areaAverage; - fields (p); -} -region2 -{ - #includeEtc "caseDicts/postProcessing/surfaceFieldValue/surfaceRegion.cfg" - operation areaAverage; - fields (p); + region1 + { + #includeEtc "caseDicts/postProcessing/surfaceFieldValue/surfaceRegion.cfg" + operation areaAverage; + fields (p); + } + region2 + { + #includeEtc "caseDicts/postProcessing/surfaceFieldValue/surfaceRegion.cfg" + operation areaAverage; + fields (p); + } } // ************************************************************************* // diff --git a/src/functionObjects/field/Make/files b/src/functionObjects/field/Make/files index 1ca2168217c..ddcb030299f 100644 --- a/src/functionObjects/field/Make/files +++ b/src/functionObjects/field/Make/files @@ -16,9 +16,9 @@ fieldMinMax/fieldMinMax.C fieldValues/fieldValue/fieldValue.C fieldValues/fieldValue/fieldValueNew.C -fieldValues/fieldValueDelta/fieldValueDelta.C fieldValues/volFieldValue/volFieldValue.C fieldValues/surfaceFieldValue/surfaceFieldValue.C +fieldValues/multiFieldValue/multiFieldValue.C heatTransferCoeff/heatTransferCoeff.C heatTransferCoeff/heatTransferCoeffModels/heatTransferCoeffModel/heatTransferCoeffModel.C diff --git a/src/functionObjects/field/fieldValues/fieldValue/fieldValue.C b/src/functionObjects/field/fieldValues/fieldValue/fieldValue.C index f981f090d00..21be1ff6cd9 100644 --- a/src/functionObjects/field/fieldValues/fieldValue/fieldValue.C +++ b/src/functionObjects/field/fieldValues/fieldValue/fieldValue.C @@ -37,7 +37,7 @@ namespace Foam namespace functionObjects { defineTypeNameAndDebug(fieldValue, 0); - defineRunTimeSelectionTable(fieldValue, dictionary); + defineRunTimeSelectionTable(fieldValue, runTime); } } @@ -55,7 +55,7 @@ Foam::functionObjects::fieldValue::fieldValue fvMeshFunctionObject(name, runTime, dict), writeFile(obr_, name, valueType, dict), writeFields_(false), - regionName_(word::null), + regionName_(), scaleFactor_(1.0), dict_(dict), fields_() @@ -75,7 +75,7 @@ Foam::functionObjects::fieldValue::fieldValue fvMeshFunctionObject(name, obr, dict), writeFile(obr_, name, valueType, dict), writeFields_(false), - regionName_(word::null), + regionName_(), scaleFactor_(1.0), dict_(dict), fields_() @@ -88,19 +88,21 @@ Foam::functionObjects::fieldValue::fieldValue bool Foam::functionObjects::fieldValue::read(const dictionary& dict) { - if (dict != dict_) + if (fvMeshFunctionObject::read(dict) && writeFile::read(dict)) { - dict_ = dict; - } + if (dict != dict_) + { + dict_ = dict; + } - fvMeshFunctionObject::read(dict); - writeFile::read(dict); + dict.readEntry("writeFields", writeFields_); + scaleFactor_ = dict.getOrDefault<scalar>("scaleFactor", 1.0); + dict.readEntry("fields", fields_); - dict.readEntry("writeFields", writeFields_); - scaleFactor_ = dict.getOrDefault<scalar>("scaleFactor", 1.0); - dict.readEntry("fields", fields_); + return true; + } - return true; + return false; } diff --git a/src/functionObjects/field/fieldValues/fieldValue/fieldValue.H b/src/functionObjects/field/fieldValues/fieldValue/fieldValue.H index 5e008f62289..a182e300224 100644 --- a/src/functionObjects/field/fieldValues/fieldValue/fieldValue.H +++ b/src/functionObjects/field/fieldValues/fieldValue/fieldValue.H @@ -98,7 +98,6 @@ class fieldValue public fvMeshFunctionObject, public writeFile { - protected: // Protected Data @@ -141,16 +140,15 @@ public: ( autoPtr, fieldValue, - dictionary, + runTime, ( const word& name, - const objectRegistry& obr, + const Time& runTime, const dictionary& dict ), - (name, obr, dict) + (name, runTime, dict) ); - // Constructors //- Construct from Time and dictionary @@ -175,7 +173,7 @@ public: static autoPtr<fieldValue> New ( const word& name, - const objectRegistry& obr, + const Time& runTime, const dictionary& dict, const bool output = true ); diff --git a/src/functionObjects/field/fieldValues/fieldValue/fieldValueNew.C b/src/functionObjects/field/fieldValues/fieldValue/fieldValueNew.C index 39ebdca2539..0868e0b86fe 100644 --- a/src/functionObjects/field/fieldValues/fieldValue/fieldValueNew.C +++ b/src/functionObjects/field/fieldValues/fieldValue/fieldValueNew.C @@ -34,7 +34,7 @@ Foam::autoPtr<Foam::functionObjects::fieldValue> Foam::functionObjects::fieldValue::New ( const word& name, - const objectRegistry& obr, + const Time& runTime, const dictionary& dict, const bool output ) @@ -46,7 +46,7 @@ Foam::functionObjects::fieldValue::New Info<< "Selecting " << typeName << ' ' << modelType << endl; } - auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType); + auto cstrIter = runTimeConstructorTablePtr_->cfind(modelType); if (!cstrIter.found()) { @@ -55,12 +55,13 @@ Foam::functionObjects::fieldValue::New dict, typeName, modelType, - *dictionaryConstructorTablePtr_ + *runTimeConstructorTablePtr_ ) << exit(FatalIOError); } - return autoPtr<fieldValue>(cstrIter()(name, obr, dict)); + return autoPtr<fieldValue>(cstrIter()(name, runTime, dict)); } + // ************************************************************************* // diff --git a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C b/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C deleted file mode 100644 index 09f4f91833a..00000000000 --- a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.C +++ /dev/null @@ -1,227 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2020 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "fieldValueDelta.H" -#include "addToRunTimeSelectionTable.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ -namespace functionObjects -{ -namespace fieldValues -{ - defineTypeNameAndDebug(fieldValueDelta, 0); - addToRunTimeSelectionTable(functionObject, fieldValueDelta, dictionary); -} -} -} - - -const Foam::Enum -< - Foam::functionObjects::fieldValues::fieldValueDelta::operationType -> -Foam::functionObjects::fieldValues::fieldValueDelta::operationTypeNames_ -({ - { operationType::opAdd, "add" }, - { operationType::opSubtract, "subtract" }, - { operationType::opMin, "min" }, - { operationType::opMax, "max" }, - { operationType::opAverage, "average" }, -}); - - -// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // - -void Foam::functionObjects::fieldValues::fieldValueDelta::writeFileHeader -( - Ostream& os -) const -{ - const wordList& fields1 = region1Ptr_->fields(); - const wordList& fields2 = region2Ptr_->fields(); - - DynamicList<word> commonFields(fields1.size()); - forAll(fields1, fieldi) - { - label index = fields2.find(fields1[fieldi]); - if (index != -1) - { - commonFields.append(fields1[fieldi]); - } - } - - writeHeaderValue(os, "Source1", region1Ptr_->name()); - writeHeaderValue(os, "Source2", region2Ptr_->name()); - writeHeaderValue(os, "Operation", operationTypeNames_[operation_]); - writeCommented(os, "Time"); - - forAll(commonFields, i) - { - os << tab << commonFields[i]; - } - - os << endl; -} - - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::functionObjects::fieldValues::fieldValueDelta::fieldValueDelta -( - const word& name, - const Time& runTime, - const dictionary& dict -) -: - fvMeshFunctionObject(name, runTime, dict), - writeFile(obr_, name, typeName, dict), - operation_(opSubtract), - region1Ptr_(nullptr), - region2Ptr_(nullptr) -{ - read(dict); - writeFileHeader(file()); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -bool Foam::functionObjects::fieldValues::fieldValueDelta::read -( - const dictionary& dict -) -{ - fvMeshFunctionObject::read(dict); - writeFile::read(dict); - - region1Ptr_.reset - ( - fieldValue::New - ( - name() + ".region1", - obr_, - dict.subDict("region1"), - false - ).ptr() - ); - region2Ptr_.reset - ( - fieldValue::New - ( - name() + ".region2", - obr_, - dict.subDict("region2"), - false - ).ptr() - ); - - operation_ = operationTypeNames_.get("operation", dict); - - return true; -} - - -bool Foam::functionObjects::fieldValues::fieldValueDelta::write() -{ - region1Ptr_->write(); - region2Ptr_->write(); - - writeCurrentTime(file()); - - Log << type() << " " << name() << " write:" << endl; - - const word& name1 = region1Ptr_->name(); - const word& name2 = region2Ptr_->name(); - - const wordList entries1 = objectResultEntries(name1); - const wordList entries2 = objectResultEntries(name2); - - if (entries1.size() != entries2.size()) - { - FatalErrorInFunction - << name() << ": objects must generate the same number of results" - << nl - << " " << name1 << " objects: " << entries1 << nl - << " " << name2 << " objects: " << entries2 << nl - << exit(FatalError); - } - - forAll(entries1, i) - { - const word& entry1(entries1[i]); - const word& entry2(entries2[i]); - const word type1 = objectResultType(name1, entry1); - const word type2 = objectResultType(name2, entry2); - - if (type1 != type2) - { - FatalErrorInFunction - << name() - << ": input values for operation must be of the same type" - << nl - << " " << entry1 << ": " << type1 << nl - << " " << entry2 << ": " << type2 << nl - << exit(FatalError); - } - - bool found = false; - - applyOperation<scalar>(type1, name1, name2, entry1, entry2, found); - applyOperation<vector>(type1, name1, name2, entry1, entry2, found); - applyOperation<sphericalTensor> - (type1, name1, name2, entry1, entry2, found); - applyOperation<symmTensor>(type1, name1, name2, entry1, entry2, found); - applyOperation<tensor>(type1, name1, name2, entry1, entry2, found); - - if (!found) - { - Log << "Operation between " - << name1 << " with result " << entry1 << " and " - << name2 << " with result " << entry2 << " not applied" - << endl; - } - } - - Log << (entries1.empty() ? " none" : "") << endl; - - file()<< endl; - - return true; -} - - -bool Foam::functionObjects::fieldValues::fieldValueDelta::execute() -{ - return true; -} - - -// ************************************************************************* // diff --git a/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.C b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.C new file mode 100644 index 00000000000..251a9a47da7 --- /dev/null +++ b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.C @@ -0,0 +1,306 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2012-2016 OpenFOAM Foundation + Copyright (C) 2015-2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "multiFieldValue.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ +namespace fieldValues +{ + defineTypeNameAndDebug(multiFieldValue, 0); + addToRunTimeSelectionTable(functionObject, multiFieldValue, dictionary); +} +} +} + + +const Foam::Enum +< + Foam::functionObjects::fieldValues::multiFieldValue::operationType +> +Foam::functionObjects::fieldValues::multiFieldValue::operationTypeNames_ +({ + { operationType::opSum, "sum" }, + { operationType::opAdd, "add" }, + { operationType::opSubtract, "subtract" }, + { operationType::opMin, "min" }, + { operationType::opMax, "max" }, + { operationType::opAverage, "average" }, +}); + + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // + +void Foam::functionObjects::fieldValues::multiFieldValue::writeFileHeader +( + Ostream& os +) const +{ + const wordList& fields0 = functions_[0].fields(); + + DynamicList<word> commonFields(fields0.size()); + + for (const word& fieldName : fields0) + { + 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 + ( + os, + "Source" + Foam::name(functioni), + functions_[functioni].name() + ); + } + + writeHeaderValue(os, "Operation", operationTypeNames_[operation_]); + writeCommented(os, "Time"); + + for (const word& fieldName : commonFields) + { + os << tab << fieldName; + } + + os << endl; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects::fieldValues::multiFieldValue::multiFieldValue +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + stateFunctionObject(name, runTime), + writeFile(runTime, name, typeName, dict), + operation_(opSubtract), + functions_() +{ + if (read(dict)) + { + writeFileHeader(file()); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::fieldValues::multiFieldValue::read +( + const dictionary& dict +) +{ + if (stateFunctionObject::read(dict) && writeFile::read(dict)) + { + const dictionary& functionsDict = dict.subDict("functions"); + functions_.resize(functionsDict.size()); + + if (functions_.empty()) + { + WarningInFunction + << "No functions specified" + << endl; + return false; + } + + label functioni = 0; + for (const entry& dEntry : functionsDict) + { + if (!dEntry.isDict()) + { + FatalIOErrorInFunction(dict) + << "Functions must be specified in dictionary format" + << exit(FatalIOError); + } + + const dictionary& localDict = dEntry.dict(); + + functions_.set + ( + functioni, + fieldValue::New + ( + IOobject::scopedName(name(), localDict.dictName()), + time(), + localDict, + false + ) + ); + + ++functioni; + } + + operation_ = operationTypeNames_.get("operation", dict); + + return true; + } + + return false; +} + + +bool Foam::functionObjects::fieldValues::multiFieldValue::write() +{ + if (functions_.empty()) + { + return false; + } + + Log << type() << " " << name() << " write:" << endl; + + const label nFunction = functions_.size(); + wordList entries0; + label nEntries = -1; + + wordList names(nFunction); + List<wordList> entries; + List<wordList> types; + + forAll(functions_, functioni) + { + auto& f = functions_[functioni]; + names[functioni] = f.name(); + + // Note: results are not available until the call to write() + f.write(); + + const wordList e(objectResultEntries(f.name())); + + if (functioni == 0) + { + entries0 = e; + nEntries = e.size(); + entries.resize(nEntries); + types.resize(nEntries); + + forAll(entries, entryi) + { + entries[entryi].resize(nFunction); + types[entryi].resize(nFunction); + } + } + + if (e.size() != nEntries) + { + const word& f0Name = functions_[0].name(); + + FatalErrorInFunction + << "Inconsistent number of result entries" << nl + << " " << f0Name << " entries:" << entries0 << nl + << " " << f.name() << " entries:" << e + << abort(FatalError); + } + + forAll(e, entryi) + { + entries[entryi][functioni] = e[entryi]; + types[entryi][functioni] = objectResultType(f.name(), e[entryi]); + } + } + + writeCurrentTime(file()); + + forAll(entries, entryi) + { + const wordList& entriesi = entries[entryi]; + const word& t0 = types[entryi][0]; + const wordList& typesi = types[entryi]; + forAll(typesi, functioni) + { + const word& t = typesi[functioni]; + + if (t != t0) + { + FatalErrorInFunction + << "Inconsistent function result types" << nl + << " " << functions_[0].name() + << " result type:" << t0 << nl + << " " << functions_[functioni].name() + << " result type:" << typesi[functioni] + << abort(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) + ); + + if (!ok) + { + Log << "Operation not applied between functions:" << nl + << flatOutput(names, FlatOutput::BareComma{}) << nl + << "with result names:" << nl + << flatOutput(entriesi, FlatOutput::BareComma{}) + << endl; + } + } + + Log << (nEntries == 0 ? " none" : "") << endl; + + file()<< endl; + + return true; +} + + +bool Foam::functionObjects::fieldValues::multiFieldValue::execute() +{ + return true; +} + + +// ************************************************************************* // diff --git a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.H similarity index 63% rename from src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H rename to src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.H index 8f6eea9cb98..d6b73499eb2 100644 --- a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDelta.H +++ b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValue.H @@ -5,8 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2020 OpenCFD Ltd. + Copyright (C) 2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,35 +24,50 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::functionObjects::fieldValues::fieldValueDelta + Foam::functionObjects::fieldValues::multiFieldValue Group grpFieldFunctionObjects Description - Computes a selected operation between two \c fieldValue function objects. + Computes a selected operation between multiple \c fieldValue function + objects. The operation is applied to all results of each \c fieldValue object. - Accordingly, each object must generate the same number and type of results. + +Note + Each object must generate the same number and type of results. Usage Minimal example by using \c system/controlDict.functions: \verbatim - fieldValueDelta1 + multiFieldValue1 { // Mandatory entries (unmodifiable) - type fieldValueDelta; - libs (fieldFunctionObjects); + type multiFieldValue; + libs (fieldFunctionObjects); // Mandatory entries (runtime modifiable) - operation subtract; - region1 - { - ... - } - region2 + operation average; + + // List of fieldValue function objects as dictionaries + functions { + region1 + { + ... + } + region2 + { + ... + } + ... + + regionN + { + ... + } } // Optional (inherited) entries @@ -63,12 +77,11 @@ Usage where the entries mean: \table - Property | Description | Type | Req'd | Dflt - type | Type name: fieldValueDelta | word | yes | - - libs | Library name: fieldFunctionObjects | word | yes | - - operation | Operation type to apply to values | word | yes | - - region1 | Region1 properties | dict | yes | - - region2 | Region2 properties | dict | yes | - + Property | Description | Type | Req'd | Dflt + 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 | - \endtable Options for the \c operation entry: @@ -88,16 +101,16 @@ Usage See also - Foam::functionObject - Foam::functionObjects::fieldValue - - ExtendedCodeGuide::functionObjects::field::fieldValueDelta + - ExtendedCodeGuide::functionObjects::field::multiFieldValue SourceFiles - fieldValueDelta.C - fieldValueDeltaTemplates.C + multiFieldValue.C + multiFieldValueTemplates.C \*---------------------------------------------------------------------------*/ -#ifndef functionObjects_fieldValueDelta_H -#define functionObjects_fieldValueDelta_H +#ifndef functionObjects_multiFieldValue_H +#define functionObjects_multiFieldValue_H #include "stateFunctionObject.H" #include "writeFile.H" @@ -114,23 +127,27 @@ namespace fieldValues { /*---------------------------------------------------------------------------*\ - Class fieldValueDelta Declaration + Class multiFieldValue Declaration \*---------------------------------------------------------------------------*/ -class fieldValueDelta +class multiFieldValue : - public fvMeshFunctionObject, - public writeFile + public functionObjects::stateFunctionObject, + public functionObjects::writeFile { public: + + // Public Data Types + //- Operation type enumeration enum operationType { - opAdd, //!< Add - opSubtract, //!< Subtract - opMin, //!< Minimum - opMax, //!< Maximum - opAverage //!< Average + opSum, //!< Sum of values + opAdd, //!< Add values (same as sum) + opSubtract, //!< Subtract values from first entry + opMin, //!< Minimum value + opMax, //!< Maximum value + opAverage //!< Average value }; //- Operation type names @@ -144,25 +161,20 @@ private: //- Operation to apply to values operationType operation_; - //- Field value region object 1 - autoPtr<fieldValue> region1Ptr_; - - //- Field value region object 2 - autoPtr<fieldValue> region2Ptr_; + //- List of fieldValue function objects + PtrList<fieldValue> functions_; // Private Member Functions - //- Templated function to apply the operation + //- Templated function to apply the operation. + // \return true if Type and resultType are correct template<class Type> - void applyOperation + bool applyOperation ( const word& resultType, - const word& name1, - const word& name2, - const word& entryName1, - const word& entryName2, - bool& found + const wordList& names, + const wordList& entryNames ); @@ -177,13 +189,13 @@ protected: public: //- Run-time type information - TypeName("fieldValueDelta"); + TypeName("multiFieldValue"); // Constructors //- Construct from Time and dictionary - fieldValueDelta + multiFieldValue ( const word& name, const Time& runTime, @@ -191,20 +203,20 @@ public: ); //- No copy construct - fieldValueDelta(const fieldValueDelta&) = delete; + multiFieldValue(const multiFieldValue&) = delete; //- No copy assignment - void operator=(const fieldValueDelta&) = delete; + void operator=(const multiFieldValue&) = delete; //- Destructor - virtual ~fieldValueDelta() = default; + virtual ~multiFieldValue() = default; // Public Member Functions //- Read from dictionary - virtual bool read(const dictionary&); + virtual bool read(const dictionary& dict); //- Do nothing virtual bool execute(); @@ -223,7 +235,7 @@ public: // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository - #include "fieldValueDeltaTemplates.C" + #include "multiFieldValueTemplates.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValueTemplates.C similarity index 74% rename from src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C rename to src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValueTemplates.C index 3ef57feddb1..714cb1c48b6 100644 --- a/src/functionObjects/field/fieldValues/fieldValueDelta/fieldValueDeltaTemplates.C +++ b/src/functionObjects/field/fieldValues/multiFieldValue/multiFieldValueTemplates.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2016 OpenCFD Ltd. + Copyright (C) 2015-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,56 +26,63 @@ License \*---------------------------------------------------------------------------*/ +#include "FlatOutput.H" + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class Type> -void Foam::functionObjects::fieldValues::fieldValueDelta::applyOperation +bool Foam::functionObjects::fieldValues::multiFieldValue::applyOperation ( const word& resultType, - const word& name1, - const word& name2, - const word& entryName1, - const word& entryName2, - bool& found + const wordList& names, + const wordList& entryNames ) { if (pTraits<Type>::typeName != resultType) { - return; + return false; } Type result = Zero; - Type value1 = this->getObjectResult<Type>(name1, entryName1); - Type value2 = this->getObjectResult<Type>(name2, entryName2); + Field<Type> values(names.size()); + forAll(values, i) + { + values[i] = this->getObjectResult<Type>(names[i], entryNames[i]); + } const word& opName = operationTypeNames_[operation_]; switch (operation_) { + case opSum: case opAdd: { - result = value1 + value2; + result = sum(values); break; } case opSubtract: { - result = value1 - value2; + result = values[0]; + for (label i = 1; i < values.size(); ++i) + { + result -= values[i]; + } break; } case opMin: { - result = min(value1, value2); + result = min(values); break; } case opMax: { - result = max(value1, value2); + result = max(values); break; } case opAverage: { - result = 0.5*(value1 + value2); + result = average(values); break; } default: @@ -87,8 +94,9 @@ void Foam::functionObjects::fieldValues::fieldValueDelta::applyOperation } } - const word resultName(opName + '(' + entryName1 + ',' + entryName2 + ')'); - + OStringStream os; + os << opName << flatOutput(entryNames, FlatOutput::ParenComma{}); + const word resultName(os.str()); Log << " " << resultName << " = " << result << endl; this->file()<< tab << result; @@ -96,7 +104,7 @@ void Foam::functionObjects::fieldValues::fieldValueDelta::applyOperation // Write state/results information this->setResult(resultName, result); - found = true; + return true; } diff --git a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C index 64713a635ab..4d9ff3ab055 100644 --- a/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C +++ b/src/functionObjects/field/fieldValues/surfaceFieldValue/surfaceFieldValue.C @@ -45,7 +45,7 @@ namespace functionObjects namespace fieldValues { defineTypeNameAndDebug(surfaceFieldValue, 0); - addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, dictionary); + addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, runTime); addToRunTimeSelectionTable(functionObject, surfaceFieldValue, dictionary); } } diff --git a/src/functionObjects/field/fieldValues/volFieldValue/volFieldValue.C b/src/functionObjects/field/fieldValues/volFieldValue/volFieldValue.C index f18041e68a9..9f355a25bb4 100644 --- a/src/functionObjects/field/fieldValues/volFieldValue/volFieldValue.C +++ b/src/functionObjects/field/fieldValues/volFieldValue/volFieldValue.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (C) 2017-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -40,7 +40,7 @@ namespace functionObjects namespace fieldValues { defineTypeNameAndDebug(volFieldValue, 0); - addToRunTimeSelectionTable(fieldValue, volFieldValue, dictionary); + addToRunTimeSelectionTable(fieldValue, volFieldValue, runTime); addToRunTimeSelectionTable(functionObject, volFieldValue, dictionary); } } diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict b/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict index 735b83ad32f..c196a53845c 100644 --- a/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict +++ b/tutorials/lagrangian/reactingParcelFoam/filter/system/controlDict @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v2012 | +| \\ / O peration | Version: v2106 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -55,6 +55,7 @@ functions #include "dataCloud" #include "vtkCloud" #include "vtkWrite" + #include "pressureDifference" } diff --git a/tutorials/lagrangian/reactingParcelFoam/filter/system/pressureDifference b/tutorials/lagrangian/reactingParcelFoam/filter/system/pressureDifference new file mode 100644 index 00000000000..64332980a9b --- /dev/null +++ b/tutorials/lagrangian/reactingParcelFoam/filter/system/pressureDifference @@ -0,0 +1,40 @@ +// -*- C++ -*- + +pressureDifference +{ + type multiFieldValue; + libs (fieldFunctionObjects); + + operation subtract; + + functions + { + inlet + { + type surfaceFieldValue; + operation areaAverage; + regionType patch; + name inlet; + fields (p); + + writeFields no; + writeToFile no; + log no; + } + outlet + { + type surfaceFieldValue; + operation areaAverage; + regionType patch; + name outlet; + fields (p); + + writeFields no; + writeToFile no; + log no; + } + } +} + + +// ************************************************************************* // -- GitLab