From b364a9e72c4aa6ca843517cda438b80c178bf974 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Mon, 1 Nov 2021 11:31:56 +0100
Subject: [PATCH] ENH: argList improvements

- argList::envExecutable() static method.
  This is identical to getEnv("FOAM_EXECUTABLE"), where the name of
  the executable has typically been set from the argList construction.

  Provides a singleton access to this value from locations that
  do not have knowledge of the originating command args (argList).
  This is a similar rationale as for the argList::envGlobalPath() static.

- additional argList::envRelativePath() static method.

- make -dry-run handling more central and easier to use by adding into
  argList itself.

STYLE: drop handling of -srcDoc (v1706 option)

- replaced with -doc-source for 1712 and never used much anyhow
---
 .../generation/snappyHexMesh/snappyHexMesh.C  |  5 +-
 .../foamRestoreFields/foamRestoreFields.C     |  7 +-
 .../decomposePar/decomposePar.C               |  5 +-
 .../redistributePar/redistributePar.C         |  5 +-
 .../lumpedPointMovement/lumpedPointMovement.C |  5 +-
 .../lumpedPointZones/lumpedPointZones.C       |  9 +--
 .../PDR/PDRsetFields/PDRsetFields.C           |  7 +-
 .../foamUpgradeCyclics/foamUpgradeCyclics.C   |  3 +-
 .../setExprBoundaryFields.C                   |  5 +-
 .../setExprFields/setExprFields.C             |  5 +-
 src/OpenFOAM/db/Time/TimePaths.C              |  4 +-
 src/OpenFOAM/global/argList/argList.C         | 62 ++++++++++----
 src/OpenFOAM/global/argList/argList.H         | 80 ++++++++++++++-----
 src/OpenFOAM/global/argList/argListI.H        | 43 ++++++----
 src/OpenFOAM/global/argList/parRun.H          | 52 ++++++++----
 src/OpenFOAM/global/foamConfig.Cver           |  5 --
 src/OpenFOAM/include/addCheckCaseOptions.H    | 25 +++++-
 src/OpenFOAM/include/createMesh.H             |  2 +-
 .../dynamicFvMesh/dynamicFvMeshNew.C          |  4 +-
 src/finiteArea/include/faCFD.H                |  2 -
 .../cfdTools/general/include/fvCFD.H          |  2 -
 .../bridge/code/polynomial-motion.C           |  5 +-
 .../building/code/building-motion.C           |  7 +-
 23 files changed, 226 insertions(+), 123 deletions(-)

diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
index 1218dadddef..1d18e68fb9d 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
@@ -756,9 +756,8 @@ int main(int argc, char *argv[])
         "checkGeometry",
         "Check all surface geometry for quality"
     );
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Check case set-up only using a single time step"
     );
     argList::addOption
@@ -789,7 +788,7 @@ int main(int argc, char *argv[])
     const bool overwrite = args.found("overwrite");
     const bool checkGeometry = args.found("checkGeometry");
     const bool surfaceSimplify = args.found("surfaceSimplify");
-    const bool dryRun = args.found("dry-run");
+    const bool dryRun = args.dryRun();
 
     if (dryRun)
     {
diff --git a/applications/utilities/miscellaneous/foamRestoreFields/foamRestoreFields.C b/applications/utilities/miscellaneous/foamRestoreFields/foamRestoreFields.C
index 03518dcc0c3..163f4c3195a 100644
--- a/applications/utilities/miscellaneous/foamRestoreFields/foamRestoreFields.C
+++ b/applications/utilities/miscellaneous/foamRestoreFields/foamRestoreFields.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018-2020 OpenCFD Ltd.
+    Copyright (C) 2018-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -228,9 +228,8 @@ int main(int argc, char *argv[])
         "In serial mode use times from processor0/ directory, but operate on "
         "processor\\d+ directories"
     );
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Report action without moving/renaming"
     );
     argList::addBoolOption
@@ -247,7 +246,7 @@ int main(int argc, char *argv[])
 
     #include "setRootCase.H"
 
-    dryrun = args.found("dry-run");
+    dryrun = args.dryRun();
     verbose = args.found("verbose");
 
 
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index 792869d3158..74d245653f4 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -325,9 +325,8 @@ int main(int argc, char *argv[])
 
     #include "addAllRegionOptions.H"
 
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test without writing the decomposition. "
         "Changes -cellDist to only write VTK output."
     );
