diff --git a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C
index 2f95d40f713993a5b5ba4888845696ab0b68e738..0661cbf8d9110630010c182e572653fa7924a7bb 100644
--- a/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C
+++ b/src/OpenFOAM/containers/Dictionaries/DictionaryBase/DictionaryBase.C
@@ -138,7 +138,7 @@ const T* Foam::DictionaryBase<IDLListType, T>::lookup(const word& keyword) const
     if (iter == hashedTs_.end())
     {
         FatalErrorInFunction
-            << keyword << " is undefined"
+            << "'" << keyword << "' not found"
             << exit(FatalError);
     }
 
@@ -154,7 +154,7 @@ T* Foam::DictionaryBase<IDLListType, T>::lookup(const word& keyword)
     if (iter == hashedTs_.end())
     {
         FatalErrorInFunction
-            << keyword << " is undefined"
+            << "'" << keyword << "' not found"
             << exit(FatalError);
     }
 
diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C
index 6223da9e0f59ea402f5ae8edcbd30f1277aaf3b3..f2adc1b5980a206a1ba01244389e5fc242eb7811 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.C
+++ b/src/OpenFOAM/db/dictionary/dictionary.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,8 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "dictionary.H"
+#include "error.H"
+#include "JobInfo.H"
 #include "primitiveEntry.H"
 #include "dictionaryEntry.H"
 #include "regExp.H"
@@ -48,7 +50,6 @@ bool Foam::dictionary::writeOptionalEntries
 
 void Foam::dictionary::excessTokens
 (
-    OSstream& msg,
     const word& keyword,
     const ITstream& is
 ) const
@@ -60,12 +61,44 @@ void Foam::dictionary::excessTokens
         return;
     }
 
-    msg << "entry '" << keyword << "' has "
-        << nExcess << " excess tokens, near line: " << is.lineNumber() << nl
-        << "dictionary: " << name() << nl
-        << "stream:  ";
-    is.writeList(msg, 0);
-    msg << nl;
+    // Similar to SafeFatalIOError
+
+    if (JobInfo::constructed)
+    {
+        OSstream& err =
+            FatalIOError
+            (
+                "",                 // functionName
+                "",                 // sourceFileName
+                0,                  // sourceFileLineNumber
+                this->name(),       // ioFileName
+                is.lineNumber()     // ioStartLineNumber
+            );
+
+        err << "'" << keyword << "' has "
+            << nExcess << " excess tokens in stream" << nl << nl
+            << "    ";
+        is.writeList(err, 0);
+
+        err << exit(FatalIOError);
+    }
+    else
+    {
+        std::cerr
+            << nl
+            << "--> FOAM FATAL IO ERROR:" << nl;
+
+        std::cerr
+            << "'" << keyword << "' has "
+            << nExcess << " excess tokens in stream" << nl << nl;
+
+        std::cerr
+            << "file: " << this->name()
+            << " at line " << is.lineNumber() << '.' << nl
+            << std::endl;
+
+        ::exit(1);
+    }
 }
 
 
@@ -296,10 +329,8 @@ const Foam::entry& Foam::dictionary::lookupEntry
 
     if (!finder.found())
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "keyword " << keyword << " is undefined in dictionary "
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
             << name()
             << exit(FatalIOError);
     }
@@ -422,10 +453,8 @@ const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
 
     if (!finder.found())
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "keyword " << keyword << " is undefined in dictionary "
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
             << name()
             << exit(FatalIOError);
     }
@@ -441,10 +470,8 @@ Foam::dictionary& Foam::dictionary::subDict(const word& keyword)
 
     if (!finder.found())
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "keyword " << keyword << " is undefined in dictionary "
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
             << name()
             << exit(FatalIOError);
     }
@@ -470,20 +497,18 @@ Foam::dictionary Foam::dictionary::subOrEmptyDict
 
     if (mustRead)
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "keyword " << keyword
-            << " is not a sub-dictionary in dictionary "
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword
+            << "' is not a sub-dictionary in dictionary "
             << name()
             << exit(FatalIOError);
     }
 
     if (finder.found())
     {
-        IOWarningInFunction((*this))
-            << "keyword " << keyword
-            << " found but not a sub-dictionary in dictionary "
+        IOWarningInFunction(*this)
+            << "'" << keyword
+            << "' found but not a sub-dictionary in dictionary "
             << name() << endl;
     }
 
