mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: driver/parser/scanner for volume expressions
This commit is contained in:
@ -265,6 +265,13 @@ $(patchExpr)/patchExprDriverFields.C
|
||||
$(patchExpr)/patchExprLemonParser.lyy-m4
|
||||
$(patchExpr)/patchExprScanner.cc
|
||||
|
||||
volumeExpr = $(expr)/volume
|
||||
$(volumeExpr)/volumeExpr.C
|
||||
$(volumeExpr)/volumeExprDriver.C
|
||||
$(volumeExpr)/volumeExprDriverFields.C
|
||||
$(volumeExpr)/volumeExprLemonParser.lyy-m4
|
||||
$(volumeExpr)/volumeExprScanner.cc
|
||||
|
||||
|
||||
fvMatrices/fvMatrices.C
|
||||
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
|
||||
|
||||
@ -96,7 +96,7 @@ Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
bool cacheReadFields,
|
||||
bool searchInMemory,
|
||||
bool searchOnDisc,
|
||||
bool searchFiles,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
@ -104,7 +104,7 @@ Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
cacheReadFields,
|
||||
searchInMemory,
|
||||
searchOnDisc,
|
||||
searchFiles,
|
||||
dict
|
||||
),
|
||||
globalScopes_(),
|
||||
@ -142,7 +142,7 @@ Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
dict.lookupOrDefault("cacheReadFields", false),
|
||||
dict.lookupOrDefault("searchInMemory", true),
|
||||
dict.lookupOrDefault("searchOnDisc", false),
|
||||
dict.lookupOrDefault("searchFiles", false),
|
||||
dict
|
||||
)
|
||||
{
|
||||
@ -603,7 +603,7 @@ Foam::word Foam::expressions::fvExprDriver::getFieldClassName
|
||||
}
|
||||
}
|
||||
|
||||
if (searchOnDisc())
|
||||
if (searchFiles())
|
||||
{
|
||||
return getHeaderClassName(this->mesh(), name);
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ public:
|
||||
(
|
||||
bool cacheReadFields = false,
|
||||
bool searchInMemory = true,
|
||||
bool searchOnDisc = false,
|
||||
bool searchFiles = false,
|
||||
const dictionary& dict = dictionary::null
|
||||
);
|
||||
|
||||
|
||||
@ -140,8 +140,8 @@ bool Foam::expressions::fvExprDriver::foundField
|
||||
{
|
||||
Info<< "fvExprDriver::foundField. Name: " << name
|
||||
<< " Type: " << Type::typeName
|
||||
<< " search memory:" << searchInMemory()
|
||||
<< " disc:" << searchOnDisc() << endl;
|
||||
<< " registry:" << searchInMemory()
|
||||
<< " disk:" << searchFiles() << endl;
|
||||
}
|
||||
|
||||
// if (std::is_void<Type>::value) ...
|
||||
@ -155,30 +155,29 @@ bool Foam::expressions::fvExprDriver::foundField
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name << " in memory" << endl;
|
||||
Info<< "Found registered: " << name << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "No " << name << " of type " << Type::typeName
|
||||
<< " found in memory";
|
||||
Info<< "Registered " << name;
|
||||
|
||||
if (ioptr)
|
||||
{
|
||||
Info<< " but of type " << ioptr->headerClassName();
|
||||
Info<< " type:" << ioptr->headerClassName();
|
||||
}
|
||||
Info<< endl;
|
||||
Info<< ", not type:" << Type::typeName << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (searchOnDisc() && getTypeOfField(name) == Type::typeName)
|
||||
if (searchFiles() && getTypeOfField(name) == Type::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name << " on disc" << endl;
|
||||
Info<< "Found file: " << name << nl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -326,7 +325,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting " << name << " from memory" << endl;
|
||||
Info<< "Retrieve registered: " << name << nl;
|
||||
}
|
||||
|
||||
const GeomField& origFld = obr.lookupObject<GeomField>(name);
|
||||
@ -356,7 +355,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (searchOnDisc() && getTypeOfField(name) == GeomField::typeName)
|
||||
else if (searchFiles() && getTypeOfField(name) == GeomField::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
@ -415,7 +414,7 @@ Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Could not find field " << name
|
||||
<< " in memory or on disc" << endl
|
||||
<< " in registry or on file-system" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
13
src/finiteVolume/expressions/volume/createCode
Executable file
13
src/finiteVolume/expressions/volume/createCode
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # Run from this directory
|
||||
# Manually create ragel scanner and lemon parser header
|
||||
|
||||
prefix=volumeExpr
|
||||
|
||||
"${WM_PROJECT_DIR:?}/wmake/scripts/makeParser" \
|
||||
-prefix="$prefix" \
|
||||
-scanner=Scanner.rl \
|
||||
-parser=LemonParser.lyy-m4 \
|
||||
"$@"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
44
src/finiteVolume/expressions/volume/volumeExpr.C
Normal file
44
src/finiteVolume/expressions/volume/volumeExpr.C
Normal file
@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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 "volumeExprFwd.H"
|
||||
#include "defineDebugSwitch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Globals * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
defineDebugSwitchWithName(volumeExpr, "volumeExpr", 0);
|
||||
registerDebugSwitchWithName(volumeExpr, volumeExpr, "volumeExpr");
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
226
src/finiteVolume/expressions/volume/volumeExprDriver.C
Normal file
226
src/finiteVolume/expressions/volume/volumeExprDriver.C
Normal file
@ -0,0 +1,226 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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 "volumeExprDriver.H"
|
||||
#include "volumeExprScanner.H"
|
||||
#include "error.H"
|
||||
#include "fvPatch.H"
|
||||
#include "fvMesh.H"
|
||||
#include "className.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace volumeExpr
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(parseDriver, 0);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
dictionary,
|
||||
volume
|
||||
);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
idName,
|
||||
volume
|
||||
);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
dictionary,
|
||||
internalField
|
||||
);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
idName,
|
||||
internalField
|
||||
);
|
||||
|
||||
} // End namespace volumeExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
static label getPatchID(const fvMesh& mesh, const word& patchName)
|
||||
{
|
||||
const auto& bMesh = mesh.boundaryMesh();
|
||||
|
||||
const label patchId = bMesh.findPatchID(patchName);
|
||||
|
||||
if (patchId < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No patch " << patchName << " found in "
|
||||
<< flatOutput(bMesh.names()) << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
return patchId;
|
||||
}
|
||||
|
||||
|
||||
static inline const polyPatch& findPolyPatch
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& patchName
|
||||
)
|
||||
{
|
||||
return mesh.boundaryMesh()[getPatchID(mesh, patchName)];
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
bool cacheReadFields
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(cacheReadFields),
|
||||
mesh_(mesh),
|
||||
resultType_(),
|
||||
isLogical_(false),
|
||||
fieldGeoType_(NO_DATA),
|
||||
resultDimension_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(dict),
|
||||
mesh_(mesh),
|
||||
resultType_(),
|
||||
isLogical_(false),
|
||||
fieldGeoType_(NO_DATA),
|
||||
resultDimension_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const parseDriver& driver
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(driver),
|
||||
mesh_(mesh),
|
||||
resultType_(),
|
||||
isLogical_(false),
|
||||
fieldGeoType_(NO_DATA),
|
||||
resultDimension_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||
(
|
||||
const word& meshName,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
:
|
||||
parseDriver(mesh)
|
||||
{
|
||||
//?? Info<< "Warn that meshName is ignored?" << nl;
|
||||
}
|
||||
|
||||
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(dict),
|
||||
mesh_(mesh),
|
||||
resultType_(),
|
||||
isLogical_(false),
|
||||
fieldGeoType_(NO_DATA),
|
||||
resultDimension_()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::volumeExpr::parseDriver::readDict
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
expressions::fvExprDriver::readDict(dict);
|
||||
dict.readIfPresent("dimensions", resultDimension_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
unsigned Foam::expressions::volumeExpr::parseDriver::parse
|
||||
(
|
||||
const std::string& expr,
|
||||
size_t pos,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
scanner scan(this->debugScanner());
|
||||
|
||||
scan.process(expr, pos, len, *this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
510
src/finiteVolume/expressions/volume/volumeExprDriver.H
Normal file
510
src/finiteVolume/expressions/volume/volumeExprDriver.H
Normal file
@ -0,0 +1,510 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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::volumeExpr::parseDriver
|
||||
|
||||
Description
|
||||
Driver for volume, surface, point field expressions
|
||||
|
||||
Additional Properties
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
dimensions | Dimensions for the expression result | no |
|
||||
\endtable
|
||||
|
||||
In addition to the standard mathematical functions, operations and
|
||||
logical and relational operations, the volume expression support the
|
||||
following driver-specific functions:
|
||||
|
||||
Functions
|
||||
\table
|
||||
Function | Description | Number of arguments |
|
||||
vol | The cell volumes | 0 |
|
||||
pos | The cell centres | 0 |
|
||||
pts | The cell points | 0 |
|
||||
area | The face area magnitudes | 0 |
|
||||
fpos | The face centres | 0 |
|
||||
weightAverage| Volume or area weighted average | 1 |
|
||||
weightSum | Volume or area weighted sum | 1 |
|
||||
face | The face areaNormal vectors | 0 |
|
||||
face | A surface-field face value | 1 |
|
||||
point | A point-field point value | 1 |
|
||||
cellToFace | Interpolate cell values onto faces | 1 |
|
||||
cellToPoint | Interpolate cell values onto points | 1 |
|
||||
pointToCell | Interpolate point values onto cells | 1 |
|
||||
reconstruct | Reconstruct cell vector from surface scalar | 1 |
|
||||
rand | Random field | 0/1 |
|
||||
\endtable
|
||||
|
||||
Selections
|
||||
\table
|
||||
Function| Description | Number of arguments |
|
||||
cset | Logical vol field corresponding to cellSet | 1 |
|
||||
fset | Logical surf field corresponding to faceSet | 1 |
|
||||
pset | Logical point field corresponding to pointSet | 1 |
|
||||
czone | Logical vol field corresponding to cellZone | 1 |
|
||||
fzone | Logical surf field corresponding to faceZone | 1 |
|
||||
pzone | Logical point field corresponding to pointZone| 1 |
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
volumeExprDriver.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_volumeExprDriver_H
|
||||
#define expressions_volumeExprDriver_H
|
||||
|
||||
#include "volumeExprFwd.H"
|
||||
#include "fvExprDriver.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "genericRagelLemonDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace volumeExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parseDriver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parseDriver
|
||||
:
|
||||
public parsing::genericRagelLemonDriver,
|
||||
public expressions::fvExprDriver
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The referenced mesh
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- The results (volume, surface, point)
|
||||
autoPtr<regIOobject> resultField_;
|
||||
|
||||
//- The result type-name.
|
||||
// Normally volScalarField, surfaceVectorField etc,
|
||||
// but Scalar is modified for logical as volScalarField etc
|
||||
word resultType_;
|
||||
|
||||
//- A logical (bool-like) field (but actually a scalar)
|
||||
bool isLogical_;
|
||||
|
||||
//- A volume/surface/point field
|
||||
enum FieldAssociation fieldGeoType_;
|
||||
|
||||
//- The result dimensions
|
||||
dimensionSet resultDimension_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Deep-copy the internalField as a result.
|
||||
// Uses the isLogical() and isPointData() values to handle
|
||||
// additional bookkeeping.
|
||||
// For isLogical(), renames the resultType_ from '*Scalar*'
|
||||
// to '*Logical*' (eg, volLogicalField)
|
||||
template<class Type>
|
||||
void setInternalFieldResult(const Field<Type>& fld);
|
||||
|
||||
//- Cell selections (as logical)
|
||||
tmp<volScalarField> field_cellSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
//- Face selections (as logical)
|
||||
tmp<surfaceScalarField> field_faceSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
//- Point selections (as logical)
|
||||
tmp<pointScalarField> field_pointSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
|
||||
// No copy copy construct
|
||||
parseDriver(const parseDriver&) = delete;
|
||||
|
||||
// No copy assignment
|
||||
void operator=(const parseDriver&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ClassName("volumeExpr::driver");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct for specified mesh
|
||||
explicit parseDriver
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
bool cacheReadFields = false
|
||||
);
|
||||
|
||||
//- Construct for specified mesh with given dictionary
|
||||
parseDriver(const fvMesh& mesh, const dictionary& dict);
|
||||
|
||||
//- Construct for specified mesh with copy of driver context
|
||||
parseDriver(const fvMesh& mesh, const parseDriver& driver);
|
||||
|
||||
//- Construct with meshName for the given mesh
|
||||
parseDriver(const word& meshName, const fvMesh& mesh);
|
||||
|
||||
//- Construct with patchName and region specified in dictionary
|
||||
parseDriver(const dictionary& dict, const fvMesh& mesh);
|
||||
|
||||
//- Clone
|
||||
virtual autoPtr<expressions::fvExprDriver> clone() const
|
||||
{
|
||||
return autoPtr<expressions::fvExprDriver>
|
||||
(
|
||||
new parseDriver(this->mesh_, *this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~parseDriver() = default;
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
//- The mesh we are attached to
|
||||
virtual const fvMesh& mesh() const
|
||||
{
|
||||
return mesh_;
|
||||
}
|
||||
|
||||
//- The underlying field size for the expression
|
||||
virtual label size() const
|
||||
{
|
||||
return mesh_.nCells();
|
||||
}
|
||||
|
||||
//- The underlying point field size for the expression
|
||||
virtual label pointSize() const
|
||||
{
|
||||
return mesh_.nPoints();
|
||||
}
|
||||
|
||||
//- Field size associated with different geometric field types
|
||||
inline label size(const FieldAssociation geoType) const;
|
||||
|
||||
|
||||
// Reading
|
||||
|
||||
//- Read variables, tables etc.
|
||||
// Adds support for "dimensions"
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Perform parsing on (sub) string
|
||||
using genericRagelLemonDriver::content;
|
||||
|
||||
//- Execute the parser
|
||||
virtual unsigned parse
|
||||
(
|
||||
const std::string& expr,
|
||||
size_t pos = 0,
|
||||
size_t len = std::string::npos
|
||||
);
|
||||
|
||||
|
||||
// Field Information
|
||||
|
||||
//- The result type-name.
|
||||
// Normally volScalarField, surfaceVectorField etc,
|
||||
// but Scalar is modified for logical as volScalarField etc
|
||||
const word& resultType() const
|
||||
{
|
||||
return resultType_;
|
||||
}
|
||||
|
||||
//- The geometric field association
|
||||
FieldAssociation fieldAssociation() const
|
||||
{
|
||||
return fieldGeoType_;
|
||||
}
|
||||
|
||||
//- A logical (bool-like) field. Actually stored as a scalar.
|
||||
bool isLogical() const
|
||||
{
|
||||
return isLogical_;
|
||||
}
|
||||
|
||||
//- A volume field
|
||||
bool isVolumeData() const
|
||||
{
|
||||
return fieldGeoType_ == FieldAssociation::VOLUME_DATA;
|
||||
}
|
||||
|
||||
//- A surface field
|
||||
bool isSurfaceData() const
|
||||
{
|
||||
return fieldGeoType_ == FieldAssociation::SURFACE_DATA;
|
||||
}
|
||||
|
||||
//- A point field
|
||||
bool isPointData() const
|
||||
{
|
||||
return fieldGeoType_ == FieldAssociation::POINT_DATA;
|
||||
}
|
||||
|
||||
//- Test if stored result pointer is the specified type
|
||||
template<class GeoField>
|
||||
const GeoField* isResultType() const;
|
||||
|
||||
//- Test if stored result pointer is the specified type
|
||||
//- and matches the specified logical type
|
||||
template<class GeoField>
|
||||
const GeoField* isResultType(bool logical, bool dieOnNull=false) const;
|
||||
|
||||
|
||||
// Set Fields
|
||||
|
||||
//- Set result (vol field)
|
||||
template<class Type>
|
||||
void setResult
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>* ptr,
|
||||
bool logical = false
|
||||
);
|
||||
|
||||
//- Set result (surface field)
|
||||
template<class Type>
|
||||
void setResult
|
||||
(
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh>* ptr,
|
||||
bool logical = false
|
||||
);
|
||||
|
||||
//- Set result (point field)
|
||||
template<class Type>
|
||||
void setResult
|
||||
(
|
||||
GeometricField<Type, pointPatchField, pointMesh>* ptr,
|
||||
bool logical = false
|
||||
);
|
||||
|
||||
|
||||
// New Fields
|
||||
|
||||
//- Return a new volume field with the mesh size
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
newVolField(const Type& val = pTraits<Type>::zero) const;
|
||||
|
||||
//- Return a new surface field with the mesh nInternalFaces size
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
|
||||
newSurfaceField(const Type& val = pTraits<Type>::zero) const;
|
||||
|
||||
//- Return a new point field with the mesh nPoints size
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, pointPatchField, pointMesh>>
|
||||
newPointField(const Type& val = pTraits<Type>::zero) const;
|
||||
|
||||
|
||||
//- Retrieve field (vol field)
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
getVolField(const word& fldName, bool getOldTime=false);
|
||||
|
||||
//- Retrieve field (surface field)
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
|
||||
getSurfaceField(const word& fldName, bool getOldTime=false);
|
||||
|
||||
//- Retrieve field (surface field)
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, pointPatchField, pointMesh>>
|
||||
getPointField(const word& fldName, bool getOldTime=false);
|
||||
|
||||
|
||||
// Field "shape" conversions
|
||||
|
||||
//- Interpolate cell to face values
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
|
||||
cellToFace
|
||||
(
|
||||
const GeometricField<Type,fvPatchField,volMesh>& field
|
||||
) const;
|
||||
|
||||
//- Interpolate cell to point values
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, pointPatchField, pointMesh>>
|
||||
cellToPoint
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& field
|
||||
) const;
|
||||
|
||||
//- Interpolate point to cell values
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
pointToCell
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& field
|
||||
) const;
|
||||
|
||||
|
||||
// Custom Field Functions
|
||||
|
||||
//- The volume-weighted average of a field
|
||||
template<class Type>
|
||||
Type volAverage
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
) const
|
||||
{
|
||||
return weightedAverage(fld.mesh().V(), fld.primitiveField());
|
||||
}
|
||||
|
||||
//- The volume-weighted sum of a field
|
||||
template<class Type>
|
||||
Type volSum
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
) const
|
||||
{
|
||||
return weightedSum(fld.mesh().V(), fld.primitiveField());
|
||||
}
|
||||
|
||||
//- The area-weighted average of a field
|
||||
template<class Type>
|
||||
Type areaAverage
|
||||
(
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh>& fld
|
||||
) const
|
||||
{
|
||||
return weightedAverage
|
||||
(
|
||||
fld.mesh().magSf().primitiveField(),
|
||||
fld.primitiveField()
|
||||
);
|
||||
}
|
||||
|
||||
//- The area-weighted sum of a field
|
||||
template<class Type>
|
||||
Type areaSum
|
||||
(
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh>& fld
|
||||
) const
|
||||
{
|
||||
return weightedSum
|
||||
(
|
||||
fld.mesh().magSf().primitiveField(),
|
||||
fld.primitiveField()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- The cell volumes - (swak = vol)
|
||||
tmp<volScalarField> field_cellVolume() const;
|
||||
|
||||
//- The cell centres - (swak = pos)
|
||||
tmp<volVectorField> field_cellCentre() const;
|
||||
|
||||
//- The face area magnitudes [magSf] - (swak = area)
|
||||
tmp<surfaceScalarField> field_faceArea() const;
|
||||
|
||||
//- The face centres - (swak = fpos)
|
||||
tmp<surfaceVectorField> field_faceCentre() const;
|
||||
|
||||
//- The face areas with their vector direction [Sf] - (swak = face)
|
||||
tmp<surfaceVectorField> field_areaNormal() const;
|
||||
|
||||
//- The mesh point locations - (swak = pts)
|
||||
tmp<pointVectorField> field_pointField() const;
|
||||
|
||||
|
||||
//- Cell selection (set)
|
||||
inline tmp<volScalarField> field_cellSet(const word& name) const;
|
||||
|
||||
//- Cell selection (zone)
|
||||
inline tmp<volScalarField> field_cellZone(const word& name) const;
|
||||
|
||||
//- Face selection (set)
|
||||
inline tmp<surfaceScalarField> field_faceSet(const word& name) const;
|
||||
|
||||
//- Face selection (zone)
|
||||
inline tmp<surfaceScalarField> field_faceZone(const word& name) const;
|
||||
|
||||
//- Point selection (set)
|
||||
inline tmp<pointScalarField> field_pointSet(const word& name) const;
|
||||
|
||||
//- Point selection (zone)
|
||||
inline tmp<pointScalarField> field_pointZone(const word& name) const;
|
||||
|
||||
//- A uniform random field
|
||||
tmp<volScalarField> field_rand(label seed=0, bool gaussian=false) const;
|
||||
|
||||
//- A Gaussian random field
|
||||
tmp<volScalarField> field_randGaussian(label seed=0) const
|
||||
{
|
||||
return field_rand(seed, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace volumeExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "volumeExprDriverI.H"
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "volumeExprDriverTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
283
src/finiteVolume/expressions/volume/volumeExprDriverFields.C
Normal file
283
src/finiteVolume/expressions/volume/volumeExprDriverFields.C
Normal file
@ -0,0 +1,283 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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 "volumeExprDriver.H"
|
||||
#include "fvPatch.H"
|
||||
#include "error.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::volScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_cellSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
auto tresult = volScalarField::New
|
||||
(
|
||||
"selected",
|
||||
mesh(),
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLZONE_SOURCE:
|
||||
case topoSetSource::sourceType::CELLSET_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto& fld = tresult.ref().primitiveFieldRef();
|
||||
UIndirectList<scalar>(fld, selected) = scalar(1);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::surfaceScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_faceSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
auto tresult = surfaceScalarField::New
|
||||
(
|
||||
"selected",
|
||||
mesh(),
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::FACESET_SOURCE:
|
||||
case topoSetSource::sourceType::FACEZONE_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& bmesh = mesh().boundaryMesh();
|
||||
|
||||
auto& result = tresult.ref();
|
||||
auto& fld = result.primitiveFieldRef();
|
||||
auto& bfld = result.boundaryFieldRef();
|
||||
|
||||
label nErrors = 0;
|
||||
|
||||
for (const label facei : selected)
|
||||
{
|
||||
if (facei < mesh().nInternalFaces())
|
||||
{
|
||||
fld[facei] = scalar(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const label patchi = bmesh.whichPatch(facei);
|
||||
|
||||
if (patchi < 0)
|
||||
{
|
||||
++nErrors;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfld[patchi][facei-bmesh[patchi].start()] = scalar(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nErrors)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "The faceSet/faceZone " << name << " contained "
|
||||
<< nErrors << " faces outside of the addressing range" << nl
|
||||
<< nl;
|
||||
}
|
||||
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_pointSelection
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
auto tresult = pointScalarField::New
|
||||
(
|
||||
"selected",
|
||||
pointMesh::New(mesh()),
|
||||
dimensionedScalar(Zero)
|
||||
);
|
||||
|
||||
labelList selected;
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::POINTSET_SOURCE:
|
||||
case topoSetSource::sourceType::POINTZONE_SOURCE:
|
||||
{
|
||||
selected = getTopoSetLabels(name, setType);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto& fld = tresult.ref().primitiveFieldRef();
|
||||
UIndirectList<scalar>(fld, selected) = scalar(1);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Foam::tmp<Foam::volScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_cellVolume() const
|
||||
{
|
||||
return volScalarField::New
|
||||
(
|
||||
"vol",
|
||||
mesh(),
|
||||
dimVol,
|
||||
mesh().V()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volVectorField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_cellCentre() const
|
||||
{
|
||||
return tmp<volVectorField>::New(mesh().C());
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::surfaceScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_faceArea() const
|
||||
{
|
||||
return surfaceScalarField::New
|
||||
(
|
||||
"face",
|
||||
mesh(),
|
||||
dimless,
|
||||
mesh().magSf()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::surfaceVectorField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_faceCentre() const
|
||||
{
|
||||
return surfaceVectorField::New
|
||||
(
|
||||
"fpos",
|
||||
mesh(),
|
||||
dimless,
|
||||
mesh().Cf()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::surfaceVectorField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_areaNormal() const
|
||||
{
|
||||
return surfaceVectorField::New
|
||||
(
|
||||
"face",
|
||||
mesh(),
|
||||
dimless,
|
||||
mesh().Sf()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::pointVectorField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_pointField() const
|
||||
{
|
||||
return pointVectorField::New
|
||||
(
|
||||
"pts",
|
||||
pointMesh::New(mesh()),
|
||||
dimless,
|
||||
mesh().points()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::volScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_rand
|
||||
(
|
||||
label seed,
|
||||
bool gaussian
|
||||
) const
|
||||
{
|
||||
auto tresult = volScalarField::New
|
||||
(
|
||||
"rand",
|
||||
mesh(),
|
||||
dimless
|
||||
);
|
||||
auto& fld = tresult.ref().primitiveFieldRef();
|
||||
|
||||
fill_random(fld, seed, gaussian);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
137
src/finiteVolume/expressions/volume/volumeExprDriverI.H
Normal file
137
src/finiteVolume/expressions/volume/volumeExprDriverI.H
Normal file
@ -0,0 +1,137 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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 Foam::label Foam::expressions::volumeExpr::parseDriver::size
|
||||
(
|
||||
const FieldAssociation geoType
|
||||
) const
|
||||
{
|
||||
switch (geoType)
|
||||
{
|
||||
case FieldAssociation::POINT_DATA :
|
||||
return mesh_.nPoints();
|
||||
break;
|
||||
case FieldAssociation::SURFACE_DATA :
|
||||
return mesh_.nInternalFaces();
|
||||
break;
|
||||
case FieldAssociation::VOLUME_DATA :
|
||||
return mesh_.nCells();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::volScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::parseDriver::field_cellSet
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_cellSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::CELLSET_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::volScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_cellZone
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_cellSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::CELLZONE_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::surfaceScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_faceSet
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_faceSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::FACESET_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::surfaceScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_faceZone
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_faceSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::FACEZONE_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::pointScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_pointSet
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_pointSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::POINTSET_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::tmp<Foam::pointScalarField>
|
||||
Foam::expressions::volumeExpr::parseDriver::field_pointZone
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return field_pointSelection
|
||||
(
|
||||
name,
|
||||
topoSetSource::sourceType::POINTZONE_SOURCE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
331
src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C
Normal file
331
src/finiteVolume/expressions/volume/volumeExprDriverTemplates.C
Normal file
@ -0,0 +1,331 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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 "exprOps.H"
|
||||
#include "FieldOps.H"
|
||||
#include "surfaceInterpolate.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "interpolatePointToCell.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::expressions::volumeExpr::parseDriver::setInternalFieldResult
|
||||
(
|
||||
const Field<Type>& fld
|
||||
)
|
||||
{
|
||||
if (isLogical_)
|
||||
{
|
||||
// Eg, volScalarField -> volLogicalField
|
||||
resultType_.replace("Scalar", "Logical");
|
||||
|
||||
Field<bool> bools(fld.size());
|
||||
FieldOps::assign(bools, fld, expressions::boolOp<Type>());
|
||||
|
||||
this->result().setResult(std::move(bools), this->isPointData());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deep copy
|
||||
this->result().setResult(fld, this->isPointData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::expressions::volumeExpr::parseDriver::setResult
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>* ptr,
|
||||
bool logical
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
resultField_.clear();
|
||||
|
||||
// Characteristics
|
||||
resultType_ = pTraits<fieldType>::typeName;
|
||||
isLogical_ = logical;
|
||||
fieldGeoType_ = VOLUME_DATA;
|
||||
|
||||
// Always strip out dimensions?
|
||||
if (!resultDimension_.dimensionless())
|
||||
{
|
||||
ptr->dimensions().reset(resultDimension_);
|
||||
}
|
||||
|
||||
setInternalFieldResult(ptr->primitiveField());
|
||||
|
||||
// Take ownership
|
||||
resultField_.reset(ptr);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::expressions::volumeExpr::parseDriver::setResult
|
||||
(
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh>* ptr,
|
||||
bool logical
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
|
||||
|
||||
resultField_.clear();
|
||||
|
||||
// Characteristics
|
||||
resultType_ = pTraits<fieldType>::typeName;
|
||||
isLogical_ = logical;
|
||||
fieldGeoType_ = SURFACE_DATA;
|
||||
|
||||
// Always strip out dimensions?
|
||||
if (!resultDimension_.dimensionless())
|
||||
{
|
||||
ptr->dimensions().reset(resultDimension_);
|
||||
}
|
||||
|
||||
setInternalFieldResult(ptr->primitiveField());
|
||||
|
||||
// Take ownership
|
||||
resultField_.reset(ptr);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::expressions::volumeExpr::parseDriver::setResult
|
||||
(
|
||||
GeometricField<Type, pointPatchField, pointMesh>* ptr,
|
||||
bool logical
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
|
||||
|
||||
resultField_.clear();
|
||||
|
||||
// Characteristics
|
||||
resultType_ = pTraits<fieldType>::typeName;
|
||||
isLogical_ = logical;
|
||||
fieldGeoType_ = POINT_DATA;
|
||||
|
||||
// Always strip out dimensions?
|
||||
if (!resultDimension_.dimensionless())
|
||||
{
|
||||
ptr->dimensions().reset(resultDimension_);
|
||||
}
|
||||
|
||||
setInternalFieldResult(ptr->primitiveField());
|
||||
|
||||
// Take ownership
|
||||
resultField_.reset(ptr);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
const GeomField*
|
||||
Foam::expressions::volumeExpr::parseDriver::isResultType() const
|
||||
{
|
||||
return dynamic_cast<const GeomField*>(resultField_.get());
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
const GeomField*
|
||||
Foam::expressions::volumeExpr::parseDriver::isResultType
|
||||
(
|
||||
bool logical,
|
||||
bool dieOnNull
|
||||
) const
|
||||
{
|
||||
const regIOobject* ptr = resultField_.get();
|
||||
|
||||
if (dieOnNull && ptr != nullptr)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No result available. Requested "
|
||||
<< pTraits<GeomField>::typeName << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (isLogical_ == logical)
|
||||
{
|
||||
return dynamic_cast<const GeomField*>(ptr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::getVolField
|
||||
(
|
||||
const word& fldName,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
return this->getOrReadField<fieldType>
|
||||
(
|
||||
fldName,
|
||||
true, // mandatory
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::getSurfaceField
|
||||
(
|
||||
const word& fldName,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
|
||||
|
||||
return this->getOrReadField<fieldType>
|
||||
(
|
||||
fldName,
|
||||
true, // mandatory
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::getPointField
|
||||
(
|
||||
const word& fldName,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
|
||||
|
||||
return this->getOrReadPointField<fieldType>
|
||||
(
|
||||
fldName,
|
||||
true, // mandatory
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::newVolField
|
||||
(
|
||||
const Type& val
|
||||
) const
|
||||
{
|
||||
return GeometricField<Type,fvPatchField,volMesh>::New
|
||||
(
|
||||
word("constant.") + word(pTraits<Type>::typeName),
|
||||
mesh(),
|
||||
dimensioned<Type>("", dimless, val)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::newSurfaceField
|
||||
(
|
||||
const Type& val
|
||||
) const
|
||||
{
|
||||
return GeometricField<Type,fvsPatchField,surfaceMesh>::New
|
||||
(
|
||||
word("constant.") + word(pTraits<Type>::typeName),
|
||||
mesh(),
|
||||
dimensioned<Type>("", dimless, val)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::newPointField
|
||||
(
|
||||
const Type& val
|
||||
) const
|
||||
{
|
||||
return GeometricField<Type,pointPatchField,pointMesh>::New
|
||||
(
|
||||
word("constant.") + word(pTraits<Type>::typeName),
|
||||
pointMesh::New(mesh()),
|
||||
dimensioned<Type>("", dimless, val)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::cellToFace
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& field
|
||||
) const
|
||||
{
|
||||
return fvc::interpolate(field);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::cellToPoint
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& field
|
||||
) const
|
||||
{
|
||||
volPointInterpolation interp(this->mesh());
|
||||
return interp.interpolate(field);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type,Foam::fvPatchField,Foam::volMesh>>
|
||||
Foam::expressions::volumeExpr::parseDriver::pointToCell
|
||||
(
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& field
|
||||
) const
|
||||
{
|
||||
auto tresult = newVolField<Type>();
|
||||
auto& result = tresult.ref();
|
||||
|
||||
forAll(result,celli)
|
||||
{
|
||||
result[celli] = interpolatePointToCell(field, celli);
|
||||
}
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
84
src/finiteVolume/expressions/volume/volumeExprFwd.H
Normal file
84
src/finiteVolume/expressions/volume/volumeExprFwd.H
Normal file
@ -0,0 +1,84 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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/>.
|
||||
|
||||
Namespace
|
||||
Foam::expressions::volumeExpr
|
||||
|
||||
Description
|
||||
Namespace for volume field expressions parsing and evaluation
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_volumeExprFwd_H
|
||||
#define expressions_volumeExprFwd_H
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace volumeExpr
|
||||
{
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Forward Declarations
|
||||
class parser;
|
||||
class scanner;
|
||||
class parseDriver;
|
||||
union scanToken;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
//- The field association for volume expressions (mutually exclusive)
|
||||
enum FieldAssociation : unsigned char
|
||||
{
|
||||
NO_DATA = 0, //!< No data
|
||||
POINT_DATA = 1, //!< Point data
|
||||
SURFACE_DATA = 2, //!< Surface data
|
||||
VOLUME_DATA = 3 //!< Volume data
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace volumeExpr
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Typedef for volumeExpr parseDriver
|
||||
typedef volumeExpr::parseDriver volumeExprDriver;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
119
src/finiteVolume/expressions/volume/volumeExprLemonParser.h
Normal file
119
src/finiteVolume/expressions/volume/volumeExprLemonParser.h
Normal file
@ -0,0 +1,119 @@
|
||||
#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_TIME 28
|
||||
#define TOK_SCALAR_ID 29
|
||||
#define TOK_MIN 30
|
||||
#define TOK_COMMA 31
|
||||
#define TOK_MAX 32
|
||||
#define TOK_SUM 33
|
||||
#define TOK_AVERAGE 34
|
||||
#define TOK_EXP 35
|
||||
#define TOK_LOG 36
|
||||
#define TOK_LOG10 37
|
||||
#define TOK_SQR 38
|
||||
#define TOK_SQRT 39
|
||||
#define TOK_CBRT 40
|
||||
#define TOK_SIN 41
|
||||
#define TOK_COS 42
|
||||
#define TOK_TAN 43
|
||||
#define TOK_ASIN 44
|
||||
#define TOK_ACOS 45
|
||||
#define TOK_ATAN 46
|
||||
#define TOK_SINH 47
|
||||
#define TOK_COSH 48
|
||||
#define TOK_TANH 49
|
||||
#define TOK_POW 50
|
||||
#define TOK_ATAN2 51
|
||||
#define TOK_POS 52
|
||||
#define TOK_NEG 53
|
||||
#define TOK_POS0 54
|
||||
#define TOK_NEG0 55
|
||||
#define TOK_SIGN 56
|
||||
#define TOK_FLOOR 57
|
||||
#define TOK_CEIL 58
|
||||
#define TOK_ROUND 59
|
||||
#define TOK_HYPOT 60
|
||||
#define TOK_RAND 61
|
||||
#define TOK_VECTOR_ID 62
|
||||
#define TOK_SPH_TENSOR_ID 63
|
||||
#define TOK_SYM_TENSOR_ID 64
|
||||
#define TOK_UNIT_TENSOR 65
|
||||
#define TOK_TENSOR_ID 66
|
||||
#define TOK_LTRUE 67
|
||||
#define TOK_LFALSE 68
|
||||
#define TOK_BOOL 69
|
||||
#define TOK_CSET 70
|
||||
#define TOK_IDENTIFIER 71
|
||||
#define TOK_CZONE 72
|
||||
#define TOK_CELL_VOLUME 73
|
||||
#define TOK_WEIGHT_AVERAGE 74
|
||||
#define TOK_WEIGHT_SUM 75
|
||||
#define TOK_FACE_EXPR 76
|
||||
#define TOK_SSCALAR_ID 77
|
||||
#define TOK_SVECTOR_ID 78
|
||||
#define TOK_SSPH_TENSOR_ID 79
|
||||
#define TOK_SSYM_TENSOR_ID 80
|
||||
#define TOK_STENSOR_ID 81
|
||||
#define TOK_FSET 82
|
||||
#define TOK_FZONE 83
|
||||
#define TOK_FACE_AREA 84
|
||||
#define TOK_FACE_CENTRE 85
|
||||
#define TOK_POINT_EXPR 86
|
||||
#define TOK_PSCALAR_ID 87
|
||||
#define TOK_PVECTOR_ID 88
|
||||
#define TOK_PSPH_TENSOR_ID 89
|
||||
#define TOK_PSYM_TENSOR_ID 90
|
||||
#define TOK_PTENSOR_ID 91
|
||||
#define TOK_PSET 92
|
||||
#define TOK_PZONE 93
|
||||
#define TOK_POINTS 94
|
||||
#define TOK_MAG 95
|
||||
#define TOK_MAGSQR 96
|
||||
#define TOK_VECTOR 97
|
||||
#define TOK_TENSOR 98
|
||||
#define TOK_SYM_TENSOR 99
|
||||
#define TOK_SPH_TENSOR 100
|
||||
#define TOK_CMPT_X 101
|
||||
#define TOK_CMPT_Y 102
|
||||
#define TOK_CMPT_Z 103
|
||||
#define TOK_CMPT_XX 104
|
||||
#define TOK_CMPT_XY 105
|
||||
#define TOK_CMPT_XZ 106
|
||||
#define TOK_CMPT_YX 107
|
||||
#define TOK_CMPT_YY 108
|
||||
#define TOK_CMPT_YZ 109
|
||||
#define TOK_CMPT_ZX 110
|
||||
#define TOK_CMPT_ZY 111
|
||||
#define TOK_CMPT_ZZ 112
|
||||
#define TOK_CMPT_II 113
|
||||
#define TOK_TRANSPOSE 114
|
||||
#define TOK_DIAG 115
|
||||
#define TOK_POINT_TO_CELL 116
|
||||
#define TOK_RECONSTRUCT 117
|
||||
#define TOK_CELL_TO_FACE 118
|
||||
#define TOK_CELL_TO_POINT 119
|
||||
826
src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4
Normal file
826
src/finiteVolume/expressions/volume/volumeExprLemonParser.lyy-m4
Normal file
@ -0,0 +1,826 @@
|
||||
%include
|
||||
{
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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/>.
|
||||
|
||||
Description
|
||||
Lemon grammar for volume expressions.
|
||||
|
||||
https://www.sqlite.org/src/doc/trunk/doc/lemon.html
|
||||
|
||||
See detailed notes in the field expression parser.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
} // %include
|
||||
|
||||
/*
|
||||
* include[volumeExprLemonParserMacros.m4]
|
||||
*include(`volumeExprLemonParserMacros.m4')dnl
|
||||
!done in a comment since many editors have issues matching m4 quotes!
|
||||
*/
|
||||
%include
|
||||
{
|
||||
#include "volumeExprDriver.H"
|
||||
#include "volumeExprParser.H"
|
||||
#include "volumeExprScanner.H"
|
||||
#include "unitConversion.H"
|
||||
#include "error.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "exprDriverOps.H"
|
||||
#include "GeometricFieldOps.H"
|
||||
#include "fvcReconstruct.H"
|
||||
|
||||
|
||||
// Enable ParseTrace
|
||||
#undef NDEBUG
|
||||
|
||||
compiler_pragmas()
|
||||
|
||||
// Local Functions
|
||||
|
||||
tmp_management()
|
||||
|
||||
dnl
|
||||
dnl #if 0
|
||||
dnl namespace Foam
|
||||
dnl {
|
||||
dnl //- Check field sizes
|
||||
dnl template<class T1, class T2>
|
||||
dnl static bool checkSizes(const char* what, T1* arg1, T2* arg2)
|
||||
dnl {
|
||||
dnl if (arg1 == nullptr || arg2 == nullptr)
|
||||
dnl {
|
||||
dnl FatalError
|
||||
dnl << "Null pointer in " << what << nl
|
||||
dnl << Foam::exit(Foam::FatalError);
|
||||
dnl }
|
||||
dnl if (arg1->size() != arg2->size())
|
||||
dnl {
|
||||
dnl FatalError
|
||||
dnl << "Size mismatch in " << what << ' '
|
||||
dnl << pTraits<typename T1::value_type>::typeName << ", "
|
||||
dnl << pTraits<typename T2::value_type>::typeName << "\n("
|
||||
dnl << arg1->size() << " != " << arg2->size() << ')' << nl
|
||||
dnl << Foam::exit(Foam::FatalError);
|
||||
dnl }
|
||||
dnl
|
||||
dnl return true;
|
||||
dnl }
|
||||
dnl } // End namespace Foam
|
||||
dnl #endif
|
||||
dnl
|
||||
} // %include
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
%namespace {}
|
||||
|
||||
// Use extra argument for the return value
|
||||
%extra_context { Foam::expressions::volumeExpr::parseDriver* driver }
|
||||
%parse_failure { driver->reportFatal("Parse failure, giving up..."); }
|
||||
%syntax_error { driver->reportFatal("Syntax error"); }
|
||||
|
||||
%token_prefix TOK_
|
||||
|
||||
// Terminals
|
||||
%token_type {Foam::expressions::volumeExpr::scanToken*}
|
||||
// Non-terminals
|
||||
%type ivalue { Foam::label }
|
||||
%type svalue { Foam::scalar }
|
||||
%type ident { Foam::word* }
|
||||
|
||||
// Volume fields
|
||||
declare_field(lfield, Foam::volScalarField, Foam::scalar, newVolField, getVolField)
|
||||
declare_field(sfield, Foam::volScalarField, Foam::scalar, newVolField, getVolField)
|
||||
declare_field(vfield, Foam::volVectorField, Foam::vector, newVolField, getVolField)
|
||||
declare_field(hfield, Foam::volSphericalTensorField, Foam::sphericalTensor, newVolField, getVolField)
|
||||
declare_field(yfield, Foam::volSymmTensorField, Foam::symmTensor, newVolField, getVolField)
|
||||
declare_field(tfield, Foam::volTensorField, Foam::tensor, newVolField, getVolField)
|
||||
|
||||
// Surface fields
|
||||
declare_field(slfield, Foam::surfaceScalarField, Foam::scalar, newSurfaceField, getSurfaceField)
|
||||
declare_field(ssfield, Foam::surfaceScalarField, Foam::scalar, newSurfaceField, getSurfaceField)
|
||||
declare_field(svfield, Foam::surfaceVectorField, Foam::vector, newSurfaceField, getSurfaceField)
|
||||
declare_field(shfield, Foam::surfaceSphericalTensorField, Foam::sphericalTensor, newSurfaceField, getSurfaceField)
|
||||
declare_field(syfield, Foam::surfaceSymmTensorField, Foam::symmTensor, newSurfaceField, getSurfaceField)
|
||||
declare_field(stfield, Foam::surfaceTensorField, Foam::tensor, newSurfaceField, getSurfaceField)
|
||||
|
||||
// Point fields
|
||||
declare_field(plfield, Foam::pointScalarField, Foam::scalar, newPointField, getPointField)
|
||||
declare_field(psfield, Foam::pointScalarField, Foam::scalar, newPointField, getPointField)
|
||||
declare_field(pvfield, Foam::pointVectorField, Foam::vector, newPointField, getPointField)
|
||||
declare_field(phfield, Foam::pointSphericalTensorField, Foam::sphericalTensor, newPointField, getPointField)
|
||||
declare_field(pyfield, Foam::pointSymmTensorField, Foam::symmTensor, newPointField, getPointField)
|
||||
declare_field(ptfield, Foam::pointTensorField, Foam::tensor, newPointField, getPointField)
|
||||
|
||||
// For each rule action with code, destruction must be done by that code block
|
||||
// Lemon does not generate a destructor for that.
|
||||
// So do not use Lemon destructors for anything.
|
||||
|
||||
operator_precedence()
|
||||
|
||||
%start_symbol evaluate
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (scalar)
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
svalue (lhs) ::= NUMBER (a) . { lhs = (a)->svalue; } // From 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(); }
|
||||
svalue (lhs) ::= RAD_TO_DEG LPAREN RPAREN . { lhs = Foam::radToDeg(); }
|
||||
svalue (lhs) ::= TIME LPAREN RPAREN . { lhs = driver->timeValue(); }
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * Volume Fields * * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
define([_logic_], [lfield])dnl
|
||||
define([_scalar_], [sfield])dnl
|
||||
define([_vector_], [vfield])dnl
|
||||
define([_sphTensor_], [hfield])dnl
|
||||
define([_symTensor_], [yfield])dnl
|
||||
define([_tensor_], [tfield])dnl
|
||||
dnl
|
||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volScalarField)
|
||||
dnl
|
||||
define([_target_], [sfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, svalue)
|
||||
rule_get_field(_target_, SCALAR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
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>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
|
||||
|
||||
// Other functions
|
||||
|
||||
_target_ (lhs) ::= RAND LPAREN RPAREN .
|
||||
{
|
||||
lhs = driver->field_rand().ptr();
|
||||
}
|
||||
|
||||
_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();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volVectorField)
|
||||
dnl
|
||||
define([_target_], [vfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, VECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volSphericalTensorField)
|
||||
dnl
|
||||
define([_target_], [hfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, SPH_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_sphTensor_operations()
|
||||
rules_sphTensor_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volSymmTensorField)
|
||||
dnl
|
||||
define([_target_], [yfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, SYM_TENSOR_ID)
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_symTensor_operations()
|
||||
rules_symTensor_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (volTensorField)
|
||||
dnl
|
||||
define([_target_], [tfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
tfield (lhs) ::= UNIT_TENSOR . { lhs = _new_tfield(Foam::tensor::I); }
|
||||
|
||||
rule_get_field(_target_, TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_tensor_operations()
|
||||
rules_tensor_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Logic field productions (volScalarField)
|
||||
dnl
|
||||
define([_target_], [lfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Logical */ }
|
||||
|
||||
_logic_ (lhs) ::= LTRUE . { lhs = _new_lfield(_logic_true_); }
|
||||
_logic_ (lhs) ::= LFALSE . { lhs = _new_lfield(_logic_false_); }
|
||||
|
||||
rule_cast_logical(_target_, _target_)
|
||||
rule_cast_logical(_target_, _scalar_, Foam::scalar)
|
||||
|
||||
rules_logical_operations(_logic_, _value_type_)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Volume-related productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_driver_volume_functions()
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * Surface Fields * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
define([_logic_], [slfield])dnl
|
||||
define([_scalar_], [ssfield])dnl
|
||||
define([_vector_], [svfield])dnl
|
||||
define([_sphTensor_], [shfield])dnl
|
||||
define([_symTensor_], [syfield])dnl
|
||||
define([_tensor_], [stfield])dnl
|
||||
dnl
|
||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
dnl> %ifndef disable_surface_fields
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceScalarField)
|
||||
dnl
|
||||
define([_target_], [ssfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, svalue, FACE_EXPR)
|
||||
rule_get_field(_target_, SSCALAR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
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>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceVectorField)
|
||||
dnl
|
||||
define([_target_], [svfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, SVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceSphericalTensorField)
|
||||
dnl
|
||||
define([_target_], [shfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, SSPH_TENSOR_ID)
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_sphTensor_operations()
|
||||
rules_sphTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceSymmTensorField)
|
||||
dnl
|
||||
define([_target_], [syfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, SSYM_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_symTensor_operations()
|
||||
rules_symTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (surfaceTensorField)
|
||||
dnl
|
||||
define([_target_], [stfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, STENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_tensor_operations()
|
||||
rules_tensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Logic field productions (surfaceScalarField)
|
||||
dnl
|
||||
define([_target_], [slfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Logical */ }
|
||||
|
||||
_logic_ (lhs) ::= FACE_EXPR LPAREN LTRUE RPAREN . { lhs = _new_slfield(_logic_true_); }
|
||||
_logic_ (lhs) ::= FACE_EXPR LPAREN LFALSE RPAREN . { lhs = _new_slfield(_logic_false_); }
|
||||
|
||||
rule_cast_logical(_target_, _target_)
|
||||
rule_cast_logical(_target_, _scalar_, Foam::scalar)
|
||||
|
||||
rules_logical_operations(_logic_, _value_type_)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Surface-related productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_driver_surface_functions()
|
||||
|
||||
dnl> %endif
|
||||
// End disable_surface_fields
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * Point Fields * * * * * * * * * * * * * * * *\
|
||||
dnl
|
||||
define([_logic_], [plfield])dnl
|
||||
define([_scalar_], [psfield])dnl
|
||||
define([_vector_], [pvfield])dnl
|
||||
define([_sphTensor_], [phfield])dnl
|
||||
define([_symTensor_], [pyfield])dnl
|
||||
define([_tensor_], [ptfield])dnl
|
||||
dnl
|
||||
dnl Several functions are incomplete for point fields
|
||||
dnl
|
||||
pushdef([incomplete_rule_unary_func], [])
|
||||
pushdef([incomplete_rule_binary_func], [])
|
||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
dnl> %ifndef disable_point_fields
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointScalarField)
|
||||
dnl
|
||||
define([_target_], [psfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_field_from_value(_target_, svalue, POINT_EXPR)
|
||||
rule_get_field(_target_, PSCALAR_ID)
|
||||
|
||||
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>())
|
||||
|
||||
// Non-standard but manage via FieldOps::assign
|
||||
rule_binary_assign(_target_, _target_, _target_, HYPOT, Foam::hypotOp<Foam::scalar>())
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Some special handling for point fields.
|
||||
* Some operators are incomplete, or ambiguous.
|
||||
* Just calculate directly on the primitiveField, which is not as bad as it
|
||||
* sounds since most of the pointPatchField operators are dummies (no-op)
|
||||
* anyhow.
|
||||
dnl
|
||||
pushdef([rule_binary_op],
|
||||
[$1 (lhs) ::= $2 (a) $4 $3 (b) .
|
||||
{
|
||||
lhs = _new_$1();
|
||||
(*lhs).primitiveFieldRef() =
|
||||
(make_obj(a).primitiveField() $5 make_obj(b).primitiveField());
|
||||
}]
|
||||
)dnl>
|
||||
dnl
|
||||
pushdef([rule_unary_func],
|
||||
[$1 (lhs) ::= $3 LPAREN $2 (a) RPAREN .
|
||||
{
|
||||
lhs = _new_$1();
|
||||
(*lhs).primitiveFieldRef() = $4 (make_obj(a).primitiveField());
|
||||
}]
|
||||
)dnl>
|
||||
dnl
|
||||
pushdef([rule_binary_func],
|
||||
[$1 (lhs) ::= $4 LPAREN $2 (a) COMMA $3 (b) RPAREN .
|
||||
{
|
||||
lhs = _new_$1();
|
||||
(*lhs).primitiveFieldRef() =
|
||||
$5(make_obj(a).primitiveField(), make_obj(b).primitiveField());
|
||||
}]
|
||||
)dnl>
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_scalar_operations()
|
||||
rules_scalar_functions()
|
||||
|
||||
dnl/* Restore definitions
|
||||
popdef([rule_binary_op])dnl
|
||||
popdef([rule_unary_func])dnl
|
||||
popdef([rule_binary_func])dnl
|
||||
popdef([incomplete_rule_unary_func])dnl
|
||||
popdef([incomplete_rule_binary_func])dnl
|
||||
dnl*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointVectorField)
|
||||
dnl
|
||||
define([_target_], [pvfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, PVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointSphericalTensorField)
|
||||
dnl
|
||||
define([_target_], [phfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, PSPH_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_sphTensor_operations()
|
||||
rules_sphTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointSymmTensorField)
|
||||
dnl
|
||||
define([_target_], [pyfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, PSYM_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_symTensor_operations()
|
||||
rules_symTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (pointTensorField)
|
||||
dnl
|
||||
define([_target_], [ptfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, PTENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_tensor_operations()
|
||||
rules_tensor_functions()
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Logic field productions (pointScalarField)
|
||||
dnl
|
||||
define([_target_], [plfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Logical */ }
|
||||
|
||||
_logic_ (lhs) ::= POINT_EXPR LPAREN LTRUE RPAREN . { lhs = _new_plfield(_logic_true_); }
|
||||
_logic_ (lhs) ::= POINT_EXPR LPAREN LFALSE RPAREN . { lhs = _new_plfield(_logic_false_); }
|
||||
rules_logical_operations(_logic_, _value_type_)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Point-related productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_driver_point_functions()
|
||||
|
||||
dnl> %endif
|
||||
// End disable_point_fields
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Volume field composition
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rule_mag_logical(sfield, lfield)
|
||||
rules_mag_functions(sfield, sfield)
|
||||
rules_mag_functions(sfield, vfield)
|
||||
rules_mag_functions(sfield, tfield)
|
||||
rules_mag_functions(sfield, yfield)
|
||||
rules_mag_functions(sfield, hfield)
|
||||
|
||||
rule_vector_zip(vfield, sfield, VECTOR)
|
||||
rule_tensor_zip(tfield, sfield, TENSOR)
|
||||
rule_symTensor_zip(yfield, sfield, SYM_TENSOR)
|
||||
rule_sphTensor_zip(hfield, sfield, SPH_TENSOR)
|
||||
|
||||
rule_vector_components(sfield, vfield)
|
||||
rule_tensor_components(sfield, tfield)
|
||||
rule_symTensor_components(sfield, yfield)
|
||||
rule_sphTensor_components(sfield, hfield)
|
||||
|
||||
rule_tensor_transpose(tfield)
|
||||
rule_symTensor_transpose(yfield)
|
||||
rule_sphTensor_transpose(hfield)
|
||||
|
||||
rule_tensor_unzipDiag(vfield, yfield)
|
||||
rule_tensor_unzipAll(vfield, tfield)
|
||||
|
||||
rule_pointToCell(sfield, psfield)
|
||||
rule_pointToCell(vfield, pvfield)
|
||||
rule_pointToCell(tfield, ptfield)
|
||||
rule_pointToCell(yfield, pyfield)
|
||||
rule_pointToCell(hfield, phfield)
|
||||
|
||||
vfield (lhs) ::= RECONSTRUCT LPAREN ssfield (a) RPAREN.
|
||||
{
|
||||
lhs = Foam::fvc::reconstruct(make_obj(a)).ptr();
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Surface field composition
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rule_mag_logical(ssfield, slfield)
|
||||
rules_mag_functions(ssfield, ssfield)
|
||||
rules_mag_functions(ssfield, svfield)
|
||||
rules_mag_functions(ssfield, stfield)
|
||||
rules_mag_functions(ssfield, syfield)
|
||||
rules_mag_functions(ssfield, shfield)
|
||||
|
||||
rule_vector_zip(svfield, ssfield, VECTOR)
|
||||
rule_tensor_zip(stfield, ssfield, TENSOR)
|
||||
rule_symTensor_zip(syfield, ssfield, SYM_TENSOR)
|
||||
rule_sphTensor_zip(shfield, ssfield, SPH_TENSOR)
|
||||
|
||||
rule_vector_components(ssfield, svfield)
|
||||
rule_tensor_components(ssfield, stfield)
|
||||
rule_symTensor_components(ssfield, syfield)
|
||||
rule_sphTensor_components(ssfield, shfield)
|
||||
|
||||
rule_tensor_transpose(stfield)
|
||||
rule_symTensor_transpose(syfield)
|
||||
rule_sphTensor_transpose(shfield)
|
||||
|
||||
rule_tensor_unzipDiag(svfield, syfield)
|
||||
rule_tensor_unzipAll(svfield, stfield)
|
||||
|
||||
rule_cellToFace(ssfield, sfield)
|
||||
rule_cellToFace(svfield, vfield)
|
||||
rule_cellToFace(stfield, tfield)
|
||||
rule_cellToFace(syfield, yfield)
|
||||
rule_cellToFace(shfield, hfield)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Point field composition
|
||||
* - Use primitiveField directly
|
||||
dnl
|
||||
pushdef([field_write_access], [($1).primitiveFieldRef()])dnl
|
||||
pushdef([field_read_access], [($1).primitiveField()])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rule_mag_logical(psfield, plfield)
|
||||
rules_mag_functions(psfield, psfield)
|
||||
rules_mag_functions(psfield, pvfield)
|
||||
rules_mag_functions(psfield, ptfield)
|
||||
rules_mag_functions(psfield, pyfield)
|
||||
rules_mag_functions(psfield, phfield)
|
||||
|
||||
rule_vector_zip(pvfield, psfield, VECTOR)
|
||||
rule_tensor_zip(ptfield, psfield, TENSOR)
|
||||
rule_symTensor_zip(pyfield, psfield, SYM_TENSOR)
|
||||
rule_sphTensor_zip(phfield, psfield, SPH_TENSOR)
|
||||
|
||||
rule_vector_components(psfield, pvfield)
|
||||
rule_tensor_components(psfield, ptfield)
|
||||
rule_symTensor_components(psfield, pyfield)
|
||||
rule_sphTensor_components(psfield, phfield)
|
||||
|
||||
rule_tensor_transpose(ptfield)
|
||||
rule_symTensor_transpose(pyfield)
|
||||
rule_sphTensor_transpose(phfield)
|
||||
|
||||
rule_tensor_unzipDiag(pvfield, pyfield)
|
||||
rule_tensor_unzipAll(pvfield, ptfield)
|
||||
|
||||
rule_cellToPoint(psfield, sfield)
|
||||
rule_cellToPoint(pvfield, vfield)
|
||||
rule_cellToPoint(ptfield, tfield)
|
||||
rule_cellToPoint(pyfield, yfield)
|
||||
rule_cellToPoint(phfield, hfield)
|
||||
|
||||
|
||||
dnl/* Restore definitions
|
||||
popdef([field_write_access])dnl
|
||||
popdef([field_read_access])dnl
|
||||
dnl*/
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
dnl/* Standard m4 quoting
|
||||
changequote([`],['])dnl
|
||||
dnl*/
|
||||
|
||||
%code
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::expressions::volumeExpr::parser::stop()
|
||||
{
|
||||
if (lemon_)
|
||||
{
|
||||
ParseFree(lemon_, ::operator delete);
|
||||
#ifndef NDEBUG
|
||||
ParseTrace(nullptr, nullptr);
|
||||
#endif
|
||||
lemon_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::volumeExpr::parser::start(parseDriver& driver_)
|
||||
{
|
||||
this->stop();
|
||||
lemon_ = ParseAlloc(::operator new, &driver_);
|
||||
|
||||
if (debug || driver_.debugParser())
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
ParseTrace(stderr, const_cast<char*>(prompt_));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::volumeExpr::parser::parse
|
||||
(
|
||||
int tokenId,
|
||||
scanToken* tokenVal
|
||||
)
|
||||
{
|
||||
Parse(lemon_, tokenId, tokenVal);
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::volumeExpr::parser::nameOfToken
|
||||
(
|
||||
int tokenId
|
||||
) const
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if
|
||||
(
|
||||
tokenId > 0
|
||||
&& unsigned(tokenId) < (sizeof(yyTokenName) / sizeof(char*))
|
||||
)
|
||||
{
|
||||
return yyTokenName[tokenId];
|
||||
}
|
||||
return "<invalid>";
|
||||
#else
|
||||
return word();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End of %code
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,139 @@
|
||||
divert(-1)dnl
|
||||
#-----------------------------------*- m4 -*-----------------------------------
|
||||
# ========= |
|
||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
# \\ / O peration |
|
||||
# \\ / A nd | www.openfoam.com
|
||||
# \\/ M anipulation |
|
||||
#------------------------------------------------------------------------------
|
||||
# Copyright (C) 2019 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, licensed under GNU General Public License
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Description
|
||||
# Driver-specific m4/lemon macros for volume expressions.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
include(`m4/lemon/base-setup.m4')dnl
|
||||
include([m4/lemon/operator-precedence.m4])dnl
|
||||
dnl
|
||||
include([m4/lemon/rules-standard.m4])dnl
|
||||
include([m4/lemon/rules-operations.m4])dnl
|
||||
include([m4/lemon/rules-functions.m4])dnl
|
||||
include([m4/lemon/rules-components.m4])dnl
|
||||
include([m4/lemon/rules-fields-components.m4])dnl
|
||||
include([m4/lemon/rules-scalar-logic.m4])dnl
|
||||
dnl
|
||||
divert(-1)dnl
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Driver rules
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rules_driver_volume_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, CSET, field_cellSet)dnl
|
||||
rule_driver_select(_logic_, CZONE, field_cellZone)dnl
|
||||
dnl
|
||||
rule_driver_nullary(_scalar_, CELL_VOLUME, field_cellVolume)dnl
|
||||
rule_driver_nullary(_vector_, POS, field_cellCentre)dnl CELL_CENTRE
|
||||
dnl
|
||||
rule_driver_inplace_unary(_scalar_, WEIGHT_AVERAGE, volAverage)dnl
|
||||
rule_driver_inplace_unary(_vector_, WEIGHT_AVERAGE, volAverage)dnl
|
||||
rule_driver_inplace_unary(_sphTensor_, WEIGHT_AVERAGE, volAverage)dnl
|
||||
rule_driver_inplace_unary(_symTensor_, WEIGHT_AVERAGE, volAverage)dnl
|
||||
rule_driver_inplace_unary(_tensor_, WEIGHT_AVERAGE, volAverage)dnl
|
||||
dnl
|
||||
rule_driver_inplace_unary(_scalar_, WEIGHT_SUM, volSum)dnl
|
||||
rule_driver_inplace_unary(_vector_, WEIGHT_SUM, volSum)dnl
|
||||
rule_driver_inplace_unary(_sphTensor_, WEIGHT_SUM, volSum)dnl
|
||||
rule_driver_inplace_unary(_symTensor_, WEIGHT_SUM, volSum)dnl
|
||||
rule_driver_inplace_unary(_tensor_, WEIGHT_SUM, volSum)dnl
|
||||
dnl
|
||||
])
|
||||
|
||||
define([rules_driver_surface_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, FSET, field_faceSet)dnl
|
||||
rule_driver_select(_logic_, FZONE, field_faceZone)dnl
|
||||
dnl
|
||||
rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl
|
||||
rule_driver_nullary(_vector_, FACE_CENTRE, field_faceCentre)dnl
|
||||
rule_driver_nullary(_vector_, FACE_EXPR, field_areaNormal)dnl
|
||||
dnl
|
||||
rule_driver_inplace_unary(_scalar_, WEIGHT_AVERAGE, areaAverage)dnl
|
||||
rule_driver_inplace_unary(_vector_, WEIGHT_AVERAGE, areaAverage)dnl
|
||||
rule_driver_inplace_unary(_sphTensor_, WEIGHT_AVERAGE, areaAverage)dnl
|
||||
rule_driver_inplace_unary(_symTensor_, WEIGHT_AVERAGE, areaAverage)dnl
|
||||
rule_driver_inplace_unary(_tensor_, WEIGHT_AVERAGE, areaAverage)dnl
|
||||
dnl
|
||||
rule_driver_inplace_unary(_scalar_, WEIGHT_SUM, areaSum)dnl
|
||||
rule_driver_inplace_unary(_vector_, WEIGHT_SUM, areaSum)dnl
|
||||
rule_driver_inplace_unary(_sphTensor_, WEIGHT_SUM, areaSum)dnl
|
||||
rule_driver_inplace_unary(_symTensor_, WEIGHT_SUM, areaSum)dnl
|
||||
rule_driver_inplace_unary(_tensor_, WEIGHT_SUM, areaSum)dnl
|
||||
dnl
|
||||
])
|
||||
|
||||
define([rules_driver_point_functions],
|
||||
[dnl
|
||||
rule_driver_select(_logic_, PSET, field_pointSet)dnl
|
||||
rule_driver_select(_logic_, PZONE, field_pointZone)dnl
|
||||
dnl
|
||||
rule_driver_nullary(_vector_, POINTS, field_pointField)dnl
|
||||
dnl
|
||||
dnl NB use non-driver versions for points - ie, unweighted
|
||||
dnl
|
||||
rule_inplace_unary(_scalar_, WEIGHT_AVERAGE, Foam::gAverage)dnl
|
||||
rule_inplace_unary(_vector_, WEIGHT_AVERAGE, Foam::gAverage)dnl
|
||||
rule_inplace_unary(_sphTensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl
|
||||
rule_inplace_unary(_symTensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl
|
||||
rule_inplace_unary(_tensor_, WEIGHT_AVERAGE, Foam::gAverage)dnl
|
||||
dnl
|
||||
rule_inplace_unary(_scalar_, WEIGHT_SUM, Foam::gSum)dnl
|
||||
rule_inplace_unary(_vector_, WEIGHT_SUM, Foam::gSum)dnl
|
||||
rule_inplace_unary(_sphTensor_, WEIGHT_SUM, Foam::gSum)dnl
|
||||
rule_inplace_unary(_symTensor_, WEIGHT_SUM, Foam::gSum)dnl
|
||||
rule_inplace_unary(_tensor_, WEIGHT_SUM, Foam::gSum)dnl
|
||||
dnl
|
||||
])
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# rule_cellToFace(out, in)
|
||||
# rule_cellToPoint(out, in)
|
||||
# rule_pointToCell(out, in)
|
||||
#
|
||||
# Description
|
||||
# Production rules for driver cellToFace, cellToPoint, pointToCell,
|
||||
# methods
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rule_cellToFace],
|
||||
[rule_driver_unary($1, $2, CELL_TO_FACE, cellToFace)])
|
||||
|
||||
define([rule_cellToPoint],
|
||||
[rule_driver_unary($1, $2, CELL_TO_POINT, cellToPoint)])
|
||||
|
||||
define([rule_pointToCell],
|
||||
[rule_driver_unary($1, $2, POINT_TO_CELL, pointToCell)])
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Standard rules for fields: declaration, new/get, driver functions etc.
|
||||
|
||||
include([m4/lemon/rules-fields.m4])dnl
|
||||
divert(-1)dnl
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Additional safety measures
|
||||
|
||||
undefine([substr])dnl # Avoid collision with C/C++ naming
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
divert(0)dnl
|
||||
106
src/finiteVolume/expressions/volume/volumeExprParser.H
Normal file
106
src/finiteVolume/expressions/volume/volumeExprParser.H
Normal file
@ -0,0 +1,106 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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::volumeExpr::parser
|
||||
|
||||
Description
|
||||
Lemon parser interface for volume expressions grammar
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_volumeExprParser_H
|
||||
#define expressions_volumeExprParser_H
|
||||
|
||||
#include "volumeExprFwd.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace volumeExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parser Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parser
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Prompt for parser tracing
|
||||
static constexpr const char* const prompt_ = "volExpr:";
|
||||
|
||||
//- The lemon parser (demand-driven)
|
||||
void* lemon_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Local object debugging
|
||||
int debug;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
parser() : lemon_(nullptr), debug(volumeExpr::debug) {}
|
||||
|
||||
|
||||
//- Destructor, deletes parser backend
|
||||
~parser()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Start parsing, with the given driver context
|
||||
void start(parseDriver& driver_);
|
||||
|
||||
//- Stop parsing, freeing the allocated parser
|
||||
void stop();
|
||||
|
||||
//- Push token/value to parser
|
||||
void parse(int tokenId, scanToken* tokenVal);
|
||||
|
||||
//- Return the text name corresponding to the tokenId
|
||||
word nameOfToken(int tokenId) const;
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace volumeExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
162
src/finiteVolume/expressions/volume/volumeExprScanner.H
Normal file
162
src/finiteVolume/expressions/volume/volumeExprScanner.H
Normal file
@ -0,0 +1,162 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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::volumeExpr::scanner
|
||||
|
||||
Description
|
||||
Ragel lexer/scanner interface for volume expressions.
|
||||
|
||||
Note
|
||||
Ragel code generated with the ./createCode script.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_volumeExprScanner_H
|
||||
#define expressions_volumeExprScanner_H
|
||||
|
||||
#include "volumeExprFwd.H"
|
||||
#include "scalar.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace volumeExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanToken Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
union scanToken
|
||||
{
|
||||
Foam::label ivalue;
|
||||
Foam::scalar svalue;
|
||||
Foam::word* name;
|
||||
|
||||
//- Null construct, bit-wise zero for union content
|
||||
scanToken() : ivalue(0) {}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class scanner Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class scanner
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Wrapped lemon parser
|
||||
parser* parser_;
|
||||
|
||||
// Ragel code state, action
|
||||
int cs, act;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Dispatch .method to parser (if known) or Fatal
|
||||
bool dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
) const;
|
||||
|
||||
//- Dispatch identifier to parser (if possible) or Fatal
|
||||
bool dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Local debugging
|
||||
int debug;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null, optionally setting debugging
|
||||
explicit scanner(bool withDebug = false)
|
||||
:
|
||||
parser_(nullptr),
|
||||
debug(volumeExpr::debug)
|
||||
{
|
||||
if (withDebug)
|
||||
{
|
||||
debug |= 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Destructor, deletes parser
|
||||
~scanner();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Evaluate sub-string
|
||||
bool process
|
||||
(
|
||||
const std::string& str, size_t pos, size_t len,
|
||||
parseDriver& driver_
|
||||
);
|
||||
|
||||
//- Evaluate sub-string
|
||||
bool process
|
||||
(
|
||||
const std::string& str, size_t pos,
|
||||
parseDriver& driver_
|
||||
)
|
||||
{
|
||||
return process(str, pos, std::string::npos, driver_);
|
||||
}
|
||||
|
||||
//- Evaluate string
|
||||
bool process(const std::string& str, parseDriver& driver_)
|
||||
{
|
||||
return process(str, 0, std::string::npos, driver_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace volumeExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
3866
src/finiteVolume/expressions/volume/volumeExprScanner.cc
Normal file
3866
src/finiteVolume/expressions/volume/volumeExprScanner.cc
Normal file
File diff suppressed because it is too large
Load Diff
694
src/finiteVolume/expressions/volume/volumeExprScanner.rl
Normal file
694
src/finiteVolume/expressions/volume/volumeExprScanner.rl
Normal file
@ -0,0 +1,694 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 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/>.
|
||||
|
||||
Description
|
||||
Ragel lexer interface for lemon grammar of volume field expressions
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "volumeExprScanner.H"
|
||||
#include "volumeExprDriver.H"
|
||||
#include "volumeExprLemonParser.h"
|
||||
#include "volumeExprParser.H"
|
||||
#include "Enum.H"
|
||||
#include "macros.H"
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
||||
|
||||
// Debugging to stderr
|
||||
#undef DebugInfo
|
||||
#define DebugInfo if (debug) InfoErr
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- Paste token prefix
|
||||
#define TOKEN_OF(T) TOK_##T
|
||||
|
||||
//- An {int, c_str} enum pairing
|
||||
#define TOKEN_PAIR(Name,T) { TOKEN_OF(T), Name }
|
||||
|
||||
// Special handling for these known (stashed) look-back types
|
||||
static const Enum<int> lookBehindTokenEnums
|
||||
({
|
||||
TOKEN_PAIR("cellSet", CSET),
|
||||
TOKEN_PAIR("faceSet", FSET),
|
||||
TOKEN_PAIR("pointSet", PSET),
|
||||
TOKEN_PAIR("cellZone", CZONE),
|
||||
TOKEN_PAIR("faceZone", FZONE),
|
||||
TOKEN_PAIR("pointZone", PZONE),
|
||||
});
|
||||
|
||||
#define HAS_LOOKBEHIND_TOKENS
|
||||
|
||||
|
||||
// Special handling of predefined method types. Eg, .x(), .y(), ...
|
||||
static const Enum<int> fieldMethodEnums
|
||||
({
|
||||
TOKEN_PAIR("x", CMPT_X),
|
||||
TOKEN_PAIR("y", CMPT_Y),
|
||||
TOKEN_PAIR("z", CMPT_Z),
|
||||
TOKEN_PAIR("xx", CMPT_XX),
|
||||
TOKEN_PAIR("xy", CMPT_XY),
|
||||
TOKEN_PAIR("xz", CMPT_XZ),
|
||||
TOKEN_PAIR("yx", CMPT_YX),
|
||||
TOKEN_PAIR("yy", CMPT_YY),
|
||||
TOKEN_PAIR("yz", CMPT_YZ),
|
||||
TOKEN_PAIR("zx", CMPT_ZX),
|
||||
TOKEN_PAIR("zy", CMPT_ZY),
|
||||
TOKEN_PAIR("zz", CMPT_ZZ),
|
||||
TOKEN_PAIR("ii", CMPT_II),
|
||||
TOKEN_PAIR("diag", DIAG), /* tensors only */
|
||||
TOKEN_PAIR("T", TRANSPOSE), /* tensors only */
|
||||
});
|
||||
|
||||
|
||||
// Known field-token types
|
||||
static const Enum<int> fieldTokenEnums
|
||||
({
|
||||
#ifdef TOK_SCALAR_ID
|
||||
TOKEN_PAIR(volScalarField::typeName.c_str(), SCALAR_ID),
|
||||
TOKEN_PAIR(volVectorField::typeName.c_str(), VECTOR_ID),
|
||||
TOKEN_PAIR(volTensorField::typeName.c_str(), TENSOR_ID),
|
||||
TOKEN_PAIR(volSymmTensorField::typeName.c_str(), SYM_TENSOR_ID),
|
||||
TOKEN_PAIR(volSphericalTensorField::typeName.c_str(), SPH_TENSOR_ID),
|
||||
#else
|
||||
#error TOK_SCALAR_ID not defined
|
||||
#endif
|
||||
#ifdef TOK_SSCALAR_ID
|
||||
TOKEN_PAIR(surfaceScalarField::typeName.c_str(), SSCALAR_ID),
|
||||
TOKEN_PAIR(surfaceVectorField::typeName.c_str(), SVECTOR_ID),
|
||||
TOKEN_PAIR(surfaceTensorField::typeName.c_str(), STENSOR_ID),
|
||||
TOKEN_PAIR(surfaceSymmTensorField::typeName.c_str(), SSYM_TENSOR_ID),
|
||||
TOKEN_PAIR(surfaceSphericalTensorField::typeName.c_str(), SSPH_TENSOR_ID),
|
||||
#else
|
||||
#warning TOK_SSCALAR_ID not defined
|
||||
#endif
|
||||
#ifdef TOK_PSCALAR_ID
|
||||
TOKEN_PAIR(pointScalarField::typeName.c_str(), PSCALAR_ID),
|
||||
TOKEN_PAIR(pointVectorField::typeName.c_str(), PVECTOR_ID),
|
||||
TOKEN_PAIR(pointTensorField::typeName.c_str(), PTENSOR_ID),
|
||||
TOKEN_PAIR(pointSymmTensorField::typeName.c_str(), PSYM_TENSOR_ID),
|
||||
TOKEN_PAIR(pointSphericalTensorField::typeName.c_str(), PSPH_TENSOR_ID),
|
||||
#else
|
||||
#warning TOK_PSCALAR_ID not defined
|
||||
#endif
|
||||
});
|
||||
|
||||
|
||||
// Simple compile-time function name declarations.
|
||||
// Useful for handling driver-specific dispatching, or functions that
|
||||
// are not universally available.
|
||||
static const Enum<int> funcTokenEnums
|
||||
({
|
||||
#ifdef TOK_FLOOR
|
||||
TOKEN_PAIR("floor", FLOOR),
|
||||
TOKEN_PAIR("ceil", CEIL),
|
||||
TOKEN_PAIR("round", ROUND),
|
||||
#endif
|
||||
#ifdef TOK_HYPOT /* Can use hypot? */
|
||||
TOKEN_PAIR("hypot", HYPOT),
|
||||
#endif
|
||||
|
||||
// Already parsed as function: TOKEN_PAIR("pos", CELL_CENTRE),
|
||||
|
||||
TOKEN_PAIR("point", POINT_EXPR), // Point value
|
||||
TOKEN_PAIR("face", FACE_EXPR), // Face value, Face areaNormal
|
||||
|
||||
TOKEN_PAIR("cellToPoint", CELL_TO_POINT),
|
||||
TOKEN_PAIR("cellToFace", CELL_TO_FACE),
|
||||
TOKEN_PAIR("pointToCell", POINT_TO_CELL),
|
||||
|
||||
TOKEN_PAIR("area", FACE_AREA),
|
||||
TOKEN_PAIR("vol", CELL_VOLUME),
|
||||
|
||||
TOKEN_PAIR("fpos", FACE_CENTRE),
|
||||
TOKEN_PAIR("pts", POINTS),
|
||||
});
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Classifying token type based on an identifier name is indeed ugly.
|
||||
//
|
||||
// 1)
|
||||
// Handle special cases (eg, cellSet,...) first that have been tagged
|
||||
// as expected content with the stashed "look-behind" token.
|
||||
// Handle not-found errors here directly.
|
||||
//
|
||||
// 2)
|
||||
// Fallback to determining which field-type (volScalarField etc) the name
|
||||
// corresponds to.
|
||||
// Handle not-found errors by return -1.
|
||||
//
|
||||
static int driverTokenType
|
||||
(
|
||||
const expressions::volumeExpr::parseDriver& driver_,
|
||||
const word& ident
|
||||
)
|
||||
{
|
||||
// Get stashed "look-behind" to decide what type of identifier we expect
|
||||
const int lookBehind = driver_.resetStashedTokenId();
|
||||
|
||||
if (lookBehind && lookBehindTokenEnums.found(lookBehind))
|
||||
{
|
||||
bool good = false;
|
||||
|
||||
switch (lookBehind)
|
||||
{
|
||||
case TOK_CSET : good = driver_.isCellSet(ident); break;
|
||||
case TOK_FSET : good = driver_.isFaceSet(ident); break;
|
||||
case TOK_PSET : good = driver_.isPointSet(ident); break;
|
||||
case TOK_CZONE : good = driver_.isCellZone(ident); break;
|
||||
case TOK_FZONE : good = driver_.isFaceZone(ident); break;
|
||||
case TOK_PZONE : good = driver_.isPointZone(ident); break;
|
||||
}
|
||||
|
||||
if (good)
|
||||
{
|
||||
return TOK_IDENTIFIER;
|
||||
}
|
||||
|
||||
// Fatal
|
||||
driver_.reportFatal
|
||||
(
|
||||
"Error no " + lookBehindTokenEnums.get(lookBehind) + ": " + ident
|
||||
);
|
||||
|
||||
return -2; // Extra safety
|
||||
}
|
||||
|
||||
// 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; \
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Point variables
|
||||
#ifdef TOK_PSCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Volume variables
|
||||
#ifdef TOK_SCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(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);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef checkFieldToken
|
||||
|
||||
// Check registered fields and/or disk-files
|
||||
{
|
||||
const word fieldType(driver_.getFieldClassName(ident));
|
||||
|
||||
int tokType = fieldTokenEnums.get(fieldType, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
return tokType;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // End anonymous namespace
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
// Ragel machine definition
|
||||
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
|
||||
//
|
||||
// Can use 'variable p xxx;' etc to change these names
|
||||
|
||||
#define EMIT_TOKEN(T) \
|
||||
driver_.parsePosition() = (ts-buf); \
|
||||
DebugInfo<< STRINGIFY(T) << ": " << driver_.parsePosition() << nl; \
|
||||
parser_->parse(TOKEN_OF(T), nullptr); \
|
||||
driver_.parsePosition() = (p-buf);
|
||||
|
||||
|
||||
%%{
|
||||
machine volumeExpr;
|
||||
write data;
|
||||
|
||||
action 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))
|
||||
{
|
||||
parser_->parse(TOKEN_OF(NUMBER), &scanTok);
|
||||
}
|
||||
else
|
||||
{
|
||||
driver_.reportFatal
|
||||
(
|
||||
"Error parsing number: " + std::string(ts, te-ts)
|
||||
);
|
||||
}
|
||||
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
action emit_ident {
|
||||
driver_.parsePosition() = (ts-buf);
|
||||
dispatch_ident(driver_, scanTok, 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));
|
||||
driver_.parsePosition() = (p-buf);
|
||||
}
|
||||
|
||||
decimal = ((digit* '.' digit+) | (digit+ '.'?)) ;
|
||||
number = ((digit+ | decimal) ([Ee][\-+]? digit+)?) ;
|
||||
ident = ((alpha|'_') . ((alnum|[._])**)) ;
|
||||
dquoted = '"' [^\"]+ '"' ;
|
||||
squoted = "'" [^\']+ "'" ;
|
||||
|
||||
|
||||
## The scanner
|
||||
main := |*
|
||||
space*;
|
||||
|
||||
number => emit_number;
|
||||
|
||||
## operators
|
||||
'!' =>{ EMIT_TOKEN(NOT); };
|
||||
'%' =>{ EMIT_TOKEN(PERCENT); };
|
||||
'(' =>{ EMIT_TOKEN(LPAREN); };
|
||||
')' =>{ EMIT_TOKEN(RPAREN); };
|
||||
'*' =>{ EMIT_TOKEN(TIMES); };
|
||||
'+' =>{ EMIT_TOKEN(PLUS); };
|
||||
'-' =>{ EMIT_TOKEN(MINUS); };
|
||||
',' =>{ EMIT_TOKEN(COMMA); };
|
||||
'.' =>{ EMIT_TOKEN(DOT); };
|
||||
'/' =>{ EMIT_TOKEN(DIVIDE); };
|
||||
'?' =>{ EMIT_TOKEN(QUESTION); };
|
||||
':' =>{ EMIT_TOKEN(COLON); };
|
||||
'<' =>{ EMIT_TOKEN(LESS); };
|
||||
'<=' =>{ EMIT_TOKEN(LESS_EQ); };
|
||||
'>' =>{ EMIT_TOKEN(GREATER); };
|
||||
'>=' =>{ EMIT_TOKEN(GREATER_EQ); };
|
||||
'==' =>{ EMIT_TOKEN(EQUAL); };
|
||||
'!=' =>{ EMIT_TOKEN(NOT_EQUAL); };
|
||||
'&&' =>{ EMIT_TOKEN(LAND); };
|
||||
'||' =>{ EMIT_TOKEN(LOR); };
|
||||
'&' =>{ EMIT_TOKEN(BIT_AND); };
|
||||
## Not needed? '|' =>{ EMIT_TOKEN(BIT_OK); };
|
||||
'^' =>{ EMIT_TOKEN(BIT_XOR); };
|
||||
|
||||
## Some '.method' - Error if unknown
|
||||
'.' alpha+ => emit_method;
|
||||
|
||||
|
||||
## Regular functions
|
||||
"pi" =>{ EMIT_TOKEN(PI); };
|
||||
"degToRad" =>{ EMIT_TOKEN(DEG_TO_RAD); };
|
||||
"radToDeg" =>{ EMIT_TOKEN(RAD_TO_DEG); };
|
||||
"exp" =>{ EMIT_TOKEN(EXP); };
|
||||
"log" =>{ EMIT_TOKEN(LOG); };
|
||||
"log10" =>{ EMIT_TOKEN(LOG10); };
|
||||
"pow" =>{ EMIT_TOKEN(POW); };
|
||||
"sqr" =>{ EMIT_TOKEN(SQR); };
|
||||
"sqrt" =>{ EMIT_TOKEN(SQRT); };
|
||||
"cbrt" =>{ EMIT_TOKEN(CBRT); };
|
||||
"sin" =>{ EMIT_TOKEN(SIN); };
|
||||
"cos" =>{ EMIT_TOKEN(COS); };
|
||||
"tan" =>{ EMIT_TOKEN(TAN); };
|
||||
"asin" =>{ EMIT_TOKEN(ASIN); };
|
||||
"acos" =>{ EMIT_TOKEN(ACOS); };
|
||||
"atan" =>{ EMIT_TOKEN(ATAN); };
|
||||
"atan2" =>{ EMIT_TOKEN(ATAN2); };
|
||||
"sinh" =>{ EMIT_TOKEN(SINH); };
|
||||
"cosh" =>{ EMIT_TOKEN(COSH); };
|
||||
"tanh" =>{ EMIT_TOKEN(TANH); };
|
||||
"mag" =>{ EMIT_TOKEN(MAG); };
|
||||
"magSqr" =>{ EMIT_TOKEN(MAGSQR); };
|
||||
|
||||
"pos" =>{ EMIT_TOKEN(POS); };
|
||||
"neg" =>{ EMIT_TOKEN(NEG); };
|
||||
"pos0" =>{ EMIT_TOKEN(POS0); };
|
||||
"neg0" =>{ EMIT_TOKEN(NEG0); };
|
||||
"sign" =>{ EMIT_TOKEN(SIGN); };
|
||||
|
||||
## Reductions, or other special functions
|
||||
"min" =>{ EMIT_TOKEN(MIN); };
|
||||
"max" =>{ EMIT_TOKEN(MAX); };
|
||||
"average" =>{ EMIT_TOKEN(AVERAGE); };
|
||||
"sum" =>{ EMIT_TOKEN(SUM); };
|
||||
"weightAverage" =>{ EMIT_TOKEN(WEIGHT_AVERAGE); };
|
||||
"weightSum" =>{ EMIT_TOKEN(WEIGHT_SUM); };
|
||||
"rand" =>{ EMIT_TOKEN(RAND); };
|
||||
|
||||
## Types
|
||||
"bool" =>{ EMIT_TOKEN(BOOL); };
|
||||
"vector" =>{ EMIT_TOKEN(VECTOR); };
|
||||
"tensor" =>{ EMIT_TOKEN(TENSOR); };
|
||||
"symmTensor" =>{ EMIT_TOKEN(SYM_TENSOR); };
|
||||
"sphericalTensor" =>{ EMIT_TOKEN(SPH_TENSOR); };
|
||||
|
||||
## Single value (constants, etc)
|
||||
"Zero" =>{ EMIT_TOKEN(ZERO); };
|
||||
"true" =>{ EMIT_TOKEN(LTRUE); };
|
||||
"false" =>{ EMIT_TOKEN(LFALSE); };
|
||||
"tensor::I" =>{ EMIT_TOKEN(UNIT_TENSOR); };
|
||||
"time" =>{ EMIT_TOKEN(TIME); };
|
||||
|
||||
## Identifier (field, etc - error if unknown)
|
||||
## Handle 'bare' names and single/double quoted ones
|
||||
ident => emit_ident;
|
||||
dquoted => emit_ident;
|
||||
squoted => emit_ident;
|
||||
|
||||
space*;
|
||||
*|;
|
||||
}%%
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::volumeExpr::scanner::~scanner()
|
||||
{
|
||||
if (parser_)
|
||||
{
|
||||
delete parser_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::volumeExpr::scanner::dispatch_method
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
) const
|
||||
{
|
||||
if (ident[0] == '.')
|
||||
{
|
||||
ident.erase(0, 1);
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Method:" << ident
|
||||
<< " at " << driver_.parsePosition() << nl;
|
||||
|
||||
const int methType = fieldMethodEnums.get(ident, -1);
|
||||
|
||||
if (methType > 0)
|
||||
{
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
driver_.reportFatal("Unknown method: " + ident);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::volumeExpr::scanner::dispatch_ident
|
||||
(
|
||||
const parseDriver& driver_,
|
||||
scanToken& scanTok,
|
||||
word&& ident
|
||||
) const
|
||||
{
|
||||
int tokType = -1;
|
||||
|
||||
const bool quoted =
|
||||
(
|
||||
(ident.front() == '"' || ident.front() == '\'')
|
||||
&& (ident.front() == ident.back())
|
||||
);
|
||||
|
||||
if (quoted)
|
||||
{
|
||||
ident.erase(ident.size()-1);
|
||||
ident.erase(0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for function name
|
||||
tokType = funcTokenEnums.get(ident, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Emit:" << ident << " function:"
|
||||
<< parser_->nameOfToken(tokType) << nl;
|
||||
|
||||
parser_->parse(tokType, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAS_LOOKBEHIND_TOKENS
|
||||
// Specials such "cset" also reset the look-behind
|
||||
tokType = lookBehindTokenEnums.get(ident, -1);
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Emit:" << ident << " as look-behind:"
|
||||
<< parser_->nameOfToken(tokType) << nl;
|
||||
|
||||
driver_.resetStashedTokenId(tokType);
|
||||
parser_->parse(tokType, nullptr);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Can also peek at stashed "look-behind"
|
||||
// const int lookBehind = driver_.stashedTokenId();
|
||||
|
||||
tokType = driverTokenType(driver_, ident);
|
||||
|
||||
if (tokType > 0)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Emit:" << ident << " token:"
|
||||
<< parser_->nameOfToken(tokType) << nl;
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Not found? Attempt to strip off '.x' endings etc,
|
||||
// but not when quoted
|
||||
|
||||
const auto dot = ident.rfind('.');
|
||||
const int methType =
|
||||
(
|
||||
quoted || dot == std::string::npos
|
||||
? -1
|
||||
: fieldMethodEnums.get(ident.substr(dot+1), -1)
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
methType > 0
|
||||
&& (tokType = driverTokenType(driver_, ident.substr(0, dot))) > 0
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Emit:" << ident.substr(0, dot).c_str() << " token:"
|
||||
<< parser_->nameOfToken(tokType) << " with "
|
||||
<< ident.substr(dot).c_str() << " token:"
|
||||
<< parser_->nameOfToken(methType) << nl;
|
||||
|
||||
// The field (before the ".")
|
||||
ident.erase(dot);
|
||||
|
||||
scanTok.name = new Foam::word(std::move(ident));
|
||||
parser_->parse(tokType, &scanTok);
|
||||
|
||||
// Dispatch '.' and "method" separately
|
||||
parser_->parse(TOK_DOT, nullptr);
|
||||
parser_->parse(methType, nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
driver_.reportFatal
|
||||
(
|
||||
"Object " + ident + " does not exist or wrong type"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::volumeExpr::scanner::process
|
||||
(
|
||||
const std::string& str,
|
||||
size_t strBeg,
|
||||
size_t strLen,
|
||||
parseDriver& driver_
|
||||
)
|
||||
{
|
||||
// Save debug value
|
||||
const int oldDebug = debug;
|
||||
|
||||
if (driver_.debugScanner())
|
||||
{
|
||||
debug |= 4;
|
||||
}
|
||||
|
||||
if (!parser_)
|
||||
{
|
||||
parser_ = new parser();
|
||||
}
|
||||
|
||||
driver_.content(str, strBeg, strLen);
|
||||
|
||||
size_t strEnd = str.length();
|
||||
|
||||
if (strBeg > str.length())
|
||||
{
|
||||
strBeg = str.length();
|
||||
}
|
||||
else if (strLen != std::string::npos)
|
||||
{
|
||||
strLen += strBeg;
|
||||
|
||||
if (strLen < str.length())
|
||||
{
|
||||
strEnd = strLen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parser_->start(driver_);
|
||||
|
||||
// Scan token type
|
||||
scanToken scanTok;
|
||||
|
||||
// Ragel token start/end (required naming)
|
||||
const char* ts;
|
||||
const char* te;
|
||||
|
||||
// Local buffer data.
|
||||
// - p, pe, eof are required Ragel naming
|
||||
// - buf is our own naming
|
||||
|
||||
const char* buf = &(str[strBeg]);
|
||||
const char* eof = &(str[strEnd]);
|
||||
const char* p = buf;
|
||||
const char* pe = eof;
|
||||
|
||||
// Initialize FSM variables
|
||||
%%{write init;}%% /* ^^^ FSM initialization here ^^^ */;
|
||||
|
||||
%%{write exec;}%% /* ^^^ FSM execution here ^^^ */;
|
||||
|
||||
if (%%{write error;}%% == cs)
|
||||
{
|
||||
driver_.reportFatal("Parse error while scanning", (p-buf));
|
||||
}
|
||||
|
||||
if (p != eof)
|
||||
{
|
||||
driver_.reportFatal("Parsing failed with remaining content", (p-buf));
|
||||
}
|
||||
|
||||
// Terminate parser execution
|
||||
parser_->parse(0, nullptr);
|
||||
parser_->stop();
|
||||
|
||||
// Restore debug value
|
||||
debug = oldDebug;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user