Commit 20589430 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: driver/parser/scanner for volume expressions

parent 82a1e325
......@@ -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);
}
......
#!/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 \
"$@"
#------------------------------------------------------------------------------
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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;
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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