mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: code reduction, improvements for expressions
- literal lookups only for expression strings - code reduction for setExprFields. - changed keyword "condition" to "fieldMask" (option -field-mask). This is a better description of its purpose and avoids possible naming ambiguities with functionObject triggers (for example) if we apply similar syntax elsewhere. BUG: erroneous check in volumeExpr::parseDriver::isResultType() - not triggered since this method is not used anywhere (may remove in future version)
This commit is contained in:
committed by
Andrew Heather
parent
39f6618d3a
commit
510ffb3322
@ -231,18 +231,21 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
dictionary& patchDict = boundaryFieldDict.subDict(patchName);
|
dictionary& patchDict = boundaryFieldDict.subDict(patchName);
|
||||||
|
|
||||||
expressions::exprString expr
|
auto valueExpr_
|
||||||
(
|
(
|
||||||
currDict.get<string>("expression"),
|
expressions::exprString::getEntry
|
||||||
currDict,
|
(
|
||||||
true // strip comments
|
"expression",
|
||||||
|
currDict,
|
||||||
|
true // strip comments
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Set boundaryField/" << patchName << '/'
|
Info<< "Set boundaryField/" << patchName << '/'
|
||||||
<< targetName << nl
|
<< targetName << nl
|
||||||
<< "with expression" << nl
|
<< "with expression" << nl
|
||||||
<< "<<<<" << nl
|
<< "<<<<" << nl
|
||||||
<< expr.c_str() << nl
|
<< valueExpr_.c_str() << nl
|
||||||
<< ">>>>" << nl;
|
<< ">>>>" << nl;
|
||||||
|
|
||||||
expressions::patchExprDriver driver(currDict, mesh);
|
expressions::patchExprDriver driver(currDict, mesh);
|
||||||
@ -255,7 +258,7 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
driver.clearVariables();
|
driver.clearVariables();
|
||||||
driver.parse(expr);
|
driver.parse(valueExpr_);
|
||||||
|
|
||||||
// Serializing via Field::writeEntry etc
|
// Serializing via Field::writeEntry etc
|
||||||
OStringStream serialize;
|
OStringStream serialize;
|
||||||
|
|||||||
@ -64,7 +64,6 @@ word fieldGeoType(const FieldAssociation geoType)
|
|||||||
case FieldAssociation::VOLUME_DATA : return "cells"; break;
|
case FieldAssociation::VOLUME_DATA : return "cells"; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ struct setExprFieldsControl
|
|||||||
bool dryRun;
|
bool dryRun;
|
||||||
bool debugParsing;
|
bool debugParsing;
|
||||||
bool cacheVariables;
|
bool cacheVariables;
|
||||||
bool useDimensions;
|
bool hasDimensions;
|
||||||
bool createNew;
|
bool createNew;
|
||||||
bool keepPatches;
|
bool keepPatches;
|
||||||
bool correctPatches;
|
bool correctPatches;
|
||||||
@ -123,13 +122,12 @@ void doCorrectBoundaryConditions
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class GeoField, class Mesh>
|
template<class GeoField>
|
||||||
void setField
|
bool setField
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const Mesh& mesh,
|
const GeoField& evaluated,
|
||||||
const GeoField& result,
|
const boolField& fieldMask,
|
||||||
const scalarField& cond,
|
|
||||||
const dimensionSet& dims,
|
const dimensionSet& dims,
|
||||||
const wordList& valuePatches,
|
const wordList& valuePatches,
|
||||||
|
|
||||||
@ -139,6 +137,8 @@ void setField
|
|||||||
Info<< "setField(" << fieldName << "): "
|
Info<< "setField(" << fieldName << "): "
|
||||||
<< pTraits<GeoField>::typeName << endl;
|
<< pTraits<GeoField>::typeName << endl;
|
||||||
|
|
||||||
|
const auto& mesh = evaluated.mesh();
|
||||||
|
|
||||||
tmp<GeoField> toutput;
|
tmp<GeoField> toutput;
|
||||||
|
|
||||||
if (ctrl.createNew)
|
if (ctrl.createNew)
|
||||||
@ -171,55 +171,57 @@ void setField
|
|||||||
|
|
||||||
auto& output = toutput.ref();
|
auto& output = toutput.ref();
|
||||||
|
|
||||||
label setCells = 0;
|
label numValuesChanged = 0;
|
||||||
|
|
||||||
if (cond.empty())
|
// Internal field
|
||||||
|
if (fieldMask.empty())
|
||||||
{
|
{
|
||||||
// No condition - set all
|
// No field-mask - set entire internal field
|
||||||
output = result;
|
numValuesChanged = output.size();
|
||||||
|
|
||||||
setCells = output.size();
|
output.primitiveFieldRef() = evaluated;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
forAll(output, celli)
|
auto& internal = output.primitiveFieldRef();
|
||||||
|
|
||||||
|
forAll(internal, idx)
|
||||||
{
|
{
|
||||||
if (expressions::boolOp<scalar>()(cond[celli]))
|
if (fieldMask[idx])
|
||||||
{
|
{
|
||||||
output[celli] = result[celli];
|
internal[idx] = evaluated[idx];
|
||||||
++setCells;
|
++numValuesChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const label totalCells = returnReduce(output.size(), plusOp<label>());
|
// Boundary fields
|
||||||
reduce(setCells, plusOp<label>());
|
forAll(evaluated.boundaryField(), patchi)
|
||||||
|
|
||||||
forAll(result.boundaryField(), patchi)
|
|
||||||
{
|
{
|
||||||
auto& pf = output.boundaryFieldRef()[patchi];
|
auto& pf = output.boundaryFieldRef()[patchi];
|
||||||
|
|
||||||
if (pf.patch().coupled())
|
if (pf.patch().coupled())
|
||||||
{
|
{
|
||||||
pf == result.boundaryField()[patchi];
|
pf == evaluated.boundaryField()[patchi];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doCorrectBoundaryConditions(ctrl.correctBCs, output);
|
||||||
|
|
||||||
if (setCells == totalCells)
|
const label numTotal = returnReduce(output.size(), plusOp<label>());
|
||||||
|
reduce(numValuesChanged, plusOp<label>());
|
||||||
|
|
||||||
|
if (numValuesChanged == numTotal)
|
||||||
{
|
{
|
||||||
Info<< "Set all ";
|
Info<< "Set all ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info<< "Set " << setCells << " of ";
|
Info<< "Set " << numValuesChanged << " of ";
|
||||||
}
|
}
|
||||||
Info<< totalCells << " cells" << endl;
|
Info<< numTotal << " values" << endl;
|
||||||
|
|
||||||
|
if (ctrl.hasDimensions)
|
||||||
doCorrectBoundaryConditions(ctrl.correctBCs, output);
|
|
||||||
|
|
||||||
if (ctrl.useDimensions)
|
|
||||||
{
|
{
|
||||||
Info<< "Setting dimensions to " << dims << endl;
|
Info<< "Setting dimensions to " << dims << endl;
|
||||||
output.dimensions().reset(dims);
|
output.dimensions().reset(dims);
|
||||||
@ -234,6 +236,8 @@ void setField
|
|||||||
Info<< "Writing to " << output.name() << nl;
|
Info<< "Writing to " << output.name() << nl;
|
||||||
output.writeObject(ctrl.streamOpt, true);
|
output.writeObject(ctrl.streamOpt, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -241,8 +245,8 @@ void evaluate
|
|||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
const word& fieldName,
|
const word& fieldName,
|
||||||
const expressions::exprString& expression,
|
const expressions::exprString& valueExpr_,
|
||||||
const expressions::exprString& condition,
|
const expressions::exprString& maskExpr_,
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const dimensionSet& dims,
|
const dimensionSet& dims,
|
||||||
const wordList& valuePatches,
|
const wordList& valuePatches,
|
||||||
@ -273,10 +277,8 @@ void evaluate
|
|||||||
if (oldFieldType == IOobject::typeName)
|
if (oldFieldType == IOobject::typeName)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Field " << fieldName << " is "
|
<< "Field " << fieldName << "(type: " << oldFieldType
|
||||||
<< oldFieldType
|
<< ") seems to be missing. Use 'create'" << nl
|
||||||
<< ". Seems that it does not exist. Use 'create'"
|
|
||||||
<< nl
|
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,17 +286,21 @@ void evaluate
|
|||||||
<< " (type " << oldFieldType << ')';
|
<< " (type " << oldFieldType << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Info<< " time=" << mesh.thisDb().time().timeName() << nl
|
Info<< " time=" << mesh.thisDb().time().timeName() << nl
|
||||||
<< "Expression:" << nl
|
<< "Expression:" << nl
|
||||||
<< ">>>>" << nl
|
<< ">>>>" << nl
|
||||||
<< expression.c_str() << nl
|
<< valueExpr_.c_str() << nl
|
||||||
<< "<<<<" << nl;
|
<< "<<<<" << nl;
|
||||||
|
|
||||||
if (condition.size() && condition != "true")
|
bool evalFieldMask =
|
||||||
|
(maskExpr_.size() && maskExpr_ != "true" && maskExpr_ != "1");
|
||||||
|
|
||||||
|
if (evalFieldMask)
|
||||||
{
|
{
|
||||||
Info<< "Condition:" << nl
|
Info<< "field-mask:" << nl
|
||||||
<< ">>>>" << nl
|
<< ">>>>" << nl
|
||||||
<< condition.c_str() << nl
|
<< maskExpr_.c_str() << nl
|
||||||
<< "<<<<" << nl;
|
<< "<<<<" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,129 +324,95 @@ void evaluate
|
|||||||
|
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Parsing expression: " << expression << "\nand condition "
|
Info<< "Parsing expression: " << valueExpr_ << "\nand field-mask "
|
||||||
<< condition << nl << endl;
|
<< maskExpr_ << nl << endl;
|
||||||
driver.setDebugging(true, true);
|
driver.setDebugging(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
driver.clearVariables();
|
driver.clearVariables();
|
||||||
|
|
||||||
scalarField conditionField;
|
|
||||||
|
|
||||||
bool evaluatedCondition = false;
|
// Handle "field-mask" evaluation
|
||||||
|
|
||||||
FieldAssociation conditionDataType(FieldAssociation::VOLUME_DATA);
|
boolField fieldMask;
|
||||||
|
FieldAssociation maskFieldAssoc(FieldAssociation::NO_DATA);
|
||||||
|
|
||||||
if (condition.size() && condition != "true")
|
if (evalFieldMask)
|
||||||
{
|
{
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Parsing condition:" << condition << endl;
|
Info<< "Parsing field-mask:" << maskExpr_ << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.parse(condition);
|
driver.parse(maskExpr_);
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Parsed condition" << endl;
|
Info<< "Parsed field-mask" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any/all scalar fields. May help with diagnosis
|
if (driver.isLogical())
|
||||||
|
|
||||||
bool goodCond = true;
|
|
||||||
while (goodCond)
|
|
||||||
{
|
{
|
||||||
// volScalarField
|
auto& result = driver.result();
|
||||||
|
if (result.is_bool())
|
||||||
{
|
{
|
||||||
const auto* ptr = driver.isResultType<volScalarField>();
|
fieldMask = result.getResult<bool>();
|
||||||
if (ptr)
|
maskFieldAssoc = driver.fieldAssociation();
|
||||||
{
|
|
||||||
conditionField = ptr->internalField();
|
|
||||||
// VOLUME_DATA
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// surfaceScalarField
|
|
||||||
{
|
|
||||||
const auto* ptr = driver.isResultType<surfaceScalarField>();
|
|
||||||
if (ptr)
|
|
||||||
{
|
|
||||||
conditionField = ptr->internalField();
|
|
||||||
conditionDataType = FieldAssociation::FACE_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
|
// Slightly pedantic...
|
||||||
goodCond = goodCond && driver.isLogical();
|
driver.clearField();
|
||||||
|
driver.clearResult();
|
||||||
|
|
||||||
if (!goodCond)
|
evalFieldMask = (maskFieldAssoc != FieldAssociation::NO_DATA);
|
||||||
|
|
||||||
|
if (!evalFieldMask)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< " condition: " << condition
|
<< " mask: " << maskExpr_
|
||||||
<< " does not evaluate to a logical expression: "
|
<< " does not evaluate to a logical expression: "
|
||||||
<< driver.resultType() << nl
|
<< driver.resultType() << nl
|
||||||
#ifdef FULLDEBUG
|
#ifdef FULLDEBUG
|
||||||
<< "contents: " << conditionField
|
<< "contents: " << fieldMask
|
||||||
#endif
|
#endif
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Condition evaluates to "
|
Info<< "Field-mask evaluates to "
|
||||||
<< conditionField << nl;
|
<< fieldMask << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluatedCondition = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Parsing expression:" << expression << endl;
|
Info<< "Parsing expression:" << valueExpr_ << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.parse(expression);
|
driver.parse(valueExpr_);
|
||||||
|
|
||||||
if (ctrl.debugParsing)
|
if (ctrl.debugParsing)
|
||||||
{
|
{
|
||||||
Info<< "Parsed expression" << endl;
|
Info<< "Parsed expression" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evaluatedCondition)
|
if (evalFieldMask && maskFieldAssoc != driver.fieldAssociation())
|
||||||
{
|
{
|
||||||
if (conditionDataType != driver.fieldAssociation())
|
FatalErrorInFunction
|
||||||
{
|
<< "Mismatch between field-mask geometric type ("
|
||||||
FatalErrorInFunction
|
<< fieldGeoType(maskFieldAssoc) << ") and" << nl
|
||||||
<< "Mismatch between condition geometric type ("
|
<< "expression geometric type ("
|
||||||
<< fieldGeoType(conditionDataType) << ") and" << nl
|
<< fieldGeoType(driver.fieldAssociation()) << ')' << nl
|
||||||
<< "expression geometric type ("
|
<< nl
|
||||||
<< fieldGeoType(driver.fieldAssociation()) << ')' << nl
|
<< "expression: " << valueExpr_ << nl
|
||||||
<< nl
|
<< "field-mask: " << maskExpr_ << nl
|
||||||
<< "Expression: " << expression << nl
|
<< nl
|
||||||
<< "Condition: " << condition << nl
|
<< exit(FatalError);
|
||||||
<< nl
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctrl.createNew && driver.resultType() != oldFieldType)
|
if (!oldFieldType.empty() && driver.resultType() != oldFieldType)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Inconsistent types: " << fieldName << " is "
|
<< "Inconsistent types: " << fieldName << " is "
|
||||||
@ -452,81 +424,69 @@ void evaluate
|
|||||||
|
|
||||||
Info<< "Dispatch ... " << driver.resultType() << nl;
|
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; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
|
|
||||||
|
bool applied = false;
|
||||||
|
switch (driver.fieldAssociation())
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(GeoField) \
|
||||||
|
{ \
|
||||||
|
const auto* ptr = driver.isResultType<GeoField>(); \
|
||||||
|
if (ptr) \
|
||||||
|
{ \
|
||||||
|
applied = setField \
|
||||||
|
( \
|
||||||
|
fieldName, \
|
||||||
|
*ptr, \
|
||||||
|
fieldMask, \
|
||||||
|
dims, \
|
||||||
|
valuePatches, \
|
||||||
|
ctrl \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
setFieldDispatch(volScalarField);
|
case FieldAssociation::VOLUME_DATA:
|
||||||
setFieldDispatch(volVectorField);
|
{
|
||||||
setFieldDispatch(volTensorField);
|
doLocalCode(volScalarField);
|
||||||
setFieldDispatch(volSymmTensorField);
|
doLocalCode(volVectorField);
|
||||||
setFieldDispatch(volSphericalTensorField);
|
doLocalCode(volTensorField);
|
||||||
|
doLocalCode(volSymmTensorField);
|
||||||
|
doLocalCode(volSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FieldAssociation::FACE_DATA:
|
||||||
|
{
|
||||||
|
doLocalCode(surfaceScalarField);
|
||||||
|
doLocalCode(surfaceVectorField);
|
||||||
|
doLocalCode(surfaceTensorField);
|
||||||
|
doLocalCode(surfaceSymmTensorField);
|
||||||
|
doLocalCode(surfaceSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FieldAssociation::POINT_DATA:
|
||||||
|
{
|
||||||
|
doLocalCode(pointScalarField);
|
||||||
|
doLocalCode(pointVectorField);
|
||||||
|
doLocalCode(pointTensorField);
|
||||||
|
doLocalCode(pointSymmTensorField);
|
||||||
|
doLocalCode(pointSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
setFieldDispatch(surfaceScalarField);
|
default: break;
|
||||||
setFieldDispatch(surfaceVectorField);
|
#undef doLocalCode
|
||||||
setFieldDispatch(surfaceTensorField);
|
}
|
||||||
setFieldDispatch(surfaceSymmTensorField);
|
|
||||||
setFieldDispatch(surfaceSphericalTensorField);
|
|
||||||
|
|
||||||
#undef setFieldDispatch
|
if (!applied)
|
||||||
#define setFieldDispatch(FieldType) \
|
{
|
||||||
{ \
|
FatalErrorInFunction
|
||||||
/* FieldType */ \
|
<< "Expression evaluates to an unsupported type: "
|
||||||
const auto* ptr = driver.isResultType<FieldType>(); \
|
<< driver.resultType() << nl << nl
|
||||||
\
|
<< "Expression " << valueExpr_ << nl << endl
|
||||||
if (ptr) \
|
<< exit(FatalError);
|
||||||
{ \
|
}
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -584,12 +544,13 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
"condition",
|
"field-mask",
|
||||||
"logic",
|
"logic",
|
||||||
"The logical condition when to apply the expression"
|
"The field mask (logical condition) when to apply the expression"
|
||||||
" (command-line operation)",
|
" (command-line operation)",
|
||||||
true // Advanced option
|
true // Advanced option
|
||||||
);
|
);
|
||||||
|
argList::addOptionCompat("field-mask", {"condition", 2106});
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
"dimensions",
|
"dimensions",
|
||||||
@ -726,7 +687,7 @@ int main(int argc, char *argv[])
|
|||||||
wordHashSet badOptions
|
wordHashSet badOptions
|
||||||
({
|
({
|
||||||
"create", "keepPatches", "value-patches",
|
"create", "keepPatches", "value-patches",
|
||||||
"condition", "expression", "dimensions"
|
"field-mask", "expression", "dimensions"
|
||||||
});
|
});
|
||||||
badOptions.retain(args.options());
|
badOptions.retain(args.options());
|
||||||
|
|
||||||
@ -802,25 +763,24 @@ int main(int argc, char *argv[])
|
|||||||
ctrl.keepPatches = args.found("keepPatches");
|
ctrl.keepPatches = args.found("keepPatches");
|
||||||
ctrl.correctPatches = !args.found("noCorrectPatches");
|
ctrl.correctPatches = !args.found("noCorrectPatches");
|
||||||
ctrl.correctBCs = args.found("correctResultBoundaryFields");
|
ctrl.correctBCs = args.found("correctResultBoundaryFields");
|
||||||
ctrl.useDimensions = args.found("dimensions");
|
ctrl.hasDimensions = args.found("dimensions");
|
||||||
ctrl.streamOpt.format(runTime.writeFormat());
|
ctrl.streamOpt.format(runTime.writeFormat());
|
||||||
if (args.found("ascii"))
|
if (args.found("ascii"))
|
||||||
{
|
{
|
||||||
ctrl.streamOpt.format(IOstream::ASCII);
|
ctrl.streamOpt.format(IOstream::ASCII);
|
||||||
}
|
}
|
||||||
|
|
||||||
expressions::exprString
|
expressions::exprString valueExpr_
|
||||||
expression
|
(
|
||||||
(
|
args["expression"],
|
||||||
args["expression"],
|
dictionary::null
|
||||||
dictionary::null
|
);
|
||||||
);
|
|
||||||
|
|
||||||
expressions::exprString condition;
|
expressions::exprString maskExpr_;
|
||||||
args.readIfPresent("condition", condition);
|
args.readIfPresent("field-mask", maskExpr_);
|
||||||
|
|
||||||
dimensionSet dims;
|
dimensionSet dims;
|
||||||
if (ctrl.useDimensions)
|
if (ctrl.hasDimensions)
|
||||||
{
|
{
|
||||||
ITstream is(args.lookup("dimensions"));
|
ITstream is(args.lookup("dimensions"));
|
||||||
is >> dims;
|
is >> dims;
|
||||||
@ -830,8 +790,8 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
fieldName,
|
fieldName,
|
||||||
expression,
|
valueExpr_,
|
||||||
condition,
|
maskExpr_,
|
||||||
dictionary::null,
|
dictionary::null,
|
||||||
dims,
|
dims,
|
||||||
args.getList<word>("value-patches", false),
|
args.getList<word>("value-patches", false),
|
||||||
@ -899,22 +859,28 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const word fieldName(dict.get<word>("field"));
|
const word fieldName(dict.get<word>("field"));
|
||||||
|
|
||||||
expressions::exprString expression
|
auto valueExpr_
|
||||||
(
|
(
|
||||||
dict.get<string>("expression"),
|
expressions::exprString::getEntry
|
||||||
dict
|
(
|
||||||
|
"expression",
|
||||||
|
dict
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
expressions::exprString condition;
|
expressions::exprString maskExpr_;
|
||||||
|
|
||||||
if (dict.found("condition"))
|
|
||||||
{
|
{
|
||||||
condition =
|
const entry* eptr = dict.findCompat
|
||||||
expressions::exprString
|
(
|
||||||
(
|
"fieldMask", {{"condition", 2106}},
|
||||||
dict.get<string>("condition"),
|
keyType::LITERAL
|
||||||
dict
|
);
|
||||||
);
|
|
||||||
|
if (eptr)
|
||||||
|
{
|
||||||
|
maskExpr_.readEntry(eptr->keyword(), dict);
|
||||||
|
maskExpr_.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dimensionSet dims;
|
dimensionSet dims;
|
||||||
@ -928,7 +894,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
dimPtr->stream() >> dims;
|
dimPtr->stream() >> dims;
|
||||||
}
|
}
|
||||||
ctrl.useDimensions = bool(dimPtr);
|
ctrl.hasDimensions = bool(dimPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.verbose() && !timei)
|
if (args.verbose() && !timei)
|
||||||
@ -941,8 +907,8 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
fieldName,
|
fieldName,
|
||||||
expression,
|
valueExpr_,
|
||||||
condition,
|
maskExpr_,
|
||||||
dict,
|
dict,
|
||||||
dims,
|
dims,
|
||||||
dict.getOrDefault<wordList>("valuePatches", wordList()),
|
dict.getOrDefault<wordList>("valuePatches", wordList()),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
| ========= | |
|
| ========= | |
|
||||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
| \\ / O peration | Version: v2106 |
|
| \\ / O peration | Version: v2112 |
|
||||||
| \\ / A nd | Website: www.openfoam.com |
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -31,7 +31,7 @@ expressions
|
|||||||
"radius = 0.1"
|
"radius = 0.1"
|
||||||
);
|
);
|
||||||
|
|
||||||
condition
|
fieldMask
|
||||||
#{
|
#{
|
||||||
// Within the radius
|
// Within the radius
|
||||||
(mag(pos() - $[(vector)constants.centre]) < radius)
|
(mag(pos() - $[(vector)constants.centre]) < radius)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*--------------------------------*- C++ -*----------------------------------*\
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
| ========= | |
|
| ========= | |
|
||||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
| \\ / O peration | Version: v2106 |
|
| \\ / O peration | Version: v2112 |
|
||||||
| \\ / A nd | Website: www.openfoam.com |
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -34,7 +34,7 @@ expressions
|
|||||||
"radius = 0.1"
|
"radius = 0.1"
|
||||||
);
|
);
|
||||||
|
|
||||||
condition
|
fieldMask
|
||||||
#{
|
#{
|
||||||
// Within the radius
|
// Within the radius
|
||||||
(mag(pos() - $[(vector)constants.centre]) < radius)
|
(mag(pos() - $[(vector)constants.centre]) < radius)
|
||||||
|
|||||||
@ -47,9 +47,7 @@ Foam::Function1Types::Function1Expression<Type>::Function1Expression
|
|||||||
debug |= 1;
|
debug |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string expr;
|
valueExpr_.readEntry("expression", dict_);
|
||||||
dict_.readEntry("expression", expr);
|
|
||||||
valueExpr_ = expressions::exprString(std::move(expr), dict_);
|
|
||||||
|
|
||||||
// Basic sanity
|
// Basic sanity
|
||||||
if (valueExpr_.empty())
|
if (valueExpr_.empty())
|
||||||
|
|||||||
@ -314,13 +314,13 @@ public:
|
|||||||
|
|
||||||
// Public Member Functions
|
// Public Member Functions
|
||||||
|
|
||||||
//- The underlying field size for the expression
|
//- The natural field size for the expression
|
||||||
virtual label size() const
|
virtual label size() const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying point field size for the expression
|
//- The point field size for the expression
|
||||||
virtual label pointSize() const
|
virtual label pointSize() const
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@ -358,6 +358,7 @@ public:
|
|||||||
void clearResult();
|
void clearResult();
|
||||||
|
|
||||||
//- Return the expression result as a tmp field
|
//- Return the expression result as a tmp field
|
||||||
|
// This also clears the result and associated memory.
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> getResult(bool wantPointData=false);
|
tmp<Field<Type>> getResult(bool wantPointData=false);
|
||||||
|
|
||||||
@ -426,7 +427,7 @@ public:
|
|||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
|
|
||||||
//- Clear temporary variables and resets from expression strings
|
//- Clear temporary variables, reset from expression strings
|
||||||
virtual void clearVariables();
|
virtual void clearVariables();
|
||||||
|
|
||||||
//- Set special-purpose scalar reference argument.
|
//- Set special-purpose scalar reference argument.
|
||||||
@ -555,7 +556,8 @@ public:
|
|||||||
size_t len = std::string::npos
|
size_t len = std::string::npos
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
//- Evaluate the expression and return the field
|
//- Evaluate the expression and return the field.
|
||||||
|
// This also clears the result and associated memory.
|
||||||
template<class Type>
|
template<class Type>
|
||||||
inline tmp<Field<Type>>
|
inline tmp<Field<Type>>
|
||||||
evaluate
|
evaluate
|
||||||
@ -564,7 +566,8 @@ public:
|
|||||||
bool wantPointData = false
|
bool wantPointData = false
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Evaluate the expression and return a single value
|
//- Evaluate the expression and return a single value.
|
||||||
|
// Does not clear the result.
|
||||||
template<class Type>
|
template<class Type>
|
||||||
inline Type evaluateUniform
|
inline Type evaluateUniform
|
||||||
(
|
(
|
||||||
|
|||||||
@ -415,10 +415,10 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
//- Change reset behaviour
|
//- Change reset behaviour
|
||||||
void noReset() { noReset_ = true; }
|
void noReset() noexcept { noReset_ = true; }
|
||||||
|
|
||||||
//- Change reset behaviour
|
//- Change reset behaviour
|
||||||
void allowReset() { noReset_ = false; }
|
void allowReset() noexcept { noReset_ = false; }
|
||||||
|
|
||||||
//- Test if field corresponds to a single-value and thus uniform.
|
//- Test if field corresponds to a single-value and thus uniform.
|
||||||
// Uses field min/max to establish uniformity.
|
// Uses field min/max to establish uniformity.
|
||||||
@ -468,11 +468,6 @@ public:
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
inline tmp<Field<Type>> getResult(bool cacheCopy=false);
|
inline tmp<Field<Type>> getResult(bool cacheCopy=false);
|
||||||
|
|
||||||
//- Get object result (Caution - potentially fragile)
|
|
||||||
//- optionally keeping a copy in cache
|
|
||||||
template<class Type>
|
|
||||||
inline tmp<Type> getObjectResult(bool cacheCopy=false);
|
|
||||||
|
|
||||||
//- Construct a uniform field from the current results
|
//- Construct a uniform field from the current results
|
||||||
// Uses the field average. Optionally warning if the min/max
|
// Uses the field average. Optionally warning if the min/max
|
||||||
// deviation is larger than SMALL.
|
// deviation is larger than SMALL.
|
||||||
|
|||||||
@ -48,20 +48,30 @@ void Foam::expressions::exprString::inplaceExpand
|
|||||||
|
|
||||||
|
|
||||||
Foam::expressions::exprString
|
Foam::expressions::exprString
|
||||||
Foam::expressions::exprString::getExpression
|
Foam::expressions::exprString::getEntry
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& key,
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const bool stripComments
|
const bool stripComments
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
string orig(dict.get<string>(name));
|
exprString expr;
|
||||||
|
expr.readEntry(key, dict, true, stripComments); // mandatory
|
||||||
|
|
||||||
// No validation
|
return expr;
|
||||||
expressions::exprString expr;
|
}
|
||||||
expr.assign(std::move(orig));
|
|
||||||
|
|
||||||
inplaceExpand(expr, dict, stripComments);
|
|
||||||
|
Foam::expressions::exprString
|
||||||
|
Foam::expressions::exprString::getOptional
|
||||||
|
(
|
||||||
|
const word& key,
|
||||||
|
const dictionary& dict,
|
||||||
|
const bool stripComments
|
||||||
|
)
|
||||||
|
{
|
||||||
|
exprString expr;
|
||||||
|
expr.readEntry(key, dict, false, stripComments); // optional
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
@ -69,8 +79,7 @@ Foam::expressions::exprString::getExpression
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::expressions::exprString&
|
void Foam::expressions::exprString::expand
|
||||||
Foam::expressions::exprString::expand
|
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const bool stripComments
|
const bool stripComments
|
||||||
@ -81,8 +90,35 @@ Foam::expressions::exprString::expand
|
|||||||
#ifdef FULLDEBUG
|
#ifdef FULLDEBUG
|
||||||
(void)valid();
|
(void)valid();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
|
||||||
|
void Foam::expressions::exprString::trim()
|
||||||
|
{
|
||||||
|
stringOps::inplaceTrim(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::expressions::exprString::readEntry
|
||||||
|
(
|
||||||
|
const word& keyword,
|
||||||
|
const dictionary& dict,
|
||||||
|
bool mandatory,
|
||||||
|
const bool stripComments
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const bool ok = dict.readEntry(keyword, *this, keyType::LITERAL, mandatory);
|
||||||
|
|
||||||
|
if (ok && !empty())
|
||||||
|
{
|
||||||
|
this->expand(dict, stripComments); // strip comments
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -135,13 +135,22 @@ public:
|
|||||||
|
|
||||||
//- Get and expand expression with dictionary entries,
|
//- Get and expand expression with dictionary entries,
|
||||||
//- optionally strip C/C++ comments from the input.
|
//- optionally strip C/C++ comments from the input.
|
||||||
//
|
|
||||||
// Expansion behaviour as per inplaceExpand
|
// Expansion behaviour as per inplaceExpand
|
||||||
static exprString getExpression
|
static exprString getEntry
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& keyword, //!< Lookup key. Uses LITERAL (not REGEX)
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const bool stripComments = false
|
const bool stripComments = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Get and expand expression with dictionary entries,
|
||||||
|
//- optionally strip C/C++ comments from the input.
|
||||||
|
// Expansion behaviour as per inplaceExpand
|
||||||
|
static exprString getOptional
|
||||||
|
(
|
||||||
|
const word& keyword, //!< Lookup key. Uses LITERAL (not REGEX)
|
||||||
|
const dictionary& dict,
|
||||||
|
const bool stripComments = true
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Copy convert string to exprString.
|
//- Copy convert string to exprString.
|
||||||
@ -155,17 +164,26 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Inplace expansion with dictionary variables,
|
|
||||||
//- and strip C/C++ comments from the input
|
|
||||||
exprString& expand
|
|
||||||
(
|
|
||||||
const dictionary& dict,
|
|
||||||
const bool stripComments = true
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check for unexpanded '$' entries. Fatal if any exist.
|
//- Check for unexpanded '$' entries. Fatal if any exist.
|
||||||
inline bool valid() const;
|
inline bool valid() const;
|
||||||
|
|
||||||
|
//- Inplace expansion with dictionary variables,
|
||||||
|
//- and strip C/C++ comments from the input
|
||||||
|
void expand(const dictionary& dict, const bool stripComments = true);
|
||||||
|
|
||||||
|
//- Inplace trim leading and trailing whitespace
|
||||||
|
void trim();
|
||||||
|
|
||||||
|
//- Read/expand entry with dictionary variables,
|
||||||
|
//- and strip C/C++ comments from the input
|
||||||
|
bool readEntry
|
||||||
|
(
|
||||||
|
const word& keyword, //!< Lookup key. Uses LITERAL (not REGEX)
|
||||||
|
const dictionary& dict,
|
||||||
|
bool mandatory = true,
|
||||||
|
const bool stripComments = true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
|
|
||||||
|
|||||||
@ -118,13 +118,13 @@ public:
|
|||||||
|
|
||||||
// Public Member Functions
|
// Public Member Functions
|
||||||
|
|
||||||
//- The underlying field size for the expression
|
//- The natural field size for the expression
|
||||||
virtual label size() const
|
virtual label size() const
|
||||||
{
|
{
|
||||||
return size_;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying point field size for the expression
|
//- The point field size for the expression
|
||||||
virtual label pointSize() const
|
virtual label pointSize() const
|
||||||
{
|
{
|
||||||
return size_;
|
return size_;
|
||||||
|
|||||||
@ -50,9 +50,7 @@ Foam::PatchFunction1Types::PatchExprField<Type>::PatchExprField
|
|||||||
debug |= 1;
|
debug |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
string expr;
|
valueExpr_.readEntry("expression", dict_);
|
||||||
dict_.readEntry("expression", expr);
|
|
||||||
valueExpr_ = expressions::exprString(std::move(expr), dict_);
|
|
||||||
|
|
||||||
// Basic sanity
|
// Basic sanity
|
||||||
if (valueExpr_.empty())
|
if (valueExpr_.empty())
|
||||||
|
|||||||
@ -410,10 +410,10 @@ public:
|
|||||||
|
|
||||||
// Public Member Functions
|
// Public Member Functions
|
||||||
|
|
||||||
//- The underlying field size for the expression
|
//- The natural field size for the expression
|
||||||
virtual label size() const = 0;
|
virtual label size() const = 0;
|
||||||
|
|
||||||
//- The underlying point field size for the expression
|
//- The point field size for the expression
|
||||||
virtual label pointSize() const = 0;
|
virtual label pointSize() const = 0;
|
||||||
|
|
||||||
|
|
||||||
@ -425,7 +425,7 @@ public:
|
|||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
|
|
||||||
//- Clear temporary variables and resets from expression strings
|
//- Clear temporary variables, reset from expression strings
|
||||||
virtual void clearVariables();
|
virtual void clearVariables();
|
||||||
|
|
||||||
//- True if named variable exists
|
//- True if named variable exists
|
||||||
|
|||||||
@ -57,18 +57,21 @@ void Foam::expressions::patchExprFieldBase::readExpressions
|
|||||||
if (expectedTypes::VALUE_TYPE == expectedType)
|
if (expectedTypes::VALUE_TYPE == expectedType)
|
||||||
{
|
{
|
||||||
// Mandatory
|
// Mandatory
|
||||||
evalValue = dict.readEntry("valueExpr", exprValue);
|
evalValue = dict.readEntry("valueExpr", exprValue, keyType::LITERAL);
|
||||||
}
|
}
|
||||||
else if (expectedTypes::GRADIENT_TYPE == expectedType)
|
else if (expectedTypes::GRADIENT_TYPE == expectedType)
|
||||||
{
|
{
|
||||||
// Mandatory
|
// Mandatory
|
||||||
evalGrad = dict.readEntry("gradientExpr", exprGrad);
|
evalGrad = dict.readEntry("gradientExpr", exprGrad, keyType::LITERAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// MIXED_TYPE
|
// MIXED_TYPE
|
||||||
evalValue = dict.readIfPresent("valueExpr", exprValue);
|
evalValue =
|
||||||
evalGrad = dict.readIfPresent("gradientExpr", exprGrad);
|
dict.readIfPresent("valueExpr", exprValue, keyType::LITERAL);
|
||||||
|
|
||||||
|
evalGrad =
|
||||||
|
dict.readIfPresent("gradientExpr", exprGrad, keyType::LITERAL);
|
||||||
|
|
||||||
if (!evalValue && !evalGrad)
|
if (!evalValue && !evalGrad)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -179,13 +179,13 @@ public:
|
|||||||
return patch_.boundaryMesh().mesh();
|
return patch_.boundaryMesh().mesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying field size for the expression
|
//- The natural field size for the expression
|
||||||
virtual label size() const
|
virtual label size() const
|
||||||
{
|
{
|
||||||
return patch_.patch().size();
|
return patch_.patch().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying point field size for the expression
|
//- The point field size for the expression
|
||||||
virtual label pointSize() const
|
virtual label pointSize() const
|
||||||
{
|
{
|
||||||
return patch_.patch().nPoints();
|
return patch_.patch().nPoints();
|
||||||
|
|||||||
@ -94,8 +94,9 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
|
|||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
resultType_(),
|
resultType_(),
|
||||||
isLogical_(false),
|
isLogical_(false),
|
||||||
|
hasDimensions_(false),
|
||||||
fieldGeoType_(NO_DATA),
|
fieldGeoType_(NO_DATA),
|
||||||
resultDimension_()
|
resultDimensions_()
|
||||||
{
|
{
|
||||||
resetTimeReference(nullptr);
|
resetTimeReference(nullptr);
|
||||||
resetDb(mesh_.thisDb());
|
resetDb(mesh_.thisDb());
|
||||||
@ -105,17 +106,18 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
|
|||||||
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
Foam::expressions::volumeExpr::parseDriver::parseDriver
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
const parseDriver& driver,
|
const parseDriver& rhs,
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
parsing::genericRagelLemonDriver(),
|
parsing::genericRagelLemonDriver(),
|
||||||
expressions::fvExprDriver(driver, dict),
|
expressions::fvExprDriver(rhs, dict),
|
||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
resultType_(),
|
resultType_(),
|
||||||
isLogical_(false),
|
isLogical_(false),
|
||||||
|
hasDimensions_(false),
|
||||||
fieldGeoType_(NO_DATA),
|
fieldGeoType_(NO_DATA),
|
||||||
resultDimension_()
|
resultDimensions_()
|
||||||
{
|
{
|
||||||
resetTimeReference(nullptr);
|
resetTimeReference(nullptr);
|
||||||
resetDb(mesh_.thisDb());
|
resetDb(mesh_.thisDb());
|
||||||
@ -146,7 +148,7 @@ Foam::expressions::volumeExpr::parseDriver::parseDriver
|
|||||||
resultType_(),
|
resultType_(),
|
||||||
isLogical_(false),
|
isLogical_(false),
|
||||||
fieldGeoType_(NO_DATA),
|
fieldGeoType_(NO_DATA),
|
||||||
resultDimension_()
|
resultDimensions_()
|
||||||
{
|
{
|
||||||
resetTimeReference(nullptr);
|
resetTimeReference(nullptr);
|
||||||
resetDb(mesh_.thisDb());
|
resetDb(mesh_.thisDb());
|
||||||
@ -161,7 +163,15 @@ bool Foam::expressions::volumeExpr::parseDriver::readDict
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
expressions::fvExprDriver::readDict(dict);
|
expressions::fvExprDriver::readDict(dict);
|
||||||
dict.readIfPresent("dimensions", resultDimension_);
|
|
||||||
|
resultDimensions_.clear(); // Avoid stickiness
|
||||||
|
|
||||||
|
hasDimensions_ = resultDimensions_.readEntry
|
||||||
|
(
|
||||||
|
"dimensions",
|
||||||
|
dict,
|
||||||
|
false // mandatory=false
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -184,4 +194,90 @@ unsigned Foam::expressions::volumeExpr::parseDriver::parse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::expressions::volumeExpr::parseDriver::clearField()
|
||||||
|
{
|
||||||
|
resultField_.reset(nullptr);
|
||||||
|
|
||||||
|
// Characteristics
|
||||||
|
resultType_.clear();
|
||||||
|
isLogical_ = false;
|
||||||
|
fieldGeoType_ = NO_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::regIOobject>
|
||||||
|
Foam::expressions::volumeExpr::parseDriver::dupZeroField() const
|
||||||
|
{
|
||||||
|
const auto* regIOobjectPtr = resultField_.get();
|
||||||
|
|
||||||
|
if (!regIOobjectPtr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
autoPtr<regIOobject> zField;
|
||||||
|
|
||||||
|
switch (fieldGeoType_)
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(GeoField) \
|
||||||
|
{ \
|
||||||
|
const auto* ptr = dynamic_cast<const GeoField*>(regIOobjectPtr); \
|
||||||
|
typedef typename GeoField::value_type Type; \
|
||||||
|
\
|
||||||
|
if (ptr) \
|
||||||
|
{ \
|
||||||
|
zField.reset \
|
||||||
|
( \
|
||||||
|
GeoField::New \
|
||||||
|
( \
|
||||||
|
word(pTraits<Type>::typeName) + word("(zero)"), \
|
||||||
|
(*ptr).mesh(), \
|
||||||
|
dimensioned<Type>(Zero) \
|
||||||
|
).ptr() \
|
||||||
|
); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
case FieldAssociation::VOLUME_DATA:
|
||||||
|
{
|
||||||
|
doLocalCode(volScalarField);
|
||||||
|
doLocalCode(volVectorField);
|
||||||
|
doLocalCode(volTensorField);
|
||||||
|
doLocalCode(volSymmTensorField);
|
||||||
|
doLocalCode(volSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FieldAssociation::FACE_DATA:
|
||||||
|
{
|
||||||
|
doLocalCode(surfaceScalarField);
|
||||||
|
doLocalCode(surfaceVectorField);
|
||||||
|
doLocalCode(surfaceTensorField);
|
||||||
|
doLocalCode(surfaceSymmTensorField);
|
||||||
|
doLocalCode(surfaceSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FieldAssociation::POINT_DATA:
|
||||||
|
{
|
||||||
|
doLocalCode(pointScalarField);
|
||||||
|
doLocalCode(pointVectorField);
|
||||||
|
doLocalCode(pointTensorField);
|
||||||
|
doLocalCode(pointSymmTensorField);
|
||||||
|
doLocalCode(pointSphericalTensorField);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!zField)
|
||||||
|
// {
|
||||||
|
// // Report
|
||||||
|
// }
|
||||||
|
|
||||||
|
return zField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -126,11 +126,14 @@ protected:
|
|||||||
//- A logical (bool-like) field (but actually a scalar)
|
//- A logical (bool-like) field (but actually a scalar)
|
||||||
bool isLogical_;
|
bool isLogical_;
|
||||||
|
|
||||||
|
//- Requested use of dimensions
|
||||||
|
bool hasDimensions_;
|
||||||
|
|
||||||
//- A volume/surface/point field
|
//- A volume/surface/point field
|
||||||
expressions::FieldAssociation fieldGeoType_;
|
expressions::FieldAssociation fieldGeoType_;
|
||||||
|
|
||||||
//- The result dimensions
|
//- The result dimensions
|
||||||
dimensionSet resultDimension_;
|
dimensionSet resultDimensions_;
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
@ -217,13 +220,13 @@ public:
|
|||||||
return mesh_;
|
return mesh_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying field size for the expression
|
//- The natural field size for the expression
|
||||||
virtual label size() const
|
virtual label size() const
|
||||||
{
|
{
|
||||||
return mesh_.nCells();
|
return mesh_.nCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- The underlying point field size for the expression
|
//- The point field size for the expression
|
||||||
virtual label pointSize() const
|
virtual label pointSize() const
|
||||||
{
|
{
|
||||||
return mesh_.nPoints();
|
return mesh_.nPoints();
|
||||||
@ -232,6 +235,16 @@ public:
|
|||||||
//- Field size associated with different geometric field types
|
//- Field size associated with different geometric field types
|
||||||
inline label size(const FieldAssociation geoType) const;
|
inline label size(const FieldAssociation geoType) const;
|
||||||
|
|
||||||
|
//- Apply dimensions() to geometric fields
|
||||||
|
inline bool hasDimensions() const noexcept;
|
||||||
|
|
||||||
|
//- The preferred result dimensions (if any)
|
||||||
|
inline const dimensionSet& dimensions() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
//- Clear out local copies of the field
|
||||||
|
void clearField();
|
||||||
|
|
||||||
|
|
||||||
// Reading
|
// Reading
|
||||||
|
|
||||||
@ -304,6 +317,9 @@ public:
|
|||||||
template<class GeoField>
|
template<class GeoField>
|
||||||
const GeoField* isResultType(bool logical, bool dieOnNull=false) const;
|
const GeoField* isResultType(bool logical, bool dieOnNull=false) const;
|
||||||
|
|
||||||
|
//- A zero-initialized field with the same type as the result field.
|
||||||
|
autoPtr<regIOobject> dupZeroField() const;
|
||||||
|
|
||||||
|
|
||||||
// Set Fields
|
// Set Fields
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,20 @@ inline Foam::label Foam::expressions::volumeExpr::parseDriver::size
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::expressions::volumeExpr::parseDriver::hasDimensions()
|
||||||
|
const noexcept
|
||||||
|
{
|
||||||
|
return hasDimensions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::dimensionSet&
|
||||||
|
Foam::expressions::volumeExpr::parseDriver::dimensions() const noexcept
|
||||||
|
{
|
||||||
|
return resultDimensions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::tmp<Foam::volScalarField>
|
inline Foam::tmp<Foam::volScalarField>
|
||||||
Foam::expressions::volumeExpr::parseDriver::parseDriver::field_cellSet
|
Foam::expressions::volumeExpr::parseDriver::parseDriver::field_cellSet
|
||||||
(
|
(
|
||||||
|
|||||||
@ -68,17 +68,17 @@ void Foam::expressions::volumeExpr::parseDriver::setResult
|
|||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||||
|
|
||||||
resultField_.clear();
|
resultField_.reset(nullptr);
|
||||||
|
|
||||||
// Characteristics
|
// Characteristics
|
||||||
resultType_ = pTraits<fieldType>::typeName;
|
resultType_ = pTraits<fieldType>::typeName;
|
||||||
isLogical_ = logical;
|
isLogical_ = logical;
|
||||||
fieldGeoType_ = VOLUME_DATA;
|
fieldGeoType_ = VOLUME_DATA;
|
||||||
|
|
||||||
// Always strip out dimensions?
|
// Assign dimensions
|
||||||
if (!resultDimension_.dimensionless())
|
if (hasDimensions_ && !logical)
|
||||||
{
|
{
|
||||||
ptr->dimensions().reset(resultDimension_);
|
ptr->dimensions().reset(resultDimensions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
setInternalFieldResult(ptr->primitiveField());
|
setInternalFieldResult(ptr->primitiveField());
|
||||||
@ -97,17 +97,17 @@ void Foam::expressions::volumeExpr::parseDriver::setResult
|
|||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> fieldType;
|
||||||
|
|
||||||
resultField_.clear();
|
resultField_.reset(nullptr);
|
||||||
|
|
||||||
// Characteristics
|
// Characteristics
|
||||||
resultType_ = pTraits<fieldType>::typeName;
|
resultType_ = pTraits<fieldType>::typeName;
|
||||||
isLogical_ = logical;
|
isLogical_ = logical;
|
||||||
fieldGeoType_ = FACE_DATA;
|
fieldGeoType_ = FACE_DATA;
|
||||||
|
|
||||||
// Always strip out dimensions?
|
// Assign dimensions
|
||||||
if (!resultDimension_.dimensionless())
|
if (hasDimensions_ && !logical)
|
||||||
{
|
{
|
||||||
ptr->dimensions().reset(resultDimension_);
|
ptr->dimensions().reset(resultDimensions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
setInternalFieldResult(ptr->primitiveField());
|
setInternalFieldResult(ptr->primitiveField());
|
||||||
@ -126,17 +126,17 @@ void Foam::expressions::volumeExpr::parseDriver::setResult
|
|||||||
{
|
{
|
||||||
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
|
typedef GeometricField<Type, pointPatchField, pointMesh> fieldType;
|
||||||
|
|
||||||
resultField_.clear();
|
resultField_.reset(nullptr);
|
||||||
|
|
||||||
// Characteristics
|
// Characteristics
|
||||||
resultType_ = pTraits<fieldType>::typeName;
|
resultType_ = pTraits<fieldType>::typeName;
|
||||||
isLogical_ = logical;
|
isLogical_ = logical;
|
||||||
fieldGeoType_ = POINT_DATA;
|
fieldGeoType_ = POINT_DATA;
|
||||||
|
|
||||||
// Always strip out dimensions?
|
// Assign dimensions
|
||||||
if (!resultDimension_.dimensionless())
|
if (hasDimensions_ && !logical)
|
||||||
{
|
{
|
||||||
ptr->dimensions().reset(resultDimension_);
|
ptr->dimensions().reset(resultDimensions_);
|
||||||
}
|
}
|
||||||
|
|
||||||
setInternalFieldResult(ptr->primitiveField());
|
setInternalFieldResult(ptr->primitiveField());
|
||||||
@ -164,7 +164,7 @@ Foam::expressions::volumeExpr::parseDriver::isResultType
|
|||||||
{
|
{
|
||||||
const regIOobject* ptr = resultField_.get();
|
const regIOobject* ptr = resultField_.get();
|
||||||
|
|
||||||
if (dieOnNull && ptr != nullptr)
|
if (dieOnNull && !ptr)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "No result available. Requested "
|
<< "No result available. Requested "
|
||||||
|
|||||||
@ -31,7 +31,7 @@ expressions
|
|||||||
"radius = 0.1"
|
"radius = 0.1"
|
||||||
);
|
);
|
||||||
|
|
||||||
condition
|
fieldMask
|
||||||
#{
|
#{
|
||||||
// Within the radius
|
// Within the radius
|
||||||
(mag(pos() - $[(vector)constants.centre]) < radius)
|
(mag(pos() - $[(vector)constants.centre]) < radius)
|
||||||
|
|||||||
Reference in New Issue
Block a user