/*---------------------------------------------------------------------------*\ ========= | \\ / 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 . Class Foam::functionObjects::fieldValues::surfaceFieldValue Group grpFieldFunctionObjects Description A \c face regionType variant of the \c 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 \c sum operator to the flux field (typically \c phi). Usage A minimal example: \verbatim surfaceFieldValuePatch1 { // Mandatory entries (unmodifiable) type surfaceFieldValue; libs (fieldFunctionObjects); // Mandatory entries (runtime modifiable) fields ( ... ); operation ; regionType patch; name ; // Optional entries (runtime modifiable) names ( ); postOperation none; weightField alpha1; scaleFactor 1.0; writeArea false; surfaceFormat none; // Optional (inherited) entries ... } surfaceFieldValueFaceZone1 { // Mandatory entries (unmodifiable) type surfaceFieldValue; libs (fieldFunctionObjects); // Mandatory entries (runtime modifiable) fields ( ... ); operation ; regionType faceZone; name ; // Optional entries (runtime modifiable) names ( ); postOperation none; weightFields (rho U); scaleFactor 1.0; writeArea false; surfaceFormat none; // Optional (inherited) entries ... } \endverbatim where the entries mean: \table Property | Description | Type | Reqd | Dflt type | Type name: surfaceFieldValue | word | yes | - libs | Libraries: fieldFunctionObjects | wordList | yes | - regionType | Face regionType: see below | word | yes | - fields | Names of operand fields | wordList | yes | - name | Name of the regionType | word | yes | - names | Extended selection | word/regex list | no | - operation | Operation type: see below | word | yes | - postOperation | Post-operation type: see below | word | no | none weightField | Name of field to apply weighting | word | maybe | weightFields | Names of fields to apply weighting | wordList | maybe | scaleFactor | Output value scaling factor | scalar | no | 1.0 writeArea | Write the surface area | bool | no | false surfaceFormat | Output value format | word | conditional on writeFields | none \endtable The inherited entries are elaborated in: - \link fieldValue.H \endlink Options for the \c regionType entry: \plaintable faceZone | The \b name entry specifies a faceZone. Supports \b names patch | The \b name entry specifies a patch. Supports \b names functionObjectSurface | The \b name entry specifies a polySurface sampledSurface | A \b sampledSurfaceDict sub-dictionary and \b name \endplaintable Options for the \c operation entry: \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 Options for the \c postOperation entry: \plaintable none | No additional operation after calculation mag | Component-wise \c mag() after normal operation sqrt | Component-wise \c sqrt() after normal operation \endplaintable Usage by the \c postProcess utility is not available. Note - Some types (eg, patch or faceZone) support the selection of multiple entries, which can be specified as list of words or regular expressions by \b names entry.
If the \b names enty exists \em and contains a literal that can be used as a suitable value for \b name, the \b name entry becomes optional instead of being mandatory. - The values reported by the \c areaNormalAverage and \c areaNormalIntegrate operations are written as the first component of a field with the same rank as the input field. - Faces on empty patches are ignored. - 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: - surface fields only supported by some surfaces - default uses sampleScheme \c cell - each face in \c sampledSurface is logically only in one cell so sampling will be wrong when they 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::functionObject - Foam::functionObjects::fieldValues::fieldValue - ExtendedCodeGuide::functionObjects::field::surfaceFieldValue 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 with faceZone(s) stPatch = 0x02, //!< Calculate with patch(es) stObject = 0x11, //!< Calculate with function object surface stSampled = 0x12 //!< Sample onto surface and calculate }; //- Region type names static const Enum 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 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 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_; //- Track if the surface needs an update bool needsUpdate_; //- Optionally write the area of the surfaceFieldValue bool writeArea_; //- Extended selections wordRes selectionNames_; //- Weight field name(s) - optional wordList weightFieldNames_; //- 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_; // Demand-driven //- The sampledSurface (when operating on sampledSurface) autoPtr sampledPtr_; //- Surface writer autoPtr 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 inline bool canWeight(const Field& 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 bool validField(const word& fieldName) const; //- Return field values by looking up field name template tmp> getFieldValues ( const word& fieldName, const bool mandatory = false ) const; //- Apply the 'operation' to the values. Operation must preserve Type. template Type processSameTypeValues ( const Field& values, const vectorField& Sf, const Field& weightField ) const; //- Apply the 'operation' to the values. Wrapper around // processSameTypeValues. See also template specialisation below. template Type processValues ( const Field& values, const vectorField& Sf, const Field& weightField ) const; //- Filter a surface field according to faceIds template tmp> filterField ( const GeometricField& field ) const; //- Filter a volume field according to faceIds template tmp> filterField ( const GeometricField& field ) const; //- Weighting factor. // Possibly applies mag() depending on the operation type. template tmp weightingFactor ( const Field& 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 tmp weightingFactor ( const Field& weightField, const vectorField& Sf ) const; //- Templated helper function to output field values template label writeAll ( const vectorField& Sf, const Field& weightField, const pointField& points, const faceList& faces ); //- Templated helper function to output field values template bool writeValues ( const word& fieldName, const vectorField& Sf, const Field& weightField, const pointField& points, const faceList& faces ); //- Output file header information virtual void writeFileHeader(Ostream& os); 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 ); //- No copy construct surfaceFieldValue(const surfaceFieldValue&) = delete; //- No copy assignment void operator=(const surfaceFieldValue&) = delete; //- 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& values, const vectorField& Sf, const scalarField& weightField ) const; //- Specialisation for vector fields template<> vector surfaceFieldValue::processValues ( const Field& values, const vectorField& Sf, const scalarField& weightField ) const; //- Specialisation for scalar - pass through template<> tmp surfaceFieldValue::weightingFactor ( const Field& weightField ) const; //- Specialisation for scalar - scalar * Area template<> tmp surfaceFieldValue::weightingFactor ( const Field& weightField, const vectorField& Sf ) const; //- Specialisation for vector - vector (dot) Area template<> tmp surfaceFieldValue::weightingFactor ( const Field& weightField, const vectorField& Sf ) const; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace fieldValues } // End namespace functionObjects } // End namespace Foam // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #include "surfaceFieldValueI.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #ifdef NoRepository #include "surfaceFieldValueTemplates.C" #endif // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // #endif // ************************************************************************* //