@@ -506,9 +531,9 @@ const Foam::dictionary& Foam::dictionary::optionalSubDict
 
     if (finder.found())
     {
-        IOWarningInFunction((*this))
-            << "keyword " << keyword
-            << " found but not a sub-dictionary in dictionary "
+        IOWarningInFunction(*this)
+            << "'" << keyword
+            << "' found but not a sub-dictionary in dictionary "
             << name() << endl;
     }
 
@@ -597,7 +622,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
         }
 
 
-        IOWarningInFunction((*this))
+        IOWarningInFunction(*this)
             << "problem replacing entry "<< entryPtr->keyword()
             << " in dictionary " << name() << endl;
 
@@ -626,7 +651,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
     }
 
 
-    IOWarningInFunction((*this))
+    IOWarningInFunction(*this)
         << "attempt to add entry " << entryPtr->keyword()
         << " which already exists in dictionary " << name()
         << endl;
diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H
index e5e6641b4d514cab2e6ab16144e3a76e2641aaff..2a8f95ec254792d031eb38dab6db783e40d2fa0f 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.H
+++ b/src/OpenFOAM/db/dictionary/dictionary.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -143,18 +143,18 @@ public:
             return name_;
         }
 
-        //- Return the dictionary name
+        //- Return the dictionary name for modification (use with caution).
         fileName& name()
         {
             return name_;
         }
 
         //- Return the local dictionary name (final part of scoped name)
-        const word dictName() const
+        word dictName() const
         {
-            const word scopedName = name_.name();
-            const auto i = scopedName.rfind('.');
+            word scopedName(name_.name());
 
+            const auto i = scopedName.rfind('.');
             if (i == std::string::npos)
             {
                 return scopedName;
@@ -383,13 +383,8 @@ private:
         ) const;
 
 
-        //- Add report of excess tokens to the messageStream
-        void excessTokens
-        (
-            OSstream& msg,
-            const word& keyword,
-            const ITstream& is
-        ) const;
+        //- Emit FatalIOError if excess tokens exist
+        void excessTokens(const word& keyword, const ITstream& is) const;
 
 
 public:
@@ -505,7 +500,7 @@ public:
         ) const;
 
         //- Find and return an entry pointer for manipulation if present,
-        //  or return a nullptr.
+        //- or return a nullptr.
         //
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
@@ -516,7 +511,7 @@ public:
             bool patternMatch
         );
 
-        //- Find and return an entry if present otherwise error.
+        //- Find and return an entry if present, otherwise FatalIOError.
         //
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
@@ -528,7 +523,7 @@ public:
         ) const;
 
         //- Find and return a T.
-        //- FatalError if not found, or if there are excess tokens.
+        //- FatalIOError if not found, or if there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param recursive search parent dictionaries
@@ -554,13 +549,13 @@ public:
         ) const;
 
         //- Find and return a T.
-        //- FatalError if not found, or if there are excess tokens.
+        //- FatalIOError if not found, or if there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param recursive search parent dictionaries
         //  \param patternMatch use regular expressions
         //
-        //  \note same as get()
+        //  \deprecated - same as the get() method
         template<class T>
         T lookupType
         (
@@ -570,7 +565,7 @@ public:
         ) const;
 
         //- Find and return a T, or return the given default value
-        //- FatalError if it is found and there are excess tokens.
+        //- FatalIOError if it is found and there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param recursive search parent dictionaries
@@ -586,7 +581,7 @@ public:
 
         //- Find and return a T, or return the given default value
         //- and add it to dictionary.
-        //- FatalError if it is found and there are excess tokens.
+        //- FatalIOError if it is found and there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param recursive search parent dictionaries
@@ -600,8 +595,26 @@ public:
             bool patternMatch = true
         );
 
+        //- Find entry and assign to T val.
+        //- FatalIOError if it is found and there are excess tokens.
+        //  Default search: non-recursive with patterns.
+        //
+        //  \param recursive search parent dictionaries
+        //  \param patternMatch use regular expressions
+        //
+        //  \return true if the entry was found.
+        template<class T>
+        bool read
+        (
+            const word& keyword,
+            T& val,
+            bool recursive = false,
+            bool patternMatch = true,
+            bool mandatory = true
+        ) const;
+
         //- Find an entry if present, and assign to T val.
-        //- FatalError if it is found and there are excess tokens.
+        //- FatalIOError if it is found and there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param val the value to read
@@ -662,7 +675,7 @@ public:
         dictionary& subDict(const word& keyword);
 
         //- Find and return a sub-dictionary as a copy, otherwise return
