From 32916fa8458e4cfdd0debfc47ce4c20e069c1d22 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Tue, 21 May 2019 19:10:14 +0100
Subject: [PATCH] ENH: dictionary checking methods with predicates on the input
 values

- can be used to check the validity of input values.

Example:

    dict.getCheck<label>("nIters", greaterOp1<label>(0));
    dict.getCheck<scalar>("relax", scalarMinMax::zero_one());

- use 'get' prefix for more regular dictionary methods.
  Eg, getOrDefault() as alternative to lookupOrDefault()

- additional ops for convenient construction of predicates

ENH: make dictionary writeOptionalEntries integer

- allow triggering of Fatal if default values are used

ENH: additional scalarRange static methods: ge0, gt0, zero_one

- use GREAT instead of VGREAT for internal placeholders

- additional MinMax static methods: gt, le
---
 .../test/dictionary2/Test-dictionary2.C       |  61 +++-
 .../scalarPredicates/Test-scalarPredicates.C  |  38 ++-
 etc/controlDict                               |   2 +
 src/OpenFOAM/db/dictionary/dictionary.C       |  48 ++-
 src/OpenFOAM/db/dictionary/dictionary.H       | 173 +++++++++--
 src/OpenFOAM/db/dictionary/dictionaryCompat.C |  10 +-
 src/OpenFOAM/db/dictionary/dictionarySearch.C |  16 +-
 .../db/dictionary/dictionaryTemplates.C       | 280 +++++++++++++++---
 src/OpenFOAM/db/dictionary/entry/entry.C      |  21 +-
 src/OpenFOAM/db/dictionary/entry/entry.H      |  36 ++-
 src/OpenFOAM/db/dictionary/entry/entryIO.C    |   6 +-
 .../functionEntries/removeEntry/removeEntry.C |   2 +-
 .../dimensionedType/dimensionedType.C         |  26 +-
 .../dimensionedType/dimensionedType.H         |  69 ++++-
 src/OpenFOAM/global/argList/argList.C         |   2 +-
 src/OpenFOAM/global/argList/argList.H         |  47 ++-
 src/OpenFOAM/global/argList/argListI.H        |   4 +-
 src/OpenFOAM/primitives/bools/Switch/Switch.C |  10 +-
 src/OpenFOAM/primitives/bools/Switch/Switch.H |  18 +-
 src/OpenFOAM/primitives/enums/Enum.C          |  14 +-
 src/OpenFOAM/primitives/enums/Enum.H          |  38 ++-
 src/OpenFOAM/primitives/ops/ops.H             |  31 +-
 .../primitives/ranges/MinMax/MinMax.H         |   6 +
 .../primitives/ranges/MinMax/MinMaxI.H        |  14 +
 .../ranges/scalarRange/scalarRange.C          |  12 +-
 .../ranges/scalarRange/scalarRange.H          |  18 +-
 .../ranges/scalarRange/scalarRangeI.H         |  64 ++--
 .../ranges/scalarRange/scalarRanges.H         |   6 +-
 28 files changed, 882 insertions(+), 190 deletions(-)

diff --git a/applications/test/dictionary2/Test-dictionary2.C b/applications/test/dictionary2/Test-dictionary2.C
index d66e0d05900..b05c18c3c34 100644
--- a/applications/test/dictionary2/Test-dictionary2.C
+++ b/applications/test/dictionary2/Test-dictionary2.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -34,6 +34,8 @@ Description
 #include "IOobject.H"
 #include "IFstream.H"
 #include "dictionary.H"
+#include "ops.H"
+#include "scalarRange.H"
 #include "stringOps.H"
 
 using namespace Foam;
@@ -108,6 +110,42 @@ scalar try_getScalar(const dictionary& dict, const word& k)
 }
 
 