@@ -410,7 +409,7 @@ int main(int argc, char *argv[])
 
     #include "setRootCase.H"
 
-    const bool dryrun           = args.found("dry-run");
+    const bool dryrun           = args.dryRun();
     const bool writeCellDist    = args.found("cellDist");
     const bool verbose          = args.found("verbose");
 
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index 5a3b4925cb8..db5f26c773e 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -2488,9 +2488,8 @@ int main(int argc, char *argv[])
     #include "addOverwriteOption.H"
     argList::addBoolOption("decompose", "Decompose case");
     argList::addBoolOption("reconstruct", "Reconstruct case");
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test without writing the decomposition. "
         "Changes -cellDist to only write volScalarField."
     );
@@ -2555,7 +2554,7 @@ int main(int argc, char *argv[])
 
     const bool reconstruct = args.found("reconstruct");
     const bool writeCellDist = args.found("cellDist");
-    const bool dryrun = args.found("dry-run");
+    const bool dryrun = args.dryRun();
     const bool newTimes = args.found("newTimes");
 
     bool decompose = args.found("decompose");
diff --git a/applications/utilities/postProcessing/lumped/lumpedPointMovement/lumpedPointMovement.C b/applications/utilities/postProcessing/lumped/lumpedPointMovement/lumpedPointMovement.C
index ef5597dcae0..659c02ccd4d 100644
--- a/applications/utilities/postProcessing/lumped/lumpedPointMovement/lumpedPointMovement.C
+++ b/applications/utilities/postProcessing/lumped/lumpedPointMovement/lumpedPointMovement.C
@@ -119,9 +119,8 @@ int main(int argc, char *argv[])
         "len",
         "Visualization length for planes (visualized as triangles)"
     );
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test movement without a mesh"
     );
     argList::addBoolOption
@@ -142,7 +141,7 @@ int main(int argc, char *argv[])
     const label span   = Foam::max(1, args.getOrDefault<label>("span", 1));
 
     // Control parameters
-    const bool dryrun = args.found("dry-run");
+    const bool dryrun = args.dryRun();
     const bool slave = args.found("slave");
     const bool removeLock = args.found("removeLock");
 
diff --git a/applications/utilities/postProcessing/lumped/lumpedPointZones/lumpedPointZones.C b/applications/utilities/postProcessing/lumped/lumpedPointZones/lumpedPointZones.C
index aae3d4c8692..ce5817d2cd4 100644
--- a/applications/utilities/postProcessing/lumped/lumpedPointZones/lumpedPointZones.C
+++ b/applications/utilities/postProcessing/lumped/lumpedPointZones/lumpedPointZones.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2016-2020 OpenCFD Ltd.
+    Copyright (C) 2016-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -55,9 +55,8 @@ int main(int argc, char *argv[])
 
     argList::noFunctionObjects();  // Never use function objects
 
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test initial lumped points state without a mesh"
     );
     argList::addOption
@@ -85,15 +84,13 @@ int main(int argc, char *argv[])
 
     const bool noInterpolate = args.found("no-interpolate");
 
-    const bool dryrun = args.found("dry-run");
-
     // const bool verbose = args.found("verbose");
 
     args.readIfPresent("visual-length", lumpedPointState::visLength);
 
     #include "createTime.H"
 
-    if (dryrun)
+    if (args.dryRun())
     {
         // Create without a mesh
         autoPtr<lumpedPointIOMovement> movement =
diff --git a/applications/utilities/preProcessing/PDR/PDRsetFields/PDRsetFields.C b/applications/utilities/preProcessing/PDR/PDRsetFields/PDRsetFields.C
index fc31f25a49b..e1cef94b1cd 100644
--- a/applications/utilities/preProcessing/PDR/PDRsetFields/PDRsetFields.C
+++ b/applications/utilities/preProcessing/PDR/PDRsetFields/PDRsetFields.C
@@ -74,9 +74,8 @@ int main(int argc, char* argv[])
         "Force use of legacy obstacles table"
     );
 
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Read obstacles and write VTK only"
     );
 
@@ -90,8 +89,6 @@ int main(int argc, char* argv[])
 
     IOdictionary setFieldsDict(dictIO);
 
