diff --git a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
index 79bc49b9ed5cb46b50539e66335fd19b1117a138..06e5eb00d750ed4eadee99ae2c9036581694b89d 100644
--- a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
+++ b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
@@ -90,7 +90,7 @@ ${typeName}PatchFunction1${FieldType}::
 ${typeName}PatchFunction1${FieldType}
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
diff --git a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
index af479f33441eca77033100feb928275b7219bb94..0aeaf7059e01ccc2e903fb61cf646826f0148310 100644
--- a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
+++ b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
@@ -75,7 +75,7 @@ public:
         ${typeName}PatchFunction1${FieldType}
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
@@ -84,13 +84,13 @@ public:
         //- Copy construct
         ${typeName}PatchFunction1${FieldType}
         (
-            const ${typeName}PatchFunction1${FieldType}&
+            const ${typeName}PatchFunction1${FieldType}& rhs
         );
 
         //- Copy construct, resetting patch
         ${typeName}PatchFunction1${FieldType}
         (
-            const ${typeName}PatchFunction1${FieldType}&,
+            const ${typeName}PatchFunction1${FieldType}& rhs,
             const polyPatch& pp
         );
 
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 570631242494be21daea3fe7ef89cc5cf21a9b5e..5382d32670bcb7839a9229f97a1369f0bf5d3dde 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -106,6 +106,7 @@ primitives/septernion/septernion.C
 primitives/triad/triad.C
 
 /* Run-time selectable functions */
+primitives/functions/Function1/Function1/function1Base.C
 primitives/functions/Function1/makeFunction1s.C
 primitives/functions/Function1/ramp/ramp.C
 primitives/functions/Function1/step/stepFunction.C
diff --git a/src/OpenFOAM/expressions/Function1/Function1Expression.C b/src/OpenFOAM/expressions/Function1/Function1Expression.C
index 92b935381b8f210199fb2740a3d515eee1662670..2575e0cb0140df3325e07bebb0b6a93b8a751907 100644
--- a/src/OpenFOAM/expressions/Function1/Function1Expression.C
+++ b/src/OpenFOAM/expressions/Function1/Function1Expression.C
@@ -36,7 +36,7 @@ Foam::Function1Types::Function1Expression<Type>::Function1Expression
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName),
+    Function1<Type>(entryName, dict),
     dict_(dict),
     valueExpr_(),
     driver_(1, dict_)
diff --git a/src/OpenFOAM/expressions/Function1/Function1Expression.H b/src/OpenFOAM/expressions/Function1/Function1Expression.H
index d0f7f8f34879d7925b723f3c8b09e8e736809683..de3d101514cc47ebe666bda9e12594c9e2844200 100644
--- a/src/OpenFOAM/expressions/Function1/Function1Expression.H
+++ b/src/OpenFOAM/expressions/Function1/Function1Expression.H
@@ -99,27 +99,22 @@ class Function1Expression
         mutable expressions::fieldExprDriver driver_;
 
 
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const Function1Expression<Type>&) = delete;
-
-
 public:
 
     //- Runtime type information
     TypeName("expression");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Function1Expression<Type>&) = delete;
+
+
     // Constructors
 
-        //- Construct from patch, entry name and dictionary
-        //  The patch must correspond to an fvPatch!
-        Function1Expression
-        (
-            const word& entryName,
-            const dictionary& dict
-        );
+        //- Construct from entry name and dictionary
+        Function1Expression(const word& entryName, const dictionary& dict);
 
         //- Copy construct
         explicit Function1Expression(const Function1Expression<Type>& rhs);
diff --git a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C
index 3ace21c0a6b8a91b25496e0f7a9825e39443604d..1aaedfa1d59f0bbe81a3f11303a8e808a0d5ff17 100644
--- a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C
+++ b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.C
@@ -250,13 +250,8 @@ const Foam::fileName& Foam::Function1Types::CSV<Type>::fName() const
 
 
 template<class Type>
-void Foam::Function1Types::CSV<Type>::writeData(Ostream& os) const
+void Foam::Function1Types::CSV<Type>::writeEntries(Ostream& os) const
 {
-    Function1<Type>::writeData(os);
-    os.endEntry();
-
-    os.beginBlock(word(this->name() + "Coeffs"));
-
     // Note: for TableBase write the dictionary entries it needs but not
     // the values themselves
     TableBase<Type>::writeEntries(os);
@@ -273,7 +268,17 @@ void Foam::Function1Types::CSV<Type>::writeData(Ostream& os) const
     os.writeEntry("separator", string(separator_));
     os.writeEntry("mergeSeparators", mergeSeparators_);
     os.writeEntry("file", fName_);
+}
+
 
+template<class Type>
+void Foam::Function1Types::CSV<Type>::writeData(Ostream& os) const
+{
+    Function1<Type>::writeData(os);
+    os.endEntry();
+
+    os.beginBlock(word(this->name() + "Coeffs"));
+    writeEntries(os);
     os.endBlock();
 }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.H b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.H
index e6025db72f4ac71235f32cce9e38748657d805dc..6b7a451a17238def1375aef4a7c6da396209a557 100644
--- a/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.H
+++ b/src/OpenFOAM/primitives/functions/Function1/CSV/CSV.H
@@ -154,6 +154,9 @@ public:
 
         //- Write in dictionary format
         virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.C b/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.C