+// Try with getCheck<scalar>
+template<class Predicate>
+scalar try_getCheckScalar
+(
+    const dictionary& dict,
+    const word& k,
+    const Predicate& pred
+)
+{
+    scalar val(-GREAT);
+
+    const bool throwingIOError = FatalIOError.throwExceptions();
+    const bool throwingError = FatalError.throwExceptions();
+
+    try
+    {
+        val = dict.getCheck<scalar>(k, pred);
+        Info<< "getCheck<scalar>(" << k << ") = " << val << nl;
+    }
+    catch (const Foam::IOerror& err)
+    {
+        Info<< "getCheck<scalar>(" << k << ") Caught FatalIOError "
+            << err << nl << endl;
+    }
+    catch (const Foam::error& err)
+    {
+        Info<< "getCheck<scalar>(" << k << ") Caught FatalError "
+            << err << nl << endl;
+    }
+    FatalError.throwExceptions(throwingError);
+    FatalIOError.throwExceptions(throwingIOError);
+
+    return val;
+}
+
+
 // Try with *entry (from findEntry) and get<scalar>
 scalar try_getScalar(const entry* eptr, const word& k)
 {
@@ -311,6 +349,7 @@ int main(int argc, char *argv[])
             IStringStream
             (
                 "good 3.14159;\n"
+                "negative -3.14159;\n"
                 "empty;\n"
                 // "bad  text;\n"            // always fails
                 // "bad  3.14159 1234;\n"    // fails for readScalar
@@ -338,6 +377,26 @@ int main(int argc, char *argv[])
             try_getScalar(dict2, "empty");
         }
 
+
+        // With getCheck<scalar>
+        {
+            Info<< nl << "Test some input with getCheck<scalar>()" << nl;
+
+            try_getCheckScalar(dict2, "good", scalarRange::gt0());
+            try_getCheckScalar(dict2, "negative", scalarRange::gt0());
+
+            try_getCheckScalar(dict2, "good", greaterOp1<scalar>(0));
+            try_getCheckScalar(dict2, "negative", greaterOp1<scalar>(0));
+
+            Info<< nl << "with lambda" << nl;
+            try_getCheckScalar
+            (
+                dict2,
+                "good",
+                [](const scalar x) { return x > 0; }
+            );
+        }
+
         // With findEntry and get<scalar>
         {
             Info<< nl
diff --git a/applications/test/scalarPredicates/Test-scalarPredicates.C b/applications/test/scalarPredicates/Test-scalarPredicates.C
index 22338e91746..587ca38b0d4 100644
--- a/applications/test/scalarPredicates/Test-scalarPredicates.C
+++ b/applications/test/scalarPredicates/Test-scalarPredicates.C
@@ -36,6 +36,8 @@ Description
 #include "FlatOutput.H"
 #include "Tuple2.H"
 #include "StringStream.H"
+#include "ops.H"
+#include "bitSet.H"
 
 using namespace Foam;
 
@@ -44,7 +46,7 @@ void doTest(const scalarList& values, const predicates::scalars& accept)
 {
     // Also tests that output is suppressed
     Info<<"Have: " << accept.size() << " predicates" << accept << endl;
-    Info<<"values: " << flatOutput(values)  << endl;
+    Info<<"values: " << flatOutput(values) << endl;
 
     for (const scalar& value : values)
     {
@@ -60,6 +62,30 @@ void doTest(const scalarList& values, const predicates::scalars& accept)
 }
 
 
+template<class Predicate>
+void testPredicate(const scalarList& values, const Predicate& pred)
+{
+    bitSet matches;
+
+    label i=0;
+
+    for (const scalar& value : values)
+    {
+        if (pred(value))
+        {
+            matches.set(i);
+        }
+
+        ++i;
+    }
+
+    IndirectList<scalar> matched(values, matches.toc());
+
+    Info<< "matched: " << flatOutput(matched.addressing())
+        << " = " << flatOutput(matched) << nl;
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 //  Main program:
 
@@ -149,6 +175,16 @@ int main(int argc, char *argv[])
     }
 
 
+    Info<< nl << "Test with ops" << nl;
+    Info<<"values: " << flatOutput(values) << endl;
+    {
+        testPredicate(values, lessOp1<scalar>(10));
+        testPredicate(values, greaterOp1<scalar>(100));
+
+        // Also with dissimilar type
+        testPredicate(values, lessEqOp1<label>(0));
+    }
+
     Info<< "\nEnd\n" << endl;
 
     return 0;
diff --git a/etc/controlDict b/etc/controlDict
index 5e03e45e20e..223f28e3abd 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -37,6 +37,8 @@ InfoSwitches
     writePrecision  6;
 
     writeDictionaries 0;
+
+    // Report optional dictionary entries. For value > 1, treat as fatal.
     writeOptionalEntries 0;
 
     // Write lagrangian "positions" file in v1706 format (and earlier)
diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C
index 775d90ea597..a15a73c8559 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.C
+++ b/src/OpenFOAM/db/dictionary/dictionary.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2015-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2015-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -42,13 +42,12 @@ namespace Foam
 
 const Foam::dictionary Foam::dictionary::null;
 
-bool Foam::dictionary::writeOptionalEntries
+int Foam::dictionary::writeOptionalEntries
 (
     Foam::debug::infoSwitch("writeOptionalEntries", 0)
 );
 
 
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::dictionary::dictionary()
@@ -311,13 +310,30 @@ void Foam::dictionary::checkITstream
 }
 
 
+void Foam::dictionary::raiseBadInput(const word& keyword) const
+{
+    // Can use FatalIOError instead of SafeFatalIOError
+    // since predicate checks are not used at the earliest stages
+    FatalIOError
+    (
+        "",                 // functionName
+        "",                 // sourceFileName
+        0,                  // sourceFileLineNumber
+        *this               // ios
+    )
+        << "Entry '" << keyword << "' with invalid input in dictionary "
+        << name() << nl << nl
+        << exit(FatalIOError);
+}
+
+
 bool Foam::dictionary::found
 (
     const word& keyword,
     enum keyType::option matchOpt
 ) const
 {
-    return csearch(keyword, matchOpt).found();
+    return csearch(keyword, matchOpt).good();
 }
 
 
@@ -359,11 +375,11 @@ const Foam::entry& Foam::dictionary::lookupEntry
 {
     const const_searcher finder(csearch(keyword, matchOpt));
 
-    if (!finder.found())
+    if (!finder.good())
     {
         FatalIOErrorInFunction(*this)
             << "Entry '" << keyword << "' not found in dictionary "
-            << name()
+            << name() << nl
             << exit(FatalIOError);
     }
 
@@ -395,7 +411,7 @@ bool Foam::dictionary::substituteKeyword(const word& keyword, bool mergeEntry)
     const const_searcher finder(csearch(varName, keyType::REGEX_RECURSIVE));
 
     // If defined insert its entries into this dictionary
-    if (finder.found())
+    if (finder.good())
     {
         for (const entry& e : finder.dict())
         {
@@ -427,7 +443,7 @@ bool Foam::dictionary::substituteScopedKeyword
     const auto finder(csearchScoped(varName, keyType::REGEX_RECURSIVE));
 
     // If defined insert its entries into this dictionary
-    if (finder.found())
+    if (finder.good())
     {
         for (const entry& e : finder.dict())
         {
@@ -473,11 +489,11 @@ const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
     // Allow patterns, non-recursive
     const const_searcher finder(csearch(keyword, keyType::REGEX));
 
-    if (!finder.found())
+    if (!finder.good())
     {
         FatalIOErrorInFunction(*this)
             << "Entry '" << keyword << "' not found in dictionary "
-            << name()
+            << name() << nl
             << exit(FatalIOError);
     }
 
@@ -490,11 +506,11 @@ Foam::dictionary& Foam::dictionary::subDict(const word& keyword)
     // Allow patterns, non-recursive
     searcher finder(search(keyword, keyType::REGEX));
 
-    if (!finder.found())
+    if (!finder.good())
     {
         FatalIOErrorInFunction(*this)
             << "Entry '" << keyword << "' not found in dictionary "
-            << name()
+            << name() << nl
             << exit(FatalIOError);
     }
 
@@ -526,7 +542,7 @@ Foam::dictionary Foam::dictionary::subOrEmptyDict
             << exit(FatalIOError);
     }
 
-    if (finder.found())
+    if (finder.good())
     {
         IOWarningInFunction(*this)
             << "Entry '" << keyword
@@ -552,7 +568,7 @@ const Foam::dictionary& Foam::dictionary::optionalSubDict
         return finder.dict();
     }
 
-    if (finder.found())
+    if (finder.good())
     {
         IOWarningInFunction(*this)
             << "Entry '" << keyword
@@ -611,7 +627,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
 
     auto iter = hashedEntries_.find(entryPtr->keyword());
 
-    if (mergeEntry && iter.found())
+    if (mergeEntry && iter.good())
     {
         // Merge dictionary with dictionary
         if (iter()->isDict() && entryPtr->isDict())
@@ -786,7 +802,7 @@ bool Foam::dictionary::merge(const dictionary& dict)
     {
         auto fnd = hashedEntries_.find(e.keyword());
 
-        if (fnd.found())
+        if (fnd.good())
         {
             // Recursively merge sub-dictionaries
             // TODO: merge without copying
diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H
index 1a510281d82..7200a507edb 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.H
+++ b/src/OpenFOAM/db/dictionary/dictionary.H
@@ -62,8 +62,8 @@ Note
         key2        $..key1; // use key1 value from parent
         subdict2
         {
-            key2        val2;
-            key3        $...key1; // use key1 value from grandparent
+            key2    val2;
+            key3    $...key1; // use key1 value from grandparent
         }
     }
 
@@ -285,8 +285,9 @@ private:
     // Private Data
 
         //- Report optional keywords and values if not present in dictionary
+        //  For value greater than 1: fatal.
         //  Set/unset via an InfoSwitch
-        static bool writeOptionalEntries;
+        static int writeOptionalEntries;
 
         //- The dictionary name
         fileName name_;
@@ -359,6 +360,10 @@ private:
         ) const;
 
 
+        //- Emit IOError about bad input for the entry
+        void raiseBadInput(const word& keyword) const;
+
+
 public:
 
     // Declare name of the class and its debug switch
@@ -532,7 +537,6 @@ public:
             enum keyType::option matchOpt = keyType::REGEX
         );
 
-        //- Search for an entry (const access) with the given keyword.
         //- Find and return a sub-dictionary pointer if present
         //  (and a sub-dictionary) otherwise return nullptr.
         //
@@ -543,6 +547,7 @@ public:
             enum keyType::option matchOpt = keyType::REGEX
         ) const;
 
+        //- Search for an entry (const access) with the given keyword.
         //
         //  \param matchOpt the default search is non-recursive with patterns
         //
@@ -553,22 +558,22 @@ public:
             enum keyType::option matchOpt
         ) const;
 
-        //- Find and return a T.
+        //- Find and return an entry data stream.
         //- FatalIOError if not found, or if the number of tokens is incorrect.
         //
         //  \param matchOpt the default search is non-recursive with patterns
-        template<class T>
-        T get
+        ITstream& lookup
         (
             const word& keyword,
             enum keyType::option matchOpt = keyType::REGEX
         ) const;
 
-        //- Find and return an entry data stream.
+        //- Find and return a T.
         //- FatalIOError if not found, or if the number of tokens is incorrect.
         //
         //  \param matchOpt the default search is non-recursive with patterns
-        ITstream& lookup
+        template<class T>
+        T get
         (
             const word& keyword,
             enum keyType::option matchOpt = keyType::REGEX
@@ -579,7 +584,7 @@ public:
         //
         //  \param matchOpt the default search is non-recursive with patterns
         template<class T>
-        T lookupOrDefault
+        T getOrDefault
         (
             const word& keyword,
             const T& deflt,
@@ -592,7 +597,7 @@ public:
         //
         //  \param matchOpt the default search is non-recursive with patterns
         template<class T>
-        T lookupOrAddDefault
+        T getOrAdd
         (
             const word& keyword,
             const T& deflt,
@@ -633,6 +638,86 @@ public:
             enum keyType::option matchOpt = keyType::REGEX
         ) const;
 
+        //- Find and return a T with additional checking
+        //- FatalIOError if not found, or if the number of tokens is incorrect.
+        //
+        //  \param pred the value check predicate
+        //  \param matchOpt the default search is non-recursive with patterns
+        template<class T, class Predicate>
+        T getCheck
+        (
+            const word& keyword,
+            const Predicate& pred,
+            enum keyType::option matchOpt = keyType::REGEX
+        ) const;
+
+        //- Find and return a T, or return the given default value.
+        //- FatalIOError if it is found and the number of tokens is incorrect.
+        //
+        //  \param pred the value check predicate
+        //  \param matchOpt the default search is non-recursive with patterns
+        template<class T, class Predicate>
+        T getCheckOrDefault
+        (
+            const word& keyword,
+            const T& deflt,
+            const Predicate& pred,
+            enum keyType::option matchOpt = keyType::REGEX
+        ) const;
+
+        //- Find and return a T, or return the given default value
+        //- and add it to dictionary.
+        //- FatalIOError if it is found and the number of tokens is incorrect.
+        //
+        //  \param pred the value check predicate
+        //  \param matchOpt the default search is non-recursive with patterns
+        template<class T, class Predicate>
+        T getCheckOrAdd
+        (
+            const word& keyword,
+            const T& deflt,
+            const Predicate& pred,
+            enum keyType::option matchOpt = keyType::REGEX
+        );
+
+        //- Find entry and assign to T val.
+        //- FatalIOError if it is found and the number of tokens is incorrect,
+        //- or it is mandatory and not found.
+        //
+        //  \param val the value to read into
+        //  \param pred the value check predicate
+        //  \param matchOpt the default search is non-recursive with patterns
+        //  \param mandatory the keyword is mandatory
+        //
+        //  \return true if the entry was found.
+        template<class T, class Predicate>
+        bool readCheck
+        (
+            const word& keyword,
+            T& val,
+            const Predicate& pred,
+            enum keyType::option matchOpt = keyType::REGEX,
+            bool mandatory = true
+        ) const;
+
+        //- Find an entry if present, and assign to T val.
+        //- FatalIOError if it is found and the number of tokens is incorrect.
+        //  Default search: non-recursive with patterns.
+        //
+        //  \param val the value to read into
+        //  \param pred the value check predicate
+        //  \param matchOpt the default search is non-recursive with patterns
+        //
+        //  \return true if the entry was found.
+        template<class T, class Predicate>
+        bool readCheckIfPresent
+        (
+            const word& keyword,
+            T& val,
+            const Predicate& pred,
+            enum keyType::option matchOpt = keyType::REGEX
+        ) const;
+
         //- Check if entry is found and and is a sub-dictionary.
         //
         //  Search type: non-recursive with patterns.
@@ -983,32 +1068,32 @@ public:
             enum keyType::option
         ) const;
 
-        //- Find and return a T
+        //- Find and return an entry data stream,
         //- using any compatibility names if needed.
-        //- FatalIOError if not found, or if there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param compat list of old compatibility keywords and the last
         //      OpenFOAM version for which they were used.
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
-        template<class T>
-        T getCompat
+        ITstream& lookupCompat
         (
             const word& keyword,
             std::initializer_list<std::pair<const char*,int>> compat,
             enum keyType::option = keyType::REGEX
         ) const;
 
-        //- Find and return an entry data stream,
+        //- Find and return a T
         //- using any compatibility names if needed.
+        //- FatalIOError if not found, or if there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param compat list of old compatibility keywords and the last
         //      OpenFOAM version for which they were used.
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
-        ITstream& lookupCompat
+        template<class T>
+        T getCompat
         (
             const word& keyword,
             std::initializer_list<std::pair<const char*,int>> compat,
@@ -1024,7 +1109,7 @@ public:
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
         template<class T>
-        T lookupOrDefaultCompat
+        T getOrDefaultCompat
         (
             const word& keyword,
             std::initializer_list<std::pair<const char*,int>> compat,
@@ -1105,6 +1190,58 @@ public:
 
     // Housekeeping
 
+        //- Find and return a T, or return the given default value.
+        //- FatalIOError if it is found and the number of tokens is incorrect.
+        //
+        //  \param matchOpt the default search is non-recursive with patterns
+        template<class T>
+        T lookupOrDefault
+        (
+            const word& keyword,
+            const T& deflt,
+            enum keyType::option matchOpt = keyType::REGEX
+        ) const
+        {
+            return getOrDefault<T>(keyword, deflt, matchOpt);
+        }
+
+
+        //- Find and return a T, or return the given default value
+        //- and add it to dictionary.
+        //- FatalIOError if it is found and the number of tokens is incorrect.
+        //
+        //  \param matchOpt the default search is non-recursive with patterns
+        template<class T>
+        T lookupOrAddDefault
+        (
+            const word& keyword,
+            const T& deflt,
+            enum keyType::option matchOpt = keyType::REGEX
+        )
+        {
+            return getOrAdd<T>(keyword, deflt, matchOpt);
+        }
+
+        //- Find and return a T, or return the given default value
+        //- using any compatibility names if needed.
+        //  Default search: non-recursive with patterns.
+        //
+        //  \param compat list of old compatibility keywords and the last
+        //      OpenFOAM version for which they were used.
+        //  \param recursive search parent dictionaries
+        //  \param patternMatch use regular expressions
+        template<class T>
+        T lookupOrDefaultCompat
+        (
+            const word& keyword,
+            std::initializer_list<std::pair<const char*,int>> compat,
+            const T& deflt,
+            enum keyType::option matchOpt = keyType::REGEX
+        ) const
+        {
+            return getOrDefaultCompat<T>(keyword, compat, deflt, matchOpt);
+        }
+
         //- Deprecated(2018-07) find and return an entry data stream
         //
         //  \deprecated(2018-07) - use lookup() method
diff --git a/src/OpenFOAM/db/dictionary/dictionaryCompat.C b/src/OpenFOAM/db/dictionary/dictionaryCompat.C
index c35d7f6b234..ca4a9a7cbb8 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryCompat.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryCompat.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -54,7 +54,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
 {
     const_searcher finder(csearch(keyword, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
         return finder;
     }
@@ -63,7 +63,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
     {
         finder = csearch(word::validate(iter.first), matchOpt);
 
-        if (finder.found())
+        if (finder.good())
         {
             // Only want a single warning (on master), but guard with a
             // parRun check to avoid Pstream::master() when Pstream has not
@@ -101,7 +101,7 @@ bool Foam::dictionary::foundCompat
     enum keyType::option matchOpt
 ) const
 {
-    return csearchCompat(keyword, compat, matchOpt).found();
+    return csearchCompat(keyword, compat, matchOpt).good();
 }
 
 
@@ -125,7 +125,7 @@ const Foam::entry& Foam::dictionary::lookupEntryCompat
 {
     const const_searcher finder(csearchCompat(keyword, compat, matchOpt));
 
-    if (!finder.found())
+    if (!finder.good())
     {
         FatalIOErrorInFunction(*this)
             << "Entry '" << keyword << "' not found in dictionary "
diff --git a/src/OpenFOAM/db/dictionary/dictionarySearch.C b/src/OpenFOAM/db/dictionary/dictionarySearch.C
index d3fcee91c45..59cebc461dd 100644
--- a/src/OpenFOAM/db/dictionary/dictionarySearch.C
+++ b/src/OpenFOAM/db/dictionary/dictionarySearch.C
@@ -130,7 +130,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped
     // a.b.c.d it would try
     // a.b, a.b.c, a.b.c.d
 
-    if (!finder.found())
+    if (!finder.good())
     {
         while (!finder.isDict())
         {
@@ -225,7 +225,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchSlashScoped
 
             auto finder = dictPtr->csearch(key, matchOpt);
 
-            if (finder.found())
+            if (finder.good())
             {
                 if (remaining)
                 {
@@ -269,7 +269,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearch
 
     auto iter = hashedEntries_.cfind(keyword);
 
-    if (iter.found())
+    if (iter.good())
     {
         finder.set(iter.val());
         return finder;
@@ -425,7 +425,7 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDict
 
             auto iter = dictPtr->hashedEntries_.cfind(cmpt);
 
-            if (iter.found())
+            if (iter.good())
             {
                 const entry *eptr = iter.val();
 
@@ -532,7 +532,7 @@ Foam::dictionary* Foam::dictionary::makeScopedDict(const fileName& dictPath)
 
             auto iter = dictPtr->hashedEntries_.find(cmptName);
 
-            if (iter.found())
+            if (iter.good())
             {
                 entry *eptr = iter.val();
 
@@ -581,7 +581,7 @@ bool Foam::dictionary::remove(const word& keyword)
 {
     auto iter = hashedEntries_.find(keyword);
 
-    if (iter.found())
+    if (iter.good())
     {
         // Delete from patterns
         auto wcLink = patterns_.begin();
@@ -621,7 +621,7 @@ bool Foam::dictionary::changeKeyword
     // Check that oldKeyword exists and can be changed
     auto iter = hashedEntries_.find(oldKeyword);
 
-    if (!iter.found())
+    if (!iter.good())
     {
         return false;
     }
@@ -638,7 +638,7 @@ bool Foam::dictionary::changeKeyword
     auto iter2 = hashedEntries_.find(newKeyword);
 
     // newKeyword already exists
-    if (iter2.found())
+    if (iter2.good())
     {
         if (overwrite)
         {
diff --git a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
index 31737707232..1ae164b5eca 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2017 OpenFOAM Foundation
@@ -64,6 +64,20 @@ T Foam::dictionary::get
 }
 
 
+template<class T, class Predicate>
+T Foam::dictionary::getCheck
+(
+    const word& keyword,
+    const Predicate& pred,
+    enum keyType::option matchOpt
+) const
+{
+    T val;
+    readCheck<T, Predicate>(keyword, val, pred, matchOpt);
+    return val;
+}
+
+
 template<class T>
 T Foam::dictionary::getCompat
 (
@@ -79,49 +93,111 @@ T Foam::dictionary::getCompat
 
 
 template<class T>
-bool Foam::dictionary::readCompat
+T Foam::dictionary::getOrDefault
 (
     const word& keyword,
-    std::initializer_list<std::pair<const char*,int>> compat,
-    T& val,
-    enum keyType::option matchOpt,
-    bool mandatory
+    const T& deflt,
+    enum keyType::option matchOpt
 ) const
 {
-    const const_searcher finder(csearchCompat(keyword, compat, matchOpt));
+    const const_searcher finder(csearch(keyword, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
+        T val;
+
         ITstream& is = finder.ptr()->stream();
         is >> val;
 
         checkITstream(is, keyword);
 
-        return true;
+        return val;
     }
-    else if (mandatory)
+    else if (writeOptionalEntries)
     {
-        FatalIOErrorInFunction(*this)
-            << "Entry '" << keyword << "' not found in dictionary "
-            << name()
-            << exit(FatalIOError);
+        if (writeOptionalEntries > 1)
+        {
+            FatalIOErrorInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Default '" << deflt << "' ignored" << nl
+                << exit(FatalIOError);
+        }
+        else
+        {
+            IOInfoInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Using default '" << deflt << "'" << nl;
+        }
     }
 
-    return false;
+    return deflt;
 }
 
 
 template<class T>
-T Foam::dictionary::lookupOrDefault
+T Foam::dictionary::getOrAdd
+(
+    const word& keyword,
+    const T& deflt,
+    enum keyType::option matchOpt
+)
+{
+    const const_searcher finder(csearch(keyword, matchOpt));
+
+    if (finder.good())
+    {
+        T val;
+
+        ITstream& is = finder.ptr()->stream();
+        is >> val;
+
+        checkITstream(is, keyword);
+
+        return val;
+    }
+    else if (writeOptionalEntries)
+    {
+        if (writeOptionalEntries > 1)
+        {
+            FatalIOErrorInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Default '" << deflt << "' ignored" << nl
+                << exit(FatalIOError);
+        }
+        else
+        {
+            IOInfoInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Adding default '" << deflt << "'" << nl;
+        }
+    }
+
+    add(new primitiveEntry(keyword, deflt));
+    return deflt;
+}
+
+
+template<class T, class Predicate>
+T Foam::dictionary::getCheckOrDefault
 (
     const word& keyword,
     const T& deflt,
+    const Predicate& pred,
     enum keyType::option matchOpt
 ) const
 {
+    if (!pred(deflt))
+    {
+        // Could be as FULLDEBUG instead?
+        FatalIOErrorInFunction(*this)
+            << "Entry '" << keyword << "' with invalid default in dictionary "
+            << name()
+            << exit(FatalIOError);
+    }
+
     const const_searcher finder(csearch(keyword, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
         T val;
 
@@ -130,31 +206,55 @@ T Foam::dictionary::lookupOrDefault
 
         checkITstream(is, keyword);
 
+        if (!pred(val))
+        {
+            raiseBadInput(keyword);
+        }
+
         return val;
     }
     else if (writeOptionalEntries)
     {
-        IOInfoInFunction(*this)
-            << "Optional entry '" << keyword
-            << "' not found, using default value '" << deflt << "'"
-            << nl;
+        if (writeOptionalEntries > 1)
+        {
+            FatalIOErrorInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Default '" << deflt << "' ignored" << nl
+                << exit(FatalIOError);
+        }
+        else
+        {
+            IOInfoInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Using default '" << deflt << "'" << nl;
+        }
     }
 
     return deflt;
 }
 
 
-template<class T>
-T Foam::dictionary::lookupOrAddDefault
+template<class T, class Predicate>
+T Foam::dictionary::getCheckOrAdd
 (
     const word& keyword,
     const T& deflt,
+    const Predicate& pred,
     enum keyType::option matchOpt
 )
 {
+    if (!pred(deflt))
+    {
+        // Could be as FULLDEBUG instead?
+        FatalIOErrorInFunction(*this)
+            << "Entry '" << keyword << "' with invalid default in dictionary "
+            << name()
+            << exit(FatalIOError);
+    }
+
     const const_searcher finder(csearch(keyword, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
         T val;
 
@@ -163,14 +263,28 @@ T Foam::dictionary::lookupOrAddDefault
 
         checkITstream(is, keyword);
 
+        if (!pred(val))
+        {
+            raiseBadInput(keyword);
+        }
+
         return val;
     }
     else if (writeOptionalEntries)
     {
-        IOInfoInFunction(*this)
-            << "Optional entry '" << keyword
-            << "' not found, adding default value '" << deflt << "'"
-            << nl;
+        if (writeOptionalEntries > 1)
+        {
+            FatalIOErrorInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Default '" << deflt << "' ignored" << nl
+                << exit(FatalIOError);
+        }
+        else
+        {
+            IOInfoInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Adding default '" << deflt << "'" << nl;
+        }
     }
 
     add(new primitiveEntry(keyword, deflt));
@@ -189,7 +303,7 @@ bool Foam::dictionary::readEntry
 {
     const const_searcher finder(csearch(keyword, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
         ITstream& is = finder.ptr()->stream();
         is >> val;
@@ -202,7 +316,78 @@ bool Foam::dictionary::readEntry
     {
         FatalIOErrorInFunction(*this)
             << "Entry '" << keyword << "' not found in dictionary "
-            << name()
+            << name() << nl
+            << exit(FatalIOError);
+    }
+
+    return false;
+}
+
+
+template<class T, class Predicate>
+bool Foam::dictionary::readCheck
+(
+    const word& keyword,
+    T& val,
+    const Predicate& pred,
+    enum keyType::option matchOpt,
+    bool mandatory
+) const
+{
+    const const_searcher finder(csearch(keyword, matchOpt));
+
+    if (finder.good())
+    {
+        ITstream& is = finder.ptr()->stream();
+        is >> val;
+
+        checkITstream(is, keyword);
+
+        if (!pred(val))
+        {
+            raiseBadInput(keyword);
+        }
+
+        return true;
+    }
+    else if (mandatory)
+    {
+        FatalIOErrorInFunction(*this)
+            << "Entry '" << keyword << "' not found in dictionary "
+            << name() << nl
+            << exit(FatalIOError);
+    }
+
+    return false;
+}
+
+
+template<class T>
+bool Foam::dictionary::readCompat
+(
+    const word& keyword,
+    std::initializer_list<std::pair<const char*,int>> compat,
+    T& val,
+    enum keyType::option matchOpt,
+    bool mandatory
+) const
+{
+    const const_searcher finder(csearchCompat(keyword, compat, matchOpt));
+
+    if (finder.good())
+    {
+        ITstream& is = finder.ptr()->stream();
+        is >> val;
+
+        checkITstream(is, keyword);
+
+        return true;
+    }
+    else if (mandatory)
+    {
+        FatalIOErrorInFunction(*this)
+            << "Entry '" << keyword << "' not found in dictionary "
+            << name() << nl
             << exit(FatalIOError);
     }
 
@@ -223,8 +408,22 @@ bool Foam::dictionary::readIfPresent
 }
 
 
+template<class T, class Predicate>
+bool Foam::dictionary::readCheckIfPresent
+(
+    const word& keyword,
+    T& val,
+    const Predicate& pred,
+    enum keyType::option matchOpt
+) const
+{
+    // Read is non-mandatory
+    return readCheck<T, Predicate>(keyword, val, pred, matchOpt, false);
+}
+
+
 template<class T>
-T Foam::dictionary::lookupOrDefaultCompat
+T Foam::dictionary::getOrDefaultCompat
 (
     const word& keyword,
     std::initializer_list<std::pair<const char*,int>> compat,
@@ -234,7 +433,7 @@ T Foam::dictionary::lookupOrDefaultCompat
 {
     const const_searcher finder(csearchCompat(keyword, compat, matchOpt));
 
-    if (finder.found())
+    if (finder.good())
     {
         T val;
 
@@ -247,10 +446,19 @@ T Foam::dictionary::lookupOrDefaultCompat
     }
     else if (writeOptionalEntries)
     {
-        IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' not found,"
-            << " using default value '" << deflt << "'"
-            << nl;
+        if (writeOptionalEntries > 1)
+        {
+            FatalIOErrorInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Default '" << deflt << "' ignored" << nl
+                << exit(FatalIOError);
+        }
+        else
+        {
+            IOInfoInFunction(*this)
+                << "Optional entry '" << keyword
+                << "' not found. Using default '" << deflt << "'" << nl;
+        }
     }
 
     return deflt;
diff --git a/src/OpenFOAM/db/dictionary/entry/entry.C b/src/OpenFOAM/db/dictionary/entry/entry.C
index 9bd55a3e050..7583c7bc81f 100644
--- a/src/OpenFOAM/db/dictionary/entry/entry.C
+++ b/src/OpenFOAM/db/dictionary/entry/entry.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           |
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2015 OpenFOAM Foundation
@@ -73,6 +73,25 @@ Foam::autoPtr<Foam::entry> Foam::entry::clone() const
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::entry::raiseBadInput(const ITstream& is) const
+{
+    const word& keyword = keyword_;
+
+    // Can use FatalIOError instead of SafeFatalIOError
+    // since predicate checks are not used at the earliest stages
+    FatalIOError
+    (
+        "",                 // functionName
+        "",                 // sourceFileName
+        0,                  // sourceFileLineNumber
+        this->name(),       // ioFileName
+        is.lineNumber()     // ioStartLineNumber
+    )
+        << "Entry '" << keyword << "' with invalid input" << nl << nl
+        << exit(FatalIOError);
+}
+
+
 void Foam::entry::checkITstream(const ITstream& is) const
 {
     const word& keyword = keyword_;
diff --git a/src/OpenFOAM/db/dictionary/entry/entry.H b/src/OpenFOAM/db/dictionary/entry/entry.H
index 1fe2e6b2d84..58180f5955b 100644
--- a/src/OpenFOAM/db/dictionary/entry/entry.H
+++ b/src/OpenFOAM/db/dictionary/entry/entry.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -109,6 +109,9 @@ private:
         //  \return True if it is a valid keyType.
         static bool getKeyword(keyType& keyword, Istream& is);
 
+        //- Emit IOError about bad input for the entry
+        void raiseBadInput(const ITstream& is) const;
+
 
 public:
 
@@ -272,6 +275,37 @@ public:
             checkITstream(is);
         }
 
+        //- Get a T from the stream,
+        //- FatalIOError if the number of tokens is incorrect.
+        //
+        //  \param pred the value check predicate
+        template<class T, class Predicate>
+        T getCheck(const Predicate& pred) const
+        {
+            T val;
+            readCheck<T>(val, pred);
+            return val;
+        }
+
+        //- Assign to T val,
+        //- FatalIOError if the number of tokens is incorrect.
+        //
+        //  \param val the value to read into
+        //  \param pred the value check predicate
+        template<class T, class Predicate>
+        void readCheck(T& val, const Predicate& pred) const
+        {
+            ITstream& is = this->stream();
+            is >> val;
+
+            checkITstream(is);
+            if (!pred(val))
+            {
+                raiseBadInput(is);
+            }
+        }
+
+
     // Write
 
         //- Write
diff --git a/src/OpenFOAM/db/dictionary/entry/entryIO.C b/src/OpenFOAM/db/dictionary/entry/entryIO.C
index 60b62f60d01..fbd29788289 100644
--- a/src/OpenFOAM/db/dictionary/entry/entryIO.C
+++ b/src/OpenFOAM/db/dictionary/entry/entryIO.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2018-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2016 OpenFOAM Foundation
@@ -246,7 +246,7 @@ bool Foam::entry::New
             const auto finder =
                 parentDict.csearchScoped(varName, keyType::REGEX_RECURSIVE);
 
-            if (finder.found())
+            if (finder.good())
             {
                 // Read as primitiveEntry
                 const keyType newKeyword(finder.ptr()->stream());
@@ -311,7 +311,7 @@ bool Foam::entry::New
         // How to manage duplicate entries
         bool mergeEntry = false;
 
-        if (finder.found())
+        if (finder.good())
         {
             // Use keyword from the found entry (ie, eliminate scoping chars)
             const keyType key = finder.ref().keyword();
diff --git a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C
index 6ab5618fa7d..b067fb76c48 100644
--- a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C
+++ b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C
@@ -65,7 +65,7 @@ bool Foam::functionEntries::removeEntry::execute
             // Remove scoped keyword, or keyword in the local scope
             auto finder(parentDict.searchScoped(key, keyType::LITERAL));
 
-            if (finder.found())
+            if (finder.good())
             {
                 finder.context().remove(finder.ptr()->keyword());
             }
diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
index 20487de8c95..cc0240be0ba 100644
--- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
+++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C
@@ -274,38 +274,38 @@ Foam::dimensioned<Type>::dimensioned
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Type>
-Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrDefault
+Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrDefault
 (
     const word& name,
     const dictionary& dict,
     const dimensionSet& dims,
-    const Type& defaultValue
+    const Type& deflt
 )
 {
     // checkDims = true
-    return dimensioned<Type>(name, dims, defaultValue, dict);
+    return dimensioned<Type>(name, dims, deflt, dict);
 }
 
 
 template<class Type>
-Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrDefault
+Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrDefault
 (
     const word& name,
     const dictionary& dict,
-    const Type& defaultValue
+    const Type& deflt
 )
 {
-    return dimensioned<Type>(name, dimless, defaultValue, dict);
+    return dimensioned<Type>(name, dimless, deflt, dict);
 }
 
 
 template<class Type>
-Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict
+Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrAddToDict
 (
     const word& name,
     dictionary& dict,
     const dimensionSet& dims,
-    const Type& defaultValue
+    const Type& deflt
 )
 {
     if (dict.found(name))
@@ -313,20 +313,20 @@ Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict
         return dimensioned<Type>(name, dims, dict);
     }
 
-    (void) dict.add(name, defaultValue);
-    return dimensioned<Type>(name, dims, defaultValue);
+    (void) dict.add(name, deflt);
+    return dimensioned<Type>(name, dims, deflt);
 }
 
 
 template<class Type>
-Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict
+Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrAddToDict
 (
     const word& name,
     dictionary& dict,
-    const Type& defaultValue
+    const Type& deflt
 )
 {
-    return lookupOrAddToDict(name, dict, dimless, defaultValue);
+    return getOrAddToDict(name, dict, dimless, deflt);
 }
 
 
diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
index 982ab31c7df..2e768cbda56 100644
--- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
+++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H
@@ -207,42 +207,42 @@ public:
 
         //- Construct dimensioned from dictionary, with default value.
         //- FatalIOError if there are excess tokens.
-        static dimensioned<Type> lookupOrDefault
+        static dimensioned<Type> getOrDefault
         (
             const word& name,
             const dictionary& dict,
             const dimensionSet& dims = dimless,
-            const Type& defaultValue = Type(Zero)
+            const Type& deflt = Type(Zero)
         );
 
         //- Construct dimensionless from dictionary, with default value.
         //  FatalIOError if it is found and there are excess tokens.
-        static dimensioned<Type> lookupOrDefault
+        static dimensioned<Type> getOrDefault
         (
             const word& name,
             const dictionary& dict,
-            const Type& defaultValue = Type(Zero)
+            const Type& deflt = Type(Zero)
         );
 
         //- Construct dimensioned from dictionary, with default value.
         //  If the value is not found, it is added into the dictionary.
         //  FatalIOError if it is found and there are excess tokens.
-        static dimensioned<Type> lookupOrAddToDict
+        static dimensioned<Type> getOrAddToDict
         (
             const word& name,
             dictionary& dict,
             const dimensionSet& dims = dimless,
-            const Type& defaultValue = Type(Zero)
+            const Type& deflt = Type(Zero)
         );
 
         //- Construct dimensionless from dictionary, with default value.
         //  If the value is not found, it is added into the dictionary.
         //  FatalIOError if it is found and there are excess tokens.
-        static dimensioned<Type> lookupOrAddToDict
+        static dimensioned<Type> getOrAddToDict
         (
             const word& name,
             dictionary& dict,
-            const Type& defaultValue = Type(Zero)
+            const Type& deflt = Type(Zero)
         );
 
 
@@ -361,6 +361,59 @@ public:
         //      dictionary instead (additional checks on the input stream).
         dimensioned(const word& name, const dimensionSet& dims, Istream& is)
         FOAM_DEPRECATED(2018-11);
+
+
+        //- Construct dimensioned from dictionary, with default value.
+        //- FatalIOError if there are excess tokens.
+        static dimensioned<Type> lookupOrDefault
+        (
+            const word& name,
+            const dictionary& dict,
+            const dimensionSet& dims = dimless,
+            const Type& deflt = Type(Zero)
+        )
+        {
+            return getOrDefault(name, dict, dims, deflt);
+        }
+
+        //- Construct dimensionless from dictionary, with default value.
+        //  FatalIOError if it is found and there are excess tokens.
+        static dimensioned<Type> lookupOrDefault
+        (
+            const word& name,
+            const dictionary& dict,
+            const Type& deflt = Type(Zero)
+        )
+        {
+            return getOrDefault(name, dict, deflt);
+        }
+
+        //- Construct dimensioned from dictionary, with default value.
+        //  If the value is not found, it is added into the dictionary.
+        //  FatalIOError if it is found and there are excess tokens.
+        static dimensioned<Type> lookupOrAddToDict
+        (
+            const word& name,
+            dictionary& dict,
+            const dimensionSet& dims = dimless,
+            const Type& deflt = Type(Zero)
+        )
+        {
+            return getOrAddToDict(name, dict, dims, deflt);
+        }
+
+        //- Construct dimensionless from dictionary, with default value.
+        //  If the value is not found, it is added into the dictionary.
+        //  FatalIOError if it is found and there are excess tokens.
+        static dimensioned<Type> lookupOrAddToDict
+        (
+            const word& name,
+            dictionary& dict,
+            const Type& deflt = Type(Zero)
+        )
+        {
+            return getOrAddToDict(name, dict, deflt);
+        }
 };
 
 
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index f9daf29dc8b..2ac39189fe8 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -1168,7 +1168,7 @@ void Foam::argList::parse
 
                 decompDict.readEntry("numberOfSubdomains", dictNProcs);
 
-                if (decompDict.lookupOrDefault("distributed", false))
+                if (decompDict.getOrDefault("distributed", false))
                 {
                     parRunControl_.distributed(true);
                     decompDict.readEntry("roots", roots);
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index d505a534aef..422818c5a28 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -124,7 +124,7 @@ namespace Foam
 
 class argList
 {
-    // Private data
+    // Private Data
 
         //- Track if command arguments are mandatory/optional
         static bool argsMandatory_;
@@ -383,7 +383,7 @@ public:
         inline T opt(const word& optName) const;
 
         //- Get a value from the named option if present, or return default.
-        //  Identical to lookupOrDefault().
+        //  Identical to getOrDefault().
         template<class T>
         inline T opt(const word& optName, const T& deflt) const;
 
@@ -405,7 +405,7 @@ public:
 
         //- Get a value from the named option if present, or return default.
         template<class T>
-        inline T lookupOrDefault
+        inline T getOrDefault
         (
             const word& optName,
             const T& deflt
@@ -590,6 +590,16 @@ public:
         inline const string& operator[](const word& optName) const;
 
 
+    // Housekeeping
+
+        //- Get a value from the named option if present, or return default.
+        template<class T>
+        T lookupOrDefault(const word& optName, const T& deflt) const
+        {
+            return getOrDefault<T>(optName, deflt);
+        }
+
+
     // Older style access (including 1712 release)
 
     #ifdef Foam_argList_1712
@@ -598,7 +608,8 @@ public:
         //  Index 1 is the first (non-option) argument.
         //  \deprecated(2018-08) - use get() method
         template<class T>
-        inline T read(const label index) const
+        T FOAM_DEPRECATED_FOR(2018-08, "get() method")
+        read(const label index) const
         {
             return this->get<T>(index);
         }
@@ -607,21 +618,24 @@ public:
         //  Index 1 is the first (non-option) argument.
         //  \deprecated(2018-01) - use get() method
         template<class T>
-        inline T argRead(const label index) const
+        T FOAM_DEPRECATED_FOR(2018-01, "get() method")
+        argRead(const label index) const
         {
             return this->get<T>(index);
         }
 
         //- Deprecated(2018-01) return true if the named option is found
         //  \deprecated(2018-01) - use found() method
-        inline bool optionFound(const word& optName) const
+        bool FOAM_DEPRECATED_FOR(2018-01, "found() method")
+        optionFound(const word& optName) const
         {
             return found(optName);
         }
 
         //- Deprecated(2018-01) return an input stream from the named option
         //  \deprecated(2018-01) - use lookup() method
-        inline ITstream optionLookup(const word& optName) const
+        ITstream FOAM_DEPRECATED_FOR(2018-01, "lookup() method")
+        optionLookup(const word& optName) const
         {
             return lookup(optName);
         }
@@ -629,7 +643,8 @@ public:
         //- Deprecated(2018-01) read a value from the named option
         //  \deprecated(2018-01) - use opt() method
         template<class T>
-        inline T optionRead(const word& optName) const
+        T FOAM_DEPRECATED_FOR(2018-01, "opt() method")
+        optionRead(const word& optName) const
         {
             return opt<T>(optName);
         }
@@ -638,7 +653,8 @@ public:
         //  Return true if the named option was found.
         //  \deprecated(2018-01) - use readIfPresent() method
         template<class T>
-        inline bool optionReadIfPresent
+        bool FOAM_DEPRECATED_FOR(2018-01, "readIfPresent() method")
+        optionReadIfPresent
         (
             const word& optName,
             T& val
@@ -652,7 +668,8 @@ public:
         //  use the supplied default and return false.
         //  \deprecated(2018-01) - use readIfPresent() method
         template<class T>
-        inline bool optionReadIfPresent
+        bool FOAM_DEPRECATED_FOR(2018-01, "readIfPresent() method")
+        optionReadIfPresent
         (
             const word& optName,
             T& val,
@@ -664,21 +681,23 @@ public:
 
         //- Deprecated(2018-01) read a value from the named option if present.
         //  Return supplied default otherwise.
-        //  \deprecated(2018-01) - use lookupOrDefault() method
+        //  \deprecated(2018-01) - use getOrDefault() method
         template<class T>
-        inline T optionLookupOrDefault
+        T FOAM_DEPRECATED_FOR(2018-01, "getOrDefault() method")
+        optionLookupOrDefault
         (
             const word& optName,
             const T& deflt
         ) const
         {
-            return lookupOrDefault<T>(optName, deflt);
+            return getOrDefault<T>(optName, deflt);
         }
 
         //- Deprecated(2018-01) read a List of values from the named option
         //  \deprecated(2018-01) - use getList() method
         template<class T>
-        inline List<T> optionReadList(const word& optName) const
+        List<T> FOAM_DEPRECATED_FOR(2018-01, "getList() method")
+        optionReadList(const word& optName) const
         {
             return this->getList<T>(optName);
         }
diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H
index 4186d6e4af8..54e4ac9d8e2 100644
--- a/src/OpenFOAM/global/argList/argListI.H
+++ b/src/OpenFOAM/global/argList/argListI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2017-2018 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017-2019 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
                             | Copyright (C) 2011-2013 OpenFOAM Foundation
@@ -316,7 +316,7 @@ inline bool Foam::argList::readIfPresent
 
 
 template<class T>
-inline T Foam::argList::lookupOrDefault
+inline T Foam::argList::getOrDefault
 (
     const word& optName,
     const T& deflt
diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.C b/src/OpenFOAM/primitives/bools/Switch/Switch.C
index 56fc8fee687..7d7e780fdf6 100644
--- a/src/OpenFOAM/primitives/bools/Switch/Switch.C
+++ b/src/OpenFOAM/primitives/bools/Switch/Switch.C
@@ -110,14 +110,14 @@ Foam::Switch::switchType Foam::Switch::parse
 }
 
 
-Foam::Switch Foam::Switch::lookupOrAddToDict
+Foam::Switch Foam::Switch::getOrAddToDict
 (
     const word& name,
     dictionary& dict,
-    const Switch defaultValue
+    const Switch deflt
 )
 {
-    return dict.lookupOrAddDefault<Switch>(name, defaultValue);
+    return dict.getOrAdd<Switch>(name, deflt);
 }
 
 
@@ -146,10 +146,10 @@ Foam::Switch::Switch
 (
     const word& key,
     const dictionary& dict,
-    const Switch defaultValue
+    const Switch deflt
 )
 :
-    Switch(defaultValue)
+    Switch(deflt)
 {
     const entry* eptr = dict.findEntry(key, keyType::LITERAL);
 
diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.H b/src/OpenFOAM/primitives/bools/Switch/Switch.H
index 0ab2a3ae0d2..90723889754 100644
--- a/src/OpenFOAM/primitives/bools/Switch/Switch.H
+++ b/src/OpenFOAM/primitives/bools/Switch/Switch.H
@@ -169,7 +169,7 @@ public:
         (
             const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
             const dictionary& dict, //!< dictionary
-            const Switch defaultValue //!< fallback if not found
+            const Switch deflt      //!< fallback if not found
         );
 
         //- Construct from Istream
@@ -180,11 +180,11 @@ public:
 
         //- Construct from dictionary, supplying default value so that if the
         //- value is not found, it is added into the dictionary.
-        static Switch lookupOrAddToDict
+        static Switch getOrAddToDict
         (
             const word& name,           //!< Lookup key. Uses REGEX!
             dictionary& dict,           //!< dictionary
-            const Switch defaultValue = switchType::FALSE //!< default to add
+            const Switch deflt = switchType::FALSE //!< default to add
         );
 
 
@@ -235,6 +235,18 @@ public:
 
     // Housekeeping
 
+        //- Construct from dictionary, supplying default value so that if the
+        //- value is not found, it is added into the dictionary.
+        static Switch lookupOrAddToDict
+        (
+            const word& name,           //!< Lookup key. Uses REGEX!
+            dictionary& dict,           //!< dictionary
+            const Switch deflt = switchType::FALSE //!< default to add
+        )
+        {
+            return getOrAddToDict(name, dict, deflt);
+        }
+
         //- Deprecated(2018-03) text representation of the Switch value
         //  \deprecated(2018-03) - use c_str() method
         inline const char* asText() const { return c_str(); };
diff --git a/src/OpenFOAM/primitives/enums/Enum.C b/src/OpenFOAM/primitives/enums/Enum.C
index 1e269ff4ede..1ef0c4cc51c 100644
--- a/src/OpenFOAM/primitives/enums/Enum.C
+++ b/src/OpenFOAM/primitives/enums/Enum.C
@@ -81,14 +81,14 @@ template<class EnumType>
 EnumType Foam::Enum<EnumType>::get
 (
     const word& enumName,
-    const EnumType defaultValue
+    const EnumType deflt
 ) const
 {
     const label idx = find(enumName);
 
     if (idx < 0)
     {
-        return defaultValue;
+        return deflt;
     }
 
     return EnumType(vals_[idx]);
@@ -136,11 +136,11 @@ EnumType Foam::Enum<EnumType>::get
 
 
 template<class EnumType>
-EnumType Foam::Enum<EnumType>::lookupOrDefault
+EnumType Foam::Enum<EnumType>::getOrDefault
 (
     const word& key,
     const dictionary& dict,
-    const EnumType defaultValue,
+    const EnumType deflt,
     const bool failsafe
 ) const
 {
@@ -163,8 +163,8 @@ EnumType Foam::Enum<EnumType>::lookupOrDefault
         {
             IOWarningInFunction(dict)
                 << enumName << " is not in enumeration: " << *this << nl
-                << "using failsafe " << get(defaultValue)
-                << " (value " << int(defaultValue) << ")" << endl;
+                << "using failsafe " << get(deflt)
+                << " (value " << int(deflt) << ")" << endl;
         }
         else
         {
@@ -174,7 +174,7 @@ EnumType Foam::Enum<EnumType>::lookupOrDefault
         }
     }
 
-    return defaultValue;
+    return deflt;
 }
 
 
diff --git a/src/OpenFOAM/primitives/enums/Enum.H b/src/OpenFOAM/primitives/enums/Enum.H
index b5ef2a36244..ede847bfc90 100644
--- a/src/OpenFOAM/primitives/enums/Enum.H
+++ b/src/OpenFOAM/primitives/enums/Enum.H
@@ -132,7 +132,7 @@ public:
 
         //- The enumeration corresponding to the given name.
         //  \return The enumeration or default if not found.
-        EnumType get(const word& enumName, const EnumType defaultValue) const;
+        EnumType get(const word& enumName, const EnumType deflt) const;
 
         //- The name corresponding to the given enumeration.
         //  Return an empty word if not found.
@@ -155,11 +155,11 @@ public:
         //
         //  \return The value found or default if not found in dictionary.
         //  FatalError (or Warning) if the enumerated name was incorrect.
-        EnumType lookupOrDefault
+        EnumType getOrDefault
         (
             const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
             const dictionary& dict, //!< dictionary
-            const EnumType defaultValue, //!< fallback if not found
+            const EnumType deflt,   //!< fallback if not found
             const bool failsafe = false  //!< Warn only on bad enumeration
         ) const;
 
@@ -216,33 +216,51 @@ public:
         inline const word& operator[](const EnumType e) const;
 
         //- Return the enumeration corresponding to the given name or
-        //- defaultValue if the name is not found.
+        //- deflt if the name is not found.
         inline EnumType operator()
         (
             const word& enumName,
-            const EnumType defaultValue
+            const EnumType deflt
         ) const;
 
 
     // Housekeeping
 
+        //- Find the key in the dictionary and return the corresponding
+        //- enumeration element based on its name.
+        //
+        //  \return The value found or default if not found in dictionary.
+        //  FatalError (or Warning) if the enumerated name was incorrect.
+        EnumType lookupOrDefault
+        (
+            const word& key,        //!< Lookup key. Uses LITERAL (not REGEX)
+            const dictionary& dict, //!< dictionary
+            const EnumType deflt,   //!< fallback if not found
+            const bool failsafe = false //!< Warn only on bad enumeration
+        ) const
+        {
+            return getOrDefault(key, dict, deflt, failsafe);
+        }
+
         //- Deprecated(2018-10) same as two-parameter get()
         //  \deprecated(2018-10) - use two-parameter get() method
-        inline EnumType lookup(const word& key, const dictionary& dict) const
+        EnumType FOAM_DEPRECATED_FOR(2018-10, "get() method")
+        lookup(const word& key, const dictionary& dict) const
         {
             return get(key, dict);
         }
 
         //- Deprecated(2018-10) lookupOrDefault with warnings instead of error.
-        //  \deprecated(2018-10) - use lookupOrDefault() with failsafe option
-        EnumType lookupOrFailsafe
+        //  \deprecated(2018-10) - use getOrDefault() with failsafe option
+        EnumType FOAM_DEPRECATED_FOR(2018-10, "getOrDefault() method")
+        lookupOrFailsafe
         (
             const word& key,
             const dictionary& dict,
-            const EnumType defaultValue
+            const EnumType deflt
         ) const
         {
-            return lookupOrDefault(key, dict, defaultValue, true);
+            return getOrDefault(key, dict, deflt, true);
         }
 };
 
diff --git a/src/OpenFOAM/primitives/ops/ops.H b/src/OpenFOAM/primitives/ops/ops.H
index c47888e8d78..2692eff18f6 100644
--- a/src/OpenFOAM/primitives/ops/ops.H
+++ b/src/OpenFOAM/primitives/ops/ops.H
@@ -27,9 +27,9 @@ InNamespace
     Foam
 
 Description
-    Various function objects for unary and binary operations.
+    Various functors for unary and binary operations.
     Can be used for parallel combine-reduce operations or other places
-    requiring a function object.
+    requiring a functor.
 
 \*---------------------------------------------------------------------------*/
 
@@ -159,6 +159,25 @@ EqOp(nopEq, (void)x)
     };
 
 
+// Operations taking one parameter, returning bool.
+// The comparison value is defined during construction
+
+#define Bool1Op(opName, op)                                                    \
+                                                                               \
+    template<class T>                                                          \
+    struct opName##Op1                                                         \
+    {                                                                          \
+        const T& value;                                                        \
+                                                                               \
+        opName##Op1(const T& v) : value(v) {}                                  \
+                                                                               \
+        bool operator()(const T& x) const WARNRETURN                           \
+        {                                                                      \
+            return op;                                                         \
+        }                                                                      \
+    };
+
+
 // Weighting operations
 
 #define WeightedOp(opName, op)                                                 \
@@ -216,10 +235,18 @@ BoolOp(lessEq, x <= y)
 BoolOp(greater, x > y)
 BoolOp(greaterEq, x >= y)
 
+Bool1Op(equal, x == value)
+Bool1Op(notEqual, x != value)
+Bool1Op(less, x < value)
+Bool1Op(lessEq, x <= value)
+Bool1Op(greater, x > value)
+Bool1Op(greaterEq, x >= value)
+
 WeightedOp(multiply, (weight*y))
 
 #undef Op
 #undef BoolOp
+#undef Bool1Op
 #undef WeightedOp
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
index 59b1f162010..6c78dfccc9d 100644
--- a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
+++ b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H
@@ -161,6 +161,12 @@ public:
 
     // Static Member Functions
 
+        //- A semi-infinite range from minVal to the type max
+        inline static MinMax<T> ge(const T& minVal);
+
+        //- A semi-infinite range from type min to maxVal
+        inline static MinMax<T> le(const T& maxVal);
+
         //- A 0-1 range corresponding to the pTraits zero, one
         inline static MinMax<T> zero_one();
 
diff --git a/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H b/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H
index afdf34916d4..d6ef1ab38e1 100644
--- a/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H
+++ b/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H
@@ -25,6 +25,20 @@ License
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
+template<class T>
+inline Foam::MinMax<T> Foam::MinMax<T>::ge(const T& minVal)
+{
+    return MinMax<T>(minVal, pTraits<T>::max);
+}
+
+
+template<class T>
+inline Foam::MinMax<T> Foam::MinMax<T>::le(const T& maxVal)
+{
+    return MinMax<T>(pTraits<T>::min, maxVal);
+}
+
+
 template<class T>
 inline Foam::MinMax<T> Foam::MinMax<T>::zero_one()
 {
diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C
index 221101fcf03..0786ed5ce73 100644
--- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C
+++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C
@@ -36,8 +36,8 @@ const Foam::scalarRange Foam::scalarRange::null;
 const Foam::scalarRange Foam::scalarRange::always
 (
     scalarRange::ALWAYS,
-    -Foam::GREAT,
-    Foam::GREAT
+    -GREAT,
+    GREAT
 );
 
 
@@ -158,21 +158,21 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const scalarRange& range)
     switch (range.type_)
     {
         case scalarRange::EQ:
-            os << range.min_;
+            os << range.min();
             break;
 
         case scalarRange::GE:
         case scalarRange::GT:
-            os << range.min_ << ":Inf";
+            os << range.min() << ":Inf";
             break;
 
         case scalarRange::LE:
         case scalarRange::LT:
-            os << "-Inf:" << range.max_;
+            os << "-Inf:" << range.max();
             break;
 
         case scalarRange::GE_LE:
-            os << range.min_ << ':' << range.max_;
+            os << range.min() << ':' << range.max();
             break;
 
         case scalarRange::ALWAYS:
diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H
index 973f446de2d..f71c97cf493 100644
--- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H
+++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H
@@ -34,6 +34,7 @@ Description
     used to define an empty (inverse) range.
 
 SeeAlso
+    Foam::MinMax
     Foam::predicates::scalars
 
 SourceFiles
@@ -154,18 +155,27 @@ public:
         static scalarRange parse(const std::string& str);
 
 
-        //- Construct a greater-than-equals bound
+        //- Construct a greater-equals bound
         inline static scalarRange ge(const scalar minVal) noexcept;
 
         //- Construct a greater-than bound
         inline static scalarRange gt(const scalar minVal) noexcept;
 
-        //- Construct a less-than-equals bound
+        //- Construct a greater-equals zero bound
+        inline static scalarRange ge0() noexcept;
+
+        //- Construct a greater-than zero bound
+        inline static scalarRange gt0() noexcept;
+
+        //- Construct a less-equals bound
         inline static scalarRange le(const scalar maxVal) noexcept;
 
         //- Construct a less-than bound
         inline static scalarRange lt(const scalar maxVal) noexcept;
 
+        //- Construct a greater-equals 0, less-equals 1 bound
+        inline static scalarRange zero_one() noexcept;
+
 
     // Member Functions
 
@@ -192,13 +202,13 @@ public:
         inline scalar value() const;
 
         //- True if the value matches the condition.
-        inline bool match(const scalar& value) const;
+        inline bool match(const scalar& val) const;
 
 
     // Member Operators
 
         //- Identical to match(), for use as a predicate.
-        inline bool operator()(const scalar& value) const;
+        inline bool operator()(const scalar& val) const;
 
         inline bool operator==(const scalarRange& rhs) const noexcept;
         inline bool operator!=(const scalarRange& rhs) const noexcept;
diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H
index 7de2ee93b76..42081f16272 100644
--- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H
+++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H
@@ -40,7 +40,7 @@ inline Foam::scalarRange::scalarRange
 
 inline Foam::scalarRange::scalarRange() noexcept
 :
-    scalarRange(scalarRange::NONE, Foam::GREAT, -Foam::GREAT)
+    scalarRange(scalarRange::NONE, GREAT, -GREAT)
 {}
 
 
@@ -62,7 +62,7 @@ inline Foam::scalarRange::scalarRange
     {
         clear();  // Inverted - explicitly mark as such
     }
-    else if (minVal == maxVal)
+    else if (equal(minVal, maxVal))
     {
         type_ = EQ;
     }
@@ -71,24 +71,42 @@ inline Foam::scalarRange::scalarRange
 
 inline Foam::scalarRange Foam::scalarRange::ge(const scalar minVal) noexcept
 {
-    return scalarRange(GE, minVal, Foam::VGREAT);
+    return scalarRange(scalarRange::GE, minVal, GREAT);
 }
 
 
 inline Foam::scalarRange Foam::scalarRange::gt(const scalar minVal) noexcept
 {
-    return scalarRange(GT, minVal, Foam::VGREAT);
+    return scalarRange(scalarRange::GT, minVal, GREAT);
+}
+
+
+inline Foam::scalarRange Foam::scalarRange::ge0() noexcept
+{
+    return scalarRange(scalarRange::GE, 0, GREAT);
+}
+
+
+inline Foam::scalarRange Foam::scalarRange::gt0() noexcept
+{
+    return scalarRange(scalarRange::GT, 0, GREAT);
 }
 
 
 inline Foam::scalarRange Foam::scalarRange::le(const scalar maxVal) noexcept
 {
-    return scalarRange(LE, -Foam::VGREAT, maxVal);
+    return scalarRange(scalarRange::LE, -GREAT, maxVal);
 }
 
 inline Foam::scalarRange Foam::scalarRange::lt(const scalar maxVal) noexcept
 {
-    return scalarRange(LT, -Foam::VGREAT, maxVal);
+    return scalarRange(scalarRange::LT, -GREAT, maxVal);
+}
+
+
+inline Foam::scalarRange Foam::scalarRange::zero_one() noexcept
+{
+    return scalarRange(scalarRange::GE_LE, 0, 1);
 }
 
 
@@ -96,8 +114,8 @@ inline Foam::scalarRange Foam::scalarRange::lt(const scalar maxVal) noexcept
 
 inline void Foam::scalarRange::clear() noexcept
 {
-    min_ = Foam::GREAT;
-    max_ = -Foam::GREAT;
+    min_ = GREAT;
+    max_ = -GREAT;
     type_ = scalarRange::NONE;
 }
 
@@ -136,16 +154,16 @@ inline Foam::scalar Foam::scalarRange::value() const
 {
     switch (type_)
     {
-        case EQ:    // For equals, min and max are identical
-        case GE:
-        case GT:
+        case scalarRange::EQ: // For equals, min and max are identical
+        case scalarRange::GE:
+        case scalarRange::GT:
             return min_;
 
-        case LE:
-        case LT:
+        case scalarRange::LE:
+        case scalarRange::LT:
             return max_;
 
-        case GE_LE:
+        case scalarRange::GE_LE:
             // Multiply before adding to avoid possible overflow
             return (0.5 * min_) + (0.5 * max_);
 
@@ -155,16 +173,16 @@ inline Foam::scalar Foam::scalarRange::value() const
 }
 
 
-inline bool Foam::scalarRange::match(const scalar& value) const
+inline bool Foam::scalarRange::match(const scalar& val) const
 {
     switch (type_)
     {
-        case EQ:    return equal(value, min_);
-        case GE:    return (value >= min_);
-        case GT:    return (value > min_);
-        case LE:    return (value <= max_);
-        case LT:    return (value < max_);
-        case GE_LE: return (value >= min_ && value <= max_);
+        case EQ:    return equal(val, min_);
+        case GE:    return (val >= min_);
+        case GT:    return (val > min_);
+        case LE:    return (val <= max_);
+        case LT:    return (val < max_);
+        case GE_LE: return (val >= min_ && val <= max_);
         case ALWAYS: return true;
         default:    return false;
     }
@@ -173,9 +191,9 @@ inline bool Foam::scalarRange::match(const scalar& value) const
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
-inline bool Foam::scalarRange::operator()(const scalar& value) const
+inline bool Foam::scalarRange::operator()(const scalar& val) const
 {
-    return match(value);
+    return match(val);
 }
 
 
diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H
index 1de90bb0f5d..d94795b4308 100644
--- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H
+++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H
@@ -67,7 +67,11 @@ public:
         //- Construct by parsing string for scalar ranges
         //  The individual items are space, comma or semicolon delimited.
         //  Optionally report when any range failed to parse
-        inline scalarRanges(const std::string& str, bool verbose = true);
+        inline explicit scalarRanges
+        (
+            const std::string& str,
+            bool verbose = true
+        );
 
 
     // Static Constructors
-- 
GitLab