mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
653 lines
20 KiB
C++
653 lines
20 KiB
C++
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | www.openfoam.com
|
|
\\/ M anipulation |
|
|
-------------------------------------------------------------------------------
|
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
|
Copyright (C) 2015-2020 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::functionObjects::fieldValues::surfaceFieldValue
|
|
|
|
Group
|
|
grpFieldFunctionObjects
|
|
|
|
Description
|
|
Provides a 'face regionType' variant of the fieldValues function object.
|
|
|
|
Given a list of user-specified fields and a selection of mesh (or general
|
|
surface) faces, a number of operations can be performed, such as sums,
|
|
averages and integrations.
|
|
|
|
For example, to calculate the volumetric or mass flux across a patch,
|
|
apply the 'sum' operator to the flux field (typically \c phi)
|
|
|
|
Usage
|
|
Examples of function object specification:
|
|
\verbatim
|
|
movingWallPatch
|
|
{
|
|
type surfaceFieldValue;
|
|
libs (fieldFunctionObjects);
|
|
|
|
log true;
|
|
writeControl writeTime;
|
|
writeFields false;
|
|
|
|
regionType patch;
|
|
name movingWall;
|
|
|
|
operation areaAverage;
|
|
fields (p phi U);
|
|
}
|
|
|
|
surfaceFieldValue1
|
|
{
|
|
type surfaceFieldValue;
|
|
libs (fieldFunctionObjects);
|
|
|
|
log true;
|
|
writeControl writeTime;
|
|
writeFields true;
|
|
|
|
surfaceFormat none;
|
|
regionType faceZone;
|
|
name f0;
|
|
|
|
operation sum;
|
|
weightField alpha1;
|
|
fields (p phi U);
|
|
}
|
|
\endverbatim
|
|
|
|
Where the entries comprise:
|
|
\table
|
|
Property | Description | Required | Default
|
|
type | Type name: surfaceFieldValue | yes |
|
|
log | Write data to standard output | no | no
|
|
regionType | Face regionType: see below | yes |
|
|
name | Name for regionType | yes |
|
|
operation | Operation to perform | yes |
|
|
postOperation | Post-operation to perform | no | none
|
|
fields | List of fields to operate on | yes |
|
|
weightField | Name of field to apply weighting | no |
|
|
scaleFactor | Output value scaling factor | no | 1
|
|
writeArea | Write the surface area | no |
|
|
writeFields | Write the region field values | yes |
|
|
surfaceFormat | Output value format | no | none
|
|
\endtable
|
|
|
|
Where \c regionType is defined by
|
|
\plaintable
|
|
faceZone | The \b name entry to specify the faceZone
|
|
patch | The \b name entry to specify the patch
|
|
functionObjectSurface | The \b name entry to specify a polySurface
|
|
sampledSurface | A \b sampledSurfaceDict sub-dictionary and \b name
|
|
\endplaintable
|
|
|
|
The \c operation is one of:
|
|
\plaintable
|
|
none | no operation
|
|
min | minimum
|
|
max | maximum
|
|
sum | sum
|
|
sumMag | sum of component magnitudes
|
|
sumDirection | sum values that are positive in given direction
|
|
sumDirectionBalance | sum of balance of values in given direction
|
|
average | ensemble average
|
|
areaAverage | area-weighted average
|
|
areaIntegrate | area integral
|
|
CoV | coefficient of variation: standard deviation/mean
|
|
areaNormalAverage | area-weighted average in face normal direction
|
|
areaNormalIntegrate | area-weighted integral in face normal directon
|
|
uniformity | uniformity index
|
|
weightedSum | weighted sum
|
|
weightedAverage | weighted average
|
|
weightedAreaAverage | weighted area average
|
|
weightedAreaIntegrate | weighted area integral
|
|
weightedUniformity | weighted uniformity index
|
|
absWeightedSum | sum using absolute weighting
|
|
absWeightedAverage | average using absolute weighting
|
|
absWeightedAreaAverage | area average using absolute weighting
|
|
absWeightedAreaIntegrate | area integral using absolute weighting
|
|
absWeightedUniformity | uniformity index using absolute weighting
|
|
\endplaintable
|
|
|
|
The \c postOperation is one of:
|
|
\plaintable
|
|
none | No additional operation after calculation
|
|
mag | Component-wise \c mag() after normal operation
|
|
sqrt | Component-wise \c sqrt() after normal operation
|
|
\endplaintable
|
|
|
|
Note
|
|
- The values reported by the areaNormalAverage and areaNormalIntegrate
|
|
operations are written as the first component of a field with the same
|
|
rank as the input field.
|
|
- Faces on empty patches get ignored
|
|
- If the field is a volField the \c faceZone can only consist of boundary
|
|
faces
|
|
- Using \c functionObjectSurface:
|
|
- The keyword %subRegion should not be used to select surfaces.
|
|
Instead specify the regionType 'functionObjectSurface' and provide
|
|
the name.
|
|
- Using \c sampledSurface:
|
|
- not available for surface fields
|
|
- if interpolate=true they use \c interpolationCellPoint
|
|
otherwise they use cell values
|
|
- each triangle in \c sampledSurface is logically only in one cell
|
|
so interpolation will be wrong when triangles are larger than
|
|
cells. This can only happen for sampling on a \c triSurfaceMesh
|
|
- take care when using isoSurfaces - these might have duplicate
|
|
triangles and so integration might be wrong
|
|
|
|
Uniformity
|
|
\f[
|
|
UI(\phi) = 1 - \frac{1}{2 \overline{\phi} A}
|
|
\int{\left| W \phi \cdot \hat{n} - \bar{W} \bar{\phi}\right| d\vec{A}}
|
|
\,,\;
|
|
\bar{\phi} = \frac{\int{W \phi \cdot d\vec{A}}}{\int{W \cdot d\vec{A}}}
|
|
\f]
|
|
|
|
A velocity uniformity index is calculated with no weighting (W=1) and
|
|
\f$ \phi = \vec{U} \f$.
|
|
|
|
A scalar concentration uniformity index is calculated with either
|
|
\f$ \rho \vec{U} \f$ or \f$ \vec{U} \f$ for weighting and
|
|
\f$ \phi = conc \f$.
|
|
|
|
See also
|
|
Foam::fieldValues
|
|
Foam::functionObject
|
|
|
|
SourceFiles
|
|
surfaceFieldValue.C
|
|
surfaceFieldValueTemplates.C
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#ifndef functionObjects_surfaceFieldValue_H
|
|
#define functionObjects_surfaceFieldValue_H
|
|
|
|
#include "fieldValue.H"
|
|
#include "Enum.H"
|
|
#include "surfaceMesh.H"
|
|
#include "polySurface.H"
|
|
#include "fvsPatchField.H"
|
|
#include "volFieldsFwd.H"
|
|
#include "polySurfaceFieldsFwd.H"
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
namespace Foam
|
|
{
|
|
|
|
// Forward Declarations
|
|
class sampledSurface;
|
|
class surfaceWriter;
|
|
|
|
namespace functionObjects
|
|
{
|
|
namespace fieldValues
|
|
{
|
|
|
|
/*---------------------------------------------------------------------------*\
|
|
Class surfaceFieldValue Declaration
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
class surfaceFieldValue
|
|
:
|
|
public fieldValue
|
|
{
|
|
public:
|
|
|
|
// Public Data Types
|
|
|
|
//- Region type enumeration
|
|
enum regionTypes
|
|
{
|
|
stFaceZone = 0x01, //!< Calculate on a faceZone
|
|
stPatch = 0x02, //!< Calculate on a patch
|
|
stObject = 0x11, //!< Calculate with function object surface
|
|
stSampled = 0x12 //!< Sample onto surface and calculate
|
|
};
|
|
|
|
//- Region type names
|
|
static const Enum<regionTypes> regionTypeNames_;
|
|
|
|
//- Bitmask values for operation variants
|
|
enum operationVariant
|
|
{
|
|
typeBase = 0, //!< Base operation
|
|
typeScalar = 0x100, //!< Operation returns a scalar
|
|
typeWeighted = 0x200, //!< Operation using weighting
|
|
typeAbsolute = 0x400, //!< Operation using mag (eg, for weighting)
|
|
};
|
|
|
|
//- Operation type enumeration
|
|
enum operationType
|
|
{
|
|
// Normal operations
|
|
|
|
opNone = 0, //!< No operation
|
|
opMin, //!< Minimum value
|
|
opMax, //!< Maximum value
|
|
opSum, //!< Sum of values
|
|
opSumMag, //!< Sum of component magnitudes
|
|
opSumDirection, //!< Sum in a given direction
|
|
|
|
//! Sum of balance of values in given direction
|
|
opSumDirectionBalance,
|
|
|
|
opAverage, //!< Ensemble average
|
|
opAreaAverage, //!< Area average
|
|
opAreaIntegrate, //!< Area integral
|
|
opCoV, //!< Coefficient of variation
|
|
|
|
// Scalar return values
|
|
|
|
//! Area average in normal direction (output is always scalar)
|
|
opAreaNormalAverage = typeScalar,
|
|
|
|
//! Area integral in normal direction (output is always scalar)
|
|
opAreaNormalIntegrate,
|
|
|
|
//! Uniformity index (output is always scalar)
|
|
opUniformity,
|
|
|
|
// Weighted variants
|
|
|
|
//! Weighted sum
|
|
opWeightedSum = (opSum | typeWeighted),
|
|
|
|
//! Weighted average
|
|
opWeightedAverage = (opAverage | typeWeighted),
|
|
|
|
//! Weighted area average
|
|
opWeightedAreaAverage = (opAreaAverage | typeWeighted),
|
|
|
|
//! Weighted area integral
|
|
opWeightedAreaIntegrate = (opAreaIntegrate | typeWeighted),
|
|
|
|
//! Weighted uniformity index
|
|
opWeightedUniformity = (opUniformity | typeWeighted),
|
|
|
|
// Variants using absolute weighting
|
|
|
|
//! Sum using abs weighting
|
|
opAbsWeightedSum = (opWeightedSum | typeAbsolute),
|
|
|
|
//! Average using abs weighting
|
|
opAbsWeightedAverage = (opWeightedAverage | typeAbsolute),
|
|
|
|
//! Area average using abs weighting
|
|
opAbsWeightedAreaAverage = (opWeightedAreaAverage | typeAbsolute),
|
|
|
|
//! Area integral using abs weighting
|
|
opAbsWeightedAreaIntegrate =
|
|
(opWeightedAreaIntegrate | typeAbsolute),
|
|
|
|
//! Uniformity index using abs weighting
|
|
opAbsWeightedUniformity =
|
|
(opWeightedUniformity | typeAbsolute),
|
|
};
|
|
|
|
//- Operation type names
|
|
static const Enum<operationType> operationTypeNames_;
|
|
|
|
|
|
//- Post-operation type enumeration
|
|
enum postOperationType
|
|
{
|
|
postOpNone, //!< No additional operation after calculation
|
|
postOpMag, //!< Component-wise mag after normal operation
|
|
postOpSqrt //!< Component-wise sqrt after normal operation
|
|
};
|
|
|
|
//- Operation type names
|
|
static const Enum<postOperationType> postOperationTypeNames_;
|
|
|
|
|
|
private:
|
|
|
|
// Private Member Functions
|
|
|
|
//- Set faces to evaluate based on a face zone
|
|
void setFaceZoneFaces();
|
|
|
|
//- Set faces to evaluate based on a patch
|
|
void setPatchFaces();
|
|
|
|
//- Combine mesh faces and points from multiple processors
|
|
void combineMeshGeometry
|
|
(
|
|
faceList& faces,
|
|
pointField& points
|
|
) const;
|
|
|
|
//- Combine surface faces and points from multiple processors
|
|
void combineSurfaceGeometry
|
|
(
|
|
faceList& faces,
|
|
pointField& points
|
|
) const;
|
|
|
|
//- Calculate and return total area of the surfaceFieldValue: sum(magSf)
|
|
scalar totalArea() const;
|
|
|
|
|
|
protected:
|
|
|
|
// Protected Data
|
|
|
|
//- Region type
|
|
regionTypes regionType_;
|
|
|
|
//- Operation to apply to values
|
|
operationType operation_;
|
|
|
|
//- Optional post-evaluation operation
|
|
postOperationType postOperation_;
|
|
|
|
//- Weight field name - optional
|
|
word weightFieldName_;
|
|
|
|
//- Track if the surface needs an update
|
|
bool needsUpdate_;
|
|
|
|
//- Optionally write the area of the surfaceFieldValue
|
|
bool writeArea_;
|
|
|
|
//- Total area of the surfaceFieldValue
|
|
scalar totalArea_;
|
|
|
|
//- Global number of faces
|
|
label nFaces_;
|
|
|
|
|
|
// If operating on mesh faces (faceZone, patch)
|
|
|
|
//- Local list of face IDs
|
|
labelList faceId_;
|
|
|
|
//- Local list of patch ID per face
|
|
labelList facePatchId_;
|
|
|
|
//- List representing the face flip map
|
|
// (false: use as-is, true: negate)
|
|
boolList faceFlip_;
|
|
|
|
//- The sampledSurface (when operating on sampledSurface)
|
|
autoPtr<sampledSurface> sampledPtr_;
|
|
|
|
//- Surface writer
|
|
autoPtr<surfaceWriter> surfaceWriterPtr_;
|
|
|
|
|
|
// Protected Member Functions
|
|
|
|
//- The volume mesh or surface registry being used
|
|
const objectRegistry& obr() const;
|
|
|
|
//- Can the surface definition sample surface-fields?
|
|
inline bool withSurfaceFields() const;
|
|
|
|
//- Can use mesh topological merge?
|
|
inline bool withTopologicalMerge() const;
|
|
|
|
//- Return the local list of face IDs
|
|
inline const labelList& faceId() const;
|
|
|
|
//- Return the local list of patch ID per face
|
|
inline const labelList& facePatch() const;
|
|
|
|
//- Return the local true/false list representing the face flip map
|
|
inline const boolList& faceFlip() const;
|
|
|
|
//- True if the operation needs a surface Sf
|
|
bool usesSf() const;
|
|
|
|
//- True if the operation variant uses mag
|
|
inline bool usesMag() const;
|
|
|
|
//- True if the operation variant uses a weight-field
|
|
inline bool usesWeight() const;
|
|
|
|
//- True if operation variant uses a weight-field that is available.
|
|
// Checks for availability on any processor.
|
|
template<class WeightType>
|
|
inline bool canWeight(const Field<WeightType>& weightField) const;
|
|
|
|
//- Update the surface and surface information as required.
|
|
// Do nothing (and return false) if no update was required
|
|
bool update();
|
|
|
|
//- Return true if the field name is known and a valid type
|
|
template<class Type>
|
|
bool validField(const word& fieldName) const;
|
|
|
|
//- Return field values by looking up field name
|
|
template<class Type>
|
|
tmp<Field<Type>> getFieldValues
|
|
(
|
|
const word& fieldName,
|
|
const bool mandatory = false
|
|
) const;
|
|
|
|
//- Apply the 'operation' to the values. Operation must preserve Type.
|
|
template<class Type, class WeightType>
|
|
Type processSameTypeValues
|
|
(
|
|
const Field<Type>& values,
|
|
const vectorField& Sf,
|
|
const Field<WeightType>& weightField
|
|
) const;
|
|
|
|
//- Apply the 'operation' to the values. Wrapper around
|
|
// processSameTypeValues. See also template specialisation below.
|
|
template<class Type, class WeightType>
|
|
Type processValues
|
|
(
|
|
const Field<Type>& values,
|
|
const vectorField& Sf,
|
|
const Field<WeightType>& weightField
|
|
) const;
|
|
|
|
|
|
//- Filter a surface field according to faceIds
|
|
template<class Type>
|
|
tmp<Field<Type>> filterField
|
|
(
|
|
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
|
|
) const;
|
|
|
|
//- Filter a volume field according to faceIds
|
|
template<class Type>
|
|
tmp<Field<Type>> filterField
|
|
(
|
|
const GeometricField<Type, fvPatchField, volMesh>& field
|
|
) const;
|
|
|
|
|
|
//- Weighting factor.
|
|
// Possibly applies mag() depending on the operation type.
|
|
template<class WeightType>
|
|
tmp<scalarField> weightingFactor
|
|
(
|
|
const Field<WeightType>& weightField
|
|
) const;
|
|
|
|
//- Weighting factor, weight field with the area.
|
|
// Possibly applies mag() depending on the operation type.
|
|
// Reverts to mag(Sf) if the weight field is not available.
|
|
template<class WeightType>
|
|
tmp<scalarField> weightingFactor
|
|
(
|
|
const Field<WeightType>& weightField,
|
|
const vectorField& Sf
|
|
) const;
|
|
|
|
|
|
//- Templated helper function to output field values
|
|
template<class WeightType>
|
|
label writeAll
|
|
(
|
|
const vectorField& Sf,
|
|
const Field<WeightType>& weightField,
|
|
const pointField& points,
|
|
const faceList& faces
|
|
);
|
|
|
|
//- Templated helper function to output field values
|
|
template<class Type, class WeightType>
|
|
bool writeValues
|
|
(
|
|
const word& fieldName,
|
|
const vectorField& Sf,
|
|
const Field<WeightType>& weightField,
|
|
const pointField& points,
|
|
const faceList& faces
|
|
);
|
|
|
|
|
|
//- Output file header information
|
|
virtual void writeFileHeader(Ostream& os) const;
|
|
|
|
|
|
public:
|
|
|
|
//- Declare type-name, virtual type (with debug switch)
|
|
TypeName("surfaceFieldValue");
|
|
|
|
|
|
// Constructors
|
|
|
|
//- Construct from name, Time and dictionary
|
|
surfaceFieldValue
|
|
(
|
|
const word& name,
|
|
const Time& runTime,
|
|
const dictionary& dict
|
|
);
|
|
|
|
//- Construct from name, objectRegistry and dictionary
|
|
surfaceFieldValue
|
|
(
|
|
const word& name,
|
|
const objectRegistry& obr,
|
|
const dictionary& dict
|
|
);
|
|
|
|
|
|
//- Destructor
|
|
virtual ~surfaceFieldValue() = default;
|
|
|
|
|
|
// Member Functions
|
|
|
|
//- Return the region type
|
|
inline regionTypes regionType() const;
|
|
|
|
//- Return the output directory
|
|
inline fileName outputDir() const;
|
|
|
|
//- Read from dictionary
|
|
virtual bool read(const dictionary& dict);
|
|
|
|
//- Calculate and write
|
|
virtual bool write();
|
|
|
|
//- Update for changes of mesh
|
|
virtual void updateMesh(const mapPolyMesh& mpm);
|
|
|
|
//- Update for changes of mesh
|
|
virtual void movePoints(const polyMesh& mesh);
|
|
};
|
|
|
|
|
|
//- Specialisation for scalar fields
|
|
template<>
|
|
scalar surfaceFieldValue::processValues
|
|
(
|
|
const Field<scalar>& values,
|
|
const vectorField& Sf,
|
|
const scalarField& weightField
|
|
) const;
|
|
|
|
|
|
//- Specialisation for vector fields
|
|
template<>
|
|
vector surfaceFieldValue::processValues
|
|
(
|
|
const Field<vector>& values,
|
|
const vectorField& Sf,
|
|
const scalarField& weightField
|
|
) const;
|
|
|
|
|
|
//- Specialisation for scalar - pass through
|
|
template<>
|
|
tmp<scalarField> surfaceFieldValue::weightingFactor
|
|
(
|
|
const Field<scalar>& weightField
|
|
) const;
|
|
|
|
|
|
//- Specialisation for scalar - scalar * Area
|
|
template<>
|
|
tmp<scalarField> surfaceFieldValue::weightingFactor
|
|
(
|
|
const Field<scalar>& weightField,
|
|
const vectorField& Sf
|
|
) const;
|
|
|
|
|
|
//- Specialisation for vector - vector (dot) Area
|
|
template<>
|
|
tmp<scalarField> surfaceFieldValue::weightingFactor
|
|
(
|
|
const Field<vector>& weightField,
|
|
const vectorField& Sf
|
|
) const;
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
} // End namespace fieldValues
|
|
} // End namespace functionObjects
|
|
} // End namespace Foam
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
#include "surfaceFieldValueI.H"
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
#ifdef NoRepository
|
|
#include "surfaceFieldValueTemplates.C"
|
|
#endif
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
#endif
|
|
|
|
// ************************************************************************* //
|