index 869dc2a1b81611881ee9bbabb8b253ed70e4e282..36c85f7f7136a7bef041b7ab2042ce1dc5d77b90 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015 OpenCFD Ltd.
+    Copyright (C) 2015-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,7 +49,7 @@ Foam::Function1Types::Constant<Type>::Constant
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName),
+    Function1<Type>(entryName, dict),
     value_(Zero)
 {
     Istream& is = dict.lookup(entryName);
diff --git a/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.H b/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.H
index e2b063aeef2378050f369f931d703f2207f476f8..978c39db310d7517fc2a925d8c98ae331550d9c8 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Constant/Constant.H
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2017 OpenFOAM Foundation
-    Copyright (C) 2015 OpenCFD Ltd.
+    Copyright (C) 2015-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -61,24 +61,25 @@ class Constant
 :
     public Function1<Type>
 {
-    // Private data
+    // Private Data
 
         //- Constant value
         Type value_;
 
 
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const Constant<Type>&) = delete;
-
-
 public:
 
     // Runtime type information
     TypeName("constant");
 
 
+
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Constant<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from components
diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C
index 266008530c813c26ab2e2a197cee9353ada7cf5b..f635078a4684c9d74317469bdf5f29c9e4b418a0 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.C
@@ -36,32 +36,26 @@ License
 template<class Type>
 Foam::Function1<Type>::Function1(const word& entryName)
 :
-    name_(entryName)
+    function1Base(entryName)
 {}
 
 
 template<class Type>
-Foam::Function1<Type>::Function1(const Function1<Type>& rhs)
+Foam::Function1<Type>::Function1(const word& entryName, const dictionary& dict)
 :
-    refCount(),
-    name_(rhs.name_)
+    function1Base(entryName, dict)
 {}
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<class Type>
-const Foam::word& Foam::Function1<Type>::name() const
-{
-    return name_;
-}
-
-
 template<class Type>
-void Foam::Function1<Type>::convertTimeBase(const Time&)
+Foam::Function1<Type>::Function1(const Function1<Type>& rhs)
+:
+    function1Base(rhs)
 {}
 
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
 template<class Type>
 Type Foam::Function1<Type>::value(const scalar x) const
 {
@@ -71,7 +65,8 @@ Type Foam::Function1<Type>::value(const scalar x) const
 
 
 template<class Type>
-Foam::tmp<Foam::Field<Type>> Foam::Function1<Type>::value
+Foam::tmp<Foam::Field<Type>>
+Foam::Function1<Type>::value
 (
     const scalarField& x
 ) const
@@ -90,7 +85,8 @@ Type Foam::Function1<Type>::integrate(const scalar x1, const scalar x2) const
 
 
 template<class Type>
-Foam::tmp<Foam::Field<Type>> Foam::Function1<Type>::integrate
+Foam::tmp<Foam::Field<Type>>
+Foam::Function1<Type>::integrate
 (
     const scalarField& x1,
     const scalarField& x2
@@ -161,6 +157,11 @@ Foam::FieldFunction1<Function1Type>::integrate
 }
 
 
+template<class Type>
+void Foam::Function1<Type>::writeEntries(Ostream& os) const
+{}
+
+
 template<class Type>
 void Foam::Function1<Type>::writeData(Ostream& os) const
 {
@@ -179,7 +180,7 @@ Foam::Ostream& Foam::operator<<
 {
     os.check(FUNCTION_NAME);
 
-    os  << rhs.name_;
+    os  << rhs.name();
     rhs.writeData(os);
 
     return os;
diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H
index 8ac9135b68f3be1b45b343aa41104dbc1dc330bc..5ff592788bcb5a6526d8abbb30ee343a15d9fd1b 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1.H
@@ -74,7 +74,7 @@ SourceFiles
 #ifndef Function1_H
 #define Function1_H
 
-#include "dictionary.H"
+#include "function1Base.H"
 #include "Field.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -94,15 +94,22 @@ template<class Type> Ostream& operator<<(Ostream&, const Function1<Type>&);
 template<class Type>
 class Function1
 :
-    public refCount
+    public function1Base
 {
-protected:
+    // Private Member Functions
 
-    // Protected Data
+        //- Selector, with alternative entry, fallback redirection, etc
+        static autoPtr<Function1<Type>> New
+        (
+            const word& entryName,   // Entry name for function
+            const entry* eptr,       // Eg, dict.findEntry(entryName)
+            const dictionary& dict,
+            const word& redirectType,
+            const bool mandatory
+        );
 
-        //- Name of entry
-        const word name_;
 
+protected:
 
     // Protected Member Functions
 
@@ -136,39 +143,59 @@ public:
         //- Construct from entry name
         explicit Function1(const word& entryName);
 
-        //- Copy constructor
+        //- Construct from entry name and dictionary
+        Function1(const word& entryName, const dictionary& dict);
+
+        //- Copy construct
         explicit Function1(const Function1<Type>& rhs);
 
         //- Construct and return a clone
         virtual tmp<Function1<Type>> clone() const = 0;
 
 
-    //- Selector
-    static autoPtr<Function1<Type>> New
-    (
-        const word& entryName,
-        const dictionary& dict,
-        const word& redirectType = word::null
-    );
-
-
-    //- Destructor
-    virtual ~Function1() = default;
-
+    // Selectors
 
-    // Member Functions
+        //- Selector, with fallback redirection
+        static autoPtr<Function1<Type>> New
+        (
+            const word& entryName,
+            const dictionary& dict,
+            const word& redirectType,
+            const bool mandatory = true
+        );
 
-        // Access
+        //- Compatibility selector, with fallback redirection
+        static autoPtr<Function1<Type>> NewCompat
+        (
+            const word& entryName,
+            std::initializer_list<std::pair<const char*,int>> compat,
+            const dictionary& dict,
+            const word& redirectType = word::null,
+            const bool mandatory = true
+        );
+
+        //- Selector, without fallback redirection
+        static autoPtr<Function1<Type>> New
+        (
+            const word& entryName,
+            const dictionary& dict,
+            const bool mandatory = true
+        );
 
-            //- Return the name of the entry
-            const word& name() const;
+        //- An optional selector
+        static autoPtr<Function1<Type>> NewIfPresent
+        (
+            const word& entryName,
+            const dictionary& dict,
+            const word& redirectType = word::null
+        );
 
 
-        // Manipulation
+    //- Destructor
+    virtual ~Function1() = default;
 
-            //- Convert time
-            virtual void convertTimeBase(const Time& t);
 
+    // Member Functions
 
         // Evaluation
 
@@ -189,17 +216,22 @@ public:
             ) const;
 
 
-        // I/O
+    // I/O
+
+        //- Ostream Operator
+        friend Ostream& operator<< <Type>
+        (
+            Ostream& os,
+            const Function1<Type>& func
+        );
 
-            //- Ostream Operator
-            friend Ostream& operator<< <Type>
-            (
-                Ostream& os,
-                const Function1<Type>& func
-            );
 
-            //- Write in dictionary format
-            virtual void writeData(Ostream& os) const;
+        //- Write in dictionary format.
+        //  \note The base output is \em without an END_STATEMENT
+        virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
@@ -212,7 +244,6 @@ class FieldFunction1
 :
     public Function1Type
 {
-
 public:
 
     typedef typename Function1Type::returnType Type;
@@ -256,6 +287,7 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+// Define Function1 run-time selection
 #define makeFunction1(Type)                                                    \
                                                                                \
     defineNamedTemplateTypeNameAndDebug(Function1<Type>, 0);                   \
@@ -267,6 +299,7 @@ public:
     );
 
 
+// Define (templated) Function1, add to (templated) run-time selection
 #define makeFunction1Type(SS, Type)                                            \
                                                                                \
     defineNamedTemplateTypeNameAndDebug(Function1Types::SS<Type>, 0);          \
@@ -276,12 +309,20 @@ public:
         add##SS##Type##ConstructorToTable_;
 
 
-#define makeScalarFunction1(SS)                                                \
+// Define a non-templated Function1 and add to (templated) run-time selection
+#define makeConcreteFunction1(SS, Type)                                        \
                                                                                \
     defineTypeNameAndDebug(SS, 0);                                             \
                                                                                \
-    Function1<scalar>::adddictionaryConstructorToTable<FieldFunction1<SS>>     \
-        add##SS##ConstructorToTable_;
+    Function1<Type>::adddictionaryConstructorToTable                           \
+        <FieldFunction1<SS>>                                                   \
+        add##SS##Type##ConstructorToTable_;
+
+
+// Define scalar Function1 and add to (templated) run-time selection
+#define makeScalarFunction1(SS)                                                \
+                                                                               \
+    makeConcreteFunction1(SS, scalar);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1New.C b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1New.C
index 85084f82a2525a4de0261a3f246a2e5139d30ee2..3f01384ce755d4c13cd35302c33d3d8437ffaefc 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Function1/Function1New.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Function1/Function1New.C
@@ -35,59 +35,43 @@ Foam::autoPtr<Foam::Function1<Type>>
 Foam::Function1<Type>::New
 (
     const word& entryName,
+    const entry* eptr,
     const dictionary& dict,
-    const word& redirectType
+    const word& redirectType,
+    const bool mandatory
 )
 {
     word modelType(redirectType);
 
-    const entry* eptr = dict.findEntry(entryName, keyType::LITERAL);
+    const dictionary* coeffs = (eptr ? eptr->dictPtr() : nullptr);
 
-    if (!eptr)
-    {
-        if (modelType.empty())
-        {
-            FatalIOErrorInFunction(dict)
-                << "No Function1 dictionary entry: "
-                << entryName << nl << nl
-                << exit(FatalIOError);
-        }
-    }
-    else if (eptr->isDict())
+    if (coeffs)
     {
-        const dictionary& coeffsDict = eptr->dict();
+        // Dictionary entry
 
-        coeffsDict.readEntry
+        coeffs->readEntry
         (
             "type",
             modelType,
             keyType::LITERAL,
-            redirectType.empty()  // mandatory when redirectType is empty
+            modelType.empty()  // "type" entry is mandatory if no 'redirect'
         );
 
-        auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
-
-        if (!cstrIter.found())
-        {
-            FatalIOErrorInFunction(dict)
-                << "Unknown Function1 type "
-                << modelType << " for " << entryName
-                << "\n\nValid Function1 types :\n"
-                << dictionaryConstructorTablePtr_->sortedToc() << nl
-                << exit(FatalIOError);
-        }
-
-        return cstrIter()(entryName, coeffsDict);
+        // Fallthrough
     }
-    else
+    else if (eptr)
     {
+        // Primitive entry
+        // - non-word : value for constant function
+        // - word : the modelType
+
         Istream& is = eptr->stream();
 
         token firstToken(is);
 
         if (!firstToken.isWord())
         {
-            // Backwards-compatibility for reading straight fields
+            // A value
             is.putBack(firstToken);
 
             const Type constValue = pTraits<Type>(is);
@@ -97,8 +81,40 @@ Foam::Function1<Type>::New
                 new Function1Types::Constant<Type>(entryName, constValue)
             );
         }
+        else
+        {
+            modelType = firstToken.wordToken();
+        }
 
-        modelType = firstToken.wordToken();
+        // Fallthrough
+    }
+
+
+    if (modelType.empty())
+    {
+        // Entry missing
+
+        if (mandatory)
+        {
+            FatalIOErrorInFunction(dict)
+                << "Missing or invalid Function1 entry: "
+                << entryName << nl
+                << exit(FatalIOError);
+        }
+
+        return nullptr;
+    }
+    else if (!coeffs)
+    {
+        // Primitive entry. Coeffs dictionary is optional.
+        // Use keyword() - not entryName - for compatibility lookup!
+
+        coeffs =
+           &dict.optionalSubDict
+            (
+                eptr->keyword() + "Coeffs",
+                keyType::LITERAL
+            );
     }
 
 
@@ -114,12 +130,78 @@ Foam::Function1<Type>::New
             << exit(FatalIOError);
     }
 
-    return cstrIter()
+    return cstrIter()(entryName, *coeffs);
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::Function1<Type>>
+Foam::Function1<Type>::New
+(
+    const word& entryName,
+    const dictionary& dict,
+    const word& redirectType,
+    const bool mandatory
+)
+{
+    return Function1<Type>::New
     (
         entryName,
-        dict.optionalSubDict(entryName + "Coeffs")
+        dict.findEntry(entryName, keyType::LITERAL),
+        dict,
+        redirectType,
+        mandatory
     );
 }
 
 
+template<class Type>
+Foam::autoPtr<Foam::Function1<Type>>
+Foam::Function1<Type>::NewCompat
+(
+    const word& entryName,
+    std::initializer_list<std::pair<const char*,int>> compat,
+    const dictionary& dict,
+    const word& redirectType,
+    const bool mandatory
+)
+{
+    return Function1<Type>::New
+    (
+        entryName,
+        dict.findCompat(entryName, compat, keyType::LITERAL),
+        dict,
+        redirectType,
+        mandatory
+    );
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::Function1<Type>>
+Foam::Function1<Type>::New
+(
+    const word& entryName,
+    const dictionary& dict,
+    const bool mandatory
+)
+{
+    return Function1<Type>::New(entryName, dict, word::null, mandatory);
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::Function1<Type>>
+Foam::Function1<Type>::NewIfPresent
+(
+    const word& entryName,
+    const dictionary& dict,
+    const word& redirectType
+)
+{
+    // mandatory = false
+    return Function1<Type>::New(entryName, dict, redirectType, false);
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C
new file mode 100644
index 0000000000000000000000000000000000000000..c4a6e0a19403ebd198665bb000dd73325f8f5efe
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.C
@@ -0,0 +1,64 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "function1Base.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
+
+Foam::function1Base::function1Base(const word& entryName)
+:
+    refCount(),
+    name_(entryName)
+{}
+
+
+Foam::function1Base::function1Base
+(
+    const word& entryName,
+    const dictionary& dict
+)
+:
+    refCount(),
+    name_(entryName)
+{}
+
+
+Foam::function1Base::function1Base(const function1Base& rhs)
+:
+    refCount(),
+    name_(rhs.name_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::function1Base::convertTimeBase(const Time& t)
+{}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H
new file mode 100644
index 0000000000000000000000000000000000000000..4aa9bf68ea29eb6281c408dafc1a53f4211c581b
--- /dev/null
+++ b/src/OpenFOAM/primitives/functions/Function1/Function1/function1Base.H
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::function1Base
+
+Description
+    Top level data entry class for use in dictionaries. Provides a mechanism
+    to specify a variable as a certain type, e.g. constant or time varying, and
+    provide functions to return the (interpolated) value, and integral between
+    limits.
+
+    Extends the Function1 class by adding autoMap and rMap functions
+
+SourceFiles
+    function1Base.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef function1Base_H
+#define function1Base_H
+
+#include "dictionary.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                     Class function1Base Declaration
+\*---------------------------------------------------------------------------*/
+
+class function1Base
+:
+    public refCount
+{
+protected:
+
+    // Protected Data
+
+        //- Name of entry
+        const word name_;
+
+
+    // Protected Member Functions
+
+        //- No copy assignment
+        void operator=(const function1Base&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from entry name
+        explicit function1Base(const word& entryName);
+
+        //- Construct from entry name and dictionary
+        function1Base(const word& entryName, const dictionary& dict);
+
+        //- Copy construct
+        explicit function1Base(const function1Base& rhs);
+
+
+    //- Destructor
+    virtual ~function1Base() = default;
+
+
+    // Member Functions
+
+    // Access
+
+        //- The name of the entry
+        const word& name() const
+        {
+            return name_;
+        }
+
+
+    // Manipulation
+
+        //- Convert time
+        virtual void convertTimeBase(const Time& t);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.C b/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.C
index 4c121a5249a9f1436a8cfe25c0766e16e030d28f..f95259c44649afcf23b780996f5a33b5b206b44c 100644
--- a/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.C
+++ b/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.C
@@ -43,7 +43,7 @@ Foam::Function1Types::OneConstant<Type>::OneConstant
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName)
+    Function1<Type>(entryName, dict)
 {}
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.H b/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.H
index f883624b4196b4a4da9b637c1972600bdf66c9fc..9c19abc14b28e2cfe178da562efb0cb5bbc0a467 100644
--- a/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.H
+++ b/src/OpenFOAM/primitives/functions/Function1/One/OneConstant.H
@@ -61,18 +61,18 @@ class OneConstant
 :
     public Function1<Type>
 {
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const OneConstant<Type>&) = delete;
-
-
 public:
 
     //- Runtime type information
     TypeName("one");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const OneConstant<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name
diff --git a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C
index c82b62c628eb73931e6798f6e8303a2b8706fa52..a21970355696bd5d8fe3ddadac40ceee13a4c286 100644
--- a/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C
+++ b/src/OpenFOAM/primitives/functions/Function1/PolynomialEntry/PolynomialEntry.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,7 +37,7 @@ Foam::Function1Types::Polynomial<Type>::Polynomial
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName),
+    Function1<Type>(entryName, dict),
     coeffs_(),
     canIntegrate_(true)
 {
@@ -48,8 +49,9 @@ Foam::Function1Types::Polynomial<Type>::Polynomial
     if (!coeffs_.size())
     {
         FatalErrorInFunction
-            << "Polynomial coefficients for entry " << this->name_
-            << " are invalid (empty)" << nl << exit(FatalError);
+            << "Invalid (empty) polynomial coefficients for "
+            << this->name() << nl
+            << exit(FatalError);
     }
 
     forAll(coeffs_, i)
@@ -66,7 +68,7 @@ Foam::Function1Types::Polynomial<Type>::Polynomial
         if (!canIntegrate_)
         {
             WarningInFunction
-                << "Polynomial " << this->name_ << " cannot be integrated"
+                << "Polynomial " << this->name() << " cannot be integrated"
                 << endl;
         }
     }
@@ -87,8 +89,9 @@ Foam::Function1Types::Polynomial<Type>::Polynomial
     if (!coeffs_.size())
     {
         FatalErrorInFunction
-            << "Polynomial coefficients for entry " << this->name_
-            << " are invalid (empty)" << nl << exit(FatalError);
+            << "Invalid (empty) polynomial coefficients for "
+            << this->name() << nl
+            << exit(FatalError);
     }
 
     forAll(coeffs_, i)
@@ -105,7 +108,7 @@ Foam::Function1Types::Polynomial<Type>::Polynomial
         if (!canIntegrate_)
         {
             WarningInFunction
-                << "Polynomial " << this->name_ << " cannot be integrated"
+                << "Polynomial " << this->name() << " cannot be integrated"
                 << endl;
         }
     }
diff --git a/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.C b/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.C
index a5d71d884a30f39a9eccfc205075e6a803bf89a8..76bb810eeed466ea572eeaabaf55fe0eefbe872c 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.C
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2017 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -61,6 +62,14 @@ Foam::Function1Types::Scale<Type>::Scale(const Scale<Type>& rhs)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<class Type>
+void Foam::Function1Types::Scale<Type>::writeEntries(Ostream& os) const
+{
+    scale_->writeData(os);
+    value_->writeData(os);
+}
+
+
 template<class Type>
 void Foam::Function1Types::Scale<Type>::writeData(Ostream& os) const
 {
@@ -68,10 +77,7 @@ void Foam::Function1Types::Scale<Type>::writeData(Ostream& os) const
     os  << token::END_STATEMENT << nl;
 
     os.beginBlock(word(this->name() + "Coeffs"));
-
-    scale_->writeData(os);
-    value_->writeData(os);
-
+    writeEntries(os);
     os.endBlock();
 }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.H b/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.H
index 22efae6afd260ea9c6f727577556e49c3f98214a..86186109cd6ab5d5c8032a5d279c05f05210cc2c 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Scale/Scale.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2017 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -106,9 +107,6 @@ class Scale
         //- Read the coefficients from the given dictionary
         void read(const dictionary& coeffs);
 
-        //- No copy assignment
-        void operator=(const Scale<Type>&) = delete;
-
 
 public:
 
@@ -116,6 +114,12 @@ public:
     TypeName("scale");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Scale<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
@@ -140,6 +144,9 @@ public:
 
         //- Write in dictionary format
         virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.C b/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.C
index f59210036119e5dc96f761e1f3660f9d6c62d42b..38948f029c0c43e65fd7d450d68a1d8ef98fe947 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.C
@@ -48,7 +48,7 @@ Foam::Function1Types::Sine<Type>::Sine
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName)
+    Function1<Type>(entryName, dict)
 {
     read(dict);
 }
@@ -69,19 +69,24 @@ Foam::Function1Types::Sine<Type>::Sine(const Sine<Type>& se)
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::Function1Types::Sine<Type>::writeData(Ostream& os) const
+void Foam::Function1Types::Sine<Type>::writeEntries(Ostream& os) const
 {
-    Function1<Type>::writeData(os);
-    os.endEntry();
-
-    os.beginBlock(word(this->name() + "Coeffs"));
-
     os.writeEntry("t0", t0_);
     amplitude_->writeData(os);
     frequency_->writeData(os);
     scale_->writeData(os);
     level_->writeData(os);
+}
+
 
+template<class Type>
+void Foam::Function1Types::Sine<Type>::writeData(Ostream& os) const
+{
+    Function1<Type>::writeData(os);
+    os.endEntry();
+
+    os.beginBlock(word(this->name() + "Coeffs"));
+    writeEntries(os);
     os.endBlock();
 }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.H b/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.H
index 200f9dc19db50d7343e73784b1756e384d5c863a..746385a04c1aa07ec41aff55c70c2055eba85fcb 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Sine/Sine.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -118,16 +119,18 @@ class Sine
         //- Read the coefficients from the given dictionary
         void read(const dictionary& coeffs);
 
-        //- No copy assignment
-        void operator=(const Sine<Type>&) = delete;
-
-
 public:
 
     // Runtime type information
     TypeName("sine");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Sine<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
@@ -152,6 +155,9 @@ public:
 
         //- Write in dictionary format
         virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Square/Square.C b/src/OpenFOAM/primitives/functions/Function1/Square/Square.C
index 93715bdfe6f563f08ca083939c0a17c652a6c140..0016bbb5ecea9e586c441c0c26acc5be50545dfd 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Square/Square.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Square/Square.C
@@ -49,7 +49,7 @@ Foam::Function1Types::Square<Type>::Square
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName)
+    Function1<Type>(entryName, dict)
 {
     read(dict);
 }
@@ -71,20 +71,25 @@ Foam::Function1Types::Square<Type>::Square(const Square<Type>& se)
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::Function1Types::Square<Type>::writeData(Ostream& os) const
+void Foam::Function1Types::Square<Type>::writeEntries(Ostream& os) const
 {
-    Function1<Type>::writeData(os);
-    os.endEntry();
-
-    os.beginBlock(word(this->name() + "Coeffs"));
-
     os.writeEntry("t0", t0_);
     os.writeEntry("markSpace", markSpace_);
     amplitude_->writeData(os);
     frequency_->writeData(os);
     scale_->writeData(os);
     level_->writeData(os);
+}
+
 
+template<class Type>
+void Foam::Function1Types::Square<Type>::writeData(Ostream& os) const
+{
+    Function1<Type>::writeData(os);
+    os.endEntry();
+
+    os.beginBlock(word(this->name() + "Coeffs"));
+    writeEntries(os);
     os.endBlock();
 }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Square/Square.H b/src/OpenFOAM/primitives/functions/Function1/Square/Square.H
index 08bc6984f97bbf87fe79dcc9b679316c736fa70d..a0055da1ac2c24efd3afeaf5064d5d0a240daa29 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Square/Square.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Square/Square.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2016-2017 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -125,9 +126,6 @@ class Square
         //- Read the coefficients from the given dictionary
         void read(const dictionary& coeffs);
 
-        //- No copy assignment
-        void operator=(const Square<Type>&) = delete;
-
 
 public:
 
@@ -135,6 +133,12 @@ public:
     TypeName("square");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Square<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
@@ -159,6 +163,9 @@ public:
 
         //- Write in dictionary format
         virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C
index 114dac54c4699864c81c038238fe4d438d9cefaf..8c1fdb25957f4dd488cefe171a883be74b4d9284 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.C
@@ -65,8 +65,7 @@ Foam::Function1Types::TableBase<Type>::TableBase
     const dictionary& dict
 )
 :
-    Function1<Type>(name),
-    name_(name),
+    Function1<Type>(name, dict),
     bounding_
     (
         bounds::repeatableBoundingNames.getOrDefault
@@ -91,7 +90,6 @@ template<class Type>
 Foam::Function1Types::TableBase<Type>::TableBase(const TableBase<Type>& tbl)
 :
     Function1<Type>(tbl),
-    name_(tbl.name_),
     bounding_(tbl.bounding_),
     interpolationScheme_(tbl.interpolationScheme_),
     table_(tbl.table_),
@@ -115,7 +113,7 @@ void Foam::Function1Types::TableBase<Type>::check() const
     if (!table_.size())
     {
         FatalErrorInFunction
-            << "Table for entry " << this->name_ << " is invalid (empty)"
+            << "Table for entry " << this->name() << " is invalid (empty)"
             << nl << exit(FatalError);
     }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H
index ce324b91d2895d528d2eaf3231dbcde48ed51ef5..82361382bd2f2573761814b678f88b0217154a29 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Table/TableBase.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -65,9 +66,6 @@ protected:
 
     // Protected Data
 
-        //- Table name
-        const word name_;
-
         //- Handling for out-of-bound values
         const bounds::repeatableBounding bounding_;
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H
index d588b8eed42087c6a1d8e04dd8755f5c1d154798..76d210a786407266e0782dfba928e652bb0eb6d2 100644
--- a/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H
+++ b/src/OpenFOAM/primitives/functions/Function1/TableFile/TableFile.H
@@ -59,9 +59,7 @@ SourceFiles
 #ifndef TableFile_H
 #define TableFile_H
 
-#include "Function1.H"
 #include "TableBase.H"
-#include "Tuple2.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.C b/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.C
index d043ad133884f061539d22265ee42c2fb2c968ef..591e430f624ea280b14f0a48c1eebf411517c5bb 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.C
+++ b/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.C
@@ -44,7 +44,7 @@ Foam::Function1Types::ZeroConstant<Type>::ZeroConstant
     const dictionary& dict
 )
 :
-    Function1<Type>(entryName)
+    Function1<Type>(entryName, dict)
 {}
 
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.H b/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.H
index 88c79e1e4c419e0867dbc54ba04c2c0fa4cd0777..2393d949dcf6ebfe821632eb4693d1500481b464 100644
--- a/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.H
+++ b/src/OpenFOAM/primitives/functions/Function1/Zero/ZeroConstant.H
@@ -61,18 +61,18 @@ class ZeroConstant
 :
     public Function1<Type>
 {
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const ZeroConstant<Type>&) = delete;
-
-
 public:
 
     //- Runtime type information
     TypeName("zero");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const ZeroConstant<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name
diff --git a/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRamp.H b/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRamp.H
index 5de2c76084024041c13c91e6bae1213fe4e1fe7d..8d4b6f524b5f12ffa10846d3d6ea62dcc2041f1d 100644
--- a/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRamp.H
+++ b/src/OpenFOAM/primitives/functions/Function1/quadraticRamp/quadraticRamp.H
@@ -29,7 +29,7 @@ Class
 
 Description
     Quadratic ramp function starting from 0 and increasing quadratically
-    to 1 from \c t_0 over the \c duration and remaining at 1 thereafter.
+    to 1 from \c start over the \c duration and remaining at 1 thereafter.
 
 See also
     Foam::Function1Types::ramp
diff --git a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
index 8b3999861c13cbe2bd3f57d4d7f886ae0c35e58d..9570edb90520623fe287c8a0bfea22f113d57524 100644
--- a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
+++ b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.C
@@ -43,7 +43,7 @@ Foam::Function1Types::ramp::ramp
     const dictionary& dict
 )
 :
-    Function1<scalar>(entryName)
+    Function1<scalar>(entryName, dict)
 {
     read(dict);
 }
@@ -51,16 +51,20 @@ Foam::Function1Types::ramp::ramp
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::Function1Types::ramp::writeEntries(Ostream& os) const
+{
+    os.writeEntry("start", start_);
+    os.writeEntry("duration", duration_);
+}
+
+
 void Foam::Function1Types::ramp::writeData(Ostream& os) const
 {
     Function1<scalar>::writeData(os);
     os  << token::END_STATEMENT << nl;
 
     os.beginBlock(word(this->name() + "Coeffs"));
-
-    os.writeEntry("start", start_);
-    os.writeEntry("duration", duration_);
-
+    writeEntries(os);
     os.endBlock();
 }
 
diff --git a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.H b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.H
index 768caa21bfa3d28e8ab2ad6361f34fc860225c5b..339da7de4e47a0aecb5100eb39f20fcc8d6b5504 100644
--- a/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.H
+++ b/src/OpenFOAM/primitives/functions/Function1/ramp/ramp.H
@@ -138,6 +138,9 @@ public:
 
         //- Write in dictionary format
         virtual void writeData(Ostream& os) const;
+
+        //- Write coefficient entries in dictionary format
+        void writeEntries(Ostream& os) const;
 };
 
 
diff --git a/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.C b/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.C
index 2ff54719b550fc2db0d928eba9286148b4c57fd0..72211dba9e501bc903fdbc0b0e24ef6312eb6f71 100644
--- a/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.C
+++ b/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.C
@@ -34,7 +34,7 @@ template<class Type>
 Foam::PatchFunction1Types::PatchExprField<Type>::PatchExprField
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
@@ -72,10 +72,7 @@ Foam::PatchFunction1Types::PatchExprField<Type>::PatchExprField
     const PatchExprField<Type>& rhs
 )
 :
