ENH: ensure that content changes in coded objects are noticed (#1293)

- for codedFunctionObject and CodedSource the main code snippets
  were not included in the SHA1 calculation, which meant that many
  changes would not be noticed and no new library would be compiled.

  As a workaround, a dummy 'code' entry could be used solely for the
  purposes of generating a SHA1, but this is easily forgotten.

  We now allow tracking of the dynamicCodeContext for the coded
  objects and append to the SHA1 hasher with specific entries.
  This should solve the previous misbehaviour.

  We additionally add information about the ordering of the code
  sections. Suppose we have a coded function object (all code
  segments are optional) with the following:

      codeExecute "";
      codeWrite   #{ Info<< "Called\n"; #};

  which we subsequently change to this:

      codeExecute #{ Info<< "Called\n"; #};
      codeWrite   "";

  If the code strings are simply concatenated together, the SHA1 hashes
  will be identical. We thus 'salt' with their semantic locations,
  choosing tags that are unlikely to occur within the code strings
  themselves.

- simplify the coded templates with constexpr for the SHA1sum
  information.

- Correct the CodedSource to use 'codeConstrain' instead of
  'codeSetValue' for consistency with the underlying functions.
This commit is contained in:
Mark Olesen 2019-05-01 14:00:54 +02:00 committed by Andrew Heather
parent 23e5d43e4e
commit a85c55bbb5
34 changed files with 1040 additions and 992 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -51,18 +51,11 @@ ${localCode}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
extern "C" void ${typeName}(Ostream& os, const dictionary& dict)
{
void ${typeName}
(
Ostream& os,
const dictionary& dict
)
{
//{{{ begin code
${code}
${code}
//}}} end code
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -42,7 +42,6 @@ ${codeInclude}
namespace Foam
{
namespace fv
{
@ -55,33 +54,26 @@ ${localCode}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
//makeRemovablePatchTypeField
//(
// fvPatch${FieldType},
// ${typeName}FvOption${SourceType}
//);
defineTypeNameAndDebug(${typeName}FvOption${SourceType}, 0);
addRemovableToRunTimeSelectionTable
(
@ -91,10 +83,6 @@ addRemovableToRunTimeSelectionTable
);
const char* const ${typeName}FvOption${SourceType}::SHA1sum =
"${SHA1sum}";
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
${typeName}FvOption${SourceType}::
@ -110,8 +98,7 @@ ${typeName}FvOption${SourceType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from components\n";
printMessage("Construct ${typeName} from components");
}
}
@ -123,7 +110,7 @@ ${typeName}FvOption${SourceType}::
{
if (${verbose:-false})
{
Info<<"destroy ${typeName} sha1: ${SHA1sum}\n";
printMessage("Destroy ${typeName}");
}
}
@ -193,14 +180,14 @@ void ${typeName}FvOption${SourceType}::constrain
}
//{{{ begin code
${codeSetValue}
${codeConstrain}
//}}} end code
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fv
} // End namespace Foam
} // End namespace fv
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -27,6 +27,7 @@ Description
Template for use with dynamic code generation of a source.
The hook functions take the following arguments:
\verbatim
codeCorrect
(
GeometricField<Type, fvPatchField, volMesh>& fld
@ -38,16 +39,18 @@ Description
const label fieldi
)
constrain
codeConstrain
(
fvMatrix<Type>& eqn,
const label fieldi
)
\endverbatim
where :
fieldi is the index in the fields entry
eqn is the fvMatrix
\verbatim
energySource
{
type scalarCodedSource;
@ -62,7 +65,6 @@ Description
codeInclude
#{
#};
codeCorrect
@ -78,18 +80,9 @@ Description
heSource -= 0.1*sqr(time.value())*V;
#};
codeSetValue
codeConstrain
#{
Pout<< "**codeSetValue**" << endl;
#};
// Dummy entry. Make dependent on above to trigger recompilation
code
#{
$codeInclude
$codeCorrect
$codeAddSup
$codeSetValue
Pout<< "**codeConstrain**" << endl;
#};
}
@ -98,6 +91,7 @@ Description
// Dummy entry
}
}
\endverbatim
SourceFiles
codedFvOptionTemplate.C
@ -113,7 +107,6 @@ SourceFiles
namespace Foam
{
namespace fv
{
@ -125,10 +118,18 @@ class ${typeName}FvOption${SourceType}
:
public cellSetOption
{
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
public:
//- Information about the SHA1 of the code itself
static const char* const SHA1sum;
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");
@ -149,44 +150,42 @@ public:
virtual ~${typeName}FvOption${SourceType}();
// Member functions
// Member Functions
//- Correct field
virtual void correct
(
GeometricField<${TemplateType}, fvPatchField, volMesh>&
);
//- Correct field
virtual void correct
(
GeometricField<${TemplateType}, fvPatchField, volMesh>& fld
);
//- Explicit and implicit matrix contributions
virtual void addSup
(
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
//- Explicit/implicit matrix contributions
virtual void addSup
(
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
//- Explicit and implicit matrix contributions for compressible
// equations
virtual void addSup
(
const volScalarField& rho,
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
//- Explicit/implicit matrix contributions for compressible equations
virtual void addSup
(
const volScalarField& rho,
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
//- Set value
virtual void constrain
(
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
//- Set value
virtual void constrain
(
fvMatrix<${TemplateType}>& eqn,
const label fieldi
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
} // End namespace fv
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -49,23 +49,20 @@ addRemovableToRunTimeSelectionTable
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
@ -101,7 +98,7 @@ tmp<pointField> ${typeName}Points0MotionSolver::curPoints() const
{
if (${verbose:-false})
{
Info<<"curPoints ${typeName} sha1: ${SHA1sum}\n";
printMessage("curPoints ${typeName}");
}
//{{{ begin code

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -56,6 +56,12 @@ class ${typeName}Points0MotionSolver
{
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
//- No copy construct
${typeName}Points0MotionSolver
(
@ -68,6 +74,9 @@ class ${typeName}Points0MotionSolver
public:
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -31,6 +31,7 @@ License
#include "volFields.H"
#include "surfaceFields.H"
#include "unitConversion.H"
//{{{ begin codeInclude
${codeInclude}
//}}} end codeInclude
@ -50,23 +51,20 @@ ${localCode}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
@ -79,10 +77,6 @@ makeRemovablePatchTypeField
);
const char* const ${typeName}FixedValueFvPatch${FieldType}::SHA1sum =
"${SHA1sum}";
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
${typeName}FixedValueFvPatch${FieldType}::
@ -96,8 +90,7 @@ ${typeName}FixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField\n";
printMessage("Construct ${typeName} : patch/DimensionedField");
}
}
@ -115,8 +108,7 @@ ${typeName}FixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField/mapper\n";
printMessage("Construct ${typeName} : patch/DimensionedField/mapper");
}
}
@ -133,8 +125,7 @@ ${typeName}FixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/dictionary\n";
printMessage("Construct ${typeName} : patch/dictionary");
}
}
@ -149,8 +140,7 @@ ${typeName}FixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" as copy\n";
printMessage("Copy construct ${typeName}");
}
}
@ -166,8 +156,7 @@ ${typeName}FixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum} "
"as copy/DimensionedField\n";
printMessage("Construct ${typeName} : copy/DimensionedField");
}
}
@ -179,7 +168,7 @@ ${typeName}FixedValueFvPatch${FieldType}::
{
if (${verbose:-false})
{
Info<<"destroy ${typeName} sha1: ${SHA1sum}\n";
printMessage("Destroy ${typeName}");
}
}
@ -195,7 +184,7 @@ void ${typeName}FixedValueFvPatch${FieldType}::updateCoeffs()
if (${verbose:-false})
{
Info<<"updateCoeffs ${typeName} sha1: ${SHA1sum}\n";
printMessage("updateCoeffs ${typeName}");
}
//{{{ begin code

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -52,10 +52,18 @@ class ${typeName}FixedValueFvPatch${FieldType}
:
public fixedValueFvPatchField<${TemplateType}>
{
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
public:
//- Information about the SHA1 of the code itself
static const char* const SHA1sum;
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");
@ -126,7 +134,7 @@ public:
virtual ~${typeName}FixedValueFvPatch${FieldType}();
// Member functions
// Member Functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -30,6 +30,7 @@ License
#include "pointPatchFieldMapper.H"
#include "pointFields.H"
#include "unitConversion.H"
//{{{ begin codeInclude
${codeInclude}
//}}} end codeInclude
@ -49,23 +50,20 @@ ${localCode}
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
@ -78,10 +76,6 @@ makePointPatchTypeField
);
const char* const ${typeName}FixedValuePointPatch${FieldType}::SHA1sum =
"${SHA1sum}";
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
${typeName}FixedValuePointPatch${FieldType}::
@ -95,8 +89,7 @@ ${typeName}FixedValuePointPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField\n";
printMessage("Construct ${typeName} : patch/DimensionedField");
}
}
@ -114,8 +107,7 @@ ${typeName}FixedValuePointPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField/mapper\n";
printMessage("Construct ${typeName} : patch/DimensionedField/mapper");
}
}
@ -133,8 +125,7 @@ ${typeName}FixedValuePointPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/dictionary\n";
printMessage("Construct ${typeName} : patch/dictionary");
}
}
@ -149,8 +140,7 @@ ${typeName}FixedValuePointPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" as copy\n";
printMessage("Copy construct ${typeName}");
}
}
@ -166,8 +156,7 @@ ${typeName}FixedValuePointPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum} "
"as copy/DimensionedField\n";
printMessage("Construct ${typeName} : copy/DimensionedField");
}
}
@ -179,7 +168,7 @@ ${typeName}FixedValuePointPatch${FieldType}::
{
if (${verbose:-false})
{
Info<<"destroy ${typeName} sha1: ${SHA1sum}\n";
printMessage("Destroy ${typeName}");
}
}
@ -195,7 +184,7 @@ void ${typeName}FixedValuePointPatch${FieldType}::updateCoeffs()
if (${verbose:-false})
{
Info<<"updateCoeffs ${typeName} sha1: ${SHA1sum}\n";
printMessage("updateCoeffs ${typeName}");
}
//{{{ begin code

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -52,10 +52,18 @@ class ${typeName}FixedValuePointPatch${FieldType}
:
public fixedValuePointPatchField<${TemplateType}>
{
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
public:
//- Information about the SHA1 of the code itself
static const char* const SHA1sum;
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");
@ -127,7 +135,7 @@ public:
virtual ~${typeName}FixedValuePointPatch${FieldType}();
// Member functions
// Member Functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -49,23 +49,20 @@ addRemovableToRunTimeSelectionTable
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
@ -112,7 +109,7 @@ bool ${typeName}FunctionObject::read(const dictionary& dict)
{
if (${verbose:-false})
{
Info<<"read ${typeName} sha1: ${SHA1sum}\n";
printMessage("read ${typeName}");
}
//{{{ begin code
@ -127,7 +124,7 @@ bool ${typeName}FunctionObject::execute()
{
if (${verbose:-false})
{
Info<<"execute ${typeName} sha1: ${SHA1sum}\n";
printMessage("execute ${typeName}");
}
//{{{ begin code
@ -142,7 +139,7 @@ bool ${typeName}FunctionObject::write()
{
if (${verbose:-false})
{
Info<<"write ${typeName} sha1: ${SHA1sum}\n";
printMessage("write ${typeName}");
}
//{{{ begin code
@ -157,7 +154,7 @@ bool ${typeName}FunctionObject::end()
{
if (${verbose:-false})
{
Info<<"end ${typeName} sha1: ${SHA1sum}\n";
printMessage("end ${typeName}");
}
//{{{ begin code

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -24,8 +24,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Template for use with dynamic code generation of a
OutputFilter functionObject.
Template for use with dynamic code generation of a functionObject.
SourceFiles
functionObjectTemplate.C
@ -57,7 +56,7 @@ class ${typeName}FunctionObject
:
public functionObjects::regionFunctionObject
{
// Private data
// Private Data
//{{{ begin codeData
${codeData}
@ -66,6 +65,13 @@ class ${typeName}FunctionObject
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
//- Cast reference of objectRegistry to fvMesh
const fvMesh& mesh() const;
//- No copy construct
@ -74,9 +80,11 @@ class ${typeName}FunctionObject
//- No copy assignment
void operator=(const ${typeName}FunctionObject&) = delete;
public:
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");
@ -98,17 +106,17 @@ public:
// Member Functions
//- Read the system calls
//- Read the dictionary
virtual bool read(const dictionary& dict);
//- Execute the "executeCalls" at each time-step
//- Execute (at time-step)
virtual bool execute();
//- Execute the "endCalls" at the final time-loop
virtual bool end();
//- Write, execute the "writeCalls"
//- Write (at write interval)
virtual bool write();
//- Executed at the final time-loop
virtual bool end();
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -31,6 +31,7 @@ License
#include "volFields.H"
#include "surfaceFields.H"
#include "unitConversion.H"
//{{{ begin codeInclude
${codeInclude}
//}}} end codeInclude
@ -47,26 +48,22 @@ namespace Foam
${localCode}
//}}} end localCode
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
extern "C"
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
extern "C" void ${typeName}_${SHA1sum}(bool load)
{
// dynamicCode:
// SHA1 = ${SHA1sum}
//
// unique function name that can be checked if the correct library version
// has been loaded
void ${typeName}_${SHA1sum}(bool load)
if (load)
{
if (load)
{
// code that can be explicitly executed after loading
}
else
{
// code that can be explicitly executed before unloading
}
// Code that can be explicitly executed after loading
}
else
{
// Code that can be explicitly executed before unloading
}
}
@ -79,10 +76,6 @@ makeRemovablePatchTypeField
);
const char* const ${typeName}MixedValueFvPatch${FieldType}::SHA1sum =
"${SHA1sum}";
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
${typeName}MixedValueFvPatch${FieldType}::
@ -96,8 +89,7 @@ ${typeName}MixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField\n";
printMessage("Construct ${typeName} : patch/DimensionedField");
}
}
@ -115,8 +107,7 @@ ${typeName}MixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/DimensionedField/mapper\n";
printMessage("Construct ${typeName} : patch/DimensionedField/mapper");
}
}
@ -133,8 +124,7 @@ ${typeName}MixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" from patch/dictionary\n";
printMessage("Construct ${typeName} : patch/dictionary");
}
}
@ -149,8 +139,7 @@ ${typeName}MixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum}"
" as copy\n";
printMessage("Copy construct ${typeName}");
}
}
@ -166,8 +155,7 @@ ${typeName}MixedValueFvPatch${FieldType}
{
if (${verbose:-false})
{
Info<<"construct ${typeName} sha1: ${SHA1sum} "
"as copy/DimensionedField\n";
printMessage("Construct ${typeName} : copy/DimensionedField");
}
}
@ -179,7 +167,7 @@ ${typeName}MixedValueFvPatch${FieldType}::
{
if (${verbose:-false})
{
Info<<"destroy ${typeName} sha1: ${SHA1sum}\n";
printMessage("Destroy ${typeName}");
}
}
@ -195,7 +183,7 @@ void ${typeName}MixedValueFvPatch${FieldType}::updateCoeffs()
if (${verbose:-false})
{
Info<<"updateCoeffs ${typeName} sha1: ${SHA1sum}\n";
printMessage("updateCoeffs ${typeName}");
}
//{{{ begin code

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) YEAR AUTHOR,AFFILIATION
@ -52,10 +52,18 @@ class ${typeName}MixedValueFvPatch${FieldType}
:
public mixedFvPatchField<${TemplateType}>
{
// Private Member Functions
//- Report a message with the SHA1sum
inline static void printMessage(const char* message)
{
Info<< message << " sha1: " << SHA1sum << '\n';
}
public:
//- Information about the SHA1 of the code itself
static const char* const SHA1sum;
//- SHA1 representation of the code content
static constexpr const char* const SHA1sum = "${SHA1sum}";
//- Runtime type information
TypeName("${typeName}");
@ -126,7 +134,7 @@ public:
virtual ~${typeName}MixedValueFvPatch${FieldType}();
// Member functions
// Member Functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -61,10 +61,6 @@ namespace functionEntries
}
const Foam::word Foam::functionEntries::codeStream::codeTemplateC
= "codeStreamTemplate.C";
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::dlLibraryTable& Foam::functionEntries::codeStream::libs
@ -94,27 +90,19 @@ bool Foam::functionEntries::codeStream::doingMasterOnlyReading
topDict
);
if (debug)
{
Pout<< "codeStream : baseIOdictionary:" << dict.name()
<< " master-only-reading:" << d.globalObject()
<< endl;
}
DebugPout
<< "codeStream : baseIOdictionary:" << dict.name()
<< " master-only-reading:" << d.globalObject() << endl;
return d.globalObject();
}
else
{
if (debug)
{
Pout<< "codeStream : not a baseIOdictionary:" << dict.name()
<< " master-only-reading:" << regIOobject::masterOnlyReading
<< endl;
}
// Fall back to regIOobject::masterOnlyReading
return regIOobject::masterOnlyReading;
}
DebugPout
<< "codeStream : not a baseIOdictionary:" << dict.name()
<< " master-only-reading:" << regIOobject::masterOnlyReading << endl;
// Fall back to regIOobject::masterOnlyReading
return regIOobject::masterOnlyReading;
}
@ -147,17 +135,13 @@ Foam::functionEntries::codeStream::getFunction
lib = libs(parentDict).findLibrary(libPath);
}
if (!lib)
{
DetailInfo
<< "Using #codeStream with " << libPath << endl;
}
// nothing loaded
// avoid compilation if possible by loading an existing library
if (!lib)
{
DetailInfo
<< "Using #codeStream with " << libPath << endl;
if (isA<baseIOdictionary>(topDict))
{
// Cached access to dl libs. Guarantees clean up upon destruction
@ -199,7 +183,7 @@ Foam::functionEntries::codeStream::getFunction
"EXE_INC = -g \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
+ " -lOpenFOAM \\\n"
" -lOpenFOAM \\\n"
+ context.libs()
);
@ -237,26 +221,21 @@ Foam::functionEntries::codeStream::getFunction
off_t masterSize = mySize;
Pstream::scatter(masterSize);
if (debug)
{
Pout<< endl<< "on processor " << Pstream::myProcNo()
<< " have masterSize:" << masterSize
<< " and localSize:" << mySize
<< endl;
}
DebugPout
<< nl << "on processor " << Pstream::myProcNo()
<< " have masterSize:" << masterSize
<< " and localSize:" << mySize << endl;
if (mySize < masterSize)
{
if (debug)
{
Pout<< "Local file " << libPath
<< " not of same size (" << mySize
<< ") as master ("
<< masterSize << "). Waiting for "
<< regIOobject::fileModificationSkew
<< " seconds." << endl;
}
DebugPout
<< "Local file " << libPath
<< " not of same size (" << mySize
<< ") as master ("
<< masterSize << "). Waiting for "
<< regIOobject::fileModificationSkew
<< " seconds." << endl;
Foam::sleep(regIOobject::fileModificationSkew);
// Recheck local size
@ -278,13 +257,10 @@ Foam::functionEntries::codeStream::getFunction
}
}
if (debug)
{
Pout<< endl<< "on processor " << Pstream::myProcNo()
<< " after waiting: have masterSize:" << masterSize
<< " and localSize:" << mySize
<< endl;
}
DebugPout
<< nl << "on processor " << Pstream::myProcNo()
<< " after waiting: have masterSize:" << masterSize
<< " and localSize:" << mySize << endl;
}
if (isA<baseIOdictionary>(topDict))
@ -293,10 +269,8 @@ Foam::functionEntries::codeStream::getFunction
// of Time.
dlLibraryTable& dlLibs = libs(parentDict);
if (debug)
{
Pout<< "Opening cached dictionary:" << libPath << endl;
}
DebugPout
<< "Opening cached dictionary:" << libPath << endl;
if (!dlLibs.open(libPath, false))
{
@ -312,10 +286,9 @@ Foam::functionEntries::codeStream::getFunction
else
{
// Uncached opening of libPath
if (debug)
{
Pout<< "Opening uncached dictionary:" << libPath << endl;
}
DebugPout
<< "Opening uncached dictionary:" << libPath << endl;
lib = dlOpen(libPath, true);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -100,12 +100,13 @@ SourceFiles
namespace Foam
{
// Forward Declarations
class dlLibraryTable;
namespace functionEntries
{
// Forward declaration of friend classes
// Forward Declarations
class calcEntry;
/*---------------------------------------------------------------------------*\
@ -147,10 +148,12 @@ class codeStream
public:
// Static data members
// Static Data Members
//- Name of the C code template to be used
static const word codeTemplateC;
static constexpr const char* const codeTemplateC
= "codeStreamTemplate.C";
// Related types

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -56,7 +56,6 @@ static inline void writeEntryIfPresent
const word& key
)
{
// non-recursive like dictionary::found, but no pattern-match either
const entry* eptr = dict.findEntry(key, keyType::LITERAL);
if (eptr)
@ -89,57 +88,58 @@ void* Foam::codedBase::loadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
const dynamicCodeContext& context
) const
{
void* lib = 0;
// Avoid compilation by loading an existing library
// avoid compilation by loading an existing library
if (!libPath.empty())
void* lib =
(
!libPath.empty() && libs().open(libPath, false)
? libs().findLibrary(libPath)
: nullptr
);
if (!lib)
{
if (libs().open(libPath, false))
return lib;
}
// verify the loaded version and unload if needed
// provision for manual execution of code after loading
if (dlSymFound(lib, globalFuncName))
{
loaderFunctionType function =
reinterpret_cast<loaderFunctionType>
(
dlSym(lib, globalFuncName)
);
if (function)
{
lib = libs().findLibrary(libPath);
(*function)(true); // force load
}
else
{
FatalIOErrorInFunction(context.dict())
<< "Failed looking up symbol " << globalFuncName
<< nl << "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorInFunction(context.dict())
<< "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
// 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
{
FatalIOErrorInFunction(contextDict)
<< "Failed looking up symbol " << globalFuncName
<< nl << "from " << libPath << exit(FatalIOError);
}
}
else
{
FatalIOErrorInFunction(contextDict)
<< "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
lib = 0;
if (!libs().close(libPath, false))
{
FatalIOErrorInFunction(contextDict)
<< "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
}
}
lib = nullptr;
if (!libs().close(libPath, false))
{
FatalIOErrorInFunction(context.dict())
<< "Failed unloading library "
<< libPath
<< exit(FatalIOError);
}
}
@ -151,17 +151,16 @@ void Foam::codedBase::unloadLibrary
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
const dynamicCodeContext& context
) const
{
void* lib = 0;
if (libPath.empty())
{
return;
}
lib = libs().findLibrary(libPath);
void* lib =
(
!libPath.empty() && libs().open(libPath, false)
? libs().findLibrary(libPath)
: nullptr
);
if (!lib)
{
@ -183,7 +182,7 @@ void Foam::codedBase::unloadLibrary
}
else
{
FatalIOErrorInFunction(contextDict)
FatalIOErrorInFunction(context.dict())
<< "Failed looking up symbol " << globalFuncName << nl
<< "from " << libPath << exit(FatalIOError);
}
@ -191,7 +190,7 @@ void Foam::codedBase::unloadLibrary
if (!libs().close(libPath, false))
{
FatalIOErrorInFunction(contextDict)
FatalIOErrorInFunction(context.dict())
<< "Failed unloading library " << libPath
<< exit(FatalIOError);
}
@ -305,21 +304,30 @@ void Foam::codedBase::createLibrary
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::codedBase::setCodeContext(const dictionary& dict)
{
context_.setCodeContext(dict);
}
void Foam::codedBase::append(const std::string& str)
{
context_.append(str);
}
void Foam::codedBase::updateLibrary
(
const word& name
const word& name,
const dynamicCodeContext& context
) const
{
const dictionary& dict = this->codeDict();
dynamicCode::checkSecurity
(
"codedBase::updateLibrary()",
dict
context.dict()
);
dynamicCodeContext context(dict);
// codeName: name + _<sha1>
// codeDir : name
dynamicCode dynCode
@ -327,10 +335,11 @@ void Foam::codedBase::updateLibrary
name + context.sha1().str(true),
name
);
const fileName libPath = dynCode.libPath();
// the correct library was already loaded => we are done
// The correct library was already loaded => we are done
if (libs().findLibrary(libPath))
{
return;
@ -338,44 +347,55 @@ void Foam::codedBase::updateLibrary
DetailInfo
<< "Using dynamicCode for " << this->description().c_str()
<< " at line " << dict.startLineNumber()
<< " in " << dict.name() << endl;
<< " at line " << context.dict().startLineNumber()
<< " in " << context.dict().name() << endl;
// remove instantiation of fvPatchField provided by library
// Remove instantiation of fvPatchField provided by library
this->clearRedirect();
// may need to unload old library
// May need to unload old library
unloadLibrary
(
oldLibPath_,
dynamicCode::libraryBaseName(oldLibPath_),
context.dict()
context
);
// try loading an existing library (avoid compilation when possible)
if (!loadLibrary(libPath, dynCode.codeName(), context.dict()))
// Try loading an existing library (avoid compilation when possible)
if (!loadLibrary(libPath, dynCode.codeName(), context))
{
createLibrary(dynCode, context);
loadLibrary(libPath, dynCode.codeName(), context.dict());
loadLibrary(libPath, dynCode.codeName(), context);
}
// retain for future reference
// Retain for future reference
oldLibPath_ = libPath;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::codedBase::codedBase()
{}
void Foam::codedBase::updateLibrary
(
const word& name,
const dictionary& dict
) const
{
updateLibrary(name, dynamicCodeContext(dict));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::codedBase::~codedBase()
{}
void Foam::codedBase::updateLibrary(const word& name) const
{
if (context_.valid())
{
updateLibrary(name, context_);
}
else
{
updateLibrary(name, dynamicCodeContext(this->codeDict()));
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -28,6 +28,15 @@ Class
Description
Base class for function objects and boundary conditions using dynamic code
that provides methods for managing loading/unloading/updating
of a dynamic library. For these purposes, it uses a dynamicCodeContext
object to maintain information about the state.
For simple coded objects, the default state management is sufficient.
When there are more complicated code segements
(eg, functionObjects::codedFunctionObject), the state management
must also register these elements as well, starting with an initial
setCodeContext() call and followed by append() to register each element.
SourceFiles
codedBase.C
@ -38,16 +47,16 @@ SourceFiles
#define codedBase_H
#include "dictionary.H"
#include "dynamicCodeContext.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
// Forward Declarations
class Ostream;
class dynamicCode;
class dynamicCodeContext;
class dlLibraryTable;
/*---------------------------------------------------------------------------*\
@ -56,11 +65,15 @@ class dlLibraryTable;
class codedBase
{
// Private data
// Private Data
//- The code context
dynamicCodeContext context_;
//- Previously loaded library
mutable fileName oldLibPath_;
// Private Member Functions
//- Global loader/unloader function type
@ -71,7 +84,7 @@ class codedBase
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
const dynamicCodeContext& context
) const;
//- Execute globalFuncName(false) and unload specified library
@ -79,11 +92,15 @@ class codedBase
(
const fileName& libPath,
const string& globalFuncName,
const dictionary& contextDict
const dynamicCodeContext& context
) const;
//- Create library based on the dynamicCodeContext
void createLibrary(dynamicCode&, const dynamicCodeContext&) const;
void createLibrary
(
dynamicCode& dynCode,
const dynamicCodeContext& context
) const;
//- No copy construct
codedBase(const codedBase&) = delete;
@ -95,22 +112,45 @@ class codedBase
protected:
//- Write code-dictionary contents
static void writeCodeDict(Ostream&, const dictionary&);
static void writeCodeDict(Ostream& os, const dictionary& dict);
//- Update library as required
// Protected Member Functions
//- Set code context from a dictionary
void setCodeContext(const dictionary& dict);
//- Add content to SHA1 hashing
void append(const std::string& str);
//- Update library as required, using the given context
void updateLibrary
(
const word& name
const word& name,
const dynamicCodeContext& context
) const;
//- Update library as required, using the given code dictionary
//- to use for the context
void updateLibrary
(
const word& name,
const dictionary& dict
) const;
//- Update library as required, using the predefined context
//- or use the codeDict() to generate one
void updateLibrary(const word& name) const;
//- Get the loaded dynamic libraries
virtual dlLibraryTable& libs() const = 0;
//- Adapt the context for the current object
virtual void prepare
(
dynamicCode&,
const dynamicCodeContext&
dynamicCode& dynCode,
const dynamicCodeContext& context
) const = 0;
// Return a description (type + name) for the output
@ -132,11 +172,11 @@ public:
// Constructors
//- Construct null
codedBase();
codedBase() = default;
//- Destructor
virtual ~codedBase();
virtual ~codedBase() = default;
};

View File

@ -36,6 +36,16 @@ License
#include "dictionary.H"
#include "foamVersion.H"
#undef EXT_SO
#ifdef __APPLE__
#define EXT_SO ".dylib"
#elif defined _WIN32
#define EXT_SO ".dll"
#else
#define EXT_SO ".so"
#endif
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::dynamicCode::allowSystemOperations
@ -130,7 +140,7 @@ void Foam::dynamicCode::copyAndFilter
{
is.getLine(line);
// Expand according to mapping.
// Expand according to HashTable mapping, not the environment.
// Expanding according to env variables might cause too many
// surprises
stringOps::inplaceExpand(line, mapping);
@ -151,10 +161,8 @@ bool Foam::dynamicCode::resolveTemplates
const fileName templateDir(Foam::getEnv(codeTemplateEnvName));
bool allOkay = true;
forAll(templateNames, fileI)
for (const fileName& templateName : templateNames)
{
const fileName& templateName = templateNames[fileI];
fileName file;
if (!templateDir.empty() && isDir(templateDir))
{
@ -188,15 +196,16 @@ bool Foam::dynamicCode::resolveTemplates
bool Foam::dynamicCode::writeCommentSHA1(Ostream& os) const
{
const bool hasSHA1 = filterVars_.found("SHA1sum");
const auto fnd = filterVars_.cfind("SHA1sum");
if (hasSHA1)
if (!fnd.found())
{
os << "/* dynamicCode:\n * SHA1 = ";
os.writeQuoted(filterVars_["SHA1sum"], false) << "\n */\n";
return false;
}
return hasSHA1;
os << "/* dynamicCode:\n * SHA1 = ";
os.writeQuoted(*fnd, false) << "\n */\n";
return true;
}
@ -214,7 +223,7 @@ bool Foam::dynamicCode::createMakeFiles() const
mkDir(dstFile.path());
OFstream os(dstFile);
//Debug: Info << "Writing to " << dstFile << endl;
//Debug: Info<< "Writing to " << dstFile << endl;
if (!os.good())
{
FatalErrorInFunction
@ -225,9 +234,9 @@ bool Foam::dynamicCode::createMakeFiles() const
writeCommentSHA1(os);
// Write compile files
forAll(compileFiles_, fileI)
for (const fileName& file : compileFiles_)
{
os.writeQuoted(compileFiles_[fileI], false) << nl;
os.writeQuoted(file, false) << nl;
}
os << nl
@ -317,13 +326,15 @@ Foam::fileName Foam::dynamicCode::codeRelPath() const
}
Foam::fileName Foam::dynamicCode::libPath() const
{
return codeRoot_/libSubDir_/"lib" + codeName_ + EXT_SO;
}
Foam::fileName Foam::dynamicCode::libRelPath() const
{
#ifdef __APPLE__
return codeRelPath()/libSubDir_/"lib" + codeName_ + ".dylib";
#else
return codeRelPath()/libSubDir_/"lib" + codeName_ + ".so";
#endif
return codeRelPath()/libSubDir_/"lib" + codeName_ + EXT_SO;
}
@ -336,7 +347,7 @@ void Foam::dynamicCode::clear()
filterVars_.set("typeName", codeName_);
filterVars_.set("SHA1sum", SHA1Digest().str());
// Provide default Make/options
// Default Make/options
makeOptions_ =
"EXE_INC = -g\n"
"\n\nLIB_LIBS = ";
@ -423,10 +434,10 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
if (!badFiles.empty())
{
FatalErrorInFunction
<< "Could not find the code template(s): "
<< "Could not find code template(s): "
<< badFiles << nl
<< "Under the $" << codeTemplateEnvName
<< " directory or via via the <etc>/"
<< " directory or via the <etc>/"
<< codeTemplateDirName << " expansion"
<< exit(FatalError);
}
@ -440,10 +451,9 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
mkDir(outputDir);
// Copy/filter files
forAll(resolvedFiles, fileI)
for (const fileName& srcFile : resolvedFiles)
{
const fileName& srcFile = resolvedFiles[fileI];
const fileName dstFile(outputDir/srcFile.name());
const fileName dstFile(outputDir/srcFile.name());
IFstream is(srcFile);
//Debug: Info<< "Reading from " << is.name() << endl;
@ -469,23 +479,20 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const
// Create files:
forAll(createFiles_, fileI)
for (const fileAndContent& content : createFiles_)
{
const fileName dstFile
(
outputDir/stringOps::expand(createFiles_[fileI].first())
);
const fileName dstFile(outputDir/stringOps::expand(content.first()));
mkDir(dstFile.path());
OFstream os(dstFile);
//Debug: Info<< "Writing to " << createFiles_[fileI].first() << endl;
//Debug: Info<< "Writing to " << content.first() << endl;
if (!os.good())
{
FatalErrorInFunction
<< "Failed writing " << dstFile
<< exit(FatalError);
}
os.writeQuoted(createFiles_[fileI].second(), false) << nl;
os.writeQuoted(content.second(), false) << nl;
}
@ -515,8 +522,7 @@ bool Foam::dynamicCode::wmakeLibso() const
else
{
// Even with details turned off, we want some feedback
Serr
<< "Invoking wmake libso " << this->codePath().c_str() << endl;
Serr<< "Invoking wmake libso " << this->codePath().c_str() << endl;
}
if (Foam::system(cmd) == 0)

View File

@ -219,21 +219,13 @@ public:
return codeRoot_/codeDirName_;
}
//- Library path for specified code name
// Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so
fileName libPath() const
{
#ifdef __APPLE__
return codeRoot_/libSubDir_/"lib" + codeName_ + ".dylib";
#else
return codeRoot_/libSubDir_/"lib" + codeName_ + ".so";
#endif
}
//- Path for specified code name relative to \<case\>
// Corresponds to topDirName/codeDirName()
fileName codeRelPath() const;
//- Library path for specified code name
// Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so
fileName libPath() const;
//- Library path for specified code name relative to \<case\>
// Corresponds to
@ -287,6 +279,23 @@ public:
//- Compile a libso
bool wmakeLibso() const;
// Convenience
//- Define a filter variables TemplateType and FieldType
template<class Type>
void setFieldTemplates()
{
std::string val(pTraits<Type>::typeName);
// Template type
setFilterVariable("TemplateType", val);
// Field type - eg, ScalarField, VectorField, ...
val[0] = toupper(val[0]);
val += "Field";
setFilterVariable("FieldType", val);
}
};

View File

@ -29,110 +29,135 @@ License
#include "stringOps.H"
#include "OSHA1stream.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::dynamicCodeContext::inplaceExpand
(
string& code,
const dictionary& dict
)
{
stringOps::inplaceTrim(code);
stringOps::inplaceExpand(code, dict);
}
unsigned Foam::dynamicCodeContext::addLineDirective
(
string& code,
label lineNum,
const fileName& file
)
{
++lineNum; // Change from 0-based to 1-based
const auto len = code.length();
if (lineNum > 0 && len && !file.empty())
{
code = "#line " + Foam::name(lineNum) + " \"" + file + "\"\n" + code;
return (code.length() - len);
}
return 0;
}
unsigned Foam::dynamicCodeContext::addLineDirective
(
string& code,
label lineNum,
const dictionary& dict
)
{
return addLineDirective(code, lineNum, dict.name());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dynamicCodeContext::dynamicCodeContext()
:
dict_(std::cref<dictionary>(dictionary::null))
{}
Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict)
:
dict_(dict),
code_(),
localCode_(),
include_(),
options_(),
libs_()
dynamicCodeContext()
{
// Expand dictionary entries
// Note: removes any leading/trailing whitespace
// - necessary for compilation options, convenient for includes
// and body.
const entry* codePtr = dict.findEntry("code", keyType::LITERAL);
if (codePtr)
{
codePtr->readEntry(code_);
stringOps::inplaceTrim(code_);
stringOps::inplaceExpand(code_, dict);
}
const entry* includePtr = dict.findEntry("codeInclude", keyType::LITERAL);
if (includePtr)
{
includePtr->readEntry(include_);
stringOps::inplaceTrim(include_);
stringOps::inplaceExpand(include_, dict);
}
const entry* optionsPtr = dict.findEntry("codeOptions", keyType::LITERAL);
if (optionsPtr)
{
optionsPtr->readEntry(options_);
stringOps::inplaceTrim(options_);
stringOps::inplaceExpand(options_, dict);
}
const entry* libsPtr = dict.findEntry("codeLibs", keyType::LITERAL);
if (libsPtr)
{
libsPtr->readEntry(libs_);
stringOps::inplaceTrim(libs_);
stringOps::inplaceExpand(libs_, dict);
}
const entry* localPtr = dict.findEntry("localCode", keyType::LITERAL);
if (localPtr)
{
localPtr->readEntry(localCode_);
stringOps::inplaceTrim(localCode_);
stringOps::inplaceExpand(localCode_, dict);
}
// Calculate SHA1 digest from include, options, localCode, code
OSHA1stream os;
os << include_ << options_ << libs_ << localCode_ << code_;
sha1_ = os.digest();
// Add line number after calculating sha1 since includes processorDDD
// in path which differs between processors.
if (codePtr)
{
addLineDirective(code_, codePtr->startLineNumber(), dict.name());
}
if (includePtr)
{
addLineDirective(include_, includePtr->startLineNumber(), dict.name());
}
// Do not add line directive to options_ (Make/options) and libs since
// they are preprocessed as a single line at this point. Can be fixed.
if (localPtr)
{
addLineDirective(localCode_, localPtr->startLineNumber(), dict.name());
}
setCodeContext(dict);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::dynamicCodeContext::addLineDirective
(
string& code,
label lineNum,
const fileName& name
)
bool Foam::dynamicCodeContext::valid() const
{
++lineNum; // Change from 0-based to 1-based
return &(dict_.get()) != &(dictionary::null);
}
if (lineNum > 0 && !name.empty())
void Foam::dynamicCodeContext::setCodeContext(const dictionary& dict)
{
dict_ = std::cref<dictionary>(dict);
sha1_.clear();
// Expand dictionary entries.
// Removing any leading/trailing whitespace is necessary for compilation
// options, but is also convenient for includes and code body.
const entry* eptr;
options_.clear();
sha1_.append("<codeOptions>");
if ((eptr = dict.findEntry("codeOptions", keyType::LITERAL)) != nullptr)
{
code = "#line " + Foam::name(lineNum) + " \"" + name + "\"\n" + code;
eptr->readEntry(options_);
dynamicCodeContext::inplaceExpand(options_, dict);
sha1_.append(options_);
// No #line for options (Make/options)
}
libs_.clear();
sha1_.append("<codeLibs>");
if ((eptr = dict.findEntry("codeLibs", keyType::LITERAL)) != nullptr)
{
eptr->readEntry(libs_);
dynamicCodeContext::inplaceExpand(libs_, dict);
sha1_.append(libs_);
// No #line for libs (LIB_LIBS)
}
include_.clear();
sha1_.append("<codeInclude>");
if ((eptr = dict.findEntry("codeInclude", keyType::LITERAL)) != nullptr)
{
eptr->readEntry(include_);
dynamicCodeContext::inplaceExpand(include_, dict);
sha1_.append(include_);
addLineDirective(include_, eptr->startLineNumber(), dict);
}
code_.clear();
sha1_.append("<code>");
if ((eptr = dict.findEntry("code", keyType::LITERAL)) != nullptr)
{
eptr->readEntry(code_);
dynamicCodeContext::inplaceExpand(code_, dict);
sha1_.append(code_);
addLineDirective(code_, eptr->startLineNumber(), dict);
}
localCode_.clear();
sha1_.append("<localCode>");
if ((eptr = dict.findEntry("localCode", keyType::LITERAL)) != nullptr)
{
eptr->readEntry(localCode_);
dynamicCodeContext::inplaceExpand(localCode_, dict);
sha1_.append(localCode_);
addLineDirective(localCode_, eptr->startLineNumber(), dict);
}
}

View File

@ -37,8 +37,9 @@ SourceFiles
#ifndef dynamicCodeContext_H
#define dynamicCodeContext_H
#include <functional>
#include "dictionary.H"
#include "SHA1Digest.H"
#include "SHA1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,19 +52,13 @@ namespace Foam
class dynamicCodeContext
{
// Private data
// Private Data
//- The parent dictionary context
const dictionary& dict_;
std::reference_wrapper<const dictionary> dict_;
//- Optional "code" entry
string code_;
//- Optional "localCode" entry
string localCode_;
//- Optional "codeInclude" entry
string include_;
//- The SHA1 of the contents
SHA1 sha1_;
//- Optional "codeOptions" entry
string options_;
@ -71,24 +66,68 @@ class dynamicCodeContext
//- Optional "codeLibs" entry
string libs_;
//- Calculated SHA1Digest
SHA1Digest sha1_;
//- Optional "codeInclude" entry
string include_;
//- Optional "code" entry
string code_;
//- Optional "localCode" entry
string localCode_;
public:
// Constructors
//- Construct null
dynamicCodeContext();
//- Construct from a dictionary
dynamicCodeContext(const dictionary& dict);
explicit dynamicCodeContext(const dictionary& dict);
// Member functions
// Static Member Functions
//- Cleanup string and expand with dictionary parameters
static void inplaceExpand(string& code, const dictionary& dict);
//- Prefix a \#line directive to code.
// The input lineNum is 0-based.
// Is a no-op if any of the arguments are invalid
// (lineNum is negative, code or file are empty)
//
// \return The change in string length caused by the directive.
// This can potentially be used to recover the substring portions.
static unsigned addLineDirective
(
string& code,
label lineNum,
const fileName& file
);
//- Prefix a \#line directive to code.
// The name of the dictionary is used for the 'file' name.
static unsigned addLineDirective
(
string& code,
label lineNum,
const dictionary& dict
);
// Member Functions
//- Considered valid if not using dictionary::null as the context
bool valid() const;
//- Set code context from a dictionary
void setCodeContext(const dictionary& dict);
//- Return the parent dictionary context
const dictionary& dict() const
{
return dict_;
return dict_.get();
}
//- Return the code-includes
@ -121,20 +160,27 @@ public:
return localCode_;
}
//- Return SHA1 digest calculated from include, options, code
const SHA1Digest& sha1() const
//- Return SHA1 calculated from options, libs, include, code
const SHA1& sha1() const
{
return sha1_;
}
//- Helper: add \#line directive
// The lineNum is 0-based. No-op if the lineNum is negative.
static void addLineDirective
(
string& code,
label lineNum,
const fileName& name
);
//- Add content to SHA1 hashing
void append(const std::string& str)
{
sha1_.append(str);
}
// Member Operators
//- Cast to dictionary
operator const dictionary&() const
{
return dict_.get();
}
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -30,38 +30,6 @@ License
#include "pointPatchFieldMapper.H"
#include "pointFields.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
const Foam::word Foam::codedFixedValuePointPatchField<Type>::codeTemplateC
= "fixedValuePointPatchFieldTemplate.C";
template<class Type>
const Foam::word Foam::codedFixedValuePointPatchField<Type>::codeTemplateH
= "fixedValuePointPatchFieldTemplate.H";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
void Foam::codedFixedValuePointPatchField<Type>::setFieldTemplates
(
dynamicCode& dynCode
)
{
word fieldType(pTraits<Type>::typeName);
// Template type for pointPatchField
dynCode.setFilterVariable("TemplateType", fieldType);
// Name for pointPatchField - eg, ScalarField, VectorField, ...
fieldType[0] = toupper(fieldType[0]);
dynCode.setFilterVariable("FieldType", fieldType + "Field");
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -71,27 +39,26 @@ const
{
const objectRegistry& obr = this->db();
if (obr.foundObject<IOdictionary>("codeDict"))
const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict");
if (dictptr)
{
return obr.lookupObject<IOdictionary>("codeDict");
return *dictptr;
}
else
{
return obr.store
return obr.store
(
new IOdictionary
(
new IOdictionary
IOobject
(
IOobject
(
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
}
)
);
}
@ -113,8 +80,7 @@ void Foam::codedFixedValuePointPatchField<Type>::prepare
dynCode.setFilterVariable("typeName", name_);
// Set TemplateType and FieldType filter variables
// (for pointPatchField)
setFieldTemplates(dynCode);
dynCode.setFieldTemplates<Type>();
// Compile filtered C template
dynCode.addCompileFile(codeTemplateC);
@ -122,23 +88,23 @@ void Foam::codedFixedValuePointPatchField<Type>::prepare
// Copy filtered H template
dynCode.addCopyFile(codeTemplateH);
// Debugging: make BC verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// Debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// DetailInfo
// <<"compile " << name_ << " 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()
);
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
" -lOpenFOAM \\\n"
" -lfiniteVolume \\\n"
+ context.libs()
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2017 OpenFOAM Foundation
@ -92,9 +92,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class dynamicCode;
class dynamicCodeContext;
// Forward Declarations
class IOdictionary;
/*---------------------------------------------------------------------------*\
@ -105,7 +103,7 @@ template<class Type>
class codedFixedValuePointPatchField
:
public fixedValuePointPatchField<Type>,
public codedBase
protected codedBase
{
// Private data
@ -121,9 +119,6 @@ class codedFixedValuePointPatchField
const IOdictionary& dict() const;
//- Set the rewrite vars controlling the Type
static void setFieldTemplates(dynamicCode& dynCode);
//- Get the loaded dynamic libraries
virtual dlLibraryTable& libs() const;
@ -142,13 +137,15 @@ class codedFixedValuePointPatchField
public:
// Static data members
// Static Data Members
//- Name of the C code template to be used
static const word codeTemplateC;
static constexpr const char* const codeTemplateC
= "fixedValuePointPatchFieldTemplate.C";
//- Name of the H code template to be used
static const word codeTemplateH;
static constexpr const char* const codeTemplateH
= "fixedValuePointPatchFieldTemplate.H";
//- Runtime type information

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,10 +26,7 @@ License
#include "codedPoints0MotionSolver.H"
#include "dictionary.H"
#include "Time.H"
#include "SHA1Digest.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -58,14 +55,15 @@ void Foam::codedPoints0MotionSolver::prepare
dynCode.setFilterVariable("typeName", name_);
// Compile filtered C template
dynCode.addCompileFile("codedPoints0MotionSolverTemplate.C");
dynCode.addCompileFile(codeTemplateC);
// Copy filtered H template
dynCode.addCopyFile("codedPoints0MotionSolverTemplate.H");
dynCode.addCopyFile(codeTemplateH);
// Debugging: make BC verbose
// Debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// DetailInfo
// <<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// Define Make/options
@ -73,12 +71,15 @@ void Foam::codedPoints0MotionSolver::prepare
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
"-I$(LIB_SRC)/fvMotionSolvers/lnInclude \\\n"
"-I$(LIB_SRC)/dynamicMesh/lnInclude \\\n"
"-I$(LIB_SRC)/meshTools/lnInclude \\\n"
"-I$(LIB_SRC)/dynamicMesh/lnInclude \\\n"
"-I$(LIB_SRC)/fvMotionSolvers/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
+ " -lfvMotionSolvers \\\n"
" -lfiniteVolume \\\n"
" -lmeshTools \\\n"
" -ldynamicMesh \\\n"
" -lfvMotionSolvers \\\n"
+ context.libs()
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -90,7 +90,7 @@ class codedPoints0MotionSolver
{
protected:
// Protected data
// Protected Data
//- Name of redirected motion solver
word name_;
@ -107,17 +107,17 @@ protected:
//- Adapt the context for the current object
virtual void prepare(dynamicCode&, const dynamicCodeContext&) const;
// Return a description (type + name) for the output
//- Return a description (type + name) for the output
virtual string description() const;
// Clear any redirected objects
//- Clear any redirected objects
virtual void clearRedirect() const;
// Get the dictionary to initialize the codeContext
// The dictionary to initialize the codeContext
virtual const dictionary& codeDict() const;
//- No copy assignment construct
//- No copy construct
codedPoints0MotionSolver(const codedPoints0MotionSolver&) = delete;
//- No copy assignment
@ -126,6 +126,17 @@ protected:
public:
// Static Data Members
//- Name of the C code template to be used
static constexpr const char* const codeTemplateC
= "codedPoints0MotionSolverTemplate.C";
//- Name of the H code template to be used
static constexpr const char* const codeTemplateH
= "codedPoints0MotionSolverTemplate.H";
//- Runtime type information
TypeName("coded");
@ -156,10 +167,10 @@ public:
virtual void solve();
//- Update local data for geometry changes
virtual void movePoints(const pointField&);
virtual void movePoints(const pointField& fld);
//- Update local data for topology changes
virtual void updateMesh(const mapPolyMesh&);
virtual void updateMesh(const mapPolyMesh& mpm);
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -31,37 +31,6 @@ License
#include "volFields.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
const Foam::word Foam::codedFixedValueFvPatchField<Type>::codeTemplateC
= "fixedValueFvPatchFieldTemplate.C";
template<class Type>
const Foam::word Foam::codedFixedValueFvPatchField<Type>::codeTemplateH
= "fixedValueFvPatchFieldTemplate.H";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
void Foam::codedFixedValueFvPatchField<Type>::setFieldTemplates
(
dynamicCode& dynCode
)
{
word fieldType(pTraits<Type>::typeName);
// template type for fvPatchField
dynCode.setFilterVariable("TemplateType", fieldType);
// Name for fvPatchField - eg, ScalarField, VectorField, ...
fieldType[0] = toupper(fieldType[0]);
dynCode.setFilterVariable("FieldType", fieldType + "Field");
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -70,27 +39,26 @@ const Foam::IOdictionary& Foam::codedFixedValueFvPatchField<Type>::dict() const
{
const objectRegistry& obr = this->db();
if (obr.foundObject<IOdictionary>("codeDict"))
const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict");
if (dictptr)
{
return obr.lookupObject<IOdictionary>("codeDict");
return *dictptr;
}
else
{
return obr.store
return obr.store
(
new IOdictionary
(
new IOdictionary
IOobject
(
IOobject
(
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
}
)
);
}
@ -108,36 +76,35 @@ void Foam::codedFixedValueFvPatchField<Type>::prepare
const dynamicCodeContext& context
) const
{
// take no chances - typeName must be identical to name_
// Take no chances - typeName must be identical to name_
dynCode.setFilterVariable("typeName", name_);
// set TemplateType and FieldType filter variables
// (for fvPatchField)
setFieldTemplates(dynCode);
// Set TemplateType and FieldType filter variables
dynCode.setFieldTemplates<Type>();
// compile filtered C template
// Compile filtered C template
dynCode.addCompileFile(codeTemplateC);
// copy filtered H template
// Copy filtered H template
dynCode.addCopyFile(codeTemplateH);
// Debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// DetailInfo
// <<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// debugging: make BC verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// define Make/options
// 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()
);
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
" -lOpenFOAM \\\n"
" -lfiniteVolume \\\n"
+ context.libs()
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -38,8 +38,8 @@ Usage
\verbatim
<patchName>
{
type codedFixedValue;
value uniform 0;
type codedFixedValue;
value uniform 0;
name rampedFixedValue; // name of generated BC
code
@ -93,9 +93,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class dynamicCode;
class dynamicCodeContext;
// Forward Declarations
class IOdictionary;
/*---------------------------------------------------------------------------*\
@ -106,9 +104,9 @@ template<class Type>
class codedFixedValueFvPatchField
:
public fixedValueFvPatchField<Type>,
public codedBase
protected codedBase
{
// Private data
// Private Data
//- Dictionary contents for the boundary condition
const dictionary dict_;
@ -122,9 +120,6 @@ class codedFixedValueFvPatchField
const IOdictionary& dict() const;
//- Set the rewrite vars controlling the Type
static void setFieldTemplates(dynamicCode& dynCode);
//- Get the loaded dynamic libraries
virtual dlLibraryTable& libs() const;
@ -146,10 +141,12 @@ public:
// Static data members
//- Name of the C code template to be used
static const word codeTemplateC;
static constexpr const char* const codeTemplateC
= "fixedValueFvPatchFieldTemplate.C";
//- Name of the H code template to be used
static const word codeTemplateH;
static constexpr const char* const codeTemplateH
= "fixedValueFvPatchFieldTemplate.H";
//- Runtime type information

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
@ -30,38 +30,6 @@ License
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
const Foam::word Foam::codedMixedFvPatchField<Type>::codeTemplateC
= "mixedFvPatchFieldTemplate.C";
template<class Type>
const Foam::word Foam::codedMixedFvPatchField<Type>::codeTemplateH
= "mixedFvPatchFieldTemplate.H";
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
void Foam::codedMixedFvPatchField<Type>::setFieldTemplates
(
dynamicCode& dynCode
)
{
word fieldType(pTraits<Type>::typeName);
// template type for fvPatchField
dynCode.setFilterVariable("TemplateType", fieldType);
// Name for fvPatchField - eg, ScalarField, VectorField, ...
fieldType[0] = toupper(fieldType[0]);
dynCode.setFilterVariable("FieldType", fieldType + "Field");
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -70,27 +38,26 @@ const Foam::IOdictionary& Foam::codedMixedFvPatchField<Type>::dict() const
{
const objectRegistry& obr = this->db();
if (obr.foundObject<IOdictionary>("codeDict"))
const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict");
if (dictptr)
{
return obr.lookupObject<IOdictionary>("codeDict");
return *dictptr;
}
else
{
return obr.store
return obr.store
(
new IOdictionary
(
new IOdictionary
IOobject
(
IOobject
(
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
"codeDict",
this->db().time().system(),
this->db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
}
)
);
}
@ -108,36 +75,35 @@ void Foam::codedMixedFvPatchField<Type>::prepare
const dynamicCodeContext& context
) const
{
// take no chances - typeName must be identical to name_
// Take no chances - typeName must be identical to name_
dynCode.setFilterVariable("typeName", name_);
// set TemplateType and FieldType filter variables
// (for fvPatchField)
setFieldTemplates(dynCode);
// Set TemplateType and FieldType filter variables
dynCode.setFieldTemplates<Type>();
// compile filtered C template
// Compile filtered C template
dynCode.addCompileFile(codeTemplateC);
// copy filtered H template
// Copy filtered H template
dynCode.addCopyFile(codeTemplateH);
// Debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// DetailInfo
// <<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// debugging: make BC verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// define Make/options
// 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()
);
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
" -lOpenFOAM \\\n"
" -lfiniteVolume \\\n"
+ context.libs()
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -132,9 +132,6 @@ class codedMixedFvPatchField
const IOdictionary& dict() const;
//- Set the rewrite vars controlling the Type
static void setFieldTemplates(dynamicCode& dynCode);
//- Get the loaded dynamic libraries
virtual dlLibraryTable& libs() const;
@ -153,13 +150,15 @@ class codedMixedFvPatchField
public:
// Static data members
// Static Data Members
//- Name of the C code template to be used
static const word codeTemplateC;
static constexpr const char* const codeTemplateC
= "mixedFvPatchFieldTemplate.C";
//- Name of the H code template to be used
static const word codeTemplateH;
static constexpr const char* const codeTemplateH
= "mixedFvPatchFieldTemplate.H";
//- Runtime type information

View File

@ -29,10 +29,7 @@ License
#include "volFields.H"
#include "dictionary.H"
#include "Time.H"
#include "SHA1Digest.H"
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "stringOps.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -42,7 +39,6 @@ namespace Foam
namespace functionObjects
{
defineTypeNameAndDebug(codedFunctionObject, 0);
addToRunTimeSelectionTable
(
functionObject,
@ -70,14 +66,15 @@ void Foam::functionObjects::codedFunctionObject::prepare
dynCode.setFilterVariable("codeEnd", codeEnd_);
// Compile filtered C template
dynCode.addCompileFile("functionObjectTemplate.C");
dynCode.addCompileFile(codeTemplateC);
// Copy filtered H template
dynCode.addCopyFile("functionObjectTemplate.H");
dynCode.addCopyFile(codeTemplateH);
// Debugging: make BC verbose
// Debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// DetailInfo
// <<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// Define Make/options
@ -88,9 +85,9 @@ void Foam::functionObjects::codedFunctionObject::prepare
"-I$(LIB_SRC)/meshTools/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
+ " -lOpenFOAM \\\n"
+ " -lfiniteVolume \\\n"
+ " -lmeshTools \\\n"
" -lOpenFOAM \\\n"
" -lfiniteVolume \\\n"
" -lmeshTools \\\n"
+ context.libs()
);
}
@ -187,84 +184,110 @@ bool Foam::functionObjects::codedFunctionObject::read(const dictionary& dict)
{
timeFunctionObject::read(dict);
codedBase::setCodeContext(dict);
dict.readCompat<word>("name", {{"redirectType", 1706}}, name_);
const entry* dataPtr = dict.findEntry("codeData", keyType::LITERAL);
label nKeywords = 0;
if (dataPtr)
const entry* eptr;
codeData_.clear();
codedBase::append("<codeData>");
if ((eptr = dict.findEntry("codeData", keyType::LITERAL)) != nullptr)
{
dataPtr->readEntry(codeData_);
stringOps::inplaceExpand(codeData_, dict);
eptr->readEntry(codeData_);
dynamicCodeContext::inplaceExpand(codeData_, dict);
codedBase::append(codeData_);
dynamicCodeContext::addLineDirective
(
codeData_,
dataPtr->startLineNumber(),
eptr->startLineNumber(),
dict.name()
);
++nKeywords;
}
const entry* readPtr = dict.findEntry("codeRead", keyType::LITERAL);
if (readPtr)
codeRead_.clear();
codedBase::append("<codeRead>");
if ((eptr = dict.findEntry("codeRead", keyType::LITERAL)) != nullptr)
{
readPtr->readEntry(codeRead_);
stringOps::inplaceExpand(codeRead_, dict);
eptr->readEntry(codeRead_);
dynamicCodeContext::inplaceExpand(codeRead_, dict);
codedBase::append(codeRead_);
dynamicCodeContext::addLineDirective
(
codeRead_,
readPtr->startLineNumber(),
eptr->startLineNumber(),
dict.name()
);
++nKeywords;
}
const entry* execPtr = dict.findEntry("codeExecute", keyType::LITERAL);
if (execPtr)
codeExecute_.clear();
codedBase::append("<codeExecute>");
if ((eptr = dict.findEntry("codeExecute", keyType::LITERAL)) != nullptr)
{
execPtr->readEntry(codeExecute_);
stringOps::inplaceExpand(codeExecute_, dict);
eptr->readEntry(codeExecute_);
dynamicCodeContext::inplaceExpand(codeExecute_, dict);
codedBase::append(codeExecute_);
dynamicCodeContext::addLineDirective
(
codeExecute_,
execPtr->startLineNumber(),
eptr->startLineNumber(),
dict.name()
);
++nKeywords;
}
const entry* writePtr = dict.findEntry("codeWrite", keyType::LITERAL);
if (writePtr)
codeWrite_.clear();
codedBase::append("<codeWrite>");
if ((eptr = dict.findEntry("codeWrite", keyType::LITERAL)) != nullptr)
{
writePtr->readEntry(codeWrite_);
stringOps::inplaceExpand(codeWrite_, dict);
eptr->readEntry(codeWrite_);
dynamicCodeContext::inplaceExpand(codeWrite_, dict);
codedBase::append(codeWrite_);
dynamicCodeContext::addLineDirective
(
codeWrite_,
writePtr->startLineNumber(),
eptr->startLineNumber(),
dict.name()
);
++nKeywords;
}
const entry* endPtr = dict.findEntry("codeEnd", keyType::LITERAL);
if (endPtr)
codeEnd_.clear();
codedBase::append("<codeEnd>");
if ((eptr = dict.findEntry("codeEnd", keyType::LITERAL)) != nullptr)
{
endPtr->readEntry(codeEnd_);
stringOps::inplaceExpand(codeEnd_, dict);
eptr->readEntry(codeEnd_);
dynamicCodeContext::inplaceExpand(codeEnd_, dict);
codedBase::append(codeEnd_);
dynamicCodeContext::addLineDirective
(
codeEnd_,
endPtr->startLineNumber(),
eptr->startLineNumber(),
dict.name()
);
++nKeywords;
}
if (!dataPtr && !readPtr && !execPtr && !writePtr && !endPtr)
if (!nKeywords)
{
IOWarningInFunction(dict)
<< "No critical \"code\" prefixed keywords were found."
<< " Please check the code documentation for more details."
<< nl << endl;
<< "No critical \"code\" prefixed keywords found." << nl
<< "Please check the code documentation for more details." << nl
<< endl;
}
updateLibrary(name_);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2017 OpenFOAM Foundation
@ -123,13 +123,13 @@ protected:
//- Adapt the context for the current object
virtual void prepare(dynamicCode&, const dynamicCodeContext&) const;
// Return a description (type + name) for the output
//- Return a description (type + name) for the output
virtual string description() const;
// Clear any redirected objects
//- Clear any redirected objects
virtual void clearRedirect() const;
// Get the dictionary to initialize the codeContext
//- The dictionary to initialize the codeContext
virtual const dictionary& codeDict() const;
@ -142,6 +142,17 @@ protected:
public:
// Static Data Members
//- Name of the C code template to be used
static constexpr const char* const codeTemplateC
= "functionObjectTemplate.C";
//- Name of the H code template to be used
static constexpr const char* const codeTemplateH
= "functionObjectTemplate.H";
//- Runtime type information
TypeName("coded");

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -50,7 +50,7 @@ void Foam::fv::CodedSource<Type>::prepare
//dynCode.removeFilterVariable("code");
dynCode.setFilterVariable("codeCorrect", codeCorrect_);
dynCode.setFilterVariable("codeAddSup", codeAddSup_);
dynCode.setFilterVariable("codeSetValue", codeSetValue_);
dynCode.setFilterVariable("codeConstrain", codeConstrain_);
// compile filtered C template
dynCode.addCompileFile("codedFvOptionTemplate.C");
@ -58,27 +58,28 @@ void Foam::fv::CodedSource<Type>::prepare
// copy filtered H template
dynCode.addCopyFile("codedFvOptionTemplate.H");
// debugging: make BC verbose
// dynCode.setFilterVariable("verbose", "true");
// Info<<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// debugging: make verbose
// dynCode.setFilterVariable("verbose", "true");
// DetailInfo
// <<"compile " << name_ << " sha1: "
// << context.sha1() << endl;
// define Make/options
dynCode.setMakeOptions
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
"-I$(LIB_SRC)/meshTools/lnInclude \\\n"
"-I$(LIB_SRC)/sampling/lnInclude \\\n"
"-I$(LIB_SRC)/fvOptions/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
+ " -lmeshTools \\\n"
+ " -lfvOptions \\\n"
+ " -lsampling \\\n"
+ " -lfiniteVolume \\\n"
+ context.libs()
);
(
"EXE_INC = -g \\\n"
"-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
"-I$(LIB_SRC)/fvOptions/lnInclude \\\n"
"-I$(LIB_SRC)/meshTools/lnInclude \\\n"
"-I$(LIB_SRC)/sampling/lnInclude \\\n"
+ context.options()
+ "\n\nLIB_LIBS = \\\n"
" -lfvOptions \\\n"
" -lmeshTools \\\n"
" -lsampling \\\n"
" -lfiniteVolume \\\n"
+ context.libs()
);
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -34,6 +34,7 @@ Description
The hook functions take the following arguments:
\verbatim
codeCorrect
(
GeometricField<Type, fvPatchField, volMesh>& field
@ -45,11 +46,12 @@ Description
const label fieldi
)
constrain
codeConstrain
(
fvMatrix<Type}>& eqn,
const label fieldi
)
\endverbatim
where :
field is the name of the field in the fields list
@ -71,7 +73,6 @@ Usage
codeInclude
#{
#};
codeCorrect
@ -87,18 +88,9 @@ Usage
heSource -= 0.1*sqr(time.value())*V;
#};
codeSetValue
codeContrain
#{
Pout<< "**codeSetValue**" << endl;
#};
// Dummy entry. Make dependent on above to trigger recompilation
code
#{
$codeInclude
$codeCorrect
$codeAddSup
$codeSetValue
Pout<< "**codeConstrain**" << endl;
#};
}
}
@ -131,18 +123,18 @@ template<class Type>
class CodedSource
:
public cellSetOption,
public codedBase
protected codedBase
{
protected:
// Protected data
// Protected Data
word name_;
string codeCorrect_;
string codeAddSup_;
string codeSetValue_;
string codeConstrain_;
//- Underlying functionObject
mutable autoPtr<option> redirectFvOptionPtr_;
@ -156,13 +148,13 @@ protected:
//- Adapt the context for the current object
virtual void prepare(dynamicCode&, const dynamicCodeContext&) const;
// Return a description (type + name) for the output
//- Return a description (type + name) for the output
virtual string description() const;
// Clear any redirected objects
//- Clear any redirected objects
virtual void clearRedirect() const;
// Get the dictionary to initialize the codeContext
//- Get the dictionary to initialize the codeContext
virtual const dictionary& codeDict() const;
@ -189,42 +181,42 @@ public:
//- Dynamically compiled fvOption
option& redirectFvOption() const;
// Evaluation
//- Correct field
virtual void correct
(
GeometricField<Type, fvPatchField, volMesh>&
);
// Evaluation
//- Explicit and implicit matrix contributions
virtual void addSup
(
fvMatrix<Type>& eqn,
const label fieldi
);
//- Correct field
virtual void correct
(
GeometricField<Type, fvPatchField, volMesh>&
);
//- Explicit and implicit matrix contributions
// to compressible equation
virtual void addSup
(
const volScalarField& rho,
fvMatrix<Type>& eqn,
const label fieldi
);
//- Explicit/implicit matrix contributions
virtual void addSup
(
fvMatrix<Type>& eqn,
const label fieldi
);
//- Set value
virtual void constrain
(
fvMatrix<Type>& eqn,
const label fieldi
);
//- Explicit/implicit matrix contributions to compressible equation
virtual void addSup
(
const volScalarField& rho,
fvMatrix<Type>& eqn,
const label fieldi
);
//- Set value
virtual void constrain
(
fvMatrix<Type>& eqn,
const label fieldi
);
// IO
// IO
//- Read source dictionary
virtual bool read(const dictionary& dict);
//- Read source dictionary
virtual bool read(const dictionary& dict);
};

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2012-2016 OpenFOAM Foundation
@ -26,70 +26,85 @@ License
\*---------------------------------------------------------------------------*/
#include "CodedSource.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::fv::CodedSource<Type>::read(const dictionary& dict)
{
if (cellSetOption::read(dict))
codedBase::setCodeContext(coeffs_);
if (!cellSetOption::read(dict))
{
coeffs_.readEntry("fields", fieldNames_);
applied_.setSize(fieldNames_.size(), false);
dict.readCompat<word>("name", {{"redirectType", 1706}}, name_);
// Code snippets
{
const entry& e =
coeffs_.lookupEntry("codeCorrect", keyType::LITERAL);
e.readEntry(codeCorrect_);
stringOps::inplaceTrim(codeCorrect_);
stringOps::inplaceExpand(codeCorrect_, coeffs_);
dynamicCodeContext::addLineDirective
(
codeCorrect_,
e.startLineNumber(),
coeffs_.name()
);
}
{
const entry& e =
coeffs_.lookupEntry("codeAddSup", keyType::LITERAL);
e.readEntry(codeAddSup_);
stringOps::inplaceTrim(codeAddSup_);
stringOps::inplaceExpand(codeAddSup_, coeffs_);
dynamicCodeContext::addLineDirective
(
codeAddSup_,
e.startLineNumber(),
coeffs_.name()
);
}
{
const entry& e =
coeffs_.lookupEntry("codeSetValue", keyType::LITERAL);
e.readEntry(codeSetValue_);
stringOps::inplaceTrim(codeSetValue_);
stringOps::inplaceExpand(codeSetValue_, coeffs_);
dynamicCodeContext::addLineDirective
(
codeSetValue_,
e.startLineNumber(),
coeffs_.name()
);
}
return true;
return false;
}
return false;
coeffs_.readEntry("fields", fieldNames_);
applied_.setSize(fieldNames_.size(), false);
dict.readCompat<word>("name", {{"redirectType", 1706}}, name_);
// Code chunks
codedBase::append("<codeCorrect>");
{
const entry& e =
coeffs_.lookupEntry("codeCorrect", keyType::LITERAL);
e.readEntry(codeCorrect_);
dynamicCodeContext::inplaceExpand(codeCorrect_, coeffs_);
codedBase::append(codeCorrect_);
dynamicCodeContext::addLineDirective
(
codeCorrect_,
e.startLineNumber(),
coeffs_
);
}
codedBase::append("<codeAddSup>");
{
const entry& e =
coeffs_.lookupEntry("codeAddSup", keyType::LITERAL);
e.readEntry(codeAddSup_);
dynamicCodeContext::inplaceExpand(codeAddSup_, coeffs_);
codedBase::append(codeAddSup_);
dynamicCodeContext::addLineDirective
(
codeAddSup_,
e.startLineNumber(),
coeffs_
);
}
codedBase::append("<codeConstrain>");
{
const entry& e =
coeffs_.lookupEntryCompat
(
"codeConstrain",
{{ "codeSetValue", 1812 }}, keyType::LITERAL
);
e.readEntry(codeConstrain_);
dynamicCodeContext::inplaceExpand(codeConstrain_, coeffs_);
codedBase::append(codeConstrain_);
dynamicCodeContext::addLineDirective
(
codeConstrain_,
e.startLineNumber(),
coeffs_
);
}
return true;
}