diff --git a/etc/caseDicts/postProcessing/fields/add b/etc/caseDicts/postProcessing/fields/add index 79f5cf9d9c..583aae89ee 100644 --- a/etc/caseDicts/postProcessing/fields/add +++ b/etc/caseDicts/postProcessing/fields/add @@ -13,7 +13,7 @@ Description type add; libs ("libfieldFunctionObjects.so"); -fields (); +fields (); executeControl writeTime; writeControl writeTime; diff --git a/etc/caseDicts/postProcessing/fields/subtract b/etc/caseDicts/postProcessing/fields/subtract index dc08604795..006c0f50d4 100644 --- a/etc/caseDicts/postProcessing/fields/subtract +++ b/etc/caseDicts/postProcessing/fields/subtract @@ -13,7 +13,7 @@ Description type subtract; libs ("libfieldFunctionObjects.so"); -fields (); +fields (); executeControl writeTime; writeControl writeTime; diff --git a/etc/caseDicts/postProcessing/fields/turbulenceFields b/etc/caseDicts/postProcessing/fields/turbulenceFields index 103ef68d18..9f761ab790 100644 --- a/etc/caseDicts/postProcessing/fields/turbulenceFields +++ b/etc/caseDicts/postProcessing/fields/turbulenceFields @@ -13,7 +13,7 @@ Description type turbulenceFields; libs ("libfieldFunctionObjects.so"); -fields (); +fields (); executeControl writeTime; writeControl writeTime; diff --git a/etc/caseDicts/postProcessing/fields/writeObjects b/etc/caseDicts/postProcessing/fields/writeObjects index 3a5f67c0ae..870174e417 100644 --- a/etc/caseDicts/postProcessing/fields/writeObjects +++ b/etc/caseDicts/postProcessing/fields/writeObjects @@ -13,7 +13,7 @@ Description type writeObjects; libs ("libutilityFunctionObjects.so"); -objects (); +objects (); writeControl writeTime; diff --git a/etc/caseDicts/postProcessing/fields/writeVTK b/etc/caseDicts/postProcessing/fields/writeVTK index 88d3112a51..30e558b70b 100644 --- a/etc/caseDicts/postProcessing/fields/writeVTK +++ b/etc/caseDicts/postProcessing/fields/writeVTK @@ -14,7 +14,7 @@ Description type writeVTK; libs ("libfoamToVTK.so"); -objects (); +objects (); writeControl writeTime; diff --git a/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage b/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage index ec81f15122..310753fa20 100644 --- a/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage +++ b/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage @@ -11,7 +11,7 @@ Description \*---------------------------------------------------------------------------*/ name ; -fields (); +fields (); operation areaAverage; #includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg" diff --git a/etc/caseDicts/postProcessing/surfaceFieldValue/patchIntegrate b/etc/caseDicts/postProcessing/surfaceFieldValue/patchIntegrate index f55c3c9ba3..1005c1125e 100644 --- a/etc/caseDicts/postProcessing/surfaceFieldValue/patchIntegrate +++ b/etc/caseDicts/postProcessing/surfaceFieldValue/patchIntegrate @@ -11,7 +11,7 @@ Description \*---------------------------------------------------------------------------*/ name ; -fields (); +fields (); operation areaIntegrate; #includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg" diff --git a/src/OpenFOAM/db/dictionary/functionEntries/functionEntry/functionEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/functionEntry/functionEntry.C index e3b6685a83..3bb95b18d6 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/functionEntry/functionEntry.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/functionEntry/functionEntry.C @@ -70,7 +70,7 @@ Foam::functionEntry::functionEntry primitiveEntry ( word(key + dict.name() + Foam::name(is.lineNumber())), - readLine(key, is).c_str() + token(word(readLine(key, is)), is.lineNumber()) ) {} @@ -164,16 +164,29 @@ bool Foam::functionEntry::execute void Foam::functionEntry::write(Ostream& os) const { - // Contents should be single string token - const token& t = operator[](0); - const string& s = t.stringToken(); + os.indent(); - for (size_t i = 0; i < s.size(); i++) + for (label i=0; i clone(const dictionary&) const + { + return autoPtr(new functionEntry(*this)); + } // Member Function Selectors diff --git a/src/OpenFOAM/db/dictionary/functionEntries/includeFuncEntry/includeFuncEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/includeFuncEntry/includeFuncEntry.C index 06e6a364c0..2af447ad96 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/includeFuncEntry/includeFuncEntry.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/includeFuncEntry/includeFuncEntry.C @@ -65,6 +65,7 @@ bool Foam::functionEntries::includeFuncEntry::execute ( fNameArgs, parentDict, + "file " + is.name() + " at line " + Foam::name(is.lineNumber()), selectedFields ); } diff --git a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C index b15ac79ee4..fe4c16d021 100644 --- a/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C +++ b/src/OpenFOAM/db/dictionary/primitiveEntry/primitiveEntryIO.C @@ -232,7 +232,7 @@ Foam::primitiveEntry::primitiveEntry(const keyType& key, Istream& is) void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const { - if (!contentsOnly && keyword().size() && keyword()[0] != '#') + if (!contentsOnly && keyword().size()) { os.writeKeyword(keyword()); } diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C index 35aa10bb16..757a71d0c4 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.C @@ -180,10 +180,55 @@ Foam::fileName Foam::functionObjectList::findDict } +void Foam::functionObjectList::checkUnsetEntries +( + const string& funcCall, + const dictionary& funcArgsDict, + const dictionary& funcDict, + const string& context +) +{ + const wordRe unset("<.*>"); + unset.compile(); + + forAllConstIter(IDLList, funcArgsDict, iter) + { + if (iter().isStream()) + { + ITstream& tokens = iter().stream(); + + forAll(tokens, i) + { + if (tokens[i].isWord()) + { + if (unset.match(tokens[i].wordToken())) + { + FatalIOErrorInFunction(funcDict) + << "Essential value for keyword '" + << iter().keyword() + << "' not set in function entry" << nl + << " " << funcCall.c_str() << nl + << " in " << context.c_str() << nl + << " Placeholder value is " + << tokens[i].wordToken() + << exit(FatalIOError); + } + } + } + } + else + { + checkUnsetEntries(funcCall, iter().dict(), funcDict, context); + } + } +} + + bool Foam::functionObjectList::readFunctionObject ( - const string& funcNameArgs, + const string& funcCall, dictionary& functionsDict, + const string& context, HashSet& requiredFields, const word& region ) @@ -195,7 +240,7 @@ bool Foam::functionObjectList::readFunctionObject // 'patchAverage(patch=inlet, p)' -> funcName = patchAverage; // args = (patch=inlet, p); field = p - word funcName(funcNameArgs); + word funcName(funcCall); int argLevel = 0; wordList args; @@ -209,8 +254,8 @@ bool Foam::functionObjectList::readFunctionObject for ( - word::const_iterator iter = funcNameArgs.begin(); - iter != funcNameArgs.end(); + word::const_iterator iter = funcCall.begin(); + iter != funcCall.end(); ++iter ) { @@ -220,7 +265,7 @@ bool Foam::functionObjectList::readFunctionObject { if (argLevel == 0) { - funcName = funcNameArgs(start, i - start); + funcName = funcCall(start, i - start); start = i+1; } ++argLevel; @@ -236,7 +281,7 @@ bool Foam::functionObjectList::readFunctionObject Tuple2 ( argName, - funcNameArgs(start, i - start) + funcCall(start, i - start) ) ); namedArg = false; @@ -245,7 +290,7 @@ bool Foam::functionObjectList::readFunctionObject { args.append ( - string::validate(funcNameArgs(start, i - start)) + string::validate(funcCall(start, i - start)) ); } start = i+1; @@ -262,7 +307,7 @@ bool Foam::functionObjectList::readFunctionObject } else if (c == '=') { - argName = string::validate(funcNameArgs(start, i - start)); + argName = string::validate(funcCall(start, i - start)); start = i+1; namedArg = true; } @@ -303,6 +348,9 @@ bool Foam::functionObjectList::readFunctionObject dictionary& funcDict = *funcDictPtr; + // Store the funcDict as read for error reporting context + const dictionary funcDict0(funcDict); + // Insert the 'field' and/or 'fields' entry corresponding to the optional // arguments or read the 'field' or 'fields' entry and add the required // fields to requiredFields @@ -310,20 +358,10 @@ bool Foam::functionObjectList::readFunctionObject { funcDict.set("field", args[0]); funcDict.set("fields", args); - requiredFields.insert(args[0]); } else if (args.size() > 1) { funcDict.set("fields", args); - requiredFields.insert(args); - } - else if (funcDict.found("field")) - { - requiredFields.insert(word(funcDict.lookup("field"))); - } - else if (funcDict.found("fields")) - { - requiredFields.insert(wordList(funcDict.lookup("fields"))); } // Insert named arguments @@ -343,9 +381,9 @@ bool Foam::functionObjectList::readFunctionObject } // Merge this functionObject dictionary into functionsDict - const word funcNameArgsWord = string::validate(funcNameArgs); + const word funcCallKeyword = string::validate(funcCall); dictionary funcArgsDict; - funcArgsDict.add(funcNameArgsWord, funcDict); + funcArgsDict.add(funcCallKeyword, funcDict); // Re-parse the funcDict to execute the functionEntries // now that the function argument entries have been added @@ -355,8 +393,22 @@ bool Foam::functionObjectList::readFunctionObject funcArgsDict = dictionary(IStringStream(os.str())()); } + checkUnsetEntries(funcCall, funcArgsDict, funcDict0, context); + + // Lookup the field and fields entries from the now expanded funcDict + // and insert into the requiredFields + dictionary& expandedFuncDict = funcArgsDict.subDict(funcCallKeyword); + if (expandedFuncDict.found("field")) + { + requiredFields.insert(word(expandedFuncDict.lookup("field"))); + } + else if (expandedFuncDict.found("fields")) + { + requiredFields.insert(wordList(expandedFuncDict.lookup("fields"))); + } + functionsDict.merge(funcArgsDict); - functionsDict.subDict(funcNameArgsWord).name() = funcDict.name(); + functionsDict.subDict(funcCallKeyword).name() = funcDict.name(); return true; } @@ -451,6 +503,7 @@ Foam::autoPtr Foam::functionObjectList::New ( args["func"], functionsDict, + "command line " + args.commandLine(), requiredFields, region ); @@ -466,6 +519,7 @@ Foam::autoPtr Foam::functionObjectList::New ( funcs[i], functionsDict, + "command line " + args.commandLine(), requiredFields, region ); diff --git a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H index fe4c6db622..4c0e47b958 100644 --- a/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H +++ b/src/OpenFOAM/db/functionObjects/functionObjectList/functionObjectList.H @@ -95,6 +95,14 @@ class functionObjectList // configuration files, add to the given map and recurse static void listDir(const fileName& dir, HashSet& foMap); + static void checkUnsetEntries + ( + const string& funcNameArgs, + const dictionary& funcArgsDict, + const dictionary& funcDict, + const string& context + ); + public: @@ -247,6 +255,7 @@ public: ( const string& funcNameArgs0, dictionary& functionsDict, + const string& context, HashSet& requiredFields, const word& region = word::null ); diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index 07e5740b37..91cc5b7e2f 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -229,6 +229,9 @@ public: // Access + //- Return the command line string + inline const string& commandLine() const; + //- Name of executable without the path inline const word& executable() const; diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H index 7dcfe00e2b..7cc3a7a291 100644 --- a/src/OpenFOAM/global/argList/argListI.H +++ b/src/OpenFOAM/global/argList/argListI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | Website: https://openfoam.org - \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,12 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +inline const Foam::string& Foam::argList::commandLine() const +{ + return argListStr_; +} + + inline const Foam::word& Foam::argList::executable() const { return executable_; diff --git a/tutorials/incompressible/pimpleFoam/RAS/pitzDaily/system/controlDict b/tutorials/incompressible/pimpleFoam/RAS/pitzDaily/system/controlDict index 5e02e4eac8..1bc284ad6c 100644 --- a/tutorials/incompressible/pimpleFoam/RAS/pitzDaily/system/controlDict +++ b/tutorials/incompressible/pimpleFoam/RAS/pitzDaily/system/controlDict @@ -49,4 +49,9 @@ adjustTimeStep yes; maxCo 5; +functions +{ + #includeFunc patchAverage(name=inlet, fields=(p U)) +} + // ************************************************************************* //