-    PatchFunction1<Type>(rhs),
-    dict_(rhs.dict_),
-    valueExpr_(rhs.valueExpr_),
-    driver_(fvPatch::lookupPatch(this->patch()), rhs.driver_)
+    PatchExprField<Type>(rhs, rhs.patch())
 {}
 
 
@@ -156,7 +153,7 @@ void Foam::PatchFunction1Types::PatchExprField<Type>::writeData
     Ostream& os
 ) const
 {
-    // PatchFunction1-from-subdict so out dictionary contains
+    // PatchFunction1-from-subdict so output dictionary contains
     // only the relevant entries.
     dict_.writeEntry(this->name(), os);
 }
diff --git a/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.H b/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.H
index d8f8f1881a2dd9f9f9d8b5a692081c0a1013693f..4a66dbc66986cf3bd6255a5f98cbc6e0eb713e31 100644
--- a/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.H
+++ b/src/finiteVolume/expressions/PatchFunction1/PatchFunction1Expression.H
@@ -97,18 +97,18 @@ class PatchExprField
         mutable expressions::patchExpr::parseDriver driver_;
 
 
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const PatchExprField<Type>&) = delete;
-
-
 public:
 
     //- Runtime type information
     TypeName("expression");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const PatchExprField<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from patch, entry name and dictionary
