From cd64f1762f0f9253fbae3a0d22803ca02670f7d7 Mon Sep 17 00:00:00 2001
From: mattijs <mattijs>
Date: Mon, 24 Oct 2011 21:33:16 +0100
Subject: [PATCH] ENH: codedFixedValue: refactor coded

---
 src/OpenFOAM/Make/files                       |   1 +
 .../db/dynamicLibrary/codedBase/codedBase.C   | 288 ++++++++++++++++
 .../db/dynamicLibrary/codedBase/codedBase.H   | 142 ++++++++
 .../codedFixedValueFvPatchField.C             | 319 +++---------------
 .../codedFixedValueFvPatchField.H             |  53 +--
 .../codedFunctionObject/codedFunctionObject.C | 312 ++++-------------
 .../codedFunctionObject/codedFunctionObject.H |  55 +--
 7 files changed, 577 insertions(+), 593 deletions(-)
 create mode 100644 src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C
 create mode 100644 src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H

diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 3e52499e25f..6e169d64bc5 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -193,6 +193,7 @@ dll = db/dynamicLibrary
 $(dll)/dlLibraryTable/dlLibraryTable.C
 $(dll)/dynamicCode/dynamicCode.C
 $(dll)/dynamicCode/dynamicCodeContext.C
+$(dll)/codedBase/codedBase.C
 
 db/functionObjects/functionObject/functionObject.C
 db/functionObjects/functionObjectList/functionObjectList.C
diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C
new file mode 100644
index 00000000000..c899b97b595
--- /dev/null
+++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C
@@ -0,0 +1,288 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+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 "codedBase.H"
+#include "SHA1Digest.H"
+#include "dynamicCode.H"
+#include "dynamicCodeContext.H"
+#include "dlLibraryTable.H"
+#include "PstreamReduceOps.H"
+#include "OSspecific.H"
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+void* Foam::codedBase::loadLibrary
+(
+    const fileName& libPath,
+    const string& globalFuncName,
+    const dictionary& contextDict
+) const
+{
+    void* lib = 0;
+
+    // avoid compilation by loading an existing library
+    if (!libPath.empty())
+    {
+        if (libs().open(libPath, false))
+        {
+            lib = libs().findLibrary(libPath);
+
+            // verify the loaded version and unload if needed
+            if (lib)
+            {
+                // provision for manual execution of code after loading
+                if (dlSymFound(lib, globalFuncName))
+                {
+                    loaderFunctionType function =
+                        reinterpret_cast<loaderFunctionType>
+                        (
+                            dlSym(lib, globalFuncName)
+                        );
+
+                    if (function)
+                    {
+                        (*function)(true);    // force load
+                    }
+                    else
+                    {
+                        FatalIOErrorIn
+                        (
+                            "codedBase::updateLibrary()",
+                            contextDict
+                        )   << "Failed looking up symbol " << globalFuncName
+                            << nl << "from " << libPath << exit(FatalIOError);
+                    }
+                }
+                else
+                {
+                    FatalIOErrorIn
+                    (
+                        "codedBase::loadLibrary()",
+                        contextDict
+                    )   << "Failed looking up symbol " << globalFuncName << nl
+                        << "from " << libPath << exit(FatalIOError);
+
+                    lib = 0;
+                    if (!libs().close(libPath, false))
+                    {
+                        FatalIOErrorIn
+                        (
+                            "codedBase::loadLibrary()",
+                            contextDict
+                        )   << "Failed unloading library "
+                            << libPath
+                            << exit(FatalIOError);
+                    }
+                }
+            }
+        }
+    }
+
+    return lib;
+}
+
+
+void Foam::codedBase::unloadLibrary
+(
+    const fileName& libPath,
+    const string& globalFuncName,
+    const dictionary& contextDict
+) const
+{
+    void* lib = 0;
+
+    if (libPath.empty())
+    {
+        return;
+    }
+
+    lib = libs().findLibrary(libPath);
+
+    if (!lib)
+    {
+        return;
+    }
+
+    // provision for manual execution of code before unloading
+    if (dlSymFound(lib, globalFuncName))
+    {
+        loaderFunctionType function =
+            reinterpret_cast<loaderFunctionType>
+            (
+                dlSym(lib, globalFuncName)
+            );
+
+        if (function)
+        {
+            (*function)(false);    // force unload
+        }
+        else
+        {
+            FatalIOErrorIn
+            (
+                "codedBase::unloadLibrary()",
+                contextDict
+            )   << "Failed looking up symbol " << globalFuncName << nl
+                << "from " << libPath << exit(FatalIOError);
+        }
+    }
+
+    if (!libs().close(libPath, false))
+    {
+        FatalIOErrorIn
+        (
+            "codedBase::updateLibrary()",
+            contextDict
+        )   << "Failed unloading library " << libPath
+            << exit(FatalIOError);
+    }
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::codedBase::createLibrary
+(
+    dynamicCode& dynCode,
+    const dynamicCodeContext& context
+) const
+{
+    bool create = Pstream::master();
+
+    if (create)
+    {
+        // Write files for new library
+        if (!dynCode.upToDate(context))
+        {
+            // filter with this context
+            dynCode.reset(context);
+
+            this->prepare(dynCode, context);
+
+            if (!dynCode.copyOrCreateFiles(true))
+            {
+                FatalIOErrorIn
+                (
+                    "codedBase::createLibrary(..)",
+                    context.dict()
+                )   << "Failed writing files for" << nl
+                    << dynCode.libRelPath() << nl
+                    << exit(FatalIOError);
+            }
+        }
+
+        if (!dynCode.wmakeLibso())
+        {
+            FatalIOErrorIn
+            (
+                "codedBase::createLibrary(..)",
+                context.dict()
+            )   << "Failed wmake " << dynCode.libRelPath() << nl
+                << exit(FatalIOError);
+        }
+    }
+
+
+    // all processes must wait for compile to finish
+    reduce(create, orOp<bool>());
+}
+
+
+void Foam::codedBase::updateLibrary
+(
+    const word& redirectType
+) const
+{
+    const dictionary& dict = this->codeDict();
+
+    dynamicCode::checkSecurity
+    (
+        "codedBase::updateLibrary()",
+        dict
+    );
+
+    dynamicCodeContext context(dict);
+
+    // codeName: redirectType + _<sha1>
+    // codeDir : redirectType
+    dynamicCode dynCode
+    (
+        redirectType + context.sha1().str(true),
+        redirectType
+    );
+    const fileName libPath = dynCode.libPath();
+
+
+    // the correct library was already loaded => we are done
+    if (libs().findLibrary(libPath))
+    {
+        return;
+    }
+
+    Info<< "Using dynamicCode for " << this->description().c_str()
+        << " at line " << dict.startLineNumber()
+        << " in " << dict.name() << endl;
+
+
+    // remove instantiation of fvPatchField provided by library
+    this->clearRedirect();
+
+    // may need to unload old library
+    unloadLibrary
+    (
+        oldLibPath_,
+        dynamicCode::libraryBaseName(oldLibPath_),
+        context.dict()
+    );
+
+    // try loading an existing library (avoid compilation when possible)
+    if (!loadLibrary(libPath, dynCode.codeName(), context.dict()))
+    {
+        createLibrary(dynCode, context);
+
+        loadLibrary(libPath, dynCode.codeName(), context.dict());
+    }
+
+    // retain for future reference
+    oldLibPath_ = libPath;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::codedBase::codedBase()
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::codedBase::~codedBase()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H
new file mode 100644
index 00000000000..391c5267c08
--- /dev/null
+++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+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::codedBase
+
+Description
+    Base class for function objects and boundary conditions using dynamic code
+
+SourceFiles
+    codedBase.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef codedBase_H
+#define codedBase_H
+
+#include "dictionary.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class dynamicCode;
+class dynamicCodeContext;
+class dlLibraryTable;
+
+/*---------------------------------------------------------------------------*\
+                       Class codedBase Declaration
+\*---------------------------------------------------------------------------*/
+
+class codedBase
+{
+    // Private data
+
+        //- Previously loaded library
+        mutable fileName oldLibPath_;
+
+    // Private Member Functions
+
+        //- Global loader/unloader function type
+        typedef void (*loaderFunctionType)(bool);
+
+        //- Load specified library and execute globalFuncName(true)
+        void* loadLibrary
+        (
+            const fileName& libPath,
+            const string& globalFuncName,
+            const dictionary& contextDict
+        ) const;
+
+        //- Execute globalFuncName(false) and unload specified library
+        void unloadLibrary
+        (
+            const fileName& libPath,
+            const string& globalFuncName,
+            const dictionary& contextDict
+        ) const;
+
+        //- Create library based on the dynamicCodeContext
+        void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
+
+        //- Disallow default bitwise copy construct
+        codedBase(const codedBase&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const codedBase&);
+
+
+protected:
+
+        //- Update library as required
+        void updateLibrary
+        (
+            const word& redirectType
+        ) const;
+
+        //- get the loaded dynamic libraries
+        virtual dlLibraryTable& libs() const = 0;
+
+        //- adapt the context for the current object
+        virtual void prepare
+        (
+            dynamicCode&,
+            const dynamicCodeContext &
+        ) const = 0;
+
+        // Return a description (type + name) for the output
+        virtual string description() const = 0;
+
+        // Clear any redirected objects
+        virtual void clearRedirect() const = 0;
+
+        // Get the dictionary to initialize the codeContext
+        virtual const dictionary& codeDict() const = 0;
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        codedBase();
+
+
+    //- Destructor
+    virtual ~codedBase();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
index 4b131118d22..acffe1a9b37 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C
@@ -26,19 +26,10 @@ License
 #include "codedFixedValueFvPatchField.H"
 #include "addToRunTimeSelectionTable.H"
 #include "fvPatchFieldMapper.H"
-#include "surfaceFields.H"
 #include "volFields.H"
-#include "dlLibraryTable.H"
-#include "IFstream.H"
-#include "OFstream.H"
-#include "SHA1Digest.H"
 #include "dynamicCode.H"
 #include "dynamicCodeContext.H"
 #include "stringOps.H"
-#include "IOdictionary.H"
-
-#include <dlfcn.h>
-#include <link.h>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -53,142 +44,6 @@ const Foam::word Foam::codedFixedValueFvPatchField<Type>::codeTemplateH
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-template<class Type>
-void* Foam::codedFixedValueFvPatchField<Type>::loadLibrary
-(
-    const fileName& libPath,
-    const string& globalFuncName,
-    const dictionary& contextDict
-) const
-{
-    void* lib = 0;
-
-    // avoid compilation by loading an existing library
-    if (!libPath.empty())
-    {
-        dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs();
-
-        if (libs.open(libPath, false))
-        {
-            lib = libs.findLibrary(libPath);
-
-            // verify the loaded version and unload if needed
-            if (lib)
-            {
-                // provision for manual execution of code after loading
-                if (dlSymFound(lib, globalFuncName))
-                {
-                    loaderFunctionType function =
-                        reinterpret_cast<loaderFunctionType>
-                        (
-                            dlSym(lib, globalFuncName)
-                        );
-
-                    if (function)
-                    {
-                        (*function)(true);    // force load
-                    }
-                    else
-                    {
-                        FatalIOErrorIn
-                        (
-                            "codedFixedValueFvPatchField<Type>::"
-                            "updateLibrary()",
-                            contextDict
-                        )   << "Failed looking up symbol " << globalFuncName
-                            << nl << "from " << libPath << exit(FatalIOError);
-                    }
-                }
-                else
-                {
-                    FatalIOErrorIn
-                    (
-                        "codedFixedValueFvPatchField<Type>::loadLibrary()",
-                        contextDict
-                    )   << "Failed looking up symbol " << globalFuncName << nl
-                        << "from " << libPath << exit(FatalIOError);
-
-                    lib = 0;
-                    if (!libs.close(libPath, false))
-                    {
-                        FatalIOErrorIn
-                        (
-                            "codedFixedValueFvPatchField<Type>::loadLibrary()",
-                            contextDict
-                        )   << "Failed unloading library "
-                            << libPath
-                            << exit(FatalIOError);
-                    }
-                }
-            }
-        }
-    }
-
-    return lib;
-}
-
-
-template<class Type>
-void Foam::codedFixedValueFvPatchField<Type>::unloadLibrary
-(
-    const fileName& libPath,
-    const string& globalFuncName,
-    const dictionary& contextDict
-) const
-{
-    void* lib = 0;
-
-    if (libPath.empty())
-    {
-        return;
-    }
-
-    dlLibraryTable& libs = const_cast<Time&>(this->db().time()).libs();
-
-    lib = libs.findLibrary(libPath);
-
-    if (!lib)
-    {
-        return;
-    }
-
-    // provision for manual execution of code before unloading
-    if (dlSymFound(lib, globalFuncName))
-    {
-        loaderFunctionType function =
-            reinterpret_cast<loaderFunctionType>
-            (
-                dlSym(lib, globalFuncName)
-            );
-
-        if (function)
-        {
-            (*function)(false);    // force unload
-        }
-        else
-        {
-            FatalIOErrorIn
-            (
-                "codedFixedValueFvPatchField<Type>::unloadLibrary()",
-                contextDict
-            )   << "Failed looking up symbol " << globalFuncName << nl
-                << "from " << libPath << exit(FatalIOError);
-        }
-    }
-
-    if (!libs.close(libPath, false))
-    {
-        FatalIOErrorIn
-        (
-            "codedFixedValueFvPatchField<Type>::"
-            "updateLibrary()",
-            contextDict
-        )   << "Failed unloading library " << libPath
-            << exit(FatalIOError);
-    }
-}
-
-
 template<class Type>
 void Foam::codedFixedValueFvPatchField<Type>::setFieldTemplates
 (
@@ -238,144 +93,82 @@ const Foam::IOdictionary& Foam::codedFixedValueFvPatchField<Type>::dict() const
 
 
 template<class Type>
-void Foam::codedFixedValueFvPatchField<Type>::createLibrary
+Foam::dlLibraryTable& Foam::codedFixedValueFvPatchField<Type>::libs() const
+{
+    return const_cast<dlLibraryTable&>(this->db().time().libs());
+}
+
+
+template<class Type>
+void Foam::codedFixedValueFvPatchField<Type>::prepare
 (
     dynamicCode& dynCode,
     const dynamicCodeContext& context
 ) const
 {
-    bool create = Pstream::master();
-
-    if (create)
-    {
-        // Write files for new library
-        if (!dynCode.upToDate(context))
-        {
-            // filter with this context
-            dynCode.reset(context);
+    // take no chances - typeName must be identical to redirectType_
+    dynCode.setFilterVariable("typeName", redirectType_);
 
-            // take no chances - typeName must be identical to redirectType_
-            dynCode.setFilterVariable("typeName", redirectType_);
+    // set TemplateType and FieldType filter variables
+    // (for fvPatchField)
+    setFieldTemplates(dynCode);
 
-            // set TemplateType and FieldType filter variables
-            // (for fvPatchField)
-            setFieldTemplates(dynCode);
+    // compile filtered C template
+    dynCode.addCompileFile(codeTemplateC);
 
-            // compile filtered C template
-            dynCode.addCompileFile(codeTemplateC);
+    // copy filtered H template
+    dynCode.addCopyFile(codeTemplateH);
 
-            // copy filtered H template
-            dynCode.addCopyFile(codeTemplateH);
-
-
-            // debugging: make BC verbose
-            //  dynCode.setFilterVariable("verbose", "true");
-            //  Info<<"compile " << redirectType_ << " sha1: "
-            //      << context.sha1() << endl;
-
-            // define Make/options
-            dynCode.setMakeOptions
-            (
-                "EXE_INC = -g \\\n"
-                "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
-              + context.options()
-              + "\n\nLIB_LIBS = \\\n"
-              + "    -lOpenFOAM \\\n"
-              + "    -lfiniteVolume \\\n"
-              + context.libs()
-            );
-
-            if (!dynCode.copyOrCreateFiles(true))
-            {
-                FatalIOErrorIn
-                (
-                    "codedFixedValueFvPatchField<Type>::createLibrary(..)",
-                    context.dict()
-                )   << "Failed writing files for" << nl
-                    << dynCode.libRelPath() << nl
-                    << exit(FatalIOError);
-            }
-        }
-
-        if (!dynCode.wmakeLibso())
-        {
-            FatalIOErrorIn
-            (
-                "codedFixedValueFvPatchField<Type>::createLibrary(..)",
-                context.dict()
-            )   << "Failed wmake " << dynCode.libRelPath() << nl
-                << exit(FatalIOError);
-        }
-    }
 
+    // debugging: make BC verbose
+    //  dynCode.setFilterVariable("verbose", "true");
+    //  Info<<"compile " << redirectType_ << " sha1: "
+    //      << context.sha1() << endl;
 
-    // all processes must wait for compile to finish
-    reduce(create, orOp<bool>());
+    // define Make/options
+    dynCode.setMakeOptions
+        (
+            "EXE_INC = -g \\\n"
+            "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
+            + context.options()
+            + "\n\nLIB_LIBS = \\\n"
+            + "    -lOpenFOAM \\\n"
+            + "    -lfiniteVolume \\\n"
+            + context.libs()
+        );
 }
 
 
 template<class Type>
-void Foam::codedFixedValueFvPatchField<Type>::updateLibrary() const
+const Foam::dictionary& Foam::codedFixedValueFvPatchField<Type>::codeDict()
+const
 {
-    dynamicCode::checkSecurity
-    (
-        "codedFixedValueFvPatchField<Type>::updateLibrary()",
-        dict_
-    );
-
     // use system/codeDict or in-line
-    const dictionary& codeDict =
+    return
     (
         dict_.found("code")
       ? dict_
       : this->dict().subDict(redirectType_)
     );
+}
 
-    dynamicCodeContext context(codeDict);
-
-    // codeName: redirectType + _<sha1>
-    // codeDir : redirectType
-    dynamicCode dynCode
-    (
-        redirectType_ + context.sha1().str(true),
-        redirectType_
-    );
-    const fileName libPath = dynCode.libPath();
-
-
-    // the correct library was already loaded => we are done
-    if (const_cast<Time&>(this->db().time()).libs().findLibrary(libPath))
-    {
-        return;
-    }
 
-    Info<< "Using dynamicCode for patch " << this->patch().name()
-        << " on field " << this->dimensionedInternalField().name() << nl
-        << "at line " << codeDict.startLineNumber()
-        << " in " << codeDict.name() << endl;
+template<class Type>
+Foam::string Foam::codedFixedValueFvPatchField<Type>::description() const
+{
+    return
+        "patch "
+      + this->patch().name()
+      + " on field "
+      + this->dimensionedInternalField().name();
+}
 
 
+template<class Type>
+void Foam::codedFixedValueFvPatchField<Type>::clearRedirect() const
+{
     // remove instantiation of fvPatchField provided by library
     redirectPatchFieldPtr_.clear();
-
-    // may need to unload old library
-    unloadLibrary
-    (
-        oldLibPath_,
-        dynamicCode::libraryBaseName(oldLibPath_),
-        context.dict()
-    );
-
-    // try loading an existing library (avoid compilation when possible)
-    if (!loadLibrary(libPath, dynCode.codeName(), context.dict()))
-    {
-        createLibrary(dynCode, context);
-
-        loadLibrary(libPath, dynCode.codeName(), context.dict());
-    }
-
-    // retain for future reference
-    oldLibPath_ = libPath;
 }
 
 
@@ -389,7 +182,7 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField
 )
 :
     fixedValueFvPatchField<Type>(p, iF),
-    oldLibPath_(),
+    codedBase(),
     redirectPatchFieldPtr_()
 {}
 
@@ -404,9 +197,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField
 )
 :
     fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
+    codedBase(),
     dict_(ptf.dict_),
     redirectType_(ptf.redirectType_),
-    oldLibPath_(ptf.oldLibPath_),
     redirectPatchFieldPtr_()
 {}
 
@@ -420,12 +213,12 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField
 )
 :
     fixedValueFvPatchField<Type>(p, iF, dict),
+    codedBase(),
     dict_(dict),
     redirectType_(dict.lookup("redirectType")),
-    oldLibPath_(),
     redirectPatchFieldPtr_()
 {
-    updateLibrary();
+    updateLibrary(redirectType_);
 }
 
 
@@ -436,9 +229,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField
 )
 :
     fixedValueFvPatchField<Type>(ptf),
