ENH: add -verbose support into argList

- similar to -dry-run handling, can be interrogated from argList,
  which makes it simpler to add into utilities.

- support multiple uses of -dry-run and -verbose to increase the
  level. For example, could have

    someApplication -verbose -verbose

 and inside of the application:

    if (args.verbose() > 2) ...

BUG: error with empty distributed roots specification (fixes #2196)

- previously used the size of distributed roots to transmit if the
  case was running in distributed mode, but this behaves rather poorly
  with bad input. Specifically, the following questionable setup:

      distributed true;
      roots ( /*none*/ );

  Now transmit the ParRunControl distributed() value instead,
  and also emit a gentle warning for the user:

      WARNING: running distributed but did not specify roots!
This commit is contained in:
Mark Olesen 2021-11-05 21:02:21 +01:00
parent c45c649d15
commit 5a121119e6
16 changed files with 249 additions and 135 deletions

View File

@ -121,6 +121,9 @@ int main(int argc, char *argv[])
argList::addArgument("label"); argList::addArgument("label");
argList::noMandatoryArgs(); argList::noMandatoryArgs();
argList::addDryRunOption("Just for testing");
argList::addVerboseOption("Increase verbosity");
#include "setRootCase.H" #include "setRootCase.H"
Pout<< "command-line (" Pout<< "command-line ("
@ -133,6 +136,10 @@ int main(int argc, char *argv[])
<< "globalPath: " << args.globalPath() << nl << "globalPath: " << args.globalPath() << nl
<< nl; << nl;
Pout<< "dry-run: " << args.dryRun()
<< " verbose: " << args.verbose() << nl;
if (args.found("relative")) if (args.found("relative"))
{ {
Pout<< "input path: " << args["relative"] << nl Pout<< "input path: " << args["relative"] << nl

View File

@ -57,9 +57,8 @@ int main(int argc, char *argv[])
#include "addAllRegionOptions.H" #include "addAllRegionOptions.H"
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"more information about decomposition" "more information about decomposition"
); );
@ -71,7 +70,6 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
const auto decompFile = args.get<fileName>(1); const auto decompFile = args.get<fileName>(1);
const bool verbose = args.found("verbose");
// Set time from database // Set time from database
#include "createTime.H" #include "createTime.H"
@ -146,7 +144,7 @@ int main(int argc, char *argv[])
nDomains nDomains
); );
if (verbose) if (args.verbose())
{ {
info.printDetails(Info); info.printDetails(Info);
Info<< nl; Info<< nl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd. Copyright (C) 2017-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -56,7 +56,7 @@ int main(int argc, char *argv[])
argList::noParallel(); argList::noParallel();
argList::noFunctionObjects(); argList::noFunctionObjects();
argList::addArgument("start size .. startN sizeN"); argList::addArgument("start size .. startN sizeN");
argList::addOption("verbose"); argList::addVerbose("enable labelRange::debug");
argList::addNote argList::addNote
( (
"The default is to add ranges, use 'add' and 'del' to toggle\n\n" "The default is to add ranges, use 'add' and 'del' to toggle\n\n"
@ -65,7 +65,7 @@ int main(int argc, char *argv[])
argList args(argc, argv, false, true); argList args(argc, argv, false, true);
if (args.found("verbose")) if (args.verbose())
{ {
labelRange::debug = 1; labelRange::debug = 1;
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd. Copyright (C) 2019-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -124,16 +124,13 @@ int main(int argc, char *argv[])
"(vector angle)", "(vector angle)",
"Rotate about the <vector> by <angle> degrees - eg, '((1 0 0) 45)'" "Rotate about the <vector> by <angle> degrees - eg, '((1 0 0) 45)'"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose", "Report euler angles"
"Additional verbosity"
); );
argList args(argc, argv); argList args(argc, argv);
const bool verbose = args.found("verbose");
vector rotVector; vector rotVector;
@ -327,7 +324,7 @@ int main(int argc, char *argv[])
tensor rotQ(quaternion(order, angles).R()); tensor rotQ(quaternion(order, angles).R());
tensor rotE(euler::rotation(order, angles, false)); tensor rotE(euler::rotation(order, angles, false));
if (verbose) if (args.verbose())
{ {
Info<< "euler " << orderName << angles << nl; Info<< "euler " << orderName << angles << nl;
printRotation(rotE); printRotation(rotE);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd. Copyright (C) 2020-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,18 +50,16 @@ int main(int argc, char *argv[])
argList::addArgument("string .. stringN"); argList::addArgument("string .. stringN");
argList::addOption("file", "name"); argList::addOption("file", "name");
argList::addOption("repeat", "count"); argList::addOption("repeat", "count");
argList::addBoolOption("verbose", "report for each repeat"); argList::addVerboseOption("report each repeat");
argList args(argc, argv, false, true); argList args(argc, argv, false, true);
const label repeat = args.getOrDefault<label>("repeat", 1); const label repeat = args.getOrDefault<label>("repeat", 1);
const bool optVerbose = args.found("verbose");
cpuTime timer; cpuTime timer;
for (label count = 0; count < repeat; ++count) for (label count = 0; count < repeat; ++count)
{ {
const bool verbose = (optVerbose || count == 0); const bool verbose = (args.verbose() || count == 0);
for (label argI=1; argI < args.size(); ++argI) for (label argI=1; argI < args.size(); ++argI)
{ {
@ -120,7 +118,7 @@ int main(int argc, char *argv[])
for (label count = 0; count < repeat; ++count) for (label count = 0; count < repeat; ++count)
{ {
const bool verbose = (optVerbose || count == 0); const bool verbose = (args.verbose() || count == 0);
label nTokens = 0; label nTokens = 0;
if (count) if (count)

View File

@ -78,9 +78,8 @@ int main(int argc, char *argv[])
"detail", "detail",
"Additional detail" "Additional detail"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity" "Additional verbosity"
); );
@ -94,7 +93,6 @@ int main(int argc, char *argv[])
const bool testOr = args.found("or"); const bool testOr = args.found("or");
const bool detail = args.found("detail"); const bool detail = args.found("detail");
const bool verbose = args.found("verbose");
label ngood = 0; label ngood = 0;
label nbad = 0; label nbad = 0;
@ -127,7 +125,7 @@ int main(int argc, char *argv[])
{ {
++ngood; ++ngood;
if (verbose) if (args.verbose())
{ {
const word addr(Foam::name(ptr)); const word addr(Foam::name(ptr));

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd. Copyright (C) 2016-2021 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -101,9 +101,8 @@ int main(int argc, char *argv[])
"rm", "rm",
"Remove selected time directories" "Remove selected time directories"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Report progress of -rm option" "Report progress of -rm option"
); );
profiling::disable(); // Disable profiling (and its output) profiling::disable(); // Disable profiling (and its output)
@ -111,7 +110,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
const bool removeFiles(args.found("rm")); const bool removeFiles(args.found("rm"));
bool verbose(args.found("verbose")); bool verbose(args.verbose());
// Get times list from the master processor and subset based on // Get times list from the master processor and subset based on

View File

@ -232,9 +232,8 @@ int main(int argc, char *argv[])
( (
"Report action without moving/renaming" "Report action without moving/renaming"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity" "Additional verbosity"
); );
@ -247,7 +246,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
dryrun = args.dryRun(); dryrun = args.dryRun();
verbose = args.found("verbose"); verbose = args.verbose();
// Construct time // Construct time

View File

@ -330,9 +330,8 @@ int main(int argc, char *argv[])
"Test without writing the decomposition. " "Test without writing the decomposition. "
"Changes -cellDist to only write VTK output." "Changes -cellDist to only write VTK output."
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity" "Additional verbosity"
); );
argList::addOption argList::addOption
@ -409,9 +408,7 @@ int main(int argc, char *argv[])
#include "setRootCase.H" #include "setRootCase.H"
const bool dryrun = args.dryRun();
const bool writeCellDist = args.found("cellDist"); const bool writeCellDist = args.found("cellDist");
const bool verbose = args.found("verbose");
// Most of these are ignored for dry-run (not triggered anywhere) // Most of these are ignored for dry-run (not triggered anywhere)
const bool copyZero = args.found("copyZero"); const bool copyZero = args.found("copyZero");
@ -432,7 +429,7 @@ int main(int argc, char *argv[])
// Allow override of time (unless dry-run) // Allow override of time (unless dry-run)
instantList times; instantList times;
if (dryrun) if (args.dryRun())
{ {
Info<< "\ndry-run: ignoring -copy*, -fields, -force, time selection" Info<< "\ndry-run: ignoring -copy*, -fields, -force, time selection"
<< nl; << nl;
@ -477,7 +474,7 @@ int main(int argc, char *argv[])
regionName == polyMesh::defaultRegion ? word::null : regionName regionName == polyMesh::defaultRegion ? word::null : regionName
); );
if (dryrun) if (args.dryRun())
{ {
Info<< "dry-run: decomposing mesh " << regionName << nl << nl Info<< "dry-run: decomposing mesh " << regionName << nl << nl
<< "Create mesh..." << flush; << "Create mesh..." << flush;
@ -498,7 +495,7 @@ int main(int argc, char *argv[])
args.getOrDefault<word>("method", word::null) args.getOrDefault<word>("method", word::null)
); );
decompTest.execute(writeCellDist, verbose); decompTest.execute(writeCellDist, args.verbose());
continue; continue;
} }

View File

@ -72,24 +72,19 @@ int main(int argc, char *argv[])
"Suppress calculation/display of point interpolators" "Suppress calculation/display of point interpolators"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity" "Additional verbosity"
); );
#include "addRegionOption.H" #include "addRegionOption.H"
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H"
const bool noInterpolate = args.found("no-interpolate"); const bool noInterpolate = args.found("no-interpolate");
// const bool verbose = args.found("verbose");
args.readIfPresent("visual-length", lumpedPointState::visLength); args.readIfPresent("visual-length", lumpedPointState::visLength);
#include "createTime.H"
if (args.dryRun()) if (args.dryRun())
{ {
// Create without a mesh // Create without a mesh

View File

@ -553,9 +553,8 @@ int main(int argc, char *argv[])
( (
"Evaluate but do not write" "Evaluate but do not write"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity", "Additional verbosity",
true // Advanced option true // Advanced option
); );
@ -662,9 +661,6 @@ int main(int argc, char *argv[])
#include "createTime.H" #include "createTime.H"
const bool dryrun = args.dryRun();
const bool verbose = args.found("verbose");
const word dictName("setExprFieldsDict"); const word dictName("setExprFieldsDict");
instantList times = timeSelector::select0(runTime, args); instantList times = timeSelector::select0(runTime, args);
@ -797,7 +793,7 @@ int main(int argc, char *argv[])
setExprFieldsControl ctrl; setExprFieldsControl ctrl;
ctrl.dryRun = dryrun; ctrl.dryRun = args.dryRun();
ctrl.debugParsing = args.found("debug-parser"); ctrl.debugParsing = args.found("debug-parser");
ctrl.cacheVariables = !args.found("no-variable-caching"); ctrl.cacheVariables = !args.found("no-variable-caching");
@ -869,7 +865,7 @@ int main(int argc, char *argv[])
setExprFieldsControl ctrl; setExprFieldsControl ctrl;
ctrl.dryRun = dryrun; ctrl.dryRun = args.dryRun();
ctrl.debugParsing = args.found("debug-parser"); ctrl.debugParsing = args.found("debug-parser");
ctrl.cacheVariables = !args.found("no-variable-caching"); ctrl.cacheVariables = !args.found("no-variable-caching");
@ -934,7 +930,7 @@ int main(int argc, char *argv[])
ctrl.useDimensions = bool(dimPtr); ctrl.useDimensions = bool(dimPtr);
} }
if (verbose && !timei) if (args.verbose() && !timei)
{ {
// Report once // Report once
Info<< "Processing" << dict << nl; Info<< "Processing" << dict << nl;

View File

@ -308,9 +308,8 @@ int main(int argc, char *argv[])
"Split surface along non-manifold edges " "Split surface along non-manifold edges "
"(default split is fully disconnected)" "(default split is fully disconnected)"
); );
argList::addBoolOption argList::addVerboseOption
( (
"verbose",
"Additional verbosity" "Additional verbosity"
); );
argList::addBoolOption argList::addBoolOption

View File

@ -28,6 +28,7 @@ License
#include "argList.H" #include "argList.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "Switch.H"
#include "clock.H" #include "clock.H"
#include "dictionary.H" #include "dictionary.H"
#include "IOobject.H" #include "IOobject.H"
@ -110,7 +111,7 @@ Foam::argList::initValidTables::initValidTables()
( (
"opt-switch", "opt-switch",
"name=val", "name=val",
"Specify the value of a registered optimisation switch (int/bool)." "Specify the value of a registered optimisation switch."
" Default is 1 if the value is omitted." " Default is 1 if the value is omitted."
" (Can be used multiple times)", " (Can be used multiple times)",
true // advanced option true // advanced option
@ -326,7 +327,7 @@ void Foam::argList::addBoolOption
bool advanced bool advanced
) )
{ {
addOption(optName, "", usage, advanced); argList::addOption(optName, "", usage, advanced);
} }
@ -455,7 +456,17 @@ void Foam::argList::addDryRunOption
bool advanced bool advanced
) )
{ {
addOption("dry-run", "", usage, advanced); argList::addBoolOption("dry-run", usage, advanced);
}
void Foam::argList::addVerboseOption
(
const string& usage,
bool advanced
)
{
argList::addBoolOption("verbose", usage, advanced);
} }
@ -469,7 +480,7 @@ void Foam::argList::noFunctionObjects(bool addWithOption)
if (addWithOption) if (addWithOption)
{ {
addBoolOption argList::addBoolOption
( (
"withFunctionObjects", "withFunctionObjects",
"Execute functionObjects", "Execute functionObjects",
@ -487,7 +498,7 @@ void Foam::argList::noJobInfo()
void Foam::argList::noLibs() void Foam::argList::noLibs()
{ {
addBoolOption argList::addBoolOption
( (
"no-libs", "no-libs",
"Disable use of the controlDict libs entry", "Disable use of the controlDict libs entry",
@ -768,11 +779,6 @@ void Foam::argList::setCasePaths()
// Executable name, unless already present in the environment // Executable name, unless already present in the environment
setEnv("FOAM_EXECUTABLE", executable_, false); setEnv("FOAM_EXECUTABLE", executable_, false);
if (validOptions.found("dry-run") && options_.found("dry-run"))
{
runControl_.dryRun(true);
}
} }
@ -847,6 +853,9 @@ Foam::argList::argList
// Set executable name immediately - useful when emitting errors. // Set executable name immediately - useful when emitting errors.
executable_ = fileName(args_[0]).name(); executable_ = fileName(args_[0]).name();
// Count -dry-run and -verbose switches
int numDryRun = 0, numVerbose = 0;
// Check arguments and options, argv[0] was already handled // Check arguments and options, argv[0] was already handled
int nArgs = 1; int nArgs = 1;
for (int argi = 1; argi < args_.size(); ++argi) for (int argi = 1; argi < args_.size(); ++argi)
@ -862,15 +871,31 @@ Foam::argList::argList
{ {
Warning Warning
<< "Ignoring lone '-' on the command-line" << endl; << "Ignoring lone '-' on the command-line" << endl;
continue;
} }
else if
// Option known and expects an argument?
// - use Switch for a tri-state
// True : known option, expects a parameter
// False : known option, no parameter
// bad() : unknown option
Switch wantArg(Switch::INVALID);
auto optIter = validOptions.cfind(optName);
if
( (
validOptions.lookup(optName, "").size() optIter.found()
|| validParOptions.lookup(optName, "").size() || (optIter = validParOptions.cfind(optName)).found()
) )
{ {
// If the option is known to require an argument, wantArg = !optIter.val().empty();
// get it or emit a FatalError. }
if (wantArg)
{
// Known option and expects a parameter
// - get it or emit a FatalError.
++argi; ++argi;
if (argi >= args_.size()) if (argi >= args_.size())
@ -883,12 +908,16 @@ Foam::argList::argList
<< "See '" << executable_ << " -help' for usage" << "See '" << executable_ << " -help' for usage"
<< nl << nl; << nl << nl;
Pstream::exit(1); // works for serial and parallel Pstream::exit(1); // works for serial and parallel
} }
commandLine_ += ' '; commandLine_ += ' ';
commandLine_ += args_[argi]; commandLine_ += args_[argi];
//
// Special handling of these options
//
if (strcmp(optName, "lib") == 0) if (strcmp(optName, "lib") == 0)
{ {
// The '-lib' option: // The '-lib' option:
@ -921,7 +950,7 @@ Foam::argList::argList
} }
else else
{ {
// Regular option: // Regular option (with a parameter):
// Duplicates handled by using the last -option specified // Duplicates handled by using the last -option specified
options_.set(optName, args_[argi]); options_.set(optName, args_[argi]);
} }
@ -932,6 +961,19 @@ Foam::argList::argList
// registered as existing. // registered as existing.
options_.insert(optName, ""); options_.insert(optName, "");
// Special increment handling for some known flags
if (wantArg.good())
{
if (strcmp(optName, "dry-run") == 0)
{
++numDryRun;
}
else if (strcmp(optName, "verbose") == 0)
{
++numVerbose;
}
}
} }
} }
else else
@ -944,6 +986,10 @@ Foam::argList::argList
} }
} }
// Commit number of -dry-run and -verbose flag occurrences
runControl_.dryRun(numDryRun);
runControl_.verbose(numVerbose);
args_.resize(nArgs); args_.resize(nArgs);
parse(checkArgs, checkOpts, initialise); parse(checkArgs, checkOpts, initialise);
@ -1043,7 +1089,7 @@ void Foam::argList::parse
foamVersion::printBuildInfo(Info.stdStream(), false); foamVersion::printBuildInfo(Info.stdStream(), false);
FatalError.write(Info, false); FatalError.write(Info, false);
Pstream::exit(1); // works for serial and parallel Pstream::exit(1); // works for serial and parallel
} }
if (initialise) if (initialise)
@ -1227,7 +1273,13 @@ void Foam::argList::parse
{ {
source = "-roots"; source = "-roots";
runControl_.distributed(true); runControl_.distributed(true);
if (roots.size() != 1) if (roots.empty())
{
FatalErrorInFunction
<< "The -roots option must contain values"
<< exit(FatalError);
}
if (roots.size() > 1)
{ {
dictNProcs = roots.size()+1; dictNProcs = roots.size()+1;
} }
@ -1235,17 +1287,27 @@ void Foam::argList::parse
else if (options_.found("hostRoots")) else if (options_.found("hostRoots"))
{ {
source = "-hostRoots"; source = "-hostRoots";
roots.resize(Pstream::nProcs()-1, fileName::null); runControl_.distributed(true);
ITstream is(this->lookup("hostRoots")); ITstream is(this->lookup("hostRoots"));
List<Tuple2<wordRe, fileName>> hostRoots(is); List<Tuple2<wordRe, fileName>> hostRoots(is);
checkITstream(is, "hostRoots"); checkITstream(is, "hostRoots");
if (hostRoots.empty())
{
FatalErrorInFunction
<< "The -hostRoots option must contain values"
<< exit(FatalError);
}
// Match machine names to roots
roots.resize(Pstream::nProcs()-1, fileName::null);
for (const auto& hostRoot : hostRoots) for (const auto& hostRoot : hostRoots)
{ {
labelList matched labelList matched
( (
findStrings(hostRoot.first(), hostMachine) findMatchingStrings(hostRoot.first(), hostMachine)
); );
for (const label matchi : matched) for (const label matchi : matched)
{ {
@ -1275,7 +1337,7 @@ void Foam::argList::parse
} }
} }
if (roots.size() != 1) if (roots.size() > 1)
{ {
dictNProcs = roots.size()+1; dictNProcs = roots.size()+1;
} }
@ -1312,6 +1374,13 @@ void Foam::argList::parse
nDomainsMandatory = true; nDomainsMandatory = true;
runControl_.distributed(true); runControl_.distributed(true);
decompDict.readEntry("roots", roots); decompDict.readEntry("roots", roots);
if (roots.empty())
{
DetailInfo
<< "WARNING: running distributed"
<< " but did not specify roots!" << nl;
}
} }
// Get numberOfSubdomains if it exists. // Get numberOfSubdomains if it exists.
@ -1330,7 +1399,7 @@ void Foam::argList::parse
{ {
// Optional if using default location // Optional if using default location
DetailInfo DetailInfo
<< "Warning: running without decomposeParDict " << "WARNING: running without decomposeParDict "
<< this->relativePath(source) << nl; << this->relativePath(source) << nl;
} }
else else
@ -1415,8 +1484,13 @@ void Foam::argList::parse
{ {
options_.set("case", roots[subproci-1]/globalCase_); options_.set("case", roots[subproci-1]/globalCase_);
OPstream toSubproc(Pstream::commsTypes::scheduled, subproci); OPstream toProc(Pstream::commsTypes::scheduled, subproci);
toSubproc << args_ << options_ << roots.size(); toProc
<< args_ << options_
<< runControl_.distributed()
<< label(runControl_.dryRun())
<< label(runControl_.verbose());
} }
options_.erase("case"); options_.erase("case");
@ -1463,24 +1537,34 @@ void Foam::argList::parse
// Distribute the master's argument list (unaltered) // Distribute the master's argument list (unaltered)
for (const int subproci : Pstream::subProcs()) for (const int subproci : Pstream::subProcs())
{ {
OPstream toSubproc(Pstream::commsTypes::scheduled, subproci); OPstream toProc(Pstream::commsTypes::scheduled, subproci);
toSubproc << args_ << options_ << roots.size(); toProc
<< args_ << options_
<< runControl_.distributed()
<< label(runControl_.dryRun())
<< label(runControl_.verbose());
} }
} }
} }
else else
{ {
// Collect the master's argument list // Collect the master's argument list
label nroots; bool isDistributed;
label numDryRun, numVerbose;
IPstream fromMaster IPstream fromMaster
( (
Pstream::commsTypes::scheduled, Pstream::commsTypes::scheduled,
Pstream::masterNo() Pstream::masterNo()
); );
fromMaster >> args_ >> options_ >> nroots; fromMaster
>> args_ >> options_
>> isDistributed
>> numDryRun >> numVerbose;
runControl_.distributed(nroots); runControl_.distributed(isDistributed);
runControl_.dryRun(numDryRun);
runControl_.verbose(numVerbose);
// Establish rootPath_/globalCase_/case_ for sub-process // Establish rootPath_/globalCase_/case_ for sub-process
setCasePaths(); setCasePaths();

View File

@ -366,16 +366,23 @@ public:
//- Return the run control (parallel, dry-run etc) //- Return the run control (parallel, dry-run etc)
inline const ParRunControl& runControl() const noexcept; inline const ParRunControl& runControl() const noexcept;
//- Return the dryRun flag
inline bool dryRun() const noexcept;
//- Modify the dryRun flag
inline bool dryRun(const bool on) noexcept;
//- Return distributed flag //- Return distributed flag
//- (i.e. are rootPaths different on different machines) //- (i.e. are rootPaths different on different machines)
inline bool distributed() const noexcept; inline bool distributed() const noexcept;
//- Return the dry-run flag
inline int dryRun() const noexcept;
//- Modify the dry-run flag
inline int dryRun(const int level) noexcept;
//- Return the verbose flag
inline int verbose() const noexcept;
//- Modify the verbose flag
inline int verbose(const int level) noexcept;
//- Mutable access to the loaded dynamic libraries //- Mutable access to the loaded dynamic libraries
inline dlLibraryTable& libs() const noexcept; inline dlLibraryTable& libs() const noexcept;
@ -603,10 +610,17 @@ public:
// Queries the Foam::infoDetailLevel flag. // Queries the Foam::infoDetailLevel flag.
static bool bannerEnabled(); static bool bannerEnabled();
//- Add a 'dry-run' bool option to validOptions with usage information //- Enable a 'dry-run' bool option, with usage information
static void addDryRunOption static void addDryRunOption
( (
const string& usage, //! usage information (mandatory) const string& usage, //! usage information (expected)
bool advanced = false
);
//- Enable a 'verbose' bool option, with usage information
static void addVerboseOption
(
const string& usage, //! usage information (expected)
bool advanced = false bool advanced = false
); );

View File

@ -107,21 +107,33 @@ Foam::argList::runControl() const noexcept
} }
inline bool Foam::argList::dryRun() const noexcept inline bool Foam::argList::distributed() const noexcept
{
return runControl_.distributed();
}
inline int Foam::argList::dryRun() const noexcept
{ {
return runControl_.dryRun(); return runControl_.dryRun();
} }
inline bool Foam::argList::dryRun(const bool on) noexcept inline int Foam::argList::dryRun(const int level) noexcept
{ {
return runControl_.dryRun(on); return runControl_.dryRun(level);
} }
inline bool Foam::argList::distributed() const noexcept inline int Foam::argList::verbose() const noexcept
{ {
return runControl_.distributed(); return runControl_.verbose();
}
inline int Foam::argList::verbose(const int level) noexcept
{
return runControl_.verbose(level);
} }