@@ -116,7 +116,7 @@ public:
         PatchExprField
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.C b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.C
index 341636606a9c2275327cd3620585707bec6db6af..5fbd999c1fe57fc253d79d68d9b8595e8fb05e63 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.C
@@ -53,7 +53,7 @@ template<class Type>
 Foam::PatchFunction1Types::Sampled<Type>::Sampled
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
@@ -76,31 +76,26 @@ Foam::PatchFunction1Types::Sampled<Type>::Sampled
 template<class Type>
 Foam::PatchFunction1Types::Sampled<Type>::Sampled
 (
-    const Sampled<Type>& ut
+    const Sampled<Type>& rhs
 )
 :
-    PatchFunction1<Type>(ut),
-    mappedPatchBase(ut),
-    fieldName_(ut.fieldName_),
-    setAverage_(ut.setAverage_),
-    average_(ut.average_),
-    interpolationScheme_(ut.interpolationScheme_)
+    Sampled<Type>(rhs, rhs.patch())
 {}
 
 
 template<class Type>
 Foam::PatchFunction1Types::Sampled<Type>::Sampled
 (
-    const Sampled<Type>& ut,
+    const Sampled<Type>& rhs,
     const polyPatch& pp
 )
 :
-    PatchFunction1<Type>(ut, pp),
-    mappedPatchBase(pp, ut),
-    fieldName_(ut.fieldName_),
-    setAverage_(ut.setAverage_),
-    average_(ut.average_),
-    interpolationScheme_(ut.interpolationScheme_)
+    PatchFunction1<Type>(rhs, pp),
+    mappedPatchBase(pp, rhs),
+    fieldName_(rhs.fieldName_),
+    setAverage_(rhs.setAverage_),
+    average_(rhs.average_),
+    interpolationScheme_(rhs.interpolationScheme_)
 {}
 
 
@@ -286,7 +281,7 @@ Foam::PatchFunction1Types::Sampled<Type>::value
     if (setAverage_ && returnReduce(newValues.size(), sumOp<label>()))
     {
         Type averagePsi;
-        if (this->faceValues_)
+        if (this->faceValues())
         {
             const scalarField magSf
             (
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.H b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.H
index c94fe001f489beb915fcaabeb305522d96061844..a92ae7fd7a5c825babf3d0be92a2b925c4f5d5ee 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/mappedField/Sampled/Sampled.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -86,7 +86,7 @@ namespace PatchFunction1Types
 {
 
 /*---------------------------------------------------------------------------*\
-                     Class Sampled Declaration
+                           Class Sampled Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
@@ -124,9 +124,6 @@ protected:
         //- Field to sample. Either on my or nbr mesh
         bool haveSampleField() const;
 
-        //- No copy assignment
-        void operator=(const Sampled<Type>&) = delete;
-
 
 public:
 
@@ -134,25 +131,31 @@ public:
     TypeName("sampled");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const Sampled<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
         Sampled
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
         );
 
-        //- Copy constructor
-        explicit Sampled(const Sampled<Type>& ut);
+        //- Copy construct
+        explicit Sampled(const Sampled<Type>& rhs);
 
-        //- Copy constructor setting patch
+        //- Copy construct setting patch
         explicit Sampled
         (
-            const Sampled<Type>& ut,
+            const Sampled<Type>& rhs,
             const polyPatch& pp
         );
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/surfaceNormalFixedValue/surfaceNormalFixedValueFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/surfaceNormalFixedValue/surfaceNormalFixedValueFvPatchVectorField.C
index 973911e22d065fac527b3644332ae1d6983d82b1..22ba3f58856b1809db702252af6c05d274baa0af 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/surfaceNormalFixedValue/surfaceNormalFixedValueFvPatchVectorField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/surfaceNormalFixedValue/surfaceNormalFixedValueFvPatchVectorField.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011-2016 OpenFOAM Foundation
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -56,13 +56,8 @@ surfaceNormalFixedValueFvPatchVectorField
 :
     fixedValueFvPatchVectorField(p, iF, dict, false),
     refValue_("refValue", dict, p.size()),
-    ramp_(nullptr)
+    ramp_(Function1<scalar>::NewIfPresent("ramp", dict))
 {
-    if (dict.found("ramp"))
-    {
-        ramp_ = Function1<scalar>::New("ramp", dict);
-    }
-
     tmp<vectorField> tvalues(refValue_*patch().nf());
 
     if (ramp_)
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/uniformNormalFixedValue/uniformNormalFixedValueFvPatchVectorField.C b/src/finiteVolume/fields/fvPatchFields/derived/uniformNormalFixedValue/uniformNormalFixedValueFvPatchVectorField.C
index 0e282caed89d3a447c0c486db2bb84c8c13983a2..7903bf3b1ea3b103388bf68830fb808aa791be17 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/uniformNormalFixedValue/uniformNormalFixedValueFvPatchVectorField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/uniformNormalFixedValue/uniformNormalFixedValueFvPatchVectorField.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2019 OpenCFD Ltd.
+    Copyright (C) 2019-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -55,13 +55,8 @@ uniformNormalFixedValueFvPatchVectorField
 :
     fixedValueFvPatchVectorField(p, iF, dict, false),
     uniformValue_(PatchFunction1<scalar>::New(p.patch(), "uniformValue", dict)),
-    ramp_(nullptr)
+    ramp_(Function1<scalar>::NewIfPresent("ramp", dict))
 {
-    if (dict.found("ramp"))
-    {
-        ramp_ = Function1<scalar>::New("ramp", dict);
-    }
-
     if (dict.found("value"))
     {
         fvPatchVectorField::operator=
diff --git a/src/fvMotionSolver/pointPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValuePointPatchField.C b/src/fvMotionSolver/pointPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValuePointPatchField.C
index 4b5921345ee263b418a485f6d1772fde48ee554b..a40cd6724497f40be937fc8a5fa45e0af6a2391b 100644
--- a/src/fvMotionSolver/pointPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValuePointPatchField.C
+++ b/src/fvMotionSolver/pointPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValuePointPatchField.C
@@ -85,13 +85,8 @@ timeVaryingMappedFixedValuePointPatchField
     endSampleTime_(-1),
     endSampledValues_(0),
     endAverage_(Zero),
-    offset_()
+    offset_(Function1<Type>::NewIfPresent("offset", dict))
 {
-    if (dict.found("offset"))
-    {
-        offset_ = Function1<Type>::New("offset", dict);
-    }
-
     if
     (
         mapMethod_ != "planarInterpolation"
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index 8b95ab2952db68493e542fae02422ecbafb62a33..13a2ccf684602da296ade369388d45f6a3b36ec8 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -305,8 +305,10 @@ mappedPatches/mappedPointPatch/mappedWallPointPatch.C
 polyTopoChange/topoAction/topoActions.C
 polyTopoChange/polyTopoChange.C
 
+/* Run-time selectable functions */
+PatchFunction1/PatchFunction1/patchFunction1Base.C
 PatchFunction1/makePatchFunction1s.C
-PatchFunction1/coordinateLabelScaling.C
+PatchFunction1/coordinateScaling/coordinateScalings.C
 PatchFunction1/CodedField/makeCodedFields.C
 PatchFunction1/MappedFile/rawIOFields.C
 
diff --git a/src/meshTools/PatchFunction1/CodedField/CodedField.C b/src/meshTools/PatchFunction1/CodedField/CodedField.C
index d09455f7a06bb86fd87553d87a260db993495244..d41b9457777143a2de7d04a66bea5a98c6d51cb8 100644
--- a/src/meshTools/PatchFunction1/CodedField/CodedField.C
+++ b/src/meshTools/PatchFunction1/CodedField/CodedField.C
@@ -135,7 +135,7 @@ template<class Type>
 Foam::PatchFunction1Types::CodedField<Type>::CodedField
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
@@ -156,10 +156,7 @@ Foam::PatchFunction1Types::CodedField<Type>::CodedField
     const CodedField<Type>& rhs
 )
 :
-    PatchFunction1<Type>(rhs),
-    codedBase(),
-    dict_(rhs.dict_),
-    name_(rhs.name_)
+    CodedField<Type>(rhs, rhs.patch())
 {}
 
 
@@ -202,7 +199,7 @@ Foam::PatchFunction1Types::CodedField<Type>::redirectFunction() const
                 this->patch(),
                 name_,
                 dict,
-                this->faceValues_
+                this->faceValues()
             )
         );
     }
diff --git a/src/meshTools/PatchFunction1/CodedField/CodedField.H b/src/meshTools/PatchFunction1/CodedField/CodedField.H
index 27666ecdb6c9d76e323114a08efed6d0a41a7f96..6cbdb1c86306c26191b9c3610323367b8b3feccf 100644
--- a/src/meshTools/PatchFunction1/CodedField/CodedField.H
+++ b/src/meshTools/PatchFunction1/CodedField/CodedField.H
@@ -135,10 +135,6 @@ protected:
         // Get the dictionary to initialize the codeContext
         virtual const dictionary& codeDict() const;
 
