From b59ae32d68a0714c9fa81d0c6285125e508ae285 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Tue, 1 Jun 2021 11:27:45 +0200
Subject: [PATCH] ENH: provide dictionary access for coded BCs etc (#1922)

- in some cases, additional dictionary inputs are useful for extending
  the input parameters or functionality of dynamic coded conditions.

  Typically this can be used to provide a simple set of dictionary
  inputs that are used to drive specific code, but allows changing the
  inputs without causing a recompilation.

  Accessed with this type of code:
  ```
  const dictionary& dict = this->codeContext();
  ```

boundary conditions and function objects:

* specify an additional codeContext dictionary entry:
  ```
  codeContext
  {
      ...
  }
  ```

PatchFunction1:

* The code context dictionary is simply the dictionary used to specify
  the PatchFunction1 coefficients.

  To replicated persistant data, use local member static data.
  Eg,
  ```
  code
  #{
      // Persistent (Member) Data
      static autoPtr<Function1<scalar>> baseVel;
      static autoPtr<Function1<vector>> baseDir;
      ...
  #}
  ```

fvOptions:

* currently not applicable
---
 .../dynamicCode/codedFvOptionTemplate.H       | 10 ++++++-
 .../dynamicCode/codedPatchFunction1Template.C | 10 -------
 .../dynamicCode/codedPatchFunction1Template.H |  7 +++--
 .../codedPoints0MotionSolverTemplate.H        | 10 ++++++-
 .../fixedValueFvPatchFieldTemplate.H          | 10 ++++++-
 .../fixedValuePointPatchFieldTemplate.H       | 10 ++++++-
 .../dynamicCode/functionObjectTemplate.H      | 10 ++++++-
 .../dynamicCode/mixedFvPatchFieldTemplate.H   | 10 ++++++-
 .../codedFixedValuePointPatchField.C          | 25 +++++++++++++++++
 .../codedFixedValuePointPatchField.H          | 13 +++++++++
 .../codedFixedValueFvPatchField.C             | 25 +++++++++++++++++
 .../codedFixedValueFvPatchField.H             | 13 +++++++++
 .../codedMixed/codedMixedFvPatchField.C       | 24 ++++++++++++++++
 .../codedMixed/codedMixedFvPatchField.H       |  8 ++++++
 .../codedFunctionObject/codedFunctionObject.C | 24 ++++++++++++++++
 .../codedFunctionObject/codedFunctionObject.H |  8 ++++++
 .../PatchFunction1/CodedField/CodedField.C    | 28 +++++++++++++++++++
 .../PatchFunction1/CodedField/CodedField.H    |  7 +++++
 18 files changed, 233 insertions(+), 19 deletions(-)

diff --git a/etc/codeTemplates/dynamicCode/codedFvOptionTemplate.H b/etc/codeTemplates/dynamicCode/codedFvOptionTemplate.H
index c9d397e1d1c..e252336236c 100644
--- a/etc/codeTemplates/dynamicCode/codedFvOptionTemplate.H
+++ b/etc/codeTemplates/dynamicCode/codedFvOptionTemplate.H
@@ -102,6 +102,7 @@ SourceFiles
 #define codedFvOptionTemplate_H
 
 #include "cellSetOption.H"
+#include "dictionaryContent.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -116,7 +117,8 @@ namespace fv
 
 class ${typeName}FvOption${SourceType}
 :
-    public fv::cellSetOption
+    public fv::cellSetOption,
+    public dictionaryContent
 {
     // Private Member Functions
 
@@ -153,6 +155,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Correct field
         virtual void correct
         (
diff --git a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
index cc7cc9e1cd0..ffce21acf36 100644
--- a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
+++ b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.C
@@ -107,16 +107,6 @@ ${typeName}PatchFunction1${FieldType}
 }
 
 
-${typeName}PatchFunction1${FieldType}::
-${typeName}PatchFunction1${FieldType}
-(
-    const ${typeName}PatchFunction1${FieldType}& rhs
-)
-:
-    parent_bctype(rhs)
-{}
-
-
 ${typeName}PatchFunction1${FieldType}::
 ${typeName}PatchFunction1${FieldType}
 (
diff --git a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
index 21b712f3568..8e53867c038 100644
--- a/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
+++ b/etc/codeTemplates/dynamicCode/codedPatchFunction1Template.H
@@ -35,6 +35,7 @@ SourceFiles
 #define codedPatchFunction1Template${FieldType}_H
 
 #include "PatchFunction1.H"
+#include "dictionaryContent.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -49,12 +50,12 @@ namespace PatchFunction1Types
 
 class ${typeName}PatchFunction1${FieldType}
 :
-    public PatchFunction1<${TemplateType}>
+    public PatchFunction1<${TemplateType}>,
+    public dictionaryContent
 {
     //- The parent PatchFunction1 type
     typedef PatchFunction1<${TemplateType}> parent_bctype;
 
-
     // Private Member Functions
 
         //- Report a message with the SHA1sum
@@ -88,7 +89,7 @@ public:
         ${typeName}PatchFunction1${FieldType}
         (
             const ${typeName}PatchFunction1${FieldType}& rhs
-        );
+        ) = default;
 
         //- Copy construct, resetting patch
         ${typeName}PatchFunction1${FieldType}
diff --git a/etc/codeTemplates/dynamicCode/codedPoints0MotionSolverTemplate.H b/etc/codeTemplates/dynamicCode/codedPoints0MotionSolverTemplate.H
index 5a8c45b4309..8a2a70fcf8d 100644
--- a/etc/codeTemplates/dynamicCode/codedPoints0MotionSolverTemplate.H
+++ b/etc/codeTemplates/dynamicCode/codedPoints0MotionSolverTemplate.H
@@ -36,6 +36,7 @@ SourceFiles
 #define codedPoints0MotionSolverTemplate_H
 
 #include "points0MotionSolver.H"
+#include "dictionaryContent.H"
 
 //{{{ begin codeInclude
 ${codeInclude}
@@ -52,7 +53,8 @@ namespace Foam
 
 class ${typeName}Points0MotionSolver
 :
-    public points0MotionSolver
+    public points0MotionSolver,
+    public dictionaryContent
 {
     // Private Member Functions
 
@@ -100,6 +102,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Provide current points for motion. Uses current motion field
         virtual tmp<pointField> curPoints() const;
 
diff --git a/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.H b/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.H
index ca1d2e5c49e..5c345838d9e 100644
--- a/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.H
+++ b/etc/codeTemplates/dynamicCode/fixedValueFvPatchFieldTemplate.H
@@ -38,6 +38,7 @@ SourceFiles
 #define fixedValueFvPatchTemplate${FieldType}_H
 
 #include "fixedValueFvPatchFields.H"
+#include "dictionaryContent.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -50,7 +51,8 @@ namespace Foam
 
 class ${typeName}FixedValueFvPatch${FieldType}
 :
-    public fixedValueFvPatchField<${TemplateType}>
+    public fixedValueFvPatchField<${TemplateType}>,
+    public dictionaryContent
 {
     //- The parent boundary condition type
     typedef fixedValueFvPatchField<${TemplateType}> parent_bctype;
@@ -140,6 +142,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Update the coefficients associated with the patch field
         virtual void updateCoeffs();
 };
diff --git a/etc/codeTemplates/dynamicCode/fixedValuePointPatchFieldTemplate.H b/etc/codeTemplates/dynamicCode/fixedValuePointPatchFieldTemplate.H
index 164d625d142..9fd6198afbf 100644
--- a/etc/codeTemplates/dynamicCode/fixedValuePointPatchFieldTemplate.H
+++ b/etc/codeTemplates/dynamicCode/fixedValuePointPatchFieldTemplate.H
@@ -38,6 +38,7 @@ SourceFiles
 #define coded_fixedValuePointPatchTemplate${FieldType}_H
 
 #include "fixedValuePointPatchFields.H"
+#include "dictionaryContent.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -50,7 +51,8 @@ namespace Foam
 
 class ${typeName}FixedValuePointPatch${FieldType}
 :
-    public fixedValuePointPatchField<${TemplateType}>
+    public fixedValuePointPatchField<${TemplateType}>,
+    public dictionaryContent
 {
     //- The parent boundary condition type
     typedef fixedValuePointPatchField<${TemplateType}> parent_bctype;
@@ -141,6 +143,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Update the coefficients associated with the patch field
         virtual void updateCoeffs();
 };
diff --git a/etc/codeTemplates/dynamicCode/functionObjectTemplate.H b/etc/codeTemplates/dynamicCode/functionObjectTemplate.H
index 3b2c2b238dc..8cb7aaaca4d 100644
--- a/etc/codeTemplates/dynamicCode/functionObjectTemplate.H
+++ b/etc/codeTemplates/dynamicCode/functionObjectTemplate.H
@@ -36,6 +36,7 @@ SourceFiles
 #define functionObjectTemplate_H
 
 #include "regionFunctionObject.H"
+#include "dictionaryContent.H"
 
 //{{{ begin codeInclude
 ${codeInclude}
@@ -55,7 +56,8 @@ class fvMesh;
 
 class ${typeName}FunctionObject
 :
-    public functionObjects::regionFunctionObject
+    public functionObjects::regionFunctionObject,
+    public dictionaryContent
 {
     // Private Data
 
@@ -113,6 +115,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Read optional controls
         virtual bool read(const dictionary& dict);
 
diff --git a/etc/codeTemplates/dynamicCode/mixedFvPatchFieldTemplate.H b/etc/codeTemplates/dynamicCode/mixedFvPatchFieldTemplate.H
index 5b915c4b789..83ef277870c 100644
--- a/etc/codeTemplates/dynamicCode/mixedFvPatchFieldTemplate.H
+++ b/etc/codeTemplates/dynamicCode/mixedFvPatchFieldTemplate.H
@@ -38,6 +38,7 @@ SourceFiles
 #define coded_mixedFvPatchTemplate${FieldType}_H
 
 #include "mixedFvPatchFields.H"
+#include "dictionaryContent.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -50,7 +51,8 @@ namespace Foam
 
 class ${typeName}MixedValueFvPatch${FieldType}
 :
-    public mixedFvPatchField<${TemplateType}>
+    public mixedFvPatchField<${TemplateType}>,
+    public dictionaryContent
 {
     //- The parent boundary condition type
     typedef mixedFvPatchField<${TemplateType}> parent_bctype;
@@ -140,6 +142,12 @@ public:
 
     // Member Functions
 
+        //- Code context as a dictionary
+        const dictionary& codeContext() const
+        {
+            return dictionaryContent::dict();
+        }
+
         //- Update the coefficients associated with the patch field
         virtual void updateCoeffs();
 };
diff --git a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C
index b3a8be6b26c..ae21366c0f6 100644
--- a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C
+++ b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C
@@ -60,6 +60,15 @@ void Foam::codedFixedValuePointPatchField<Type>::clearRedirect() const
 }
 
 
+template<class Type>
+const Foam::dictionary&
+Foam::codedFixedValuePointPatchField<Type>::codeContext() const
+{
+    const dictionary* ptr = dict_.findDict("codeContext", keyType::LITERAL);
+    return (ptr ? *ptr : dictionary::null);
+}
+
+
 template<class Type>
 const Foam::dictionary&
 Foam::codedFixedValuePointPatchField<Type>::codeDict() const
@@ -235,6 +244,22 @@ Foam::codedFixedValuePointPatchField<Type>::redirectPatchField() const
                 constructDict
             ).ptr()
         );
+
+
+        // Forward copy of codeContext to the code template
+        auto* contentPtr =
+            dynamic_cast<dictionaryContent*>(redirectPatchFieldPtr_.get());
+
+        if (contentPtr)
+        {
+            contentPtr->dict(this->codeContext());
+        }
+        else
+        {
+            WarningInFunction
+                << name_ << " Did not derive from dictionaryContent"
+                << nl << nl;
+        }
     }
     return *redirectPatchFieldPtr_;
 }
