functionObject: Improved incorrect and incomplete argument error messages

Both the functionObject call context (the command line for postProcess, and the
controlDict path for run-time post-precessing) and the configuration file
context where the arguments are substituted are now printed in the error
message, e.g.

    postProcess -func 'patchAverage(name=inlet, ields=(p U))'

generates the message

--> FOAM FATAL IO ERROR:
Essential value for keyword 'fields' not set in function entry
    patchAverage(name=inlet, ields=(p U))
    in command line postProcess -func patchAverage(name=inlet, ields=(p U))
    Placeholder value is <field_names>

file: /home/dm2/henry/OpenFOAM/OpenFOAM-dev/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage from line 13 to line 17.

and with the following in controlDict

functions
{
    #includeFunc patchAverage(name=inlet, ields=(p U))
}

generates the message

--> FOAM FATAL IO ERROR:
Essential value for keyword 'fields' not set in function entry
     patchAverage(name=inlet, ields=(p U))
    in file /home/dm2/henry/OpenFOAM/OpenFOAM-dev/tutorials/incompressible/pimpleFoam/RAS/pitzDaily/system/controlDict at line 55
    Placeholder value is <field_names>

file: /home/dm2/henry/OpenFOAM/OpenFOAM-dev/etc/caseDicts/postProcessing/surfaceFieldValue/patchAverage from line 13 to line 17.
This commit is contained in:
Henry Weller
2019-08-10 19:16:25 +01:00
parent 808e827d20
commit 81f9320119
16 changed files with 132 additions and 39 deletions

View File

@ -13,7 +13,7 @@ Description
type add; type add;
libs ("libfieldFunctionObjects.so"); libs ("libfieldFunctionObjects.so");
fields (<field names>); fields (<field_names>);
executeControl writeTime; executeControl writeTime;
writeControl writeTime; writeControl writeTime;

View File

@ -13,7 +13,7 @@ Description
type subtract; type subtract;
libs ("libfieldFunctionObjects.so"); libs ("libfieldFunctionObjects.so");
fields (<field names>); fields (<field_names>);
executeControl writeTime; executeControl writeTime;
writeControl writeTime; writeControl writeTime;

View File

@ -13,7 +13,7 @@ Description
type turbulenceFields; type turbulenceFields;
libs ("libfieldFunctionObjects.so"); libs ("libfieldFunctionObjects.so");
fields (<field names>); fields (<field_names>);
executeControl writeTime; executeControl writeTime;
writeControl writeTime; writeControl writeTime;

View File

@ -13,7 +13,7 @@ Description
type writeObjects; type writeObjects;
libs ("libutilityFunctionObjects.so"); libs ("libutilityFunctionObjects.so");
objects (<object names>); objects (<object_names>);
writeControl writeTime; writeControl writeTime;

View File

@ -14,7 +14,7 @@ Description
type writeVTK; type writeVTK;
libs ("libfoamToVTK.so"); libs ("libfoamToVTK.so");
objects (<object names>); objects (<object_names>);
writeControl writeTime; writeControl writeTime;

View File

@ -11,7 +11,7 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
name <patchName>; name <patchName>;
fields (<field names>); fields (<field_names>);
operation areaAverage; operation areaAverage;
#includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg" #includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg"

View File

@ -11,7 +11,7 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
name <patchName>; name <patchName>;
fields (<field names>); fields (<field_names>);
operation areaIntegrate; operation areaIntegrate;
#includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg" #includeEtc "caseDicts/postProcessing/surfaceFieldValue/patch.cfg"

View File