-        //- No copy assignment
-        void operator=(const CodedField<Type>&) = delete;
-
-
 public:
 
     // Static Data Members
@@ -156,13 +152,19 @@ public:
     TypeName("coded");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const CodedField<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
         CodedField
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
diff --git a/src/meshTools/PatchFunction1/ConstantField/ConstantField.C b/src/meshTools/PatchFunction1/ConstantField/ConstantField.C
index 3467d1e84b424a028be18ace6585c6c77a8e81cc..7dd8331dbd444fb33059b91fa5568277f9112e2b 100644
--- a/src/meshTools/PatchFunction1/ConstantField/ConstantField.C
+++ b/src/meshTools/PatchFunction1/ConstantField/ConstantField.C
@@ -42,7 +42,7 @@ Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
     PatchFunction1<Type>(pp, entryName, dict, faceValues),
     isUniform_(true),
     uniformValue_(uniformValue),
-    value_((faceValues ? pp.size() : pp.nPoints()), uniformValue_)
+    value_(this->size(), uniformValue_)
 {}
 
 
@@ -63,24 +63,23 @@ Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
     uniformValue_(uniformValue),
     value_(fieldValues)
 {
-    const label len = (faceValues ? pp.size() : pp.nPoints());
-
-    if (fieldValues.size() != len)
+    if (fieldValues.size() != this->size())
     {
         FatalIOErrorInFunction(dict)
             << "Supplied field size " << fieldValues.size()
             << " is not equal to the number of "
             << (faceValues ? "faces" : "points") << ' '
-            << len << " of patch " << pp.name() << nl
+            << this->size() << " of patch " << pp.name() << nl
             << exit(FatalIOError);
     }
 }
 
 
 template<class Type>