diff --git a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.H b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.H
index 3a891d0b33b..6d79944f12c 100644
--- a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.H
+++ b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.H
@@ -38,6 +38,7 @@ Description
        codeLibs    | linker line: added to LIB_LIBS (Make/options)
        localCode   | c++; local static functions
        code        | c++; patch value assignment
+       codeContext | additional dictionary context for the code
     \endplaintable
 
     Example:
@@ -56,6 +57,11 @@ Description
             );
         #};
 
+        codeContext
+        {
+             ...
+        }
+
         //codeInclude
         //#{
         //    #include "fvCFD.H"
@@ -82,6 +88,10 @@ Description
     }
     \endverbatim
 
+Note
+    The code context dictionary can be supplied separately as the
+    \c codeContext entry.
+
 See also
     codedFixedValueFvPatchField
 
@@ -136,6 +146,9 @@ class codedFixedValuePointPatchField
         //- Clear redirected object(s)
         virtual void clearRedirect() const;
 
+        //- Additional 'codeContext' dictionary to pass through
+        virtual const dictionary& codeContext() const;
+
         //- The code dictionary. Inline "code" or from system/codeDict
         virtual const dictionary& codeDict() const;
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
index 6882ded6ea9..73f1e360041 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
@@ -60,6 +60,15 @@ void Foam::codedFixedValueFvPatchField<Type>::clearRedirect() const
 }
 
 