@ -70,7 +70,7 @@ Foam::functionEntry::functionEntry
primitiveEntry primitiveEntry
( (
word(key + dict.name() + Foam::name(is.lineNumber())), 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 void Foam::functionEntry::write(Ostream& os) const
{ {
// Contents should be single string token os.indent();
const token& t = operator[](0);
const string& s = t.stringToken();
for (size_t i = 0; i < s.size(); i++) for (label i=0; i<size(); ++i)
{ {
os.write(s[i]); const token& t = operator[](i);
if (t.type() == token::VERBATIMSTRING)
{
// Bypass token output operator to avoid losing verbatimness.
// Handle in Ostreams themselves
os.write(t);
}
else
{
os << t;
}
if (i < size()-1)
{
os << token::SPACE;
}
} }
os << endl; os << endl;
} }

View File

@ -78,8 +78,10 @@ public:
//- Construct from keyword, parent dictionary and Istream //- Construct from keyword, parent dictionary and Istream
functionEntry(const word&, const dictionary&, Istream&); functionEntry(const word&, const dictionary&, Istream&);
//- Disallow default bitwise copy construction autoPtr<entry> clone(const dictionary&) const
functionEntry(const functionEntry&) = delete; {
return autoPtr<entry>(new functionEntry(*this));
}
// Member Function Selectors // Member Function Selectors

View File

@ -65,6 +65,7 @@ bool Foam::functionEntries::includeFuncEntry::execute
( (
fNameArgs, fNameArgs,
parentDict, parentDict,
"file " + is.name() + " at line " + Foam::name(is.lineNumber()),
selectedFields selectedFields
); );
} }

View File

@ -232,7 +232,7 @@ Foam::primitiveEntry::primitiveEntry(const keyType& key, Istream& is)
void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const void Foam::primitiveEntry::write(Ostream& os, const bool contentsOnly) const
{ {
if (!contentsOnly && keyword().size() && keyword()[0] != '#') if (!contentsOnly && keyword().size())
{ {
os.writeKeyword(keyword()); os.writeKeyword(keyword());
} }

View File

@ -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<entry>, 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 bool Foam::functionObjectList::readFunctionObject
( (
const string& funcNameArgs, const string& funcCall,
dictionary& functionsDict, dictionary& functionsDict,
const string& context,
HashSet<word>& requiredFields, HashSet<word>& requiredFields,
const word& region const word& region
) )
@ -195,7 +240,7 @@ bool Foam::functionObjectList::readFunctionObject
// 'patchAverage(patch=inlet, p)' -> funcName = patchAverage; // 'patchAverage(patch=inlet, p)' -> funcName = patchAverage;
// args = (patch=inlet, p); field = p // args = (patch=inlet, p); field = p
word funcName(funcNameArgs); word funcName(funcCall);
int argLevel = 0; int argLevel = 0;
wordList args; wordList args;
@ -209,8 +254,8 @@ bool Foam::functionObjectList::readFunctionObject
for for
( (
word::const_iterator iter = funcNameArgs.begin(); word::const_iterator iter = funcCall.begin();
iter != funcNameArgs.end(); iter != funcCall.end();
++iter ++iter
) )
{ {
@ -220,7 +265,7 @@ bool Foam::functionObjectList::readFunctionObject
{ {
if (argLevel == 0) if (argLevel == 0)
{ {
funcName = funcNameArgs(start, i - start); funcName = funcCall(start, i - start);
start = i+1; start = i+1;
} }
++argLevel; ++argLevel;
@ -236,7 +281,7 @@ bool Foam::functionObjectList::readFunctionObject
Tuple2<word, string> Tuple2<word, string>
( (
argName, argName,
funcNameArgs(start, i - start) funcCall(start, i - start)
) )
); );
namedArg = false; namedArg = false;
@ -245,7 +290,7 @@ bool Foam::functionObjectList::readFunctionObject
{ {
args.append args.append
( (
string::validate<word>(funcNameArgs(start, i - start)) string::validate<word>(funcCall(start, i - start))
); );
} }
start = i+1; start = i+1;
@ -262,7 +307,7 @@ bool Foam::functionObjectList::readFunctionObject
} }
else if (c == '=') else if (c == '=')
{ {
argName = string::validate<word>(funcNameArgs(start, i - start)); argName = string::validate<word>(funcCall(start, i - start));
start = i+1; start = i+1;
namedArg = true; namedArg = true;
} }
@ -303,6 +348,9 @@ bool Foam::functionObjectList::readFunctionObject
dictionary& funcDict = *funcDictPtr; 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 // Insert the 'field' and/or 'fields' entry corresponding to the optional
// arguments or read the 'field' or 'fields' entry and add the required // arguments or read the 'field' or 'fields' entry and add the required
// fields to requiredFields // fields to requiredFields
@ -310,20 +358,10 @@ bool Foam::functionObjectList::readFunctionObject
{ {
funcDict.set("field", args[0]); funcDict.set("field", args[0]);
funcDict.set("fields", args); funcDict.set("fields", args);
requiredFields.insert(args[0]);
} }
else if (args.size() > 1) else if (args.size() > 1)
{ {
funcDict.set("fields", args); 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 // Insert named arguments
@ -343,9 +381,9 @@ bool Foam::functionObjectList::readFunctionObject
} }
// Merge this functionObject dictionary into functionsDict // Merge this functionObject dictionary into functionsDict
const word funcNameArgsWord = string::validate<word>(funcNameArgs); const word funcCallKeyword = string::validate<word>(funcCall);
dictionary funcArgsDict; dictionary funcArgsDict;
funcArgsDict.add(funcNameArgsWord, funcDict); funcArgsDict.add(funcCallKeyword, funcDict);
// Re-parse the funcDict to execute the functionEntries // Re-parse the funcDict to execute the functionEntries
// now that the function argument entries have been added // now that the function argument entries have been added
@ -355,8 +393,22 @@ bool Foam::functionObjectList::readFunctionObject
funcArgsDict = dictionary(IStringStream(os.str())()); 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.merge(funcArgsDict);
functionsDict.subDict(funcNameArgsWord).name() = funcDict.name(); functionsDict.subDict(funcCallKeyword).name() = funcDict.name();
return true; return true;
} }
@ -451,6 +503,7 @@ Foam::autoPtr<Foam::functionObjectList> Foam::functionObjectList::New
( (
args["func"], args["func"],
functionsDict, functionsDict,
"command line " + args.commandLine(),
requiredFields, requiredFields,
region region
); );
@ -466,6 +519,7 @@ Foam::autoPtr<Foam::functionObjectList> Foam::functionObjectList::New
( (
funcs[i], funcs[i],
functionsDict, functionsDict,
"command line " + args.commandLine(),
requiredFields, requiredFields,
region region
); );

