mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add expression support for scalar/vector expression lookups
- similar idea to swak timelines/lookuptables but combined together
and based on Function1 for more flexibility.
Specified as 'functions<scalar>' or 'functions<vector>'.
For example,
functions<scalar>
{
intakeType table ((0 0) (10 1.2));
p_inlet
{
type sine;
frequency 3000;
scale 50;
level 101325;
}
}
These can be referenced in the expressions as a nullary function or a
unary function.
Within the parser, the names are prefixed with "fn:" (function).
It is thus possible to define "fn:sin()" that is different than
the builtin "sin()" function.
* A nullary call uses time value
- Eg, fn:p_inlet()
* A unary call acts as a remapper function.
- Eg, fn:intakeType(6.25)
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
| ========= | |
|
| ========= | |
|
||||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
| \\ / O peration | Version: v2106 |
|
| \\ / O peration | Version: v2112 |
|
||||||
| \\ / A nd | Website: www.openfoam.com |
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -138,4 +138,53 @@ cosine6
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
expr1
|
||||||
|
{
|
||||||
|
type expression;
|
||||||
|
|
||||||
|
functions<scalar>
|
||||||
|
{
|
||||||
|
func1 constant 21;
|
||||||
|
func2 constant 15;
|
||||||
|
sin constant -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
functions<vector>
|
||||||
|
{
|
||||||
|
vfunc3 constant (1 2 3);
|
||||||
|
vfunc4 constant (3 2 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
expression
|
||||||
|
#{
|
||||||
|
100 * fn:vfunc3() & fn:vfunc4() * (vector::z) .z()
|
||||||
|
* (fn:sin(arg()) + fn:func1(fn:func2()))
|
||||||
|
#};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
expr2
|
||||||
|
{
|
||||||
|
type expression;
|
||||||
|
|
||||||
|
functions<scalar>
|
||||||
|
{
|
||||||
|
func1 constant 21;
|
||||||
|
func2 constant 15;
|
||||||
|
sin constant -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
functions<vector>
|
||||||
|
{
|
||||||
|
vfunc3 constant (1 2 3);
|
||||||
|
vfunc4 constant (3 2 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
expression
|
||||||
|
#{
|
||||||
|
(fn:vfunc3() & vector::z) * arg()
|
||||||
|
#};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -168,6 +168,7 @@ $(expr)/traits/exprTraits.C
|
|||||||
|
|
||||||
$(expr)/exprDriver/exprDriver.C
|
$(expr)/exprDriver/exprDriver.C
|
||||||
$(expr)/exprDriver/exprDriverFields.C
|
$(expr)/exprDriver/exprDriverFields.C
|
||||||
|
$(expr)/exprDriver/exprDriverFunctions.C
|
||||||
$(expr)/exprDriver/exprDriverIO.C
|
$(expr)/exprDriver/exprDriverIO.C
|
||||||
|
|
||||||
fieldExpr = $(expr)/fields
|
fieldExpr = $(expr)/fields
|
||||||
|
|||||||
@ -98,6 +98,30 @@ static string getEntryString
|
|||||||
return exprTools::expressionEntry::evaluate(*eptr);
|
return exprTools::expressionEntry::evaluate(*eptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
static void shallowCloneFunctions
|
||||||
|
(
|
||||||
|
HashTable<refPtr<Function1<Type>>>& dest,
|
||||||
|
const HashTable<refPtr<Function1<Type>>>& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Add in shallow copy for other functions
|
||||||
|
forAllConstIters(rhs, iter)
|
||||||
|
{
|
||||||
|
const word& key = iter.key();
|
||||||
|
|
||||||
|
if (!dest.found(key))
|
||||||
|
{
|
||||||
|
refPtr<Function1<Type>> func;
|
||||||
|
func.cref(iter.val().shallowClone());
|
||||||
|
|
||||||
|
dest.emplace_set(key, std::move(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
@ -118,6 +142,23 @@ void Foam::expressions::exprDriver::resetTimeReference(const TimeState& ts)
|
|||||||
void Foam::expressions::exprDriver::resetDb(const objectRegistry* obrPtr)
|
void Foam::expressions::exprDriver::resetDb(const objectRegistry* obrPtr)
|
||||||
{
|
{
|
||||||
obrPtr_ = obrPtr;
|
obrPtr_ = obrPtr;
|
||||||
|
|
||||||
|
forAllIters(scalarFuncs_, iter)
|
||||||
|
{
|
||||||
|
auto& funcPtr = iter.val();
|
||||||
|
if (funcPtr && !funcPtr.is_const())
|
||||||
|
{
|
||||||
|
(*funcPtr).resetDb(obrPtr_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAllIters(vectorFuncs_, iter)
|
||||||
|
{
|
||||||
|
auto& funcPtr = iter.val();
|
||||||
|
if (funcPtr && !funcPtr.is_const())
|
||||||
|
{
|
||||||
|
(*funcPtr).resetDb(obrPtr_);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +180,8 @@ Foam::expressions::exprDriver::exprDriver
|
|||||||
result_(),
|
result_(),
|
||||||
variableStrings_(),
|
variableStrings_(),
|
||||||
variables_(16),
|
variables_(16),
|
||||||
|
scalarFuncs_(0),
|
||||||
|
vectorFuncs_(0),
|
||||||
arg1Value_(0),
|
arg1Value_(0),
|
||||||
timeStatePtr_(nullptr),
|
timeStatePtr_(nullptr),
|
||||||
obrPtr_(nullptr),
|
obrPtr_(nullptr),
|
||||||
@ -162,6 +205,8 @@ Foam::expressions::exprDriver::exprDriver
|
|||||||
result_(rhs.result_),
|
result_(rhs.result_),
|
||||||
variableStrings_(rhs.variableStrings_),
|
variableStrings_(rhs.variableStrings_),
|
||||||
variables_(rhs.variables_),
|
variables_(rhs.variables_),
|
||||||
|
scalarFuncs_(0),
|
||||||
|
vectorFuncs_(0),
|
||||||
arg1Value_(rhs.arg1Value_),
|
arg1Value_(rhs.arg1Value_),
|
||||||
timeStatePtr_(rhs.timeStatePtr_),
|
timeStatePtr_(rhs.timeStatePtr_),
|
||||||
obrPtr_(rhs.obrPtr_),
|
obrPtr_(rhs.obrPtr_),
|
||||||
@ -174,7 +219,16 @@ Foam::expressions::exprDriver::exprDriver
|
|||||||
prevIterIsOldTime_(rhs.prevIterIsOldTime_),
|
prevIterIsOldTime_(rhs.prevIterIsOldTime_),
|
||||||
|
|
||||||
searchCtrl_(rhs.searchCtrl_)
|
searchCtrl_(rhs.searchCtrl_)
|
||||||
{}
|
{
|
||||||
|
// Partially like readDict()
|
||||||
|
|
||||||
|
// Create Function1s from dictionary content
|
||||||
|
resetFunctions(dict_);
|
||||||
|
|
||||||
|
// Add in shallow copy for other functions
|
||||||
|
shallowCloneFunctions(scalarFuncs_, rhs.scalarFuncs_);
|
||||||
|
shallowCloneFunctions(vectorFuncs_, rhs.vectorFuncs_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::expressions::exprDriver::exprDriver
|
Foam::expressions::exprDriver::exprDriver
|
||||||
@ -246,9 +300,9 @@ bool Foam::expressions::exprDriver::readDict
|
|||||||
// Regular variables
|
// Regular variables
|
||||||
variableStrings_ = readVariableStrings(dict);
|
variableStrings_ = readVariableStrings(dict);
|
||||||
|
|
||||||
// Other tables?
|
// Create Function1s from dictionary content
|
||||||
// readTable("timelines", dict, lines_);
|
resetFunctions(dict);
|
||||||
// readTable("lookuptables", dict, lookup_);
|
|
||||||
// readTable("lookuptables2D", dict, lookup2D_);
|
// readTable("lookuptables2D", dict, lookup2D_);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -36,6 +36,8 @@ Description
|
|||||||
\table
|
\table
|
||||||
Property | Description | Required | Default
|
Property | Description | Required | Default
|
||||||
variables | List of variables for expressions | no | ()
|
variables | List of variables for expressions | no | ()
|
||||||
|
lookup\<scalar\> | Dictionary of scalar Function1 | no | {}
|
||||||
|
lookup\<vector\> | Dictionary of vector Function1 | no | {}
|
||||||
allowShadowing | Allow variables to shadow field names | no | false
|
allowShadowing | Allow variables to shadow field names | no | false
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
@ -47,10 +49,15 @@ Description
|
|||||||
debugParser | Add debug for parser | no | false
|
debugParser | Add debug for parser | no | false
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
|
The \c lookup<scalar> and \c lookup<vector> are dictionaries
|
||||||
|
of Function1 definitions that can either be used to establish
|
||||||
|
a time-varying quantity, to remap a field of scalar values, or both.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
exprDriverI.H
|
exprDriverI.H
|
||||||
exprDriver.C
|
exprDriver.C
|
||||||
exprDriverFields.C
|
exprDriverFields.C
|
||||||
|
exprDriverFunctions.C
|
||||||
exprDriverIO.C
|
exprDriverIO.C
|
||||||
exprDriverTemplates.C
|
exprDriverTemplates.C
|
||||||
|
|
||||||
@ -65,6 +72,9 @@ SourceFiles
|
|||||||
#include "pointField.H"
|
#include "pointField.H"
|
||||||
#include "primitiveFields.H"
|
#include "primitiveFields.H"
|
||||||
#include "objectRegistry.H"
|
#include "objectRegistry.H"
|
||||||
|
#include "HashTable.H"
|
||||||
|
#include "HashSet.H"
|
||||||
|
#include "Function1.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -105,6 +115,18 @@ private:
|
|||||||
//- Get search/caching controls from dictionary entries
|
//- Get search/caching controls from dictionary entries
|
||||||
static int getSearchControls(const dictionary& dict);
|
static int getSearchControls(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Read/reset Function1 entries
|
||||||
|
void resetFunctions(const dictionary& dict);
|
||||||
|
|
||||||
|
//- Helper for lookup of Function1 in table
|
||||||
|
template<class Type>
|
||||||
|
static const Function1<Type>* getFunction1Ptr
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const HashTable<refPtr<Function1<Type>>>& tbl,
|
||||||
|
wordList* listFailure = nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -124,6 +146,14 @@ protected:
|
|||||||
//- The variables table
|
//- The variables table
|
||||||
HashTable<exprResult> variables_;
|
HashTable<exprResult> variables_;
|
||||||
|
|
||||||
|
//- Function1 mappings/timelines (scalar),
|
||||||
|
//- evaluated at the simulation time or with arbitrary scalars
|
||||||
|
HashTable<refPtr<Function1<scalar>>> scalarFuncs_;
|
||||||
|
|
||||||
|
//- Function1 mappings/timelines (vector),
|
||||||
|
//- evaluated at the simulation time or with arbitrary scalars
|
||||||
|
HashTable<refPtr<Function1<vector>>> vectorFuncs_;
|
||||||
|
|
||||||
//- Special-purpose scalar reference argument
|
//- Special-purpose scalar reference argument
|
||||||
scalar arg1Value_;
|
scalar arg1Value_;
|
||||||
|
|
||||||
@ -173,24 +203,8 @@ protected:
|
|||||||
static tmp<GeoField>
|
static tmp<GeoField>
|
||||||
cfindFieldObject(const objectRegistry& obr, const word& fldName);
|
cfindFieldObject(const objectRegistry& obr, const word& fldName);
|
||||||
|
|
||||||
//- Read an interpolation table
|
//- Write scalar/vector Function1 entries in dictionary format
|
||||||
template<typename TableType>
|
void writeFunctions(Ostream& os) const;
|
||||||
static bool readTable
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const dictionary& dict,
|
|
||||||
HashTable<TableType>& tbl,
|
|
||||||
bool clear=true
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Write an interpolation table
|
|
||||||
template<class TableType>
|
|
||||||
static void writeTable
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const word& name,
|
|
||||||
const HashTable<TableType>& tbl
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
@ -444,6 +458,27 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Scalar mappings (timelines / lookups)
|
||||||
|
|
||||||
|
//- Named mapping with given type exists
|
||||||
|
template<class Type>
|
||||||
|
bool isFunction(const word& name) const;
|
||||||
|
|
||||||
|
//- Evaluate named mapping for the given time/value.
|
||||||
|
//- Zero for undefined/unknown
|
||||||
|
template<class Type>
|
||||||
|
Type getFunctionValue(const word& name, const scalar x) const;
|
||||||
|
|
||||||
|
//- Fill result with values remapped according to the named Function1
|
||||||
|
template<class Type>
|
||||||
|
void fillFunctionValues
|
||||||
|
(
|
||||||
|
Field<Type>& result,
|
||||||
|
const word& name,
|
||||||
|
const scalarField& input
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
|
|
||||||
//- Test existence of a local variable
|
//- Test existence of a local variable
|
||||||
|
|||||||
231
src/OpenFOAM/expressions/exprDriver/exprDriverFunctions.C
Normal file
231
src/OpenFOAM/expressions/exprDriver/exprDriverFunctions.C
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "exprDriver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Check for acceptable Function1 keywords in the given dictionary,
|
||||||
|
// with special handling to avoid accidental inclusion of coeffs
|
||||||
|
// dictionaries etc
|
||||||
|
static wordHashSet getAcceptableFunctionKeys
|
||||||
|
(
|
||||||
|
const dictionary* dictPtr,
|
||||||
|
const bool acceptPrimitiveEntry,
|
||||||
|
const bool report = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
wordHashSet acceptKeys(0);
|
||||||
|
|
||||||
|
if (!dictPtr)
|
||||||
|
{
|
||||||
|
return acceptKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dictionary& dict = *dictPtr;
|
||||||
|
|
||||||
|
acceptKeys.resize(2*dict.size());
|
||||||
|
wordHashSet rejectKeys(2*dict.size());
|
||||||
|
|
||||||
|
for (const entry& dEntry : dict)
|
||||||
|
{
|
||||||
|
const keyType& kw = dEntry.keyword();
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if (kw.isPattern())
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
else if (dEntry.isDict())
|
||||||
|
{
|
||||||
|
// Dictionary entry - require "type", which should eliminate
|
||||||
|
// any *Coeffs dictionaries
|
||||||
|
|
||||||
|
ok = dEntry.dict().found("type", keyType::LITERAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Primitive entry. Trust that it is okay?
|
||||||
|
ok = acceptPrimitiveEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
acceptKeys.insert(kw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rejectKeys.insert(kw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report && rejectKeys.size())
|
||||||
|
{
|
||||||
|
InfoInFunction
|
||||||
|
<< "Dropped invalid/redundant entries: "
|
||||||
|
<< flatOutput(rejectKeys.sortedToc()) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acceptKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read and reset Function1 for given dictionary.
|
||||||
|
// Uses getAcceptableFunctionKeys
|
||||||
|
template<class Type>
|
||||||
|
static void resetFuncsImpl
|
||||||
|
(
|
||||||
|
const word& subDictName,
|
||||||
|
const dictionary& topDict,
|
||||||
|
HashTable<refPtr<Function1<Type>>>& tbl,
|
||||||
|
const objectRegistry* obrPtr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tbl.clear();
|
||||||
|
|
||||||
|
const dictionary* dictPtr =
|
||||||
|
topDict.findDict(subDictName, keyType::LITERAL);
|
||||||
|
|
||||||
|
if (!dictPtr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wordHashSet acceptKeys
|
||||||
|
(
|
||||||
|
getAcceptableFunctionKeys
|
||||||
|
(
|
||||||
|
dictPtr,
|
||||||
|
true // Accept primitive entries, hope for the best
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const dictionary& dict = *dictPtr;
|
||||||
|
|
||||||
|
for (const word& entryName : acceptKeys)
|
||||||
|
{
|
||||||
|
// From autoPtr -> refPtr
|
||||||
|
refPtr<Function1<Type>> func
|
||||||
|
(
|
||||||
|
Function1<Type>::New(entryName, dict, obrPtr)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
tbl.insert(entryName, std::move(func));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write out entries, if they originated from dictionary
|
||||||
|
template<class Type>
|
||||||
|
static void writeFuncsImpl
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const word& subDictName,
|
||||||
|
const dictionary& topDict,
|
||||||
|
const HashTable<refPtr<Function1<Type>>>& tbl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const dictionary* dictPtr =
|
||||||
|
topDict.findDict(subDictName, keyType::LITERAL);
|
||||||
|
|
||||||
|
if (!dictPtr || tbl.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
label nwrote = 0;
|
||||||
|
|
||||||
|
const dictionary& dict = *dictPtr;
|
||||||
|
|
||||||
|
for (const entry& dEntry : dict)
|
||||||
|
{
|
||||||
|
const word& entryName = dEntry.keyword();
|
||||||
|
|
||||||
|
const auto iter = tbl.cfind(entryName);
|
||||||
|
|
||||||
|
if (!iter.found())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& funcPtr = iter.val();
|
||||||
|
|
||||||
|
if (funcPtr)
|
||||||
|
{
|
||||||
|
if (!nwrote++)
|
||||||
|
{
|
||||||
|
os.beginBlock(subDictName);
|
||||||
|
}
|
||||||
|
|
||||||
|
os.beginBlock(entryName);
|
||||||
|
os.writeEntry("type", (*funcPtr).type());
|
||||||
|
(*funcPtr).writeEntries(os);
|
||||||
|
os.endBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nwrote)
|
||||||
|
{
|
||||||
|
os.endBlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::expressions::exprDriver::resetFunctions
|
||||||
|
(
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
resetFuncsImpl<scalar>("functions<scalar>", dict_, scalarFuncs_, obrPtr_);
|
||||||
|
resetFuncsImpl<vector>("functions<vector>", dict_, vectorFuncs_, obrPtr_);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
writeFunctions(InfoInFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::expressions::exprDriver::writeFunctions(Ostream& os) const
|
||||||
|
{
|
||||||
|
writeFuncsImpl<scalar>(os, "functions<scalar>", dict_, scalarFuncs_);
|
||||||
|
writeFuncsImpl<vector>(os, "functions<vector>", dict_, vectorFuncs_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -46,63 +46,6 @@ Foam::expressions::exprDriver::cfindFieldObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TableType>
|
|
||||||
bool Foam::expressions::exprDriver::readTable
|
|
||||||
(
|
|
||||||
const word& name,
|
|
||||||
const dictionary& dict,
|
|
||||||
HashTable<TableType>& tbl,
|
|
||||||
bool clear
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (clear)
|
|
||||||
{
|
|
||||||
tbl.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dict.found(name))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ITstream& is = dict.lookup(name);
|
|
||||||
List<dictionary> input(is);
|
|
||||||
|
|
||||||
for (const dictionary& d : input)
|
|
||||||
{
|
|
||||||
tbl.insert(dict.get<word>("name"), TableType(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class TableType>
|
|
||||||
void Foam::expressions::exprDriver::writeTable
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const word& name,
|
|
||||||
const HashTable<TableType>& tbl
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (tbl.size())
|
|
||||||
{
|
|
||||||
os.writeKeyword(name);
|
|
||||||
os << token::BEGIN_LIST << nl;
|
|
||||||
|
|
||||||
forAllConstIters(tbl, iter)
|
|
||||||
{
|
|
||||||
os.beginBlock();
|
|
||||||
os.writeEntry("name", iter.key());
|
|
||||||
(*iter).write(os);
|
|
||||||
os.endBlock();
|
|
||||||
}
|
|
||||||
os << token::END_LIST
|
|
||||||
<< token::END_STATEMENT << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
@ -180,6 +123,181 @@ Foam::expressions::exprDriver::getResult(bool wantPointData)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const Foam::Function1<Type>* Foam::expressions::exprDriver::getFunction1Ptr
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const HashTable<refPtr<Function1<Type>>>& tbl,
|
||||||
|
wordList* listFailure
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const Function1<Type>* func = nullptr;
|
||||||
|
|
||||||
|
const auto iter = tbl.cfind(name);
|
||||||
|
|
||||||
|
if (iter.found())
|
||||||
|
{
|
||||||
|
func = iter.val().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!func && listFailure)
|
||||||
|
{
|
||||||
|
*listFailure = tbl.sortedToc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::expressions::exprDriver::isFunction(const word& name) const
|
||||||
|
{
|
||||||
|
// Currently only scalar, vector
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(WhichType, MapperMember) \
|
||||||
|
if (std::is_same<Type, WhichType>::value) \
|
||||||
|
{ \
|
||||||
|
return bool \
|
||||||
|
( \
|
||||||
|
this->template getFunction1Ptr<WhichType> \
|
||||||
|
( \
|
||||||
|
name, MapperMember \
|
||||||
|
) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(scalar, scalarFuncs_);
|
||||||
|
doLocalCode(vector, vectorFuncs_);
|
||||||
|
#undef doLocalCode
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Type Foam::expressions::exprDriver::getFunctionValue
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const scalar x
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const Function1<Type>* func = nullptr;
|
||||||
|
|
||||||
|
wordList failed;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Currently only scalar, vector
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(WhichType, MapperMember) \
|
||||||
|
if (std::is_same<Type, WhichType>::value) \
|
||||||
|
{ \
|
||||||
|
const Function1<WhichType>* ptr = \
|
||||||
|
this->template getFunction1Ptr<WhichType> \
|
||||||
|
( \
|
||||||
|
name, MapperMember, &failed \
|
||||||
|
); \
|
||||||
|
func = reinterpret_cast<const Function1<Type>*>(ptr); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(scalar, scalarFuncs_);
|
||||||
|
doLocalCode(vector, vectorFuncs_);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
if (!failed.empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No mapping '" << name << " (" << pTraits<Type>::typeName
|
||||||
|
<< ") found." << nl
|
||||||
|
<< "Valid entries: "
|
||||||
|
<< flatOutput(failed) << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
return func->value(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTraits<Type>::zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::expressions::exprDriver::fillFunctionValues
|
||||||
|
(
|
||||||
|
Field<Type>& result,
|
||||||
|
const word& name,
|
||||||
|
const scalarField& input
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// #ifdef FULLDEBUG
|
||||||
|
// checkSize(result, input);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
const Function1<Type>* func = nullptr;
|
||||||
|
|
||||||
|
wordList failed;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Currently only scalar, vector
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(WhichType, MapperMember) \
|
||||||
|
if (std::is_same<Type, WhichType>::value) \
|
||||||
|
{ \
|
||||||
|
const Function1<WhichType>* ptr = \
|
||||||
|
this->template getFunction1Ptr<WhichType> \
|
||||||
|
( \
|
||||||
|
name, MapperMember, &failed \
|
||||||
|
); \
|
||||||
|
func = reinterpret_cast<const Function1<Type>*>(ptr); \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(scalar, scalarFuncs_);
|
||||||
|
doLocalCode(vector, vectorFuncs_);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
if (!failed.empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No mapping '" << name << " (" << pTraits<Type>::typeName
|
||||||
|
<< ") found." << nl
|
||||||
|
<< "Valid entries: "
|
||||||
|
<< flatOutput(failed) << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
const label len = min(result.size(), input.size());
|
||||||
|
|
||||||
|
for (label i = 0; i < len; ++i)
|
||||||
|
{
|
||||||
|
result[i] = func->value(input[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety
|
||||||
|
for (label i = len; i < result.size(); ++i)
|
||||||
|
{
|
||||||
|
result[i] = Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
bool Foam::expressions::exprDriver::isLocalVariable
|
bool Foam::expressions::exprDriver::isLocalVariable
|
||||||
(
|
(
|
||||||
|
|||||||
@ -178,7 +178,7 @@ Foam::exprTools::getList
|
|||||||
FatalIOErrorInFunction(dict)
|
FatalIOErrorInFunction(dict)
|
||||||
<< " Entry '"<< keyword
|
<< " Entry '"<< keyword
|
||||||
<< "' not a string or list of strings" << nl
|
<< "' not a string or list of strings" << nl
|
||||||
<< exit(FatalError);
|
<< exit(FatalIOError);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -156,8 +156,7 @@ public:
|
|||||||
|
|
||||||
//- Return named field (variable) if available
|
//- Return named field (variable) if available
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>>
|
tmp<Field<Type>> getField(const word& fieldName) const;
|
||||||
getField(const word& fieldName) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Custom Field Functions
|
// Custom Field Functions
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
|
|||||||
@ -173,8 +173,11 @@ svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
|||||||
|
|
||||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
lhs = driver->getFunctionValue<Foam::scalar>
|
||||||
lhs = 0;
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -193,8 +196,12 @@ vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
|||||||
|
|
||||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
auto val = driver->getFunctionValue<Foam::vector>
|
||||||
lhs = new Foam::vector(0,0,0);
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
|
lhs = new Foam::vector(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -253,8 +260,12 @@ _target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN.
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,8 +294,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -219,12 +219,16 @@ static int driverTokenType
|
|||||||
|
|
||||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||||
dquoted = '"' [^\"]+ '"' ;
|
dquoted = '"' [^\"]+ '"' ;
|
||||||
squoted = "'" [^\']+ "'" ;
|
squoted = "'" [^\']+ "'" ;
|
||||||
|
|
||||||
|
## Allow 'fn:' prefix for function identifier
|
||||||
|
ident = ('fn:')? identifier ;
|
||||||
|
|
||||||
|
## ===========
|
||||||
## The scanner
|
## The scanner
|
||||||
|
## ===========
|
||||||
main := |*
|
main := |*
|
||||||
space*;
|
space*;
|
||||||
|
|
||||||
@ -431,6 +435,22 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(TokType, Type) \
|
||||||
|
if (driver_.isFunction<Type>(funcName)) \
|
||||||
|
{ \
|
||||||
|
ident = std::move(funcName); \
|
||||||
|
tokType = TokType; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOK_SCALAR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_SCALAR_FUNCTION_ID, scalar);
|
||||||
|
#endif
|
||||||
|
#ifdef TOK_VECTOR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_VECTOR_FUNCTION_ID, vector);
|
||||||
|
#endif
|
||||||
|
#undef doLocalCode
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -251,9 +251,8 @@ Foam::Ostream& Foam::expressions::fvExprDriver::writeCommon
|
|||||||
os.writeEntry("globalScopes", globalScopes_);
|
os.writeEntry("globalScopes", globalScopes_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeTable(os, "timelines", lines_);
|
// Write "functions<scalar>" ...
|
||||||
// writeTable(os, "lookuptables", lookup_);
|
writeFunctions(os);
|
||||||
// writeTable(os, "lookuptables2D", lookup2D_);
|
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,8 +139,11 @@ svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
|||||||
|
|
||||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
lhs = driver->getFunctionValue<Foam::scalar>
|
||||||
lhs = 0;
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
@ -158,8 +161,12 @@ vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
|||||||
|
|
||||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
auto val = driver->getFunctionValue<Foam::vector>
|
||||||
lhs = new Foam::vector(0,0,0);
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
|
lhs = new Foam::vector(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,8 +228,12 @@ _target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN.
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -253,8 +264,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -397,8 +412,12 @@ rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -425,8 +444,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -352,12 +352,16 @@ static int driverTokenType
|
|||||||
|
|
||||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||||
dquoted = '"' [^\"]+ '"' ;
|
dquoted = '"' [^\"]+ '"' ;
|
||||||
squoted = "'" [^\']+ "'" ;
|
squoted = "'" [^\']+ "'" ;
|
||||||
|
|
||||||
|
## Allow 'fn:' prefix for function identifier
|
||||||
|
ident = ('fn:')? identifier ;
|
||||||
|
|
||||||
|
## ===========
|
||||||
## The scanner
|
## The scanner
|
||||||
|
## ===========
|
||||||
main := |*
|
main := |*
|
||||||
space*;
|
space*;
|
||||||
|
|
||||||
@ -571,6 +575,22 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(TokType, Type) \
|
||||||
|
if (driver_.isFunction<Type>(funcName)) \
|
||||||
|
{ \
|
||||||
|
ident = std::move(funcName); \
|
||||||
|
tokType = TokType; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOK_SCALAR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_SCALAR_FUNCTION_ID, scalar);
|
||||||
|
#endif
|
||||||
|
#ifdef TOK_VECTOR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_VECTOR_FUNCTION_ID, vector);
|
||||||
|
#endif
|
||||||
|
#undef doLocalCode
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -180,8 +180,11 @@ svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
|||||||
|
|
||||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
lhs = driver->getFunctionValue<Foam::scalar>
|
||||||
lhs = 0;
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -200,8 +203,12 @@ vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
|||||||
|
|
||||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||||
{
|
{
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
auto val = driver->getFunctionValue<Foam::vector>
|
||||||
lhs = new Foam::vector(0,0,0);
|
(
|
||||||
|
make_obj(name.name_),
|
||||||
|
driver->timeValue()
|
||||||
|
);
|
||||||
|
lhs = new Foam::vector(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -261,8 +268,12 @@ _target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN .
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -291,8 +302,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -420,8 +435,12 @@ rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<_value_typ
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -448,8 +467,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -584,8 +607,12 @@ rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<_value_typ
|
|||||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -659,8 +686,12 @@ rules_vector_functions()
|
|||||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||||
{
|
{
|
||||||
lhs = _new_target_;
|
lhs = _new_target_;
|
||||||
(void) make_obj(values);
|
driver->fillFunctionValues<_value_type_>
|
||||||
driver->reportFatal("Not implemented: " + make_obj(name.name_));
|
(
|
||||||
|
*lhs,
|
||||||
|
make_obj(name.name_),
|
||||||
|
make_obj(values)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -371,12 +371,16 @@ static int driverTokenType
|
|||||||
|
|
||||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||||
dquoted = '"' [^\"]+ '"' ;
|
dquoted = '"' [^\"]+ '"' ;
|
||||||
squoted = "'" [^\']+ "'" ;
|
squoted = "'" [^\']+ "'" ;
|
||||||
|
|
||||||
|
## Allow 'fn:' prefix for function identifier
|
||||||
|
ident = ('fn:')? identifier ;
|
||||||
|
|
||||||
|
## ===========
|
||||||
## The scanner
|
## The scanner
|
||||||
|
## ===========
|
||||||
main := |*
|
main := |*
|
||||||
space*;
|
space*;
|
||||||
|
|
||||||
@ -585,6 +589,22 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(TokType, Type) \
|
||||||
|
if (driver_.isFunction<Type>(funcName)) \
|
||||||
|
{ \
|
||||||
|
ident = std::move(funcName); \
|
||||||
|
tokType = TokType; \
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOK_SCALAR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_SCALAR_FUNCTION_ID, scalar);
|
||||||
|
#endif
|
||||||
|
#ifdef TOK_VECTOR_FUNCTION_ID
|
||||||
|
doLocalCode(TOK_VECTOR_FUNCTION_ID, vector);
|
||||||
|
#endif
|
||||||
|
#undef doLocalCode
|
||||||
}
|
}
|
||||||
while (false);
|
while (false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user