mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add coded Function1 (#2282)
- update coded templates with qualified names GIT: add in missing PatchFunction1 constant() method - was missed in a previous commit
This commit is contained in:
@ -0,0 +1,247 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "dynamicCode.H"
|
||||
#include "dynamicCodeContext.H"
|
||||
#include "dictionaryContent.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::dlLibraryTable&
|
||||
Foam::Function1Types::CodedFunction1<Type>::libs() const
|
||||
{
|
||||
return this->time().libs();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::string
|
||||
Foam::Function1Types::CodedFunction1<Type>::description() const
|
||||
{
|
||||
return "CodedFunction1 " + redirectName_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::Function1Types::CodedFunction1<Type>::clearRedirect() const
|
||||
{
|
||||
redirectFunctionPtr_.reset(nullptr);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
const Foam::dictionary&
|
||||
Foam::Function1Types::CodedFunction1<Type>::codeContext() const
|
||||
{
|
||||
// What else would make sense?
|
||||
return dict_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
const Foam::dictionary&
|
||||
Foam::Function1Types::CodedFunction1<Type>::codeDict
|
||||
(
|
||||
const dictionary& dict
|
||||
) const
|
||||
{
|
||||
// Use named subdictionary if present to provide the code.
|
||||
// This allows running with multiple Function1s
|
||||
|
||||
return
|
||||
(
|
||||
dict.found("code")
|
||||
? dict
|
||||
: dict.subDict(redirectName_)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
const Foam::dictionary&
|
||||
Foam::Function1Types::CodedFunction1<Type>::codeDict() const
|
||||
{
|
||||
return codeDict(dict_);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::Function1Types::CodedFunction1<Type>::prepare
|
||||
(
|
||||
dynamicCode& dynCode,
|
||||
const dynamicCodeContext& context
|
||||
) const
|
||||
{
|
||||
if (context.code().empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict_)
|
||||
<< "No code section in input dictionary for Function1 "
|
||||
<< " name " << redirectName_
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Take no chances - typeName must be identical to redirectName_
|
||||
dynCode.setFilterVariable("typeName", redirectName_);
|
||||
|
||||
// Set TemplateType and FieldType filter variables
|
||||
dynCode.setFieldTemplates<Type>();
|
||||
|
||||
// Compile filtered C template
|
||||
dynCode.addCompileFile(codeTemplateC);
|
||||
|
||||
// Copy filtered H template
|
||||
dynCode.addCopyFile(codeTemplateH);
|
||||
|
||||
#ifdef FULLDEBUG
|
||||
dynCode.setFilterVariable("verbose", "true");
|
||||
DetailInfo
|
||||
<<"compile " << redirectName_ << " sha1: " << context.sha1() << endl;
|
||||
#endif
|
||||
|
||||
// Define Make/options
|
||||
dynCode.setMakeOptions
|
||||
(
|
||||
"EXE_INC = -g \\\n"
|
||||
"-I$(LIB_SRC)/meshTools/lnInclude \\\n"
|
||||
+ context.options()
|
||||
+ "\n\nLIB_LIBS = \\\n"
|
||||
" -lOpenFOAM \\\n"
|
||||
" -lmeshTools \\\n"
|
||||
+ context.libs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Function1Types::CodedFunction1<Type>::CodedFunction1
|
||||
(
|
||||
const word& entryName,
|
||||
const dictionary& dict,
|
||||
const objectRegistry* obrPtr
|
||||
)
|
||||
:
|
||||
Function1<Type>(entryName, dict, obrPtr),
|
||||
codedBase(),
|
||||
dict_(dict),
|
||||
redirectName_(dict.getOrDefault<word>("name", entryName))
|
||||
{
|
||||
this->codedBase::setCodeContext(dict_);
|
||||
|
||||
// No additional code chunks...
|
||||
|
||||
updateLibrary(redirectName_);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Function1Types::CodedFunction1<Type>::CodedFunction1
|
||||
(
|
||||
const CodedFunction1<Type>& rhs
|
||||
)
|
||||
:
|
||||
Function1<Type>(rhs),
|
||||
codedBase(),
|
||||
dict_(rhs.dict_),
|
||||
redirectName_(rhs.redirectName_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
const Foam::Function1<Type>&
|
||||
Foam::Function1Types::CodedFunction1<Type>::redirectFunction() const
|
||||
{
|
||||
if (!redirectFunctionPtr_)
|
||||
{
|
||||
dictionary constructDict;
|
||||
// Force 'redirectName_' sub-dictionary into existence
|
||||
dictionary& coeffs = constructDict.subDictOrAdd(redirectName_);
|
||||
|
||||
coeffs = dict_; // Copy input code and coefficients
|
||||
coeffs.remove("name"); // Redundant
|
||||
coeffs.set("type", redirectName_); // Specify our new (redirect) type
|
||||
|
||||
redirectFunctionPtr_.reset
|
||||
(
|
||||
Function1<Type>::New
|
||||
(
|
||||
redirectName_,
|
||||
constructDict,
|
||||
this->whichDb()
|
||||
)
|
||||
);
|
||||
|
||||
// Forward copy of codeContext to the code template
|
||||
auto* contentPtr =
|
||||
dynamic_cast<dictionaryContent*>(redirectFunctionPtr_.get());
|
||||
|
||||
if (contentPtr)
|
||||
{
|
||||
contentPtr->dict(this->codeContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< redirectName_ << " Did not derive from dictionaryContent"
|
||||
<< nl << nl;
|
||||
}
|
||||
}
|
||||
return *redirectFunctionPtr_;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Type Foam::Function1Types::CodedFunction1<Type>::value
|
||||
(
|
||||
const scalar x
|
||||
) const
|
||||
{
|
||||
// Ensure library containing user-defined code is up-to-date
|
||||
updateLibrary(redirectName_);
|
||||
|
||||
return redirectFunction().value(x);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::Function1Types::CodedFunction1<Type>::writeData
|
||||
(
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
// Should really only output only relevant entries but since using
|
||||
// Function1-from-subdict upon construction our dictionary contains
|
||||
// only the relevant entries.
|
||||
dict_.writeEntry(this->name(), os);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,225 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Class
|
||||
Foam::Function1Types::CodedFunction1
|
||||
|
||||
Description
|
||||
Function1 with the code supplied by an on-the-fly compiled C++
|
||||
expression.
|
||||
|
||||
The code entries:
|
||||
\plaintable
|
||||
codeInclude | include files
|
||||
codeOptions | compiler line: added to EXE_INC (Make/options)
|
||||
codeLibs | linker line: added to LIB_LIBS (Make/options)
|
||||
localCode | c++; local static functions
|
||||
code | c++; return the patch values at (scalar x)
|
||||
\endplaintable
|
||||
|
||||
Usage
|
||||
Example:
|
||||
\verbatim
|
||||
<patchName>
|
||||
{
|
||||
type uniformFixedValue;
|
||||
uniformValue
|
||||
{
|
||||
type coded;
|
||||
name myExpression; // Name of generated PatchFunction1
|
||||
|
||||
code
|
||||
#{
|
||||
const polyPatch& pp = this->patch();
|
||||
Pout<< "** Patch size:" << pp.size() << endl;
|
||||
return tmp<vectorField>::New(pp.size(), vector(1, 0, 0))
|
||||
#};
|
||||
|
||||
//codeInclude
|
||||
//#{
|
||||
// #include "volFields.H"
|
||||
//#};
|
||||
|
||||
//codeOptions
|
||||
//#{
|
||||
// -I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
//#};
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Note
|
||||
The code context dictionary is simply the dictionary used to specify
|
||||
the PatchFunction1 coefficients.
|
||||
|
||||
See also
|
||||
Foam::dynamicCode
|
||||
Foam::codedFixedValue
|
||||
Foam::functionEntries::codeStream
|
||||
|
||||
SourceFiles
|
||||
CodedFunction1.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Function1Types_CodedFunction1_H
|
||||
#define Function1Types_CodedFunction1_H
|
||||
|
||||
#include "Function1.H"
|
||||
#include "codedBase.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace Function1Types
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class CodedFunction1 Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class CodedFunction1
|
||||
:
|
||||
public Function1<Type>,
|
||||
protected codedBase
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Dictionary contents for the function
|
||||
const dictionary dict_;
|
||||
|
||||
const word redirectName_;
|
||||
|
||||
mutable autoPtr<Function1<Type>> redirectFunctionPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Get reference to the underlying Function1
|
||||
const Function1<Type>& redirectFunction() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Mutable access to the loaded dynamic libraries
|
||||
virtual dlLibraryTable& libs() const;
|
||||
|
||||
//- Description (type + name) for the output
|
||||
virtual string description() const;
|
||||
|
||||
//- Clear redirected object(s)
|
||||
virtual void clearRedirect() const;
|
||||
|
||||
//- Additional 'codeContext' dictionary to pass through
|
||||
virtual const dictionary& codeContext() const;
|
||||
|
||||
// Get the code (sub)dictionary
|
||||
virtual const dictionary& codeDict(const dictionary& dict) const;
|
||||
|
||||
// Get the code dictionary
|
||||
virtual const dictionary& codeDict() const;
|
||||
|
||||
//- Adapt the context for the current object
|
||||
virtual void prepare(dynamicCode&, const dynamicCodeContext&) const;
|
||||
|
||||
|
||||
// Generated Methods
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const CodedFunction1<Type>&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
// Static Data Members
|
||||
|
||||
//- Name of the C code template to be used
|
||||
static constexpr const char* const codeTemplateC
|
||||
= "codedFunction1Template.C";
|
||||
|
||||
//- Name of the H code template to be used
|
||||
static constexpr const char* const codeTemplateH
|
||||
= "codedFunction1Template.H";
|
||||
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("coded");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from entry name, dictionary and optional registry
|
||||
CodedFunction1
|
||||
(
|
||||
const word& entryName,
|
||||
const dictionary& dict,
|
||||
const objectRegistry* obrPtr = nullptr
|
||||
);
|
||||
|
||||
//- Copy construct
|
||||
explicit CodedFunction1(const CodedFunction1<Type>& rhs);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<Function1<Type>> clone() const
|
||||
{
|
||||
return tmp<Function1<Type>>(new CodedFunction1<Type>(*this));
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~CodedFunction1() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return value at current time
|
||||
virtual inline Type value(const scalar x) const;
|
||||
|
||||
// Integrate etc are not implemented!
|
||||
|
||||
//- Write in dictionary format
|
||||
virtual void writeData(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Function1Types
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "CodedFunction1.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -78,7 +78,7 @@ void Foam::Function1Types::FunctionObjectTrigger<Type>::writeEntries
|
||||
) const
|
||||
{
|
||||
os.writeKeyword("triggers");
|
||||
flatOutput(triggers_);
|
||||
os << flatOutput(triggers_);
|
||||
os.endEntry();
|
||||
|
||||
if (defaultValue_)
|
||||
|
||||
@ -26,6 +26,7 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "CodedFunction1.H"
|
||||
#include "Constant.H"
|
||||
#include "Uniform.H"
|
||||
#include "ZeroConstant.H"
|
||||
@ -48,6 +49,7 @@ License
|
||||
|
||||
#define makeFunction1s(Type) \
|
||||
makeFunction1(Type); \
|
||||
makeFunction1Type(CodedFunction1, Type); \
|
||||
makeFunction1Type(Constant, Type); \
|
||||
makeFunction1Type(Uniform, Type); \
|
||||
makeFunction1Type(None, Type); \
|
||||
|
||||
Reference in New Issue
Block a user