+    codedBase(),
     dict_(ptf.dict_),
     redirectType_(ptf.redirectType_),
-    oldLibPath_(ptf.oldLibPath_),
     redirectPatchFieldPtr_()
 {}
 
@@ -451,9 +244,9 @@ Foam::codedFixedValueFvPatchField<Type>::codedFixedValueFvPatchField
 )
 :
     fixedValueFvPatchField<Type>(ptf, iF),
+    codedBase(),
     dict_(ptf.dict_),
     redirectType_(ptf.redirectType_),
-    oldLibPath_(ptf.oldLibPath_),
     redirectPatchFieldPtr_()
 {}
 
@@ -499,7 +292,7 @@ void Foam::codedFixedValueFvPatchField<Type>::updateCoeffs()
     }
 
     // Make sure library containing user-defined fvPatchField is up-to-date
-    updateLibrary();
+    updateLibrary(redirectType_);
 
     const fvPatchField<Type>& fvp = redirectPatchField();
 
@@ -519,7 +312,7 @@ void Foam::codedFixedValueFvPatchField<Type>::evaluate
 )
 {
     // Make sure library containing user-defined fvPatchField is up-to-date
-    updateLibrary();
+    updateLibrary(redirectType_);
 
     const fvPatchField<Type>& fvp = redirectPatchField();
 
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
index 86172fe86b6..56fef9354e4 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
+++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.H
@@ -79,9 +79,7 @@ SourceFiles
 #define codedFixedValueFvPatchField_H
 
 #include "fixedValueFvPatchFields.H"
-
-#include <dlfcn.h>
-#include <link.h>
+#include "codedBase.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -100,7 +98,8 @@ class IOdictionary;
 template<class Type>
 class codedFixedValueFvPatchField
 :
-    public fixedValueFvPatchField<Type>
+    public fixedValueFvPatchField<Type>,
+    public codedBase
 {
     // Private data
 
@@ -109,51 +108,29 @@ class codedFixedValueFvPatchField
 
         const word redirectType_;
 
-        //- Previously loaded library
-        mutable fileName oldLibPath_;
-
         mutable autoPtr<fvPatchField<Type> > redirectPatchFieldPtr_;
 
-
     // Private Member Functions
 
         const IOdictionary& dict() const;
 
-        //- Global loader/unloader function type
-        typedef void (*loaderFunctionType)(bool);
-
-        static int collectLibsCallback
-        (
-            struct dl_phdr_info *info,
-            size_t size,
-            void *data
-        );
-
-        //- Load specified library and execute globalFuncName(true)
-        void* loadLibrary
-        (
-            const fileName& libPath,
-            const string& globalFuncName,
-            const dictionary& contextDict
-        ) const;
-
-        //- Execute globalFuncName(false) and unload specified library
-        void unloadLibrary
-        (
-            const fileName& libPath,
-            const string& globalFuncName,
-            const dictionary& contextDict
-        ) const;
-
         //- Set the rewrite vars controlling the Type
         static void setFieldTemplates(dynamicCode& dynCode);
 
-        //- Create library based on the dynamicCodeContext
-        void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
+        //- get the loaded dynamic libraries
+        virtual dlLibraryTable& libs() const;
+
+        //- adapt the context for the current object
+        virtual void prepare(dynamicCode&, const dynamicCodeContext&) const;
+
+        // Return a description (type + name) for the output
+        virtual string description() const;
 
-        //- Update library as required
-        void updateLibrary() const;
+        // Clear the ptr to the redirected object
+        virtual void clearRedirect() const;
 
+        // Get the dictionary to initialize the codeContext
+        virtual const dictionary& codeDict() const;
 
 public:
 
diff --git a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
index c50fa7b64f8..45a915456ac 100644
--- a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
+++ b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C
@@ -49,271 +49,71 @@ namespace Foam
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-void* Foam::codedFunctionObject::loadLibrary
-(
-    const fileName& libPath,
-    const string& globalFuncName,
-    const dictionary& contextDict
-) const
-{
-    void* lib = 0;
-
-    // avoid compilation by loading an existing library
-    if (!libPath.empty())
-    {
-        dlLibraryTable& libs = const_cast<Time&>(time_).libs();
-
-        if (libs.open(libPath, false))
-        {
-            lib = libs.findLibrary(libPath);
-
-            // verify the loaded version and unload if needed
-            if (lib)
-            {
-                // provision for manual execution of code after loading
-                if (dlSymFound(lib, globalFuncName))
-                {
-                    loaderFunctionType function =
-                        reinterpret_cast<loaderFunctionType>
-                        (
-                            dlSym(lib, globalFuncName)
-                        );
-
-                    if (function)
-                    {
-                        (*function)(true);    // force load
-                    }
-                    else
-                    {
-                        FatalIOErrorIn
-                        (
-                            "codedFunctionObject::updateLibrary()",
-                            contextDict
-                        )   << "Failed looking up symbol " << globalFuncName
-                            << nl << "from " << libPath << exit(FatalIOError);
-                    }
-                }
-                else
-                {
-                    FatalIOErrorIn
-                    (
-                        "codedFunctionObject::loadLibrary()",
-                        contextDict
-                    )   << "Failed looking up symbol " << globalFuncName << nl
-                        << "from " << libPath << exit(FatalIOError);
-
-                    lib = 0;
-                    if (!libs.close(libPath, false))
-                    {
-                        FatalIOErrorIn
-                        (
-                            "codedFunctionObject::loadLibrary()",
-                            contextDict
-                        )   << "Failed unloading library "
-                            << libPath
-                            << exit(FatalIOError);
-                    }
-                }
-            }
-        }
-    }
-
-    return lib;
-}
-
-
-void Foam::codedFunctionObject::unloadLibrary
-(
-    const fileName& libPath,
-    const string& globalFuncName,
-    const dictionary& contextDict
-) const
-{
-    void* lib = 0;
-
-    if (libPath.empty())
-    {
-        return;
-    }
-
-    dlLibraryTable& libs = const_cast<Time&>(time_).libs();
-
-    lib = libs.findLibrary(libPath);
-
-    if (!lib)
-    {
-        return;
-    }
-
-    // provision for manual execution of code before unloading
-    if (dlSymFound(lib, globalFuncName))
-    {
-        loaderFunctionType function =
-            reinterpret_cast<loaderFunctionType>
-            (
-                dlSym(lib, globalFuncName)
-            );
-
-        if (function)
-        {
-            (*function)(false);    // force unload
-        }
-        else
-        {
-            FatalIOErrorIn
-            (
-                "codedFunctionObject::unloadLibrary()",
-                contextDict
-            )   << "Failed looking up symbol " << globalFuncName << nl
-                << "from " << libPath << exit(FatalIOError);
-        }
-    }
-
-    if (!libs.close(libPath, false))
-    {
-        FatalIOErrorIn
-        (
-            "codedFunctionObject::"
-            "updateLibrary()",
-            contextDict
-        )   << "Failed unloading library " << libPath
-            << exit(FatalIOError);
-    }
-}
-
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::codedFunctionObject::createLibrary
+void Foam::codedFunctionObject::prepare
 (
     dynamicCode& dynCode,
     const dynamicCodeContext& context
 ) const
 {
-    bool create = Pstream::master();
-
-    if (create)
-    {
-        // Write files for new library
-        if (!dynCode.upToDate(context))
-        {
-            // filter with this context
-            dynCode.reset(context);
-
-            // Set additional rewrite rules
-            dynCode.setFilterVariable("typeName", redirectType_);
-            dynCode.setFilterVariable("codeRead", codeRead_);
-            dynCode.setFilterVariable("codeExecute", codeExecute_);
-            dynCode.setFilterVariable("codeEnd", codeEnd_);
-            //dynCode.setFilterVariable("codeWrite", codeWrite_);
-
-            // compile filtered C template
-            dynCode.addCompileFile("functionObjectTemplate.C");
-            dynCode.addCompileFile("FilterFunctionObjectTemplate.C");
-
-            // copy filtered H template
-            dynCode.addCopyFile("FilterFunctionObjectTemplate.H");
-            dynCode.addCopyFile("functionObjectTemplate.H");
-            dynCode.addCopyFile("IOfunctionObjectTemplate.H");
-
-            // debugging: make BC verbose
-            //         dynCode.setFilterVariable("verbose", "true");
-            //         Info<<"compile " << redirectType_ << " sha1: "
-            //             << context.sha1() << endl;
-
-            // define Make/options
-            dynCode.setMakeOptions
-            (
-                "EXE_INC = -g \\\n"
-                "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
-              + context.options()
-              + "\n\nLIB_LIBS = \\\n"
-              + "    -lOpenFOAM \\\n"
-              + "    -lfiniteVolume \\\n"
-              + context.libs()
-            );
-
-            if (!dynCode.copyOrCreateFiles(true))
-            {
-                FatalIOErrorIn
-                (
-                    "codedFunctionObject::createLibrary(..)",
-                    context.dict()
-                )   << "Failed writing files for" << nl
-                    << dynCode.libRelPath() << nl
-                    << exit(FatalIOError);
-            }
-        }
-
-        if (!dynCode.wmakeLibso())
-        {
-            FatalIOErrorIn
-            (
-                "codedFunctionObject::createLibrary(..)",
-                context.dict()
-            )   << "Failed wmake " << dynCode.libRelPath() << nl
-                << exit(FatalIOError);
-        }
-    }
-
-
-    // all processes must wait for compile to finish
-    reduce(create, orOp<bool>());
+    // Set additional rewrite rules
+    dynCode.setFilterVariable("typeName", redirectType_);
+    dynCode.setFilterVariable("codeRead", codeRead_);
+    dynCode.setFilterVariable("codeExecute", codeExecute_);
+    dynCode.setFilterVariable("codeEnd", codeEnd_);
+    //dynCode.setFilterVariable("codeWrite", codeWrite_);
+
+    // compile filtered C template
+    dynCode.addCompileFile("functionObjectTemplate.C");
+    dynCode.addCompileFile("FilterFunctionObjectTemplate.C");
+
+    // copy filtered H template
+    dynCode.addCopyFile("FilterFunctionObjectTemplate.H");
+    dynCode.addCopyFile("functionObjectTemplate.H");
+    dynCode.addCopyFile("IOfunctionObjectTemplate.H");
+
+    // debugging: make BC verbose
+    //         dynCode.setFilterVariable("verbose", "true");
+    //         Info<<"compile " << redirectType_ << " sha1: "
+    //             << context.sha1() << endl;
+
+    // define Make/options
+    dynCode.setMakeOptions
+        (
+            "EXE_INC = -g \\\n"
+            "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
+            + context.options()
+            + "\n\nLIB_LIBS = \\\n"
+            + "    -lOpenFOAM \\\n"
+            + "    -lfiniteVolume \\\n"
+            + context.libs()
+        );
 }
 
 
-void Foam::codedFunctionObject::updateLibrary() const
+Foam::dlLibraryTable& Foam::codedFunctionObject::libs() const
 {
-    dynamicCode::checkSecurity
-    (
-        "codedFunctionObject::updateLibrary()",
-        dict_
-    );
-
-    dynamicCodeContext context(dict_);
-
-    // codeName: redirectType + _<sha1>
-    // codeDir : redirectType
-    dynamicCode dynCode
-    (
-        redirectType_ + context.sha1().str(true),
-        redirectType_
-    );
-    const fileName libPath = dynCode.libPath();
-
+    return const_cast<Time&>(time_).libs();
+}
 
-    // the correct library was already loaded => we are done
-    if (const_cast<Time&>(time_).libs().findLibrary(libPath))
-    {
-        return;
-    }
 
-    Info<< "Using dynamicCode for functionObject " << name()
-        << " at line " << dict_.startLineNumber()
-        << " in " << dict_.name() << endl;
+Foam::string Foam::codedFunctionObject::description() const
+{
+    return "functionObject " + name();
+}
 
 
-    // remove instantiation of fvPatchField provided by library
+void Foam::codedFunctionObject::clearRedirect() const
+{
     redirectFunctionObjectPtr_.clear();
+}
 
-    // may need to unload old library
-    unloadLibrary
-    (
-        oldLibPath_,
-        dynamicCode::libraryBaseName(oldLibPath_),
-        context.dict()
-    );
-
-    // try loading an existing library (avoid compilation when possible)
-    if (!loadLibrary(libPath, dynCode.codeName(), context.dict()))
-    {
-        createLibrary(dynCode, context);
-
-        loadLibrary(libPath, dynCode.codeName(), context.dict());
-    }
 
-    // retain for future reference
-    oldLibPath_ = libPath;
+const Foam::dictionary& Foam::codedFunctionObject::codeDict() const
+{
+    return dict_;
 }
 
 
@@ -323,14 +123,18 @@ Foam::codedFunctionObject::codedFunctionObject
 (
     const word& name,
     const Time& time,
-    const dictionary& dict
+    const dictionary& dict,
+    bool readNow
 )
 :
     functionObject(name),
-    time_(time),
-    dict_(dict)
+    codedBase(),
+    time_(time)
 {
-    read(dict_);
+    if (readNow)
+    {
+        read(dict_);
+    }
 }
 
 
@@ -363,21 +167,21 @@ Foam::codedFunctionObject::redirectFunctionObject() const
 
 bool Foam::codedFunctionObject::start()
 {
-    updateLibrary();
+    updateLibrary(redirectType_);
     return redirectFunctionObject().start();
 }
 
 
 bool Foam::codedFunctionObject::execute(const bool forceWrite)
 {
-    updateLibrary();
+    updateLibrary(redirectType_);
     return redirectFunctionObject().execute(forceWrite);
 }
 
 
 bool Foam::codedFunctionObject::end()
 {
-    updateLibrary();
+    updateLibrary(redirectType_);
     return redirectFunctionObject().end();
 }
 
@@ -440,7 +244,7 @@ bool Foam::codedFunctionObject::read(const dictionary& dict)
         );
     }
 