+template<class Type>
+const Foam::dictionary&
+Foam::codedFixedValueFvPatchField<Type>::codeContext() const
+{
+    const dictionary* ptr = dict_.findDict("codeContext", keyType::LITERAL);
+    return (ptr ? *ptr : dictionary::null);
+}
+
+
 template<class Type>
 const Foam::dictionary&
 Foam::codedFixedValueFvPatchField<Type>::codeDict() const
@@ -234,6 +243,22 @@ Foam::codedFixedValueFvPatchField<Type>::redirectPatchField() const
                 constructDict
             ).ptr()
         );
+
+
+        // Forward copy of codeContext to the code template
+        auto* contentPtr =
+            dynamic_cast<dictionaryContent*>(redirectPatchFieldPtr_.get());
+
+        if (contentPtr)
+        {
+            contentPtr->dict(this->codeContext());
+        }
+        else
+        {
+            WarningInFunction
+                << name_ << " Did not derive from dictionaryContent"
+                << nl << nl;
+        }
     }
     return *redirectPatchFieldPtr_;
 }
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
index 8ae89cdc44f..19201b6b43c 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
@@ -41,6 +41,7 @@ Description
        codeLibs    | linker line: added to LIB_LIBS (Make/options)
        localCode   | c++; local static functions
        code        | c++; patch value assignment