-Foam::Field<Type> Foam::PatchFunction1Types::ConstantField<Type>::getValue
+Foam::Field<Type>
+Foam::PatchFunction1Types::ConstantField<Type>::getValue
 (
-    const word& keyword,
+    const entry* eptr,
     const dictionary& dict,
     const label len,
     bool& isUniform,
@@ -94,7 +93,13 @@ Foam::Field<Type> Foam::PatchFunction1Types::ConstantField<Type>::getValue
 
     if (len)
     {
-        ITstream& is = dict.lookup(keyword);
+        if (!eptr || !eptr->isStream())
+        {
+            FatalIOErrorInFunction(dict)
+                << "Null or invalid entry" << nl
+                << exit(FatalIOError);
+        }
+        ITstream& is = eptr->stream();
 
         // Read first token
         token firstToken(is);
@@ -172,20 +177,49 @@ template<class Type>
 Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
+    const word& entryName,
+    const dictionary& dict,
+    const bool faceValues
+)
+:
+    PatchFunction1<Type>(pp, entryName, dict, faceValues),
+    isUniform_(true),  // overwritten by getValue()
+    uniformValue_(Zero),  // overwritten by getValue()
+    value_
+    (
+        getValue
+        (
+            dict.findEntry(entryName, keyType::LITERAL),
+            dict,
+            this->size(),
+            isUniform_,
+            uniformValue_
+        )
+    )
+{}
+
+
+template<class Type>
+Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
+(
+    const polyPatch& pp,
+    const entry* eptr,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
 )
 :
     PatchFunction1<Type>(pp, entryName, dict, faceValues),
+    isUniform_(true),  // overwritten by getValue()
+    uniformValue_(Zero),  // overwritten by getValue()
     value_
     (
         getValue
         (
-            entryName,
+            eptr,
             dict,
-            (faceValues ? pp.size() : pp.nPoints()),
+            this->size(),
             isUniform_,
             uniformValue_
         )
@@ -196,34 +230,27 @@ Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
 template<class Type>
 Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
 (
-    const ConstantField<Type>& cnst
+    const ConstantField<Type>& rhs
 )
 :
-    PatchFunction1<Type>(cnst),
-    isUniform_(cnst.isUniform_),
-    uniformValue_(cnst.uniformValue_),
-    value_(cnst.value_)
+    ConstantField<Type>(rhs, rhs.patch())
 {}
 
 
 template<class Type>
 Foam::PatchFunction1Types::ConstantField<Type>::ConstantField
 (
-    const ConstantField<Type>& cnst,
+    const ConstantField<Type>& rhs,
     const polyPatch& pp
 )
 :
-    PatchFunction1<Type>(cnst, pp),
-    isUniform_(cnst.isUniform_),
-    uniformValue_(cnst.uniformValue_),
-    value_(cnst.value_)
+    PatchFunction1<Type>(rhs, pp),
+    isUniform_(rhs.isUniform_),
+    uniformValue_(rhs.uniformValue_),
+    value_(rhs.value_)
 {
     // If sizes are different...
-    value_.resize
-    (
-        (this->faceValues_ ? this->patch_.size() : this->patch_.nPoints()),
-        Zero
-    );
+    value_.resize(this->size(), Zero);
 
     if (isUniform_)
     {
@@ -272,13 +299,13 @@ void Foam::PatchFunction1Types::ConstantField<Type>::writeData
 
     if (isUniform_)
     {
-        os.writeKeyword(this->name_)
+        os.writeKeyword(this->name())
             << word("constant") << token::SPACE << uniformValue_
             << token::END_STATEMENT << nl;
     }
     else
     {
-        value_.writeEntry(this->name_, os);
+        value_.writeEntry(this->name(), os);
     }
 }
 
diff --git a/src/meshTools/PatchFunction1/ConstantField/ConstantField.H b/src/meshTools/PatchFunction1/ConstantField/ConstantField.H
index 81ce0d6b96ea94870564aa91e264dfa1b3b8b545..e53b363f35cec4a78a0ec24db56b2e7c42cd6c45 100644
--- a/src/meshTools/PatchFunction1/ConstantField/ConstantField.H
+++ b/src/meshTools/PatchFunction1/ConstantField/ConstantField.H
@@ -74,11 +74,11 @@ class ConstantField
 
     // Private Member Functions
 
-        //- Helper to read value from dictionary
+        //- Helper to read value from dictionary entry
         static Field<Type> getValue
         (
-            const word& keyword,
-            const dictionary& dict,
+            const entry* eptr,  // primitiveEntry
+            const dictionary& dict,  // For error context
             const label len,
             bool& isUniform,
             Type& uniformValue
@@ -122,19 +122,29 @@ public:
         ConstantField
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
+            const word& entryName,
+            const dictionary& dict,
+            const bool faceValues = true
+        );
+
+        //- Construct from primitive entry, entry name and dictionary
+        ConstantField
+        (
+            const polyPatch& pp,
+            const entry* eptr,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
         );
 
         //- Copy construct
-        explicit ConstantField(const ConstantField<Type>& cnst);
+        explicit ConstantField(const ConstantField<Type>& rhs);
 
-        //- Copy constructor setting patch
+        //- Copy construct setting patch
         explicit ConstantField
         (
-            const ConstantField<Type>& cnst,
+            const ConstantField<Type>& rhs,
             const polyPatch& pp
         );
 
diff --git a/src/meshTools/PatchFunction1/MappedFile/MappedFile.C b/src/meshTools/PatchFunction1/MappedFile/MappedFile.C
index fe2a7d226e1b560f81a8598c4a55e438c77ad73b..3a1b28f19e910e0598f87448278fd03364d835e5 100644
--- a/src/meshTools/PatchFunction1/MappedFile/MappedFile.C
+++ b/src/meshTools/PatchFunction1/MappedFile/MappedFile.C
@@ -34,7 +34,7 @@ template<class Type>
 Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
@@ -42,8 +42,8 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 :
     PatchFunction1<Type>(pp, entryName, dict, faceValues),
     dictConstructed_(true),
-    fieldTableName_(entryName),
     setAverage_(dict.getOrDefault("setAverage", false)),
+    fieldTableName_(entryName),
     perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
     pointsName_(dict.getOrDefault<word>("points", "points")),
     mapMethod_
@@ -62,13 +62,8 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
     endSampleTime_(-1),
     endSampledValues_(0),
     endAverage_(Zero),
-    offset_(nullptr)
+    offset_(Function1<Type>::NewIfPresent("offset", dict))
 {
-    if (dict.found("offset"))
-    {
-        offset_ = Function1<Type>::New("offset", dict);
-    }
-
     if
     (
         mapMethod_ != "planarInterpolation"
@@ -96,8 +91,8 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 :
     PatchFunction1<Type>(pp, entryName, dict, faceValues),
     dictConstructed_(false),
-    fieldTableName_(fieldTableName),
     setAverage_(dict.getOrDefault("setAverage", false)),
+    fieldTableName_(fieldTableName),
     perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
     pointsName_(dict.getOrDefault<word>("points", "points")),
     mapMethod_
@@ -116,13 +111,8 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
     endSampleTime_(-1),
     endSampledValues_(0),
     endAverage_(Zero),
-    offset_(nullptr)
+    offset_(Function1<Type>::NewIfPresent("offset", dict))
 {
-    if (dict.found("offset"))
-    {
-        offset_ = Function1<Type>::New("offset", dict);
-    }
-
     if
     (
         mapMethod_ != "planarInterpolation"
@@ -139,51 +129,36 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 template<class Type>
 Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 (
-    const MappedFile<Type>& ut
+    const MappedFile<Type>& rhs
 )
 :
-    PatchFunction1<Type>(ut),
-    dictConstructed_(ut.dictConstructed_),
-    fieldTableName_(ut.fieldTableName_),
-    setAverage_(ut.setAverage_),
-    perturb_(ut.perturb_),
-    pointsName_(ut.pointsName_),
-    mapMethod_(ut.mapMethod_),
-    mapperPtr_(ut.mapperPtr_.clone()),
-    sampleTimes_(ut.sampleTimes_),
-    startSampleTime_(ut.startSampleTime_),
-    startSampledValues_(ut.startSampledValues_),
-    startAverage_(ut.startAverage_),
-    endSampleTime_(ut.endSampleTime_),
-    endSampledValues_(ut.endSampledValues_),
-    endAverage_(ut.endAverage_),
-    offset_(ut.offset_.clone())
+    MappedFile<Type>(rhs, rhs.patch())
 {}
 
 
 template<class Type>
 Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
 (
-    const MappedFile<Type>& ut,
+    const MappedFile<Type>& rhs,
     const polyPatch& pp
 )
 :
-    PatchFunction1<Type>(ut, pp),
-    dictConstructed_(ut.dictConstructed_),
-    fieldTableName_(ut.fieldTableName_),
-    setAverage_(ut.setAverage_),
-    perturb_(ut.perturb_),
-    pointsName_(ut.pointsName_),
-    mapMethod_(ut.mapMethod_),
-    mapperPtr_(ut.mapperPtr_.clone()),
-    sampleTimes_(ut.sampleTimes_),
-    startSampleTime_(ut.startSampleTime_),
-    startSampledValues_(ut.startSampledValues_),
-    startAverage_(ut.startAverage_),
-    endSampleTime_(ut.endSampleTime_),
-    endSampledValues_(ut.endSampledValues_),
-    endAverage_(ut.endAverage_),
-    offset_(ut.offset_.clone())
+    PatchFunction1<Type>(rhs, pp),
+    dictConstructed_(rhs.dictConstructed_),
+    setAverage_(rhs.setAverage_),
+    fieldTableName_(rhs.fieldTableName_),
+    perturb_(rhs.perturb_),
+    pointsName_(rhs.pointsName_),
+    mapMethod_(rhs.mapMethod_),
+    mapperPtr_(rhs.mapperPtr_.clone()),
+    sampleTimes_(rhs.sampleTimes_),
+    startSampleTime_(rhs.startSampleTime_),
+    startSampledValues_(rhs.startSampledValues_),
+    startAverage_(rhs.startAverage_),
+    endSampleTime_(rhs.endSampleTime_),
+    endSampledValues_(rhs.endSampledValues_),
+    endAverage_(rhs.endAverage_),
+    offset_(rhs.offset_.clone())
 {}
 
 
@@ -279,7 +254,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
         );
 
         // Allocate the interpolator
-        if (this->faceValues_)
+        if (this->faceValues())
         {
             mapperPtr_.reset
             (
@@ -536,7 +511,7 @@ Foam::PatchFunction1Types::MappedFile<Type>::value
     if (setAverage_)
     {
         Type averagePsi;
-        if (this->faceValues_)
+        if (this->faceValues())
         {
             const scalarField magSf(mag(this->patch_.faceAreas()));
             averagePsi = gSum(magSf*fld)/gSum(magSf);
diff --git a/src/meshTools/PatchFunction1/MappedFile/MappedFile.H b/src/meshTools/PatchFunction1/MappedFile/MappedFile.H
index 6bb091b05241b8061929ccd0584afa126a77e2e8..79adeb448ec775ac84130068b289aec928d255f1 100644
--- a/src/meshTools/PatchFunction1/MappedFile/MappedFile.H
+++ b/src/meshTools/PatchFunction1/MappedFile/MappedFile.H
@@ -73,12 +73,12 @@ class MappedFile
         //- Whether constructed from dictionary
         const bool dictConstructed_;
 
-        //- Name of the field data table, defaults to the name of the field
-        word fieldTableName_;
-
         //- If true adjust the mapped field to maintain average value
         bool setAverage_;
 
+        //- Name of the field data table, defaults to the name of the field
+        word fieldTableName_;
+
         //- Fraction of perturbation (fraction of bounding box) to add
         scalar perturb_;
 
@@ -120,23 +120,25 @@ class MappedFile
 
         void checkTable(const scalar t) const;
 
-        //- No copy assignment
-        void operator=(const MappedFile<Type>&) = delete;
-
-
 public:
 
     //- Runtime type information
     TypeName("mappedFile");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const MappedFile<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
         MappedFile
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
@@ -152,13 +154,13 @@ public:
             const bool faceValues
         );
 
-        //- Copy constructor
-        explicit MappedFile(const MappedFile<Type>& ut);
+        //- Copy construct
+        explicit MappedFile(const MappedFile<Type>& rhs);
 
-        //- Copy constructor setting patch
+        //- Copy construct setting patch
         explicit MappedFile
         (
-            const MappedFile<Type>& ut,
+            const MappedFile<Type>& rhs,
             const polyPatch& pp
         );
 
diff --git a/src/meshTools/PatchFunction1/PatchFunction1.C b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.C
similarity index 79%
rename from src/meshTools/PatchFunction1/PatchFunction1.C
rename to src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.C
index c833c3ab663bcb5a7dbf103c9b294890e3e7f78a..3f0d4721d2ddd85385ffb6f8dc3205b38a5100b0 100644
--- a/src/meshTools/PatchFunction1/PatchFunction1.C
+++ b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -39,10 +39,7 @@ Foam::PatchFunction1<Type>::PatchFunction1
     const bool faceValues
 )
 :
-    refCount(),
-    name_(entryName),
-    patch_(pp),
-    faceValues_(faceValues),
+    patchFunction1Base(pp, entryName, faceValues),
     coordSys_()
 {}
 
@@ -56,68 +53,32 @@ Foam::PatchFunction1<Type>::PatchFunction1
     const bool faceValues
 )
 :
-    refCount(),
-    name_(entryName),
-    patch_(pp),
-    faceValues_(faceValues),
+    patchFunction1Base(pp, entryName, dict, faceValues),
     coordSys_(pp.boundaryMesh().mesh().thisDb(), dict)
 {}
 
 
 template<class Type>
-Foam::PatchFunction1<Type>::PatchFunction1(const PatchFunction1<Type>& pf1)
+Foam::PatchFunction1<Type>::PatchFunction1(const PatchFunction1<Type>& rhs)
 :
-    refCount(),
-    name_(pf1.name_),
-    patch_(pf1.patch_),
-    faceValues_(pf1.faceValues_),
-    coordSys_(pf1.coordSys_)
+    PatchFunction1<Type>(rhs, rhs.patch())
 {}
 
 
 template<class Type>
 Foam::PatchFunction1<Type>::PatchFunction1
 (
-    const PatchFunction1<Type>& pf1,
+    const PatchFunction1<Type>& rhs,
     const polyPatch& pp
 )
 :
-    refCount(),
-    name_(pf1.name_),
-    patch_(pp),
-    faceValues_(pf1.faceValues_),
-    coordSys_(pf1.coordSys_)
+    patchFunction1Base(pp, rhs.name(), rhs.faceValues()),
+    coordSys_(rhs.coordSys_)
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template<class Type>
-const Foam::word& Foam::PatchFunction1<Type>::name() const
-{
-    return name_;
-}
-
-
-template<class Type>
-const Foam::polyPatch& Foam::PatchFunction1<Type>::patch() const
-{
-    return patch_;
-}
-
-
-template<class Type>
-bool Foam::PatchFunction1<Type>::faceValues() const
-{
-    return faceValues_;
-}
-
-
-template<class Type>
-void Foam::PatchFunction1<Type>::convertTimeBase(const Time&)
-{}
-
-
 template<class Type>
 Foam::tmp<Foam::Field<Type>> Foam::PatchFunction1<Type>::value
 (
@@ -125,8 +86,7 @@ Foam::tmp<Foam::Field<Type>> Foam::PatchFunction1<Type>::value
 ) const
 {
     NotImplemented;
-
-    return Field<Type>();
+    return nullptr;
 }
 
 template<class Type>
@@ -144,8 +104,7 @@ Foam::tmp<Foam::Field<Type>> Foam::PatchFunction1<Type>::integrate
 ) const
 {
     NotImplemented;
-
-    return Field<Type>();
+    return nullptr;
 }
 
 
@@ -175,7 +134,7 @@ Foam::tmp<Foam::Field<Type>> Foam::PatchFunction1<Type>::transform
 
     tmp<Field<Type>> tresult =
     (
-        faceValues_
+        this->faceValues()
       ? this->coordSys_.transform(this->patch_.faceCentres(), tfld())
       : this->coordSys_.transform(this->patch_.localPoints(), tfld())
     );
@@ -196,7 +155,7 @@ Foam::tmp<Foam::Field<Type>> Foam::PatchFunction1<Type>::transform
         return fld;
     }
 
-    if (faceValues_)
+    if (this->faceValues())
     {
         return this->coordSys_.transform(this->patch_.faceCentres(), fld);
     }
@@ -215,7 +174,7 @@ void Foam::PatchFunction1<Type>::autoMap(const FieldMapper& mapper)
 template<class Type>
 void Foam::PatchFunction1<Type>::rmap
 (
-    const PatchFunction1<Type>& pf1,
+    const PatchFunction1<Type>& rhs,
     const labelList& addr
 )
 {}
@@ -228,7 +187,7 @@ void Foam::PatchFunction1<Type>::writeData(Ostream& os) const
 
     // Leave type() output up to derived type. This is so 'Constant'&Uniform
     // can do backwards compatibility.
-    //os.writeKeyword(name_) << type();
+    //os.writeKeyword(this->name()) << this->type();
 }
 
 
@@ -243,7 +202,7 @@ Foam::Ostream& Foam::operator<<
 {
     os.check(FUNCTION_NAME);
 
-    os  << rhs.name_;
+    os  << rhs.name();
     rhs.writeData(os);
 
     return os;
diff --git a/src/meshTools/PatchFunction1/PatchFunction1.H b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.H
similarity index 73%
rename from src/meshTools/PatchFunction1/PatchFunction1.H
rename to src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.H
index 6a812af2a5da5fac7e62f47ab01340424c0e5c5b..b6039cf3d5c5f210812064bf0ba6043000d19a3a 100644
--- a/src/meshTools/PatchFunction1/PatchFunction1.H
+++ b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1.H
@@ -46,10 +46,9 @@ SeeAlso
 #ifndef PatchFunction1_H
 #define PatchFunction1_H
 
-#include "dictionary.H"
-#include "Field.H"
-#include "polyPatch.H"
+#include "patchFunction1Base.H"
 #include "coordinateScaling.H"
+#include "Field.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -70,20 +69,25 @@ Ostream& operator<<(Ostream&, const PatchFunction1<Type>&);
 template<class Type>
 class PatchFunction1
 :
-    public refCount
+    public patchFunction1Base
 {
-protected:
+    // Private Member Functions
 
-    // Protected Data
+        //- Selector, with alternative entry etc
+        static autoPtr<PatchFunction1<Type>> New
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            const entry* eptr,
+            const dictionary& dict,
+            const bool faceValues,
+            const bool mandatory
+        );
 
-        //- Name of entry
-        const word name_;
 
-        //- Reference to the patch
-        const polyPatch& patch_;
+protected:
 
-        //- Whether to generate face or point values on patch
-        const bool faceValues_;
+    // Protected Data
 
         //- Optional local co-ordinate system and scaling
         coordinateScaling<Type> coordSys_;
@@ -138,56 +142,61 @@ public:
             const bool faceValues = true
         );
 
-        //- Copy constructor
-        explicit PatchFunction1(const PatchFunction1<Type>& pf1);
+        //- Copy construct
+        explicit PatchFunction1(const PatchFunction1<Type>& rhs);
 
-        //- Copy constructor setting patch
+        //- Copy construct setting patch
         explicit PatchFunction1
         (
-            const PatchFunction1<Type>& pf1,
+            const PatchFunction1<Type>& rhs,
             const polyPatch& pp
         );
 
-        //- Construct and return a clone
+        //- Return a clone
         virtual tmp<PatchFunction1<Type>> clone() const = 0;
 
-        //- Construct and return a clone setting patch
+        //- Return a clone, setting patch
         virtual tmp<PatchFunction1<Type>> clone(const polyPatch& pp) const = 0;
 
 
-    //- Selector
-    static autoPtr<PatchFunction1<Type>> New
-    (
-        const polyPatch& pp,
-        const word& entryName,
-        const dictionary& dict,
-        const bool faceValues = true
-    );
-
-
-    //- Destructor
-    virtual ~PatchFunction1() = default;
-
-
-    // Member Functions
+    // Selectors
 
-        // Access
-
-            //- Return the name of the entry
-            const word& name() const;
+        //- Selector
+        static autoPtr<PatchFunction1<Type>> New
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            const dictionary& dict,
+            const bool faceValues = true,
+            const bool mandatory = true
+        );
 
-            //- Reference to the patch
-            const polyPatch& patch() const;
+        //- Compatibility selector
+        static autoPtr<PatchFunction1<Type>> NewCompat
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            std::initializer_list<std::pair<const char*,int>> compat,
+            const dictionary& dict,
+            const bool faceValues = true,
+            const bool mandatory = true
+        );
 
-            //- Whether to generate face or point values on patch
-            bool faceValues() const;
+        //- An optional selector
+        static autoPtr<PatchFunction1<Type>> NewIfPresent
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            const dictionary& dict,
+            const bool faceValues = true
+        );
 
 
-        // Manipulation
+    //- Destructor
+    virtual ~PatchFunction1() = default;
 
-            //- Convert time
-            virtual void convertTimeBase(const Time& t);
 
+    // Member Functions
 
         // Evaluation
 
@@ -231,7 +240,7 @@ public:
             //- Reverse map the given PatchFunction1 onto this PatchFunction1
             virtual void rmap
             (
-                const PatchFunction1<Type>& pf1,
+                const PatchFunction1<Type>& rhs,
                 const labelList& addr
             );
 
@@ -256,6 +265,7 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+// Define PatchFunction1 run-time selection
 #define makePatchFunction1(Type)                                               \
                                                                                \
     defineNamedTemplateTypeNameAndDebug(PatchFunction1<Type>, 0);              \
@@ -266,6 +276,8 @@ public:
         dictionary                                                             \
     );
 
