mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-expressions' into 'develop'
Feature expressions ### Summary This branch represents an implementation of what is considered to be the most useful aspects of swak4Foam ([Swiss-Army-Knife for FOAM](https://openfoamwiki.net/index.php/Contrib/swak4Foam)) from Bernhard Gschaider, namely the ability to use text-based expressions instead of coding in C++ for the following cases: - expression-based boundary conditions (also known as _groovy_ boundary conditions) - expression-based setFields (also known as _funky_ set fields) The idea of what we currently term *expressions* was pioneered by (Bernhard Gschaider) and is now firmly established in `swak4Foam`. Among other things, expressions attempt to bridge the gap between using standard, predefined boundary conditions and writing dedicated, special-purpose ones. Although part of this gap is now covered within OpenFOAM by using dynamically compiled user coding (eg, coded boundary conditions), there remains substantial areas where it can be significantly more convenient to have a series of predefined functions and expression sytax with some access to base OpenFOAM field functionality that enables rapid deployment of boundary conditions, or custom-defined `setFields` without writing code. A significant portion of `swak4Foam` expressions has been adapted for direct integration into OpenFOAM. During the integration and rewrite, we have tried to pare things down to a smaller subset with the aim of covering 90% or more of the common cases. The remaining cases are left to be reassessed for extending the *expressions* functionality in the future, but they also may be better served with other approaches (eg, with coded conditions) that were not available when `swak4Foam` was originally conceived. To the greatest extent possible, the integrated *expressions* have been designed to avoid name clashes with `swak` so it should remain possible to use the most recent versions of `swak` without problem. ### Risks - New functionality, so low chance of regression. - The scope of the functionality will be revised in the future ### Naming (for `swak4Foam` users) The following are the *expressions* correspondences to `swak`: - The `exprFixedValue` and `exprGradient` boundary conditions are roughly equivalent to the _groovy_ boundary conditions. - The utilities `setExprFields` and `setExprBoundaryFields` are roughly equivalent to the _funky_ utilities of similar name. The naming of the boundary conditions and utilities not only reflects the slightly different input requirements, but simultaneously seeks to avoid any potential name-clash with `swak4Foam` in a mixed environment. The names for the boundary condition dictionary entries tend be shorter and slightly different (eg, `valueExpr` vs `valueExpression`) to serve as a small reminder that the *expressions* syntax is slightly different than the *groovy* equivalents. It also allows the user to fashion dictionary entries that are sufficient for **both** boundary condition variants and quickly toggle between them simply by changing the boundary condition `type`. See merge request Development/openfoam!300
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
setExprBoundaryFields.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/setExprBoundaryFields
|
||||
@ -0,0 +1,8 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,262 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
setExprFields
|
||||
|
||||
Group
|
||||
grpPreProcessingUtilities
|
||||
|
||||
Description
|
||||
Set boundary values using an expression
|
||||
|
||||
Note
|
||||
Based on funkySetBoundaryFields
|
||||
Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "fvMesh.H"
|
||||
#include "pointMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "patchExprDriver.H"
|
||||
#include "timeSelector.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noFunctionObjects(true);
|
||||
|
||||
// No -constant, no special treatment for 0/
|
||||
timeSelector::addOptions(false);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"dict",
|
||||
"file",
|
||||
"Alternative dictionary for setExprBoundaryFieldsDict"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"cache-fields",
|
||||
"Cache fields between calls",
|
||||
true // Advanced
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"backup",
|
||||
"Preserve sub-entry as .backup",
|
||||
true // Advanced
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"dry-run",
|
||||
"Evaluate but do not write"
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool dryrun = args.found("dry-run");
|
||||
const bool backup = args.found("backup");
|
||||
const bool cacheFields = args.found("cache-fields");
|
||||
|
||||
if (cacheFields)
|
||||
{
|
||||
Warning
|
||||
<< "The current cache-fields behaviour (caching disk reads) "
|
||||
<< "may lead to unexpected behaviour as previous modifications "
|
||||
<< "will not be visible."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const word dictName("setExprBoundaryFieldsDict");
|
||||
|
||||
#include "createTime.H"
|
||||
|
||||
instantList times = timeSelector::select0(runTime, args);
|
||||
|
||||
if (times.size() < 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No times selected." << exit(FatalError);
|
||||
}
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
#include "setSystemMeshDictionaryIO.H"
|
||||
IOdictionary setExprDict(dictIO);
|
||||
|
||||
forAll(times, timei)
|
||||
{
|
||||
runTime.setTime(times[timei], timei);
|
||||
|
||||
Info<< "\nTime = " << runTime.timeName() << endl;
|
||||
|
||||
mesh.readUpdate();
|
||||
|
||||
for (const entry& dEntry : setExprDict)
|
||||
{
|
||||
if (!dEntry.isDict())
|
||||
{
|
||||
Info<< "Ignoring non-dictionary entry "
|
||||
<< dEntry.keyword() << nl;
|
||||
continue;
|
||||
}
|
||||
|
||||
const dictionary& dict = dEntry.dict();
|
||||
|
||||
const word fieldName(dict.get<word>("field"));
|
||||
|
||||
List<dictionary> exprDicts;
|
||||
dict.readEntry("expressions", exprDicts);
|
||||
|
||||
if (exprDicts.empty())
|
||||
{
|
||||
Info<< "No expressions for " << fieldName << nl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Read dictionary
|
||||
// Note: disable class type checking so we can load field
|
||||
const word oldTypeName = IOdictionary::typeName;
|
||||
const_cast<word&>(IOdictionary::typeName) = word::null;
|
||||
|
||||
IOobject fieldHeader
|
||||
(
|
||||
fieldName,
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
const bool headOk = fieldHeader.typeHeaderOk<IOdictionary>(false);
|
||||
|
||||
if (!headOk)
|
||||
{
|
||||
// Restore type
|
||||
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
|
||||
|
||||
WarningInFunction
|
||||
<< "Requested field to change " << fieldName
|
||||
<< " does not exist in " << fieldHeader.path() << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
IOdictionary fieldDict(fieldHeader);
|
||||
|
||||
// Restore type
|
||||
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
|
||||
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
|
||||
|
||||
Info<< "Processing field " << fieldName << nl;
|
||||
|
||||
dictionary& boundaryFieldDict = fieldDict.subDict("boundaryField");
|
||||
|
||||
for (const dictionary& currDict : exprDicts)
|
||||
{
|
||||
const word targetName = currDict.get<word>("target");
|
||||
const word patchName = currDict.get<word>("patch");
|
||||
|
||||
dictionary& patchDict = boundaryFieldDict.subDict(patchName);
|
||||
|
||||
expressions::exprString expr
|
||||
(
|
||||
currDict.get<string>("expression"),
|
||||
currDict,
|
||||
true // strip comments
|
||||
);
|
||||
|
||||
Info<< "Set boundaryField/" << patchName << '/'
|
||||
<< targetName << nl
|
||||
<< "with expression" << nl
|
||||
<< "<<<<" << nl
|
||||
<< expr.c_str() << nl
|
||||
<< ">>>>" << nl;
|
||||
|
||||
expressions::patchExprDriver driver(currDict, mesh);
|
||||
|
||||
// Search on disc
|
||||
driver.setSearchBehaviour(cacheFields, false, true);
|
||||
|
||||
driver.clearVariables();
|
||||
driver.parse(expr);
|
||||
|
||||
// Serializing via Field::writeEntry etc
|
||||
OStringStream serialize;
|
||||
driver.result().writeEntry("", serialize);
|
||||
|
||||
if (backup && !dryrun)
|
||||
{
|
||||
patchDict.changeKeyword
|
||||
(
|
||||
targetName,
|
||||
word(targetName + ".backup"),
|
||||
true // Overwrite
|
||||
);
|
||||
}
|
||||
|
||||
patchDict.set(targetName, serialize.str().c_str());
|
||||
|
||||
if (dryrun)
|
||||
{
|
||||
Info<< "Evaluated:" << nl
|
||||
<< "<<<<" << nl
|
||||
<< serialize.str().c_str() // (already includes nl)
|
||||
<< ">>>>" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dryrun)
|
||||
{
|
||||
Info<< "Write " << fieldDict.filePath() << nl;
|
||||
fieldDict.regIOobject::write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,34 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object setExprBoundaryFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
pattern
|
||||
{
|
||||
field T;
|
||||
|
||||
expressions
|
||||
(
|
||||
{
|
||||
patch bottom;
|
||||
target theta0;
|
||||
expression #{ (pos().x() < 1e-4 ? 60 : 120) #};
|
||||
}
|
||||
);
|
||||
|
||||
keepPatches true;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
setExprFields.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/setExprFields
|
||||
@ -0,0 +1,8 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lmeshTools \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,915 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
setExprFields
|
||||
|
||||
Group
|
||||
grpPreProcessingUtilities
|
||||
|
||||
Description
|
||||
Set values on a selected set of cells/patch-faces via a dictionary.
|
||||
|
||||
Note
|
||||
Based on funkySetFields
|
||||
Copyright 2006-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "fvMesh.H"
|
||||
#include "pointMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "exprOps.H"
|
||||
#include "volumeExprDriver.H"
|
||||
#include "timeSelector.H"
|
||||
#include "dlLibraryTable.H"
|
||||
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
using FieldAssociation = expressions::volumeExpr::FieldAssociation;
|
||||
|
||||
word fieldGeoType(const FieldAssociation geoType)
|
||||
{
|
||||
switch (geoType)
|
||||
{
|
||||
case FieldAssociation::VOLUME_DATA : return "cells"; break;
|
||||
case FieldAssociation::SURFACE_DATA : return "faces"; break;
|
||||
case FieldAssociation::POINT_DATA : return "points"; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
|
||||
//- Simple control structure to with collected switches to simplify passing
|
||||
struct setExprFieldsControl
|
||||
{
|
||||
bool dryRun;
|
||||
bool debugParsing;
|
||||
bool cacheVariables;
|
||||
bool useDimension;
|
||||
bool createNew;
|
||||
bool keepPatches;
|
||||
bool correctPatches;
|
||||
bool correctBCs;
|
||||
};
|
||||
|
||||
|
||||
template<class Type>
|
||||
void doCorrectBoundaryConditions
|
||||
(
|
||||
bool correctBCs,
|
||||
GeometricField<Type, fvPatchField, volMesh>& field
|
||||
)
|
||||
{
|
||||
if (correctBCs)
|
||||
{
|
||||
Info<< "Correcting boundary conditions: " << field.name() << nl;
|
||||
field.correctBoundaryConditions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void doCorrectBoundaryConditions
|
||||
(
|
||||
bool correctBCs,
|
||||
GeometricField<Type, pointPatchField, pointMesh>& field
|
||||
)
|
||||
{
|
||||
if (correctBCs)
|
||||
{
|
||||
Info<< "Correcting boundary conditions: " << field.name() << nl;
|
||||
field.correctBoundaryConditions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void doCorrectBoundaryConditions
|
||||
(
|
||||
bool correctBCs,
|
||||
GeometricField<Type, fvsPatchField, surfaceMesh>& field
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class GeoField, class Mesh>
|
||||
void setField
|
||||
(
|
||||
const word& fieldName,
|
||||
const Mesh& mesh,
|
||||
const GeoField& result,
|
||||
const scalarField& cond,
|
||||
const dimensionSet& dims,
|
||||
const wordList& valuePatches,
|
||||
|
||||
const setExprFieldsControl& ctrl
|
||||
)
|
||||
{
|
||||
Info<< "setField(" << fieldName << "): "
|
||||
<< pTraits<GeoField>::typeName << endl;
|
||||
|
||||
tmp<GeoField> toutput;
|
||||
|
||||
if (ctrl.createNew)
|
||||
{
|
||||
// Create with zero
|
||||
toutput = GeoField::New
|
||||
(
|
||||
fieldName,
|
||||
mesh,
|
||||
dimensioned<typename GeoField::value_type>(dims)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read
|
||||
toutput = tmp<GeoField>::New
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // No register
|
||||
),
|
||||
mesh
|
||||
);
|
||||
}
|
||||
|
||||
auto& output = toutput.ref();
|
||||
|
||||
label setCells = 0;
|
||||
|
||||
if (cond.empty())
|
||||
{
|
||||
// No condition
|
||||
output = result;
|
||||
|
||||
setCells = output.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(output, celli)
|
||||
{
|
||||
if (expressions::boolOp<scalar>()(cond[celli]))
|
||||
{
|
||||
output[celli] = result[celli];
|
||||
++setCells;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const label totalCells = returnReduce(output.size(), plusOp<label>());
|
||||
reduce(setCells, plusOp<label>());
|
||||
|
||||
forAll(result.boundaryField(), patchi)
|
||||
{
|
||||
auto& pf = output.boundaryFieldRef()[patchi];
|
||||
|
||||
if (pf.patch().coupled())
|
||||
{
|
||||
pf == result.boundaryField()[patchi];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (setCells == totalCells)
|
||||
{
|
||||
Info<< "Set all ";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Set " << setCells << " of ";
|
||||
}
|
||||
Info<< totalCells << " cells" << endl;
|
||||
|
||||
|
||||
doCorrectBoundaryConditions(ctrl.correctBCs, output);
|
||||
|
||||
if (ctrl.useDimension)
|
||||
{
|
||||
Info<< "Setting dimension to " << dims << endl;
|
||||
output.dimensions().reset(dims);
|
||||
}
|
||||
|
||||
if (ctrl.dryRun)
|
||||
{
|
||||
Info<< "(dry-run): Writing to " << output.name() << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Writing to " << output.name() << nl;
|
||||
output.write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void evaluate
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& fieldName,
|
||||
const expressions::exprString& expression,
|
||||
const expressions::exprString& condition,
|
||||
const dictionary& dict,
|
||||
const dimensionSet& dims,
|
||||
const wordList& valuePatches,
|
||||
|
||||
const setExprFieldsControl& ctrl
|
||||
)
|
||||
{
|
||||
word oldFieldType;
|
||||
|
||||
if (ctrl.createNew)
|
||||
{
|
||||
Info<< "Set new field: " << fieldName;
|
||||
}
|
||||
else
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
fieldName,
|
||||
mesh.thisDb().time().timeName(),
|
||||
mesh.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
io.typeHeaderOk<IOobject>(false);
|
||||
|
||||
oldFieldType = io.headerClassName();
|
||||
|
||||
if (oldFieldType == IOobject::typeName)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Field " << fieldName << " is "
|
||||
<< oldFieldType
|
||||
<< ". Seems that it does not exist. Use 'create'"
|
||||
<< nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< "Modify field: " << fieldName
|
||||
<< " (type " << oldFieldType << ')';
|
||||
}
|
||||
|
||||
Info<< " time=" << mesh.thisDb().time().timeName() << nl
|
||||
<< "Expression:" << nl
|
||||
<< ">>>>" << nl
|
||||
<< expression.c_str() << nl
|
||||
<< "<<<<" << nl
|
||||
<< "Condition:" << nl
|
||||
<< ">>>>" << nl
|
||||
<< condition.c_str() << nl
|
||||
<< "<<<<" << nl;
|
||||
|
||||
if (ctrl.keepPatches)
|
||||
{
|
||||
Info<< "Keeping patches unaltered" << endl;
|
||||
}
|
||||
else if (!valuePatches.empty())
|
||||
{
|
||||
Info<< "Setting patches " << flatOutput(valuePatches)
|
||||
<< " to fixed value" << endl;
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
|
||||
expressions::volumeExprDriver driver
|
||||
(
|
||||
mesh,
|
||||
ctrl.cacheVariables
|
||||
);
|
||||
|
||||
driver.readDict(dict);
|
||||
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Parsing expression: " << expression << "\nand condition "
|
||||
<< condition << nl << endl;
|
||||
driver.setDebugging(true, true);
|
||||
}
|
||||
|
||||
|
||||
driver.clearVariables();
|
||||
|
||||
scalarField conditionField;
|
||||
|
||||
bool evaluatedCondition = false;
|
||||
|
||||
FieldAssociation conditionDataType(FieldAssociation::VOLUME_DATA);
|
||||
|
||||
if (condition.size() && condition != "true")
|
||||
{
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Parsing condition:" << condition << endl;
|
||||
}
|
||||
|
||||
driver.parse(condition);
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Parsed condition" << endl;
|
||||
}
|
||||
|
||||
// Process any/all scalar fields. May help with diagnosis
|
||||
|
||||
bool goodCond = true;
|
||||
while (goodCond)
|
||||
{
|
||||
// volScalarField
|
||||
{
|
||||
const auto* ptr = driver.isResultType<volScalarField>();
|
||||
if (ptr)
|
||||
{
|
||||
conditionField = ptr->internalField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// surfaceScalarField
|
||||
{
|
||||
const auto* ptr = driver.isResultType<surfaceScalarField>();
|
||||
if (ptr)
|
||||
{
|
||||
conditionField = ptr->internalField();
|
||||
conditionDataType = FieldAssociation::SURFACE_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// pointScalarField
|
||||
{
|
||||
const auto* ptr = driver.isResultType<pointScalarField>();
|
||||
if (ptr)
|
||||
{
|
||||
conditionField = ptr->internalField();
|
||||
conditionDataType = FieldAssociation::POINT_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No matching field types
|
||||
goodCond = false;
|
||||
}
|
||||
|
||||
// Verify that it also logical
|
||||
goodCond = goodCond && driver.isLogical();
|
||||
|
||||
if (!goodCond)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< " condition: " << condition
|
||||
<< " does not evaluate to a logical expression: "
|
||||
<< driver.resultType() << nl
|
||||
#ifdef FULLDEBUG
|
||||
<< "contents: " << conditionField
|
||||
#endif
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Condition evaluates to "
|
||||
<< conditionField << nl;
|
||||
}
|
||||
|
||||
evaluatedCondition = true;
|
||||
}
|
||||
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Parsing expression:" << expression << endl;
|
||||
}
|
||||
|
||||
driver.parse(expression);
|
||||
|
||||
if (ctrl.debugParsing)
|
||||
{
|
||||
Info<< "Parsed expression" << endl;
|
||||
}
|
||||
|
||||
if (evaluatedCondition)
|
||||
{
|
||||
if (conditionDataType != driver.fieldAssociation())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Mismatch between condition geometric type ("
|
||||
<< fieldGeoType(conditionDataType) << ") and" << nl
|
||||
<< "expression geometric type ("
|
||||
<< fieldGeoType(driver.fieldAssociation()) << ')' << nl
|
||||
<< nl
|
||||
<< "Expression: " << expression << nl
|
||||
<< "Condition: " << condition << nl
|
||||
<< nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctrl.createNew && driver.resultType() != oldFieldType)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Inconsistent types: " << fieldName << " is "
|
||||
<< oldFieldType
|
||||
<< " but the expression evaluates to "
|
||||
<< driver.resultType()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< "Dispatch ... " << driver.resultType() << nl;
|
||||
|
||||
#undef setFieldDispatch
|
||||
#define setFieldDispatch(FieldType) \
|
||||
{ \
|
||||
/* FieldType */ \
|
||||
const auto* ptr = driver.isResultType<FieldType>(); \
|
||||
if (ptr) \
|
||||
{ \
|
||||
/* driver.getResult<FieldType>(correctPatches), */ \
|
||||
\
|
||||
setField \
|
||||
( \
|
||||
fieldName, \
|
||||
mesh, \
|
||||
*ptr, \
|
||||
conditionField, \
|
||||
dims, \
|
||||
valuePatches, \
|
||||
ctrl \
|
||||
); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
setFieldDispatch(volScalarField);
|
||||
setFieldDispatch(volVectorField);
|
||||
setFieldDispatch(volTensorField);
|
||||
setFieldDispatch(volSymmTensorField);
|
||||
setFieldDispatch(volSphericalTensorField);
|
||||
|
||||
setFieldDispatch(surfaceScalarField);
|
||||
setFieldDispatch(surfaceVectorField);
|
||||
setFieldDispatch(surfaceTensorField);
|
||||
setFieldDispatch(surfaceSymmTensorField);
|
||||
setFieldDispatch(surfaceSphericalTensorField);
|
||||
|
||||
#undef setFieldDispatch
|
||||
#define setFieldDispatch(FieldType) \
|
||||
{ \
|
||||
/* FieldType */ \
|
||||
const auto* ptr = driver.isResultType<FieldType>(); \
|
||||
\
|
||||
if (ptr) \
|
||||
{ \
|
||||
/* driver.getResult<FieldType>(correctPatches), */ \
|
||||
\
|
||||
setField \
|
||||
( \
|
||||
fieldName, \
|
||||
pointMesh::New(mesh), \
|
||||
*ptr, \
|
||||
conditionField, \
|
||||
dims, \
|
||||
valuePatches, \
|
||||
ctrl \
|
||||
); \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
|
||||
setFieldDispatch(pointScalarField);
|
||||
setFieldDispatch(pointVectorField);
|
||||
setFieldDispatch(pointTensorField);
|
||||
setFieldDispatch(pointSymmTensorField);
|
||||
setFieldDispatch(pointSphericalTensorField);
|
||||
|
||||
#undef setFieldDispatch
|
||||
|
||||
// Nothing dispatched?
|
||||
|
||||
FatalErrorInFunction
|
||||
<< "Expression evaluates to an unsupported type: "
|
||||
<< driver.resultType() << nl << nl
|
||||
<< "Expression " << expression << nl << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noFunctionObjects(true);
|
||||
|
||||
// No -constant, no special treatment for 0/
|
||||
timeSelector::addOptions(false);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"dict",
|
||||
"file",
|
||||
"Alternative dictionary for setExprFieldsDict"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"dry-run",
|
||||
"Evaluate but do not write"
|
||||
);
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"verbose",
|
||||
"Additional verbosity",
|
||||
true // Advanced option
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"field",
|
||||
"name",
|
||||
"The field to overwrite command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"expression",
|
||||
"expr",
|
||||
"The expression to evaluate (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"condition",
|
||||
"logic",
|
||||
"The logical condition when to apply the expression"
|
||||
" (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"dimension",
|
||||
"dims",
|
||||
"The dimensions to apply for created fields"
|
||||
" (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"debug-parser",
|
||||
"Additional debugging information",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"no-variable-cache",
|
||||
"Disable caching of expression variables",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"create",
|
||||
"Create a new field (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"keepPatches",
|
||||
"Leave patches unaltered"
|
||||
" (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"value-patches",
|
||||
"(patches)",
|
||||
"A list of patches that receive a fixed value"
|
||||
" (command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"dummy-phi",
|
||||
"(command-line operation)",
|
||||
true // Advanced option
|
||||
);
|
||||
|
||||
// Future?
|
||||
#if 0
|
||||
argList::addBoolOption
|
||||
(
|
||||
"noCorrectPatches",
|
||||
""
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"correctResultBoundaryFields",
|
||||
"",
|
||||
true
|
||||
);
|
||||
#endif
|
||||
|
||||
#include "addRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
|
||||
#include "createTime.H"
|
||||
|
||||
const bool dryrun = args.found("dry-run");
|
||||
const bool verbose = args.found("verbose");
|
||||
|
||||
const word dictName("setExprFieldsDict");
|
||||
|
||||
instantList times = timeSelector::select0(runTime, args);
|
||||
|
||||
if (times.size() < 1)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No times selected." << exit(FatalError);
|
||||
}
|
||||
|
||||
// Disable dimension checking during operation
|
||||
dimensionSet::debug = false;
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
autoPtr<surfaceScalarField> dummyPhi;
|
||||
|
||||
autoPtr<IOdictionary> exprDictPtr;
|
||||
|
||||
// Sort out conflicts
|
||||
|
||||
const bool useCommandArgs = args.found("field");
|
||||
|
||||
if (useCommandArgs)
|
||||
{
|
||||
if (args.found("dict"))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot specify both dictionary and command-line arguments"
|
||||
<< nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (args.found("create") && args.found("keepPatches"))
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot specify both 'create' and 'keepPatches'" << nl
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Carp about inapplicable options
|
||||
|
||||
wordHashSet badOptions
|
||||
({
|
||||
"create", "keepPatches", "valuePatches",
|
||||
"dimension", "condition", "expression"
|
||||
});
|
||||
|
||||
badOptions.retain(args.options());
|
||||
|
||||
if (!badOptions.empty())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Using a dictionary. Cannot specify command options:" << nl
|
||||
<< nl
|
||||
<< flatOutput(badOptions.sortedToc()) << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
#include "setSystemMeshDictionaryIO.H"
|
||||
exprDictPtr.reset(new IOdictionary(dictIO));
|
||||
}
|
||||
|
||||
|
||||
forAll(times, timei)
|
||||
{
|
||||
runTime.setTime(times[timei], timei);
|
||||
|
||||
Info<< "\nTime = " << runTime.timeName() << endl;
|
||||
|
||||
mesh.readUpdate();
|
||||
|
||||
if (args.found("dummy-phi") && !dummyPhi.valid())
|
||||
{
|
||||
Info<< "Adding a dummy phi" << endl;
|
||||
dummyPhi.reset
|
||||
(
|
||||
new surfaceScalarField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"phi",
|
||||
mesh.thisDb().time().constant(),
|
||||
mesh.thisDb(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar(Zero)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (args.found("withFunctionObjects"))
|
||||
{
|
||||
runTime.functionObjects().start();
|
||||
}
|
||||
|
||||
if (args.found("field"))
|
||||
{
|
||||
const word fieldName(args.get<word>("field"));
|
||||
|
||||
Info<< "Using command-line options for "
|
||||
<< fieldName << nl << endl;
|
||||
|
||||
setExprFieldsControl ctrl;
|
||||
|
||||
ctrl.dryRun = dryrun;
|
||||
ctrl.debugParsing = args.found("debug-parser");
|
||||
ctrl.cacheVariables = !args.found("no-variable-caching");
|
||||
|
||||
ctrl.createNew = args.found("create");
|
||||
ctrl.keepPatches = args.found("keepPatches");
|
||||
ctrl.correctPatches = !args.found("noCorrectPatches");
|
||||
ctrl.correctBCs = args.found("correctResultBoundaryFields");
|
||||
ctrl.useDimension = args.found("dimension");
|
||||
|
||||
expressions::exprString
|
||||
expression
|
||||
(
|
||||
args.opt("expression"),
|
||||
dictionary::null
|
||||
);
|
||||
|
||||
expressions::exprString condition;
|
||||
if (args.found("condition"))
|
||||
{
|
||||
args.readIfPresent("condition", condition);
|
||||
}
|
||||
|
||||
dimensionSet dims;
|
||||
|
||||
if (ctrl.useDimension)
|
||||
{
|
||||
ITstream is(args.lookup("dimension"));
|
||||
is >> dims;
|
||||
}
|
||||
|
||||
evaluate
|
||||
(
|
||||
mesh,
|
||||
fieldName,
|
||||
expression,
|
||||
condition,
|
||||
dictionary::null,
|
||||
dims,
|
||||
args.getList<word>("valuePatches", false),
|
||||
|
||||
ctrl
|
||||
);
|
||||
}
|
||||
else if (exprDictPtr.valid())
|
||||
{
|
||||
const dictionary& exprDict = exprDictPtr();
|
||||
|
||||
// Read set construct info from dictionary
|
||||
PtrList<entry> actions(exprDict.lookup("expressions"));
|
||||
|
||||
for (const entry& dEntry : actions)
|
||||
{
|
||||
if (!dEntry.isDict())
|
||||
{
|
||||
Info<< "Ignore non-dictionary entry: "
|
||||
<< dEntry.keyword() << nl;
|
||||
continue;
|
||||
}
|
||||
|
||||
const dictionary& dict = dEntry.dict();
|
||||
|
||||
setExprFieldsControl ctrl;
|
||||
|
||||
ctrl.dryRun = dryrun;
|
||||
ctrl.debugParsing = args.found("debug-parser");
|
||||
ctrl.cacheVariables = !args.found("no-variable-caching");
|
||||
|
||||
ctrl.createNew = dict.getOrDefault("create", false);
|
||||
ctrl.keepPatches = dict.getOrDefault("keepPatches", false);
|
||||
ctrl.correctPatches = !args.found("noCorrectPatches");
|
||||
ctrl.correctBCs = args.found("correctResultBoundaryFields");
|
||||
|
||||
if (ctrl.createNew && ctrl.keepPatches)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot specify both 'create' and 'keepPatches'"
|
||||
<< nl << endl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Local override
|
||||
dict.readIfPresent
|
||||
(
|
||||
"correctResultBoundaryFields",
|
||||
ctrl.correctBCs
|
||||
);
|
||||
|
||||
|
||||
const word fieldName(dict.get<word>("field"));
|
||||
|
||||
expressions::exprString expression
|
||||
(
|
||||
dict.get<string>("expression"),
|
||||
dict
|
||||
);
|
||||
|
||||
expressions::exprString condition;
|
||||
|
||||
if (dict.found("condition"))
|
||||
{
|
||||
condition =
|
||||
expressions::exprString
|
||||
(
|
||||
dict.get<string>("condition"),
|
||||
dict
|
||||
);
|
||||
}
|
||||
|
||||
ctrl.useDimension = dict.found("dimension");
|
||||
|
||||
dimensionSet dims;
|
||||
if (ctrl.useDimension)
|
||||
{
|
||||
dict.lookup("dimension") >> dims;
|
||||
}
|
||||
|
||||
wordList valuePatches;
|
||||
dict.readIfPresent("valuePatches", valuePatches);
|
||||
|
||||
if (verbose && !timei)
|
||||
{
|
||||
// Report once
|
||||
Info<< "Processing" << dict << nl;
|
||||
}
|
||||
|
||||
evaluate
|
||||
(
|
||||
mesh,
|
||||
fieldName,
|
||||
expression,
|
||||
condition,
|
||||
dict,
|
||||
dims,
|
||||
valuePatches,
|
||||
|
||||
ctrl
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (exprDictPtr.valid())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No command-line or dictionary??" << nl << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object setExprFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
expressions
|
||||
(
|
||||
T
|
||||
{
|
||||
field T;
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
constants
|
||||
{
|
||||
centre (0.21 0 0.01);
|
||||
}
|
||||
|
||||
variables
|
||||
(
|
||||
"radius = 0.1"
|
||||
);
|
||||
|
||||
condition
|
||||
#{
|
||||
// Within the radius
|
||||
(mag(pos() - $[(vector)constants.centre]) < radius)
|
||||
|
||||
// but only +ve y!
|
||||
&& pos((pos() - $[(vector)constants.centre]).y()) > 0
|
||||
#};
|
||||
|
||||
expression
|
||||
#{
|
||||
300
|
||||
+ 200 * (1 - mag(pos() - $[(vector)constants.centre]) / radius)
|
||||
#};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -250,6 +250,35 @@ $(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C
|
||||
fields/volFields/volFields.C
|
||||
fields/surfaceFields/surfaceFields.C
|
||||
|
||||
expr = expressions
|
||||
$(expr)/base/exprDriverWriter.C
|
||||
|
||||
$(expr)/base/fvExprDriver.C
|
||||
$(expr)/base/fvExprDriverFields.C
|
||||
$(expr)/base/fvExprDriverIO.C
|
||||
$(expr)/base/fvExprDriverNew.C
|
||||
|
||||
patchExpr = $(expr)/patch
|
||||
$(patchExpr)/patchExpr.C
|
||||
$(patchExpr)/patchExprDriver.C
|
||||
$(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
|
||||
|
||||
fieldExpr = $(expr)/fields
|
||||
$(fieldExpr)/base/patchExprFieldBase.C
|
||||
$(fieldExpr)/fvPatchFields/exprFixedValueFvPatchFields.C
|
||||
$(fieldExpr)/fvPatchFields/exprMixedFvPatchFields.C
|
||||
$(fieldExpr)/pointPatchFields/exprValuePointPatchFields.C
|
||||
|
||||
|
||||
fvMatrices/fvMatrices.C
|
||||
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
|
||||
fvMatrices/solvers/MULES/MULES.C
|
||||
|
||||
100
src/finiteVolume/expressions/base/exprDriverWriter.C
Normal file
100
src/finiteVolume/expressions/base/exprDriverWriter.C
Normal file
@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "exprDriverWriter.H"
|
||||
#include "fvExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
defineTypeName(exprDriverWriter);
|
||||
|
||||
} // namespace expressions
|
||||
} // namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::exprDriverWriter::exprDriverWriter
|
||||
(
|
||||
const word& name,
|
||||
fvExprDriver& driver
|
||||
)
|
||||
:
|
||||
regIOobject
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
driver.mesh().time().timeName(),
|
||||
"expressions",
|
||||
driver.mesh().time(),
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::AUTO_WRITE
|
||||
)
|
||||
),
|
||||
driver_(driver)
|
||||
{
|
||||
if (headerOk())
|
||||
{
|
||||
readData(readStream("exprDriverWriter", true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::exprDriverWriter::readData(Istream& is)
|
||||
{
|
||||
dictionary dict(is);
|
||||
|
||||
// driver_.readDict(is);
|
||||
|
||||
driver_.getData(dict);
|
||||
|
||||
return !is.bad();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::exprDriverWriter::writeData(Ostream& os) const
|
||||
{
|
||||
// driver_.writeDict(os);
|
||||
|
||||
dictionary dict;
|
||||
driver_.prepareData(dict);
|
||||
dict.write(os, false);
|
||||
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
109
src/finiteVolume/expressions/base/exprDriverWriter.H
Normal file
109
src/finiteVolume/expressions/base/exprDriverWriter.H
Normal file
@ -0,0 +1,109 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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::exprDriverWriter
|
||||
|
||||
Description
|
||||
Registered input/output for an expressions::fvExprDriver
|
||||
|
||||
SourceFiles
|
||||
exprDriverWriter.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_exprDriverWriter_H
|
||||
#define expressions_exprDriverWriter_H
|
||||
|
||||
#include "fvExprDriver.H"
|
||||
#include "regIOobject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class exprDriverWriter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class exprDriverWriter
|
||||
:
|
||||
public regIOobject
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The driver to read/write
|
||||
fvExprDriver& driver_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- No null constructor
|
||||
exprDriverWriter() = delete;
|
||||
|
||||
//- No copy construct
|
||||
exprDriverWriter(const exprDriverWriter&) = delete;
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const exprDriverWriter&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeNameNoDebug("exprDriverWriter");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct for named driver
|
||||
exprDriverWriter(const word& name, fvExprDriver& driver);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~exprDriverWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
virtual bool readData(Istream& is);
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
765
src/finiteVolume/expressions/base/fvExprDriver.C
Normal file
765
src/finiteVolume/expressions/base/fvExprDriver.C
Normal file
@ -0,0 +1,765 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "fvExprDriver.H"
|
||||
#include "exprDriverWriter.H"
|
||||
#include "expressionEntry.H"
|
||||
#include "exprResultGlobals.H"
|
||||
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
#include "stringOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(fvExprDriver, 0);
|
||||
defineRunTimeSelectionTable(fvExprDriver, dictionary);
|
||||
defineRunTimeSelectionTable(fvExprDriver, idName);
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// Currently not working?
|
||||
bool Foam::expressions::fvExprDriver::cacheSets_ = true;
|
||||
|
||||
const Foam::fvMesh* Foam::expressions::fvExprDriver::defaultMeshPtr_ = nullptr;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fvMesh& Foam::expressions::fvExprDriver::defaultMesh()
|
||||
{
|
||||
if (!defaultMeshPtr_)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No default mesh set" << nl
|
||||
<< "Try the 'fvExprDriverFunctionObject' as a workaround"
|
||||
<< endl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return *defaultMeshPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::fvMesh* Foam::expressions::fvExprDriver::resetDefaultMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const bool force
|
||||
)
|
||||
{
|
||||
const fvMesh* ptr = defaultMeshPtr_;
|
||||
|
||||
if (force || (ptr != nullptr))
|
||||
{
|
||||
defaultMeshPtr_ = &mesh;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
bool cacheReadFields,
|
||||
bool searchInMemory,
|
||||
bool searchFiles,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
expressions::exprDriver
|
||||
(
|
||||
cacheReadFields,
|
||||
searchInMemory,
|
||||
searchFiles,
|
||||
dict
|
||||
),
|
||||
globalScopes_(),
|
||||
delayedVariables_(),
|
||||
storedVariables_(),
|
||||
specialVariablesIndex_(-1),
|
||||
otherMeshName_(),
|
||||
libs_(),
|
||||
writer_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
const fvExprDriver& rhs
|
||||
)
|
||||
:
|
||||
expressions::exprDriver(rhs),
|
||||
globalScopes_(rhs.globalScopes_),
|
||||
delayedVariables_(rhs.delayedVariables_),
|
||||
storedVariables_(rhs.storedVariables_),
|
||||
specialVariablesIndex_(rhs.specialVariablesIndex_),
|
||||
otherMeshName_(),
|
||||
libs_(),
|
||||
writer_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::fvExprDriver::fvExprDriver
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fvExprDriver
|
||||
(
|
||||
dict.lookupOrDefault("cacheReadFields", false),
|
||||
dict.lookupOrDefault("searchInMemory", true),
|
||||
dict.lookupOrDefault("searchFiles", false),
|
||||
dict
|
||||
)
|
||||
{
|
||||
readDict(dict);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::fvExprDriver::~fvExprDriver()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::fvExprDriver::readDict
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
expressions::exprDriver::readDict(dict);
|
||||
|
||||
// wordList plugins;
|
||||
// if (dict.readIfPresent("functionPlugins", plugins))
|
||||
// {
|
||||
// for (const word& plugin : plugins)
|
||||
// {
|
||||
// libs_.open("libswak" + plugin + "FunctionPlugin.so");
|
||||
// }
|
||||
// }
|
||||
|
||||
dict.readIfPresent("globalScopes", globalScopes_);
|
||||
|
||||
const entry* eptr = nullptr;
|
||||
|
||||
// Special variables
|
||||
|
||||
if
|
||||
(
|
||||
// storedVariables
|
||||
(eptr = dict.findEntry("storedVariables", keyType::LITERAL))
|
||||
!= nullptr
|
||||
)
|
||||
{
|
||||
ITstream& is = eptr->stream();
|
||||
|
||||
if (writer_.valid() && storedVariables_.size())
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "The 'storedVariables' was already read."
|
||||
<< " No update from " << is
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
storedVariables_ = List<exprResultStored>(is);
|
||||
|
||||
// Check for excess tokens
|
||||
dict.checkITstream(is, "storedVariables");
|
||||
}
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
// delayedVariables
|
||||
(eptr = dict.findEntry("delayedVariables", keyType::LITERAL))
|
||||
!= nullptr
|
||||
)
|
||||
{
|
||||
ITstream& is = eptr->stream();
|
||||
|
||||
if (writer_.valid() && delayedVariables_.size())
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "Seems like 'delayedVariables' was already read."
|
||||
<< " No update from " << is
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<exprResultDelayed> inputs(is);
|
||||
|
||||
// Check for excess tokens
|
||||
dict.checkITstream(is, "delayedVariables");
|
||||
|
||||
for (auto& var : inputs)
|
||||
{
|
||||
delayedVariables_.insert(var.name(), var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::Time& Foam::expressions::fvExprDriver::runTime() const
|
||||
{
|
||||
return this->mesh().time();
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::timeName() const
|
||||
{
|
||||
return runTime().timeName();
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::expressions::fvExprDriver::timeValue() const
|
||||
{
|
||||
return runTime().value();
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::updateSpecialVariables(bool force)
|
||||
{
|
||||
const bool updated = this->update();
|
||||
|
||||
const label eventIndex = mesh().time().timeIndex();
|
||||
const scalar eventTime = mesh().time().value();
|
||||
|
||||
DebugInfo
|
||||
<< "fvExprDriver::updateSpecialVariables(force="
|
||||
<< force << ") Updated: " << updated << endl;
|
||||
|
||||
if (specialVariablesIndex_ < 0)
|
||||
{
|
||||
DebugInfo
|
||||
<< "First update: " << eventIndex << endl;
|
||||
|
||||
specialVariablesIndex_ = eventIndex;
|
||||
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
DebugInfo
|
||||
<< v.name() << " = " << v.initialValueExpression()
|
||||
<< " (has value "
|
||||
<< v.hasValue() << ")" << endl;
|
||||
|
||||
if (!v.hasValue())
|
||||
{
|
||||
DebugInfo
|
||||
<< "First value: " << v.initialValueExpression()
|
||||
<< " -> " << v.name() << endl;
|
||||
|
||||
parse(v.initialValueExpression());
|
||||
v = result_;
|
||||
DebugInfo
|
||||
<< "Parser size: " << this->size() << nl
|
||||
<< "Calculated: " << result_ << nl
|
||||
<< "Stored: " << v << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (force || specialVariablesIndex_ != eventIndex)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Store variables: " << force << ' '
|
||||
<< specialVariablesIndex_ << ' '
|
||||
<< eventIndex << endl;
|
||||
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
if (variables_.found(v.name()))
|
||||
{
|
||||
DebugInfo
|
||||
<< "Storing variable: " << v.name() << " "
|
||||
<< variables_[v.name()] << endl;
|
||||
|
||||
v = variables_[v.name()];
|
||||
}
|
||||
}
|
||||
specialVariablesIndex_ = eventIndex;
|
||||
}
|
||||
|
||||
forAllIters(delayedVariables_, iter)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Updating delayed variable " << iter().name() << endl;
|
||||
|
||||
if (!iter().updateReadValue(eventTime))
|
||||
{
|
||||
const exprString& expr = iter().startupValueExpression();
|
||||
|
||||
DebugInfo
|
||||
<< "Evaluate: " << expr << endl;
|
||||
|
||||
parse(expr);
|
||||
iter().setReadValue(result_);
|
||||
|
||||
DebugInfo
|
||||
<< "Value " << iter() << nl
|
||||
<< "Type " << iter().valueType() << "("
|
||||
<< result_.valueType() << ")" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugInfo
|
||||
<< iter().name() << " updated without problem" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::clearVariables()
|
||||
{
|
||||
DebugInfo
|
||||
<< "Clearing variables" << endl;
|
||||
|
||||
const scalar eventTime = mesh().time().value();
|
||||
|
||||
(void)this->update();
|
||||
|
||||
updateSpecialVariables();
|
||||
variables_.clear();
|
||||
for (exprResultStored& v : storedVariables_)
|
||||
{
|
||||
variables_.insert(v.name(), v);
|
||||
}
|
||||
|
||||
addVariables(variableStrings_, false);
|
||||
|
||||
forAllIters(delayedVariables_, iter)
|
||||
{
|
||||
iter().storeValue(eventTime);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::evaluateVariable
|
||||
(
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
)
|
||||
{
|
||||
const regIOobject* objPtr = mesh().findObject<regIOobject>(varName);
|
||||
|
||||
if (!allowShadowing_ && objPtr)
|
||||
{
|
||||
WarningInFunction
|
||||
// << "Context: " << driverContext_ << nl
|
||||
<< "Field '" << varName << "' (type " << objPtr->headerClassName()
|
||||
<< ") is shadowed by a variable of the same name." << nl
|
||||
<< "This may lead to trouble" << nl
|
||||
<< "If this is OK set 'allowShadowing'"
|
||||
<< " in the relevant parser" << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
parse(expr);
|
||||
result_.testIfSingleValue();
|
||||
|
||||
DebugInfo
|
||||
<< "Evaluating: " << expr << " -> " << varName << endl
|
||||
<< result_;
|
||||
|
||||
|
||||
// Assign
|
||||
if (delayedVariables_.found(varName))
|
||||
{
|
||||
// Avoid potential conflicts?
|
||||
variables_.erase(varName);
|
||||
|
||||
DebugInfo
|
||||
<< varName << " is delayed" << endl;
|
||||
|
||||
// Copy assignment
|
||||
delayedVariables_[varName] = result_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite with a copy
|
||||
variables_.set(varName, exprResult(result_));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::evaluateVariableRemote
|
||||
(
|
||||
string remote,
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
)
|
||||
{
|
||||
DebugInfo
|
||||
<< "Evaluating remote " << remote.c_str()
|
||||
<< " : " << expr << " -> " << varName << endl;
|
||||
|
||||
word driverType("patch"); // default is patch
|
||||
word identName, regionName;
|
||||
|
||||
const auto slashPos = remote.find('/');
|
||||
if (slashPos != std::string::npos)
|
||||
{
|
||||
regionName = word::validate(remote.substr(slashPos+1));
|
||||
remote.resize(slashPos);
|
||||
}
|
||||
|
||||
const auto quotePos = remote.find('\'');
|
||||
if (quotePos != std::string::npos)
|
||||
{
|
||||
driverType = word::validate(remote.substr(0, quotePos));
|
||||
identName = word::validate(remote.substr(quotePos+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
identName = word::validate(remote);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
driverType == "patch"
|
||||
&&
|
||||
(
|
||||
identName.empty()
|
||||
|| identName == "volume"
|
||||
|| identName == "internalField"
|
||||
)
|
||||
)
|
||||
{
|
||||
driverType = "internalField";
|
||||
}
|
||||
|
||||
const fvMesh* pRegion = &(this->mesh());
|
||||
|
||||
if (!regionName.empty())
|
||||
{
|
||||
pRegion = pRegion->time().cfindObject<fvMesh>(regionName);
|
||||
|
||||
if (!pRegion)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Cannot resolve mesh region: " << regionName << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Call other with ("
|
||||
<< driverType << ", " << identName << ", " << regionName << ")\n";
|
||||
|
||||
autoPtr<fvExprDriver> otherDriver =
|
||||
fvExprDriver::New(driverType, identName, *pRegion);
|
||||
|
||||
otherDriver->setSearchBehaviour(*this);
|
||||
otherDriver->setGlobalScopes(this->globalScopes_);
|
||||
|
||||
otherDriver->parse(expr);
|
||||
|
||||
exprResult otherResult(this->getRemoteResult(*otherDriver));
|
||||
|
||||
// Check / re-check for uniform. Not normally needed
|
||||
if (!otherResult.isUniform())
|
||||
{
|
||||
otherResult.testIfSingleValue();
|
||||
}
|
||||
|
||||
DebugInfo
|
||||
<< "Remote result: " << otherResult << nl;
|
||||
|
||||
// Assign
|
||||
if (delayedVariables_.found(varName))
|
||||
{
|
||||
// Avoid potential conflicts?
|
||||
variables_.erase(varName);
|
||||
|
||||
DebugInfo
|
||||
<< varName << " is delayed - setting" << nl;
|
||||
|
||||
// Move assignment
|
||||
delayedVariables_[varName] = std::move(otherResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Overwrite with a copy
|
||||
variables_.set(varName, std::move(otherResult));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::fvMesh&
|
||||
Foam::expressions::fvExprDriver::regionMesh
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh,
|
||||
bool readIfNecessary
|
||||
)
|
||||
{
|
||||
word regionName;
|
||||
|
||||
if (!dict.readIfPresent("region", regionName))
|
||||
{
|
||||
DebugInFunction << "Using original mesh " << nl;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
DebugInFunction << "Using mesh " << regionName << endl;
|
||||
|
||||
fvMesh* meshPtr = mesh.time().getObjectPtr<fvMesh>(regionName);
|
||||
|
||||
if (!meshPtr && readIfNecessary)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Region " << regionName
|
||||
<< " not in memory. Loading it" << endl;
|
||||
|
||||
meshPtr = new fvMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
regionName,
|
||||
mesh.time().constant(),
|
||||
mesh.time(),
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
meshPtr->polyMesh::store();
|
||||
}
|
||||
|
||||
if (!meshPtr)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No mesh region loaded: " << regionName
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return *meshPtr;
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getTypeOfField
|
||||
(
|
||||
const word& fieldName
|
||||
) const
|
||||
{
|
||||
return getHeaderClassName(this->mesh(), fieldName);
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getFieldClassName
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (searchInMemory())
|
||||
{
|
||||
const regIOobject* ioptr = this->mesh().findObject<regIOobject>(name);
|
||||
|
||||
if (ioptr)
|
||||
{
|
||||
return ioptr->type();
|
||||
}
|
||||
}
|
||||
|
||||
if (searchFiles())
|
||||
{
|
||||
return getHeaderClassName(this->mesh(), name);
|
||||
}
|
||||
|
||||
return word::null;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoSetType(const word& setName) const
|
||||
{
|
||||
IOobject io(topoSet::findIOobject(mesh(), setName));
|
||||
|
||||
if (cellSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::CELLSET_SOURCE;
|
||||
}
|
||||
if (faceSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::FACESET_SOURCE;
|
||||
}
|
||||
if (pointSet::typeName == io.headerClassName())
|
||||
{
|
||||
return topoSetSource::sourceType::POINTSET_SOURCE;
|
||||
}
|
||||
|
||||
return topoSetSource::sourceType::UNKNOWN_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoZoneType(const word& setName) const
|
||||
{
|
||||
if (mesh().cellZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::CELLZONE_SOURCE;
|
||||
}
|
||||
|
||||
if (mesh().faceZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::FACEZONE_SOURCE;
|
||||
}
|
||||
|
||||
if (mesh().pointZones().findZoneID(setName) >= 0)
|
||||
{
|
||||
return topoSetSource::sourceType::POINTZONE_SOURCE;
|
||||
}
|
||||
|
||||
return topoSetSource::sourceType::UNKNOWN_SOURCE;
|
||||
}
|
||||
|
||||
|
||||
Foam::topoSetSource::sourceType
|
||||
Foam::expressions::fvExprDriver::topoSourceType(const word& setName) const
|
||||
{
|
||||
auto setType = topoZoneType(setName);
|
||||
|
||||
if (topoSetSource::sourceType::UNKNOWN_SOURCE == setType)
|
||||
{
|
||||
setType = topoSetType(setName);
|
||||
}
|
||||
|
||||
return setType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isCellSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::CELLSET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isFaceSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::FACESET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isPointSet(const word& setName) const
|
||||
{
|
||||
return
|
||||
(
|
||||
topoSetSource::sourceType::POINTSET_SOURCE
|
||||
== topoSetType(setName)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isCellZone(const word& name) const
|
||||
{
|
||||
return (mesh().cellZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isFaceZone(const word& name) const
|
||||
{
|
||||
return (mesh().faceZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::isPointZone(const word& name) const
|
||||
{
|
||||
return (mesh().pointZones().findZoneID(name) >= 0);
|
||||
}
|
||||
|
||||
|
||||
const Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::lookupGlobal
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return exprResultGlobals::New(this->mesh()).get(name, globalScopes_);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::expressions::fvExprDriver::hasDataToWrite() const
|
||||
{
|
||||
return (!storedVariables_.empty() || !delayedVariables_.empty());
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::getData
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
dict.readIfPresent("storedVariables", storedVariables_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::prepareData
|
||||
(
|
||||
dictionary& dict
|
||||
) const
|
||||
{
|
||||
auto& driver = const_cast<fvExprDriver&>(*this);
|
||||
|
||||
(void)driver.update();
|
||||
|
||||
if (storedVariables_.size())
|
||||
{
|
||||
driver.updateSpecialVariables(true);
|
||||
|
||||
dict.add("storedVariables", storedVariables_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
646
src/finiteVolume/expressions/base/fvExprDriver.H
Normal file
646
src/finiteVolume/expressions/base/fvExprDriver.H
Normal file
@ -0,0 +1,646 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2010-2018 Bernhard Gschaider
|
||||
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::fvExprDriver
|
||||
|
||||
Description
|
||||
Base driver for parsing value expressions associated with an fvMesh.
|
||||
|
||||
Largely based on code and ideas from swak4foam
|
||||
|
||||
Properties
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
variables | List of variables for expressions | no | ()
|
||||
delayedVariables | List of delayed variables | no | ()
|
||||
storedVariables | List of stored variables | no | ()
|
||||
globalScopes | Scopes for global variables | no | ()
|
||||
allowShadowing | Allow variables to shadow field names | no | false
|
||||
\endtable
|
||||
|
||||
Debug Properties
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
debugBaseDriver | Debug level (int) for base driver | no |
|
||||
debugScanner | Add debug for scanner | no | false
|
||||
debugParser | Add debug for parser | no | false
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
fvExprDriverI.H
|
||||
fvExprDriver.C
|
||||
fvExprDriverFields.C
|
||||
fvExprDriverIO.C
|
||||
fvExprDriverNew.C
|
||||
fvExprDriverTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_fvExprDriver_H
|
||||
#define expressions_fvExprDriver_H
|
||||
|
||||
#include "exprDriver.H"
|
||||
#include "exprResultDelayed.H"
|
||||
#include "exprResultStored.H"
|
||||
#include "pointMesh.H"
|
||||
#include "volFields.H"
|
||||
#include "topoSetSource.H"
|
||||
#include "dlLibraryTable.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class exprDriverWriter;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class fvExprDriver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class fvExprDriver
|
||||
:
|
||||
public expressions::exprDriver
|
||||
{
|
||||
// Static Data
|
||||
|
||||
//- Pointer to the "default" mesh
|
||||
static const fvMesh *defaultMeshPtr_;
|
||||
|
||||
//- Cache cellSets, faceSets insted of reading from disc each time
|
||||
static bool cacheSets_;
|
||||
|
||||
|
||||
// Protected Data
|
||||
|
||||
// Stored Data
|
||||
|
||||
//- The scopes for global variables
|
||||
List<word> globalScopes_;
|
||||
|
||||
//- The (delayed) variables table
|
||||
HashTable<exprResultDelayed> delayedVariables_;
|
||||
|
||||
//- Stored expressions. Read from dictionary and updated as required
|
||||
List<exprResultStored> storedVariables_;
|
||||
|
||||
//- Time index when handling special variables
|
||||
label specialVariablesIndex_;
|
||||
|
||||
//- The name of the other mesh (if it is to be required)
|
||||
word otherMeshName_;
|
||||
|
||||
//- Additional libraries
|
||||
dlLibraryTable libs_;
|
||||
|
||||
//- Writing and restoring
|
||||
autoPtr<exprDriverWriter> writer_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Read the IOobject and return the headerClassName
|
||||
static word getHeaderClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
);
|
||||
|
||||
//- Read the set IOobject and return its headerClassName
|
||||
static word getSetClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
);
|
||||
|
||||
|
||||
//- No copy assignment
|
||||
void operator=(const fvExprDriver&) = delete;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Determine mesh or region mesh as specified in the dictionary
|
||||
//- with the keyword "region"
|
||||
static const fvMesh& regionMesh
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh,
|
||||
bool readIfNecessary
|
||||
);
|
||||
|
||||
//- Default boundary type is calculated
|
||||
template<class T>
|
||||
static inline word defaultBoundaryType(const T&)
|
||||
{
|
||||
return "calculated";
|
||||
}
|
||||
|
||||
//- Default boundary type for volume fields is zeroGradient
|
||||
template<class Type>
|
||||
static inline word defaultBoundaryType
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>&
|
||||
)
|
||||
{
|
||||
return "zeroGradient";
|
||||
}
|
||||
|
||||
|
||||
//- Apply correctBoundaryConditions (volume fields only)
|
||||
template<class T>
|
||||
static inline void correctField(T&) {}
|
||||
|
||||
template<class Type>
|
||||
static inline void correctField
|
||||
(
|
||||
GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
)
|
||||
{
|
||||
fld.correctBoundaryConditions();
|
||||
}
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// Mesh related
|
||||
|
||||
//- The mesh we are attached to
|
||||
virtual const fvMesh& mesh() const = 0;
|
||||
|
||||
|
||||
// Variables
|
||||
|
||||
//- Define scopes for global variables
|
||||
void setGlobalScopes(const wordUList& scopes)
|
||||
{
|
||||
globalScopes_ = scopes;
|
||||
}
|
||||
|
||||
//- Non-const access to the named variable (sub-classes only)
|
||||
inline virtual exprResult& variable(const word& name);
|
||||
|
||||
//- Test existence of a global variable
|
||||
template<class T>
|
||||
bool isGlobalVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize = -1
|
||||
) const;
|
||||
|
||||
//- Return the global variable if available or a null result
|
||||
const exprResult& lookupGlobal(const word& name) const;
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Test for the existence of a mesh field
|
||||
template<class Type>
|
||||
bool isField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1 //!< ignored
|
||||
) const;
|
||||
|
||||
|
||||
//- Retrieve field from memory or disk
|
||||
template<class GeomField>
|
||||
inline tmp<GeomField> getOrReadField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Retrieve point field from memory or disk
|
||||
template<class GeomField>
|
||||
inline tmp<GeomField> getOrReadPointField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Retrieve field from memory or disk (implementation)
|
||||
template<class GeomField, class MeshRef>
|
||||
tmp<GeomField> getOrReadFieldImpl
|
||||
(
|
||||
const word& name,
|
||||
const MeshRef& meshRef,
|
||||
bool mandatory = true,
|
||||
bool getOldTime = false
|
||||
);
|
||||
|
||||
//- Helper function for getOrReadField
|
||||
template<class GeomField, class MeshRef>
|
||||
inline tmp<GeomField> readAndRegister
|
||||
(
|
||||
const word& name,
|
||||
const MeshRef& meshRef
|
||||
);
|
||||
|
||||
//- Create a random field
|
||||
//
|
||||
// \param field the field to populate
|
||||
// \param seed the seed value. If zero or negative, use as an offset
|
||||
// to the current timeIndex
|
||||
// \param gaussian generate a Gaussian distribution
|
||||
void fill_random
|
||||
(
|
||||
scalarField& field,
|
||||
label seed = 0,
|
||||
const bool gaussian = false
|
||||
) const;
|
||||
|
||||
|
||||
// Sets
|
||||
|
||||
//- The origin of the topoSet
|
||||
enum SetOrigin { INVALID = 0, NEW, FILE, MEMORY, CACHE };
|
||||
|
||||
//- Get topoSet
|
||||
template<class T>
|
||||
autoPtr<T> getTopoSet
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& setName,
|
||||
SetOrigin& origin
|
||||
) const;
|
||||
|
||||
//- Update topoSet
|
||||
template<class T>
|
||||
inline bool updateSet
|
||||
(
|
||||
autoPtr<T>& setPtr,
|
||||
const word& setName,
|
||||
SetOrigin origin
|
||||
) const;
|
||||
|
||||
|
||||
// Updating
|
||||
|
||||
//- Examine current variable values and update stored variables
|
||||
virtual void updateSpecialVariables(bool force=false);
|
||||
|
||||
//- Do we need a data file to be written
|
||||
virtual bool hasDataToWrite() const;
|
||||
|
||||
//- Prepare/update special variables and add to dictionary,
|
||||
//- normally via the reader/writer
|
||||
virtual void prepareData(dictionary& dict) const;
|
||||
|
||||
//- Read data from dictionary, normally via the reader/writer
|
||||
virtual void getData(const dictionary& dict);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Friends
|
||||
friend class exprDriverWriter;
|
||||
|
||||
|
||||
// Static Member Functions
|
||||
|
||||
//- Get the default mesh, if one is defined
|
||||
static const fvMesh& defaultMesh();
|
||||
|
||||
//- Set the default mesh (if not already set)
|
||||
static const fvMesh* resetDefaultMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const bool force = false //!< Force reset, even if already set
|
||||
);
|
||||
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("fvExprDriver");
|
||||
|
||||
|
||||
// Run-time selection
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
fvExprDriver,
|
||||
dictionary,
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
),
|
||||
(dict,mesh)
|
||||
);
|
||||
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
fvExprDriver,
|
||||
idName,
|
||||
(
|
||||
const word& ident,
|
||||
const fvMesh& mesh
|
||||
),
|
||||
(ident, mesh)
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor, and null construct with search preferences
|
||||
explicit fvExprDriver
|
||||
(
|
||||
bool cacheReadFields = false,
|
||||
bool searchInMemory = true,
|
||||
bool searchFiles = false,
|
||||
const dictionary& dict = dictionary::null
|
||||
);
|
||||
|
||||
//- Copy construct
|
||||
fvExprDriver(const fvExprDriver&);
|
||||
|
||||
//- Construct from a dictionary
|
||||
explicit fvExprDriver(const dictionary& dict);
|
||||
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
);
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
//- Return a reference to the selected value driver
|
||||
static autoPtr<fvExprDriver> New
|
||||
(
|
||||
const word& type,
|
||||
const word& id,
|
||||
const fvMesh& mesh
|
||||
);
|
||||
|
||||
//- Clone
|
||||
virtual autoPtr<fvExprDriver> clone() const = 0;
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~fvExprDriver();
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
//- The underlying field size for the expression
|
||||
virtual label size() const = 0;
|
||||
|
||||
//- The underlying point field size for the expression
|
||||
virtual label pointSize() const = 0;
|
||||
|
||||
|
||||
// Mesh Related
|
||||
|
||||
//- The Time associated with the mesh
|
||||
const Time& runTime() const;
|
||||
|
||||
//- The current time name
|
||||
virtual word timeName() const;
|
||||
|
||||
//- The current time value
|
||||
virtual scalar timeValue() const;
|
||||
|
||||
|
||||
// General Controls
|
||||
|
||||
//- Status of cache-sets (static variable)
|
||||
bool cacheSets() const { return cacheSets_; }
|
||||
|
||||
|
||||
// Variables
|
||||
|
||||
//- Clear temporary variables and resets from expression strings
|
||||
virtual void clearVariables();
|
||||
|
||||
//- True if named variable exists
|
||||
inline virtual bool hasVariable(const word& name) const;
|
||||
|
||||
//- Return const-access to the named variable
|
||||
inline virtual const exprResult& variable(const word& name) const;
|
||||
|
||||
//- Test for existence of a local/global variable or a field
|
||||
template<class Type>
|
||||
inline bool isVariableOrField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1
|
||||
) const;
|
||||
|
||||
//- Retrieve local/global variable as a tmp field
|
||||
//
|
||||
// \param name The name of the local/global field
|
||||
// \param expectSize The size check on the variable, -1 to ignore
|
||||
// \param mandatory A missing variable is Fatal, or return
|
||||
// an invalid tmp
|
||||
template<class Type>
|
||||
tmp<Field<Type>> getVariable
|
||||
(
|
||||
const word& name,
|
||||
label expectSize,
|
||||
const bool mandatory = true
|
||||
) const;
|
||||
|
||||
|
||||
//- Lookup the field class name (memory or read from disk)
|
||||
//
|
||||
// Return empty if the name cannot be resolved.
|
||||
word getFieldClassName(const word& name) const;
|
||||
|
||||
|
||||
// Types
|
||||
|
||||
//- Return cell/face/point set type or unknown
|
||||
topoSetSource::sourceType topoSetType(const word& name) const;
|
||||
|
||||
//- Return cell/face/point zone type or unknown
|
||||
topoSetSource::sourceType topoZoneType(const word& name) const;
|
||||
|
||||
//- Return cell/face/point zone/set type or unknown
|
||||
topoSetSource::sourceType topoSourceType(const word& name) const;
|
||||
|
||||
//- Read and return labels associated with the topo set
|
||||
labelList getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const;
|
||||
|
||||
//- Test if name is a known cellZone
|
||||
bool isCellZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known faceZone
|
||||
bool isFaceZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known pointZone
|
||||
bool isPointZone(const word& name) const;
|
||||
|
||||
//- Test if name is a known cellSet
|
||||
bool isCellSet(const word& name) const;
|
||||
|
||||
//- Test if name is a known faceSet
|
||||
bool isFaceSet(const word& name) const;
|
||||
|
||||
//- Test if name is a known pointSet
|
||||
bool isPointSet(const word& name) const;
|
||||
|
||||
|
||||
// Evaluation
|
||||
|
||||
//- Evaluate the expression
|
||||
//- and save as the specified named variable
|
||||
virtual void evaluateVariable
|
||||
(
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
);
|
||||
|
||||
//- Evaluate an expression on a remote
|
||||
//- and save as the specified named variable
|
||||
//
|
||||
// The fully qualified form of the remote is given as follows
|
||||
// \verbatim
|
||||
// type'name/region
|
||||
// \endverbatim
|
||||
//
|
||||
// If not specified, the default type is "patch", which means the
|
||||
// following are equivalent
|
||||
// \verbatim
|
||||
// patch'name/region
|
||||
// name/region
|
||||
// \endverbatim
|
||||
//
|
||||
// If region is identical to the current region, it can be omitted:
|
||||
// \verbatim
|
||||
// patch'name
|
||||
// name (default is patch)
|
||||
// \endverbatim
|
||||
virtual void evaluateVariableRemote
|
||||
(
|
||||
string remote,
|
||||
const word& varName,
|
||||
const expressions::exprString& expr
|
||||
);
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Test existence of a local/global variable
|
||||
template<class Type>
|
||||
inline bool isVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal = false,
|
||||
label expectSize = -1
|
||||
) const;
|
||||
|
||||
//- Test if specified field can be found in memory or disk
|
||||
template<class Type>
|
||||
bool foundField(const word& name) const;
|
||||
|
||||
//- Read the IOobject for fieldName and return its headerClassName
|
||||
// Empty if the field could not be found.
|
||||
word getTypeOfField(const word& fieldName) const;
|
||||
|
||||
|
||||
// Handling remote data (future)
|
||||
|
||||
// //- Access the other mesh name (future)
|
||||
// const word& otherMeshName() const { return otherMeshName_; }
|
||||
//
|
||||
// //- Access the other mesh name (future)
|
||||
// word& otherMeshName() { return otherMeshName_; }
|
||||
|
||||
|
||||
// Reading
|
||||
|
||||
//- Read variables, tables etc.
|
||||
// Also usable for objects not constructed from a dictionary.
|
||||
virtual bool readDict(const dictionary& dict);
|
||||
|
||||
|
||||
// Writing
|
||||
|
||||
//- Write "variables", "storedVariables", "delayedVariables",
|
||||
//- "globalScopes" if they are present.
|
||||
Ostream& writeCommon(Ostream& os, bool debug=false) const;
|
||||
|
||||
//- Create a writer for this object
|
||||
void createWriterAndRead(const word& name);
|
||||
|
||||
//- Write data if apropriate
|
||||
//- Should enable exact restarts
|
||||
void tryWrite() const;
|
||||
|
||||
|
||||
// Plugins (future)
|
||||
|
||||
/// //- Tests for a plugin-function
|
||||
/// virtual bool hasPlugin(const word& name) = 0;
|
||||
///
|
||||
/// //- Return a new plugin-function
|
||||
/// virtual autoPtr<CommonPluginFunction>
|
||||
/// getPlugin(const word& name) = 0;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "fvExprDriverI.H"
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "fvExprDriverTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
49
src/finiteVolume/expressions/base/fvExprDriverFields.C
Normal file
49
src/finiteVolume/expressions/base/fvExprDriverFields.C
Normal file
@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "fvExprDriver.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::expressions::fvExprDriver::fill_random
|
||||
(
|
||||
scalarField& field,
|
||||
label seed,
|
||||
const bool gaussian
|
||||
) const
|
||||
{
|
||||
exprDriver::fill_random
|
||||
(
|
||||
field, (seed <= 0 ? (runTime().timeIndex() - seed) : seed),
|
||||
gaussian
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
179
src/finiteVolume/expressions/base/fvExprDriverI.H
Normal file
179
src/finiteVolume/expressions/base/fvExprDriverI.H
Normal file
@ -0,0 +1,179 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::expressions::fvExprDriver::hasVariable
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
return delayedVariables_.found(name) || variables_.found(name);
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::variable
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (delayedVariables_.found(name))
|
||||
{
|
||||
return delayedVariables_[name];
|
||||
}
|
||||
|
||||
return variables_[name];
|
||||
}
|
||||
|
||||
|
||||
inline Foam::expressions::exprResult&
|
||||
Foam::expressions::fvExprDriver::variable
|
||||
(
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
if (delayedVariables_.found(name))
|
||||
{
|
||||
return delayedVariables_[name];
|
||||
}
|
||||
|
||||
return variables_[name];
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline bool Foam::expressions::fvExprDriver::isVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
) const
|
||||
{
|
||||
return
|
||||
(
|
||||
this->isLocalVariable<Type>(name, isPointVal, expectedSize)
|
||||
|| this->isGlobalVariable<Type>(name, isPointVal, expectedSize)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline bool Foam::expressions::fvExprDriver::isVariableOrField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
)
|
||||
const
|
||||
{
|
||||
return
|
||||
(
|
||||
this->isVariable<Type>(name, isPointVal, expectedSize)
|
||||
|| this->isField<Type>(name, isPointVal)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::getOrReadField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
return this->getOrReadFieldImpl<GeomField>
|
||||
(
|
||||
name,
|
||||
this->mesh(),
|
||||
mandatory,
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::getOrReadPointField
|
||||
(
|
||||
const word& name,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
return this->getOrReadFieldImpl<GeomField>
|
||||
(
|
||||
name,
|
||||
pointMesh::New(this->mesh()),
|
||||
mandatory,
|
||||
getOldTime
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField, class Mesh>
|
||||
inline Foam::tmp<GeomField>
|
||||
Foam::expressions::fvExprDriver::readAndRegister
|
||||
(
|
||||
const word& name,
|
||||
const Mesh& meshRef
|
||||
)
|
||||
{
|
||||
GeomField* ptr = new GeomField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name,
|
||||
meshRef.thisDb().time().timeName(),
|
||||
meshRef.thisDb(),
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Unregistered
|
||||
),
|
||||
meshRef
|
||||
);
|
||||
|
||||
if (cacheReadFields())
|
||||
{
|
||||
DebugInfo
|
||||
<< "Registering a copy of " << name << " with mesh" << nl;
|
||||
|
||||
// This is clunky
|
||||
ptr->checkIn();
|
||||
return tmp<GeomField>(regIOobject::store(ptr));
|
||||
}
|
||||
|
||||
return tmp<GeomField>(ptr);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
280
src/finiteVolume/expressions/base/fvExprDriverIO.C
Normal file
280
src/finiteVolume/expressions/base/fvExprDriverIO.C
Normal file
@ -0,0 +1,280 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "fvExprDriver.H"
|
||||
#include "exprDriverWriter.H"
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "pointSet.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::expressions::fvExprDriver::getTopoSetLabels
|
||||
(
|
||||
const word& name,
|
||||
enum topoSetSource::sourceType setType
|
||||
) const
|
||||
{
|
||||
// Zones first - they are cheap to handle (no IO)
|
||||
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().cellZones();
|
||||
const word& zoneTypeName = cellZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::FACEZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().faceZones();
|
||||
const word& zoneTypeName = faceZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::POINTZONE_SOURCE:
|
||||
{
|
||||
const auto& zones = mesh().pointZones();
|
||||
const word& zoneTypeName = pointZone::typeName;
|
||||
|
||||
const label zoneID = zones.findZoneID(name);
|
||||
if (zoneID < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No " << zoneTypeName << " named "
|
||||
<< name << "found. Has zones: " << zones.names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return zones[zoneID];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
IOobject io(topoSet::findIOobject(mesh(), name));
|
||||
|
||||
switch (setType)
|
||||
{
|
||||
case topoSetSource::sourceType::CELLSET_SOURCE:
|
||||
{
|
||||
typedef cellSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::FACESET_SOURCE:
|
||||
{
|
||||
typedef faceSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
case topoSetSource::sourceType::POINTSET_SOURCE:
|
||||
{
|
||||
typedef pointSet classType;
|
||||
|
||||
if (classType::typeName != io.headerClassName())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Error reading " << classType::typeName
|
||||
<< " <" << name << "> : found "
|
||||
<< io.headerClassName() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
classType set(io);
|
||||
return set.sortedToc();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unexpected sourceType: " << int(setType) << nl
|
||||
<< " for set <" << name << ">" << nl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return labelList::null();
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::fvExprDriver::getHeaderClassName
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
IOobject io
|
||||
(
|
||||
name,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
io.typeHeaderOk<IOobject>(false);
|
||||
|
||||
DebugInfo
|
||||
<< "Registry: " << mesh.path()
|
||||
<< " Name: " << name
|
||||
<< " Time: " << mesh.time().timeName()
|
||||
<< " Path: " << io.localFilePath(io.headerClassName())
|
||||
<< " Class: " << io.headerClassName() << endl;
|
||||
|
||||
return io.headerClassName();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::expressions::fvExprDriver::writeCommon
|
||||
(
|
||||
Ostream& os,
|
||||
bool debug
|
||||
) const
|
||||
{
|
||||
// Write "variables", even if empty
|
||||
writeVariableStrings(os, "variables");
|
||||
|
||||
if (debug)
|
||||
{
|
||||
os.writeEntry("variableValues", variables_);
|
||||
}
|
||||
|
||||
if (!storedVariables_.empty() || !delayedVariables_.empty())
|
||||
{
|
||||
const_cast<fvExprDriver&>
|
||||
(
|
||||
*this
|
||||
).updateSpecialVariables(true);
|
||||
}
|
||||
|
||||
if (!storedVariables_.empty())
|
||||
{
|
||||
os.writeEntry("storedVariables", storedVariables_);
|
||||
}
|
||||
|
||||
if (!delayedVariables_.empty())
|
||||
{
|
||||
List<exprResultDelayed> list(delayedVariables_.size());
|
||||
|
||||
auto outIter = list.begin();
|
||||
|
||||
forAllConstIters(delayedVariables_, iter)
|
||||
{
|
||||
*outIter = *iter;
|
||||
++outIter;
|
||||
}
|
||||
|
||||
os.writeEntry("delayedVariables", list);
|
||||
}
|
||||
|
||||
if (!globalScopes_.empty())
|
||||
{
|
||||
os.writeEntry("globalScopes", globalScopes_);
|
||||
}
|
||||
|
||||
// writeTable(os, "timelines", lines_);
|
||||
// writeTable(os, "lookuptables", lookup_);
|
||||
// writeTable(os, "lookuptables2D", lookup2D_);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::createWriterAndRead(const word& name)
|
||||
{
|
||||
if (hasDataToWrite() && !writer_.valid())
|
||||
{
|
||||
writer_.set(new exprDriverWriter(name + "_" + this->type(), *this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::fvExprDriver::tryWrite() const
|
||||
{
|
||||
if (writer_.valid() && mesh().time().outputTime())
|
||||
{
|
||||
writer_->write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
105
src/finiteVolume/expressions/base/fvExprDriverNew.C
Normal file
105
src/finiteVolume/expressions/base/fvExprDriverNew.C
Normal file
@ -0,0 +1,105 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "fvExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
return fvExprDriver::New
|
||||
(
|
||||
dict,
|
||||
defaultMesh()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
{
|
||||
const word driverType(dict.get<word>("valueType"));
|
||||
|
||||
auto cstrIter = dictionaryConstructorTablePtr_->cfind(driverType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalIOErrorInLookup
|
||||
(
|
||||
dict,
|
||||
"valueType",
|
||||
driverType,
|
||||
*dictionaryConstructorTablePtr_
|
||||
) << exit(FatalIOError);
|
||||
}
|
||||
|
||||
DebugInFunction << "Creating driver of type " << driverType << endl;
|
||||
|
||||
resetDefaultMesh(mesh, false); // lazy
|
||||
|
||||
return autoPtr<fvExprDriver>(cstrIter()(dict, mesh));
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::expressions::fvExprDriver>
|
||||
Foam::expressions::fvExprDriver::New
|
||||
(
|
||||
const word& driverType,
|
||||
const word& id,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
{
|
||||
auto cstrIter = idNameConstructorTablePtr_->cfind(driverType);
|
||||
|
||||
if (!cstrIter.found())
|
||||
{
|
||||
FatalErrorInLookup
|
||||
(
|
||||
"valueType",
|
||||
driverType,
|
||||
*idNameConstructorTablePtr_
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
DebugInFunction << "Creating driver of type " << driverType << endl;
|
||||
|
||||
resetDefaultMesh(mesh, false); // lazy
|
||||
|
||||
return autoPtr<fvExprDriver>(cstrIter()(id, mesh));
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
626
src/finiteVolume/expressions/base/fvExprDriverTemplates.C
Normal file
626
src/finiteVolume/expressions/base/fvExprDriverTemplates.C
Normal file
@ -0,0 +1,626 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2010-2018 Bernhard Gschaider <bgschaid@hfd-research.com>
|
||||
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 "surfaceMesh.H"
|
||||
#include "fvsPatchField.H"
|
||||
#include "pointPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::isGlobalVariable
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label expectedSize
|
||||
) const
|
||||
{
|
||||
DebugInfo
|
||||
<< "Looking for global" << (isPointVal ? " point" : "")
|
||||
<< " field name:" << name;
|
||||
|
||||
const exprResult& result = lookupGlobal(name);
|
||||
|
||||
DebugInfo
|
||||
<< " - found (" << result.valueType() << ' ' << result.isPointValue() << ')';
|
||||
|
||||
|
||||
bool good = (result.isType<Type>() && result.isPointValue(isPointVal));
|
||||
|
||||
// Do size checking if requested
|
||||
if (good && expectedSize >= 0)
|
||||
{
|
||||
good = (result.size() == expectedSize);
|
||||
reduce(good, andOp<bool>());
|
||||
|
||||
if (debug && !good)
|
||||
{
|
||||
Info<< " size is";
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfo << (good ? " good" : " bad") << endl;
|
||||
|
||||
return good;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::fvExprDriver::getVariable
|
||||
(
|
||||
const word& name,
|
||||
label expectedSize,
|
||||
const bool mandatory
|
||||
) const
|
||||
{
|
||||
tmp<Field<Type>> tresult;
|
||||
|
||||
bool isSingleValue = false;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
{
|
||||
isSingleValue = variable(name).isUniform();
|
||||
tresult = variable(name).cref<Type>().clone();
|
||||
}
|
||||
else if (isGlobalVariable<Type>(name, false))
|
||||
{
|
||||
const exprResult& var = lookupGlobal(name);
|
||||
|
||||
isSingleValue = var.isUniform();
|
||||
|
||||
tresult = var.cref<Type>().clone();
|
||||
}
|
||||
|
||||
if (tresult.valid())
|
||||
{
|
||||
if
|
||||
(
|
||||
expectedSize < 0
|
||||
|| returnReduce((tresult->size() == expectedSize), andOp<bool>())
|
||||
)
|
||||
{
|
||||
return tresult;
|
||||
}
|
||||
|
||||
if (!isSingleValue)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Variable " << name
|
||||
<< " is not a single value and does not fit the size "
|
||||
<< expectedSize << ". Using average" << endl;
|
||||
}
|
||||
|
||||
return tmp<Field<Type>>::New(expectedSize, gAverage(tresult()));
|
||||
}
|
||||
|
||||
if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Variable (" << name << ") not found." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::foundField
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::foundField. Name: " << name
|
||||
<< " Type: " << Type::typeName
|
||||
<< " registry:" << searchInMemory()
|
||||
<< " disk:" << searchFiles() << endl;
|
||||
}
|
||||
|
||||
// if (std::is_void<Type>::value) ...
|
||||
|
||||
if (searchInMemory())
|
||||
{
|
||||
const regIOobject* ioptr =
|
||||
this->mesh().findObject<regIOobject>(name);
|
||||
|
||||
if (this->mesh().foundObject<Type>(name))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found registered: " << name << endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Registered " << name;
|
||||
|
||||
if (ioptr)
|
||||
{
|
||||
Info<< " type:" << ioptr->headerClassName();
|
||||
}
|
||||
Info<< ", not type:" << Type::typeName << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (searchFiles() && getTypeOfField(name) == Type::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found file: " << name << nl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< name << " not found" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool Foam::expressions::fvExprDriver::isField
|
||||
(
|
||||
const word& name,
|
||||
bool isPointVal,
|
||||
label
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::isField <" << name << '>' << endl;
|
||||
}
|
||||
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfieldType;
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
|
||||
|
||||
return
|
||||
(
|
||||
isPointVal
|
||||
? this->foundField<pfieldType>(name)
|
||||
:
|
||||
(
|
||||
this->foundField<vfieldType>(name)
|
||||
|| this->foundField<sfieldType>(name)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
template<class GeomField, class Mesh>
|
||||
Foam::tmp<GeomField> Foam::expressions::fvExprDriver::getOrReadFieldImpl
|
||||
(
|
||||
const word& name,
|
||||
const Mesh& meshRef,
|
||||
bool mandatory,
|
||||
bool getOldTime
|
||||
)
|
||||
{
|
||||
typedef typename GeomField::value_type Type;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "fvExprDriver::getOrReadField <" << name
|
||||
<< "> Type: " << GeomField::typeName << endl;
|
||||
}
|
||||
|
||||
tmp<GeomField> tfield;
|
||||
|
||||
if
|
||||
(
|
||||
(hasVariable(name) && variable(name).isType<Type>())
|
||||
|| isGlobalVariable<Type>(name, false)
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting " << name << " from variables" << endl;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating field " << name << " of type "
|
||||
<< GeomField::typeName << nl;
|
||||
}
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
GeomField::New(name, meshRef, dimensioned<Type>(Zero))
|
||||
);
|
||||
|
||||
GeomField& fld = tfield.ref();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "New field: " << name << " ownedByRegistry"
|
||||
<< fld.ownedByRegistry() << endl;
|
||||
}
|
||||
|
||||
Field<Type> vals;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
{
|
||||
vals = variable(name).cref<Type>();
|
||||
}
|
||||
else
|
||||
{
|
||||
vals = lookupGlobal(name).cref<Type>();
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "sizes: " << vals.size() << ' ' << fld.size() << endl;
|
||||
}
|
||||
|
||||
if (returnReduce((vals.size() == fld.size()), andOp<bool>()))
|
||||
{
|
||||
fld.primitiveFieldRef() = vals;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type avg = gAverage(vals);
|
||||
|
||||
bool noWarn = false;
|
||||
|
||||
if (!noWarn)
|
||||
{
|
||||
MinMax<Type> range = gMinMax(vals);
|
||||
|
||||
if (range.mag() > SMALL)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "The min/max ranges differ " << range
|
||||
<< " - using average " << avg << nl;
|
||||
}
|
||||
}
|
||||
|
||||
fld.primitiveFieldRef() = avg;
|
||||
}
|
||||
|
||||
correctField(fld);
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
const objectRegistry& obr = meshRef.thisDb();
|
||||
|
||||
if (searchInMemory() && obr.foundObject<GeomField>(name))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Retrieve registered: " << name << nl;
|
||||
}
|
||||
|
||||
const GeomField& origFld = obr.lookupObject<GeomField>(name);
|
||||
|
||||
// Avoid shadowing the original object
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
GeomField::New(name + "_exprDriverCopy", origFld)
|
||||
);
|
||||
|
||||
if (getOldTime)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting oldTime of " << name << " has "
|
||||
<< origFld.nOldTimes() << endl;
|
||||
}
|
||||
|
||||
if (!origFld.nOldTimes() && this->prevIterIsOldTime())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "No oldTime, using previous iteration" << endl;
|
||||
}
|
||||
tfield.ref().oldTime() = origFld.prevIter();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (searchFiles() && getTypeOfField(name) == GeomField::typeName)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Reading " << name << " from disc" << endl;
|
||||
}
|
||||
|
||||
tfield.reset
|
||||
(
|
||||
this->readAndRegister<GeomField>(name, meshRef)
|
||||
);
|
||||
// oldTime automatically read
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "field: valid()=" << tfield.valid() << endl;
|
||||
}
|
||||
|
||||
if (tfield.valid())
|
||||
{
|
||||
GeomField& fld = tfield.ref();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Valid " << name << " found. Removing dimensions" << nl;
|
||||
}
|
||||
|
||||
fld.dimensions().clear();
|
||||
|
||||
if (fld.nOldTimes())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Removing dimensions of oldTime of " << name
|
||||
<< " has " << fld.nOldTimes() << nl;
|
||||
}
|
||||
|
||||
// Switch dimension checking off
|
||||
const int oldDebug = dimensionSet::debug;
|
||||
dimensionSet::debug = 0;
|
||||
|
||||
// go through ALL old times
|
||||
GeomField* fp = &(fld);
|
||||
|
||||
while (fp->nOldTimes())
|
||||
{
|
||||
fp = &(fp->oldTime());
|
||||
fp->dimensions().clear();
|
||||
}
|
||||
|
||||
// Restore old value of dimension checking
|
||||
dimensionSet::debug = oldDebug;
|
||||
}
|
||||
}
|
||||
else if (mandatory)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Could not find field " << name
|
||||
<< " in registry or on file-system" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::autoPtr<T> Foam::expressions::fvExprDriver::getTopoSet
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& name,
|
||||
SetOrigin& origin
|
||||
) const
|
||||
{
|
||||
// Avoid possible name clashes
|
||||
const word regName = name + "RegisteredNameFor" + T::typeName;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Looking for " << T::typeName << " named " << name;
|
||||
|
||||
Info<< " or registered as " << regName << " with mesh "
|
||||
<< "Caching:" << cacheSets()
|
||||
<< " Found:" << (mesh.foundObject<T>(name))
|
||||
<< " Found registered:" << mesh.foundObject<T>(regName)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
origin = SetOrigin::INVALID;
|
||||
autoPtr<T> setPtr;
|
||||
|
||||
if
|
||||
(
|
||||
!cacheSets()
|
||||
||
|
||||
(
|
||||
!mesh.thisDb().foundObject<T>(regName)
|
||||
&& !mesh.thisDb().foundObject<T>(name)
|
||||
)
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Constructing new " << T::typeName << ' ' << name << nl;
|
||||
|
||||
if (debug > 1)
|
||||
{
|
||||
Pout<< mesh.thisDb().names();
|
||||
}
|
||||
}
|
||||
|
||||
origin = SetOrigin::FILE;
|
||||
setPtr.reset(new T(mesh, name, IOobject::MUST_READ));
|
||||
|
||||
if (cacheSets())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Registering a copy of " << name << " with mesh" << nl;
|
||||
}
|
||||
|
||||
autoPtr<T> toCache(new T(mesh, regName, *setPtr));
|
||||
toCache->store(toCache);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const T* ptr = mesh.thisDb().findObject<T>(name);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting existing " << name << endl;
|
||||
}
|
||||
|
||||
origin = SetOrigin::MEMORY;
|
||||
setPtr.reset(new T(mesh, name, *ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Getting existing " << regName << endl;
|
||||
}
|
||||
|
||||
origin = SetOrigin::CACHE;
|
||||
setPtr.reset(new T(mesh, name, mesh.lookupObject<T>(regName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return setPtr;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::expressions::fvExprDriver::updateSet
|
||||
(
|
||||
autoPtr<T>& setPtr,
|
||||
const word& name,
|
||||
SetOrigin origin
|
||||
) const
|
||||
{
|
||||
const label oldSize = setPtr->size();
|
||||
|
||||
bool updated = false;
|
||||
const polyMesh& mesh = dynamic_cast<const polyMesh&>(setPtr->db());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "UpdateSet: " << setPtr->name() << " Id: " << name
|
||||
<< " Origin: " << int(origin) << endl;
|
||||
}
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case SetOrigin::FILE:
|
||||
{
|
||||
IOobject header
|
||||
(
|
||||
name,
|
||||
mesh.time().timeName(),
|
||||
polyMesh::meshSubDir/"sets",
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (header.typeHeaderOk<T>())
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Rereading from "
|
||||
<< header.localFilePath(T::typeName) << endl;
|
||||
}
|
||||
setPtr.reset(new T(header));
|
||||
updated = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SetOrigin::NEW:
|
||||
case SetOrigin::MEMORY:
|
||||
case SetOrigin::CACHE:
|
||||
{
|
||||
if (origin == SetOrigin::NEW)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "State NEW shouldn't exist"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
word sName = name;
|
||||
|
||||
const T* ptr = mesh.thisDb().findObject<T>(name);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Found " << name
|
||||
<< " and rereading it" << endl;
|
||||
}
|
||||
|
||||
setPtr.reset(new T(mesh, name, *ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< name << " Not found" << endl
|
||||
<< "In registry: " << mesh.thisDb().names() << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
updated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case INVALID:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< T::typeName << ' ' << name << " is invalid" << endl
|
||||
<< exit(FatalError);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Origin " << int(origin) << " not implemented" << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< name << " old size " << oldSize << " new: "
|
||||
<< setPtr->size() << endl;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
186
src/finiteVolume/expressions/fields/base/patchExprFieldBase.C
Normal file
186
src/finiteVolume/expressions/fields/base/patchExprFieldBase.C
Normal file
@ -0,0 +1,186 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2011-2018 Bernhard Gschaider
|
||||
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 "patchExprFieldBase.H"
|
||||
#include "facePointPatch.H"
|
||||
#include "fvMesh.H"
|
||||
#include "fvPatch.H"
|
||||
#include "pointMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fvPatch&
|
||||
Foam::expressions::patchExprFieldBase::getFvPatch(const facePointPatch& pp)
|
||||
{
|
||||
const polyMesh& pmesh = pp.boundaryMesh().mesh().mesh();
|
||||
|
||||
const fvMesh* meshptr = isA<fvMesh>(pmesh);
|
||||
|
||||
if (!meshptr)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Point patch not attached to a base fvMesh, "
|
||||
<< "cannot use patch expressions" << nl << endl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return meshptr->boundary()[pp.index()];
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::patchExprFieldBase::patchExprFieldBase()
|
||||
:
|
||||
patchExprFieldBase(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExprFieldBase::patchExprFieldBase
|
||||
(
|
||||
bool allowGradient
|
||||
)
|
||||
:
|
||||
debug_(false),
|
||||
allowGradient_(allowGradient),
|
||||
evalOnConstruct_(false),
|
||||
valueExpr_(),
|
||||
gradExpr_(),
|
||||
fracExpr_()
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExprFieldBase::patchExprFieldBase
|
||||
(
|
||||
const dictionary& dict,
|
||||
bool allowGradient,
|
||||
bool isPointVal
|
||||
)
|
||||
:
|
||||
debug_(dict.lookupOrDefault("debug", false)),
|
||||
allowGradient_(allowGradient),
|
||||
evalOnConstruct_(dict.lookupOrDefault<bool>("evalOnConstruct", false)),
|
||||
valueExpr_(),
|
||||
gradExpr_(),
|
||||
fracExpr_()
|
||||
{
|
||||
if (debug_)
|
||||
{
|
||||
Info<< "Expression BC with " << dict << nl;
|
||||
}
|
||||
|
||||
string expr;
|
||||
|
||||
if (dict.readIfPresent("valueExpr", expr))
|
||||
{
|
||||
valueExpr_ = expressions::exprString(expr, dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No value expression - same as Zero
|
||||
if (debug_)
|
||||
{
|
||||
Info<< "No valueExpr" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowGradient)
|
||||
{
|
||||
if (dict.readIfPresent("gradientExpr", expr))
|
||||
{
|
||||
gradExpr_ = expressions::exprString(expr, dict);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No gradient expression - same as Zero
|
||||
|
||||
if (debug_)
|
||||
{
|
||||
Info<< "No gradientExpr" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
if (dict.readIfPresent("fractionExpr", expr))
|
||||
{
|
||||
if (!expr.empty() && expr != "0")
|
||||
{
|
||||
if (isPointVal)
|
||||
{
|
||||
expr = "toPoint(" + expr + ")";
|
||||
}
|
||||
|
||||
fracExpr_ = expressions::exprString(expr, dict);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No fraction expression - same as 1 (one)
|
||||
// Mixed BC may elect to simply ignore gradient expression
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::expressions::patchExprFieldBase::patchExprFieldBase
|
||||
(
|
||||
const patchExprFieldBase& rhs
|
||||
)
|
||||
:
|
||||
debug_(rhs.debug_),
|
||||
allowGradient_(rhs.allowGradient_),
|
||||
evalOnConstruct_(rhs.evalOnConstruct_),
|
||||
valueExpr_(rhs.valueExpr_),
|
||||
gradExpr_(rhs.gradExpr_),
|
||||
fracExpr_(rhs.fracExpr_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::expressions::patchExprFieldBase::write(Ostream& os) const
|
||||
{
|
||||
os.writeEntryIfDifferent<bool>("evalOnConstruct", false, evalOnConstruct_);
|
||||
|
||||
// Do not emit debug_ value
|
||||
|
||||
if (!valueExpr_.empty())
|
||||
{
|
||||
os.writeEntry("valueExpr", valueExpr_);
|
||||
}
|
||||
if (!gradExpr_.empty())
|
||||
{
|
||||
os.writeEntry("gradientExpr", gradExpr_);
|
||||
}
|
||||
if (!fracExpr_.empty())
|
||||
{
|
||||
os.writeEntry("fractionExpr", fracExpr_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
131
src/finiteVolume/expressions/fields/base/patchExprFieldBase.H
Normal file
131
src/finiteVolume/expressions/fields/base/patchExprFieldBase.H
Normal file
@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2011-2018 Bernhard Gschaider
|
||||
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::patchExprFieldBase
|
||||
|
||||
Description
|
||||
Base class for managing patches with expressions.
|
||||
The expected input supports values, gradients and mixed conditions
|
||||
|
||||
Usage
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
valueExpr | expression for fixed value | no | 0
|
||||
gradientExpr | expression for patch normal gradient | no | 0
|
||||
fractionExpr | expression for value fraction weight | no | 1
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
patchExprFieldBase.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_patchExprFieldBase_H
|
||||
#define expressions_patchExprFieldBase_H
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "dictionary.H"
|
||||
#include "exprString.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class facePointPatch;
|
||||
class fvPatch;
|
||||
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class patchExprFieldBase Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class patchExprFieldBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
bool debug_;
|
||||
bool allowGradient_;
|
||||
|
||||
//- Slightly dodgy concept here
|
||||
bool evalOnConstruct_;
|
||||
|
||||
// The expressions
|
||||
expressions::exprString valueExpr_;
|
||||
expressions::exprString gradExpr_;
|
||||
expressions::exprString fracExpr_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Static Methods
|
||||
|
||||
//- Find (guess) fvPatch from a pointPatch
|
||||
static const fvPatch& getFvPatch(const facePointPatch& fp);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Null constructor
|
||||
patchExprFieldBase();
|
||||
|
||||
//- Construct with specified gradient handling
|
||||
explicit patchExprFieldBase(bool allowGradient);
|
||||
|
||||
//- Construct from dictionary
|
||||
explicit patchExprFieldBase
|
||||
(
|
||||
const dictionary& dict,
|
||||
bool allowGradient = false,
|
||||
bool isPointVal = false
|
||||
);
|
||||
|
||||
//- Copy constructor
|
||||
patchExprFieldBase(const patchExprFieldBase& rhs);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Write
|
||||
void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,215 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2009-2018 Bernhard Gschaider
|
||||
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 "exprFixedValueFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprFixedValueFvPatchField<Type>::setDebug()
|
||||
{
|
||||
if (expressions::patchExprFieldBase::debug_ && !debug)
|
||||
{
|
||||
debug = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(false),
|
||||
driver_(this->patch())
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const dictionary& dict,
|
||||
const bool valueRequired
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(dict),
|
||||
driver_(this->patch(), dict)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
|
||||
// Basic sanity
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The valueExpr was not defined!" << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
driver_.readDict(dict);
|
||||
|
||||
if (dict.found("value"))
|
||||
{
|
||||
fvPatchField<Type>::operator=
|
||||
(
|
||||
Field<Type>("value", dict, p.size())
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*this) == this->patchInternalField();
|
||||
|
||||
WarningInFunction
|
||||
<< "No value defined for "
|
||||
<< this->internalField().name() << " on "
|
||||
<< this->patch().name() << " - setting to internalField value "
|
||||
<< nl;
|
||||
}
|
||||
|
||||
if (this->evalOnConstruct_)
|
||||
{
|
||||
// For potentialFoam or other solvers that don't evaluate
|
||||
this->evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<Type>(ptf),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<Type>(ptf, iF),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprFixedValueFvPatchField<Type>::updateCoeffs()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction
|
||||
<< "Value: " << this->valueExpr_ << nl
|
||||
<< "Variables: ";
|
||||
driver_.writeVariableStrings(Info) << endl;
|
||||
}
|
||||
|
||||
if (this->updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DebugInFunction
|
||||
<< "updating" << nl;
|
||||
|
||||
// Expression evaluation
|
||||
{
|
||||
driver_.clearVariables();
|
||||
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
(*this) == Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp<Field<Type>> tresult(driver_.evaluate<Type>(this->valueExpr_));
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Evaluated: " << tresult();
|
||||
}
|
||||
|
||||
(*this) == tresult;
|
||||
}
|
||||
}
|
||||
|
||||
fixedValueFvPatchField<Type>::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprFixedValueFvPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
fixedValueFvPatchField<Type>::write(os);
|
||||
expressions::patchExprFieldBase::write(os);
|
||||
|
||||
// driver_.writeCommon(os, this->debug_ || debug);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,175 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2009-2018 Bernhard Gschaider
|
||||
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::exprFixedValueFvPatchField
|
||||
|
||||
Description
|
||||
A fixed value boundary condition with expressions.
|
||||
|
||||
Usage
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
value | fixed value | yes |
|
||||
valueExpr | expression for fixed value | yes |
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
exprFixedValueFvPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprFixedValueFvPatchField_H
|
||||
#define exprFixedValueFvPatchField_H
|
||||
|
||||
#include "fixedValueFvPatchField.H"
|
||||
#include "patchExprFieldBase.H"
|
||||
#include "patchExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class exprFixedValueFvPatchField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class exprFixedValueFvPatchField
|
||||
:
|
||||
public fixedValueFvPatchField<Type>,
|
||||
public expressions::patchExprFieldBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The expression driver
|
||||
expressions::patchExpr::parseDriver driver_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set debug ON if "debug" is enabled
|
||||
void setDebug();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("exprFixedValue");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
exprFixedValueFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
exprFixedValueFvPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const dictionary& dict,
|
||||
const bool valueRequired=true
|
||||
);
|
||||
|
||||
//- Construct by mapping given exprFixedValueFvPatchField
|
||||
//- onto a new patch
|
||||
exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>&
|
||||
);
|
||||
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchField<Type>> clone() const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new exprFixedValueFvPatchField<Type>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
exprFixedValueFvPatchField
|
||||
(
|
||||
const exprFixedValueFvPatchField<Type>&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchField<Type>> clone
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new exprFixedValueFvPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "exprFixedValueFvPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "exprFixedValueFvPatchFields.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makePatchFields(exprFixedValue);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprFixedValueFvPatchFields_H
|
||||
#define exprFixedValueFvPatchFields_H
|
||||
|
||||
#include "exprFixedValueFvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeFieldTypedefs(exprFixedValue);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprFixedValueFvPatchFieldsFwd_H
|
||||
#define exprFixedValueFvPatchFieldsFwd_H
|
||||
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class exprFixedValueFvPatchField;
|
||||
|
||||
makePatchTypeFieldTypedefs(exprFixedValue);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,309 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2009-2018 Bernhard Gschaider
|
||||
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 "exprMixedFvPatchField.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprMixedFvPatchField<Type>::setDebug()
|
||||
{
|
||||
if (expressions::patchExprFieldBase::debug_ && !debug)
|
||||
{
|
||||
debug = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::exprMixedFvPatchField<Type>::exprMixedFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
mixedFvPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(true), // allowGradient
|
||||
driver_(this->patch())
|
||||
{
|
||||
this->refValue() = Zero;
|
||||
this->refGrad() = Zero;
|
||||
this->valueFraction() = scalar(1);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprMixedFvPatchField<Type>::exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
mixedFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprMixedFvPatchField<Type>::exprMixedFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
mixedFvPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(dict, true),
|
||||
driver_(this->patch(), dict)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
|
||||
// Basic sanity checks
|
||||
if (this->valueExpr_.empty() && this->gradExpr_.empty())
|
||||
{
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The valueExpr was not defined!" << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
if (this->gradExpr_.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The gradientExpr was not defined!" << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
driver_.readDict(dict);
|
||||
|
||||
// Similar to fvPatchField constructor, which we have bypassed
|
||||
dict.readIfPresent("patchType", this->patchType());
|
||||
|
||||
if (dict.found("refValue"))
|
||||
{
|
||||
this->refValue() = Field<Type>("refValue", dict, p.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->refValue() = this->patchInternalField();
|
||||
}
|
||||
|
||||
if (dict.found("value"))
|
||||
{
|
||||
fvPatchField<Type>::operator=
|
||||
(
|
||||
Field<Type>("value", dict, p.size())
|
||||
);
|
||||
|
||||
if (!dict.found("refValue"))
|
||||
{
|
||||
// Ensure refValue has a sensible value for the "update" below
|
||||
this->refValue() = Field<Type>("value", dict, p.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fvPatchField<Type>::operator=(this->refValue());
|
||||
|
||||
WarningInFunction
|
||||
<< "No value defined for "
|
||||
<< this->internalField().name()
|
||||
<< " on " << this->patch().name() << " therefore using "
|
||||
<< "the internal field next to the patch"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
if (dict.found("refGradient"))
|
||||
{
|
||||
this->refGrad() = Field<Type>("refGradient", dict, p.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->refGrad() = Zero;
|
||||
}
|
||||
|
||||
if (dict.found("valueFraction"))
|
||||
{
|
||||
this->valueFraction() = Field<scalar>("valueFraction", dict, p.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
this->valueFraction() = 1;
|
||||
}
|
||||
|
||||
|
||||
if (this->evalOnConstruct_)
|
||||
{
|
||||
// For potentialFoam or other solvers that don't evaluate
|
||||
this->evaluate();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Emulate mixedFvPatchField<Type>::evaluate,
|
||||
// but avoid our own updateCoeffs
|
||||
if (!this->updated())
|
||||
{
|
||||
this->mixedFvPatchField<Type>::updateCoeffs();
|
||||
}
|
||||
|
||||
Field<Type>::operator=
|
||||
(
|
||||
this->valueFraction()*this->refValue()
|
||||
+
|
||||
(1.0 - this->valueFraction())*
|
||||
(
|
||||
this->patchInternalField()
|
||||
+ this->refGrad()/this->patch().deltaCoeffs()
|
||||
)
|
||||
);
|
||||
|
||||
fvPatchField<Type>::evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprMixedFvPatchField<Type>::exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
mixedFvPatchField<Type>(ptf),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprMixedFvPatchField<Type>::exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
mixedFvPatchField<Type>(ptf, iF),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_(this->patch(), ptf.driver_)
|
||||
{
|
||||
setDebug();
|
||||
DebugInFunction << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprMixedFvPatchField<Type>::updateCoeffs()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction
|
||||
<< "Value: " << this->valueExpr_ << nl
|
||||
<< "Gradient: " << this->gradExpr_ << nl
|
||||
<< "Fraction: " << this->fracExpr_ << nl
|
||||
<< "Variables: ";
|
||||
|
||||
driver_.writeVariableStrings(Info) << endl;
|
||||
}
|
||||
|
||||
if (this->updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DebugInFunction << " - updating" << nl;
|
||||
|
||||
|
||||
// Expression evaluation
|
||||
{
|
||||
driver_.clearVariables();
|
||||
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
this->refValue() = Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->refValue() = driver_.evaluate<Type>(this->valueExpr_);
|
||||
}
|
||||
|
||||
bool evalGrad = !this->gradExpr_.empty();
|
||||
|
||||
if (this->fracExpr_.empty() || this->fracExpr_ == "1")
|
||||
{
|
||||
evalGrad = false;
|
||||
this->valueFraction() = scalar(1);
|
||||
}
|
||||
else if (this->fracExpr_ == "0")
|
||||
{
|
||||
this->valueFraction() = Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->valueFraction() = driver_.evaluate<scalar>(this->fracExpr_);
|
||||
}
|
||||
|
||||
if (evalGrad)
|
||||
{
|
||||
this->refGrad() = driver_.evaluate<Type>(this->gradExpr_);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->refGrad() = Zero;
|
||||
}
|
||||
}
|
||||
|
||||
mixedFvPatchField<Type>::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprMixedFvPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
mixedFvPatchField<Type>::write(os);
|
||||
expressions::patchExprFieldBase::write(os);
|
||||
|
||||
// driver_.writeCommon(os, this->debug_ || debug);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,172 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2009-2018 Bernhard Gschaider
|
||||
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::exprMixedFvPatchField
|
||||
|
||||
Description
|
||||
A mixed boundary condition with expressions.
|
||||
|
||||
Usage
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
valueExpr | expression for fixed value | no | 0
|
||||
gradientExpr | expression for patch normal gradient | no | 0
|
||||
fractionExpr | expression for value weighting | no | 1
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
exprMixedFvPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprMixedFvPatchField_H
|
||||
#define exprMixedFvPatchField_H
|
||||
|
||||
#include "mixedFvPatchField.H"
|
||||
#include "patchExprFieldBase.H"
|
||||
#include "patchExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class exprMixedFvPatchField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class exprMixedFvPatchField
|
||||
:
|
||||
public mixedFvPatchField<Type>,
|
||||
public expressions::patchExprFieldBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The expression driver
|
||||
expressions::patchExpr::parseDriver driver_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set debug ON if "debug" is enabled
|
||||
void setDebug();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("exprMixed");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
exprMixedFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
exprMixedFvPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
//- Construct by mapping given exprMixedFvPatchField onto a new patch
|
||||
exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchField<Type>> clone() const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new exprMixedFvPatchField<Type>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
exprMixedFvPatchField
|
||||
(
|
||||
const exprMixedFvPatchField<Type>&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchField<Type> > clone
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchField<Type>>
|
||||
(
|
||||
new exprMixedFvPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "exprMixedFvPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "exprMixedFvPatchFields.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makePatchFields(exprMixed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprMixedFvPatchFields_H
|
||||
#define exprMixedFvPatchFields_H
|
||||
|
||||
#include "exprMixedFvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeFieldTypedefs(exprMixed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprMixedFvPatchFieldsFwd_H
|
||||
#define exprMixedFvPatchFieldsFwd_H
|
||||
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class exprMixedFvPatchField;
|
||||
|
||||
makePatchTypeFieldTypedefs(exprMixed);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,219 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2010-2018 Bernhard Gschaider
|
||||
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 "exprValuePointPatchField.H"
|
||||
#include "pointPatchFieldMapper.H"
|
||||
#include "typeInfo.H"
|
||||
#include "facePointPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::exprValuePointPatchField<Type>::exprValuePointPatchField
|
||||
(
|
||||
const pointPatch& p,
|
||||
const DimensionedField<Type, pointMesh>& iF
|
||||
)
|
||||
:
|
||||
valuePointPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(false),
|
||||
driver_
|
||||
(
|
||||
expressions::patchExprFieldBase::getFvPatch
|
||||
(
|
||||
dynamicCast<const facePointPatch>(this->patch())
|
||||
)
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprValuePointPatchField<Type>::exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>& ptf,
|
||||
const pointPatch& p,
|
||||
const DimensionedField<Type, pointMesh>& iF,
|
||||
const pointPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
valuePointPatchField<Type>(ptf, p, iF, mapper),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_
|
||||
(
|
||||
expressions::patchExprFieldBase::getFvPatch
|
||||
(
|
||||
dynamicCast<const facePointPatch>(this->patch())
|
||||
),
|
||||
ptf.driver_
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprValuePointPatchField<Type>::exprValuePointPatchField
|
||||
(
|
||||
const pointPatch& p,
|
||||
const DimensionedField<Type, pointMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
valuePointPatchField<Type>(p, iF),
|
||||
expressions::patchExprFieldBase(dict, false, true),
|
||||
driver_
|
||||
(
|
||||
expressions::patchExprFieldBase::getFvPatch
|
||||
(
|
||||
dynamicCast<const facePointPatch>(this->patch())
|
||||
),
|
||||
dict
|
||||
)
|
||||
{
|
||||
// Basic sanity
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The valueExpr was not defined!" << nl
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
driver_.readDict(dict);
|
||||
|
||||
if (dict.found("value"))
|
||||
{
|
||||
Field<Type>::operator=
|
||||
(
|
||||
Field<Type>("value", dict, p.size())
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< "No value defined for "
|
||||
<< this->internalField().name()
|
||||
<< " on " << this->patch().name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (this->evalOnConstruct_)
|
||||
{
|
||||
// For potentialFoam or other solvers that don't evaluate
|
||||
this->evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprValuePointPatchField<Type>::exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, pointMesh>& iF
|
||||
)
|
||||
:
|
||||
valuePointPatchField<Type>(ptf, iF),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_
|
||||
(
|
||||
expressions::patchExprFieldBase::getFvPatch
|
||||
(
|
||||
dynamicCast<const facePointPatch>(this->patch())
|
||||
),
|
||||
ptf.driver_
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::exprValuePointPatchField<Type>::exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
valuePointPatchField<Type>(ptf),
|
||||
expressions::patchExprFieldBase(ptf),
|
||||
driver_
|
||||
(
|
||||
expressions::patchExprFieldBase::getFvPatch
|
||||
(
|
||||
dynamicCast<const facePointPatch>(this->patch())
|
||||
),
|
||||
ptf.driver_
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprValuePointPatchField<Type>::updateCoeffs()
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
InfoInFunction
|
||||
<< "Value: " << this->valueExpr_ << nl
|
||||
<< "Variables: ";
|
||||
driver_.writeVariableStrings(Info) << endl;
|
||||
}
|
||||
|
||||
if (this->updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Expression evaluation
|
||||
{
|
||||
driver_.clearVariables();
|
||||
|
||||
if (this->valueExpr_.empty())
|
||||
{
|
||||
(*this) == Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Field<Type>::operator=
|
||||
(
|
||||
driver_.evaluate<Type>(this->valueExpr_, true)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
valuePointPatchField<Type>::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::exprValuePointPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
valuePointPatchField<Type>::write(os);
|
||||
expressions::patchExprFieldBase::write(os);
|
||||
|
||||
this->writeEntry("value",os);
|
||||
|
||||
// driver_.writeCommon(os,this->debug_ || debug);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,175 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Original code Copyright (C) 2010-2018 Bernhard Gschaider
|
||||
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::exprValuePointPatchField
|
||||
|
||||
Description
|
||||
A fixed value point boundary condition with expressions.
|
||||
|
||||
Usage
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
value | fixed value | yes |
|
||||
valueExpr | expression for fixed value | yes |
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
exprValuePointPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprValuePointPatchField_H
|
||||
#define exprValuePointPatchField_H
|
||||
|
||||
#include "valuePointPatchField.H"
|
||||
#include "patchExprFieldBase.H"
|
||||
#include "patchExprDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class exprValuePointPatchField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class exprValuePointPatchField
|
||||
:
|
||||
public valuePointPatchField<Type>,
|
||||
public expressions::patchExprFieldBase
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The expression driver
|
||||
expressions::patchExpr::parseDriver driver_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("exprValue");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
exprValuePointPatchField
|
||||
(
|
||||
const pointPatch&,
|
||||
const DimensionedField<Type, pointMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
exprValuePointPatchField
|
||||
(
|
||||
const pointPatch&,
|
||||
const DimensionedField<Type, pointMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given patchField<Type> onto a new patch
|
||||
exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>&,
|
||||
const pointPatch&,
|
||||
const DimensionedField<Type, pointMesh>&,
|
||||
const pointPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>&,
|
||||
const DimensionedField<Type, pointMesh>&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
exprValuePointPatchField
|
||||
(
|
||||
const exprValuePointPatchField<Type>&
|
||||
);
|
||||
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<pointPatchField<Type> > clone() const
|
||||
{
|
||||
return autoPtr<pointPatchField<Type>>
|
||||
(
|
||||
new exprValuePointPatchField<Type>
|
||||
(
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual autoPtr<pointPatchField<Type>> clone
|
||||
(
|
||||
const DimensionedField<Type, pointMesh>& iF
|
||||
) const
|
||||
{
|
||||
return autoPtr<pointPatchField<Type>>
|
||||
(
|
||||
new exprValuePointPatchField<Type>
|
||||
(
|
||||
*this,
|
||||
iF
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Update the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "exprValuePointPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "exprValuePointPatchFields.H"
|
||||
#include "pointPatchFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makePointPatchFields(exprValue);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef exprValuePointPatchFields_H
|
||||
#define exprValuePointPatchFields_H
|
||||
|
||||
#include "exprValuePointPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePointPatchFieldTypedefs(exprValue);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
13
src/finiteVolume/expressions/patch/createCode
Executable file
13
src/finiteVolume/expressions/patch/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=patchExpr
|
||||
|
||||
"${WM_PROJECT_DIR:?}/wmake/scripts/makeParser" \
|
||||
-prefix="$prefix" \
|
||||
-scanner=Scanner.rl \
|
||||
-parser=LemonParser.lyy-m4 \
|
||||
"$@"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
45
src/finiteVolume/expressions/patch/patchExpr.C
Normal file
45
src/finiteVolume/expressions/patch/patchExpr.C
Normal file
@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "patchExprFwd.H"
|
||||
#include "defineDebugSwitch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Globals * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
|
||||
defineDebugSwitchWithName(patchExpr, "patchExpr", 0);
|
||||
registerDebugSwitchWithName(patchExpr, patchExpr, "patchExpr");
|
||||
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
188
src/finiteVolume/expressions/patch/patchExprDriver.C
Normal file
188
src/finiteVolume/expressions/patch/patchExprDriver.C
Normal file
@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "patchExprDriver.H"
|
||||
#include "patchExprScanner.H"
|
||||
#include "error.H"
|
||||
#include "fvPatch.H"
|
||||
#include "fvMesh.H"
|
||||
#include "className.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(parseDriver, 0);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
dictionary,
|
||||
patch
|
||||
);
|
||||
|
||||
addNamedToRunTimeSelectionTable
|
||||
(
|
||||
fvExprDriver,
|
||||
parseDriver,
|
||||
idName,
|
||||
patch
|
||||
);
|
||||
|
||||
} // End namespace patchExpr
|
||||
} // 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 fvPatch& findFvPatch
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& patchName
|
||||
)
|
||||
{
|
||||
return mesh.boundary()[getPatchID(mesh, patchName)];
|
||||
}
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fvPatch& Foam::expressions::patchExpr::parseDriver::getFvPatch
|
||||
(
|
||||
const fvMesh& fvm,
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
return findFvPatch
|
||||
(
|
||||
regionMesh(dict, fvm, true),
|
||||
dict.get<word>("patch")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver(const fvPatch& p)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(),
|
||||
patch_(p)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver
|
||||
(
|
||||
const fvPatch& p,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(dict),
|
||||
patch_(p)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver
|
||||
(
|
||||
const fvPatch& p,
|
||||
const parseDriver& driver_
|
||||
)
|
||||
:
|
||||
parsing::genericRagelLemonDriver(),
|
||||
expressions::fvExprDriver(driver_),
|
||||
patch_(p)
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver
|
||||
(
|
||||
const word& patchName,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
:
|
||||
parseDriver(findFvPatch(mesh, patchName))
|
||||
{}
|
||||
|
||||
|
||||
Foam::expressions::patchExpr::parseDriver::parseDriver
|
||||
(
|
||||
const dictionary& dict,
|
||||
const fvMesh& mesh
|
||||
)
|
||||
:
|
||||
parseDriver(getFvPatch(mesh, dict), dict)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
unsigned Foam::expressions::patchExpr::parseDriver::parse
|
||||
(
|
||||
const std::string& expr,
|
||||
size_t pos,
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
scanner scan(this->debugScanner());
|
||||
|
||||
scan.process(expr, pos, len, *this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
305
src/finiteVolume/expressions/patch/patchExprDriver.H
Normal file
305
src/finiteVolume/expressions/patch/patchExprDriver.H
Normal file
@ -0,0 +1,305 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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::patchExpr::parseDriver
|
||||
|
||||
Description
|
||||
Driver for patch expressions
|
||||
|
||||
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 face centres | 0 |
|
||||
pts | The face points | 0 |
|
||||
area | The face area magnitudes | 0 |
|
||||
weightAverage| Area weighted average | 1 |
|
||||
weightSum | Area weighted sum | 1 |
|
||||
face | The face areaNormal vectors | 0 |
|
||||
point | A point-field point value | 1 |
|
||||
faceToPoint | Interpolate face values onto points | 1 |
|
||||
pointToFace | Interpolate point values onto faces | 1 |
|
||||
rand | Random field | 0/1 |
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
patchExprDriver.C
|
||||
patchExprDriverFields.C
|
||||
patchExprDriverTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_patchExprDriver_H
|
||||
#define expressions_patchExprDriver_H
|
||||
|
||||
#include "patchExprFwd.H"
|
||||
#include "fvExprDriver.H"
|
||||
#include "Enum.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "genericRagelLemonDriver.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parseDriver Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parseDriver
|
||||
:
|
||||
public parsing::genericRagelLemonDriver,
|
||||
public expressions::fvExprDriver
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
static const fvPatch& getFvPatch
|
||||
(
|
||||
const fvMesh& fvm,
|
||||
const dictionary& dict
|
||||
);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- The referenced patch
|
||||
const fvPatch& patch_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
// No copy copy construct
|
||||
parseDriver(const parseDriver&) = delete;
|
||||
|
||||
// No copy assignment
|
||||
void operator=(const parseDriver&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ClassName("patchExpr::driver");
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct for specified patch
|
||||
explicit parseDriver(const fvPatch& p);
|
||||
|
||||
//- Construct for specified patch with given dictionary
|
||||
parseDriver(const fvPatch& p, const dictionary& dict);
|
||||
|
||||
//- Construct for specified patch with copy of driver context
|
||||
parseDriver(const fvPatch& p, const parseDriver& driver_);
|
||||
|
||||
//- Construct with patchName for the given mesh
|
||||
parseDriver(const word& patchName, const fvMesh& mesh);
|
||||
|
||||
//- Construct with "patch" (mandatory) and "region" (optional)
|
||||
//- specified in dictionary
|
||||
parseDriver(const dictionary& dict, const fvMesh& mesh);
|
||||
|
||||
//- Clone
|
||||
virtual autoPtr<expressions::fvExprDriver> clone() const
|
||||
{
|
||||
return autoPtr<expressions::fvExprDriver>
|
||||
(
|
||||
new parseDriver(this->patch_, *this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~parseDriver() = default;
|
||||
|
||||
|
||||
// Public Member Functions
|
||||
|
||||
//- The mesh we are attached to
|
||||
virtual const fvMesh& mesh() const
|
||||
{
|
||||
return patch_.boundaryMesh().mesh();
|
||||
}
|
||||
|
||||
//- The underlying field size for the expression
|
||||
virtual label size() const
|
||||
{
|
||||
return patch_.patch().size();
|
||||
}
|
||||
|
||||
//- The underlying point field size for the expression
|
||||
virtual label pointSize() const
|
||||
{
|
||||
return patch_.patch().nPoints();
|
||||
}
|
||||
|
||||
//- Field size associated with different geometric field types
|
||||
inline label size(const FieldAssociation geoType) const;
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
// Fields
|
||||
|
||||
//- Set result
|
||||
template<class Type>
|
||||
void setResult(Field<Type>* ptr, bool pointVal = false)
|
||||
{
|
||||
result().setResult<Type>(ptr, pointVal);
|
||||
}
|
||||
|
||||
|
||||
//- Retrieve variable as field if possible.
|
||||
// Test tmp for validity to determine success of the operation.
|
||||
template<class Type>
|
||||
tmp<Field<Type>> getVariableIfAvailable(const word& fldName) const;
|
||||
|
||||
//- Retrieve field (vol field)
|
||||
template<class Type>
|
||||
tmp<Field<Type>>
|
||||
getVolField(const word& fldName);
|
||||
|
||||
//- Retrieve field (surface field)
|
||||
template<class Type>
|
||||
tmp<Field<Type>>
|
||||
getSurfaceField(const word& fldName);
|
||||
|
||||
//- Retrieve field (point field)
|
||||
template<class Type>
|
||||
tmp<Field<Type>>
|
||||
getPointField(const word& fldName);
|
||||
|
||||
//- Return named field
|
||||
template<class Type>
|
||||
tmp<Field<Type>> getField(const word& fldName);
|
||||
|
||||
|
||||
// Field "shape" conversions
|
||||
|
||||
//- Interpolate face to point
|
||||
template<class Type>
|
||||
tmp<Field<Type>> faceToPoint(const Field<Type>& field) const;
|
||||
|
||||
//- Interpolate point to face values
|
||||
template<class Type>
|
||||
tmp<Field<Type>> pointToFace(const Field<Type>& field) const;
|
||||
|
||||
|
||||
// Custom Field Functions
|
||||
|
||||
//- The area-weighted average of a field
|
||||
template<class Type>
|
||||
Type areaAverage(const Field<Type>& fld) const
|
||||
{
|
||||
return weightedAverage(patch_.magSf(), fld);
|
||||
}
|
||||
|
||||
//- The area-weighted sum of a field
|
||||
template<class Type>
|
||||
Type areaSum(const Field<Type>& fld) const
|
||||
{
|
||||
return weightedSum(patch_.magSf(), fld);
|
||||
}
|
||||
|
||||
//- The face area magnitudes [magSf] - (swak = area)
|
||||
tmp<scalarField> field_faceArea() const;
|
||||
|
||||
//- The face centres - (swak = pos)
|
||||
tmp<vectorField> field_faceCentre() const;
|
||||
|
||||
//- The face areas with their vector direction [Sf] - (swak = face)
|
||||
tmp<vectorField> field_areaNormal() const;
|
||||
|
||||
//- The patch point locations - (swak = pts)
|
||||
tmp<vectorField> field_pointField() const;
|
||||
|
||||
//- A uniform random field
|
||||
tmp<scalarField> field_rand(label seed=0, bool gaussian=false) const;
|
||||
|
||||
//- A Gaussian random field
|
||||
tmp<scalarField> field_randGaussian(label seed=0) const
|
||||
{
|
||||
return field_rand(seed, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Template specializations
|
||||
|
||||
//- Retrieve field (surface field: bool)
|
||||
template<>
|
||||
tmp<Field<bool>> parseDriver::getSurfaceField<bool>(const word& fldName);
|
||||
|
||||
//- Retrieve field (point field: bool)
|
||||
template<>
|
||||
tmp<Field<bool>> parseDriver::getPointField<bool>(const word& fldName);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace patchExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "patchExprDriverI.H"
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "patchExprDriverTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
100
src/finiteVolume/expressions/patch/patchExprDriverFields.C
Normal file
100
src/finiteVolume/expressions/patch/patchExprDriverFields.C
Normal file
@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "patchExprDriver.H"
|
||||
#include "fvPatch.H"
|
||||
#include "error.H"
|
||||
|
||||
// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * //
|
||||
|
||||
template<>
|
||||
Foam::tmp<Foam::Field<bool>>
|
||||
Foam::expressions::patchExpr::parseDriver::getSurfaceField<bool>
|
||||
(
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
return getVariable<bool>(name, this->size());
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
Foam::tmp<Foam::Field<bool>>
|
||||
Foam::expressions::patchExpr::parseDriver::getPointField<bool>
|
||||
(
|
||||
const word& name
|
||||
)
|
||||
{
|
||||
return getVariable<bool>(name, this->pointSize());
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceArea() const
|
||||
{
|
||||
return patch_.magSf();
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::vectorField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_faceCentre() const
|
||||
{
|
||||
return patch_.Cf();
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::vectorField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_areaNormal() const
|
||||
{
|
||||
return patch_.Sf();
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::vectorField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_pointField() const
|
||||
{
|
||||
return patch_.patch().localPoints();
|
||||
}
|
||||
|
||||
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::expressions::patchExpr::parseDriver::field_rand
|
||||
(
|
||||
label seed,
|
||||
bool gaussian
|
||||
) const
|
||||
{
|
||||
auto tresult = tmp<scalarField>::New(this->size());
|
||||
fill_random(tresult.ref(), seed, gaussian);
|
||||
|
||||
return tresult;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
50
src/finiteVolume/expressions/patch/patchExprDriverI.H
Normal file
50
src/finiteVolume/expressions/patch/patchExprDriverI.H
Normal file
@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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::patchExpr::parseDriver::size
|
||||
(
|
||||
const FieldAssociation geoType
|
||||
) const
|
||||
{
|
||||
switch (geoType)
|
||||
{
|
||||
case FieldAssociation::POINT_DATA :
|
||||
return patch_.patch().nPoints();
|
||||
break;
|
||||
case FieldAssociation::SURFACE_DATA :
|
||||
return patch_.patch().size();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
228
src/finiteVolume/expressions/patch/patchExprDriverTemplates.C
Normal file
228
src/finiteVolume/expressions/patch/patchExprDriverTemplates.C
Normal file
@ -0,0 +1,228 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "primitivePatchInterpolation.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::getVariableIfAvailable
|
||||
(
|
||||
const word& name
|
||||
) const
|
||||
{
|
||||
bool isPointVal = false;
|
||||
bool isUniformVal = false;
|
||||
|
||||
tmp<Field<Type>> tfield;
|
||||
|
||||
if (hasVariable(name) && variable(name).isType<Type>())
|
||||
{
|
||||
const expressions::exprResult& var = variable(name);
|
||||
|
||||
isPointVal = var.isPointValue();
|
||||
isUniformVal = var.isUniform();
|
||||
|
||||
tfield = var.cref<Type>().clone();
|
||||
}
|
||||
else if (isGlobalVariable<Type>(name, false))
|
||||
{
|
||||
const expressions::exprResult& var = lookupGlobal(name);
|
||||
|
||||
isUniformVal = var.isUniform();
|
||||
|
||||
tfield = var.cref<Type>().clone();
|
||||
}
|
||||
|
||||
if (tfield.valid())
|
||||
{
|
||||
const label fldLen = tfield().size();
|
||||
const label len = (isPointVal ? this->pointSize() : this->size());
|
||||
|
||||
if (returnReduce((fldLen == len), andOp<bool>()))
|
||||
{
|
||||
return tfield;
|
||||
}
|
||||
|
||||
if (!isUniformVal)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Variable " << name
|
||||
<< " does not fit the size and is not a uniform value." << nl
|
||||
<< "Using average value" << endl;
|
||||
}
|
||||
|
||||
return tmp<Field<Type>>::New(this->size(), gAverage(tfield));
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::getVolField(const word& name)
|
||||
{
|
||||
return getField<Type>(name);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::getSurfaceField(const word& name)
|
||||
{
|
||||
return getField<Type>(name);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::getPointField(const word& name)
|
||||
{
|
||||
return getField<Type>(name);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::getField(const word& name)
|
||||
{
|
||||
tmp<Field<Type>> tfield = getVariableIfAvailable<Type>(name);
|
||||
|
||||
if (tfield.valid())
|
||||
{
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vfieldType;
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sfieldType;
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> pfieldType;
|
||||
|
||||
const objectRegistry& obr = this->mesh().thisDb();
|
||||
|
||||
const vfieldType* vfield = obr.findObject<vfieldType>(name);
|
||||
const sfieldType* sfield = obr.findObject<sfieldType>(name);
|
||||
const pfieldType* pfield = obr.findObject<pfieldType>(name);
|
||||
|
||||
// Local, temporary storage
|
||||
tmp<vfieldType> t_vfield;
|
||||
tmp<sfieldType> t_sfield;
|
||||
tmp<pfieldType> t_pfield;
|
||||
|
||||
if (searchFiles() && !vfield && !sfield && !pfield)
|
||||
{
|
||||
const word fldType = this->getTypeOfField(name);
|
||||
|
||||
if (fldType == vfieldType::typeName)
|
||||
{
|
||||
t_vfield = this->readAndRegister<vfieldType>(name, mesh());
|
||||
vfield = t_vfield.get();
|
||||
}
|
||||
else if (fldType == sfieldType::typeName)
|
||||
{
|
||||
t_sfield = this->readAndRegister<sfieldType>(name, mesh());
|
||||
sfield = t_sfield.get();
|
||||
}
|
||||
else if (fldType == pfieldType::typeName)
|
||||
{
|
||||
t_pfield = this->readAndRegister<pfieldType>
|
||||
(
|
||||
name,
|
||||
pointMesh::New(mesh())
|
||||
);
|
||||
pfield = t_pfield.get();
|
||||
}
|
||||
}
|
||||
|
||||
const label patchIndex = patch_.index();
|
||||
|
||||
if (vfield)
|
||||
{
|
||||
return tmp<Field<Type>>::New
|
||||
(
|
||||
vfield->boundaryField()[patchIndex]
|
||||
);
|
||||
}
|
||||
|
||||
if (sfield)
|
||||
{
|
||||
return tmp<Field<Type>>::New
|
||||
(
|
||||
sfield->boundaryField()[patchIndex]
|
||||
);
|
||||
}
|
||||
|
||||
if (pfield)
|
||||
{
|
||||
return pfield->boundaryField()[patchIndex].patchInternalField();
|
||||
}
|
||||
|
||||
|
||||
FatalErrorInFunction
|
||||
<< "No field '" << name << "' of type "
|
||||
<< pTraits<Type>::typeName << nl << nl
|
||||
<< vfieldType::typeName << " Fields: "
|
||||
<< flatOutput(obr.sortedNames<vfieldType>()) << nl
|
||||
<< sfieldType::typeName << " Fields: "
|
||||
<< flatOutput(obr.sortedNames<sfieldType>()) << nl
|
||||
<< pfieldType::typeName << " Fields: "
|
||||
<< flatOutput(obr.sortedNames<pfieldType>()) << nl
|
||||
<< exit(FatalError);
|
||||
|
||||
return tmp<Field<Type>>::New();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::faceToPoint
|
||||
(
|
||||
const Field<Type>& field
|
||||
) const
|
||||
{
|
||||
primitivePatchInterpolation interp(patch_.patch());
|
||||
|
||||
return interp.pointToFaceInterpolate(field);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::expressions::patchExpr::parseDriver::pointToFace
|
||||
(
|
||||
const Field<Type>& field
|
||||
) const
|
||||
{
|
||||
primitivePatchInterpolation interp(patch_.patch());
|
||||
|
||||
return interp.faceToPointInterpolate(field);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
84
src/finiteVolume/expressions/patch/patchExprFwd.H
Normal file
84
src/finiteVolume/expressions/patch/patchExprFwd.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::patchExpr
|
||||
|
||||
Description
|
||||
Namespace for patch expressions parsing and evaluation
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_patchExprFwd_H
|
||||
#define expressions_patchExprFwd_H
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Forward Declarations
|
||||
class parser;
|
||||
class scanner;
|
||||
class parseDriver;
|
||||
union scanToken;
|
||||
|
||||
//- Static debugging option
|
||||
extern int debug;
|
||||
|
||||
|
||||
//- The field association for patch expressions (mutually exclusive)
|
||||
enum FieldAssociation : unsigned char
|
||||
{
|
||||
NO_DATA = 0, //!< No data
|
||||
POINT_DATA = 1, //!< Point data
|
||||
SURFACE_DATA = 2 //!< Surface data
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace patchExpr
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Typedef for patchExpr parseDriver
|
||||
typedef patchExpr::parseDriver patchExprDriver;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
110
src/finiteVolume/expressions/patch/patchExprLemonParser.h
Normal file
110
src/finiteVolume/expressions/patch/patchExprLemonParser.h
Normal file
@ -0,0 +1,110 @@
|
||||
#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_SSCALAR_ID 30
|
||||
#define TOK_MIN 31
|
||||
#define TOK_COMMA 32
|
||||
#define TOK_MAX 33
|
||||
#define TOK_SUM 34
|
||||
#define TOK_AVERAGE 35
|
||||
#define TOK_EXP 36
|
||||
#define TOK_LOG 37
|
||||
#define TOK_LOG10 38
|
||||
#define TOK_SQR 39
|
||||
#define TOK_SQRT 40
|
||||
#define TOK_CBRT 41
|
||||
#define TOK_SIN 42
|
||||
#define TOK_COS 43
|
||||
#define TOK_TAN 44
|
||||
#define TOK_ASIN 45
|
||||
#define TOK_ACOS 46
|
||||
#define TOK_ATAN 47
|
||||
#define TOK_SINH 48
|
||||
#define TOK_COSH 49
|
||||
#define TOK_TANH 50
|
||||
#define TOK_POW 51
|
||||
#define TOK_ATAN2 52
|
||||
#define TOK_POS 53
|
||||
#define TOK_NEG 54
|
||||
#define TOK_POS0 55
|
||||
#define TOK_NEG0 56
|
||||
#define TOK_SIGN 57
|
||||
#define TOK_FLOOR 58
|
||||
#define TOK_CEIL 59
|
||||
#define TOK_ROUND 60
|
||||
#define TOK_HYPOT 61
|
||||
#define TOK_RAND 62
|
||||
#define TOK_VECTOR_ID 63
|
||||
#define TOK_SVECTOR_ID 64
|
||||
#define TOK_SPH_TENSOR_ID 65
|
||||
#define TOK_SSPH_TENSOR_ID 66
|
||||
#define TOK_SYM_TENSOR_ID 67
|
||||
#define TOK_SSYM_TENSOR_ID 68
|
||||
#define TOK_UNIT_TENSOR 69
|
||||
#define TOK_TENSOR_ID 70
|
||||
#define TOK_STENSOR_ID 71
|
||||
#define TOK_LTRUE 72
|
||||
#define TOK_LFALSE 73
|
||||
#define TOK_BOOL 74
|
||||
#define TOK_SBOOL_ID 75
|
||||
#define TOK_FACE_AREA 76
|
||||
#define TOK_FACE_EXPR 77
|
||||
#define TOK_WEIGHT_AVERAGE 78
|
||||
#define TOK_WEIGHT_SUM 79
|
||||
#define TOK_POINT_EXPR 80
|
||||
#define TOK_PSCALAR_ID 81
|
||||
#define TOK_PVECTOR_ID 82
|
||||
#define TOK_PSPH_TENSOR_ID 83
|
||||
#define TOK_PSYM_TENSOR_ID 84
|
||||
#define TOK_PTENSOR_ID 85
|
||||
#define TOK_PBOOL_ID 86
|
||||
#define TOK_POINTS 87
|
||||
#define TOK_MAG 88
|
||||
#define TOK_MAGSQR 89
|
||||
#define TOK_VECTOR 90
|
||||
#define TOK_TENSOR 91
|
||||
#define TOK_SYM_TENSOR 92
|
||||
#define TOK_SPH_TENSOR 93
|
||||
#define TOK_CMPT_X 94
|
||||
#define TOK_CMPT_Y 95
|
||||
#define TOK_CMPT_Z 96
|
||||
#define TOK_CMPT_XX 97
|
||||
#define TOK_CMPT_XY 98
|
||||
#define TOK_CMPT_XZ 99
|
||||
#define TOK_CMPT_YX 100
|
||||
#define TOK_CMPT_YY 101
|
||||
#define TOK_CMPT_YZ 102
|
||||
#define TOK_CMPT_ZX 103
|
||||
#define TOK_CMPT_ZY 104
|
||||
#define TOK_CMPT_ZZ 105
|
||||
#define TOK_CMPT_II 106
|
||||
#define TOK_TRANSPOSE 107
|
||||
#define TOK_DIAG 108
|
||||
#define TOK_POINT_TO_FACE 109
|
||||
#define TOK_FACE_TO_POINT 110
|
||||
565
src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4
Normal file
565
src/finiteVolume/expressions/patch/patchExprLemonParser.lyy-m4
Normal file
@ -0,0 +1,565 @@
|
||||
%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 patch expressions.
|
||||
|
||||
https://www.sqlite.org/src/doc/trunk/doc/lemon.html
|
||||
|
||||
See detailed notes in the field expression parser.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
} // %include
|
||||
|
||||
/*
|
||||
* include[patchExprLemonParserMacros.m4]
|
||||
*include(`patchExprLemonParserMacros.m4')dnl
|
||||
!done in a comment since many editors have issues matching m4 quotes!
|
||||
*/
|
||||
%include
|
||||
{
|
||||
#include "patchExprDriver.H"
|
||||
#include "patchExprParser.H"
|
||||
#include "patchExprScanner.H"
|
||||
#include "unitConversion.H"
|
||||
#include "error.H"
|
||||
#include "volFields.H"
|
||||
#include "exprOps.H"
|
||||
#include "exprDriverOps.H"
|
||||
#include "GeometricFieldOps.H"
|
||||
|
||||
// Enable ParseTrace
|
||||
#undef NDEBUG
|
||||
|
||||
compiler_pragmas()
|
||||
|
||||
// Local Functions
|
||||
|
||||
tmp_management()
|
||||
|
||||
} // %include
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
%namespace {}
|
||||
|
||||
// Use extra argument for the return value
|
||||
%extra_context { Foam::expressions::patchExpr::parseDriver* driver }
|
||||
%parse_failure { driver->reportFatal("Parse failure, giving up..."); }
|
||||
%syntax_error { driver->reportFatal("Syntax error"); }
|
||||
|
||||
%token_prefix TOK_
|
||||
|
||||
// Terminals
|
||||
%token_type {Foam::expressions::patchExpr::scanToken*}
|
||||
// Non-terminals
|
||||
%type ivalue { Foam::label }
|
||||
%type svalue { Foam::scalar }
|
||||
%type ident { Foam::word* }
|
||||
|
||||
// Face fields
|
||||
declare_field(lfield, Foam::boolField, bool, newField, getSurfaceField)
|
||||
declare_field(sfield, Foam::scalarField, Foam::scalar, newField, getField)
|
||||
declare_field(vfield, Foam::vectorField, Foam::vector, newField, getField)
|
||||
declare_field(hfield, Foam::sphericalTensorField, Foam::sphericalTensor, newField, getField)
|
||||
declare_field(yfield, Foam::symmTensorField, Foam::symmTensor, newField, getField)
|
||||
declare_field(tfield, Foam::tensorField, Foam::tensor, newField, getField)
|
||||
|
||||
// Point fields
|
||||
declare_field(plfield, Foam::boolField, bool, newPointField, getPointField)
|
||||
declare_field(psfield, Foam::scalarField, Foam::scalar, newPointField, getPointField)
|
||||
declare_field(pvfield, Foam::vectorField, Foam::vector, newPointField, getPointField)
|
||||
declare_field(phfield, Foam::sphericalTensorField, Foam::sphericalTensor, newPointField, getPointField)
|
||||
declare_field(pyfield, Foam::symmTensorField, Foam::symmTensor, newPointField, getPointField)
|
||||
declare_field(ptfield, Foam::tensorField, 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(); }
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * Face 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 (scalarField)
|
||||
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)
|
||||
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 works directly for scalarField
|
||||
rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
||||
|
||||
|
||||
// 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 (vectorField)
|
||||
dnl
|
||||
define([_target_], [vfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
|
||||
rule_get_field(_target_, VECTOR_ID)
|
||||
rule_get_field(_target_, SVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (sphericalTensorField)
|
||||
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)
|
||||
rule_get_field(_target_, SSPH_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_sphTensor_operations()
|
||||
rules_sphTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (symmTensorField)
|
||||
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)
|
||||
rule_get_field(_target_, SSYM_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_symTensor_operations()
|
||||
rules_symTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (tensorField)
|
||||
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)
|
||||
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 (boolField)
|
||||
dnl
|
||||
define([_target_], [lfield])dnl
|
||||
define([_value_type_], [bool])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a); }
|
||||
_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)
|
||||
|
||||
dnl/* Handling of named logic fields not really tested (disable in scanner) */
|
||||
rule_get_field(_target_, SBOOL_ID)
|
||||
rules_logical_operations(_logic_, _value_type_)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Surface-related productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_driver_surface_functions()
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * 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
|
||||
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point scalarField)
|
||||
dnl
|
||||
define([_target_], [psfield])dnl
|
||||
define([_value_type_], [Foam::scalar])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
rule_field_from_value(_target_, svalue, POINT_EXPR)
|
||||
rule_get_field(_target_, PSCALAR_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 works directly for scalarField
|
||||
rule_binary_func(_target_, _target_, _target_, HYPOT, Foam::hypot)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point vectorField)
|
||||
dnl
|
||||
define([_target_], [pvfield])dnl
|
||||
define([_value_type_], [Foam::vector])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
rule_get_field(_target_, PVECTOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_vector_operations()
|
||||
rules_vector_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point sphericalTensorField)
|
||||
dnl
|
||||
define([_target_], [phfield])dnl
|
||||
define([_value_type_], [Foam::sphericalTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
rule_get_field(_target_, PSPH_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_sphTensor_operations()
|
||||
rules_sphTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point symmTensorField)
|
||||
dnl
|
||||
define([_target_], [pyfield])dnl
|
||||
define([_value_type_], [Foam::symmTensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
rule_get_field(_target_, PSYM_TENSOR_ID)
|
||||
|
||||
rules_standard(_target_, _value_type_, _logic_)
|
||||
rules_inplace_gUnary(_target_)
|
||||
rules_symTensor_operations()
|
||||
rules_symTensor_functions()
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Productions (point tensorField)
|
||||
dnl
|
||||
define([_target_], [ptfield])dnl
|
||||
define([_value_type_], [Foam::tensor])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
|
||||
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 (point boolField)
|
||||
dnl
|
||||
define([_target_], [plfield])dnl
|
||||
define([_value_type_], [bool])dnl
|
||||
dnl
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
evaluate ::= _target_ (a) . { driver->setResult(a, true); /* Point */ }
|
||||
_logic_ (lhs) ::= POINT_EXPR LPAREN LTRUE RPAREN . { lhs = _new_plfield(_logic_true_); }
|
||||
_logic_ (lhs) ::= POINT_EXPR LPAREN LFALSE RPAREN . { lhs = _new_plfield(_logic_false_); }
|
||||
|
||||
rule_cast_logical(_target_, _target_)
|
||||
rule_cast_logical(_target_, _scalar_, Foam::scalar)
|
||||
|
||||
dnl/* Handling of named logic fields not really tested (disable in scanner) */
|
||||
rule_get_field(_target_, PBOOL_ID)
|
||||
rules_logical_operations(_logic_, _value_type_)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* General Point-related productions
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
rules_driver_point_functions()
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Face 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_pointToFace(sfield, psfield)
|
||||
rule_pointToFace(vfield, pvfield)
|
||||
rule_pointToFace(tfield, ptfield)
|
||||
rule_pointToFace(yfield, pyfield)
|
||||
rule_pointToFace(hfield, phfield)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
* Point field composition
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
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_faceToPoint(psfield, sfield)
|
||||
rule_faceToPoint(pvfield, vfield)
|
||||
rule_faceToPoint(ptfield, tfield)
|
||||
rule_faceToPoint(pyfield, yfield)
|
||||
rule_faceToPoint(phfield, hfield)
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
dnl/* Standard m4 quoting
|
||||
changequote([`],['])dnl
|
||||
dnl*/
|
||||
|
||||
%code
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::expressions::patchExpr::parser::stop()
|
||||
{
|
||||
if (lemon_)
|
||||
{
|
||||
ParseFree(lemon_, ::operator delete);
|
||||
#ifndef NDEBUG
|
||||
ParseTrace(nullptr, nullptr);
|
||||
#endif
|
||||
lemon_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::expressions::patchExpr::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::patchExpr::parser::parse
|
||||
(
|
||||
int tokenId,
|
||||
scanToken* tokenVal
|
||||
)
|
||||
{
|
||||
Parse(lemon_, tokenId, tokenVal);
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::expressions::patchExpr::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
|
||||
|
||||
// ************************************************************************* //
|
||||
109
src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4
Normal file
109
src/finiteVolume/expressions/patch/patchExprLemonParserMacros.m4
Normal file
@ -0,0 +1,109 @@
|
||||
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 patch 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
|
||||
|
||||
use_bool_logic()dnl # Use boolField directly
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Driver rules
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
define([rules_driver_surface_functions],
|
||||
[dnl
|
||||
rule_driver_nullary(_scalar_, FACE_AREA, field_faceArea)dnl
|
||||
rule_driver_nullary(_vector_, POS, field_faceCentre)dnl FACE_CENTRE
|
||||
rule_driver_nullary(_vector_, FACE_EXPR, field_areaNormal)dnl
|
||||
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_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_faceToPoint(out, in)
|
||||
# rule_pointToFace(out, in)
|
||||
#
|
||||
# Description
|
||||
# Production rules for driver faceToPoint, pointToFace,
|
||||
# methods
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
define([rule_faceToPoint],
|
||||
[rule_driver_unary($1, $2, FACE_TO_POINT, faceToPoint)])
|
||||
|
||||
define([rule_pointToFace],
|
||||
[rule_driver_unary($1, $2, POINT_TO_FACE, pointToFace)])
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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/patch/patchExprParser.H
Normal file
106
src/finiteVolume/expressions/patch/patchExprParser.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::patchExpr::parser
|
||||
|
||||
Description
|
||||
Lemon parser interface for patch expressions grammar
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_patchExprParser_H
|
||||
#define expressions_patchExprParser_H
|
||||
|
||||
#include "patchExprFwd.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class parser Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class parser
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Prompt for parser tracing
|
||||
static constexpr const char* const prompt_ = "patchExpr:";
|
||||
|
||||
//- The lemon parser (demand-driven)
|
||||
void* lemon_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Local object debugging
|
||||
int debug;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
parser() : lemon_(nullptr), debug(patchExpr::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 patchExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
162
src/finiteVolume/expressions/patch/patchExprScanner.H
Normal file
162
src/finiteVolume/expressions/patch/patchExprScanner.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::patchExpr::scanner
|
||||
|
||||
Description
|
||||
Ragel lexer/scanner interface for patch expressions.
|
||||
|
||||
Note
|
||||
Ragel code generated with the ./createCode script.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef expressions_patchExprScanner_H
|
||||
#define expressions_patchExprScanner_H
|
||||
|
||||
#include "patchExprFwd.H"
|
||||
#include "scalar.H"
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace expressions
|
||||
{
|
||||
namespace patchExpr
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
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(patchExpr::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 patchExpr
|
||||
} // End namespace expressions
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
3836
src/finiteVolume/expressions/patch/patchExprScanner.cc
Normal file
3836
src/finiteVolume/expressions/patch/patchExprScanner.cc
Normal file
File diff suppressed because it is too large
Load Diff
664
src/finiteVolume/expressions/patch/patchExprScanner.rl
Normal file
664
src/finiteVolume/expressions/patch/patchExprScanner.rl
Normal file
@ -0,0 +1,664 @@
|
||||
/*--------------------------------*- 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 for patch expressions
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "patchExprScanner.H"
|
||||
#include "patchExprDriver.H"
|
||||
#include "patchExprLemonParser.h"
|
||||
#include "patchExprParser.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 }
|
||||
|
||||
#undef 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
|
||||
#error 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", FACE_CENTRE),
|
||||
|
||||
TOKEN_PAIR("point", POINT_EXPR), // Point value
|
||||
TOKEN_PAIR("face", FACE_EXPR), // Face areaNormal
|
||||
|
||||
TOKEN_PAIR("faceToPoint", FACE_TO_POINT),
|
||||
TOKEN_PAIR("pointToFace", POINT_TO_FACE),
|
||||
|
||||
TOKEN_PAIR("area", FACE_AREA),
|
||||
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::patchExpr::parseDriver& driver_,
|
||||
const word& ident
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
// 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
|
||||
}
|
||||
#endif
|
||||
|
||||
// Face variables
|
||||
#ifdef TOK_SSCALAR_ID
|
||||
{
|
||||
#undef checkFieldToken
|
||||
#define checkFieldToken(TokType, Type) \
|
||||
if (driver_.isVariable<Type>(ident, false)) \
|
||||
{ \
|
||||
return TokType; \
|
||||
}
|
||||
|
||||
checkFieldToken(TOK_SSCALAR_ID, scalar);
|
||||
checkFieldToken(TOK_SVECTOR_ID, vector);
|
||||
checkFieldToken(TOK_SSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_SSPH_TENSOR_ID, sphericalTensor);
|
||||
checkFieldToken(TOK_STENSOR_ID, tensor);
|
||||
|
||||
// Not tested: checkFieldToken(TOK_SBOOL_ID, bool);
|
||||
}
|
||||
#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_PTENSOR_ID, tensor);
|
||||
checkFieldToken(TOK_PTENSOR_ID, tensor);
|
||||
checkFieldToken(TOK_PSYM_TENSOR_ID, symmTensor);
|
||||
checkFieldToken(TOK_PSPH_TENSOR_ID, sphericalTensor);
|
||||
|
||||
// Not tested: checkFieldToken(TOK_PBOOL_ID, bool);
|
||||
}
|
||||
#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 patchExpr;
|
||||
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::patchExpr::scanner::~scanner()
|
||||
{
|
||||
if (parser_)
|
||||
{
|
||||
delete parser_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::expressions::patchExpr::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::patchExpr::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::patchExpr::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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,55 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object T;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
internalField uniform 300;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type outletMappedUniformInletHeatAddition;
|
||||
outletPatch outlet1;
|
||||
Q 5; // Heat addition in W
|
||||
TMin 300;
|
||||
TMax 500;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,50 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volVectorField;
|
||||
object U;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 1 -1 0 0 0 0];
|
||||
|
||||
internalField uniform (0 0 0);
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type pressureInletOutletVelocity;
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue uniform (0 0 0);
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue uniform (0 0 0);
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,50 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object alphat;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [1 -1 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 1e-3;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type compressible::alphatWallFunction;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,53 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object epsilon;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -3 0 0 0 0];
|
||||
|
||||
internalField uniform 200;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type turbulentMixingLengthDissipationRateInlet;
|
||||
mixingLength 0.01; // 1cm - half channel height
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type epsilonWallFunction;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,51 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object k;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 1;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type turbulentIntensityKineticEnergyInlet;
|
||||
intensity 0.05; // 5% turbulent intensity
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type inletOutlet;
|
||||
inletValue $internalField;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type kqRWallFunction;
|
||||
value $internalField;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,44 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object nuTilda;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,50 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
location "0";
|
||||
object nut;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [0 2 -1 0 0 0 0];
|
||||
|
||||
internalField uniform 0;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type calculated;
|
||||
value uniform 0;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type nutkWallFunction;
|
||||
value uniform 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,71 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class volScalarField;
|
||||
object p;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dimensions [1 -1 -2 0 0 0 0];
|
||||
|
||||
internalField uniform 1e5;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
inlet
|
||||
{
|
||||
type uniformTotalPressure;
|
||||
gamma 1.2;
|
||||
|
||||
p0 table
|
||||
(
|
||||
(0 1e5)
|
||||
(1 1.4e5)
|
||||
);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type fixedValue;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type exprFixedValue;
|
||||
value $internalField;
|
||||
|
||||
valueExpr "0.5*(pInlet + pOutlet2)";
|
||||
variables
|
||||
(
|
||||
"pInlet{inlet} = weightAverage(p)"
|
||||
"pOutlet2{outlet2} = p"
|
||||
);
|
||||
|
||||
// debug true;
|
||||
// debugScanner true;
|
||||
// debugParser true;
|
||||
}
|
||||
|
||||
|
||||
outlet2
|
||||
{
|
||||
type fixedValue;
|
||||
value $internalField;
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
15/8/8 Simple T-junction. Inlet on left, one outlet at bottom, one at top.
|
||||
To test multiple outlets.
|
||||
|
||||
Enable debugScanner/debugParser for a verbose view of the parsing engine.
|
||||
@ -0,0 +1,22 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object fvOptions;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
viscousDissipation
|
||||
{
|
||||
type viscousDissipation;
|
||||
enabled true;
|
||||
}
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,48 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object thermophysicalProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
thermoType
|
||||
{
|
||||
type hePsiThermo;
|
||||
mixture pureMixture;
|
||||
transport sutherland;
|
||||
thermo hConst;
|
||||
equationOfState perfectGas;
|
||||
specie specie;
|
||||
energy sensibleEnthalpy;
|
||||
}
|
||||
|
||||
mixture
|
||||
{
|
||||
specie
|
||||
{
|
||||
molWeight 28.9;
|
||||
}
|
||||
thermodynamics
|
||||
{
|
||||
Cp 1007;
|
||||
Hf 0;
|
||||
}
|
||||
transport
|
||||
{
|
||||
As 1.4792e-06;
|
||||
Ts 116;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,30 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object turbulenceProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
simulationType RAS;
|
||||
|
||||
RAS
|
||||
{
|
||||
RASModel kEpsilon;
|
||||
|
||||
turbulence on;
|
||||
|
||||
printCoeffs on;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,127 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object blockMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// outlet1
|
||||
// +-+
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------+ |
|
||||
// |inlet |
|
||||
// +-----------+ |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// +-+
|
||||
// outlet2
|
||||
|
||||
scale 1;
|
||||
|
||||
vertices
|
||||
(
|
||||
(0.0 -0.01 0) //0
|
||||
(0.2 -0.01 0)
|
||||
(0.2 0.01 0) //2
|
||||
(0.0 0.01 0)
|
||||
|
||||
(0.22 -0.01 0) //4
|
||||
(0.22 0.01 0)
|
||||
|
||||
(0.2 -0.21 0) //6
|
||||
(0.22 -0.21 0)
|
||||
|
||||
(0.2 0.21 0) //8
|
||||
(0.22 0.21 0)
|
||||
|
||||
// Z
|
||||
(0.0 -0.01 0.02) //0
|
||||
(0.2 -0.01 0.02)
|
||||
(0.2 0.01 0.02) //2
|
||||
(0.0 0.01 0.02)
|
||||
|
||||
(0.22 -0.01 0.02) //4
|
||||
(0.22 0.01 0.02)
|
||||
|
||||
(0.2 -0.21 0.02) //6
|
||||
(0.22 -0.21 0.02)
|
||||
|
||||
(0.2 0.21 0.02) //8
|
||||
(0.22 0.21 0.02)
|
||||
|
||||
);
|
||||
|
||||
blocks
|
||||
(
|
||||
// inlet block
|
||||
hex (0 1 2 3 10 11 12 13) (50 5 5) simpleGrading (1 1 1)
|
||||
|
||||
// central block
|
||||
hex (1 4 5 2 11 14 15 12) (5 5 5) simpleGrading (1 1 1)
|
||||
|
||||
// bottom block
|
||||
hex (6 7 4 1 16 17 14 11) (5 50 5) simpleGrading (1 1 1)
|
||||
|
||||
// top block
|
||||
hex (2 5 9 8 12 15 19 18) (5 50 5) simpleGrading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
(
|
||||
);
|
||||
|
||||
boundary
|
||||
(
|
||||
inlet
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(0 10 13 3)
|
||||
);
|
||||
}
|
||||
|
||||
outlet1
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(6 7 17 16)
|
||||
);
|
||||
}
|
||||
|
||||
outlet2
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(8 18 19 9)
|
||||
);
|
||||
}
|
||||
|
||||
defaultFaces
|
||||
{
|
||||
type wall;
|
||||
faces ();
|
||||
}
|
||||
);
|
||||
|
||||
mergePatchPairs
|
||||
(
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,52 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object controlDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
application rhoPimpleFoam;
|
||||
|
||||
startFrom startTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
stopAt endTime;
|
||||
|
||||
endTime 1.0;
|
||||
|
||||
deltaT 0.001;
|
||||
|
||||
writeControl adjustable;
|
||||
|
||||
writeInterval 0.1;
|
||||
|
||||
purgeWrite 0;
|
||||
|
||||
writeFormat ascii;
|
||||
|
||||
writePrecision 6;
|
||||
|
||||
writeCompression off;
|
||||
|
||||
timeFormat general;
|
||||
|
||||
timePrecision 6;
|
||||
|
||||
runTimeModifiable true;
|
||||
|
||||
adjustTimeStep yes;
|
||||
|
||||
maxCo 3;
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,57 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSchemes;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
ddtSchemes
|
||||
{
|
||||
default Euler;
|
||||
}
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
default Gauss linear;
|
||||
}
|
||||
|
||||
divSchemes
|
||||
{
|
||||
default none;
|
||||
div(phi,U) Gauss limitedLinearV 1;
|
||||
div(phi,k) Gauss limitedLinear 1;
|
||||
div(phi,epsilon) Gauss limitedLinear 1;
|
||||
div(phi,h) Gauss limitedLinear 1;
|
||||
div(phi,R) Gauss limitedLinear 1;
|
||||
div(R) Gauss linear;
|
||||
div(phi,K) Gauss linear;
|
||||
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
|
||||
}
|
||||
|
||||
laplacianSchemes
|
||||
{
|
||||
default Gauss linear corrected;
|
||||
}
|
||||
|
||||
interpolationSchemes
|
||||
{
|
||||
default linear;
|
||||
}
|
||||
|
||||
snGradSchemes
|
||||
{
|
||||
default corrected;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,70 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "system";
|
||||
object fvSolution;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
solvers
|
||||
{
|
||||
p
|
||||
{
|
||||
solver GAMG;
|
||||
tolerance 1e-08;
|
||||
relTol 0.01;
|
||||
smoother GaussSeidel;
|
||||
}
|
||||
|
||||
pFinal
|
||||
{
|
||||
solver GAMG;
|
||||
tolerance 1e-08;
|
||||
relTol 0;
|
||||
smoother GaussSeidel;
|
||||
}
|
||||
|
||||
"(rho|U|k|epsilon|h)"
|
||||
{
|
||||
solver smoothSolver;
|
||||
smoother symGaussSeidel;
|
||||
tolerance 1e-07;
|
||||
relTol 0.05;
|
||||
}
|
||||
|
||||
"(rho|U|k|epsilon|h)Final"
|
||||
{
|
||||
$U;
|
||||
tolerance 1e-07;
|
||||
relTol 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIMPLE
|
||||
{
|
||||
momentumPredictor no;
|
||||
transonic no;
|
||||
nOuterCorrectors 1;
|
||||
nCorrectors 5;
|
||||
nNonOrthogonalCorrectors 0;
|
||||
}
|
||||
|
||||
relaxationFactors
|
||||
{
|
||||
equations
|
||||
{
|
||||
".*" 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,32 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object setExprBoundaryFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
pattern
|
||||
{
|
||||
field T;
|
||||
|
||||
expressions
|
||||
(
|
||||
{
|
||||
patch outlet2;
|
||||
target something;
|
||||
expression #{ (pos().x() < 1e-4 ? 60 : 120) #};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,53 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object setExprFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
expressions
|
||||
(
|
||||
T
|
||||
{
|
||||
field T;
|
||||
dimensions [0 0 0 1 0 0 0];
|
||||
|
||||
constants
|
||||
{
|
||||
centre (0.21 0 0.01);
|
||||
}
|
||||
|
||||
variables
|
||||
(
|
||||
"radius = 0.1"
|
||||
);
|
||||
|
||||
condition
|
||||
#{
|
||||
// Within the radius
|
||||
(mag(pos() - $[(vector)constants.centre]) < radius)
|
||||
|
||||
// but only +ve y!
|
||||
&& pos((pos() - $[(vector)constants.centre]).y()) > 0
|
||||
#};
|
||||
|
||||
expression
|
||||
#{
|
||||
300
|
||||
+ 200 * (1 - mag(pos() - $[(vector)constants.centre]) / radius)
|
||||
#};
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user