-        //  an empty dictionary.
+        //- an empty dictionary.
         //  Warn if the entry exists but is not a sub-dictionary.
         //
         //  Search type: non-recursive with patterns.
@@ -984,7 +997,7 @@ public:
             bool patternMatch
         ) const;
 
-        //- Find and return an entry if present otherwise error,
+        //- Find and return an entry if present, otherwise FatalIOError,
         //- using any compatibility names if needed.
         //
         //  \param compat list of old compatibility keywords and the last
@@ -999,6 +1012,24 @@ public:
             bool patternMatch
         ) const;
 
+        //- 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
+        template<class T>
+        T getCompat
+        (
+            const word& keyword,
+            std::initializer_list<std::pair<const char*,int>> compat,
+            bool recursive = false,
+            bool patternMatch = true
+        ) const;
+
         //- Find and return an entry data stream,
         //- using any compatibility names if needed.
         //  Default search: non-recursive with patterns.
@@ -1033,8 +1064,32 @@ public:
             bool patternMatch = true
         ) const;
 
+        //- Find entry and assign to T val
+        //- using any compatibility names if needed.
+        //- FatalIOError 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 val the value to read
+        //  \param recursive search parent dictionaries
+        //  \param patternMatch use regular expressions
+        //
+        //  \return true if the entry was found.
+        template<class T>
+        bool readCompat
+        (
+            const word& keyword,
+            std::initializer_list<std::pair<const char*,int>> compat,
+            T& val,
+            bool recursive = false,
+            bool patternMatch = true,
+            bool mandatory = true
+        ) const;
+
         //- Find an entry if present, and assign to T val
         //- using any compatibility names if needed.
+        //- FatalIOError if it is found and there are excess tokens.
         //  Default search: non-recursive with patterns.
         //
         //  \param compat list of old compatibility keywords and the last
diff --git a/src/OpenFOAM/db/dictionary/dictionaryCompat.C b/src/OpenFOAM/db/dictionary/dictionaryCompat.C
index 46567b61266e8700aad57b39adc5f952b5f43485..ab8e50001469943cf475a28d28529719f53cba12 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryCompat.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryCompat.C
@@ -52,7 +52,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
     bool patternMatch
 ) const
 {
-    const_searcher finder(csearch(keyword, recursive,patternMatch));
+    const_searcher finder(csearch(keyword, recursive, patternMatch));
 
     if (finder.found())
     {
@@ -61,7 +61,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat
 
     for (const std::pair<const char*,int>& iter : compat)
     {
-        finder = csearch(word::validate(iter.first), recursive,patternMatch);
+        finder = csearch(word::validate(iter.first), recursive, patternMatch);
 
         if (finder.found())
         {
@@ -95,7 +95,7 @@ bool Foam::dictionary::foundCompat
     bool patternMatch
 ) const
 {
-    return csearchCompat(keyword, compat, recursive,patternMatch).found();
+    return csearchCompat(keyword, compat, recursive, patternMatch).found();
 }
 
 
@@ -107,7 +107,7 @@ const Foam::entry* Foam::dictionary::lookupEntryPtrCompat
     bool patternMatch
 ) const
 {
-    return csearchCompat(keyword, compat, recursive,patternMatch).ptr();
+    return csearchCompat(keyword, compat, recursive, patternMatch).ptr();
 }
 
 
@@ -120,14 +120,12 @@ const Foam::entry& Foam::dictionary::lookupEntryCompat
 ) const
 {
     const const_searcher
-        finder(csearchCompat(keyword, compat, recursive,patternMatch));
+        finder(csearchCompat(keyword, compat, recursive, patternMatch));
 
     if (!finder.found())
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "keyword " << keyword << " is undefined in dictionary "
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
             << name()
             << exit(FatalIOError);
     }
@@ -144,7 +142,8 @@ Foam::ITstream& Foam::dictionary::lookupCompat
     bool patternMatch
 ) const
 {
-    return lookupEntryCompat(keyword, compat, recursive,patternMatch).stream();
+    return
+        lookupEntryCompat(keyword, compat, recursive, patternMatch).stream();
 }
 
 
