#includeModel, #includeConstraint: New dictionary directives
#includeModel includes an fvModel configuration file into the fvModels file
#includeConstraint includes an fvModel configuration file into the fvConstraints file
These operate in the same manner as #includeFunc does for functionObjects and
search the etc/caseDicts/fvModels and etc/caseDicts/fvConstraints directories
for configuration files and apply optional argument substitution.
Class
Foam::functionEntries::includeFvModelEntry
Description
Specify a fvModel dictionary file to include, expects the
fvModel name to follow with option arguments (without quotes).
Searches for fvModel dictionary file in user/group/shipped
directories allowing for version-specific and version-independent files
using the following hierarchy:
- \b user settings:
- ~/.OpenFOAM/\<VERSION\>/caseDicts/fvModels
- ~/.OpenFOAM/caseDicts/fvModels
- \b group (site) settings (when $WM_PROJECT_SITE is set):
- $WM_PROJECT_SITE/\<VERSION\>/etc/caseDicts/fvModels
- $WM_PROJECT_SITE/etc/caseDicts/fvModels
- \b group (site) settings (when $WM_PROJECT_SITE is not set):
- $WM_PROJECT_INST_DIR/site/\<VERSION\>/etc/caseDicts/fvModels
- $WM_PROJECT_INST_DIR/site/etc/caseDicts/fvModels
- \b other (shipped) settings:
- $WM_PROJECT_DIR/etc/caseDicts/fvModels
The optional field arguments included in the name are inserted in 'field' or
'fields' entries in the fvModel dictionary and included in the name
of the fvModel entry to avoid conflict.
Examples:
\verbatim
#includeModel clouds
#includeModel surfaceFilms
\endverbatim
Other dictionary entries may also be specified using named arguments.
See also
Foam::includeFvConstraintEntry
Foam::includeFuncEntry
Class
Foam::functionEntries::includeFvConstraintEntry
Description
Specify a fvConstraint dictionary file to include, expects the
fvConstraint name to follow with option arguments (without quotes).
Searches for fvConstraint dictionary file in user/group/shipped
directories allowing for version-specific and version-independent files
using the following hierarchy:
- \b user settings:
- ~/.OpenFOAM/\<VERSION\>/caseDicts/fvConstraints
- ~/.OpenFOAM/caseDicts/fvConstraints
- \b group (site) settings (when $WM_PROJECT_SITE is set):
- $WM_PROJECT_SITE/\<VERSION\>/etc/caseDicts/fvConstraints
- $WM_PROJECT_SITE/etc/caseDicts/fvConstraints
- \b group (site) settings (when $WM_PROJECT_SITE is not set):
- $WM_PROJECT_INST_DIR/site/\<VERSION\>/etc/caseDicts/fvConstraints
- $WM_PROJECT_INST_DIR/site/etc/caseDicts/fvConstraints
- \b other (shipped) settings:
- $WM_PROJECT_DIR/etc/caseDicts/fvConstraints
The optional field arguments included in the name are inserted in 'field' or
'fields' entries in the fvConstraint dictionary and included in the name
of the fvConstraint entry to avoid conflict.
Examples:
\verbatim
#includeConstraint limitPressure(minFactor=0.1, maxFactor=2)
#includeConstraint limitTemperature(min=101, max=1000)
\endverbatim
or for a multiphase case:
\verbatim
#includeConstraint limitLowPressure(min=1e4)
#includeConstraint limitTemperature(phase=steam, min=270, max=2000)
#includeConstraint limitTemperature(phase=water, min=270, max=2000)
\endverbatim
Other dictionary entries may also be specified using named arguments.
See also
Foam::includeFvModelEntry
Foam::includeFuncEntry
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -27,17 +27,6 @@ License
|
||||
#include "argList.H"
|
||||
#include "timeControlFunctionObject.H"
|
||||
#include "dictionaryEntry.H"
|
||||
#include "stringOps.H"
|
||||
#include "etcFiles.H"
|
||||
#include "wordAndDictionary.H"
|
||||
|
||||
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||
|
||||
Foam::fileName Foam::functionObjectList::functionObjectDictPath
|
||||
(
|
||||
"caseDicts/postProcessing"
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
@ -69,391 +58,6 @@ Foam::functionObject* Foam::functionObjectList::remove
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjectList::listDir
|
||||
(
|
||||
const fileName& dir,
|
||||
HashSet<word>& foMap
|
||||
)
|
||||
{
|
||||
// Search specified directory for functionObject configuration files
|
||||
{
|
||||
fileNameList foFiles(fileHandler().readDir(dir));
|
||||
forAll(foFiles, f)
|
||||
{
|
||||
if (foFiles[f].ext().empty())
|
||||
{
|
||||
foMap.insert(foFiles[f]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse into sub-directories
|
||||
{
|
||||
fileNameList foDirs(fileHandler().readDir(dir, fileType::directory));
|
||||
forAll(foDirs, fd)
|
||||
{
|
||||
listDir(dir/foDirs[fd], foMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::functionObjectList::list()
|
||||
{
|
||||
HashSet<word> foMap;
|
||||
|
||||
fileNameList etcDirs(findEtcDirs(functionObjectDictPath));
|
||||
|
||||
forAll(etcDirs, ed)
|
||||
{
|
||||
listDir(etcDirs[ed], foMap);
|
||||
}
|
||||
|
||||
return foMap.sortedToc();
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::functionObjectList::findDict
|
||||
(
|
||||
const word& funcName,
|
||||
const word& region
|
||||
)
|
||||
{
|
||||
// First check if there is a functionObject dictionary file in the
|
||||
// region system directory
|
||||
{
|
||||
const fileName dictFile
|
||||
(
|
||||
stringOps::expand("$FOAM_CASE")/"system"/region/funcName
|
||||
);
|
||||
|
||||
if (isFile(dictFile))
|
||||
{
|
||||
return dictFile;
|
||||
}
|
||||
}
|
||||
|
||||
// Next, if the region is specified, check if there is a functionObject
|
||||
// dictionary file in the global system directory
|
||||
if (region != word::null)
|
||||
{
|
||||
const fileName dictFile
|
||||
(
|
||||
stringOps::expand("$FOAM_CASE")/"system"/funcName
|
||||
);
|
||||
|
||||
if (isFile(dictFile))
|
||||
{
|
||||
return dictFile;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, check etc directories
|
||||
{
|
||||
const fileNameList etcDirs(findEtcDirs(functionObjectDictPath));
|
||||
|
||||
forAll(etcDirs, i)
|
||||
{
|
||||
const fileName dictFile(search(funcName, etcDirs[i]));
|
||||
|
||||
if (!dictFile.empty())
|
||||
{
|
||||
return dictFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fileName::null;
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::Tuple2<Foam::word, Foam::string>>
|
||||
Foam::functionObjectList::unsetEntries(const dictionary& funcDict)
|
||||
{
|
||||
const wordRe unsetPattern("<.*>");
|
||||
unsetPattern.compile();
|
||||
|
||||
List<Tuple2<word, string>> unsetArgs;
|
||||
|
||||
forAllConstIter(IDLList<entry>, funcDict, iter)
|
||||
{
|
||||
if (iter().isStream())
|
||||
{
|
||||
ITstream& its = iter().stream();
|
||||
OStringStream oss;
|
||||
bool isUnset = false;
|
||||
|
||||
forAll(its, i)
|
||||
{
|
||||
oss << its[i];
|
||||
if (its[i].isWord() && unsetPattern.match(its[i].wordToken()))
|
||||
{
|
||||
isUnset = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isUnset)
|
||||
{
|
||||
unsetArgs.append
|
||||
(
|
||||
Tuple2<word, string>
|
||||
(
|
||||
iter().keyword(),
|
||||
oss.str()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Tuple2<word, string>> subUnsetArgs =
|
||||
unsetEntries(iter().dict());
|
||||
|
||||
forAll(subUnsetArgs, i)
|
||||
{
|
||||
unsetArgs.append
|
||||
(
|
||||
Tuple2<word, string>
|
||||
(
|
||||
iter().keyword() + '/' + subUnsetArgs[i].first(),
|
||||
subUnsetArgs[i].second()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return unsetArgs;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjectList::readFunctionObject
|
||||
(
|
||||
const string& funcArgs,
|
||||
dictionary& functionsDict,
|
||||
const Pair<string>& contextTypeAndValue,
|
||||
const word& region
|
||||
)
|
||||
{
|
||||
word funcType;
|
||||
wordReList args;
|
||||
List<Tuple2<word, string>> namedArgs;
|
||||
|
||||
dictArgList(funcArgs, funcType, args, namedArgs);
|
||||
|
||||
// Search for the functionObject dictionary
|
||||
fileName path = findDict(funcType, region);
|
||||
|
||||
if (path == fileName::null)
|
||||
{
|
||||
if (funcType == word::null)
|
||||
{
|
||||
FatalIOErrorInFunction(functionsDict)
|
||||
<< "functionObject configuration file name not specified"
|
||||
<< nl << nl
|
||||
<< "Available configured functionObjects:"
|
||||
<< list()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(functionsDict)
|
||||
<< "Cannot find functionObject configuration file "
|
||||
<< funcType << nl << nl
|
||||
<< "Available configured functionObjects:"
|
||||
<< list()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the functionObject dictionary
|
||||
// IFstream fileStream(path);
|
||||
autoPtr<ISstream> fileStreamPtr(fileHandler().NewIFstream(path));
|
||||
ISstream& fileStream = fileStreamPtr();
|
||||
|
||||
// Delay processing the functionEntries
|
||||
// until after the function argument entries have been added
|
||||
entry::disableFunctionEntries = true;
|
||||
dictionary funcsDict(funcType, functionsDict, fileStream);
|
||||
entry::disableFunctionEntries = false;
|
||||
|
||||
dictionary* funcDictPtr = &funcsDict;
|
||||
|
||||
if (funcsDict.found(funcType) && funcsDict.isDict(funcType))
|
||||
{
|
||||
funcDictPtr = &funcsDict.subDict(funcType);
|
||||
}
|
||||
|
||||
dictionary& funcDict = *funcDictPtr;
|
||||
|
||||
// Store the funcDict as read for error reporting context
|
||||
const dictionary funcDict0(funcDict);
|
||||
|
||||
// Insert the 'field' and/or 'fields' and 'objects' entries corresponding
|
||||
// to both the arguments and the named arguments
|
||||
DynamicList<wordAndDictionary> fieldArgs;
|
||||
forAll(args, i)
|
||||
{
|
||||
fieldArgs.append(wordAndDictionary(args[i], dictionary::null));
|
||||
}
|
||||
forAll(namedArgs, i)
|
||||
{
|
||||
if (namedArgs[i].first() == "field")
|
||||
{
|
||||
IStringStream iss(namedArgs[i].second());
|
||||
fieldArgs.append(wordAndDictionary(iss));
|
||||
}
|
||||
if
|
||||
(
|
||||
namedArgs[i].first() == "fields"
|
||||
|| namedArgs[i].first() == "objects"
|
||||
)
|
||||
{
|
||||
IStringStream iss(namedArgs[i].second());
|
||||
fieldArgs.append(List<wordAndDictionary>(iss));
|
||||
}
|
||||
}
|
||||
if (fieldArgs.size() == 1)
|
||||
{
|
||||
funcDict.set("field", fieldArgs[0].first());
|
||||
funcDict.merge(fieldArgs[0].second());
|
||||
}
|
||||
if (fieldArgs.size() >= 1)
|
||||
{
|
||||
funcDict.set("fields", fieldArgs);
|
||||
funcDict.set("objects", fieldArgs);
|
||||
}
|
||||
|
||||
// Insert non-field arguments
|
||||
forAll(namedArgs, i)
|
||||
{
|
||||
if
|
||||
(
|
||||
namedArgs[i].first() != "field"
|
||||
&& namedArgs[i].first() != "fields"
|
||||
&& namedArgs[i].first() != "objects"
|
||||
)
|
||||
{
|
||||
const Pair<word> dAk(dictAndKeyword(namedArgs[i].first()));
|
||||
dictionary& subDict(funcDict.scopedDict(dAk.first()));
|
||||
IStringStream entryStream
|
||||
(
|
||||
dAk.second() + ' ' + namedArgs[i].second() + ';'
|
||||
);
|
||||
subDict.set(entry::New(entryStream).ptr());
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the region name if specified
|
||||
if (region != word::null)
|
||||
{
|
||||
funcDict.set("region", region);
|
||||
}
|
||||
|
||||
// Set the name of the function entry to that specified by the optional
|
||||
// funcName argument otherwise automatically generate a unique name
|
||||
// from the function type and arguments
|
||||
const word funcName
|
||||
(
|
||||
funcDict.lookupOrDefault("funcName", string::validate<word>(funcArgs))
|
||||
);
|
||||
|
||||
// Check for anything in the configuration that has not been set
|
||||
List<Tuple2<word, string>> unsetArgs = unsetEntries(funcDict);
|
||||
bool hasUnsetError = false;
|
||||
forAll(unsetArgs, i)
|
||||
{
|
||||
if
|
||||
(
|
||||
unsetArgs[i].first() != "fields"
|
||||
&& unsetArgs[i].first() != "objects"
|
||||
)
|
||||
{
|
||||
hasUnsetError = true;
|
||||
}
|
||||
}
|
||||
if (!hasUnsetError)
|
||||
{
|
||||
forAll(unsetArgs, i)
|
||||
{
|
||||
funcDict.set(unsetArgs[i].first(), wordList());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(funcDict0)
|
||||
<< nl;
|
||||
|
||||
forAll(unsetArgs, i)
|
||||
{
|
||||
FatalIOErrorInFunction(funcDict0)
|
||||
<< "Essential value for keyword '" << unsetArgs[i].first()
|
||||
<< "' not set" << nl;
|
||||
}
|
||||
|
||||
FatalIOErrorInFunction(funcDict0)
|
||||
<< nl << "In function entry:" << nl
|
||||
<< " " << funcArgs.c_str() << nl
|
||||
<< nl << "In " << contextTypeAndValue.first().c_str() << ":" << nl
|
||||
<< " " << contextTypeAndValue.second().c_str() << nl;
|
||||
|
||||
word funcType;
|
||||
wordReList args;
|
||||
List<Tuple2<word, string>> namedArgs;
|
||||
dictArgList(funcArgs, funcType, args, namedArgs);
|
||||
|
||||
string argList;
|
||||
forAll(args, i)
|
||||
{
|
||||
args[i].strip(" \n");
|
||||
argList += (argList.size() ? ", " : "") + args[i];
|
||||
}
|
||||
forAll(namedArgs, i)
|
||||
{
|
||||
namedArgs[i].second().strip(" \n");
|
||||
argList +=
|
||||
(argList.size() ? ", " : "")
|
||||
+ namedArgs[i].first() + " = " + namedArgs[i].second();
|
||||
}
|
||||
forAll(unsetArgs, i)
|
||||
{
|
||||
unsetArgs[i].second().strip(" \n");
|
||||
argList +=
|
||||
(argList.size() ? ", " : "")
|
||||
+ unsetArgs[i].first() + " = " + unsetArgs[i].second();
|
||||
}
|
||||
|
||||
FatalIOErrorInFunction(funcDict0)
|
||||
<< nl << "The function entry should be:" << nl
|
||||
<< " " << funcType << '(' << argList.c_str() << ')'
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Re-parse the funcDict to execute the functionEntries
|
||||
// now that the function argument entries have been added
|
||||
dictionary funcArgsDict;
|
||||
funcArgsDict.add(funcName, funcDict);
|
||||
{
|
||||
OStringStream os;
|
||||
funcArgsDict.write(os);
|
||||
funcArgsDict = dictionary
|
||||
(
|
||||
funcType,
|
||||
functionsDict,
|
||||
IStringStream(os.str())()
|
||||
);
|
||||
}
|
||||
|
||||
// Merge this functionObject dictionary into functionsDict
|
||||
functionsDict.merge(funcArgsDict);
|
||||
functionsDict.subDict(funcName).name() = funcDict.name();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjectList::functionObjectList
|
||||
@ -538,10 +142,11 @@ Foam::autoPtr<Foam::functionObjectList> Foam::functionObjectList::New
|
||||
|
||||
if (args.optionFound("func"))
|
||||
{
|
||||
readFunctionObject
|
||||
readConfigFile
|
||||
(
|
||||
args["func"],
|
||||
functionsDict,
|
||||
functionEntries::includeFuncEntry::functionObjectDictPath,
|
||||
{"command", args.commandLine()},
|
||||
region
|
||||
);
|
||||
@ -553,10 +158,11 @@ Foam::autoPtr<Foam::functionObjectList> Foam::functionObjectList::New
|
||||
|
||||
forAll(funcs, i)
|
||||
{
|
||||
readFunctionObject
|
||||
readConfigFile
|
||||
(
|
||||
funcs[i],
|
||||
functionsDict,
|
||||
functionEntries::includeFuncEntry::functionObjectDictPath,
|
||||
{"command", args.commandLine()},
|
||||
region
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user