-    updateLibrary();
+    updateLibrary(redirectType_);
     return redirectFunctionObject().read(dict);
 }
 
diff --git a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
index c950ea2ab6f..9f0659ac72d 100644
--- a/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
+++ b/src/postProcessing/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H
@@ -35,30 +35,22 @@ SourceFiles
 #ifndef codedFunctionObject_H
 #define codedFunctionObject_H
 
-#include "pointFieldFwd.H"
 #include "functionObject.H"
-#include "dictionary.H"
+#include "codedBase.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// Forward declaration of classes
-class objectRegistry;
-class dictionary;
-class mapPolyMesh;
-class dynamicCode;
-class dynamicCodeContext;
-class IOdictionary;
-
 /*---------------------------------------------------------------------------*\
                        Class codedFunctionObject Declaration
 \*---------------------------------------------------------------------------*/
 
 class codedFunctionObject
 :
-    public functionObject
+    public functionObject,
+    public codedBase
 {
 protected:
 
@@ -76,42 +68,28 @@ protected:
         string codeExecute_;
         string codeEnd_;
 
-        //- Previously loaded library
-        mutable fileName oldLibPath_;
-
         //- Underlying functionObject
         mutable autoPtr<functionObject> redirectFunctionObjectPtr_;
 
-    // Private Member Functions
 
-        //- Global loader/unloader function type
-        typedef void (*loaderFunctionType)(bool);
+    // Protected Member Functions
 
-        //- Load specified library and execute globalFuncName(true)
-        void* loadLibrary
-        (
-            const fileName& libPath,
-            const string& globalFuncName,
-            const dictionary& contextDict
-        ) const;
+        //- get the loaded dynamic libraries
+        virtual dlLibraryTable& libs() const;
 
-        //- Execute globalFuncName(false) and unload specified library
-        void unloadLibrary
-        (
-            const fileName& libPath,
-            const string& globalFuncName,
-            const dictionary& contextDict
-        ) const;
+        //- adapt the context for the current object
+        virtual void prepare(dynamicCode &,const dynamicCodeContext&) const;
 
+        // Return a description (type + name) for the output
+        virtual string description() const;
 
-        //- Create library based on the dynamicCodeContext
-        void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
+        // Clear any redirected objects
+        virtual void clearRedirect() const;
 
-        //- Update library as required
-        void updateLibrary() const;
+        // Get the dictionary to initialize the codeContext
+        virtual const dictionary& codeDict() const;
 
-        //- Read relevant dictionary entries
-        void readDict();
+private:
 
         //- Disallow default bitwise copy construct
         codedFunctionObject(const codedFunctionObject&);
@@ -134,7 +112,8 @@ public:
         (
             const word& name,
             const Time& time,
-            const dictionary& dict
+            const dictionary& dict,
+            bool readNow=true   // allow child-classes to avoid compilation
         );
 
 
-- 
GitLab