diff --git a/src/OpenFOAM/db/dictionary/dictionarySearch.C b/src/OpenFOAM/db/dictionary/dictionarySearch.C
index cea0844cdfcfc377a96cadd2ccd2b73dfba001e0..34bdd4bca9525294757410fe52827dfb22d674ae 100644
--- a/src/OpenFOAM/db/dictionary/dictionarySearch.C
+++ b/src/OpenFOAM/db/dictionary/dictionarySearch.C
@@ -27,18 +27,17 @@ License
 #include "dictionaryEntry.H"
 #include "stringOps.H"
 
-/* * * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * * */
+// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
 
-namespace Foam
+namespace
 {
-    // file-scope
-    //- Walk lists of patterns and regexps for an exact match
-    //  or regular expression match
+    // Walk lists of patterns and regexps for an exact match
+    // or a regular expression match
     template<class WcIterator, class ReIterator>
     static bool findInPatterns
     (
         const bool patternMatch,
-        const word& keyword,
+        const Foam::word& keyword,
         WcIterator& wcIter,
         ReIterator& reIter
     )
@@ -61,7 +60,8 @@ namespace Foam
 
         return false;
     }
-}
+
+} // End anonymous namespace
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -73,7 +73,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped
     bool patternMatch
 ) const
 {
-    std::string::size_type scopePos = keyword.find('.');
+    auto scopePos = keyword.find('.');
 
     if (scopePos == string::npos)
     {
@@ -101,10 +101,8 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped
             }
             else
             {
-                FatalIOErrorInFunction
-                (
-                    *this
-                )   << "No parent of current dictionary when searching for "
+                FatalIOErrorInFunction(*this)
+                    << "No parent of current dictionary when searching for "
                     << keyword.substr(1)
                     << exit(FatalIOError);
 
@@ -210,10 +208,8 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchSlashScoped
             }
             else
             {
-                FatalIOErrorInFunction
-                (
-                    *dictPtr
-                )   << "No parent of current dictionary when searching for "
+                FatalIOErrorInFunction(*dictPtr)
+                    << "No parent of current dictionary when searching for "
                     << keyword << " at " << cmpt
                     << exit(FatalIOError);
                 break;
@@ -424,10 +420,8 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDictPtr
             }
             else
             {
-                FatalIOErrorInFunction
-                (
-                    *dictPtr
-                )   << "No parent for dictionary while searching "
+                FatalIOErrorInFunction(*dictPtr)
+                    << "No parent for dictionary while searching "
                     << path
                     << exit(FatalIOError);
 
@@ -451,10 +445,8 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDictPtr
                 }
                 else
                 {
-                    FatalIOErrorInFunction
-                    (
-                        *dictPtr
-                    )   << "Found entry '" << cmpt
+                    FatalIOErrorInFunction(*dictPtr)
+                        << "Found entry '" << cmpt
                         << "' but not a dictionary, while searching scoped"
                         << nl
                         << "    " << path
@@ -533,10 +525,8 @@ Foam::dictionary* Foam::dictionary::makeScopedDictPtr(const fileName& dictPath)
             }
             else
             {
-                FatalIOErrorInFunction
-                (
-                    *dictPtr
-                )   << "No parent for dictionary while searching "
+                FatalIOErrorInFunction(*dictPtr)
+                    << "No parent for dictionary while searching "
                     << path
                     << exit(FatalIOError);
 
@@ -561,10 +551,8 @@ Foam::dictionary* Foam::dictionary::makeScopedDictPtr(const fileName& dictPath)
                 }
                 else
                 {
-                    FatalIOErrorInFunction
-                    (
-                        *dictPtr
-                    )   << "Cannot create sub-dictionary entry '" << cmptName
+                    FatalIOErrorInFunction(*dictPtr)
+                        << "Cannot create sub-dictionary entry '" << cmptName
                         << "' - a non-dictionary entry is in the way"
                         << nl << "Encountered in scope" << nl
                         << "    " << path
@@ -621,10 +609,8 @@ bool Foam::dictionary::remove(const word& keyword)
 
         return true;
     }
-    else
-    {
-        return false;
-    }
+
+    return false;
 }
 
 