+       codeContext | additional dictionary context for the code
     \endplaintable
 
 Usage
@@ -52,6 +53,11 @@ Usage
         value   uniform 0;
         name    rampedFixedValue;   // name of generated BC
 
+        codeContext
+        {
+            ...
+        }
+
         code
         #{
             operator==(min(10, 0.1*this->db().time().value()));
@@ -83,6 +89,10 @@ Usage
     }
     \endverbatim
 
+Note
+    The code context dictionary can be supplied separately as the
+    \c codeContext entry.
+
 See also
     Foam::dynamicCode
     Foam::functionEntries::codeStream
@@ -138,6 +148,9 @@ class codedFixedValueFvPatchField
         //- Clear redirected object(s)
         virtual void clearRedirect() const;
 
+        //- Additional 'codeContext' dictionary to pass through
+        virtual const dictionary& codeContext() const;
+
         //- The code dictionary. Inline "code" or from system/codeDict
         virtual const dictionary& codeDict() const;
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C
index 8f73c442888..e294c6474d5 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C
@@ -60,6 +60,15 @@ void Foam::codedMixedFvPatchField<Type>::clearRedirect() const
 }
 
 
+template<class Type>
+const Foam::dictionary&
+Foam::codedMixedFvPatchField<Type>::codeContext() const
+{
+    const dictionary* ptr = dict_.findDict("codeContext", keyType::LITERAL);
+    return (ptr ? *ptr : dictionary::null);
+}
+
+
 template<class Type>
 const Foam::dictionary&
 Foam::codedMixedFvPatchField<Type>::codeDict() const
@@ -240,6 +249,21 @@ Foam::codedMixedFvPatchField<Type>::redirectPatchField() const
                 ).ptr()
             )
         );
+
+        // Forward copy of dictionary content to the code template
+        auto* contentPtr =
+            dynamic_cast<dictionaryContent*>(redirectPatchFieldPtr_.get());
+
+        if (contentPtr)
+        {
+            contentPtr->dict(this->codeContext());
+        }
+        else
+        {
+            WarningInFunction
+                << name_ << " Did not derive from dictionaryContent"
+                << nl << nl;
+        }
     }
     return *redirectPatchFieldPtr_;
 }
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H
index 63430f2d34e..89bbc2320d1 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.H
@@ -41,6 +41,7 @@ Description
        codeLibs    | linker line: added to LIB_LIBS (Make/options)
        localCode   | c++; local static functions;
        code        | c++; patch value assignment
+       codeContext | additional dictionary context for the code
     \endplaintable
 
 Usage
@@ -93,6 +94,10 @@ Usage
     }
     \endverbatim
 
+Note
+    The code context dictionary can be supplied separately as the
+    \c codeContext entry.
+
 See also
     Foam::dynamicCode
     Foam::functionEntries::codeStream
@@ -150,6 +155,9 @@ protected:
         //- Clear redirected object(s)
         virtual void clearRedirect() const;
 
+        //- Additional 'codeContext' dictionary to pass through
+        virtual const dictionary& codeContext() const;
+
         //- The code dictionary. Inline "code" or from system/codeDict
         virtual const dictionary& codeDict() const;
 
diff --git a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
index 9914a37f412..cc8ab31bc89 100644
--- a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
+++ b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
@@ -72,6 +72,14 @@ void Foam::functionObjects::codedFunctionObject::clearRedirect() const
 }
 
 
