surfaceFieldValue.H 18.9 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
5
    \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
6
     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
7
8
9
10
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

11
12
13
14
    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.
15
16
17
18
19
20
21

    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
22
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
23
24

Class
25
    Foam::functionObjects::fieldValues::surfaceFieldValue
26

andy's avatar
andy committed
27
28
29
Group
    grpFieldFunctionObjects

30
Description
31
32
33
34
35
    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.
andy's avatar
andy committed
36
37
38

    For example, to calculate the volumetric or mass flux across a patch,
    apply the 'sum' operator to the flux field (typically \c phi)
39

Andrew Heather's avatar
Andrew Heather committed
40
Usage
41
    Examples of function object specification:
andy's avatar
andy committed
42
    \verbatim
43
44
    movingWallPatch
    {
45
        type            surfaceFieldValue;
46
47
48
49
        libs            ("libfieldFunctionObjects.so");

        log             true;
        writeControl    writeTime;
50
        writeFields     false;
51
52
53
54
55

        regionType      patch;
        name            movingWall;

        operation       areaAverage;
56
        fields          (p phi U);
57
58
    }

59
    surfaceFieldValue1
60
    {
61
        type            surfaceFieldValue;
62
        libs            ("libfieldFunctionObjects.so");
63
64
65

        log             true;
        writeControl    writeTime;
66
        writeFields     true;
67

andy's avatar
andy committed
68
        surfaceFormat   none;
69
70
        regionType      faceZone;
        name            f0;
71

Andrew Heather's avatar
Andrew Heather committed
72
        operation       sum;
andy's avatar
andy committed
73
        weightField     alpha1;
74
        fields          (p phi U);
75
    }
andy's avatar
andy committed
76
    \endverbatim
77

Andrew Heather's avatar
Andrew Heather committed
78
    Where the entries comprise:
andy's avatar
andy committed
79
    \table
80
81
82
83
84
85
86
87
88
89
90
91
92
        Property     | Description                      | Required    | Default
        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   |
        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          |
        scaleFactor  | scale factor                     | no          | 1
        fields       | list of fields to operate on     | yes         |
andy's avatar
andy committed
93
    \endtable
94

95
    Where \c regionType is defined by
andy's avatar
andy committed
96
    \plaintable
97
98
99
100
        faceZone     | requires a \b name entry to specify the faceZone
        patch        | requires a \b name entry to specify the patch
        surface      | requires a \b name entry to specify the surfMesh
        sampledSurface | requires a \b sampledSurfaceDict sub-dictionary
andy's avatar
andy committed
101
102
103
104
105
    \endplaintable

    The \c operation is one of:
    \plaintable
       none          | no operation
106
107
       min           | minimum
       max           | maximum
andy's avatar
andy committed
108
       sum           | sum
109
       sumMag        | sum of component magnitudes
110
       sumDirection  | sum values that are positive in given direction
111
       sumDirectionBalance | sum of balance of values in given direction
andy's avatar
andy committed
112
       average       | ensemble average
113
       areaAverage   | area-weighted average
andy's avatar
andy committed
114
115
       areaIntegrate | area integral
       CoV           | coefficient of variation: standard deviation/mean
116
       areaNormalAverage | area-weighted average in face normal direction
117
       areaNormalIntegrate | area-weighted integral in face normal directon
118
       uniformity    | uniformity index
119
120
121
       weightedSum           | weighted sum
       weightedAverage       | weighted average
       weightedAreaAverage   | weighted area average
122
       weightedAreaIntegrate | weighted area integral
123
124
125
126
       weightedUniformity    | weighted uniformity index
       absWeightedSum           | sum using absolute weighting
       absWeightedAverage       | average using absolute weighting
       absWeightedAreaAverage   | area average using absolute weighting
127
       absWeightedAreaIntegrate | area integral using absolute weighting
128
       absWeightedUniformity    | uniformity index using absolute weighting
andy's avatar
andy committed
129
    \endplaintable
andy's avatar
andy committed
130