@@ -651,10 +637,8 @@ bool Foam::dictionary::changeKeyword
 
     if (iter()->keyword().isPattern())
     {
-        FatalIOErrorInFunction
-        (
-            *this
-        )   << "Old keyword "<< oldKeyword
+        FatalIOErrorInFunction(*this)
+            << "Old keyword "<< oldKeyword
             << " is a pattern."
             << "Pattern replacement not yet implemented."
             << exit(FatalIOError);
@@ -688,10 +672,8 @@ bool Foam::dictionary::changeKeyword
         }
         else
         {
-            IOWarningInFunction
-            (
-                *this
-            )   << "cannot rename keyword "<< oldKeyword
+            IOWarningInFunction(*this)
+                << "cannot rename keyword "<< oldKeyword
                 << " to existing keyword " << newKeyword
                 << " in dictionary " << name() << endl;
             return false;
diff --git a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
index e2a5ab621d6632bbcdce1b92f91ac83a82e9ab84..dc13b26d142f9a6dc1d2c4ae4aed7659e54cd4ae 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C
@@ -57,31 +57,63 @@ T Foam::dictionary::get
     bool patternMatch
 ) const
 {
-    const const_searcher finder(csearch(keyword, recursive, patternMatch));
+    T val;
+    read<T>(keyword, val, recursive, patternMatch);
+    return val;
+}
 
-    if (!finder.found())
-    {
-        FatalIOErrorInFunction(*this)
-            << "keyword " << keyword << " is undefined in dictionary "
-            << name()
-            << exit(FatalIOError);
-    }
 
+template<class T>
+T Foam::dictionary::getCompat
+(
+    const word& keyword,
+    std::initializer_list<std::pair<const char*,int>> compat,
+    bool recursive,
+    bool patternMatch
+) const
+{
     T val;
-    ITstream& is = finder.ptr()->stream();
-    is >> val;
+    readCompat<T>(keyword, compat, val, recursive, patternMatch);
+    return val;
+}
+
 
-    if (!is.eof())
+template<class T>
+bool Foam::dictionary::readCompat
+(
+    const word& keyword,
+    std::initializer_list<std::pair<const char*,int>> compat,
+    T& val,
+    bool recursive,
+    bool patternMatch,
+    bool mandatory
+) const
+{
+    const const_searcher
+        finder(csearchCompat(keyword, compat, recursive, patternMatch));
+
+    if (finder.found())
     {
-        auto err = FatalIOErrorInFunction(*this);
-        excessTokens(err, keyword, is);
-        err << exit(FatalIOError);
+        ITstream& is = finder.ptr()->stream();
+        is >> val;
+
+        excessTokens(keyword, is);
+
+        return true;
+    }
+    else if (mandatory)
+    {
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
+            << name()
+            << exit(FatalIOError);
     }
 
-    return val;
+    return false;
 }
 
 
+// older name
 template<class T>
 T Foam::dictionary::lookupType
 (
@@ -112,21 +144,15 @@ T Foam::dictionary::lookupOrDefault
         ITstream& is = finder.ptr()->stream();
         is >> val;
 
-        if (!is.eof())
-        {
-            auto err = FatalIOErrorInFunction(*this);
-            excessTokens(err, keyword, is);
-            err << exit(FatalIOError);
-        }
+        excessTokens(keyword, is);
 
         return val;
     }
-
-    if (writeOptionalEntries)
+    else if (writeOptionalEntries)
     {
         IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' is not present,"
-            << " returning the default value '" << deflt << "'"
+            << "Optional entry '" << keyword << "' not found,"
+            << " using default value '" << deflt << "'"
             << endl;
     }
 
@@ -152,21 +178,15 @@ T Foam::dictionary::lookupOrAddDefault
         ITstream& is = finder.ptr()->stream();
         is >> val;
 
-        if (!is.eof())
-        {
-            auto err = FatalIOErrorInFunction(*this);
-            excessTokens(err, keyword, is);
-            err << exit(FatalIOError);
-        }
+        excessTokens(keyword, is);
 
         return val;
     }
-
-    if (writeOptionalEntries)
+    else if (writeOptionalEntries)
     {
         IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' is not present,"
-            << " adding and returning the default value '" << deflt << "'"
+            << "Optional entry '" << keyword << "' not found,"
+            << " adding default value '" << deflt << "'"
             << endl;
     }
 
@@ -176,12 +196,13 @@ T Foam::dictionary::lookupOrAddDefault
 
 
 template<class T>