-    const bool dryrun = args.found("dry-run");
-
     const fileName& casepath = runTime.globalPath();
 
     pars.timeName = "0";
@@ -181,7 +178,7 @@ int main(int argc, char* argv[])
 
     PDRobstacle::generateVtk(casepath/"VTK", obstacles, cylinders);
 
-    if (dryrun)
+    if (args.dryRun())
     {
         Info<< nl
             << "dry-run: stopping after reading/writing obstacles" << nl
diff --git a/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C
index e04f6d7deb5..db36f8f8194 100644
--- a/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C
+++ b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C
@@ -404,9 +404,8 @@ int main(int argc, char *argv[])
     timeSelector::addOptions();
 
     argList::addOptionCompat("dry-run", {"test", 1806});
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test only do not change any files"
     );
     argList::addBoolOption
diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
index 6c1953c18cb..5cafecddffe 100644
--- a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
+++ b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C
@@ -91,16 +91,15 @@ int main(int argc, char *argv[])
         "Preserve sub-entry as .backup",
         true // Advanced
     );
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Evaluate but do not write"
     );
 
     #include "addRegionOption.H"
     #include "setRootCase.H"
 
-    const bool dryrun      = args.found("dry-run");
+    const bool dryrun      = args.dryRun();
     const bool backup      = args.found("backup");
     const bool cacheFields = args.found("cache-fields");
 
diff --git a/applications/utilities/preProcessing/setExprFields/setExprFields.C b/applications/utilities/preProcessing/setExprFields/setExprFields.C
index 9a7ba3dfcdc..37c8b3b15ef 100644
--- a/applications/utilities/preProcessing/setExprFields/setExprFields.C
+++ b/applications/utilities/preProcessing/setExprFields/setExprFields.C
@@ -549,9 +549,8 @@ int main(int argc, char *argv[])
         "file",
         "Alternative dictionary for setExprFieldsDict"
     );
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Evaluate but do not write"
     );
     argList::addBoolOption
@@ -663,7 +662,7 @@ int main(int argc, char *argv[])
 
     #include "createTime.H"
 
-    const bool dryrun = args.found("dry-run");
+    const bool dryrun = args.dryRun();
     const bool verbose = args.found("verbose");
 
     const word dictName("setExprFieldsDict");
diff --git a/src/OpenFOAM/db/Time/TimePaths.C b/src/OpenFOAM/db/Time/TimePaths.C
index e74c0731faf..08b8657f4d1 100644
--- a/src/OpenFOAM/db/Time/TimePaths.C
+++ b/src/OpenFOAM/db/Time/TimePaths.C
@@ -72,8 +72,8 @@ Foam::TimePaths::TimePaths
     const word& constantName
 )
 :
-    processorCase_(args.parRunControl().parRun()),
-    distributed_(args.parRunControl().distributed()),
+    processorCase_(args.runControl().parRun()),
+    distributed_(args.runControl().distributed()),
     rootPath_(args.rootPath()),
     globalCaseName_(args.globalCaseName()),
     case_(args.caseName()),
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index 4a5d6e2537e..b500f8e895d 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -449,6 +449,16 @@ bool Foam::argList::bannerEnabled()
 }
 
 
+void Foam::argList::addDryRunOption
+(
+    const string& usage,
+    bool advanced
+)
+{
+    addOption("dry-run", "", usage, advanced);
+}
+
+
 void Foam::argList::noFunctionObjects(bool addWithOption)
 {
     removeOption("noFunctionObjects");
@@ -519,12 +529,33 @@ bool Foam::argList::postProcess(int argc, char *argv[])
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
+Foam::word Foam::argList::envExecutable()
+{
+    return Foam::getEnv("FOAM_EXECUTABLE");
+}
+
+
 Foam::fileName Foam::argList::envGlobalPath()
 {
     return Foam::getEnv("FOAM_CASE");
 }
 
 
+Foam::fileName Foam::argList::envRelativePath
+(
+    const fileName& input,
+    const bool caseTag
+)
+{
+    if (input.isAbsolute())
+    {
+        return input.relative(envGlobalPath(), caseTag);
+    }
+
+    return input;
+}
+
+
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 Foam::word Foam::argList::optionCompat(const word& optName)
@@ -735,6 +766,11 @@ void Foam::argList::setCasePaths()
 
     // Executable name, unless already present in the environment
     setEnv("FOAM_EXECUTABLE", executable_, false);
+
+    if (validOptions.found("dry-run") && options_.found("dry-run"))
+    {
+        runControl_.dryRun(true);
+    }
 }
 
 