131
Note
andy's avatar
andy committed
132
133
134
    - 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.
135
    - faces on empty patches get ignored
andy's avatar
andy committed
136
137
    - if the field is a volField the \c faceZone can only consist of boundary
      faces
138
139
140
    - Using \c surface:
      - The keyword %subRegion should not be used to select surfaces.
        Specify instead the regionType 'surface' and provide the surface name.
141
    - using \c sampledSurface:
andy's avatar
andy committed
142
        - not available for surface fields
andy's avatar
andy committed
143
144
145
146
        - 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
andy's avatar
andy committed
147
          cells.  This can only happen for sampling on a \c triSurfaceMesh
andy's avatar
andy committed
148
        - take care when using isoSurfaces - these might have duplicate
andy's avatar
andy committed
149
150
          triangles and so integration might be wrong

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
    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$.

166
See also
andy's avatar
andy committed
167
168
    Foam::fieldValues
    Foam::functionObject
Andrew Heather's avatar
Andrew Heather committed
169

170
SourceFiles
171
172
    surfaceFieldValue.C
    surfaceFieldValueTemplates.C
173
174
175

\*---------------------------------------------------------------------------*/

176
177
#ifndef functionObjects_surfaceFieldValue_H
#define functionObjects_surfaceFieldValue_H
178
179