+const Foam::dictionary&
+Foam::functionObjects::codedFunctionObject::codeContext() const
+{
+    const dictionary* ptr = dict_.findDict("codeContext", keyType::LITERAL);
+    return (ptr ? *ptr : dictionary::null);
+}
+
+
 const Foam::dictionary&
 Foam::functionObjects::codedFunctionObject::codeDict() const
 {
@@ -157,6 +165,22 @@ Foam::functionObjects::codedFunctionObject::redirectFunctionObject() const
             time_,
             constructDict
         );
+
+
+        // Forward copy of codeContext to the code template
+        auto* contentPtr =
+            dynamic_cast<dictionaryContent*>(redirectFunctionObjectPtr_.get());
+
+        if (contentPtr)
+        {
+            contentPtr->dict(this->codeContext());
+        }
+        else
+        {
+            WarningInFunction
+                << name_ << " Did not derive from dictionaryContent"
+                << nl << nl;
+        }
     }
     return *redirectFunctionObjectPtr_;
 }
diff --git a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
index 202365ca337..8508c4a4087 100644
--- a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
+++ b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
@@ -44,6 +44,7 @@ Description
        codeExecute | c++; upon functionObject::execute()
        codeWrite   | c++; upon functionObject::write()
        codeEnd     | c++; upon functionObject::end()
+       codeContext | additional dictionary context for the code
     \endplaintable
 
 Usage
@@ -67,6 +68,10 @@ Usage
     }
     \endverbatim
 
+Note
+    The code context dictionary can be supplied separately as the
+    \c codeContext entry.
+
 See also
     Foam::functionObject
     Foam::codedBase
@@ -128,6 +133,9 @@ protected:
         //- Clear redirected object(s)
         virtual void clearRedirect() const;
 
+        //- Additional 'codeContext' dictionary to pass through
+        virtual const dictionary& codeContext() const;
+
         //- The code dictionary
         virtual const dictionary& codeDict() const;
 
diff --git a/src/meshTools/PatchFunction1/CodedField/CodedField.C b/src/meshTools/PatchFunction1/CodedField/CodedField.C
index b97e16c714a..60ca1ecca87 100644
--- a/src/meshTools/PatchFunction1/CodedField/CodedField.C
+++ b/src/meshTools/PatchFunction1/CodedField/CodedField.C
@@ -54,6 +54,15 @@ void Foam::PatchFunction1Types::CodedField<Type>::clearRedirect() const
 }
 
 
+template<class Type>
+const Foam::dictionary&
+Foam::PatchFunction1Types::CodedField<Type>::codeContext() const
+{
+    // What else would make sense?
+    return dict_;
+}
+
+
 template<class Type>
 const Foam::dictionary&
 Foam::PatchFunction1Types::CodedField<Type>::codeDict
@@ -148,6 +157,10 @@ Foam::PatchFunction1Types::CodedField<Type>::CodedField
     dict_(dict),
     name_(dict.getOrDefault<word>("name", entryName))
 {
+    this->codedBase::setCodeContext(dict_);
+
+    // No additional code chunks...
+
     updateLibrary(name_);
 }
 
@@ -202,6 +215,21 @@ Foam::PatchFunction1Types::CodedField<Type>::redirectFunction() const
                 this->faceValues()
             )
         );
+
+        // Forward copy of codeContext to the code template
+        auto* contentPtr =
+            dynamic_cast<dictionaryContent*>(redirectFunctionPtr_.get());
+
+        if (contentPtr)
+        {
+            contentPtr->dict(this->codeContext());
+        }
+        else
+        {
+            WarningInFunction
+                << name_ << " Did not derive from dictionaryContent"
+                << nl << nl;
+        }
     }
     return *redirectFunctionPtr_;
 }
diff --git a/src/meshTools/PatchFunction1/CodedField/CodedField.H b/src/meshTools/PatchFunction1/CodedField/CodedField.H
index 5751215f070..a4dd238c8d6 100644
--- a/src/meshTools/PatchFunction1/CodedField/CodedField.H
+++ b/src/meshTools/PatchFunction1/CodedField/CodedField.H
@@ -70,6 +70,10 @@ Usage
     }
     \endverbatim
 
+Note
+    The code context dictionary is simply the dictionary used to specify
+    the PatchFunction1 coefficients.
+
 See also
     Foam::dynamicCode
     Foam::codedFixedValue
@@ -132,6 +136,9 @@ protected:
         //- Clear redirected object(s)
         virtual void clearRedirect() const;
 
+        //- Additional 'codeContext' dictionary to pass through
+        virtual const dictionary& codeContext() const;
+
         // Get the code (sub)dictionary
         virtual const dictionary& codeDict(const dictionary& dict) const;
 
-- 
GitLab