/*---------------------------------------------------------------------------*\
========= |
\\ / 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 .
\*---------------------------------------------------------------------------*/
#include "dynamicCode.H"
#include "dynamicCodeContext.H"
#include "dictionaryContent.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template
Foam::dlLibraryTable&
Foam::Function1Types::CodedFunction1::libs() const
{
return this->time().libs();
}
template
Foam::string
Foam::Function1Types::CodedFunction1::description() const
{
return "CodedFunction1 " + redirectName_;
}
template
void Foam::Function1Types::CodedFunction1::clearRedirect() const
{
redirectFunctionPtr_.reset(nullptr);
}
template
const Foam::dictionary&
Foam::Function1Types::CodedFunction1::codeContext() const
{
// What else would make sense?
return dict_;
}
template
const Foam::dictionary&
Foam::Function1Types::CodedFunction1::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
const Foam::dictionary&
Foam::Function1Types::CodedFunction1::codeDict() const
{
return codeDict(dict_);
}
template
void Foam::Function1Types::CodedFunction1::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();
// 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
Foam::Function1Types::CodedFunction1::CodedFunction1
(
const word& entryName,
const dictionary& dict,
const objectRegistry* obrPtr
)
:
Function1(entryName, dict, obrPtr),
codedBase(),
dict_(dict),
redirectName_(dict.getOrDefault("name", entryName))
{
this->codedBase::setCodeContext(dict_);
// No additional code chunks...
updateLibrary(redirectName_);
}
template
Foam::Function1Types::CodedFunction1::CodedFunction1
(
const CodedFunction1& rhs
)
:
Function1(rhs),
codedBase(),
dict_(rhs.dict_),
redirectName_(rhs.redirectName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template
const Foam::Function1&
Foam::Function1Types::CodedFunction1::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::New
(
redirectName_,
constructDict,
this->whichDb()
)
);
// Forward copy of codeContext to the code template
auto* contentPtr =
dynamic_cast(redirectFunctionPtr_.get());
if (contentPtr)
{
contentPtr->dict(this->codeContext());
}
else
{
WarningInFunction
<< redirectName_ << " Did not derive from dictionaryContent"
<< nl << nl;
}
}
return *redirectFunctionPtr_;
}
template
Type Foam::Function1Types::CodedFunction1::value
(
const scalar x
) const
{
// Ensure library containing user-defined code is up-to-date
updateLibrary(redirectName_);
return redirectFunction().value(x);
}
template
void Foam::Function1Types::CodedFunction1::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);
}
// ************************************************************************* //