View File

@ -54,7 +54,8 @@ namespace Foam
class ParRunControl class ParRunControl
{ {
bool dryRun_; int dryRun_;
int verbose_;
bool parallel_; bool parallel_;
bool distributed_; bool distributed_;
@ -63,7 +64,8 @@ public:
//- Default construct //- Default construct
ParRunControl() ParRunControl()
: :
dryRun_(false), dryRun_(0),
verbose_(0),
parallel_(false), parallel_(false),
distributed_(false) distributed_(false)
{} {}
@ -79,49 +81,68 @@ public:
} }
//- Initialize Pstream for a parallel run // Parallel Control
void runPar(int& argc, char**& argv, bool needsThread)
{ //- Initialize Pstream for a parallel run
if (!UPstream::init(argc, argv, needsThread)) void runPar(int& argc, char**& argv, bool needsThread)
{ {
Info<< "Failed to start parallel run" << endl; if (!UPstream::init(argc, argv, needsThread))
UPstream::exit(1); {
Info<< "Failed to start parallel run" << endl;
UPstream::exit(1);
}
parallel_ = true;
} }
parallel_ = true;
}
//- True if set as 'dry-run' //- True if this is a parallel run
bool dryRun() const noexcept bool parRun() const noexcept
{ {
return dryRun_; return parallel_;
} }
//- Set as 'dry-run', return old value //- True if this is a parallel run and uses distributed roots.
bool dryRun(bool on) noexcept bool distributed() const noexcept
{ {
bool old(dryRun_); return (parallel_ && distributed_);
dryRun_ = on; }
return old;
}
//- True if this is a parallel run //- Set use of distributed roots, but only if actually parallel
bool parRun() const noexcept void distributed(bool on) noexcept
{ {
return parallel_; distributed_ = (parallel_ && on);
} }
//- True if this is a parallel run and uses distributed roots.
bool distributed() const noexcept
{
return (parallel_ && distributed_);
}
//- Set use of distributed roots, but only if actually parallel // General Control
void distributed(bool on) noexcept
{ //- Non-zero if set as 'dry-run'
distributed_ = (parallel_ && on); int dryRun() const noexcept
} {
return dryRun_;
}
//- Change 'dry-run', return old value
int dryRun(const int level) noexcept
{
int old(dryRun_);
dryRun_ = level;
return old;
}
//- Non-zero if set as 'verbose'
int verbose() const noexcept
{
return verbose_;
}
//- Change 'verbose', return old value
int verbose(const int level) noexcept
{
int old(verbose_);
verbose_ = level;
return old;
}
}; };