Skip to content
Snippets Groups Projects
surfaceFieldValue.H 15.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
        \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
    
         \\/     M anipulation  | Copyright (C) 2015-2017 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/>.
    
        Foam::functionObjects::fieldValues::surfaceFieldValue
    
    Group
        grpFieldFunctionObjects
    
    
        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)
    
        Examples of function object specification:
    
    andy's avatar
    andy committed
        \verbatim
    
        movingWallPatch
        {
    
            libs            ("libfieldFunctionObjects.so");
    
            log             true;
            writeControl    writeTime;
            writeFields     true;
    
            regionType      patch;
            name            movingWall;
    
            operation       areaAverage;
    
            libs            ("libfieldFunctionObjects.so");
    
    
            log             true;
            writeControl    writeTime;
    
    andy's avatar
    andy committed
            surfaceFormat   none;
    
            operation       sum;
    
            weightField     alpha1;
    
    andy's avatar
    andy committed
        \endverbatim
    
        Where the entries comprise:
    
        \table
            Property     | Description             | Required    | Default value
    
            type         | type name: surfaceFieldValue   | yes         |
    
            log          | write data to standard output | no    | no
    
            writeFields  | Write the region field values  | yes     |
    
            writeArea    | Write the area of the surfaceFieldValue | no |
    
    andy's avatar
    andy committed
            surfaceFormat | output value format    | no          |
    
            regionType   | face regionType: see below  | yes         |
            name         | name of face regionType if required  | no |
    
            operation    | operation to perform    | yes         |
    
            postOperation | post-operation to perform    | no | none |
    
            weightField  | name of field to apply weighting | no |
    
            orientedWeightField  | name of oriented field to apply weighting | no |
    
            scaleFactor  | scale factor            | no          | 1
    
            fields       | list of fields to operate on | yes    |
        \endtable
    
        \plaintable
    
            faceZone     | requires a 'name' entry to specify the faceZone
            patch        | requires a 'name' entry to specify the patch
    
            surface      | requires a 'name' entry to specify the surfMesh
    
            sampledSurface | requires a 'sampledSurfaceDict' sub-dictionary
        \endplaintable
    
        The \c operation is one of:
        \plaintable
           none          | no operation
           sum           | sum
    
           weightedSum   | weighted sum
    
           sumMag        | sum of component magnitudes
    
           sumDirection  | sum values which are positive in given direction
    
           sumDirectionBalance | sum of balance of values in given direction
    
           average       | ensemble average
           weightedAverage | weighted average
    
           areaAverage   | area-weighted average
    
           weightedAreaAverage | weighted area average
    
           areaIntegrate | area integral
    
           weightedAreaIntegrate | weighted area integral
    
           min           | minimum
           max           | maximum
           CoV           | coefficient of variation: standard deviation/mean
    
           areaNormalAverage| area-weighted average in face normal direction
           areaNormalIntegrate | area-weighted integral in face normal directon
    
        \endplaintable
    
    andy's avatar
    andy committed
    
    
        - 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
    
    andy's avatar
    andy committed
        - if the field is a volField the \c faceZone can only consist of boundary
          faces
    
        - Using \c surface:
          - The keyword %subRegion should not be used to select surfaces.
            Specify instead the regionType 'surface' and provide the surface name.
    
            - not available for surface fields
    
    andy's avatar
    andy committed
            - 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
    
    andy's avatar
    andy committed
            - take care when using isoSurfaces - these might have duplicate
    
              triangles and so integration might be wrong
    
    
        Foam::fieldValues
        Foam::functionObject
    
        surfaceFieldValue.C
        surfaceFieldValueTemplates.C
    
    
    \*---------------------------------------------------------------------------*/
    
    
    #ifndef functionObjects_surfaceFieldValue_H
    #define functionObjects_surfaceFieldValue_H
    
    
    #include "fieldValue.H"
    
    #include "surfaceMesh.H"
    #include "fvsPatchField.H"
    #include "volFieldsFwd.H"
    #include "surfFieldsFwd.H"
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    namespace fieldValues
    {
    
    /*---------------------------------------------------------------------------*\
    
    \*---------------------------------------------------------------------------*/
    
    
    :
        public fieldValue
    {
    public:
    
        // Public data types
    
    
            //- Region type enumeration
    
            //- Region type names
            static const NamedEnum<regionTypes, 4> regionTypeNames_;
    
    
    
            //- Operation type enumeration
            enum operationType
            {
    
                opNone,                 //!< None
                opSum,                  //!< Sum
    
                opWeightedSum,          //!< Weighted sum
    
                opSumMag,               //!< Magnitude of sum
                opSumDirection,         //!< Sum in a given direction
                opSumDirectionBalance,  //!< Sum in a given direction for multiple
                opAverage,              //!< Average
                opWeightedAverage,      //!< Weighted average
                opAreaAverage,          //!< Area average
                opWeightedAreaAverage,  //!< Weighted area average
                opAreaIntegrate,        //!< Area integral
    
                opWeightedAreaIntegrate, //!< Weighted area integral
    
                opMin,                  //!< Minimum
                opMax,                  //!< Maximum
                opCoV,                  //!< Coefficient of variation
                opAreaNormalAverage,    //!< Area average in normal direction
                opAreaNormalIntegrate   //!< Area integral in normal direction
    
            };
    
            //- Operation type names
    
            static const NamedEnum<operationType, 17> operationTypeNames_;
    
            //- Post-operation type enumeration
            enum postOperationType
            {
                postOpNone,
                postOpSqrt
            };
    
            //- Operation type names
            static const NamedEnum<postOperationType, 2> postOperationTypeNames_;
    
    
    
    
            //- 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)
    
    
            //- Operation to apply to values
            operationType operation_;
    
    
            //- Optional post-evaluation operation
            postOperationType postOperation_;
    
    
            //- Weight field name - optional
    
            //- Optionally write the area of the surfaceFieldValue
    
            //- 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_;
    
            //- Underlying sampledSurface (if operating on sampledSurface)
            autoPtr<sampledSurface> surfacePtr_;
    
            //- Surface writer
            autoPtr<surfaceWriter> surfaceWriterPtr_;
    
            //- The volume mesh or surface registry being used
            const objectRegistry& obr() const override;
    
            //- 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 specified operation needs a surface Sf
            bool needsSf() const;
    
            //- True if the specified operation needs a weight-field
            bool needsWeight() const;
    
    
            //- Initialise, e.g. face addressing
    
            void initialise(const dictionary& dict);
    
            //- 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>
    
            //- 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
    
            //- Filter a volume field according to faceIds
            template<class Type>
            tmp<Field<Type>> filterField
            (
    
                const GeometricField<Type, fvPatchField, volMesh>& field
    
            ) const;
    
            //- Weighting factor
            template<class WeightType>
            static tmp<scalarField> weightingFactor
            (
                const Field<WeightType>& weightField
            );
    
            //- Weighting factor, weight field with the area
            template<class WeightType>
            static tmp<scalarField> weightingFactor
            (
                const Field<WeightType>& weightField,
                const vectorField& Sf
            );
    
    
            //- Templated helper function to output field values
            template<class WeightType>
            label writeAll
            (
                const vectorField& Sf,
                const Field<WeightType>& weightField,
                const meshedSurf& surfToWrite
            );
    
            //- 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 meshedSurf& surfToWrite
            );
    
    
    
            //- Output file header information
    
            virtual void writeFileHeader(Ostream& os) const;
    
    
    
    public:
    
        //- Run-time type information
    
            //- Construct from name, Time and dictionary
    
            (
                const word& name,
                const Time& runTime,
                const dictionary& dict
            );
    
            //- Construct from name, objectRegistry and dictionary
    
            //- Return the region type
            inline const regionTypes& regionType() const;
    
            //- Return the output directory
            inline fileName outputDir() const;
    
            virtual bool read(const dictionary& dict) override;
    
            virtual bool write() override;
    
    //- Specialisation for scalar fields
    
    (
        const Field<scalar>& values,
        const vectorField& Sf,
        const scalarField& weightField
    ) const;
    
    
    
    //- Specialisation for vector fields
    
    (
        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
    );
    
    
    //- Specialisation for scalar - scalar * Area
    template<>
    tmp<scalarField> surfaceFieldValue::weightingFactor
    (
        const Field<scalar>& weightField,
        const vectorField& Sf
    );
    
    
    //- Specialisation for vector - vector (dot) Area
    template<>
    tmp<scalarField> surfaceFieldValue::weightingFactor
    (
        const Field<vector>& weightField,
        const vectorField& Sf
    );
    
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace fieldValues
    
    } // End namespace Foam
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    #ifdef NoRepository
    
    #endif
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    #endif
    
    // ************************************************************************* //