mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-expr-improvements' into 'develop'
Updates for expressions to improve robustness and support functions, external context etc. See merge request Development/openfoam!501
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2106 |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ 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()
|
||||
#};
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -21,6 +21,7 @@ Description
|
||||
#include "uLabel.H"
|
||||
#include "error.H"
|
||||
#include "stringList.H"
|
||||
#include "exprScanToken.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
@ -71,6 +72,34 @@ int main()
|
||||
<< getName(expressions::valueTypeCode::type_bool) << nl;
|
||||
|
||||
|
||||
{
|
||||
expressions::scanToken tok;
|
||||
expressions::scanToken tok2;
|
||||
|
||||
Info<< nl << "sizeof(scanToken): "
|
||||
<< sizeof(tok) << nl;
|
||||
|
||||
Info<< " type:" << int(tok.type_) << nl;
|
||||
Info<< " ptr:" << Foam::name(tok.name_) << nl;
|
||||
|
||||
Info<< " type:" << int(tok2.type_) << nl;
|
||||
Info<< " ptr:" << Foam::name(tok2.name_) << nl;
|
||||
|
||||
tok.setWord("hello");
|
||||
|
||||
Info<< " type:" << int(tok.type_) << nl;
|
||||
Info<< " ptr:" << Foam::name(tok.name_) << nl;
|
||||
|
||||
tok2 = tok;
|
||||
Info<< " type:" << int(tok2.type_) << nl;
|
||||
Info<< " ptr:" << Foam::name(tok2.name_) << nl;
|
||||
|
||||
tok2.destroy();
|
||||
|
||||
Info<< " type:" << int(tok2.type_) << nl;
|
||||
Info<< " ptr:" << Foam::name(tok2.name_) << nl;
|
||||
}
|
||||
|
||||
Info<< nl << "Done" << nl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -162,11 +162,13 @@ $(expr)/exprResult/exprResultStored.C
|
||||
$(expr)/exprResult/exprResultStoredStack.C
|
||||
$(expr)/exprString/exprString.C
|
||||
$(expr)/exprTools/exprTools.C
|
||||
$(expr)/scanToken/exprScanToken.C
|
||||
|
||||
$(expr)/traits/exprTraits.C
|
||||
|
||||
$(expr)/exprDriver/exprDriver.C
|
||||
$(expr)/exprDriver/exprDriverFields.C
|
||||
$(expr)/exprDriver/exprDriverFunctions.C
|
||||
$(expr)/exprDriver/exprDriverIO.C
|
||||
|
||||
fieldExpr = $(expr)/fields
|
||||
|
||||
@ -98,6 +98,30 @@ static string getEntryString
|
||||
return exprTools::expressionEntry::evaluate(*eptr);
|
||||
}
|
||||
#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
|
||||
|
||||
|
||||
@ -118,6 +142,23 @@ void Foam::expressions::exprDriver::resetTimeReference(const TimeState& ts)
|
||||
void Foam::expressions::exprDriver::resetDb(const objectRegistry* 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,9 @@ Foam::expressions::exprDriver::exprDriver
|
||||
result_(),
|
||||
variableStrings_(),
|
||||
variables_(16),
|
||||
scalarFuncs_(0),
|
||||
vectorFuncs_(0),
|
||||
contextObjects_(0),
|
||||
arg1Value_(0),
|
||||
timeStatePtr_(nullptr),
|
||||
obrPtr_(nullptr),
|
||||
@ -162,6 +206,9 @@ Foam::expressions::exprDriver::exprDriver
|
||||
result_(rhs.result_),
|
||||
variableStrings_(rhs.variableStrings_),
|
||||
variables_(rhs.variables_),
|
||||
scalarFuncs_(0),
|
||||
vectorFuncs_(0),
|
||||
contextObjects_(rhs.contextObjects_),
|
||||
arg1Value_(rhs.arg1Value_),
|
||||
timeStatePtr_(rhs.timeStatePtr_),
|
||||
obrPtr_(rhs.obrPtr_),
|
||||
@ -174,7 +221,16 @@ Foam::expressions::exprDriver::exprDriver
|
||||
prevIterIsOldTime_(rhs.prevIterIsOldTime_),
|
||||
|
||||
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
|
||||
@ -246,9 +302,9 @@ bool Foam::expressions::exprDriver::readDict
|
||||
// Regular variables
|
||||
variableStrings_ = readVariableStrings(dict);
|
||||
|
||||
// Other tables?
|
||||
// readTable("timelines", dict, lines_);
|
||||
// readTable("lookuptables", dict, lookup_);
|
||||
// Create Function1s from dictionary content
|
||||
resetFunctions(dict);
|
||||
|
||||
// readTable("lookuptables2D", dict, lookup2D_);
|
||||
|
||||
return true;
|
||||
|
||||
@ -36,6 +36,8 @@ Description
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
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
|
||||
\endtable
|
||||
|
||||
@ -47,10 +49,16 @@ Description
|
||||
debugParser | Add debug for parser | no | false
|
||||
\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
|
||||
exprDriverI.H
|
||||
exprDriverContextI.H
|
||||
exprDriver.C
|
||||
exprDriverFields.C
|
||||
exprDriverFunctions.C
|
||||
exprDriverIO.C
|
||||
exprDriverTemplates.C
|
||||
|
||||
@ -65,6 +73,9 @@ SourceFiles
|
||||
#include "pointField.H"
|
||||
#include "primitiveFields.H"
|
||||
#include "objectRegistry.H"
|
||||
#include "HashTable.H"
|
||||
#include "HashSet.H"
|
||||
#include "Function1.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -98,6 +109,10 @@ public:
|
||||
};
|
||||
|
||||
|
||||
//- Externally defined context fields
|
||||
typedef HashTable<const regIOobject*> contextObjectTableType;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private Member Functions
|
||||
@ -105,6 +120,18 @@ private:
|
||||
//- Get search/caching controls from dictionary entries
|
||||
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:
|
||||
|
||||
@ -124,6 +151,17 @@ protected:
|
||||
//- The variables table
|
||||
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_;
|
||||
|
||||
//- Externally defined context fields
|
||||
contextObjectTableType contextObjects_;
|
||||
|
||||
//- Special-purpose scalar reference argument
|
||||
scalar arg1Value_;
|
||||
|
||||
@ -167,30 +205,8 @@ protected:
|
||||
//- Reset the time-state reference
|
||||
void resetTimeReference(const TimeState& ts);
|
||||
|
||||
//- Lookup field object.
|
||||
// \return const-ref tmp or invalid if not found
|
||||
template<class GeoField>
|
||||
static tmp<GeoField>
|
||||
cfindFieldObject(const objectRegistry& obr, const word& fldName);
|
||||
|
||||
//- Read an interpolation table
|
||||
template<typename TableType>
|
||||
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
|
||||
);
|
||||
//- Write scalar/vector Function1 entries in dictionary format
|
||||
void writeFunctions(Ostream& os) const;
|
||||
|
||||
|
||||
// Variables
|
||||
@ -444,6 +460,59 @@ public:
|
||||
);
|
||||
|
||||
|
||||
// Context fields (similar to objectRegistry)
|
||||
|
||||
//- True if any context fields are defined
|
||||
inline bool hasContextObjects() const;
|
||||
|
||||
//- Find named context field, if it exists
|
||||
inline const regIOobject* cfindContextIOobject(const word& name) const;
|
||||
|
||||
//- Find context field object of specified type
|
||||
// \return nullptr if not found
|
||||
template<class ObjType>
|
||||
const ObjType* cfindContextObject(const word& name) const;
|
||||
|
||||
//- Add the object to the context
|
||||
inline void addContextObject(const word& name, const regIOobject*);
|
||||
|
||||
//- Add the object to the context
|
||||
inline void addContextObject(const regIOobject*);
|
||||
|
||||
//- Remove the object from the context
|
||||
inline void removeContextObject(const word& name);
|
||||
|
||||
//- Remove the object from the context
|
||||
inline void removeContextObject(const regIOobject*);
|
||||
|
||||
//- Read access to the object context
|
||||
inline const contextObjectTableType& contextObjects() const noexcept;
|
||||
|
||||
//- Write access to the object context
|
||||
inline contextObjectTableType& contextObjects() noexcept;
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
//- Test existence of a local variable
|
||||
@ -585,6 +654,7 @@ public:
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "exprDriverI.H"
|
||||
#include "exprDriverContextI.H"
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "exprDriverTemplates.C"
|
||||
|
||||
120
src/OpenFOAM/expressions/exprDriver/exprDriverContextI.H
Normal file
120
src/OpenFOAM/expressions/exprDriver/exprDriverContextI.H
Normal file
@ -0,0 +1,120 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::expressions::exprDriver::hasContextObjects() const
|
||||
{
|
||||
return !contextObjects_.empty();
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::regIOobject*
|
||||
Foam::expressions::exprDriver::cfindContextIOobject
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
// Like objectRegistry::cfindIOobject()
|
||||
return contextObjects_.lookup(name, nullptr);
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::expressions::exprDriver::addContextObject
|
||||
(
|
||||
const word& name,
|
||||
const regIOobject* objptr
|
||||
)
|
||||
{
|
||||
if (objptr)
|
||||
{
|
||||
contextObjects_.set(name, objptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
contextObjects_.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::expressions::exprDriver::addContextObject
|
||||
(
|
||||
const regIOobject* objptr
|
||||
)
|
||||
{
|
||||
if (objptr)
|
||||
{
|
||||
addContextObject(objptr->name(), objptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::expressions::exprDriver::removeContextObject
|
||||
(
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
contextObjects_.erase(name);
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::expressions::exprDriver::removeContextObject
|
||||
(
|
||||
const regIOobject* objptr
|
||||
)
|
||||
{
|
||||
if (objptr)
|
||||
{
|
||||
contextObjects_.erase(objptr->name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::HashTable<const Foam::regIOobject*>&
|
||||
Foam::expressions::exprDriver::contextObjects() const noexcept
|
||||
{
|
||||
return contextObjects_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::HashTable<const Foam::regIOobject*>&
|
||||
Foam::expressions::exprDriver::contextObjects() noexcept
|
||||
{
|
||||
return contextObjects_;
|
||||
}
|
||||
|
||||
|
||||
template<class ObjType>
|
||||
const ObjType*
|
||||
Foam::expressions::exprDriver::cfindContextObject(const word& name) const
|
||||
{
|
||||
// Like objectRegistry::cfindObject()
|
||||
return dynamic_cast<const ObjType*>(this->cfindContextIOobject(name));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
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_);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -28,81 +28,6 @@ License
|
||||
|
||||
#include "objectRegistry.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::expressions::exprDriver::cfindFieldObject
|
||||
(
|
||||
const objectRegistry& obr,
|
||||
const word& fldName
|
||||
)
|
||||
{
|
||||
tmp<GeoField> tfld;
|
||||
|
||||
tfld.cref(obr.cfindObject<GeoField>(fldName));
|
||||
|
||||
return tfld;
|
||||
}
|
||||
|
||||
|
||||
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 * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
@ -180,6 +105,181 @@ Foam::expressions::exprDriver::getResult(bool wantPointData)
|
||||
|
||||
// * * * * * * * * * * * * * * * 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>
|
||||
bool Foam::expressions::exprDriver::isLocalVariable
|
||||
(
|
||||
|
||||
@ -178,7 +178,7 @@ Foam::exprTools::getList
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< " Entry '"<< keyword
|
||||
<< "' not a string or list of strings" << nl
|
||||
<< exit(FatalError);
|
||||
<< exit(FatalIOError);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -156,8 +156,7 @@ public:
|
||||
|
||||
//- Return named field (variable) if available
|
||||
template<class Type>
|
||||
tmp<Field<Type>>
|
||||
getField(const word& fieldName) const;
|
||||
tmp<Field<Type>> getField(const word& fieldName) const;
|
||||
|
||||
|
||||
// Custom Field Functions
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,7 +47,6 @@ namespace fieldExpr
|
||||
class parser;
|
||||
class scanner;
|
||||
class parseDriver;
|
||||
union scanToken;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
@ -1,93 +1,99 @@
|
||||
#define TOK_QUESTION 1
|
||||
#define TOK_COLON 2
|
||||
#define TOK_LOR 3
|
||||
#define TOK_LAND 4
|
||||
#define TOK_BIT_XOR 5
|
||||
#define TOK_BIT_AND 6
|
||||
#define TOK_EQUAL 7
|
||||
#define TOK_NOT_EQUAL 8
|
||||
#define TOK_LESS_EQ 9
|
||||
#define TOK_GREATER_EQ 10
|
||||
#define TOK_LESS 11
|
||||
#define TOK_GREATER 12
|
||||
#define TOK_PLUS 13
|
||||
#define TOK_MINUS 14
|
||||
#define TOK_TIMES 15
|
||||
#define TOK_DIVIDE 16
|
||||
#define TOK_PERCENT 17
|
||||
#define TOK_NEGATE 18
|
||||
#define TOK_NOT 19
|
||||
#define TOK_DOT 20
|
||||
#define TOK_NUMBER 21
|
||||
#define TOK_ZERO 22
|
||||
#define TOK_PI 23
|
||||
#define TOK_LPAREN 24
|
||||
#define TOK_RPAREN 25
|
||||
#define TOK_DEG_TO_RAD 26
|
||||
#define TOK_RAD_TO_DEG 27
|
||||
#define TOK_ARG 28
|
||||
#define TOK_TIME 29
|
||||
#define TOK_DELTA_T 30
|
||||
#define TOK_SCALAR_ID 31
|
||||
#define TOK_MIN 32
|
||||
#define TOK_COMMA 33
|
||||
#define TOK_MAX 34
|
||||
#define TOK_SUM 35
|
||||
#define TOK_AVERAGE 36
|
||||
#define TOK_EXP 37
|
||||
#define TOK_LOG 38
|
||||
#define TOK_LOG10 39
|
||||
#define TOK_SQR 40
|
||||
#define TOK_SQRT 41
|
||||
#define TOK_CBRT 42
|
||||
#define TOK_SIN 43
|
||||
#define TOK_COS 44
|
||||
#define TOK_TAN 45
|
||||
#define TOK_ASIN 46
|
||||
#define TOK_ACOS 47
|
||||
#define TOK_ATAN 48
|
||||
#define TOK_SINH 49
|
||||
#define TOK_COSH 50
|
||||
#define TOK_TANH 51
|
||||
#define TOK_POW 52
|
||||
#define TOK_ATAN2 53
|
||||
#define TOK_POS 54
|
||||
#define TOK_NEG 55
|
||||
#define TOK_POS0 56
|
||||
#define TOK_NEG0 57
|
||||
#define TOK_SIGN 58
|
||||
#define TOK_FLOOR 59
|
||||
#define TOK_CEIL 60
|
||||
#define TOK_ROUND 61
|
||||
#define TOK_HYPOT 62
|
||||
#define TOK_RAND 63
|
||||
#define TOK_VECTOR_ID 64
|
||||
#define TOK_SPH_TENSOR_ID 65
|
||||
#define TOK_SYM_TENSOR_ID 66
|
||||
#define TOK_IDENTITY_TENSOR 67
|
||||
#define TOK_TENSOR_ID 68
|
||||
#define TOK_LTRUE 69
|
||||
#define TOK_LFALSE 70
|
||||
#define TOK_BOOL 71
|
||||
#define TOK_BOOL_ID 72
|
||||
#define TOK_MAG 73
|
||||
#define TOK_MAGSQR 74
|
||||
#define TOK_VECTOR 75
|
||||
#define TOK_TENSOR 76
|
||||
#define TOK_SYM_TENSOR 77
|
||||
#define TOK_SPH_TENSOR 78
|
||||
#define TOK_CMPT_X 79
|
||||
#define TOK_CMPT_Y 80
|
||||
#define TOK_CMPT_Z 81
|
||||
#define TOK_CMPT_XX 82
|
||||
#define TOK_CMPT_XY 83
|
||||
#define TOK_CMPT_XZ 84
|
||||
#define TOK_CMPT_YX 85
|
||||
#define TOK_CMPT_YY 86
|
||||
#define TOK_CMPT_YZ 87
|
||||
#define TOK_CMPT_ZX 88
|
||||
#define TOK_CMPT_ZY 89
|
||||
#define TOK_CMPT_ZZ 90
|
||||
#define TOK_CMPT_II 91
|
||||
#define TOK_TRANSPOSE 92
|
||||
#define TOK_DIAG 93
|
||||
#define TOK_LPAREN 1
|
||||
#define TOK_RPAREN 2
|
||||
#define TOK_COMMA 3
|
||||
#define TOK_QUESTION 4
|
||||
#define TOK_COLON 5
|
||||
#define TOK_LOR 6
|
||||
#define TOK_LAND 7
|
||||
#define TOK_LNOT 8
|
||||
#define TOK_BIT_OR 9
|
||||
#define TOK_BIT_XOR 10
|
||||
#define TOK_BIT_AND 11
|
||||
#define TOK_BIT_NOT 12
|
||||
#define TOK_EQUAL 13
|
||||
#define TOK_NOT_EQUAL 14
|
||||
#define TOK_LESS 15
|
||||
#define TOK_LESS_EQ 16
|
||||
#define TOK_GREATER 17
|
||||
#define TOK_GREATER_EQ 18
|
||||
#define TOK_PLUS 19
|
||||
#define TOK_MINUS 20
|
||||
#define TOK_TIMES 21
|
||||
#define TOK_DIVIDE 22
|
||||
#define TOK_PERCENT 23
|
||||
#define TOK_NEGATE 24
|
||||
#define TOK_DOT 25
|
||||
#define TOK_BOOL 26
|
||||
#define TOK_LTRUE 27
|
||||
#define TOK_LFALSE 28
|
||||
#define TOK_NUMBER 29
|
||||
#define TOK_ZERO 30
|
||||
#define TOK_IDENTIFIER 31
|
||||
#define TOK_PI 32
|
||||
#define TOK_DEG_TO_RAD 33
|
||||
#define TOK_RAD_TO_DEG 34
|
||||
#define TOK_ARG 35
|
||||
#define TOK_TIME 36
|
||||
#define TOK_DELTA_T 37
|
||||
#define TOK_SCALAR_FUNCTION_ID 38
|
||||
#define TOK_VECTOR_VALUE 39
|
||||
#define TOK_VECTOR_FUNCTION_ID 40
|
||||
#define TOK_SCALAR_ID 41
|
||||
#define TOK_MIN 42
|
||||
#define TOK_MAX 43
|
||||
#define TOK_SUM 44
|
||||
#define TOK_AVERAGE 45
|
||||
#define TOK_EXP 46
|
||||
#define TOK_LOG 47
|
||||
#define TOK_LOG10 48
|
||||
#define TOK_SQR 49
|
||||
#define TOK_SQRT 50
|
||||
#define TOK_CBRT 51
|
||||
#define TOK_SIN 52
|
||||
#define TOK_COS 53
|
||||
#define TOK_TAN 54
|
||||
#define TOK_ASIN 55
|
||||
#define TOK_ACOS 56
|
||||
#define TOK_ATAN 57
|
||||
#define TOK_SINH 58
|
||||
#define TOK_COSH 59
|
||||
#define TOK_TANH 60
|
||||
#define TOK_POW 61
|
||||
#define TOK_ATAN2 62
|
||||
#define TOK_POS 63
|
||||
#define TOK_NEG 64
|
||||
#define TOK_POS0 65
|
||||
#define TOK_NEG0 66
|
||||
#define TOK_SIGN 67
|
||||
#define TOK_FLOOR 68
|
||||
#define TOK_CEIL 69
|
||||
#define TOK_ROUND 70
|
||||
#define TOK_HYPOT 71
|
||||
#define TOK_RAND 72
|
||||
#define TOK_VECTOR_ID 73
|
||||
#define TOK_SPH_TENSOR_ID 74
|
||||
#define TOK_SYM_TENSOR_ID 75
|
||||
#define TOK_IDENTITY_TENSOR 76
|
||||
#define TOK_TENSOR_ID 77
|
||||
#define TOK_BOOL_ID 78
|
||||
#define TOK_MAG 79
|
||||
#define TOK_MAGSQR 80
|
||||
#define TOK_VECTOR 81
|
||||
#define TOK_TENSOR 82
|
||||
#define TOK_SYM_TENSOR 83
|
||||
#define TOK_SPH_TENSOR 84
|
||||
#define TOK_CMPT_X 85
|
||||
#define TOK_CMPT_Y 86
|
||||
#define TOK_CMPT_Z 87
|
||||
#define TOK_CMPT_XX 88
|
||||
#define TOK_CMPT_XY 89
|
||||
#define TOK_CMPT_XZ 90
|
||||
#define TOK_CMPT_YX 91
|
||||
#define TOK_CMPT_YY 92
|
||||
#define TOK_CMPT_YZ 93
|
||||
#define TOK_CMPT_ZX 94
|
||||
#define TOK_CMPT_ZY 95
|
||||
#define TOK_CMPT_ZZ 96
|
||||
#define TOK_CMPT_II 97
|
||||
#define TOK_TRANSPOSE 98
|
||||
#define TOK_DIAG 99
|
||||
|
||||
@ -98,6 +98,7 @@ TBD
|
||||
*/
|
||||
%include
|
||||
{
|
||||
#include "exprScanToken.H"
|
||||
#include "fieldExprDriver.H"
|
||||
#include "fieldExprParser.H"
|
||||
#include "fieldExprScanner.H"
|
||||
@ -131,11 +132,8 @@ tmp_management()
|
||||
%token_prefix TOK_
|
||||
|
||||
// Terminals
|
||||
%token_type {Foam::expressions::fieldExpr::scanToken*}
|
||||
// Non-terminals
|
||||
%type ivalue { Foam::label }
|
||||
%type svalue { Foam::scalar }
|
||||
%type ident { Foam::word* }
|
||||
%token_type {Foam::expressions::scanToken}
|
||||
%token_destructor { ($$).destroy(); }
|
||||
|
||||
// Fields
|
||||
declare_field(lfield, Foam::boolField, bool, newField, getField)
|
||||
@ -150,6 +148,7 @@ declare_field(tfield, Foam::tensorField, Foam::tensor, newField, getField)
|
||||
// Lemon does not generate a destructor for that.
|
||||
// So do not use Lemon destructors for anything.
|
||||
|
||||
standard_tokens()
|
||||
operator_precedence()
|
||||
|
||||
%start_symbol evaluate
|
||||
@ -160,7 +159,10 @@ operator_precedence()
|
||||
* Productions (scalar)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
svalue (lhs) ::= NUMBER (a) . { lhs = (a)->svalue; } // From scanToken
|
||||
%type svalue { Foam::scalar }
|
||||
|
||||
svalue (lhs) ::= NUMBER (tok) . { lhs = (tok).scalarValue; } // scanToken
|
||||
|
||||
svalue (lhs) ::= ZERO . { lhs = Foam::Zero; }
|
||||
svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; }
|
||||
svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
|
||||
@ -169,6 +171,39 @@ svalue (lhs) ::= ARG LPAREN RPAREN . { lhs = driver->argValue(); }
|
||||
svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
|
||||
svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
||||
|
||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
lhs = driver->getFunctionValue<Foam::scalar>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (vector)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%type vvalue { Foam::vector* }
|
||||
%destructor vvalue { delete($$); $$ = nullptr; }
|
||||
|
||||
vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
||||
{
|
||||
// Take ownership of pointer from scan token
|
||||
lhs = tok.vectorPtr; tok.vectorPtr = nullptr;
|
||||
}
|
||||
|
||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
auto val = driver->getFunctionValue<Foam::vector>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
lhs = new Foam::vector(val);
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * Fields * * * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
@ -184,7 +219,9 @@ dnl
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (scalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [sfield])dnl
|
||||
define([_new_target_], [_new_sfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -200,9 +237,9 @@ rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but works directly for scalarField
|
||||
rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
||||
@ -217,20 +254,34 @@ _target_ (lhs) ::= RAND LPAREN RPAREN.
|
||||
|
||||
_target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN.
|
||||
{
|
||||
lhs = driver->field_rand(std::round((seed)->svalue)).ptr();
|
||||
lhs = driver->field_rand(std::round((seed).scalarValue)).ptr();
|
||||
}
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (vectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [vfield])dnl
|
||||
define([_new_target_], [_new_vfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, vvalue)
|
||||
rule_get_field(_target_, VECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
@ -238,11 +289,26 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
// Other functions
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (sphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [hfield])dnl
|
||||
define([_new_target_], [_new_hfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -260,7 +326,9 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (symmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [yfield])dnl
|
||||
define([_new_target_], [_new_yfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -278,7 +346,9 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (tensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [tfield])dnl
|
||||
define([_new_target_], [_new_tfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -300,6 +370,7 @@ rules_tensor_functions()
|
||||
* Logic field productions (boolField)
|
||||
dnl
|
||||
define([_target_], [lfield])dnl
|
||||
define([_new_target_], [_new_lfield])dnl
|
||||
define([_value_type_], [bool])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -393,13 +464,15 @@ void Foam::expressions::fieldExpr::parser::start(parseDriver& driver_)
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fieldExpr::parser::parse
|
||||
(
|
||||
int tokenId,
|
||||
scanToken* tokenVal
|
||||
)
|
||||
void Foam::expressions::fieldExpr::parser::parse(int tokenId)
|
||||
{
|
||||
Parse(lemon_, tokenId, tokenVal);
|
||||
Parse(lemon_, tokenId, scanToken::null());
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fieldExpr::parser::parse(int tokenId, scanToken tok)
|
||||
{
|
||||
Parse(lemon_, tokenId, tok);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,6 +34,7 @@ Description
|
||||
#ifndef expressions_fieldExprParser_H
|
||||
#define expressions_fieldExprParser_H
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "fieldExprFwd.H"
|
||||
|
||||
namespace Foam
|
||||
@ -97,10 +98,14 @@ public:
|
||||
//- Stop parsing, freeing the allocated parser
|
||||
void stop();
|
||||
|
||||
//- Push token/value to parser
|
||||
void parse(int tokenId, scanToken* tokenVal);
|
||||
//- Push token type to parser with default token
|
||||
void parse(int tokenId);
|
||||
|
||||
//- Push token type/value to parser
|
||||
void parse(int tokenId, scanToken tok);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fieldExpr
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,7 +38,6 @@ Note
|
||||
#define expressions_fieldExprScanner_H
|
||||
|
||||
#include "fieldExprFwd.H"
|
||||
#include "scalar.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
@ -47,21 +46,6 @@ namespace expressions
|
||||
namespace fieldExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanToken Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
union scanToken
|
||||
{
|
||||
Foam::label ivalue;
|
||||
Foam::scalar svalue;
|
||||
Foam::word* name;
|
||||
|
||||
//- Default construct, bit-wise zero for union content
|
||||
scanToken() : ivalue(0) {}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanner Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -83,16 +67,14 @@ class scanner
|
||||
bool dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
//- Dispatch identifier to parser (if possible) or Fatal
|
||||
bool dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "fieldExprScanner.H"
|
||||
#include "fieldExprDriver.H"
|
||||
#include "fieldExprLemonParser.h"
|
||||
@ -42,7 +43,6 @@ Description
|
||||
#undef DebugInfo
|
||||
#define DebugInfo if (debug & 0x2) InfoErr
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -55,8 +55,9 @@ namespace Foam
|
||||
#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name }
|
||||
|
||||
//- An {int, c_str} enum pairing for field types
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
|
||||
// No known look-back types
|
||||
#undef HAS_LOOKBEHIND_TOKENS
|
||||
|
||||
// Special handling of predefined method types. Eg, .x(), .y(), ...
|
||||
@ -121,22 +122,27 @@ static int driverTokenType
|
||||
const word& ident
|
||||
)
|
||||
{
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Get stashed "look-behind" to decide what type of identifier we expect
|
||||
#endif
|
||||
|
||||
// Field variables
|
||||
#ifdef TOK_SCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isLocalVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isLocalVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_SCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_VECTOR_ID, vector);
|
||||
checkFieldToken(TOK_SYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_SPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_TENSOR_ID, tensor);
|
||||
// Not tested: checkFieldToken(TOK_BOOL_ID, bool);
|
||||
doLocalCode(TOK_SCALAR_ID, scalar);
|
||||
doLocalCode(TOK_VECTOR_ID, vector);
|
||||
doLocalCode(TOK_SYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_SPH_TENSOR_ID, sphericalTensor);
|
||||
doLocalCode(TOK_TENSOR_ID, tensor);
|
||||
// Not tested: doLocalCode(TOK_BOOL_ID, bool);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -156,7 +162,15 @@ static int driverTokenType
|
||||
#define EMIT_TOKEN(T) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
|
||||
parser_->parse(TOKEN_OF(T), nullptr); \
|
||||
parser_->parse(TOKEN_OF(T)); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
#define EMIT_VECTOR_TOKEN(X, Y, Z) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< "VECTOR at " << driver_.parsePosition() << nl; \
|
||||
scanToken scanTok; \
|
||||
scanTok.setVector(X,Y,Z); \
|
||||
parser_->parse(TOK_VECTOR_VALUE, scanTok); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
|
||||
@ -165,15 +179,18 @@ static int driverTokenType
|
||||
write data;
|
||||
|
||||
action emit_number {
|
||||
// Emit number
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
|
||||
DebugInfo
|
||||
<< "Number:" << std::string(ts, te-ts).c_str()
|
||||
<< " at " << driver_.parsePosition() << nl;
|
||||
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.svalue))
|
||||
scanToken scanTok;
|
||||
scanTok.setScalar(0);
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.scalarValue))
|
||||
{
|
||||
parser_->parse(TOKEN_OF(NUMBER), &scanTok);
|
||||
parser_->parse(TOKEN_OF(NUMBER), scanTok);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -187,33 +204,38 @@ static int driverTokenType
|
||||
}
|
||||
|
||||
action emit_ident {
|
||||
// Emit identifier
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_ident(driver_, scanTok, word(ts, te-ts, false));
|
||||
dispatch_ident(driver_, word(ts, te-ts, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
action emit_method {
|
||||
// Tokenized ".method" - dispatch '.' and "method" separately
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_method(driver_, scanTok, word(ts+1, te-ts-1, false));
|
||||
dispatch_method(driver_, word(ts+1, te-ts-1, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
dquoted = '"' [^\"]+ '"' ;
|
||||
squoted = "'" [^\']+ "'" ;
|
||||
|
||||
## Allow 'fn:' prefix for function identifier
|
||||
ident = ('fn:')? identifier ;
|
||||
|
||||
## ===========
|
||||
## The scanner
|
||||
## ===========
|
||||
main := |*
|
||||
space*;
|
||||
|
||||
number => emit_number;
|
||||
|
||||
## Operators
|
||||
'!' =>{ EMIT_TOKEN(NOT); };
|
||||
'!' =>{ EMIT_TOKEN(LNOT); };
|
||||
'%' =>{ EMIT_TOKEN(PERCENT); };
|
||||
'(' =>{ EMIT_TOKEN(LPAREN); };
|
||||
')' =>{ EMIT_TOKEN(RPAREN); };
|
||||
@ -234,7 +256,7 @@ static int driverTokenType
|
||||
'&&' =>{ EMIT_TOKEN(LAND); };
|
||||
'||' =>{ EMIT_TOKEN(LOR); };
|
||||
'&' =>{ EMIT_TOKEN(BIT_AND); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OK); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OR); };
|
||||
'^' =>{ EMIT_TOKEN(BIT_XOR); };
|
||||
|
||||
## Some '.method' - Error if unknown
|
||||
@ -286,13 +308,16 @@ static int driverTokenType
|
||||
"sphericalTensor" =>{ EMIT_TOKEN(SPH_TENSOR); };
|
||||
|
||||
## Single value (constants, etc)
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"true" =>{ EMIT_TOKEN(LTRUE); };
|
||||
"false" =>{ EMIT_TOKEN(LFALSE); };
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"vector::x" =>{ EMIT_VECTOR_TOKEN(1,0,0); };
|
||||
"vector::y" =>{ EMIT_VECTOR_TOKEN(0,1,0); };
|
||||
"vector::z" =>{ EMIT_VECTOR_TOKEN(0,0,1); };
|
||||
"tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
|
||||
"arg" =>{ EMIT_TOKEN(ARG); };
|
||||
## "time" =>{ EMIT_TOKEN(TIME); };
|
||||
## "deltaT" =>{ EMIT_TOKEN(DELTA_T); };
|
||||
"time" =>{ EMIT_TOKEN(TIME); };
|
||||
"deltaT" =>{ EMIT_TOKEN(DELTA_T); };
|
||||
|
||||
## Identifier (field, etc - error if unknown)
|
||||
## Handle 'bare' names and single/double quoted ones
|
||||
@ -321,8 +346,7 @@ Foam::expressions::fieldExpr::scanner::~scanner()
|
||||
bool Foam::expressions::fieldExpr::scanner::dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
if (ident[0] == '.')
|
||||
@ -339,8 +363,8 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_method
|
||||
if (methType > 0)
|
||||
{
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -353,10 +377,11 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_method
|
||||
bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
// Peek at stashed "look-behind". It may influence decisions
|
||||
int lookBehindTok = driver_.stashedTokenId();
|
||||
int tokType = -1;
|
||||
|
||||
const bool quoted =
|
||||
@ -381,12 +406,12 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " function:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Specials such "cset" also reset the look-behind
|
||||
// Specials such "cellSet" etc also reset the look-behind
|
||||
tokType = lookBehindTokenEnums.lookup(ident, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
@ -396,17 +421,44 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
driver_.resetStashedTokenId(tokType);
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Functions: scalar, vector, probably don't need others
|
||||
// - "fn:" prefix to avoid any ambiguities
|
||||
if (lookBehindTok <= 0 && ident.starts_with("fn:"))
|
||||
{
|
||||
word funcName(ident.substr(3)); // strip prefix
|
||||
|
||||
// Can also peek at stashed "look-behind"
|
||||
// const int lookBehind = driver_.stashedTokenId();
|
||||
do
|
||||
{
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isFunction<Type>(funcName)) \
|
||||
{ \
|
||||
ident = std::move(funcName); \
|
||||
tokType = TokType; \
|
||||
break; \
|
||||
}
|
||||
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
#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);
|
||||
}
|
||||
|
||||
if (tokType <= 0)
|
||||
{
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
}
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
@ -414,8 +466,9 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " token:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -447,12 +500,13 @@ bool Foam::expressions::fieldExpr::scanner::dispatch_ident
|
||||
// The field (before the ".")
|
||||
ident.erase(dot);
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -515,9 +569,6 @@ bool Foam::expressions::fieldExpr::scanner::process
|
||||
|
||||
parser_->start(driver_);
|
||||
|
||||
// Scan token type
|
||||
scanToken scanTok;
|
||||
|
||||
// Token start/end (Ragel naming)
|
||||
const char* ts;
|
||||
const char* te;
|
||||
@ -547,7 +598,7 @@ bool Foam::expressions::fieldExpr::scanner::process
|
||||
}
|
||||
|
||||
// Terminate parser execution
|
||||
parser_->parse(0, nullptr);
|
||||
parser_->parse(0);
|
||||
parser_->stop();
|
||||
|
||||
if (debug & 0x6)
|
||||
|
||||
92
src/OpenFOAM/expressions/scanToken/exprScanToken.C
Normal file
92
src/OpenFOAM/expressions/scanToken/exprScanToken.C
Normal file
@ -0,0 +1,92 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "exprScanToken.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::scanToken Foam::expressions::scanToken::null()
|
||||
{
|
||||
scanToken tok;
|
||||
tok.type_ = LABEL;
|
||||
tok.labelValue = 0;
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::destroy()
|
||||
{
|
||||
if (type_ == VECTOR)
|
||||
{
|
||||
delete vectorPtr;
|
||||
vectorPtr = nullptr;
|
||||
}
|
||||
else if (type_ == WORD)
|
||||
{
|
||||
delete wordPtr;
|
||||
wordPtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::setLabel(label val)
|
||||
{
|
||||
type_ = LABEL;
|
||||
labelValue = val;
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::setScalar(scalar val)
|
||||
{
|
||||
type_ = SCALAR;
|
||||
scalarValue = val;
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::setVector(scalar x, scalar y, scalar z)
|
||||
{
|
||||
type_ = VECTOR;
|
||||
vectorPtr = new Foam::vector(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::setVector(const vector& val)
|
||||
{
|
||||
type_ = VECTOR;
|
||||
vectorPtr = new Foam::vector(val);
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::scanToken::setWord(const word& val)
|
||||
{
|
||||
type_ = WORD;
|
||||
wordPtr = new Foam::word(val);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
116
src/OpenFOAM/expressions/scanToken/exprScanToken.H
Normal file
116
src/OpenFOAM/expressions/scanToken/exprScanToken.H
Normal file
@ -0,0 +1,116 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019-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::expressions::scanToken
|
||||
|
||||
Description
|
||||
A low-level input/scan token content.
|
||||
No defined constructors/destructors.
|
||||
All memory management is manual!
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_scanToken_H
|
||||
#define expressions_scanToken_H
|
||||
|
||||
#include "scalar.H"
|
||||
#include "vector.H"
|
||||
#include "word.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanToken Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
struct scanToken
|
||||
{
|
||||
//- Tagged union types
|
||||
enum tokenType : unsigned char
|
||||
{
|
||||
LABEL = 0,
|
||||
SCALAR,
|
||||
VECTOR,
|
||||
WORD
|
||||
};
|
||||
|
||||
|
||||
// Data
|
||||
|
||||
//- The data content (as a union).
|
||||
// For memory alignment have this appear as the first member.
|
||||
union
|
||||
{
|
||||
Foam::label labelValue;
|
||||
Foam::scalar scalarValue;
|
||||
Foam::vector* vectorPtr;
|
||||
Foam::word* wordPtr;
|
||||
Foam::word* name_;
|
||||
};
|
||||
|
||||
//- The token type
|
||||
tokenType type_;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return a null token - in lieu of a default constructor
|
||||
static scanToken null();
|
||||
|
||||
//- Assign type/value to be LABEL. Does not call destroy().
|
||||
void setLabel(label val);
|
||||
|
||||
//- Assign type/value to be SCALAR. Does not call destroy().
|
||||
void setScalar(scalar val);
|
||||
|
||||
//- Assign type/value to be VECTOR. Does not call destroy().
|
||||
void setVector(scalar x, scalar y, scalar z);
|
||||
|
||||
//- Assign type/value to be VECTOR. Does not call destroy().
|
||||
void setVector(const vector& val);
|
||||
|
||||
//- Assign type/value to be WORD (name). Does not call destroy().
|
||||
void setWord(const word& val);
|
||||
|
||||
//- Manual deletion of pointer types
|
||||
void destroy();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Named versions (as m4 macros) of single quoted characters to avoid
|
||||
|
||||
@ -6,11 +6,10 @@ divert(-1)dnl
|
||||
# \\ / A nd | www.openfoam.com
|
||||
# \\/ M anipulation |
|
||||
#------------------------------------------------------------------------------
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
# Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# A collection of 'base' setup of m4 macros for lemon, and setup
|
||||
@ -34,7 +33,7 @@ divert(-1)dnl
|
||||
# _sphTensor_, _symTensor_, _tensor_
|
||||
#
|
||||
# Values for the currently targeted rule
|
||||
# _target_, _value_type_
|
||||
# _target_, _value_type_, _scalar_arg_
|
||||
#
|
||||
# Note
|
||||
# The `undefine' occur immediately upon inclusion of this file.
|
||||
@ -109,18 +108,19 @@ Foam::tmp<T> make_tmp(T* p)
|
||||
|
||||
//- Default [make_obj] is pass-through
|
||||
template<class T>
|
||||
const T& make_obj(const T& obj)
|
||||
const T& make_obj(const T& o) noexcept
|
||||
{
|
||||
return obj;
|
||||
return o;
|
||||
}
|
||||
|
||||
//- Move construct an object from a pointer and destroy the pointer
|
||||
template<class T>
|
||||
T make_obj(T* p)
|
||||
T make_obj(T*& p)
|
||||
{
|
||||
T obj(std::move(*p));
|
||||
T o(std::move(*p));
|
||||
delete p;
|
||||
return obj;
|
||||
p = nullptr; // Prevent caller from deleting too
|
||||
return o;
|
||||
}]
|
||||
)
|
||||
|
||||
@ -149,6 +149,7 @@ undefine([_tensor_])
|
||||
|
||||
undefine([_target_])
|
||||
undefine([_value_type_])
|
||||
undefine([_scalar_arg_])
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
divert(0)dnl
|
||||
|
||||
@ -6,11 +6,10 @@ divert(-1)dnl
|
||||
# \\ / A nd | www.openfoam.com
|
||||
# \\/ M anipulation |
|
||||
#------------------------------------------------------------------------------
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
# Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Defines standard operator precedence macro for lemon grammar.
|
||||
@ -20,18 +19,34 @@ divert(-1)dnl
|
||||
|
||||
define([operator_precedence],
|
||||
[// [https://en.cppreference.com/w/cpp/language/operator_precedence]
|
||||
%right QUESTION COLON . // 16: right-to-left
|
||||
%left LOR . // 15:
|
||||
%left LAND . // 14:
|
||||
// %left BIT_OR . // 13 (unused)
|
||||
%left BIT_XOR . // 12
|
||||
%left BIT_AND . // 11
|
||||
%left EQUAL NOT_EQUAL . // 10
|
||||
%left LESS_EQ GREATER_EQ LESS GREATER . // 9
|
||||
%left PLUS MINUS . // 6
|
||||
%left TIMES DIVIDE PERCENT . // 5
|
||||
%right NEGATE NOT . // 3: right-to-left
|
||||
%left DOT . // 2: (method)]
|
||||
%right QUESTION COLON . // 13: right-to-left
|
||||
%left LOR . // 12:
|
||||
%left LAND . // 11:
|
||||
%left BIT_OR . // 10 (unused)
|
||||
%left BIT_XOR . // 9
|
||||
%left BIT_AND . // 8
|
||||
%left EQUAL NOT_EQUAL . // 7
|
||||
%left LESS LESS_EQ GREATER GREATER_EQ . // 6
|
||||
%left PLUS MINUS . // 4
|
||||
%left TIMES DIVIDE PERCENT . // 3
|
||||
%right NEGATE LNOT BIT_NOT . // 2: right-to-left
|
||||
%left DOT . // 1: (method)]
|
||||
)
|
||||
|
||||
|
||||
define([standard_tokens],
|
||||
[// Standard tokens for operators, constants and common types]
|
||||
%token
|
||||
LPAREN RPAREN COMMA
|
||||
QUESTION COLON LOR LAND LNOT
|
||||
BIT_OR BIT_XOR BIT_AND BIT_NOT
|
||||
EQUAL NOT_EQUAL
|
||||
LESS LESS_EQ GREATER GREATER_EQ
|
||||
PLUS MINUS TIMES DIVIDE PERCENT
|
||||
NEGATE DOT
|
||||
BOOL LTRUE LFALSE
|
||||
NUMBER ZERO IDENTIFIER
|
||||
.
|
||||
)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Various "boilerplate" parser methods (C++)
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Collection of VectorSpace `component' functions
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Rules for vector/tensor `zip' functions, which are used to combine
|
||||
|
||||
@ -62,39 +62,20 @@ define([_get_]$1, [driver->$5<$3>($][1).ptr()])dnl
|
||||
# Example
|
||||
# rule_get_field(sfield, SCALAR_ID)
|
||||
#
|
||||
# sfield (lhs) ::= SCALAR_ID (ident) .
|
||||
# sfield (lhs) ::= SCALAR_ID (name) .
|
||||
# {
|
||||
# lhs = driver->getVolField<Foam::scalar>(make_obj(ident->name)).ptr();
|
||||
# lhs = driver->getVolField<Foam::scalar>(make_obj(name.name_)).ptr();
|
||||
# }
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rule_get_field],
|
||||
[$1 (lhs) ::= $2 (ident) .
|
||||
[$1 (lhs) ::= $2 (name) .
|
||||
{
|
||||
lhs = _get_$1(make_obj(ident->name));
|
||||
lhs = _get_$1(make_obj(name.name_));
|
||||
}]
|
||||
)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# rule_driver_select(out, tok, method)
|
||||
#
|
||||
# Description
|
||||
# Production rule for driver get cell/face/point selection methods
|
||||
#
|
||||
# Example
|
||||
# rule_driver_select(sfield, CSET, field_cellSet)
|
||||
#
|
||||
# sfield (lhs) ::= CSET LPAREN IDENTIFIER (ident) RPAREN .
|
||||
# {
|
||||
# lhs = driver->field_cellSet(make_obj(ident->name)).ptr();
|
||||
# }
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rule_driver_select],
|
||||
[rule_driver_unary_named($1, $2, IDENTIFIER, $3)])
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# rule_field_from_value(out, in, [prefix])
|
||||
#
|
||||
@ -454,19 +435,19 @@ ifelse($5,[],[],[<$5>])dnl # Optional template parameter (value_type)
|
||||
# Foam::scalar
|
||||
# )
|
||||
#
|
||||
# sfield(lhs) ::= SN_GRAD LPAREN SCALAR_ID (ident) RPAREN .
|
||||
# sfield(lhs) ::= SN_GRAD LPAREN SCALAR_ID (name) RPAREN .
|
||||
# {
|
||||
# lhs = driver->patchNormalField<Foam::scalar>(make_obj(ident->name)).ptr();
|
||||
# lhs = driver->patchNormalField<Foam::scalar>(make_obj(name.name_)).ptr();
|
||||
# }
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rule_driver_unary_named],
|
||||
[$1 (lhs) ::= $2 LPAREN $3 (ident) RPAREN .
|
||||
[$1 (lhs) ::= $2 LPAREN $3 (name) RPAREN .
|
||||
{
|
||||
lhs = driver->$4[]dnl # The method call
|
||||
ifelse($5,[],[],[<$5>])dnl # Optional template parameter (value_type)
|
||||
(make_obj(ident->name)).ptr();
|
||||
(make_obj(name.name_)).ptr();
|
||||
}]
|
||||
)
|
||||
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Collection of `standard' functions and type-specific ones.
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Collection of `standard' operations and type-specific ones.
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Logic rules, using bool or Foam::scalar for its storage.
|
||||
@ -98,7 +97,7 @@ define([rule_logical_or],
|
||||
)
|
||||
|
||||
define([rule_logical_negate],
|
||||
[$1 (lhs) ::= NOT $1 (a). _lemon_precedence(NEGATE)
|
||||
[$1 (lhs) ::= LNOT $1 (a). _lemon_precedence(NEGATE)
|
||||
{
|
||||
lhs = a;
|
||||
Foam::FieldOps::assign
|
||||
|
||||
@ -9,8 +9,7 @@ divert(-1)dnl
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GNU General Public
|
||||
# License GPL-3.0 or later <https://www.gnu.org/licenses/gpl-3.0>
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Description
|
||||
# Collection of common functions that should work on all (non-logical)
|
||||
|
||||
@ -471,8 +471,8 @@ public:
|
||||
//- Return cell/face/point zone/set type or unknown
|
||||
topoSetSource::sourceType topoSourceType(const word& name) const;
|
||||
|
||||
//- Read and return labels associated with the topo set
|
||||
labelList getTopoSetLabels
|
||||
//- Get the labels associated with the topo set
|
||||
refPtr<labelList> getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
|
||||
@ -34,13 +34,17 @@ License
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
Foam::refPtr<Foam::labelList>
|
||||
Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
// Zones first - they are cheap to handle (no IO)
|
||||
refPtr<labelList> selected;
|
||||
|
||||
// Zones first
|
||||
// - cheap to handle (no IO) and can simply reference their labels
|
||||
|
||||
switch (setType)
|
||||
{
|
||||
@ -58,7 +62,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
selected.cref(zones[zoneID]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -76,7 +80,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
selected.cref(zones[zoneID]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -94,7 +98,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
selected.cref(zones[zoneID]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -103,6 +107,12 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
}
|
||||
|
||||
|
||||
if (selected.valid())
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
|
||||
IOobject io(topoSet::findIOobject(mesh(), name));
|
||||
|
||||
switch (setType)
|
||||
@ -121,7 +131,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
selected.reset(refPtr<labelList>::New(set.sortedToc()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -139,7 +149,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
selected.reset(refPtr<labelList>::New(set.sortedToc()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -157,7 +167,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
selected.reset(refPtr<labelList>::New(set.sortedToc()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -171,7 +181,7 @@ Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
}
|
||||
}
|
||||
|
||||
return labelList::null();
|
||||
return selected;
|
||||
}
|
||||
|
||||
|
||||
@ -251,9 +261,8 @@ Foam::Ostream& Foam::expressions::fvExprDriver::writeCommon
|
||||
os.writeEntry("globalScopes", globalScopes_);
|
||||
}
|
||||
|
||||
// writeTable(os, "timelines", lines_);
|
||||
// writeTable(os, "lookuptables", lookup_);
|
||||
// writeTable(os, "lookuptables2D", lookup2D_);
|
||||
// Write "functions<scalar>" ...
|
||||
writeFunctions(os);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
@ -146,31 +146,57 @@ bool Foam::expressions::fvExprDriver::foundField
|
||||
<< " disk:" << searchFiles() << endl;
|
||||
}
|
||||
|
||||
// if (std::is_void<Type>::value) ...
|
||||
|
||||
if (searchRegistry())
|
||||
for (int checki = 0; checki < 2; ++checki)
|
||||
{
|
||||
const regIOobject* ioptr =
|
||||
this->mesh().cfindObject<regIOobject>(name);
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
const regIOobject* ioptr = nullptr;
|
||||
|
||||
if (this->mesh().foundObject<Type>(name))
|
||||
if (checki == 0)
|
||||
{
|
||||
ioptr = exprDriver::cfindContextIOobject(name);
|
||||
}
|
||||
else if (searchRegistry())
|
||||
{
|
||||
ioptr = this->mesh().cfindIOobject(name);
|
||||
}
|
||||
if (!ioptr) continue;
|
||||
|
||||
const Type* fldPtr = dynamic_cast<const Type*>(ioptr);
|
||||
|
||||
if (fldPtr)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found registered: " << name << endl;
|
||||
if (checki)
|
||||
{
|
||||
Info<< "Found registered:";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Found context object:";
|
||||
}
|
||||
Info<< name << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
else if (ioptr)
|
||||
{
|
||||
Info<< "Registered " << name;
|
||||
|
||||
if (ioptr)
|
||||
if (debug)
|
||||
{
|
||||
Info<< " type:" << ioptr->headerClassName();
|
||||
if (checki)
|
||||
{
|
||||
Info<< "Registered:";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Context object:";
|
||||
}
|
||||
Info<< name << " type:"
|
||||
<< ioptr->headerClassName() << " != type:"
|
||||
<< Type::typeName << nl;
|
||||
}
|
||||
Info<< ", not type:" << Type::typeName << nl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,14 +209,11 @@ bool Foam::expressions::fvExprDriver::foundField
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< name << " not found" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< name << " not found" << endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -236,12 +259,18 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
{
|
||||
typedef typename GeomField::value_type Type;
|
||||
|
||||
tmp<GeomField> tfield;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::getOrReadField <" << name
|
||||
<< "> Type: " << GeomField::typeName << endl;
|
||||
}
|
||||
|
||||
|
||||
// Handle variables
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
|
||||
refPtr<expressions::exprResult> tvar;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
@ -253,9 +282,6 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
tvar.cref(lookupGlobal(name));
|
||||
}
|
||||
|
||||
|
||||
tmp<GeomField> tfield;
|
||||
|
||||
if (tvar.valid())
|
||||
{
|
||||
const auto& var = tvar.cref();
|
||||
@ -327,24 +353,45 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
}
|
||||
|
||||
|
||||
const objectRegistry& obr = meshRef.thisDb();
|
||||
// Find context or registered field
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const GeomField* origFldPtr;
|
||||
const GeomField* origFldPtr = nullptr;
|
||||
|
||||
if
|
||||
(
|
||||
searchRegistry()
|
||||
&& (origFldPtr = obr.cfindObject<GeomField>(name)) != nullptr
|
||||
)
|
||||
for (int checki = 0; !origFldPtr && checki < 2; ++checki)
|
||||
{
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
|
||||
if (checki == 0)
|
||||
{
|
||||
origFldPtr = exprDriver::cfindContextObject<GeomField>(name);
|
||||
}
|
||||
else if (searchRegistry())
|
||||
{
|
||||
origFldPtr =
|
||||
meshRef.thisDb().template cfindObject<GeomField>(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (origFldPtr)
|
||||
{
|
||||
// Found from context or registry
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Retrieve registered: " << name << nl;
|
||||
Info<< "Retrieve context/registered:" << name << nl;
|
||||
}
|
||||
|
||||
const GeomField& origFld = *origFldPtr;
|
||||
|
||||
// Avoid shadowing the original object
|
||||
// Make a deep copy of the data to return. Avoids shadowing
|
||||
// the original object, but most importantly the backend
|
||||
// parser (eg, lemon) will be working with combining via plain
|
||||
// pointers. We thus lose any of the tmp<> shallow copy semantics
|
||||
// anyhow. Additionally, need to disable dimension checking here or
|
||||
// elsewhere too.
|
||||
|
||||
tfield = GeomField::New(name + "_exprDriverCopy", origFld);
|
||||
|
||||
if (getOldTime)
|
||||
@ -445,9 +492,8 @@ Foam::autoPtr<T> Foam::expressions::fvExprDriver::getTopoSet
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Looking for " << T::typeName << " named " << name;
|
||||
|
||||
Info<< " or registered as " << regName << " with mesh "
|
||||
Info<< "Looking for " << T::typeName << " named " << name
|
||||
<< " or registered as " << regName << " with mesh "
|
||||
<< "Caching:" << cacheSets()
|
||||
<< " Found:" << (mesh.foundObject<T>(name))
|
||||
<< " Found registered:" << mesh.foundObject<T>(regName)
|
||||
@ -494,7 +540,7 @@ Foam::autoPtr<T> Foam::expressions::fvExprDriver::getTopoSet
|
||||
}
|
||||
else
|
||||
{
|
||||
const T* ptr = mesh.thisDb().cfindObject<T>(name);
|
||||
const T* ptr = mesh.thisDb().template cfindObject<T>(name);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
|
||||
@ -111,6 +111,21 @@ protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Cell selections (as logical)
|
||||
tmp<boolField> field_cellSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
//- Face selections (as logical)
|
||||
tmp<boolField> field_faceSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
|
||||
// No copy copy construct
|
||||
parseDriver(const parseDriver&) = delete;
|
||||
|
||||
@ -281,6 +296,20 @@ public:
|
||||
//- The patch point locations - (swak = pts)
|
||||
tmp<vectorField> field_pointField() const;
|
||||
|
||||
|
||||
//- Cell selection (set)
|
||||
inline tmp<boolField> field_cellSet(const word& name) const;
|
||||
|
||||
//- Cell selection (zone)
|
||||
inline tmp<boolField> field_cellZone(const word& name) const;
|
||||
|
||||
//- Face selection (set)
|
||||
inline tmp<boolField> field_faceSet(const word& name) const;
|
||||
|
||||
//- Face selection (zone)
|
||||
inline tmp<boolField> field_faceZone(const word& name) const;
|
||||
|
||||
|
||||
//- A uniform random field
|
||||
tmp<scalarField> field_rand(label seed=0, bool gaussian=false) const;
|
||||
|
||||
|
||||
@ -55,6 +55,97 @@ Foam::expressions::patchExpr::parseDriver::getPointField<bool>
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_cellSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
refPtr<labelList> tselected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLZONE_SOURCE:
|
||||
case topoSetSource::sourceType::CELLSET_SOURCE:
|
||||
{
|
||||
tselected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not particularly efficient...
|
||||
labelHashSet inSelection(tselected());
|
||||
|
||||
const labelList& faceCells = patch_.faceCells();
|
||||
auto tresult = tmp<boolField>::New(this->size(), false);
|
||||
auto& result = tresult.ref();
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (inSelection.found(faceCells[facei]))
|
||||
{
|
||||
result[facei] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
refPtr<labelList> tselected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::FACESET_SOURCE:
|
||||
case topoSetSource::sourceType::FACEZONE_SOURCE:
|
||||
{
|
||||
tselected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Not particularly efficient...
|
||||
labelHashSet inSelection(tselected());
|
||||
|
||||
const label patchStart = patch_.start();
|
||||
|
||||
auto tresult = tmp<boolField>::New(this->size(), false);
|
||||
auto& result = tresult.ref();
|
||||
|
||||
forAll(result, facei)
|
||||
{
|
||||
if (inSelection.found(facei + patchStart))
|
||||
{
|
||||
result[facei] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceArea() const
|
||||
{
|
||||
|
||||
@ -47,4 +47,60 @@ inline Foam::label Foam::expressions::patchExpr::parseDriver::size
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver::field_cellSet
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_cellSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::CELLSET_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_cellZone
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_cellSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::CELLZONE_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceSet
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_faceSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::FACESET_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::boolField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceZone
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_faceSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::FACEZONE_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -125,28 +125,43 @@ Foam::expressions::patchExpr::parseDriver::getField(const word& name)
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
|
||||
|
||||
// Local, temporary storage and/or lookup values
|
||||
bool findField = true;
|
||||
bool found = false;
|
||||
tmp<vfieldType> vfield;
|
||||
tmp<sfieldType> sfield;
|
||||
tmp<pfieldType> pfield;
|
||||
|
||||
if (findField)
|
||||
for (int checki = 0; !found && checki < 2; ++checki)
|
||||
{
|
||||
vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
|
||||
findField = !vfield.valid();
|
||||
}
|
||||
if (findField)
|
||||
{
|
||||
sfield = exprDriver::cfindFieldObject<sfieldType>(obr, name);
|
||||
findField = !sfield.valid();
|
||||
}
|
||||
if (findField)
|
||||
{
|
||||
pfield = exprDriver::cfindFieldObject<pfieldType>(obr, name);
|
||||
findField = !pfield.valid();
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
const regIOobject* ioptr =
|
||||
(
|
||||
(checki == 0)
|
||||
? exprDriver::cfindContextIOobject(name)
|
||||
: obr.cfindIOobject(name)
|
||||
);
|
||||
if (!ioptr) continue;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
vfield.cref(dynamic_cast<const vfieldType*>(ioptr));
|
||||
found = vfield.valid();
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
sfield.cref(dynamic_cast<const sfieldType*>(ioptr));
|
||||
found = sfield.valid();
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
pfield.cref(dynamic_cast<const pfieldType*>(ioptr));
|
||||
found = pfield.valid();
|
||||
}
|
||||
}
|
||||
|
||||
if (findField && searchFiles())
|
||||
|
||||
// Finally, search files if necessary (and permitted)
|
||||
if (!found && searchFiles())
|
||||
{
|
||||
const word fldType = this->getTypeOfField(name);
|
||||
|
||||
@ -236,22 +251,37 @@ Foam::expressions::patchExpr::parseDriver::patchInternalField
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
|
||||
|
||||
// Local, temporary storage and/or lookup values
|
||||
bool findField = true;
|
||||
bool found = false;
|
||||
tmp<vfieldType> vfield;
|
||||
tmp<pfieldType> pfield;
|
||||
|
||||
if (findField)
|
||||
for (int checki = 0; !found && checki < 2; ++checki)
|
||||
{
|
||||
vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
|
||||
findField = !vfield.valid();
|
||||
}
|
||||
if (findField)
|
||||
{
|
||||
pfield = exprDriver::cfindFieldObject<pfieldType>(obr, name);
|
||||
findField = !pfield.valid();
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
const regIOobject* ioptr =
|
||||
(
|
||||
(checki == 0)
|
||||
? exprDriver::cfindContextIOobject(name)
|
||||
: obr.cfindIOobject(name)
|
||||
);
|
||||
if (!ioptr) continue;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
vfield.cref(dynamic_cast<const vfieldType*>(ioptr));
|
||||
found = vfield.valid();
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
pfield.cref(dynamic_cast<const pfieldType*>(ioptr));
|
||||
found = pfield.valid();
|
||||
}
|
||||
}
|
||||
|
||||
if (findField && searchFiles())
|
||||
|
||||
// Finally, search files if necessary (and permitted)
|
||||
if (!found && searchFiles())
|
||||
{
|
||||
const word fldType = this->getTypeOfField(name);
|
||||
|
||||
@ -322,16 +352,31 @@ Foam::expressions::patchExpr::parseDriver::patchNeighbourField
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
|
||||
|
||||
// Local, temporary storage and/or lookup values
|
||||
bool findField = true;
|
||||
bool found = false;
|
||||
tmp<vfieldType> vfield;
|
||||
|
||||
if (findField)
|
||||
for (int checki = 0; !found && checki < 2; ++checki)
|
||||
{
|
||||
vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
|
||||
findField = !vfield.valid();
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
const regIOobject* ioptr =
|
||||
(
|
||||
(checki == 0)
|
||||
? exprDriver::cfindContextIOobject(name)
|
||||
: obr.cfindIOobject(name)
|
||||
);
|
||||
if (!ioptr) continue;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
vfield.cref(dynamic_cast<const vfieldType*>(ioptr));
|
||||
found = vfield.valid();
|
||||
}
|
||||
}
|
||||
|
||||
if (findField && searchFiles())
|
||||
|
||||
// Finally, search files if necessary (and permitted)
|
||||
if (!found && searchFiles())
|
||||
{
|
||||
const word fldType = this->getTypeOfField(name);
|
||||
|
||||
@ -386,16 +431,31 @@ Foam::expressions::patchExpr::parseDriver::patchNormalField
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
|
||||
|
||||
// Local, temporary storage and/or lookup values
|
||||
bool found = false;
|
||||
tmp<vfieldType> vfield;
|
||||
bool findField = true;
|
||||
|
||||
if (findField)
|
||||
for (int checki = 0; !found && checki < 2; ++checki)
|
||||
{
|
||||
vfield = exprDriver::cfindFieldObject<vfieldType>(obr, name);
|
||||
findField = !vfield.valid();
|
||||
// Check 0: object context (first)
|
||||
// Check 1: regular objectRegistry
|
||||
const regIOobject* ioptr =
|
||||
(
|
||||
(checki == 0)
|
||||
? exprDriver::cfindContextIOobject(name)
|
||||
: obr.cfindIOobject(name)
|
||||
);
|
||||
if (!ioptr) continue;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
vfield.cref(dynamic_cast<const vfieldType*>(ioptr));
|
||||
found = vfield.valid();
|
||||
}
|
||||
}
|
||||
|
||||
if (findField && searchFiles())
|
||||
|
||||
// Finally, search files if necessary (and permitted)
|
||||
if (!found && searchFiles())
|
||||
{
|
||||
const word fldType = this->getTypeOfField(name);
|
||||
|
||||
|
||||
@ -47,7 +47,6 @@ namespace patchExpr
|
||||
class parser;
|
||||
class scanner;
|
||||
class parseDriver;
|
||||
union scanToken;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
@ -1,115 +1,125 @@
|
||||
#define TOK_QUESTION 1
|
||||
#define TOK_COLON 2
|
||||
#define TOK_LOR 3
|
||||
#define TOK_LAND 4
|
||||
#define TOK_BIT_XOR 5
|
||||
#define TOK_BIT_AND 6
|
||||
#define TOK_EQUAL 7
|
||||
#define TOK_NOT_EQUAL 8
|
||||
#define TOK_LESS_EQ 9
|
||||
#define TOK_GREATER_EQ 10
|
||||
#define TOK_LESS 11
|
||||
#define TOK_GREATER 12
|
||||
#define TOK_PLUS 13
|
||||
#define TOK_MINUS 14
|
||||
#define TOK_TIMES 15
|
||||
#define TOK_DIVIDE 16
|
||||
#define TOK_PERCENT 17
|
||||
#define TOK_NEGATE 18
|
||||
#define TOK_NOT 19
|
||||
#define TOK_DOT 20
|
||||
#define TOK_NUMBER 21
|
||||
#define TOK_ZERO 22
|
||||
#define TOK_PI 23
|
||||
#define TOK_LPAREN 24
|
||||
#define TOK_RPAREN 25
|
||||
#define TOK_DEG_TO_RAD 26
|
||||
#define TOK_RAD_TO_DEG 27
|
||||
#define TOK_ARG 28
|
||||
#define TOK_TIME 29
|
||||
#define TOK_DELTA_T 30
|
||||
#define TOK_SCALAR_ID 31
|
||||
#define TOK_SSCALAR_ID 32
|
||||
#define TOK_INTERNAL_FIELD 33
|
||||
#define TOK_NEIGHBOUR_FIELD 34
|
||||
#define TOK_SN_GRAD 35
|
||||
#define TOK_MIN 36
|
||||
#define TOK_COMMA 37
|
||||
#define TOK_MAX 38
|
||||
#define TOK_SUM 39
|
||||
#define TOK_AVERAGE 40
|
||||
#define TOK_EXP 41
|
||||
#define TOK_LOG 42
|
||||
#define TOK_LOG10 43
|
||||
#define TOK_SQR 44
|
||||
#define TOK_SQRT 45
|
||||
#define TOK_CBRT 46
|
||||
#define TOK_SIN 47
|
||||
#define TOK_COS 48
|
||||
#define TOK_TAN 49
|
||||
#define TOK_ASIN 50
|
||||
#define TOK_ACOS 51
|
||||
#define TOK_ATAN 52
|
||||
#define TOK_SINH 53
|
||||
#define TOK_COSH 54
|
||||
#define TOK_TANH 55
|
||||
#define TOK_POW 56
|
||||
#define TOK_ATAN2 57
|
||||
#define TOK_POS 58
|
||||
#define TOK_NEG 59
|
||||
#define TOK_POS0 60
|
||||
#define TOK_NEG0 61
|
||||
#define TOK_SIGN 62
|
||||
#define TOK_FLOOR 63
|
||||
#define TOK_CEIL 64
|
||||
#define TOK_ROUND 65
|
||||
#define TOK_HYPOT 66
|
||||
#define TOK_RAND 67
|
||||
#define TOK_VECTOR_ID 68
|
||||
#define TOK_SVECTOR_ID 69
|
||||
#define TOK_SPH_TENSOR_ID 70
|
||||
#define TOK_SSPH_TENSOR_ID 71
|
||||
#define TOK_SYM_TENSOR_ID 72
|
||||
#define TOK_SSYM_TENSOR_ID 73
|
||||
#define TOK_IDENTITY_TENSOR 74
|
||||
#define TOK_TENSOR_ID 75
|
||||
#define TOK_STENSOR_ID 76
|
||||
#define TOK_LTRUE 77
|
||||
#define TOK_LFALSE 78
|
||||
#define TOK_BOOL 79
|
||||
#define TOK_SBOOL_ID 80
|
||||
#define TOK_FACE_AREA 81
|
||||
#define TOK_FACE_EXPR 82
|
||||
#define TOK_WEIGHT_AVERAGE 83
|
||||
#define TOK_WEIGHT_SUM 84
|
||||
#define TOK_POINT_EXPR 85
|
||||
#define TOK_PSCALAR_ID 86
|
||||
#define TOK_PVECTOR_ID 87
|
||||
#define TOK_PSPH_TENSOR_ID 88
|
||||
#define TOK_PSYM_TENSOR_ID 89
|
||||
#define TOK_PTENSOR_ID 90
|
||||
#define TOK_PBOOL_ID 91
|
||||
#define TOK_POINTS 92
|
||||
#define TOK_MAG 93
|
||||
#define TOK_MAGSQR 94
|
||||
#define TOK_VECTOR 95
|
||||
#define TOK_TENSOR 96
|
||||
#define TOK_SYM_TENSOR 97
|
||||
#define TOK_SPH_TENSOR 98
|
||||
#define TOK_CMPT_X 99
|
||||
#define TOK_CMPT_Y 100
|
||||
#define TOK_CMPT_Z 101
|
||||
#define TOK_CMPT_XX 102
|
||||
#define TOK_CMPT_XY 103
|
||||
#define TOK_CMPT_XZ 104
|
||||
#define TOK_CMPT_YX 105
|
||||
#define TOK_CMPT_YY 106
|
||||
#define TOK_CMPT_YZ 107
|
||||
#define TOK_CMPT_ZX 108
|
||||
#define TOK_CMPT_ZY 109
|
||||
#define TOK_CMPT_ZZ 110
|
||||
#define TOK_CMPT_II 111
|
||||
#define TOK_TRANSPOSE 112
|
||||
#define TOK_DIAG 113
|
||||
#define TOK_POINT_TO_FACE 114
|
||||
#define TOK_FACE_TO_POINT 115
|
||||
#define TOK_LPAREN 1
|
||||
#define TOK_RPAREN 2
|
||||
#define TOK_COMMA 3
|
||||
#define TOK_QUESTION 4
|
||||
#define TOK_COLON 5
|
||||
#define TOK_LOR 6
|
||||
#define TOK_LAND 7
|
||||
#define TOK_LNOT 8
|
||||
#define TOK_BIT_OR 9
|
||||
#define TOK_BIT_XOR 10
|
||||
#define TOK_BIT_AND 11
|
||||
#define TOK_BIT_NOT 12
|
||||
#define TOK_EQUAL 13
|
||||
#define TOK_NOT_EQUAL 14
|
||||
#define TOK_LESS 15
|
||||
#define TOK_LESS_EQ 16
|
||||
#define TOK_GREATER 17
|
||||
#define TOK_GREATER_EQ 18
|
||||
#define TOK_PLUS 19
|
||||
#define TOK_MINUS 20
|
||||
#define TOK_TIMES 21
|
||||
#define TOK_DIVIDE 22
|
||||
#define TOK_PERCENT 23
|
||||
#define TOK_NEGATE 24
|
||||
#define TOK_DOT 25
|
||||
#define TOK_BOOL 26
|
||||
#define TOK_LTRUE 27
|
||||
#define TOK_LFALSE 28
|
||||
#define TOK_NUMBER 29
|
||||
#define TOK_ZERO 30
|
||||
#define TOK_IDENTIFIER 31
|
||||
#define TOK_PI 32
|
||||
#define TOK_DEG_TO_RAD 33
|
||||
#define TOK_RAD_TO_DEG 34
|
||||
#define TOK_ARG 35
|
||||
#define TOK_TIME 36
|
||||
#define TOK_DELTA_T 37
|
||||
#define TOK_SCALAR_FUNCTION_ID 38
|
||||
#define TOK_VECTOR_VALUE 39
|
||||
#define TOK_VECTOR_FUNCTION_ID 40
|
||||
#define TOK_SCALAR_ID 41
|
||||
#define TOK_SSCALAR_ID 42
|
||||
#define TOK_INTERNAL_FIELD 43
|
||||
#define TOK_NEIGHBOUR_FIELD 44
|
||||
#define TOK_SN_GRAD 45
|
||||
#define TOK_MIN 46
|
||||
#define TOK_MAX 47
|
||||
#define TOK_SUM 48
|
||||
#define TOK_AVERAGE 49
|
||||
#define TOK_EXP 50
|
||||
#define TOK_LOG 51
|
||||
#define TOK_LOG10 52
|
||||
#define TOK_SQR 53
|
||||
#define TOK_SQRT 54
|
||||
#define TOK_CBRT 55
|
||||
#define TOK_SIN 56
|
||||
#define TOK_COS 57
|
||||
#define TOK_TAN 58
|
||||
#define TOK_ASIN 59
|
||||
#define TOK_ACOS 60
|
||||
#define TOK_ATAN 61
|
||||
#define TOK_SINH 62
|
||||
#define TOK_COSH 63
|
||||
#define TOK_TANH 64
|
||||
#define TOK_POW 65
|
||||
#define TOK_ATAN2 66
|
||||
#define TOK_POS 67
|
||||
#define TOK_NEG 68
|
||||
#define TOK_POS0 69
|
||||
#define TOK_NEG0 70
|
||||
#define TOK_SIGN 71
|
||||
#define TOK_FLOOR 72
|
||||
#define TOK_CEIL 73
|
||||
#define TOK_ROUND 74
|
||||
#define TOK_HYPOT 75
|
||||
#define TOK_RAND 76
|
||||
#define TOK_VECTOR_ID 77
|
||||
#define TOK_SVECTOR_ID 78
|
||||
#define TOK_SPH_TENSOR_ID 79
|
||||
#define TOK_SSPH_TENSOR_ID 80
|
||||
#define TOK_SYM_TENSOR_ID 81
|
||||
#define TOK_SSYM_TENSOR_ID 82
|
||||
#define TOK_IDENTITY_TENSOR 83
|
||||
#define TOK_TENSOR_ID 84
|
||||
#define TOK_STENSOR_ID 85
|
||||
#define TOK_SBOOL_ID 86
|
||||
#define TOK_CELL_SET 87
|
||||
#define TOK_CELL_ZONE 88
|
||||
#define TOK_FACE_SET 89
|
||||
#define TOK_FACE_ZONE 90
|
||||
#define TOK_FACE_AREA 91
|
||||
#define TOK_FACE_EXPR 92
|
||||
#define TOK_WEIGHT_AVERAGE 93
|
||||
#define TOK_WEIGHT_SUM 94
|
||||
#define TOK_POINT_EXPR 95
|
||||
#define TOK_PSCALAR_ID 96
|
||||
#define TOK_PVECTOR_ID 97
|
||||
#define TOK_PSPH_TENSOR_ID 98
|
||||
#define TOK_PSYM_TENSOR_ID 99
|
||||
#define TOK_PTENSOR_ID 100
|
||||
#define TOK_PBOOL_ID 101
|
||||
#define TOK_POINTS 102
|
||||
#define TOK_MAG 103
|
||||
#define TOK_MAGSQR 104
|
||||
#define TOK_VECTOR 105
|
||||
#define TOK_TENSOR 106
|
||||
#define TOK_SYM_TENSOR 107
|
||||
#define TOK_SPH_TENSOR 108
|
||||
#define TOK_CMPT_X 109
|
||||
#define TOK_CMPT_Y 110
|
||||
#define TOK_CMPT_Z 111
|
||||
#define TOK_CMPT_XX 112
|
||||
#define TOK_CMPT_XY 113
|
||||
#define TOK_CMPT_XZ 114
|
||||
#define TOK_CMPT_YX 115
|
||||
#define TOK_CMPT_YY 116
|
||||
#define TOK_CMPT_YZ 117
|
||||
#define TOK_CMPT_ZX 118
|
||||
#define TOK_CMPT_ZY 119
|
||||
#define TOK_CMPT_ZZ 120
|
||||
#define TOK_CMPT_II 121
|
||||
#define TOK_TRANSPOSE 122
|
||||
#define TOK_DIAG 123
|
||||
#define TOK_POINT_TO_FACE 124
|
||||
#define TOK_FACE_TO_POINT 125
|
||||
|
||||
@ -42,6 +42,7 @@ Description
|
||||
*/
|
||||
%include
|
||||
{
|
||||
#include "exprScanToken.H"
|
||||
#include "patchExprDriver.H"
|
||||
#include "patchExprParser.H"
|
||||
#include "patchExprScanner.H"
|
||||
@ -77,11 +78,8 @@ tmp_management()
|
||||
%token_prefix TOK_
|
||||
|
||||
// Terminals
|
||||
%token_type {Foam::expressions::patchExpr::scanToken*}
|
||||
// Non-terminals
|
||||
%type ivalue { Foam::label }
|
||||
%type svalue { Foam::scalar }
|
||||
%type ident { Foam::word* }
|
||||
%token_type {Foam::expressions::scanToken}
|
||||
%token_destructor { ($$).destroy(); }
|
||||
|
||||
// Face fields
|
||||
declare_field(lfield, Foam::boolField, bool, newField, getSurfaceField)
|
||||
@ -104,17 +102,33 @@ declare_field(ptfield, Foam::tensorField, Foam::tensor, newPointField, getPointF
|
||||
// Lemon does not generate a destructor for that.
|
||||
// So do not use Lemon destructors for anything.
|
||||
|
||||
standard_tokens()
|
||||
operator_precedence()
|
||||
|
||||
%start_symbol evaluate
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%type identifier { Foam::word* }
|
||||
%destructor identifier { delete($$); $$ = nullptr; }
|
||||
|
||||
identifier (lhs) ::= IDENTIFIER (tok) .
|
||||
{
|
||||
// Take ownership of pointer from scan token
|
||||
lhs = tok.name_; tok.name_ = nullptr;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (scalar)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
svalue (lhs) ::= NUMBER (a) . { lhs = (a)->svalue; } // From scanToken
|
||||
%type svalue { Foam::scalar }
|
||||
|
||||
svalue (lhs) ::= NUMBER (tok) . { lhs = (tok).scalarValue; } // scanToken
|
||||
svalue (lhs) ::= ZERO . { lhs = Foam::Zero; }
|
||||
svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; }
|
||||
svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
|
||||
@ -123,6 +137,38 @@ svalue (lhs) ::= ARG LPAREN RPAREN . { lhs = driver->argValue(); }
|
||||
svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
|
||||
svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
||||
|
||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
lhs = driver->getFunctionValue<Foam::scalar>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (vector)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%type vvalue { Foam::vector* }
|
||||
%destructor vvalue { delete($$); $$ = nullptr; }
|
||||
|
||||
vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
||||
{
|
||||
// Take ownership of pointer from scan token
|
||||
lhs = tok.vectorPtr; tok.vectorPtr = nullptr;
|
||||
}
|
||||
|
||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
auto val = driver->getFunctionValue<Foam::vector>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
lhs = new Foam::vector(val);
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * Face Fields * * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
@ -138,7 +184,9 @@ dnl
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (scalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [sfield])dnl
|
||||
define([_new_target_], [_new_sfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -156,9 +204,9 @@ rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but works directly for scalarField
|
||||
rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
||||
@ -174,20 +222,34 @@ _target_ (lhs) ::= RAND LPAREN RPAREN.
|
||||
_target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN.
|
||||
{
|
||||
// Call with -ve seed to signal use of time index as seed
|
||||
lhs = driver->field_rand(std::round(-(seed)->svalue)).ptr();
|
||||
lhs = driver->field_rand(std::round(-(seed).scalarValue)).ptr();
|
||||
}
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (vectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [vfield])dnl
|
||||
define([_new_target_], [_new_vfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, vvalue)
|
||||
rule_get_field(_target_, VECTOR_ID)
|
||||
rule_get_field(_target_, SVECTOR_ID)
|
||||
rule_get_patchfields(_target_, _value_type_, VECTOR_ID)
|
||||
@ -197,11 +259,26 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
// Other functions
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (sphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [hfield])dnl
|
||||
define([_new_target_], [_new_hfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -221,7 +298,9 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (symmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [yfield])dnl
|
||||
define([_new_target_], [_new_yfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -241,7 +320,9 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (tensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [tfield])dnl
|
||||
define([_new_target_], [_new_tfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -303,7 +384,9 @@ dnl
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point scalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [psfield])dnl
|
||||
define([_new_target_], [_new_psfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -319,24 +402,38 @@ rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but works directly for scalarField
|
||||
rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point vectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [pvfield])dnl
|
||||
define([_new_target_], [_new_pvfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
rule_field_from_value(_target_, vvalue, POINT_EXPR)
|
||||
rule_get_field(_target_, PVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
@ -344,10 +441,22 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point sphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [phfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
@ -366,6 +475,7 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point symmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [pyfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
@ -384,6 +494,7 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point tensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [ptfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
@ -544,13 +655,15 @@ void Foam::expressions::patchExpr::parser::start(parseDriver& driver_)
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::patchExpr::parser::parse
|
||||
(
|
||||
int tokenId,
|
||||
scanToken* tokenVal
|
||||
)
|
||||
void Foam::expressions::patchExpr::parser::parse(int tokenId)
|
||||
{
|
||||
Parse(lemon_, tokenId, tokenVal);
|
||||
Parse(lemon_, tokenId, scanToken::null());
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::patchExpr::parser::parse(int tokenId, scanToken tok)
|
||||
{
|
||||
Parse(lemon_, tokenId, tok);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -59,6 +59,23 @@ rule_driver_unary_named($1, SN_GRAD, $3, patchNormalField, $2)dnl
|
||||
|
||||
define([rules_driver_surface_functions],
|
||||
[dnl
|
||||
_logic_ (lhs) ::= CELL_SET LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_cellSet(make_obj(name)).ptr();
|
||||
}dnl
|
||||
_logic_ (lhs) ::= CELL_ZONE LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_cellZone(make_obj(name)).ptr();
|
||||
}dnl
|
||||
_logic_ (lhs) ::= FACE_SET LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_faceSet(make_obj(name)).ptr();
|
||||
}dnl
|
||||
_logic_ (lhs) ::= FACE_ZONE LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_faceZone(make_obj(name)).ptr();
|
||||
}dnl
|
||||
dnl
|
||||
rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl
|
||||
rule_driver_nullary(_vector_, POS, field_faceCentre)dnl FACE_CENTRE
|
||||
rule_driver_nullary(_vector_, FACE_EXPR, field_areaNormal)dnl
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,6 +34,7 @@ Description
|
||||
#ifndef expressions_patchExprParser_H
|
||||
#define expressions_patchExprParser_H
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "patchExprFwd.H"
|
||||
|
||||
namespace Foam
|
||||
@ -97,8 +98,11 @@ public:
|
||||
//- Stop parsing, freeing the allocated parser
|
||||
void stop();
|
||||
|
||||
//- Push token/value to parser
|
||||
void parse(int tokenId, scanToken* tokenVal);
|
||||
//- Push token type to parser with default token
|
||||
void parse(int tokenId);
|
||||
|
||||
//- Push token type/value to parser
|
||||
void parse(int tokenId, scanToken tok);
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,8 +37,8 @@ Note
|
||||
#ifndef expressions_patchExprScanner_H
|
||||
#define expressions_patchExprScanner_H
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "patchExprFwd.H"
|
||||
#include "scalar.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
@ -47,21 +47,6 @@ namespace expressions
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanToken Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
union scanToken
|
||||
{
|
||||
Foam::label ivalue;
|
||||
Foam::scalar svalue;
|
||||
Foam::word* name;
|
||||
|
||||
//- Default construct, bit-wise zero for union content
|
||||
scanToken() : ivalue(0) {}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanner Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -83,16 +68,14 @@ class scanner
|
||||
bool dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
//- Dispatch identifier to parser (if possible) or Fatal
|
||||
bool dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "patchExprScanner.H"
|
||||
#include "patchExprDriver.H"
|
||||
#include "patchExprLemonParser.h"
|
||||
@ -42,7 +43,6 @@ Description
|
||||
#undef DebugInfo
|
||||
#define DebugInfo if (debug & 0x2) InfoErr
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -55,9 +55,20 @@ namespace Foam
|
||||
#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name }
|
||||
|
||||
//- An {int, c_str} enum pairing for field types
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
|
||||
#define HAS_LOOKBEHIND_TOKENS
|
||||
// Special handling for these known (stashed) look-back types
|
||||
static const Enum<int> lookBehindTokenEnums
|
||||
({
|
||||
TOKEN_PAIR("cellZone", CELL_ZONE), TOKEN_PAIR("cellSet", CELL_SET),
|
||||
TOKEN_PAIR("faceZone", FACE_ZONE), TOKEN_PAIR("faceSet", FACE_SET),
|
||||
#ifdef TOK_POINT_ZONE
|
||||
TOKEN_PAIR("pointZone", POINT_ZONE), TOKEN_PAIR("pointSet", POINT_SET),
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
#undef HAS_LOOKBEHIND_TOKENS
|
||||
|
||||
// Special handling of predefined method types. Eg, .x(), .y(), ...
|
||||
static const Enum<int> fieldMethodEnums
|
||||
@ -176,7 +187,7 @@ static int driverTokenType
|
||||
const word& ident
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Get stashed "look-behind" to decide what type of identifier we expect
|
||||
const int lookBehind = driver_.resetStashedTokenId();
|
||||
|
||||
@ -186,12 +197,17 @@ static int driverTokenType
|
||||
|
||||
switch (lookBehind)
|
||||
{
|
||||
case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
|
||||
case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
|
||||
case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
|
||||
case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
|
||||
case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
|
||||
|
||||
case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
|
||||
case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
|
||||
|
||||
#ifdef TOK_POINT_ZONE
|
||||
// Not yet ready or particularly useful it seems
|
||||
case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
|
||||
case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (good)
|
||||
@ -207,51 +223,49 @@ static int driverTokenType
|
||||
|
||||
return -2; // Extra safety
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Face variables
|
||||
#ifdef TOK_SSCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_SSCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_SVECTOR_ID, vector);
|
||||
checkFieldToken(TOK_SSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_SSPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_STENSOR_ID, tensor);
|
||||
|
||||
// Not tested: checkFieldToken(TOK_SBOOL_ID, bool);
|
||||
doLocalCode(TOK_SSCALAR_ID, scalar);
|
||||
doLocalCode(TOK_SVECTOR_ID, vector);
|
||||
doLocalCode(TOK_SSYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_SSPH_TENSOR_ID, sphericalTensor);
|
||||
doLocalCode(TOK_STENSOR_ID, tensor);
|
||||
// Untested: doLocalCode(TOK_SBOOL_ID, bool);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
// Point variables
|
||||
#ifdef TOK_PSCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, true)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, true)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_PSCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_PVECTOR_ID, vector);
|
||||
checkFieldToken(TOK_PTENSOR_ID, tensor);
|
||||
checkFieldToken(TOK_PTENSOR_ID, tensor);
|
||||
checkFieldToken(TOK_PSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_PSPH_TENSOR_ID, sphericalTensor);
|
||||
|
||||
// Not tested: checkFieldToken(TOK_PBOOL_ID, bool);
|
||||
doLocalCode(TOK_PSCALAR_ID, scalar);
|
||||
doLocalCode(TOK_PVECTOR_ID, vector);
|
||||
doLocalCode(TOK_PTENSOR_ID, tensor);
|
||||
doLocalCode(TOK_PTENSOR_ID, tensor);
|
||||
doLocalCode(TOK_PSYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_PSPH_TENSOR_ID, sphericalTensor);
|
||||
// Untested: doLocalCode(TOK_SBOOL_ID, bool);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef checkFieldToken
|
||||
|
||||
// Check registered fields and/or disk-files
|
||||
{
|
||||
const word fieldType(driver_.getFieldClassName(ident));
|
||||
@ -267,7 +281,7 @@ static int driverTokenType
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // End anonymous namespace
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
@ -280,7 +294,15 @@ static int driverTokenType
|
||||
#define EMIT_TOKEN(T) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
|
||||
parser_->parse(TOKEN_OF(T), nullptr); \
|
||||
parser_->parse(TOKEN_OF(T)); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
#define EMIT_VECTOR_TOKEN(X, Y, Z) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< "VECTOR at " << driver_.parsePosition() << nl; \
|
||||
scanToken scanTok; \
|
||||
scanTok.setVector(X,Y,Z); \
|
||||
parser_->parse(TOK_VECTOR_VALUE, scanTok); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
|
||||
@ -289,15 +311,18 @@ static int driverTokenType
|
||||
write data;
|
||||
|
||||
action emit_number {
|
||||
// Emit number
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
|
||||
DebugInfo
|
||||
<< "Number:" << std::string(ts, te-ts).c_str()
|
||||
<< " at " << driver_.parsePosition() << nl;
|
||||
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.svalue))
|
||||
scanToken scanTok;
|
||||
scanTok.setScalar(0);
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.scalarValue))
|
||||
{
|
||||
parser_->parse(TOKEN_OF(NUMBER), &scanTok);
|
||||
parser_->parse(TOKEN_OF(NUMBER), scanTok);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -311,33 +336,38 @@ static int driverTokenType
|
||||
}
|
||||
|
||||
action emit_ident {
|
||||
// Emit identifier
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_ident(driver_, scanTok, word(ts, te-ts, false));
|
||||
dispatch_ident(driver_, word(ts, te-ts, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
action emit_method {
|
||||
// Tokenized ".method" - dispatch '.' and "method" separately
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_method(driver_, scanTok, word(ts+1, te-ts-1, false));
|
||||
dispatch_method(driver_, word(ts+1, te-ts-1, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
dquoted = '"' [^\"]+ '"' ;
|
||||
squoted = "'" [^\']+ "'" ;
|
||||
|
||||
## Allow 'fn:' prefix for function identifier
|
||||
ident = ('fn:')? identifier ;
|
||||
|
||||
## ===========
|
||||
## The scanner
|
||||
## ===========
|
||||
main := |*
|
||||
space*;
|
||||
|
||||
number => emit_number;
|
||||
|
||||
## Operators
|
||||
'!' =>{ EMIT_TOKEN(NOT); };
|
||||
'!' =>{ EMIT_TOKEN(LNOT); };
|
||||
'%' =>{ EMIT_TOKEN(PERCENT); };
|
||||
'(' =>{ EMIT_TOKEN(LPAREN); };
|
||||
')' =>{ EMIT_TOKEN(RPAREN); };
|
||||
@ -358,7 +388,7 @@ static int driverTokenType
|
||||
'&&' =>{ EMIT_TOKEN(LAND); };
|
||||
'||' =>{ EMIT_TOKEN(LOR); };
|
||||
'&' =>{ EMIT_TOKEN(BIT_AND); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OK); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OR); };
|
||||
'^' =>{ EMIT_TOKEN(BIT_XOR); };
|
||||
|
||||
## Some '.method' - Error if unknown
|
||||
@ -417,9 +447,12 @@ static int driverTokenType
|
||||
"sphericalTensor" =>{ EMIT_TOKEN(SPH_TENSOR); };
|
||||
|
||||
## Single value (constants, etc)
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"true" =>{ EMIT_TOKEN(LTRUE); };
|
||||
"false" =>{ EMIT_TOKEN(LFALSE); };
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"vector::x" =>{ EMIT_VECTOR_TOKEN(1,0,0); };
|
||||
"vector::y" =>{ EMIT_VECTOR_TOKEN(0,1,0); };
|
||||
"vector::z" =>{ EMIT_VECTOR_TOKEN(0,0,1); };
|
||||
"tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
|
||||
"arg" =>{ EMIT_TOKEN(ARG); };
|
||||
"time" =>{ EMIT_TOKEN(TIME); };
|
||||
@ -452,8 +485,7 @@ Foam::expressions::patchExpr::scanner::~scanner()
|
||||
bool Foam::expressions::patchExpr::scanner::dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
if (ident[0] == '.')
|
||||
@ -470,8 +502,8 @@ bool Foam::expressions::patchExpr::scanner::dispatch_method
|
||||
if (methType > 0)
|
||||
{
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -484,10 +516,11 @@ bool Foam::expressions::patchExpr::scanner::dispatch_method
|
||||
bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
// Peek at stashed "look-behind". It may influence decisions
|
||||
int lookBehindTok = driver_.stashedTokenId();
|
||||
int tokType = -1;
|
||||
|
||||
const bool quoted =
|
||||
@ -512,12 +545,12 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " function:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Specials such "cset" also reset the look-behind
|
||||
// Specials such "cellSet" etc also reset the look-behind
|
||||
tokType = lookBehindTokenEnums.lookup(ident, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
@ -527,17 +560,44 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
driver_.resetStashedTokenId(tokType);
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Functions: scalar, vector, probably don't need others
|
||||
// - "fn:" prefix to avoid any ambiguities
|
||||
if (lookBehindTok <= 0 && ident.starts_with("fn:"))
|
||||
{
|
||||
word funcName(ident.substr(3)); // strip prefix
|
||||
|
||||
// Can also peek at stashed "look-behind"
|
||||
// const int lookBehind = driver_.stashedTokenId();
|
||||
do
|
||||
{
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isFunction<Type>(funcName)) \
|
||||
{ \
|
||||
ident = std::move(funcName); \
|
||||
tokType = TokType; \
|
||||
break; \
|
||||
}
|
||||
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
#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);
|
||||
}
|
||||
|
||||
if (tokType <= 0)
|
||||
{
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
}
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
@ -545,8 +605,9 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " token:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -578,12 +639,13 @@ bool Foam::expressions::patchExpr::scanner::dispatch_ident
|
||||
// The field (before the ".")
|
||||
ident.erase(dot);
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -646,9 +708,6 @@ bool Foam::expressions::patchExpr::scanner::process
|
||||
|
||||
parser_->start(driver_);
|
||||
|
||||
// Scan token type
|
||||
scanToken scanTok;
|
||||
|
||||
// Token start/end (Ragel naming)
|
||||
const char* ts;
|
||||
const char* te;
|
||||
@ -678,7 +737,7 @@ bool Foam::expressions::patchExpr::scanner::process
|
||||
}
|
||||
|
||||
// Terminate parser execution
|
||||
parser_->parse(0, nullptr);
|
||||
parser_->parse(0);
|
||||
parser_->stop();
|
||||
|
||||
if (debug & 0x6)
|
||||
|
||||
@ -45,13 +45,13 @@ Foam::expressions::volumeExpr::parseDriver::field_cellSelection
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
refPtr<labelList> tselected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLZONE_SOURCE:
|
||||
case topoSetSource::sourceType::CELLSET_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
tselected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -63,6 +63,7 @@ Foam::expressions::volumeExpr::parseDriver::field_cellSelection
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto& selected = tselected();
|
||||
|
||||
auto& fld = tresult.ref().primitiveFieldRef();
|
||||
UIndirectList<scalar>(fld, selected) = scalar(1);
|
||||
@ -85,13 +86,13 @@ Foam::expressions::volumeExpr::parseDriver::field_faceSelection
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
refPtr<labelList> tselected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::FACESET_SOURCE:
|
||||
case topoSetSource::sourceType::FACEZONE_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
tselected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -103,6 +104,7 @@ Foam::expressions::volumeExpr::parseDriver::field_faceSelection
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto& selected = tselected();
|
||||
|
||||
const auto& bmesh = mesh().boundaryMesh();
|
||||
|
||||
@ -160,13 +162,13 @@ Foam::expressions::volumeExpr::parseDriver::field_pointSelection
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
refPtr<labelList> tselected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::POINTSET_SOURCE:
|
||||
case topoSetSource::sourceType::POINTZONE_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
tselected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -178,6 +180,7 @@ Foam::expressions::volumeExpr::parseDriver::field_pointSelection
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto& selected = tselected();
|
||||
|
||||
auto& fld = tresult.ref().primitiveFieldRef();
|
||||
UIndirectList<scalar>(fld, selected) = scalar(1);
|
||||
|
||||
@ -47,7 +47,6 @@ namespace volumeExpr
|
||||
class parser;
|
||||
class scanner;
|
||||
class parseDriver;
|
||||
union scanToken;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
@ -1,121 +1,126 @@
|
||||
#define TOK_QUESTION 1
|
||||
#define TOK_COLON 2
|
||||
#define TOK_LOR 3
|
||||
#define TOK_LAND 4
|
||||
#define TOK_BIT_XOR 5
|
||||
#define TOK_BIT_AND 6
|
||||
#define TOK_EQUAL 7
|
||||
#define TOK_NOT_EQUAL 8
|
||||
#define TOK_LESS_EQ 9
|
||||
#define TOK_GREATER_EQ 10
|
||||
#define TOK_LESS 11
|
||||
#define TOK_GREATER 12
|
||||
#define TOK_PLUS 13
|
||||
#define TOK_MINUS 14
|
||||
#define TOK_TIMES 15
|
||||
#define TOK_DIVIDE 16
|
||||
#define TOK_PERCENT 17
|
||||
#define TOK_NEGATE 18
|
||||
#define TOK_NOT 19
|
||||
#define TOK_DOT 20
|
||||
#define TOK_NUMBER 21
|
||||
#define TOK_ZERO 22
|
||||
#define TOK_PI 23
|
||||
#define TOK_LPAREN 24
|
||||
#define TOK_RPAREN 25
|
||||
#define TOK_DEG_TO_RAD 26
|
||||
#define TOK_RAD_TO_DEG 27
|
||||
#define TOK_ARG 28
|
||||
#define TOK_TIME 29
|
||||
#define TOK_DELTA_T 30
|
||||
#define TOK_SCALAR_ID 31
|
||||
#define TOK_MIN 32
|
||||
#define TOK_COMMA 33
|
||||
#define TOK_MAX 34
|
||||
#define TOK_SUM 35
|
||||
#define TOK_AVERAGE 36
|
||||
#define TOK_EXP 37
|
||||
#define TOK_LOG 38
|
||||
#define TOK_LOG10 39
|
||||
#define TOK_SQR 40
|
||||
#define TOK_SQRT 41
|
||||
#define TOK_CBRT 42
|
||||
#define TOK_SIN 43
|
||||
#define TOK_COS 44
|
||||
#define TOK_TAN 45
|
||||
#define TOK_ASIN 46
|
||||
#define TOK_ACOS 47
|
||||
#define TOK_ATAN 48
|
||||
#define TOK_SINH 49
|
||||
#define TOK_COSH 50
|
||||
#define TOK_TANH 51
|
||||
#define TOK_POW 52
|
||||
#define TOK_ATAN2 53
|
||||
#define TOK_POS 54
|
||||
#define TOK_NEG 55
|
||||
#define TOK_POS0 56
|
||||
#define TOK_NEG0 57
|
||||
#define TOK_SIGN 58
|
||||
#define TOK_FLOOR 59
|
||||
#define TOK_CEIL 60
|
||||
#define TOK_ROUND 61
|
||||
#define TOK_HYPOT 62
|
||||
#define TOK_RAND 63
|
||||
#define TOK_VECTOR_ID 64
|
||||
#define TOK_SPH_TENSOR_ID 65
|
||||
#define TOK_SYM_TENSOR_ID 66
|
||||
#define TOK_IDENTITY_TENSOR 67
|
||||
#define TOK_TENSOR_ID 68
|
||||
#define TOK_LTRUE 69
|
||||
#define TOK_LFALSE 70
|
||||
#define TOK_BOOL 71
|
||||
#define TOK_CELL_SET 72
|
||||
#define TOK_IDENTIFIER 73
|
||||
#define TOK_CELL_ZONE 74
|
||||
#define TOK_CELL_VOLUME 75
|
||||
#define TOK_WEIGHT_AVERAGE 76
|
||||
#define TOK_WEIGHT_SUM 77
|
||||
#define TOK_FACE_EXPR 78
|
||||
#define TOK_SSCALAR_ID 79
|
||||
#define TOK_SVECTOR_ID 80
|
||||
#define TOK_SSPH_TENSOR_ID 81
|
||||
#define TOK_SSYM_TENSOR_ID 82
|
||||
#define TOK_STENSOR_ID 83
|
||||
#define TOK_FACE_SET 84
|
||||
#define TOK_FACE_ZONE 85
|
||||
#define TOK_FACE_AREA 86
|
||||
#define TOK_FACE_CENTRE 87
|
||||
#define TOK_POINT_EXPR 88
|
||||
#define TOK_PSCALAR_ID 89
|
||||
#define TOK_PVECTOR_ID 90
|
||||
#define TOK_PSPH_TENSOR_ID 91
|
||||
#define TOK_PSYM_TENSOR_ID 92
|
||||
#define TOK_PTENSOR_ID 93
|
||||
#define TOK_POINT_SET 94
|
||||
#define TOK_POINT_ZONE 95
|
||||
#define TOK_POINTS 96
|
||||
#define TOK_MAG 97
|
||||
#define TOK_MAGSQR 98
|
||||
#define TOK_VECTOR 99
|
||||
#define TOK_TENSOR 100
|
||||
#define TOK_SYM_TENSOR 101
|
||||
#define TOK_SPH_TENSOR 102
|
||||
#define TOK_CMPT_X 103
|
||||
#define TOK_CMPT_Y 104
|
||||
#define TOK_CMPT_Z 105
|
||||
#define TOK_CMPT_XX 106
|
||||
#define TOK_CMPT_XY 107
|
||||
#define TOK_CMPT_XZ 108
|
||||
#define TOK_CMPT_YX 109
|
||||
#define TOK_CMPT_YY 110
|
||||
#define TOK_CMPT_YZ 111
|
||||
#define TOK_CMPT_ZX 112
|
||||
#define TOK_CMPT_ZY 113
|
||||
#define TOK_CMPT_ZZ 114
|
||||
#define TOK_CMPT_II 115
|
||||
#define TOK_TRANSPOSE 116
|
||||
#define TOK_DIAG 117
|
||||
#define TOK_POINT_TO_CELL 118
|
||||
#define TOK_RECONSTRUCT 119
|
||||
#define TOK_CELL_TO_FACE 120
|
||||
#define TOK_CELL_TO_POINT 121
|
||||
#define TOK_LPAREN 1
|
||||
#define TOK_RPAREN 2
|
||||
#define TOK_COMMA 3
|
||||
#define TOK_QUESTION 4
|
||||
#define TOK_COLON 5
|
||||
#define TOK_LOR 6
|
||||
#define TOK_LAND 7
|
||||
#define TOK_LNOT 8
|
||||
#define TOK_BIT_OR 9
|
||||
#define TOK_BIT_XOR 10
|
||||
#define TOK_BIT_AND 11
|
||||
#define TOK_BIT_NOT 12
|
||||
#define TOK_EQUAL 13
|
||||
#define TOK_NOT_EQUAL 14
|
||||
#define TOK_LESS 15
|
||||
#define TOK_LESS_EQ 16
|
||||
#define TOK_GREATER 17
|
||||
#define TOK_GREATER_EQ 18
|
||||
#define TOK_PLUS 19
|
||||
#define TOK_MINUS 20
|
||||
#define TOK_TIMES 21
|
||||
#define TOK_DIVIDE 22
|
||||
#define TOK_PERCENT 23
|
||||
#define TOK_NEGATE 24
|
||||
#define TOK_DOT 25
|
||||
#define TOK_BOOL 26
|
||||
#define TOK_LTRUE 27
|
||||
#define TOK_LFALSE 28
|
||||
#define TOK_NUMBER 29
|
||||
#define TOK_ZERO 30
|
||||
#define TOK_IDENTIFIER 31
|
||||
#define TOK_PI 32
|
||||
#define TOK_DEG_TO_RAD 33
|
||||
#define TOK_RAD_TO_DEG 34
|
||||
#define TOK_ARG 35
|
||||
#define TOK_TIME 36
|
||||
#define TOK_DELTA_T 37
|
||||
#define TOK_SCALAR_FUNCTION_ID 38
|
||||
#define TOK_VECTOR_VALUE 39
|
||||
#define TOK_VECTOR_FUNCTION_ID 40
|
||||
#define TOK_SCALAR_ID 41
|
||||
#define TOK_MIN 42
|
||||
#define TOK_MAX 43
|
||||
#define TOK_SUM 44
|
||||
#define TOK_AVERAGE 45
|
||||
#define TOK_EXP 46
|
||||
#define TOK_LOG 47
|
||||
#define TOK_LOG10 48
|
||||
#define TOK_SQR 49
|
||||
#define TOK_SQRT 50
|
||||
#define TOK_CBRT 51
|
||||
#define TOK_SIN 52
|
||||
#define TOK_COS 53
|
||||
#define TOK_TAN 54
|
||||
#define TOK_ASIN 55
|
||||
#define TOK_ACOS 56
|
||||
#define TOK_ATAN 57
|
||||
#define TOK_SINH 58
|
||||
#define TOK_COSH 59
|
||||
#define TOK_TANH 60
|
||||
#define TOK_POW 61
|
||||
#define TOK_ATAN2 62
|
||||
#define TOK_POS 63
|
||||
#define TOK_NEG 64
|
||||
#define TOK_POS0 65
|
||||
#define TOK_NEG0 66
|
||||
#define TOK_SIGN 67
|
||||
#define TOK_FLOOR 68
|
||||
#define TOK_CEIL 69
|
||||
#define TOK_ROUND 70
|
||||
#define TOK_HYPOT 71
|
||||
#define TOK_RAND 72
|
||||
#define TOK_VECTOR_ID 73
|
||||
#define TOK_SPH_TENSOR_ID 74
|
||||
#define TOK_SYM_TENSOR_ID 75
|
||||
#define TOK_IDENTITY_TENSOR 76
|
||||
#define TOK_TENSOR_ID 77
|
||||
#define TOK_CELL_SET 78
|
||||
#define TOK_CELL_ZONE 79
|
||||
#define TOK_CELL_VOLUME 80
|
||||
#define TOK_WEIGHT_AVERAGE 81
|
||||
#define TOK_WEIGHT_SUM 82
|
||||
#define TOK_FACE_EXPR 83
|
||||
#define TOK_SSCALAR_ID 84
|
||||
#define TOK_SVECTOR_ID 85
|
||||
#define TOK_SSPH_TENSOR_ID 86
|
||||
#define TOK_SSYM_TENSOR_ID 87
|
||||
#define TOK_STENSOR_ID 88
|
||||
#define TOK_FACE_SET 89
|
||||
#define TOK_FACE_ZONE 90
|
||||
#define TOK_FACE_AREA 91
|
||||
#define TOK_FACE_CENTRE 92
|
||||
#define TOK_POINT_EXPR 93
|
||||
#define TOK_PSCALAR_ID 94
|
||||
#define TOK_PVECTOR_ID 95
|
||||
#define TOK_PSPH_TENSOR_ID 96
|
||||
#define TOK_PSYM_TENSOR_ID 97
|
||||
#define TOK_PTENSOR_ID 98
|
||||
#define TOK_POINT_SET 99
|
||||
#define TOK_POINT_ZONE 100
|
||||
#define TOK_POINTS 101
|
||||
#define TOK_MAG 102
|
||||
#define TOK_MAGSQR 103
|
||||
#define TOK_VECTOR 104
|
||||
#define TOK_TENSOR 105
|
||||
#define TOK_SYM_TENSOR 106
|
||||
#define TOK_SPH_TENSOR 107
|
||||
#define TOK_CMPT_X 108
|
||||
#define TOK_CMPT_Y 109
|
||||
#define TOK_CMPT_Z 110
|
||||
#define TOK_CMPT_XX 111
|
||||
#define TOK_CMPT_XY 112
|
||||
#define TOK_CMPT_XZ 113
|
||||
#define TOK_CMPT_YX 114
|
||||
#define TOK_CMPT_YY 115
|
||||
#define TOK_CMPT_YZ 116
|
||||
#define TOK_CMPT_ZX 117
|
||||
#define TOK_CMPT_ZY 118
|
||||
#define TOK_CMPT_ZZ 119
|
||||
#define TOK_CMPT_II 120
|
||||
#define TOK_TRANSPOSE 121
|
||||
#define TOK_DIAG 122
|
||||
#define TOK_POINT_TO_CELL 123
|
||||
#define TOK_RECONSTRUCT 124
|
||||
#define TOK_CELL_TO_FACE 125
|
||||
#define TOK_CELL_TO_POINT 126
|
||||
|
||||
@ -42,6 +42,7 @@ Description
|
||||
*/
|
||||
%include
|
||||
{
|
||||
#include "exprScanToken.H"
|
||||
#include "volumeExprDriver.H"
|
||||
#include "volumeExprParser.H"
|
||||
#include "volumeExprScanner.H"
|
||||
@ -110,11 +111,8 @@ dnl
|
||||
%token_prefix TOK_
|
||||
|
||||
// Terminals
|
||||
%token_type {Foam::expressions::volumeExpr::scanToken*}
|
||||
// Non-terminals
|
||||
%type ivalue { Foam::label }
|
||||
%type svalue { Foam::scalar }
|
||||
%type ident { Foam::word* }
|
||||
%token_type {Foam::expressions::scanToken}
|
||||
%token_destructor { ($$).destroy(); }
|
||||
|
||||
// Volume fields
|
||||
declare_field(lfield, Foam::volScalarField, Foam::scalar, newVolField, getVolField)
|
||||
@ -144,17 +142,34 @@ declare_field(ptfield, Foam::pointTensorField, Foam::tensor, newPointField, getP
|
||||
// Lemon does not generate a destructor for that.
|
||||
// So do not use Lemon destructors for anything.
|
||||
|
||||
standard_tokens()
|
||||
operator_precedence()
|
||||
|
||||
%start_symbol evaluate
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%type identifier { Foam::word* }
|
||||
%destructor identifier { delete($$); $$ = nullptr; }
|
||||
|
||||
identifier (lhs) ::= IDENTIFIER (tok) .
|
||||
{
|
||||
// Take ownership of pointer from scan token
|
||||
lhs = tok.name_; tok.name_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (scalar)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
svalue (lhs) ::= NUMBER (a) . { lhs = (a)->svalue; } // From scanToken
|
||||
%type svalue { Foam::scalar }
|
||||
|
||||
svalue (lhs) ::= NUMBER (tok) . { lhs = (tok).scalarValue; } // scanToken
|
||||
svalue (lhs) ::= ZERO . { lhs = Foam::Zero; }
|
||||
svalue (lhs) ::= PI LPAREN RPAREN . { lhs = Foam::constant::mathematical::pi; }
|
||||
svalue (lhs) ::= DEG_TO_RAD LPAREN RPAREN . { lhs = Foam::degToRad(); }
|
||||
@ -163,6 +178,39 @@ svalue (lhs) ::= ARG LPAREN RPAREN . { lhs = driver->argValue(); }
|
||||
svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
|
||||
svalue (lhs) ::= DELTA_T LPAREN RPAREN . { lhs = driver->deltaT(); }
|
||||
|
||||
svalue (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
lhs = driver->getFunctionValue<Foam::scalar>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (vector)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
%type vvalue { Foam::vector* }
|
||||
%destructor vvalue { delete($$); $$ = nullptr; }
|
||||
|
||||
vvalue (lhs) ::= VECTOR_VALUE (tok) .
|
||||
{
|
||||
// Take ownership of pointer from scan token
|
||||
lhs = tok.vectorPtr; tok.vectorPtr = nullptr;
|
||||
}
|
||||
|
||||
vvalue (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN RPAREN .
|
||||
{
|
||||
auto val = driver->getFunctionValue<Foam::vector>
|
||||
(
|
||||
make_obj(name.name_),
|
||||
driver->timeValue()
|
||||
);
|
||||
lhs = new Foam::vector(val);
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * Volume Fields * * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
@ -178,7 +226,9 @@ dnl
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volScalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [sfield])dnl
|
||||
define([_new_target_], [_new_sfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -194,12 +244,12 @@ rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<_value_type_>())
|
||||
|
||||
|
||||
// Other functions
|
||||
@ -212,20 +262,34 @@ _target_ (lhs) ::= RAND LPAREN RPAREN .
|
||||
_target_ (lhs) ::= RAND LPAREN NUMBER (seed) RPAREN .
|
||||
{
|
||||
// Call with -ve seed to signal use of time index as seed
|
||||
lhs = driver->field_rand(std::round(-(seed)->svalue)).ptr();
|
||||
lhs = driver->field_rand(std::round(-(seed).scalarValue)).ptr();
|
||||
}
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volVectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [vfield])dnl
|
||||
define([_new_target_], [_new_vfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, vvalue)
|
||||
rule_get_field(_target_, VECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
@ -233,9 +297,24 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
// Other functions
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volSphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [hfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
@ -253,6 +332,7 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volSymmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [yfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
@ -269,6 +349,7 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [sfield])dnl
|
||||
define([_target_], [tfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
@ -326,7 +407,9 @@ dnl> %ifndef disable_surface_fields
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceScalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [ssfield])dnl
|
||||
define([_target_], [ssfield])dnl
|
||||
define([_new_target_], [_new_ssfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -342,24 +425,38 @@ rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<_value_type_>())
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceVectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [ssfield])dnl
|
||||
define([_target_], [svfield])dnl
|
||||
define([_new_target_], [_new_svfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, vvalue, FACE_EXPR)
|
||||
rule_get_field(_target_, SVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
@ -367,10 +464,22 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceSphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [ssfield])dnl
|
||||
define([_target_], [shfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
@ -388,6 +497,7 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceSymmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [ssfield])dnl
|
||||
define([_target_], [syfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
@ -406,6 +516,7 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [ssfield])dnl
|
||||
define([_target_], [stfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
@ -470,7 +581,9 @@ dnl> %ifndef disable_point_fields
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointScalarField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [psfield])dnl
|
||||
define([_new_target_], [_new_psfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -484,12 +597,23 @@ rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<Foam::scalar>())
|
||||
rule_unary_assign(_target_, _target_, FLOOR, Foam::floorOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, CEIL, Foam::ceilOp<_value_type_>())
|
||||
rule_unary_assign(_target_, _target_, ROUND, Foam::roundOp<_value_type_>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<_value_type_>())
|
||||
|
||||
_target_ (lhs) ::= SCALAR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
@ -542,13 +666,16 @@ dnl*/
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointVectorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [pvfield])dnl
|
||||
define([_new_target_], [_new_pvfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, vvalue, POINT_EXPR)
|
||||
rule_get_field(_target_, PVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
@ -556,9 +683,21 @@ rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
_target_ (lhs) ::= VECTOR_FUNCTION_ID (name) LPAREN _scalar_arg_ (values) RPAREN.
|
||||
{
|
||||
lhs = _new_target_;
|
||||
driver->fillFunctionValues<_value_type_>
|
||||
(
|
||||
*lhs,
|
||||
make_obj(name.name_),
|
||||
make_obj(values)
|
||||
);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointSphericalTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [phfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
@ -577,6 +716,7 @@ rules_sphTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointSymmTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [pyfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
@ -595,6 +735,7 @@ rules_symTensor_functions()
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointTensorField)
|
||||
dnl
|
||||
define([_scalar_arg_], [psfield])dnl
|
||||
define([_target_], [ptfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
@ -802,13 +943,15 @@ void Foam::expressions::volumeExpr::parser::start(parseDriver& driver_)
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::volumeExpr::parser::parse
|
||||
(
|
||||
int tokenId,
|
||||
scanToken* tokenVal
|
||||
)
|
||||
void Foam::expressions::volumeExpr::parser::parse(int tokenId)
|
||||
{
|
||||
Parse(lemon_, tokenId, tokenVal);
|
||||
Parse(lemon_, tokenId, scanToken::null());
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::volumeExpr::parser::parse(int tokenId, scanToken tok)
|
||||
{
|
||||
Parse(lemon_, tokenId, tok);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -34,8 +34,14 @@ divert(-1)dnl
|
||||
|
||||
define([rules_driver_volume_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, CELL_SET, field_cellSet)dnl
|
||||
rule_driver_select(_logic_, CELL_ZONE, field_cellZone)dnl
|
||||
_logic_ (lhs) ::= CELL_SET LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_cellSet(make_obj(name)).ptr();dnl
|
||||
}dnl
|
||||
_logic_ (lhs) ::= CELL_ZONE LPAREN identifier (name) RPAREN .dnl
|
||||
{
|
||||
lhs = driver->field_cellZone(make_obj(name)).ptr();dnl
|
||||
}dnl
|
||||
dnl
|
||||
rule_driver_nullary(_scalar_, CELL_VOLUME, field_cellVolume)dnl
|
||||
rule_driver_nullary(_vector_, POS, field_cellCentre)dnl CELL_CENTRE
|
||||
@ -56,8 +62,14 @@ dnl
|
||||
|
||||
define([rules_driver_surface_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, FACE_SET, field_faceSet)dnl
|
||||
rule_driver_select(_logic_, FACE_ZONE, field_faceZone)dnl
|
||||
_logic_ (lhs) ::= FACE_SET LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_faceSet(make_obj(name)).ptr();dnl
|
||||
}dnl
|
||||
_logic_ (lhs) ::= FACE_ZONE LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_faceZone(make_obj(name)).ptr();dnl
|
||||
}dnl
|
||||
dnl
|
||||
rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl
|
||||
rule_driver_nullary(_vector_, FACE_CENTRE, field_faceCentre)dnl
|
||||
@ -79,8 +91,14 @@ dnl
|
||||
|
||||
define([rules_driver_point_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, POINT_SET, field_pointSet)dnl
|
||||
rule_driver_select(_logic_, POINT_ZONE, field_pointZone)dnl
|
||||
_logic_ (lhs) ::= POINT_SET LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_pointSet(make_obj(*name)).ptr();dnl
|
||||
}dnl
|
||||
_logic_ (lhs) ::= POINT_ZONE LPAREN identifier (name) RPAREN .dnl
|
||||
{dnl
|
||||
lhs = driver->field_pointZone(make_obj(*name)).ptr();dnl
|
||||
}dnl
|
||||
dnl
|
||||
rule_driver_nullary(_vector_, POINTS, field_pointField)dnl
|
||||
dnl
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,6 +34,7 @@ Description
|
||||
#ifndef expressions_volumeExprParser_H
|
||||
#define expressions_volumeExprParser_H
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "volumeExprFwd.H"
|
||||
|
||||
namespace Foam
|
||||
@ -97,8 +98,11 @@ public:
|
||||
//- Stop parsing, freeing the allocated parser
|
||||
void stop();
|
||||
|
||||
//- Push token/value to parser
|
||||
void parse(int tokenId, scanToken* tokenVal);
|
||||
//- Push token type to parser with default token
|
||||
void parse(int tokenId);
|
||||
|
||||
//- Push token type/value to parser
|
||||
void parse(int tokenId, scanToken tok);
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,8 +37,8 @@ Note
|
||||
#ifndef expressions_volumeExprScanner_H
|
||||
#define expressions_volumeExprScanner_H
|
||||
|
||||
#include "exprScanToken.H"
|
||||
#include "volumeExprFwd.H"
|
||||
#include "scalar.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
@ -47,21 +47,6 @@ namespace expressions
|
||||
namespace volumeExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanToken Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
union scanToken
|
||||
{
|
||||
Foam::label ivalue;
|
||||
Foam::scalar svalue;
|
||||
Foam::word* name;
|
||||
|
||||
//- Default construct, bit-wise zero for union content
|
||||
scanToken() : ivalue(0) {}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanner Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -83,16 +68,14 @@ class scanner
|
||||
bool dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
//- Dispatch identifier to parser (if possible) or Fatal
|
||||
bool dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident // Receives a copy
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,6 @@ Description
|
||||
#undef DebugInfo
|
||||
#define DebugInfo if (debug & 0x2) InfoErr
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -55,22 +54,20 @@ namespace Foam
|
||||
#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name }
|
||||
|
||||
//- An {int, c_str} enum pairing for field types
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
#define FIELD_PAIR(Fld,T) { TOKEN_OF(T), Fld::typeName.c_str() }
|
||||
|
||||
|
||||
// Special handling for these known (stashed) look-back types
|
||||
#define HAS_LOOKBEHIND_TOKENS
|
||||
static const Enum<int> lookBehindTokenEnums
|
||||
({
|
||||
TOKEN_PAIR("cellSet", CELL_SET),
|
||||
TOKEN_PAIR("faceSet", FACE_SET),
|
||||
TOKEN_PAIR("pointSet", POINT_SET),
|
||||
TOKEN_PAIR("cellZone", CELL_ZONE),
|
||||
TOKEN_PAIR("faceZone", FACE_ZONE),
|
||||
TOKEN_PAIR("pointZone", POINT_ZONE),
|
||||
TOKEN_PAIR("cellZone", CELL_ZONE), TOKEN_PAIR("cellSet", CELL_SET),
|
||||
TOKEN_PAIR("faceZone", FACE_ZONE), TOKEN_PAIR("faceSet", FACE_SET),
|
||||
#ifdef TOK_POINT_ZONE
|
||||
TOKEN_PAIR("pointZone", POINT_ZONE), TOKEN_PAIR("pointSet", POINT_SET),
|
||||
#endif
|
||||
});
|
||||
|
||||
#define HAS_LOOKBEHIND_TOKENS
|
||||
|
||||
|
||||
// Special handling of predefined method types. Eg, .x(), .y(), ...
|
||||
static const Enum<int> fieldMethodEnums
|
||||
@ -192,6 +189,7 @@ static int driverTokenType
|
||||
const word& ident
|
||||
)
|
||||
{
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Get stashed "look-behind" to decide what type of identifier we expect
|
||||
const int lookBehind = driver_.resetStashedTokenId();
|
||||
|
||||
@ -201,12 +199,16 @@ static int driverTokenType
|
||||
|
||||
switch (lookBehind)
|
||||
{
|
||||
case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
|
||||
case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
|
||||
case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
|
||||
case TOK_CELL_ZONE : good = driver_.isCellZone(ident); break;
|
||||
case TOK_CELL_SET : good = driver_.isCellSet(ident); break;
|
||||
|
||||
case TOK_FACE_ZONE : good = driver_.isFaceZone(ident); break;
|
||||
case TOK_FACE_SET : good = driver_.isFaceSet(ident); break;
|
||||
|
||||
#ifdef TOK_POINT_ZONE
|
||||
case TOK_POINT_ZONE : good = driver_.isPointZone(ident); break;
|
||||
case TOK_POINT_SET : good = driver_.isPointSet(ident); break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (good)
|
||||
@ -222,65 +224,67 @@ static int driverTokenType
|
||||
|
||||
return -2; // Extra safety
|
||||
}
|
||||
#endif
|
||||
|
||||
// Surface variables - distinguish from volume by size
|
||||
#ifdef TOK_SSCALAR_ID
|
||||
{
|
||||
const label len = driver_.mesh().nInternalFaces();
|
||||
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false, len)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false, len)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_SSCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_SVECTOR_ID, vector);
|
||||
checkFieldToken(TOK_SSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_SSPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_STENSOR_ID, tensor);
|
||||
doLocalCode(TOK_SSCALAR_ID, scalar);
|
||||
doLocalCode(TOK_SVECTOR_ID, vector);
|
||||
doLocalCode(TOK_SSYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_SSPH_TENSOR_ID, sphericalTensor);
|
||||
doLocalCode(TOK_STENSOR_ID, tensor);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
// Point variables
|
||||
#ifdef TOK_PSCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, true)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, true)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_PSCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_PVECTOR_ID, vector);
|
||||
checkFieldToken(TOK_PSPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_PSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_PTENSOR_ID, tensor);
|
||||
doLocalCode(TOK_PSCALAR_ID, scalar);
|
||||
doLocalCode(TOK_PVECTOR_ID, vector);
|
||||
doLocalCode(TOK_PSPH_TENSOR_ID, sphericalTensor);
|
||||
doLocalCode(TOK_PSYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_PTENSOR_ID, tensor);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
// Volume variables
|
||||
#ifdef TOK_SCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_SCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_VECTOR_ID, vector);
|
||||
checkFieldToken(TOK_SPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_SYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_TENSOR_ID, tensor);
|
||||
doLocalCode(TOK_SCALAR_ID, scalar);
|
||||
doLocalCode(TOK_VECTOR_ID, vector);
|
||||
doLocalCode(TOK_SPH_TENSOR_ID, sphericalTensor);
|
||||
doLocalCode(TOK_SYM_TENSOR_ID, symmTensor);
|
||||
doLocalCode(TOK_TENSOR_ID, tensor);
|
||||
#undef doLocalCode
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef checkFieldToken
|
||||
|
||||
// Check registered fields and/or disk-files
|
||||
{
|
||||
const word fieldType(driver_.getFieldClassName(ident));
|
||||
@ -296,7 +300,7 @@ static int driverTokenType
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // End anonymous namespace
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
@ -309,7 +313,16 @@ static int driverTokenType
|
||||
#define EMIT_TOKEN(T) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< STRINGIFY(T) << " at " << driver_.parsePosition() << nl; \
|
||||
parser_->parse(TOKEN_OF(T), nullptr); \
|
||||
parser_->parse(TOKEN_OF(T)); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
|
||||
#define EMIT_VECTOR_TOKEN(X, Y, Z) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< "VECTOR at " << driver_.parsePosition() << nl; \
|
||||
scanToken scanTok; \
|
||||
scanTok.setVector(X,Y,Z); \
|
||||
parser_->parse(TOK_VECTOR_VALUE, scanTok); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
|
||||
@ -318,15 +331,18 @@ static int driverTokenType
|
||||
write data;
|
||||
|
||||
action emit_number {
|
||||
// Emit number
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
|
||||
DebugInfo
|
||||
<< "Number:" << std::string(ts, te-ts).c_str()
|
||||
<< " at " << driver_.parsePosition() << nl;
|
||||
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.svalue))
|
||||
scanToken scanTok;
|
||||
scanTok.setScalar(0);
|
||||
if (readScalar(std::string(ts, te-ts), scanTok.scalarValue))
|
||||
{
|
||||
parser_->parse(TOKEN_OF(NUMBER), &scanTok);
|
||||
parser_->parse(TOKEN_OF(NUMBER), scanTok);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -340,33 +356,38 @@ static int driverTokenType
|
||||
}
|
||||
|
||||
action emit_ident {
|
||||
// Emit identifier
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_ident(driver_, scanTok, word(ts, te-ts, false));
|
||||
dispatch_ident(driver_, word(ts, te-ts, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
action emit_method {
|
||||
// Tokenized ".method" - dispatch '.' and "method" separately
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_method(driver_, scanTok, word(ts+1, te-ts-1, false));
|
||||
dispatch_method(driver_, word(ts+1, te-ts-1, false));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
identifier = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
dquoted = '"' [^\"]+ '"' ;
|
||||
squoted = "'" [^\']+ "'" ;
|
||||
|
||||
## Allow 'fn:' prefix for function identifier
|
||||
ident = ('fn:')? identifier ;
|
||||
|
||||
## ===========
|
||||
## The scanner
|
||||
## ===========
|
||||
main := |*
|
||||
space*;
|
||||
|
||||
number => emit_number;
|
||||
|
||||
## Operators
|
||||
'!' =>{ EMIT_TOKEN(NOT); };
|
||||
'!' =>{ EMIT_TOKEN(LNOT); };
|
||||
'%' =>{ EMIT_TOKEN(PERCENT); };
|
||||
'(' =>{ EMIT_TOKEN(LPAREN); };
|
||||
')' =>{ EMIT_TOKEN(RPAREN); };
|
||||
@ -387,7 +408,7 @@ static int driverTokenType
|
||||
'&&' =>{ EMIT_TOKEN(LAND); };
|
||||
'||' =>{ EMIT_TOKEN(LOR); };
|
||||
'&' =>{ EMIT_TOKEN(BIT_AND); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OK); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OR); };
|
||||
'^' =>{ EMIT_TOKEN(BIT_XOR); };
|
||||
|
||||
## Some '.method' - Error if unknown
|
||||
@ -441,9 +462,12 @@ static int driverTokenType
|
||||
"sphericalTensor" =>{ EMIT_TOKEN(SPH_TENSOR); };
|
||||
|
||||
## Single value (constants, etc)
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"true" =>{ EMIT_TOKEN(LTRUE); };
|
||||
"false" =>{ EMIT_TOKEN(LFALSE); };
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"vector::x" =>{ EMIT_VECTOR_TOKEN(1,0,0); };
|
||||
"vector::y" =>{ EMIT_VECTOR_TOKEN(0,1,0); };
|
||||
"vector::z" =>{ EMIT_VECTOR_TOKEN(0,0,1); };
|
||||
"tensor::I" =>{ EMIT_TOKEN(IDENTITY_TENSOR); };
|
||||
"arg" =>{ EMIT_TOKEN(ARG); };
|
||||
"time" =>{ EMIT_TOKEN(TIME); };
|
||||
@ -476,8 +500,7 @@ Foam::expressions::volumeExpr::scanner::~scanner()
|
||||
bool Foam::expressions::volumeExpr::scanner::dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
if (ident[0] == '.')
|
||||
@ -494,8 +517,8 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_method
|
||||
if (methType > 0)
|
||||
{
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -508,10 +531,11 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_method
|
||||
bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
word ident
|
||||
) const
|
||||
{
|
||||
// Peek at stashed "look-behind". It may influence decisions
|
||||
int lookBehindTok = driver_.stashedTokenId();
|
||||
int tokType = -1;
|
||||
|
||||
const bool quoted =
|
||||
@ -536,12 +560,12 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " function:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Specials such "cset" also reset the look-behind
|
||||
// Specials such "cellSet" etc also reset the look-behind
|
||||
tokType = lookBehindTokenEnums.lookup(ident, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
@ -551,17 +575,44 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
driver_.resetStashedTokenId(tokType);
|
||||
parser_->parse(tokType, nullptr);
|
||||
parser_->parse(tokType);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Functions: scalar, vector, probably don't need others
|
||||
// - "fn:" prefix to avoid any ambiguities
|
||||
if (lookBehindTok <= 0 && ident.starts_with("fn:"))
|
||||
{
|
||||
word funcName(ident.substr(3)); // strip prefix
|
||||
|
||||
// Can also peek at stashed "look-behind"
|
||||
// const int lookBehind = driver_.stashedTokenId();
|
||||
do
|
||||
{
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokType, Type) \
|
||||
if (driver_.isFunction<Type>(funcName)) \
|
||||
{ \
|
||||
ident = std::move(funcName); \
|
||||
tokType = TokType; \
|
||||
break; \
|
||||
}
|
||||
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
#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);
|
||||
}
|
||||
|
||||
if (tokType <= 0)
|
||||
{
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
}
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
@ -569,8 +620,9 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
<< "Emit:" << ident << " token:"
|
||||
<< parser_->tokenName(tokType) << nl;
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -602,12 +654,13 @@ bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
// The field (before the ".")
|
||||
ident.erase(dot);
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
scanToken scanTok;
|
||||
scanTok.setWord(ident);
|
||||
parser_->parse(tokType, scanTok);
|
||||
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
parser_->parse(TOK_DOT);
|
||||
parser_->parse(methType);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -670,9 +723,6 @@ bool Foam::expressions::volumeExpr::scanner::process
|
||||
|
||||
parser_->start(driver_);
|
||||
|
||||
// Scan token type
|
||||
scanToken scanTok;
|
||||
|
||||
// Token start/end (Ragel naming)
|
||||
const char* ts;
|
||||
const char* te;
|
||||
@ -702,7 +752,7 @@ bool Foam::expressions::volumeExpr::scanner::process
|
||||
}
|
||||
|
||||
// Terminate parser execution
|
||||
parser_->parse(0, nullptr);
|
||||
parser_->parse(0);
|
||||
parser_->stop();
|
||||
|
||||
if (debug & 0x6)
|
||||
|
||||
Reference in New Issue
Block a user