View File

@ -95,6 +95,14 @@ class functionObjectList
// configuration files, add to the given map and recurse // configuration files, add to the given map and recurse
static void listDir(const fileName& dir, HashSet<word>& foMap); static void listDir(const fileName& dir, HashSet<word>& foMap);
static void checkUnsetEntries
(
const string& funcNameArgs,
const dictionary& funcArgsDict,
const dictionary& funcDict,
const string& context
);
public: public:
@ -247,6 +255,7 @@ public:
( (
const string& funcNameArgs0, const string& funcNameArgs0,
dictionary& functionsDict, dictionary& functionsDict,
const string& context,
HashSet<word>& requiredFields, HashSet<word>& requiredFields,
const word& region = word::null const word& region = word::null
); );

View File

@ -229,6 +229,9 @@ public:
// Access // Access
//- Return the command line string
inline const string& commandLine() const;
//- Name of executable without the path //- Name of executable without the path
inline const word& executable() const; inline const word& executable() const;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,6 +27,12 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::string& Foam::argList::commandLine() const
{
return argListStr_;
}
inline const Foam::word& Foam::argList::executable() const inline const Foam::word& Foam::argList::executable() const
{ {
return executable_; return executable_;

View File

@ -49,4 +49,9 @@ adjustTimeStep yes;
maxCo 5; maxCo 5;
functions
{
#includeFunc patchAverage(name=inlet, fields=(p U))
}
// ************************************************************************* // // ************************************************************************* //