-bool Foam::dictionary::readIfPresent
+bool Foam::dictionary::read
 (
     const word& keyword,
     T& val,
     bool recursive,
-    bool patternMatch
+    bool patternMatch,
+    bool mandatory
 ) const
 {
     const const_searcher finder(csearch(keyword, recursive, patternMatch));
@@ -191,28 +212,36 @@ bool Foam::dictionary::readIfPresent
         ITstream& is = finder.ptr()->stream();
         is >> val;
 
-        if (!is.eof())
-        {
-            auto err = FatalIOErrorInFunction(*this);
-            excessTokens(err, keyword, is);
-            err << exit(FatalIOError);
-        }
+        excessTokens(keyword, is);
 
         return true;
     }
-
-    if (writeOptionalEntries)
+    else if (mandatory)
     {
-        IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' is not present,"
-            << " the default value '" << val << "' will be used."
-            << endl;
+        FatalIOErrorInFunction(*this)
+            << "'" << keyword << "' not found in dictionary "
+            << name()
+            << exit(FatalIOError);
     }
 
     return false;
 }
 
 
+template<class T>
+bool Foam::dictionary::readIfPresent
+(
+    const word& keyword,
+    T& val,
+    bool recursive,
+    bool patternMatch
+) const
+{
+    // Read is non-mandatory
+    return read<T>(keyword, val, recursive, patternMatch, false);
+}
+
+
 template<class T>
 T Foam::dictionary::lookupOrDefaultCompat
 (
@@ -233,21 +262,15 @@ T Foam::dictionary::lookupOrDefaultCompat
         ITstream& is = finder.ptr()->stream();
         is >> val;
 
-        if (!is.eof())
-        {
-            auto err = FatalIOErrorInFunction(*this);
-            excessTokens(err, keyword, is);
-            err << exit(FatalIOError);
-        }
+        excessTokens(keyword, is);
 
         return val;
     }
-
-    if (writeOptionalEntries)
+    else if (writeOptionalEntries)
     {
         IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' is not present,"
-            << " returning the default value '" << deflt << "'"
+            << "Optional entry '" << keyword << "' not found,"
+            << " using default value '" << deflt << "'"
             << endl;
     }
 
@@ -265,33 +288,8 @@ bool Foam::dictionary::readIfPresentCompat
     bool patternMatch
 ) const
 {
-    const const_searcher
-        finder(csearchCompat(keyword, compat, recursive, patternMatch));
-
-    if (finder.found())
-    {
-        ITstream& is = finder.ptr()->stream();
-        is >> val;
-
-        if (!is.eof())
-        {
-            auto err = FatalIOErrorInFunction(*this);
-            excessTokens(err, keyword, is);
-            err << exit(FatalIOError);
-        }
-
-        return true;
-    }
-
-    if (writeOptionalEntries)
-    {
-        IOInfoInFunction(*this)
-            << "Optional entry '" << keyword << "' is not present,"
-            << " the default value '" << val << "' will be used."
-            << endl;
-    }
-
-    return false;
+    // Read is non-mandatory
+    return readCompat<T>(keyword, compat, recursive, patternMatch, false);
 }
 
 
diff --git a/src/OpenFOAM/db/error/IOerror.C b/src/OpenFOAM/db/error/IOerror.C
index d200c578ab06e7aa1a78632259170d9f0fc66b48..9b6eea93c9ae30cf36a41d6b6c08a7ad1f72c591 100644
--- a/src/OpenFOAM/db/error/IOerror.C
+++ b/src/OpenFOAM/db/error/IOerror.C
@@ -139,15 +139,15 @@ void Foam::IOerror::SafeFatalIOError
     else
     {
         std::cerr
-            << std::endl
-            << "--> FOAM FATAL IO ERROR:" << std::endl
+            << nl
+            << "--> FOAM FATAL IO ERROR:" << nl
             << msg
-            << std::endl
+            << nl
             << "file: " << ioStream.name()
             << " at line " << ioStream.lineNumber() << '.'
-            << std::endl << std::endl
+            << nl << nl
             << "    From function " << functionName
-            << std::endl
+            << nl
             << "    in file " << sourceFileName
             << " at line " << sourceFileLineNumber << '.'
             << std::endl;
diff --git a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
index 773a072f2ef794b5a6889a3fb6dd6f6ab3f660ea..1f39dafa3edf6e266d37e4a044f75c27be95d8dc 100644
--- a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
+++ b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
@@ -30,7 +30,7 @@ License
 void Foam::Function1Types::ramp::read(const dictionary& coeffs)
 {
     start_ = coeffs.lookupOrDefault<scalar>("start", 0);
-    duration_ = coeffs.lookupType<scalar>("duration");
+    duration_ = coeffs.get<scalar>("duration");
 }