foamDictionary: Improved parallel operation

When running in parallel the decomposed dictionary files are read from the
case directory in either un-collated or collated format and changed dictionaries
written in the form specified by the selected fileHandler.

The instance directory of the dictionary file is obtained from the file path
argument, e.g.

    mpirun -np 4 foamDictionary 0.5/U \
        -entry boundaryField.movingWall.value \
        -set "uniform (2 0 0)" -parallel
This commit is contained in:
Henry Weller
2019-08-07 16:22:15 +01:00
parent 2bd1913fd2
commit 0dbeb66ba9

View File

@ -27,11 +27,14 @@ Application
Description Description
Interrogates and manipulates dictionaries. Interrogates and manipulates dictionaries.
Supports parallel operation for decomposed dictionary files associated with
a case. These may be mesh or field files or any other decomposed
dictionaries.
Usage Usage
\b foamDictionary [OPTION] dictionary \b foamDictionary [OPTION] dictionary
- \par -case \<dir\> - \par -case \<dir\>
Select a case directory, Select a case directory
required to process decomposed fields in parallel cases
- \par -parallel - \par -parallel
Specify case as a parallel job Specify case as a parallel job
@ -105,7 +108,7 @@ Usage
- Change bc parameter in parallel: - Change bc parameter in parallel:
\verbatim \verbatim
mpirun -np 4 foamDictionary -case . 0/U \ mpirun -np 4 foamDictionary 0.5/U \
-entry boundaryField.movingWall.value \ -entry boundaryField.movingWall.value \
-set "uniform (2 0 0)" -parallel -set "uniform (2 0 0)" -parallel
\endverbatim \endverbatim
@ -316,7 +319,9 @@ int main(int argc, char *argv[])
writeInfoHeader = false; writeInfoHeader = false;
argList::addNote("manipulates dictionaries"); argList::addNote("manipulates dictionaries");
argList::validArgs.append("dictionary file"); argList::validArgs.append("dictionary file");
argList::addBoolOption("keywords", "list keywords"); argList::addBoolOption("keywords", "list keywords");
argList::addOption("entry", "name", "report/select the named entry"); argList::addOption("entry", "name", "report/select the named entry");
argList::addBoolOption argList::addBoolOption
@ -389,7 +394,7 @@ int main(int argc, char *argv[])
entry::disableFunctionEntries = true; entry::disableFunctionEntries = true;
} }
const fileName dictFileName(args[1]); const fileName dictPath(args[1]);
Time* runTimePtr = nullptr; Time* runTimePtr = nullptr;
localIOdictionary* localDictPtr = nullptr; localIOdictionary* localDictPtr = nullptr;
@ -397,9 +402,9 @@ int main(int argc, char *argv[])
dictionary* dictPtr = nullptr; dictionary* dictPtr = nullptr;
IOstream::streamFormat dictFormat = IOstream::ASCII; IOstream::streamFormat dictFormat = IOstream::ASCII;
// If the case option is specified read the dictionary as a // When running in parallel read the dictionary as a case localIOdictionary
// case localIOdictionary supporting parallel operation and file handlers // supporting file handlers
if (args.optionFound("case")) if (Pstream::parRun())
{ {
if (!args.checkRootCase()) if (!args.checkRootCase())
{ {
@ -408,6 +413,28 @@ int main(int argc, char *argv[])
runTimePtr = new Time(Time::controlDictName, args); runTimePtr = new Time(Time::controlDictName, args);
const wordList dictPathComponents(dictPath.components());
if (dictPathComponents.size() == 1)
{
FatalErrorInFunction
<< "File name " << dictPath
<< " does not contain an instance path needed in parallel"
<< exit(FatalError, 1);
}
const word instance = dictPathComponents[0];
const fileName dictFileName
(
SubList<word>(dictPathComponents, dictPathComponents.size() - 1, 1)
);
scalar time;
if (readScalar(instance.c_str(), time))
{
runTimePtr->setTime(time, 0);
}
const word oldTypeName = localIOdictionary::typeName; const word oldTypeName = localIOdictionary::typeName;
const_cast<word&>(localIOdictionary::typeName) = word::null; const_cast<word&>(localIOdictionary::typeName) = word::null;
@ -416,6 +443,7 @@ int main(int argc, char *argv[])
IOobject IOobject
( (
dictFileName, dictFileName,
instance,
*runTimePtr, *runTimePtr,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -428,7 +456,7 @@ int main(int argc, char *argv[])
else else
{ {
dictPtr = new dictionary; dictPtr = new dictionary;
dictFormat = readDict(*dictPtr, dictFileName); dictFormat = readDict(*dictPtr, dictPath);
} }
dictionary& dict = localDictPtr ? *localDictPtr : *dictPtr; dictionary& dict = localDictPtr ? *localDictPtr : *dictPtr;
@ -442,7 +470,7 @@ int main(int argc, char *argv[])
else if (args.optionFound("expand")) else if (args.optionFound("expand"))
{ {
IOobject::writeBanner(Info) IOobject::writeBanner(Info)
<<"//\n// " << dictFileName << "\n//\n"; <<"//\n// " << dictPath << "\n//\n";
dict.dictionary::write(Info, false); dict.dictionary::write(Info, false);
IOobject::writeDivider(Info); IOobject::writeDivider(Info);
@ -656,7 +684,7 @@ int main(int argc, char *argv[])
} }
else if (dictPtr) else if (dictPtr)
{ {
OFstream os(dictFileName, dictFormat); OFstream os(dictPath, dictFormat);
IOobject::writeBanner(os); IOobject::writeBanner(os);
dictPtr->write(os, false); dictPtr->write(os, false);
IOobject::writeEndDivider(os); IOobject::writeEndDivider(os);