+
+// Define (templated) PatchFunction1, add to (templated) run-time selection
 #define makePatchFunction1Type(SS, Type)                                       \
                                                                                \
     defineNamedTemplateTypeNameAndDebug(PatchFunction1Types::SS<Type>, 0);     \
@@ -274,6 +286,23 @@ public:
         <PatchFunction1Types::SS<Type>>                                        \
         add##SS##Type##ConstructorToTable_;
 
+
+// Define (non-templated) PatchFunction1, add to (templated) run-time selection
+#define makeConcretePatchFunction1Type(SS, Type)                               \
+                                                                               \
+    defineTypeNameAndDebug(SS, 0);                                             \
+                                                                               \
+    PatchFunction1<Type>::adddictionaryConstructorToTable                      \
+        <PatchFunction1Types::SS>                                              \
+        add##SS##Type##ConstructorToTable_;
+
+
+// Define scalar PatchFunction1 and add to (templated) run-time selection
+#define makeScalarPatchFunction1(SS)                                           \
+                                                                               \
+    makeConcretePatchFunction1Type(SS, scalar);
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
diff --git a/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1New.C b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1New.C
new file mode 100644
index 0000000000000000000000000000000000000000..925af5b0337d6f05566dff30a9c0c666706ed900
--- /dev/null
+++ b/src/meshTools/PatchFunction1/PatchFunction1/PatchFunction1New.C
@@ -0,0 +1,219 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2018-2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "ConstantField.H"
+
+// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
+
+template<class Type>
+Foam::autoPtr<Foam::PatchFunction1<Type>>
+Foam::PatchFunction1<Type>::New
+(
+    const polyPatch& pp,
+    const word& entryName,
+    const entry* eptr,
+    const dictionary& dict,
+    const bool faceValues,
+    const bool mandatory
+)
+{
+    word modelType;
+
+    const dictionary* coeffs = (eptr ? eptr->dictPtr() : nullptr);
+
+    if (coeffs)
+    {
+        // Dictionary entry
+
+        coeffs->readEntry
+        (
+            "type",
+            modelType,
+            keyType::LITERAL
+            // "type" entry is mandatory, there is no 'redirect'
+        );
+    }
+    else if (eptr)
+    {
+        // Primitive entry
+        // - non-word : value for constant (uniform) function
+        // - word : the modelType, or uniform/nonuniform
+
+        ITstream& is = eptr->stream();
+
+        token firstToken(is);
+
+        // Compatibility for reading straight fields
+        if (!firstToken.isWord())
+        {
+            // A value
+            is.putBack(firstToken);
+
+            const Type constValue = pTraits<Type>(is);
+
+            return autoPtr<PatchFunction1<Type>>
+            (
+                new PatchFunction1Types::ConstantField<Type>
+                (
+                    pp,
+                    entryName,
+                    constValue,
+                    dict,
+                    faceValues
+                )
+            );
+        }
+
+        modelType = firstToken.wordToken();
+
+        // Looks like a normal field entry?
+        if (modelType == "uniform" || modelType == "nonuniform")
+        {
+            return autoPtr<PatchFunction1<Type>>
+            (
+                new PatchFunction1Types::ConstantField<Type>
+                (
+                    pp,
+                    eptr,
+                    entryName,
+                    dict,
+                    faceValues
+                )
+            );
+        }
+
+        // Fallthrough
+    }
+
+
+    if (modelType.empty())
+    {
+        // Entry missing
+
+        if (mandatory)
+        {
+            FatalIOErrorInFunction(dict)
+                << "Missing or invalid PatchFunction1 entry: "
+                << entryName << nl
+                << exit(FatalIOError);
+        }
+
+        return nullptr;
+    }
+    else if (!coeffs)
+    {
+        // Primitive entry. Coeffs dictionary is optional.
+        // Use keyword() - not entryName - for compatibility lookup!
+
+        coeffs =
+           &dict.optionalSubDict
+            (
+                eptr->keyword() + "Coeffs",
+                keyType::LITERAL
+            );
+    }
+
+
+    auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
+
+    if (!cstrIter.found())
+    {
+        FatalIOErrorInFunction(dict)
+            << "Unknown PatchFunction1 type "
+            << modelType << " for " << entryName
+            << "\n\nValid PatchFunction1 types :\n"
+            << dictionaryConstructorTablePtr_->sortedToc() << nl
+            << exit(FatalIOError);
+    }
+
+    return cstrIter()(pp, modelType, entryName, *coeffs, faceValues);
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::PatchFunction1<Type>>
+Foam::PatchFunction1<Type>::New
+(
+    const polyPatch& pp,
+    const word& entryName,
+    const dictionary& dict,
+    const bool faceValues,
+    const bool mandatory
+)
+{
+    return PatchFunction1<Type>::New
+    (
+        pp,
+        entryName,
+        dict.findEntry(entryName, keyType::LITERAL),
+        dict,
+        faceValues,
+        mandatory
+    );
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::PatchFunction1<Type>>
+Foam::PatchFunction1<Type>::NewCompat
+(
+    const polyPatch& pp,
+    const word& entryName,
+    std::initializer_list<std::pair<const char*,int>> compat,
+    const dictionary& dict,
+    const bool faceValues,
+    const bool mandatory
+)
+{
+    return PatchFunction1<Type>::New
+    (
+        pp,
+        entryName,
+        dict.findCompat(entryName, compat, keyType::LITERAL),
+        dict,
+        faceValues,
+        mandatory
+    );
+}
+
+
+template<class Type>
+Foam::autoPtr<Foam::PatchFunction1<Type>>
+Foam::PatchFunction1<Type>::NewIfPresent
+(
+    const polyPatch& pp,
+    const word& entryName,
+    const dictionary& dict,
+    const bool faceValues
+)
+{
+    // mandatory = false
+    return PatchFunction1<Type>::New(pp, entryName, dict, faceValues, false);
+}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.C b/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.C
new file mode 100644
index 0000000000000000000000000000000000000000..6902e773bd61959e5242a71afcae2771f84cc38e
--- /dev/null
+++ b/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.C
@@ -0,0 +1,88 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "patchFunction1Base.H"
+#include "polyPatch.H"
+#include "Time.H"
+
+// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
+
+Foam::patchFunction1Base::patchFunction1Base
+(
+    const polyPatch& pp,
+    const word& entryName,
+    const bool faceValues
+)
+:
+    refCount(),
+    name_(entryName),
+    patch_(pp),
+    faceValues_(faceValues)
+{}
+
+
+Foam::patchFunction1Base::patchFunction1Base
+(
+    const polyPatch& pp,
+    const word& entryName,
+    const dictionary& dict,
+    const bool faceValues
+)
+:
+    refCount(),
+    name_(entryName),
+    patch_(pp),
+    faceValues_(faceValues)
+{}
+
+
+Foam::patchFunction1Base::patchFunction1Base(const patchFunction1Base& rhs)
+:
+    patchFunction1Base(rhs, rhs.patch())
+{}
+
+
+Foam::patchFunction1Base::patchFunction1Base
+(
+    const patchFunction1Base& rhs,
+    const polyPatch& pp
+)
+:
+    refCount(),
+    name_(rhs.name_),
+    patch_(pp),
+    faceValues_(rhs.faceValues_)
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::patchFunction1Base::convertTimeBase(const Time&)
+{}
+
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.H b/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.H
new file mode 100644
index 0000000000000000000000000000000000000000..f2c60158e5c20b7e7f31f9ed3333dca955774833
--- /dev/null
+++ b/src/meshTools/PatchFunction1/PatchFunction1/patchFunction1Base.H
@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | www.openfoam.com
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+    Copyright (C) 2020 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::patchFunction1Base
+
+Description
+    Top level data entry class for use in dictionaries. Provides a mechanism
+    to specify a variable as a certain type, e.g. constant or time varying, and
+    provide functions to return the (interpolated) value, and integral between
+    limits.
+
+    Extends the Function1 class by adding autoMap and rMap functions
+
+SourceFiles
+    patchFunction1Base.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef patchFunction1Base_H
+#define patchFunction1Base_H
+
+#include "dictionary.H"
+#include "polyPatch.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class Time;
+
+/*---------------------------------------------------------------------------*\
+                     Class patchFunction1Base Declaration
+\*---------------------------------------------------------------------------*/
+
+class patchFunction1Base
+:
+    public refCount
+{
+protected:
+
+    // Protected Data
+
+        //- Name of entry
+        const word name_;
+
+        //- Reference to the patch
+        const polyPatch& patch_;
+
+        //- Generate face or point values on patch
+        const bool faceValues_;
+
+
+    // Protected Member Functions
+
+        //- No copy assignment
+        void operator=(const patchFunction1Base&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from polyPatch and entry name
+        patchFunction1Base
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            const bool faceValues = true
+        );
+
+        //- Construct from polyPatch, dictionary and entry name
+        patchFunction1Base
+        (
+            const polyPatch& pp,
+            const word& entryName,
+            const dictionary& dict,
+            const bool faceValues = true
+        );
+
+        //- Copy construct
+        explicit patchFunction1Base(const patchFunction1Base& rhs);
+
+        //- Copy construct setting patch
+        explicit patchFunction1Base
+        (
+            const patchFunction1Base& rhs,
+            const polyPatch& pp
+        );
+
+
+    //- Destructor
+    virtual ~patchFunction1Base() = default;
+
+
+    // Member Functions
+
+    // Access
+
+        //- The name of the entry
+        const word& name() const
+        {
+            return name_;
+        }
+
+        //- Reference to the patch
+        const polyPatch& patch() const
+        {
+            return patch_;
+        }
+
+        //- Generate face or point values on patch?
+        bool faceValues() const
+        {
+            return faceValues_;
+        }
+
+        //- Number of faces or points on the patch
+        label size() const
+        {
+            return (faceValues_ ? patch_.size() : patch_.nPoints());
+        }
+
+
+    // Manipulation
+
+        //- Convert time
+        virtual void convertTimeBase(const Time&);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/meshTools/PatchFunction1/PatchFunction1New.C b/src/meshTools/PatchFunction1/PatchFunction1New.C
deleted file mode 100644
index f7821bbd1d6937374ac3e43fcbaf95ac4f75b97a..0000000000000000000000000000000000000000
--- a/src/meshTools/PatchFunction1/PatchFunction1New.C
+++ /dev/null
@@ -1,143 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | www.openfoam.com
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-    Copyright (C) 2018-2020 OpenCFD Ltd.
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software: you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-
-\*---------------------------------------------------------------------------*/
-
-#include "ConstantField.H"
-
-// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
-
-template<class Type>
-Foam::autoPtr<Foam::PatchFunction1<Type>>
-Foam::PatchFunction1<Type>::New
-(
-    const polyPatch& pp,
-    const word& entryName,
-    const dictionary& dict,
-    const bool faceValues
-)
-{
-    const entry* eptr = dict.findEntry(entryName, keyType::LITERAL);
-
-    if (!eptr)
-    {
-        FatalIOErrorInFunction(dict)
-            << "No PatchFunction1 dictionary entry: "
-            << entryName << nl << nl
-            << exit(FatalIOError);
-
-        // Failed
-        return nullptr;
-    }
-    else if (eptr->isDict())
-    {
-        const dictionary& coeffsDict = eptr->dict();
-
-        const word modelType(coeffsDict.getWord("type", keyType::LITERAL));
-
-        auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
-
-        if (!cstrIter.found())
-        {
-            FatalIOErrorInFunction(coeffsDict)
-                << "Unknown PatchFunction1 type "
-                << modelType << " for " << entryName
-                << "\n\nValid PatchFunction1 types :\n"
-                << dictionaryConstructorTablePtr_->sortedToc() << nl
-                << exit(FatalIOError);
-        }
-
-        return cstrIter()(pp, modelType, entryName, coeffsDict, faceValues);
-    }
-    else
-    {
-        ITstream& is = eptr->stream();
-
-        token firstToken(is);
-
-        if (!firstToken.isWord())
-        {
-            // Backwards-compatibility for reading straight fields
-            is.putBack(firstToken);
-
-            const Type uniformValue = pTraits<Type>(is);
-
-            return autoPtr<PatchFunction1<Type>>
-            (
-                new PatchFunction1Types::ConstantField<Type>
-                (
-                    pp,
-                    entryName,
-                    uniformValue,
-                    dict,
-                    faceValues
-                )
-            );
-        }
-
-        const word modelType = firstToken.wordToken();
-
-        // Check to see if this looks like a normal field entry
-        if (modelType == "uniform" || modelType == "nonuniform")
-        {
-            return autoPtr<PatchFunction1<Type>>
-            (
-                new PatchFunction1Types::ConstantField<Type>
-                (
-                    pp,
-                    PatchFunction1Types::ConstantField<Type>::typeName,
-                    entryName,
-                    dict,
-                    faceValues
-                )
-            );
-        }
-
-
-        auto cstrIter = dictionaryConstructorTablePtr_->cfind(modelType);
-
-        if (!cstrIter.found())
-        {
-            FatalIOErrorInFunction(dict)
-                << "Unknown PatchFunction1 type "
-                << modelType << " for " << entryName
-                << "\n\nValid PatchFunction1 types :\n"
-                << dictionaryConstructorTablePtr_->sortedToc() << nl
-                << exit(FatalIOError);
-        }
-
-        return cstrIter()
-        (
-            pp,
-            modelType,
-            entryName,
-            dict.optionalSubDict(entryName + "Coeffs"),
-            faceValues
-        );
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.C b/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.C
index 30fba43191cf0763ec09731f7684e5fcfd276e2a..5e3069ac859813e4924b7fe9e6941a406697ebdf 100644
--- a/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.C
+++ b/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -34,7 +34,7 @@ template<class Type>
 Foam::PatchFunction1Types::UniformValueField<Type>::UniformValueField
 (
     const polyPatch& pp,
-    const word& type,
+    const word& redirectType,
     const word& entryName,
     const dictionary& dict,
     const bool faceValues
@@ -47,7 +47,7 @@ Foam::PatchFunction1Types::UniformValueField<Type>::UniformValueField
         (
             entryName,
             dict,
-            type
+            redirectType
         )
     )
 {}
@@ -56,23 +56,22 @@ Foam::PatchFunction1Types::UniformValueField<Type>::UniformValueField
 template<class Type>
 Foam::PatchFunction1Types::UniformValueField<Type>::UniformValueField
 (
-    const UniformValueField<Type>& ut
+    const UniformValueField<Type>& rhs
 )
 :
-    PatchFunction1<Type>(ut),
-    uniformValuePtr_(ut.uniformValuePtr_.clone())
+    UniformValueField<Type>(rhs, rhs.patch())
 {}
 
 
 template<class Type>
 Foam::PatchFunction1Types::UniformValueField<Type>::UniformValueField
 (
-    const UniformValueField<Type>& ut,
+    const UniformValueField<Type>& rhs,
     const polyPatch& pp
 )
 :
-    PatchFunction1<Type>(ut, pp),
-    uniformValuePtr_(ut.uniformValuePtr_.clone())
+    PatchFunction1<Type>(rhs, pp),
+    uniformValuePtr_(rhs.uniformValuePtr_.clone())
 {}
 
 
diff --git a/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.H b/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.H
index d133dca4f9bd3d01091034a9e6088e4aa6196f7e..70b1e1170a2ad740229168bc77d4dfbeff27a8ca 100644
--- a/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.H
+++ b/src/meshTools/PatchFunction1/UniformValueField/UniformValueField.H
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -67,38 +67,37 @@ class UniformValueField
         //- Source of uniform values (in local coordinate system)
         autoPtr<Foam::Function1<Type>> uniformValuePtr_;
 
-
-    // Private Member Functions
-
-        //- No copy assignment
-        void operator=(const UniformValueField<Type>&) = delete;
-
-
 public:
 
     // Runtime type information
     TypeName("uniformValue");
 
 
+    // Generated Methods
+
+        //- No copy assignment
+        void operator=(const UniformValueField<Type>&) = delete;
+
+
     // Constructors
 
         //- Construct from entry name and dictionary
         UniformValueField
         (
             const polyPatch& pp,
-            const word& type,
+            const word& redirectType,
             const word& entryName,
             const dictionary& dict,
             const bool faceValues = true
         );
 
-        //- Copy constructor
-        explicit UniformValueField(const UniformValueField<Type>& ut);
+        //- Copy construct
+        explicit UniformValueField(const UniformValueField<Type>& rhs);
 
-        //- Copy constructor setting patch
+        //- Copy construct setting patch
         explicit UniformValueField
         (
-            const UniformValueField<Type>& ut,
+            const UniformValueField<Type>& rhs,
             const polyPatch& pp
         );
 
diff --git a/src/meshTools/PatchFunction1/UniformValueField/UniformValueFieldI.H b/src/meshTools/PatchFunction1/UniformValueField/UniformValueFieldI.H
index fa7e5a871bb1fd9f3d24652f2442754274f8393e..c9093061fd413ed61a4559ec30eba7a758d3d6f6 100644
--- a/src/meshTools/PatchFunction1/UniformValueField/UniformValueFieldI.H
+++ b/src/meshTools/PatchFunction1/UniformValueField/UniformValueFieldI.H
@@ -46,13 +46,10 @@ Foam::PatchFunction1Types::UniformValueField<Type>::value
     const scalar x
 ) const
 {
-    const label len =
-        (this->faceValues_ ? this->patch_.size() : this->patch_.nPoints());
-
     auto tfld =
         tmp<Field<Type>>::New
         (
-            len,
+            this->size(),
             uniformValuePtr_->value(x)
         );
 
@@ -68,13 +65,10 @@ Foam::PatchFunction1Types::UniformValueField<Type>::integrate
     const scalar x2
 ) const
 {
-    const label len =
-        (this->faceValues_ ? this->patch_.size() : this->patch_.nPoints());
-
     auto tfld =
         tmp<Field<Type>>::New
         (
-            len,
+            this->size(),
             uniformValuePtr_->integrate(x1, x2)
         );
 
diff --git a/src/meshTools/PatchFunction1/coordinateScaling.C b/src/meshTools/PatchFunction1/coordinateScaling/coordinateScaling.C
similarity index 100%
rename from src/meshTools/PatchFunction1/coordinateScaling.C
rename to src/meshTools/PatchFunction1/coordinateScaling/coordinateScaling.C
diff --git a/src/meshTools/PatchFunction1/coordinateScaling.H b/src/meshTools/PatchFunction1/coordinateScaling/coordinateScaling.H
similarity index 100%
rename from src/meshTools/PatchFunction1/coordinateScaling.H
rename to src/meshTools/PatchFunction1/coordinateScaling/coordinateScaling.H
diff --git a/src/meshTools/PatchFunction1/coordinateLabelScaling.C b/src/meshTools/PatchFunction1/coordinateScaling/coordinateScalings.C
similarity index 100%
rename from src/meshTools/PatchFunction1/coordinateLabelScaling.C
rename to src/meshTools/PatchFunction1/coordinateScaling/coordinateScalings.C
diff --git a/src/rigidBodyMeshMotion/rigidBodyMeshMotion/rigidBodyMeshMotion.C b/src/rigidBodyMeshMotion/rigidBodyMeshMotion/rigidBodyMeshMotion.C
index 5c71f9dc53396bc84e0a13e15cdf99c41915d277..e27d8d1c8081ce4854ba5de40017f9a54721ca1d 100644
--- a/src/rigidBodyMeshMotion/rigidBodyMeshMotion/rigidBodyMeshMotion.C
+++ b/src/rigidBodyMeshMotion/rigidBodyMeshMotion/rigidBodyMeshMotion.C
@@ -33,7 +33,6 @@ License
 #include "pointConstraints.H"
 #include "uniformDimensionedFields.H"
 #include "forces.H"
-#include "OneConstant.H"
 #include "mathematicalConstants.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -120,7 +119,7 @@ Foam::rigidBodyMeshMotion::rigidBodyMeshMotion
     test_(coeffDict().getOrDefault("test", false)),
     rhoInf_(1.0),
     rhoName_(coeffDict().getOrDefault<word>("rho", "rho")),
-    ramp_(nullptr),
+    ramp_(Function1<scalar>::NewIfPresent("ramp", coeffDict())),
     curTimeIndex_(-1)
 {
     if (rhoName_ == "rhoInf")
@@ -128,15 +127,6 @@ Foam::rigidBodyMeshMotion::rigidBodyMeshMotion
         readEntry("rhoInf", rhoInf_);
     }
 
-    if (coeffDict().found("ramp"))
-    {
-        ramp_ = Function1<scalar>::New("ramp", coeffDict());
-    }
-    else
-    {
-        ramp_.reset(new Function1Types::OneConstant<scalar>("ramp"));
-    }
-
     const dictionary& bodiesDict = coeffDict().subDict("bodies");
 
     for (const entry& dEntry : bodiesDict)
@@ -242,7 +232,7 @@ void Foam::rigidBodyMeshMotion::solve()
         curTimeIndex_ = this->db().time().timeIndex();
     }
 
-    const scalar ramp = ramp_->value(t.value());
+    const scalar ramp = (ramp_ ? ramp_->value(t.value()) : 1.0);
 
     if (t.foundObject<uniformDimensionedVectorField>("g"))
     {