@@ -796,7 +832,7 @@ Foam::argList::argList
 
             if (validParOptions.found(optName))
             {
-                parRunControl_.runPar(argc, argv, needsThread);
+                runControl_.runPar(argc, argv, needsThread);
                 break;
             }
         }
@@ -921,7 +957,7 @@ Foam::argList::argList
     bool initialise
 )
 :
-    parRunControl_(args.parRunControl_),
+    runControl_(args.runControl_),
     args_(args.args_),
     options_(options),
     libs_(),
@@ -957,11 +993,7 @@ void Foam::argList::parse
             displayDoc(false);
             quickExit = true;
         }
-        else if
-        (
-            options_.found("doc-source")
-         || options_.found("srcDoc")  // Compat 1706
-        )
+        else if (options_.found("doc-source"))
         {
             displayDoc(true);
             quickExit = true;
@@ -1103,7 +1135,7 @@ void Foam::argList::parse
     const int writeHostsSwitch = Foam::debug::infoSwitch("writeHosts", 1);
 
     // Collect machine/pid, and check that the build is identical
-    if (parRunControl_.parRun())
+    if (runControl_.parRun())
     {
         if (Pstream::master())
         {
@@ -1151,7 +1183,7 @@ void Foam::argList::parse
     fileNameList roots;
 
     // If this actually is a parallel run
-    if (parRunControl_.parRun())
+    if (runControl_.parRun())
     {
         // For the master
         if (Pstream::master())
@@ -1192,7 +1224,7 @@ void Foam::argList::parse
             if (this->readListIfPresent("roots", roots))
             {
                 source = "-roots";
-                parRunControl_.distributed(true);
+                runControl_.distributed(true);
                 if (roots.size() != 1)
                 {
                     dictNProcs = roots.size()+1;
@@ -1276,7 +1308,7 @@ void Foam::argList::parse
                     if (decompDict.getOrDefault("distributed", false))
                     {
                         nDomainsMandatory = true;
-                        parRunControl_.distributed(true);
+                        runControl_.distributed(true);
                         decompDict.readEntry("roots", roots);
                     }
 
@@ -1446,7 +1478,7 @@ void Foam::argList::parse
             );
             fromMaster >> args_ >> options_ >> nroots;
 
-            parRunControl_.distributed(nroots);
+            runControl_.distributed(nroots);
 
             // Establish rootPath_/globalCase_/case_ for sub-process
             setCasePaths();
@@ -1470,7 +1502,7 @@ void Foam::argList::parse
     }
 
     // If needed, adjust fileHandler for distributed roots
-    if (parRunControl_.distributed())
+    if (runControl_.distributed())
     {
         if (fileOperation::fileHandlerPtr_)
         {
@@ -1479,7 +1511,7 @@ void Foam::argList::parse
     }
 
     // Keep/discard sub-process host/root information for reporting:
-    if (Pstream::master() && parRunControl_.parRun())
+    if (Pstream::master() && runControl_.parRun())
     {
         if (!writeHostsSwitch)
         {
@@ -1497,7 +1529,7 @@ void Foam::argList::parse
         Info<< "Case   : " << (rootPath_/globalCase_).c_str() << nl
             << "nProcs : " << nProcs << nl;
 
-        if (parRunControl_.parRun())
+        if (runControl_.parRun())
         {
             if (hostProcs.size())
             {
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index e9d022b5455..ab7bb28d1b7 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -103,7 +103,7 @@ SourceFiles
 #include "SLList.H"
 #include "HashSet.H"
 #include "fileName.H"
-#include "parRun.H"
+#include "parRun.H"  // "ParRunControl"
 #include "ITstream.H"
 #include "dlLibraryTable.H"
 #include "OSspecific.H"
@@ -131,9 +131,9 @@ class argList
         //- Track enabled/disabled checking of processor directories state
         static bool checkProcessorDirectories_;
 
-        //- Switch on/off parallel mode.
+        //- Switch on/off parallel mode, dry-run etc.
         //  Construct first so destructor is done last.
-        ParRunControl parRunControl_;
+        ParRunControl runControl_;
 
         //- The arguments after removing known options
         stringList args_;
@@ -183,9 +183,11 @@ class argList
         //   * [-case dir]
         //   * cwd
         //
-        // Also export FOAM_CASE and FOAM_CASENAME environment variables
-        // so they can be used immediately (eg, in decomposeParDict), as well
-        // as the FOAM_EXECUTABLE environment.
+        // Exports FOAM_CASE and FOAM_CASENAME env variables so they can
+        // be used immediately (eg, in decomposeParDict).
+        // Exports FOAM_EXECUTABLE env variable.
+        //
+        // Detects -dry-run option
         void setCasePaths();
 
         //- Transcribe argv into internal args_.
@@ -284,6 +286,15 @@ public:
 
     // Environment
 
+        //- Name of the executable from environment variable
+        //
+        //  Returns the contents of the \c FOAM_EXECUTABLE variable,
+        //  which has previously been set by argList.
+        //
+        //  This will normally be identical to the value of executable(),
+        //  but obtained from the environment.
+        static word envExecutable();
+
         //- Global case (directory) from environment variable
         //
         //  Returns the contents of the \c FOAM_CASE variable,
@@ -293,6 +304,19 @@ public:
         //  but obtained via the environment.
         static fileName envGlobalPath();
 
+        //- Return the input relative to the globalPath by stripping off
+        //- a leading value of the envGlobalPath
+        //
+        //  \param input the directory or filename to make case-relative
+        //  \param caseTag replace globalPath with \<case\> for later
+        //      use with expand(), or prefix \<case\> if the file name was
+        //      not an absolute location
+        static fileName envRelativePath
+        (
+            const fileName& input,
+            const bool caseTag = false
+        );
+
 
     // Low-level
 
@@ -304,19 +328,19 @@ public:
     // Access
 
         //- Name of executable without the path
-        inline const word& executable() const;
+        inline const word& executable() const noexcept;
 
         //- The command line options and arguments concatenated as a string
-        inline const string& commandLine() const;
+        inline const string& commandLine() const noexcept;
 
         //- Return root path
-        inline const fileName& rootPath() const;
+        inline const fileName& rootPath() const noexcept;
 
         //- Return case name (parallel run) or global case (serial run)
-        inline const fileName& caseName() const;
+        inline const fileName& caseName() const noexcept;
 
         //- Return global case name
-        inline const fileName& globalCaseName() const;
+        inline const fileName& globalCaseName() const noexcept;
 
         //- Return the full path to the (processor local) case
         //  \note This is guaranteed to be an absolute path
@@ -339,30 +363,36 @@ public:
             const bool caseTag = false
         ) const;
 
+        //- Return the run control (parallel, dry-run etc)
+        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
         //- (i.e. are rootPaths different on different machines)
-        inline bool distributed() const;
-
-        //- Return the ParRunControl
-        inline const ParRunControl& parRunControl() const;
+        inline bool distributed() const noexcept;
 
         //- Mutable access to the loaded dynamic libraries
-        inline dlLibraryTable& libs() const;
+        inline dlLibraryTable& libs() const noexcept;
 
         //- The number of arguments
         inline label size() const noexcept;
 
         //- Return arguments
-        inline const stringList& args() const;
+        inline const stringList& args() const noexcept;
 
         //- Non-const access to the command arguments (non-options)
-        inline stringList& args();
+        inline stringList& args() noexcept;
 
         //- Return options
-        inline const HashTable<string>& options() const;
+        inline const HashTable<string>& options() const noexcept;
 
         //- Return non-const access to the command options
-        inline HashTable<string>& options();
+        inline HashTable<string>& options() noexcept;
 
         //- Return true if the named option is found
         inline bool found(const word& optName) const;
@@ -573,6 +603,13 @@ public:
         //  Queries the Foam::infoDetailLevel flag.
         static bool bannerEnabled();
 
+        //- Add a 'dry-run' bool option to validOptions with usage information
+        static void addDryRunOption
+        (
+            const string& usage,  //! usage information (mandatory)
+            bool advanced = false
+        );
+
         //- Remove '-noFunctionObjects' option and ignore any occurrences.
         //  Optionally add a '-withFunctionObjects' option instead
         static void noFunctionObjects(bool addWithOption = false);
@@ -687,6 +724,9 @@ public:
             return this->getOrDefault<T>(optName, deflt);
         }
 
+        //- Same as runControl() - v2106 and earlier
+        const ParRunControl& parRunControl() const { return runControl_; }
+
 
     // Older style access (including 1712 release)
 
diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H
index a9e70bfb925..112012fd4bc 100644
--- a/src/OpenFOAM/global/argList/argListI.H
+++ b/src/OpenFOAM/global/argList/argListI.H
@@ -48,31 +48,31 @@ inline void Foam::argList::readList(ITstream& is, List<T>& list)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-inline const Foam::word& Foam::argList::executable() const
+inline const Foam::word& Foam::argList::executable() const noexcept
 {
     return executable_;
 }
 
 
-inline const Foam::string& Foam::argList::commandLine() const
+inline const Foam::string& Foam::argList::commandLine() const noexcept
 {
     return commandLine_;
 }
 
 
-inline const Foam::fileName& Foam::argList::rootPath() const
+inline const Foam::fileName& Foam::argList::rootPath() const noexcept
 {
     return rootPath_;
 }
 
 
-inline const Foam::fileName& Foam::argList::caseName() const
+inline const Foam::fileName& Foam::argList::caseName() const noexcept
 {
     return case_;
 }
 
 
-inline const Foam::fileName& Foam::argList::globalCaseName() const
+inline const Foam::fileName& Foam::argList::globalCaseName() const noexcept
 {
     return globalCase_;
 }
@@ -100,19 +100,32 @@ inline Foam::fileName Foam::argList::relativePath
 }
 
 
-inline bool Foam::argList::distributed() const
+inline const Foam::ParRunControl&
+Foam::argList::runControl() const noexcept
 {
-    return parRunControl_.distributed();
+    return runControl_;
 }
 
 
-inline const Foam::ParRunControl& Foam::argList::parRunControl() const
+inline bool Foam::argList::dryRun() const noexcept
 {
-    return parRunControl_;
+    return runControl_.dryRun();
 }
 
 
-inline Foam::dlLibraryTable& Foam::argList::libs() const
+inline bool Foam::argList::dryRun(const bool on) noexcept
+{
+    return runControl_.dryRun(on);
+}
+
+
+inline bool Foam::argList::distributed() const noexcept
+{
+    return runControl_.distributed();
+}
+
+
+inline Foam::dlLibraryTable& Foam::argList::libs() const noexcept
 {
     return libs_;
 }
@@ -124,25 +137,27 @@ inline Foam::label Foam::argList::size() const noexcept
 }
 
 
-inline const Foam::stringList& Foam::argList::args() const
+inline const Foam::stringList& Foam::argList::args() const noexcept
 {
     return args_;
 }
 
 
-inline Foam::stringList& Foam::argList::args()
+inline Foam::stringList& Foam::argList::args() noexcept
 {
     return args_;
 }
 
 
-inline const Foam::HashTable<Foam::string>& Foam::argList::options() const
+inline const Foam::HashTable<Foam::string>&
+Foam::argList::options() const noexcept
 {
     return options_;
 }
 
 
-inline Foam::HashTable<Foam::string>& Foam::argList::options()
+inline Foam::HashTable<Foam::string>&
+Foam::argList::options() noexcept
 {
     return options_;
 }
diff --git a/src/OpenFOAM/global/argList/parRun.H b/src/OpenFOAM/global/argList/parRun.H
index 1c93d68db7d..96b77f4f197 100644
--- a/src/OpenFOAM/global/argList/parRun.H
+++ b/src/OpenFOAM/global/argList/parRun.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2018 OpenFOAM Foundation
-    Copyright (C) 2018-2020 OpenCFD Ltd.
+    Copyright (C) 2018-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,13 +28,17 @@ Class
     Foam::ParRunControl
 
 Description
-    Helper class for initializing parallel jobs from the command arguments.
+    Helper class for initializing parallel jobs from the command arguments,
+    storing 'dry-run' state etc.
     Also handles cleanup of parallel (or serial) jobs.
 
+Note
+    In the meantime the class name may be slightly misleading.
+
 \*---------------------------------------------------------------------------*/
 
-#ifndef parRun_H
-#define parRun_H
+#ifndef argListRunControl_H
+#define argListRunControl_H
 
 #include "Pstream.H"
 #include "IOstreams.H"
@@ -45,11 +49,12 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class ParRunControl Declaration
+                      Class ParRunControl Declaration
 \*---------------------------------------------------------------------------*/
 
 class ParRunControl
 {
+    bool dryRun_;
     bool parallel_;
     bool distributed_;
 
@@ -58,6 +63,7 @@ public:
     //- Default construct
     ParRunControl()
     :
+        dryRun_(false),
         parallel_(false),
         distributed_(false)
     {}
@@ -69,38 +75,52 @@ public:
         {
             Info<< "Finalising parallel run" << endl;
         }
-
-        Pstream::shutdown();
+        UPstream::shutdown();
     }
 
 
     //- Initialize Pstream for a parallel run
     void runPar(int& argc, char**& argv, bool needsThread)
     {
-        if (!Pstream::init(argc, argv, needsThread))
+        if (!UPstream::init(argc, argv, needsThread))
         {
             Info<< "Failed to start parallel run" << endl;
-            Pstream::exit(1);
+            UPstream::exit(1);
         }
         parallel_ = true;
     }
 
-    //- True if this is parallel run.
-    bool parRun() const
+
+    //- True if set as 'dry-run'
+    bool dryRun() const noexcept
+    {
+        return dryRun_;
+    }
+
+    //- Set as 'dry-run', return old value
+    bool dryRun(bool on) noexcept
+    {
+        bool old(dryRun_);
+        dryRun_ = on;
+        return old;
+    }
+
+    //- True if this is a parallel run
+    bool parRun() const noexcept
     {
         return parallel_;
     }
 
     //- True if this is a parallel run and uses distributed roots.
-    bool distributed() const
+    bool distributed() const noexcept
     {
-        return parallel_ && distributed_;
+        return (parallel_ && distributed_);
     }
 
-    //- Set use of distributed roots.
-    void distributed(bool on)
+    //- Set use of distributed roots, but only if actually parallel
+    void distributed(bool on) noexcept
     {
-        distributed_ = (parallel_ ? on : false);
+        distributed_ = (parallel_ && on);
     }
 };
 
diff --git a/src/OpenFOAM/global/foamConfig.Cver b/src/OpenFOAM/global/foamConfig.Cver
index c90e6cf589d..3e090540f23 100644
--- a/src/OpenFOAM/global/foamConfig.Cver
+++ b/src/OpenFOAM/global/foamConfig.Cver
@@ -38,9 +38,6 @@ Description
 
 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-namespace
-{
-
 // Extract value from "key=<digits>", eg "LSB;label=32;scalar=64"
 // The 'tag' string includes the '=' for additional safety.
 // Return 0 on any errors
@@ -59,8 +56,6 @@ static inline unsigned getTaggedSize(const char* tag, const std::string& s)
     return std::stoul(s.substr(first, last));
 }
 
-} // End namespace anonymous
-
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/include/addCheckCaseOptions.H b/src/OpenFOAM/include/addCheckCaseOptions.H
index 15caf168b57..40837dbf56a 100644
--- a/src/OpenFOAM/include/addCheckCaseOptions.H
+++ b/src/OpenFOAM/include/addCheckCaseOptions.H
@@ -1,6 +1,25 @@
-Foam::argList::addBoolOption
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2018-2021 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
+
+Description
+    Add -dry-run and -dry-run-write options
+
+Required Classes
+    - Foam::argList
+
+\*---------------------------------------------------------------------------*/
+
+Foam::argList::addDryRunOption
 (
-    "dry-run",
     "Check case set-up only using a single time step"
 );
 Foam::argList::addBoolOption
@@ -8,3 +27,5 @@ Foam::argList::addBoolOption
     "dry-run-write",
     "Check case set-up and write only using a single time step"
 );
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/include/createMesh.H b/src/OpenFOAM/include/createMesh.H
index 67dc3e91194..153466f1f70 100644
--- a/src/OpenFOAM/include/createMesh.H
+++ b/src/OpenFOAM/include/createMesh.H
@@ -28,7 +28,7 @@ Provided Variables
 Foam::autoPtr<Foam::fvMesh> meshPtr(nullptr);
 Foam::word regionName(Foam::polyMesh::defaultRegion);
 
-if (args.found("dry-run") || args.found("dry-run-write"))
+if (args.dryRun() || args.found("dry-run-write"))
 {
     Foam::Info
         << "Operating in 'dry-run' mode: case will run for 1 time step.  "
diff --git a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMeshNew.C b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMeshNew.C
index 487534b1d24..0ae2fd5c1f6 100644
--- a/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMeshNew.C
+++ b/src/dynamicFvMesh/dynamicFvMesh/dynamicFvMeshNew.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2019-2020 OpenCFD Ltd.
+    Copyright (C) 2019-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -125,7 +125,7 @@ Foam::autoPtr<Foam::dynamicFvMesh> Foam::dynamicFvMesh::New
     const Time& runTime
 )
 {
-    if (args.found("dry-run") || args.found("dry-run-write"))
+    if (args.dryRun() || args.found("dry-run-write"))
     {
         Info
             << "Operating in 'dry-run' mode: case will run for 1 time step.  "
diff --git a/src/finiteArea/include/faCFD.H b/src/finiteArea/include/faCFD.H
index 4343da9f6bb..9dbf8b9137d 100644
--- a/src/finiteArea/include/faCFD.H
+++ b/src/finiteArea/include/faCFD.H
@@ -1,8 +1,6 @@
 #ifndef faCFD_H
 #define faCFD_H
 
-#include "parRun.H"
-
 #include "Time.H"
 #include "faMesh.H"
 #include "areaFields.H"
diff --git a/src/finiteVolume/cfdTools/general/include/fvCFD.H b/src/finiteVolume/cfdTools/general/include/fvCFD.H
index 392bf2c6f87..bc9f8242a8a 100644
--- a/src/finiteVolume/cfdTools/general/include/fvCFD.H
+++ b/src/finiteVolume/cfdTools/general/include/fvCFD.H
@@ -1,8 +1,6 @@
 #ifndef fvCFD_H
 #define fvCFD_H
 
-#include "parRun.H"
-
 #include "Time.H"
 #include "fvMesh.H"
 #include "fvc.H"
diff --git a/tutorials/incompressible/lumpedPointMotion/bridge/code/polynomial-motion.C b/tutorials/incompressible/lumpedPointMotion/bridge/code/polynomial-motion.C
index c15a39f067a..88fcbf1b5b5 100644
--- a/tutorials/incompressible/lumpedPointMotion/bridge/code/polynomial-motion.C
+++ b/tutorials/incompressible/lumpedPointMotion/bridge/code/polynomial-motion.C
@@ -194,9 +194,8 @@ int main(int argc, char *argv[])
     );
 
     // Run controls
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test movement without a mesh"
     );
     argList::addBoolOption
@@ -232,7 +231,7 @@ int main(int argc, char *argv[])
 
 
     // Control parameters
-    const bool dryrun = args.found("dry-run");
+    const bool dryrun = args.dryRun();
     const bool slave = args.found("slave");
     const bool removeLock = args.found("removeLock");
 
diff --git a/tutorials/incompressible/lumpedPointMotion/building/code/building-motion.C b/tutorials/incompressible/lumpedPointMotion/building/code/building-motion.C
index 1e4c5c77a94..fcd94ccbb14 100644
--- a/tutorials/incompressible/lumpedPointMotion/building/code/building-motion.C
+++ b/tutorials/incompressible/lumpedPointMotion/building/code/building-motion.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2020 OpenCFD Ltd.
+    Copyright (C) 2020-2021 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -246,9 +246,8 @@ int main(int argc, char *argv[])
     );
 
     // Run controls
-    argList::addBoolOption
+    argList::addDryRunOption
     (
-        "dry-run",
         "Test movement without a mesh"
     );
     argList::addBoolOption
@@ -273,7 +272,7 @@ int main(int argc, char *argv[])
 
 
     // Control parameters
-    const bool dryrun = args.found("dry-run");
+    const bool dryrun = args.dryRun();
     const bool slave = args.found("slave");
     const bool removeLock = args.found("removeLock");
 
-- 
GitLab