#include "fieldValue.H"
180
#include "Enum.H"
181
#include "meshedSurf.H"
182
183
184
185
#include "surfaceMesh.H"
#include "fvsPatchField.H"
#include "volFieldsFwd.H"
#include "surfFieldsFwd.H"
186
187
188
189
190

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{
191
192

class sampledSurface;
193
class surfaceWriter;
194

195
196
namespace functionObjects
{
197
198
199
200
namespace fieldValues
{

/*---------------------------------------------------------------------------*\
201
                      Class surfaceFieldValue Declaration
202
203
\*---------------------------------------------------------------------------*/

204
class surfaceFieldValue
205
206
207
208
209
210
211
:
    public fieldValue
{
public:

    // Public data types

212
        //- Region type enumeration
213
        enum regionTypes
214
        {
215
216
217
218
            stFaceZone,         //!< Calculate on a faceZone
            stPatch,            //!< Calculate on a patch
            stSurface,          //!< Calculate with fields on a surfMesh
            stSampledSurface    //!< Sample onto surface and calculate
219
220
        };

221
        //- Region type names
222
        static const Enum<regionTypes> regionTypeNames_;
223

224
225
226
227
228
229
230
        //- Bitmask values for operation variants
        enum operationVariant
        {
            typeBase = 0,         //!< Base operation
            typeWeighted = 0x100, //!< Operation using weighting
            typeAbsolute = 0x200, //!< Operation using mag (eg, for weighting)
        };
231
232
233
234

        //- Operation type enumeration
        enum operationType
        {
235
236
237
238
239
240
241
            // Normal operations

            opNone = 0,             //!< No operation
            opMin,                  //!< Minimum value
            opMax,                  //!< Maximum value
            opSum,                  //!< Sum of values
            opSumMag,               //!< Sum of component magnitudes
242
            opSumDirection,         //!< Sum in a given direction
243
244
245
246
247

            //! Sum of balance of values in given direction
            opSumDirectionBalance,

            opAverage,              //!< Ensemble average
248
249
250
251
            opAreaAverage,          //!< Area average
            opAreaIntegrate,        //!< Area integral
            opCoV,                  //!< Coefficient of variation
            opAreaNormalAverage,    //!< Area average in normal direction
252
            opAreaNormalIntegrate,  //!< Area integral in normal direction
253
            opUniformity,           //!< Uniformity index
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

            // Weighted variants

            //! Weighted sum
            opWeightedSum = (opSum | typeWeighted),

            //! Weighted average
            opWeightedAverage = (opAverage | typeWeighted),

            //! Weighted area average
            opWeightedAreaAverage = (opAreaAverage | typeWeighted),

            //! Weighted area integral
            opWeightedAreaIntegrate = (opAreaIntegrate | typeWeighted),

269
270
271
            //! Weighted uniformity index
            opWeightedUniformity = (opUniformity | typeWeighted),

272
273
274
275
276
277
278
279
280
281
282
283
284
285
            // 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),
286
287
288
289

            //! Uniformity index using abs weighting
            opAbsWeightedUniformity =
                (opWeightedUniformity | typeAbsolute),
290
291
292
        };

        //- Operation type names
293
        static const Enum<operationType> operationTypeNames_;
294
295


296
297
298
        //- Post-operation type enumeration
        enum postOperationType
        {
299
300
            postOpNone,   //!< No additional operation after calculation
            postOpSqrt    //!< Perform sqrt after normal operation
301
302
303
        };

        //- Operation type names
304
        static const Enum<postOperationType> postOperationTypeNames_;
305
306


307
308
private:

309
    // Private Member Functions
310
311
312
313
314
315
316

        //- Set faces to evaluate based on a face zone
        void setFaceZoneFaces();

        //- Set faces to evaluate based on a patch
        void setPatchFaces();

317
        //- Combine mesh faces and points from multiple processors
318
319
320
321
322
323
        void combineMeshGeometry
        (
            faceList& faces,
            pointField& points
        ) const;

324
        //- Combine surface faces and points from multiple processors
325
326
327
328
329
330
        void combineSurfaceGeometry
        (
            faceList& faces,
            pointField& points
        ) const;

331
        //- Calculate and return total area of the surfaceFieldValue: sum(magSf)
332
333
        scalar totalArea() const;

334
335
336
337
338

protected:

    // Protected data

339
        //- Region type
340
        regionTypes regionType_;
341
342
343
344

        //- Operation to apply to values
        operationType operation_;

345
346
347
        //- Optional post-evaluation operation
        postOperationType postOperation_;

348
        //- Weight field name - optional
349
350
        word weightFieldName_;

351
        //- Total area of the surfaceFieldValue
352
353
        scalar totalArea_;

354
        //- Optionally write the area of the surfaceFieldValue
355
356
        bool writeArea_;

357
358
359
        //- Global number of faces
        label nFaces_;

360

361
        // If operating on mesh faces (faceZone, patch)
362

363
364
365
366
367
368
            //- Local list of face IDs
            labelList faceId_;

            //- Local list of patch ID per face
            labelList facePatchId_;

369
370
371
            //- List representing the face flip map
            //  (false: use as-is, true: negate)
            boolList faceFlip_;
372

373

374
375
        //- Underlying sampledSurface (if operating on sampledSurface)
        autoPtr<sampledSurface> surfacePtr_;
376

377
378
        //- Surface writer
        autoPtr<surfaceWriter> surfaceWriterPtr_;
379

Andrew Heather's avatar
Andrew Heather committed
380

381
    // Protected Member Functions
382

383
        //- The volume mesh or surface registry being used
384
        const objectRegistry& obr() const;
385
386
387
388
389
390
391
392
393
394

        //- 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;

395
396
397
398
399
        //- True if the operation needs a surface Sf
        bool usesSf() const;

        //- True if the operation variant uses mag
        inline bool usesMag() const;
400

401
402
403
404
405
406
407
        //- 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;
408

409
        //- Initialise, e.g. face addressing
Andrew Heather's avatar
Andrew Heather committed
410
        void initialise(const dictionary& dict);
411

412
        //- Return true if the field name is known and a valid type
413
        template<class Type>
414
415
416
417
        bool validField(const word& fieldName) const;

        //- Return field values by looking up field name
        template<class Type>
418
        tmp<Field<Type>> getFieldValues
419
420
        (
            const word& fieldName,
421
            const bool mustGet = false
422
        ) const;
423

424
425
        //- Apply the 'operation' to the values. Operation must preserve Type.
        template<class Type, class WeightType>
426
427
428
429
        Type processSameTypeValues
        (
            const Field<Type>& values,
            const vectorField& Sf,
430
            const Field<WeightType>& weightField
431
432
433
434
        ) const;

        //- Apply the 'operation' to the values. Wrapper around
        //  processSameTypeValues. See also template specialisation below.
435
        template<class Type, class WeightType>
436
437
438
        Type processValues
        (
            const Field<Type>& values,
439
            const vectorField& Sf,
440
441
442
            const Field<WeightType>& weightField
        ) const;

443

444
445
446
447
        //- Filter a surface field according to faceIds
        template<class Type>
        tmp<Field<Type>> filterField
        (
448
            const GeometricField<Type, fvsPatchField, surfaceMesh>& field
449
        ) const;
450

451
452
453
454
        //- Filter a volume field according to faceIds
        template<class Type>
        tmp<Field<Type>> filterField
        (
455
            const GeometricField<Type, fvPatchField, volMesh>& field
456
457
        ) const;

458
459
460

        //- Weighting factor.
        //  Possibly applies mag() depending on the operation type.
461
        template<class WeightType>
462
        tmp<scalarField> weightingFactor
463
464
        (
            const Field<WeightType>& weightField
465
        ) const;
466

467
468
469
        //- 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.
470
        template<class WeightType>
471
        tmp<scalarField> weightingFactor
472
473
474
        (
            const Field<WeightType>& weightField,
            const vectorField& Sf
475
        ) const;
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497


        //- 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
        );


498
        //- Output file header information
499
        virtual void writeFileHeader(Ostream& os) const;
500
501
502
503
504


public:

    //- Run-time type information
505
    TypeName("surfaceFieldValue");
506
507


508
    // Constructors
509

510
        //- Construct from name, Time and dictionary
511
        surfaceFieldValue
512
513
514
515
516
        (
            const word& name,
            const Time& runTime,
            const dictionary& dict
        );
517

518
        //- Construct from name, objectRegistry and dictionary
519
        surfaceFieldValue
520
521
522
        (
            const word& name,
            const objectRegistry& obr,
523
            const dictionary& dict
524
        );
525
526
527


    //- Destructor
528
    virtual ~surfaceFieldValue();
529
530


531
    // Public Member Functions
532

533
534
        //- Return the region type
        inline const regionTypes& regionType() const;
535

536
537
        //- Return the output directory
        inline fileName outputDir() const;
538

539
        //- Read from dictionary
540
        virtual bool read(const dictionary& dict);
541

542
        //- Calculate and write
543
        virtual bool write();
544
545
546
};


547
//- Specialisation for scalar fields
548
template<>
549
scalar surfaceFieldValue::processValues
550
551
552
553
554
555
556
(
    const Field<scalar>& values,
    const vectorField& Sf,
    const scalarField& weightField
) const;


557
//- Specialisation for vector fields
558
template<>
559
vector surfaceFieldValue::processValues
560
561
562
563
564
565
566
(
    const Field<vector>& values,
    const vectorField& Sf,
    const scalarField& weightField
) const;


567
568
569
570
571
//- Specialisation for scalar - pass through
template<>
tmp<scalarField> surfaceFieldValue::weightingFactor
(
    const Field<scalar>& weightField
572
) const;
573
574
575
576
577
578
579
580


//- Specialisation for scalar - scalar * Area
template<>
tmp<scalarField> surfaceFieldValue::weightingFactor
(
    const Field<scalar>& weightField,
    const vectorField& Sf
581
) const;
582
583
584
585
586
587
588
589


//- Specialisation for vector - vector (dot) Area
template<>
tmp<scalarField> surfaceFieldValue::weightingFactor
(
    const Field<vector>& weightField,
    const vectorField& Sf
590
) const;
591
592


593
594
595
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace fieldValues
596
} // End namespace functionObjects
597
598
599
600
} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

601
#include "surfaceFieldValueI.H"
602
603
604
605

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#ifdef NoRepository
606
    #include "surfaceFieldValueTemplates.C"
607
608
609
610
611
612
613
#endif

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //