functionObjects: fieldsExpression: Type flexibility and new operations
The fieldsExpression function has been generalised to work with a
general operator. Existing functions "add" and "subtract" have been made
to use this system, and two new operations, "multiply" and "divide",
have been added.
The functions can now handle multiple types in both input and output. A
multiply (outer product) operation on two vectors and a scalar will
result in a tensor. If the operation chain is not supported (e.g.,
division by a vector) then a warning will be generated.
In addition, a "uniform" function has been added, which will create a
uniform geometric field of a given type with specified dimensions and
calculated boundary conditions. This is mostly useful for testing
purposes and for conveniently creating simple input fields for the
operation functions described above. The function can be called by
postProcess as follows:
postProcess -func "uniform(fieldType=volScalarField, name=length, dimensions=[m], value=2)"
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2016-2019 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2016-2021 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -127,9 +127,38 @@ bool Foam::functionObjects::fieldsExpression::execute()
|
||||
{
|
||||
if (!calc())
|
||||
{
|
||||
Warning
|
||||
<< " functionObjects::" << type() << " " << name()
|
||||
<< " cannot find required fields " << fieldNames_ << endl;
|
||||
DynamicList<word> notFoundFieldNames;
|
||||
forAll(fieldNames_, i)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
#define findFieldType(Type, GeoField) \
|
||||
found = \
|
||||
found \
|
||||
|| mesh_.foundObject<GeoField<Type>>(fieldNames_[i]);
|
||||
FOR_ALL_FIELD_TYPES(findFieldType, VolField);
|
||||
FOR_ALL_FIELD_TYPES(findFieldType, SurfaceField);
|
||||
#undef findFieldType
|
||||
|
||||
if (!found)
|
||||
{
|
||||
notFoundFieldNames.append(fieldNames_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!notFoundFieldNames.empty())
|
||||
{
|
||||
Warning
|
||||
<< "functionObjects::" << type() << " " << name()
|
||||
<< " cannot find fields " << notFoundFieldNames << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning
|
||||
<< "functionObjects::" << type() << " " << name()
|
||||
<< " fields are not compatible with the " << type()
|
||||
<< " function" << endl;
|
||||
}
|
||||
|
||||
// Clear the result fields from the objectRegistry if present
|
||||
clear();
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2012-2020 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2012-2021 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -68,26 +68,74 @@ protected:
|
||||
|
||||
// Protected member functions
|
||||
|
||||
//- Set the result name
|
||||
void setResultName
|
||||
(
|
||||
const word& functionName,
|
||||
const wordList& defaultFieldNames = wordList::null()
|
||||
);
|
||||
|
||||
//- Call 'calcFieldType' for the given functionObject
|
||||
// for 'volField' and 'surfaceField' field types
|
||||
template<class Type, class FOType>
|
||||
bool calcFieldTypes(FOType& fo);
|
||||
//- Operate on the fields and store the result. Supported overload.
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA,
|
||||
class TypeB,
|
||||
class Enable = Op<TypeA, TypeB>
|
||||
>
|
||||
bool opAndStore
|
||||
(
|
||||
const GeoField<TypeA>& a,
|
||||
const GeoField<TypeB>& b
|
||||
);
|
||||
|
||||
//- Call 'calcFieldTypes' for the given 'Type' and functionObject
|
||||
template<class Type, class FOType>
|
||||
bool calcType(FOType& fo);
|
||||
//- Operate on the fields and store the result. Not-supported overload.
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class ... Args
|
||||
>
|
||||
bool opAndStore(const Args& ...);
|
||||
|
||||
//- Call 'calcType' for the given functionObject
|
||||
// for each primitive type
|
||||
template<class FOType>
|
||||
bool calcAllTypes(FOType& fo);
|
||||
//- Fold the fields expression up one place
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA,
|
||||
class TypeB
|
||||
>
|
||||
bool foldAB(const label i);
|
||||
|
||||
//- Fold the fields expression up one place
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA
|
||||
>
|
||||
bool foldA(const label i);
|
||||
|
||||
//- Fold the fields expression up one place
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op
|
||||
>
|
||||
bool fold(const label i);
|
||||
|
||||
//- Calculate and store the fields expression for the given geometric
|
||||
// field type and operation
|
||||
template<template<class> class GeoField, template<class ...> class Op>
|
||||
bool calcGeoFieldOp();
|
||||
|
||||
//- Calculate and store the fields expression for the given operation
|
||||
template<template<class ...> class Op>
|
||||
bool calcOp();
|
||||
|
||||
//- Perform calculation on the list of fields and return success
|
||||
virtual bool calc() = 0;
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration | Website: https://openfoam.org
|
||||
\\ / A nd | Copyright (C) 2016-2020 OpenFOAM Foundation
|
||||
\\ / A nd | Copyright (C) 2016-2021 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
@ -23,57 +23,142 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fieldsExpression.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type, class FOType>
|
||||
bool Foam::functionObjects::fieldsExpression::calcFieldTypes(FOType& fo)
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA,
|
||||
class TypeB,
|
||||
class Enable
|
||||
>
|
||||
bool Foam::functionObjects::fieldsExpression::opAndStore
|
||||
(
|
||||
const GeoField<TypeA>& a,
|
||||
const GeoField<TypeB>& b
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
||||
|
||||
if (foundObject<VolFieldType>(fieldNames_[0]))
|
||||
{
|
||||
return store
|
||||
(
|
||||
resultName_,
|
||||
fo.template calcFieldType<VolFieldType>()
|
||||
);
|
||||
}
|
||||
else if (foundObject<SurfaceFieldType>(fieldNames_[0]))
|
||||
{
|
||||
return store
|
||||
(
|
||||
resultName_,
|
||||
fo.template calcFieldType<SurfaceFieldType>()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return store(resultName_, Op<GeoField<TypeA>, GeoField<TypeB>>()(a, b));
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class FOType>
|
||||
bool Foam::functionObjects::fieldsExpression::calcType(FOType& fo)
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class ... Args
|
||||
>
|
||||
bool Foam::functionObjects::fieldsExpression::opAndStore
|
||||
(
|
||||
const Args& ...
|
||||
)
|
||||
{
|
||||
return calcFieldTypes<Type>(fo);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class FOType>
|
||||
bool Foam::functionObjects::fieldsExpression::calcAllTypes(FOType& fo)
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA,
|
||||
class TypeB
|
||||
>
|
||||
bool Foam::functionObjects::fieldsExpression::foldAB(const label i)
|
||||
{
|
||||
bool processed = false;
|
||||
if
|
||||
(
|
||||
i == 0
|
||||
&& foundObject<GeoField<TypeA>>(fieldNames_[0])
|
||||
)
|
||||
{
|
||||
clearObject(resultName_);
|
||||
return store
|
||||
(
|
||||
resultName_,
|
||||
lookupObject<GeoField<TypeA>>(fieldNames_[0]).clone()
|
||||
);
|
||||
}
|
||||
|
||||
#define processType(fieldType, none) \
|
||||
processed = processed || fo.template calcType<fieldType>(fo);
|
||||
FOR_ALL_FIELD_TYPES(processType)
|
||||
if
|
||||
(
|
||||
i > 0
|
||||
&& foundObject<GeoField<TypeA>>(resultName_)
|
||||
&& foundObject<GeoField<TypeB>>(fieldNames_[i])
|
||||
)
|
||||
{
|
||||
tmp<GeoField<TypeA>> a =
|
||||
lookupObject<GeoField<TypeA>>(resultName_).clone();
|
||||
const GeoField<TypeB>& b =
|
||||
lookupObject<GeoField<TypeB>>(fieldNames_[i]);
|
||||
|
||||
return processed;
|
||||
clearObject(resultName_);
|
||||
return opAndStore<GeoField, Op>(a(), b);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
template<class> class GeoField,
|
||||
template<class ...> class Op,
|
||||
class TypeA
|
||||
>
|
||||
bool Foam::functionObjects::fieldsExpression::foldA(const label i)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
#define processType(Type, none) \
|
||||
success = success || foldAB<GeoField, Op, TypeA, Type>(i);
|
||||
FOR_ALL_FIELD_TYPES(processType);
|
||||
#undef processType
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
template<template<class> class GeoField, template<class ...> class Op>
|
||||
bool Foam::functionObjects::fieldsExpression::fold(const label i)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
#define processType(Type, none) \
|
||||
success = success || foldA<GeoField, Op, Type>(i);
|
||||
FOR_ALL_FIELD_TYPES(processType);
|
||||
#undef processType
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
template<template<class> class GeoField, template<class ...> class Op>
|
||||
bool Foam::functionObjects::fieldsExpression::calcGeoFieldOp()
|
||||
{
|
||||
forAll(fieldNames_, i)
|
||||
{
|
||||
if (!fold<GeoField, Op>(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<template<class ...> class Op>
|
||||
bool Foam::functionObjects::fieldsExpression::calcOp()
|
||||
{
|
||||
return
|
||||
calcGeoFieldOp<VolField, Op>()
|
||||
|| calcGeoFieldOp<SurfaceField, Op>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user