surfaceFieldValue.C 23.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) 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
25

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

26
#include "surfaceFieldValue.H"
27
28
#include "fvMesh.H"
#include "emptyPolyPatch.H"
29
#include "coupledPolyPatch.H"
30
#include "sampledSurface.H"
31
32
#include "mergePoints.H"
#include "indirectPrimitivePatch.H"
33
#include "PatchTools.H"
34
#include "meshedSurfRef.H"
35
#include "addToRunTimeSelectionTable.H"
36
37
38

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

39
namespace Foam
40
{
41
42
43
44
namespace functionObjects
{
namespace fieldValues
{
45
46
47
    defineTypeNameAndDebug(surfaceFieldValue, 0);
    addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, dictionary);
    addToRunTimeSelectionTable(functionObject, surfaceFieldValue, dictionary);
48
49
}
}
50
51
}

52
53
54
template<>
const char* Foam::NamedEnum
<
55
    Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes,
56
    4
57
58
59
60
>::names[] =
{
    "faceZone",
    "patch",
61
    "surface",
62
63
    "sampledSurface"
};
64

65
66
67
template<>
const char* Foam::NamedEnum
<
68
    Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
69
    17
70
71
72
73
>::names[] =
{
    "none",
    "sum",
74
    "weightedSum",
75
76
77
78
79
80
81
82
    "sumMag",
    "sumDirection",
    "sumDirectionBalance",
    "average",
    "weightedAverage",
    "areaAverage",
    "weightedAreaAverage",
    "areaIntegrate",
83
    "weightedAreaIntegrate",
84
85
86
87
88
89
90
    "min",
    "max",
    "CoV",
    "areaNormalAverage",
    "areaNormalIntegrate"
};

91
92
93
94
95
96
97
98
99
100
101
102
template<>
const char* Foam::NamedEnum
<
    Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationType,
    2
>::names[] =
{
    "none",
    "sqrt"
};


103
104
const Foam::NamedEnum
<
105
    Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes,
106
    4
107
> Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypeNames_;
108
109
110

const Foam::NamedEnum
<
111
    Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
112
    17
113
> Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_;
114

115
116
117
118
119
120
121
const Foam::NamedEnum
<
    Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationType,
    2
>
Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_;

122

Henry Weller's avatar
Henry Weller committed
123
// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
const Foam::objectRegistry&
Foam::functionObjects::fieldValues::surfaceFieldValue::obr() const
{
    if (regionType_ == stSurface)
    {
        return mesh_.lookupObject<objectRegistry>(regionName_);
    }
    else
    {
        return mesh_;
    }
}


139
void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
140
{
141
    const label zoneId = mesh_.faceZones().findZoneID(regionName_);
142
143
144

    if (zoneId < 0)
    {
145
        FatalErrorInFunction
146
            << type() << " " << name() << ": "
147
148
            << regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
            << "    Unknown face zone name: " << regionName_
149
            << ". Valid face zones are: " << mesh_.faceZones().names()
150
151
152
            << nl << exit(FatalError);
    }

153
    const faceZone& fZone = mesh_.faceZones()[zoneId];
154

155
156
    DynamicList<label> faceIds(fZone.size());
    DynamicList<label> facePatchIds(fZone.size());
157
    DynamicList<bool> faceFlip(fZone.size());
158
159
160

    forAll(fZone, i)
    {
161
        const label facei = fZone[i];
162
163
164

        label faceId = -1;
        label facePatchId = -1;
165
        if (mesh_.isInternalFace(facei))
166
        {
167
            faceId = facei;
168
169
170
171
            facePatchId = -1;
        }
        else
        {
172
173
            facePatchId = mesh_.boundaryMesh().whichPatch(facei);
            const polyPatch& pp = mesh_.boundaryMesh()[facePatchId];
174
            if (isA<coupledPolyPatch>(pp))
175
            {
176
                if (refCast<const coupledPolyPatch>(pp).owner())
177
                {
178
                    faceId = pp.whichFace(facei);
179
180
181
182
183
184
185
186
                }
                else
                {
                    faceId = -1;
                }
            }
            else if (!isA<emptyPolyPatch>(pp))
            {
187
                faceId = facei - pp.start();
188
189
190
191
192
193
194
195
196
197
            }
            else
            {
                faceId = -1;
                facePatchId = -1;
            }
        }

        if (faceId >= 0)
        {
198
199
            faceIds.append(faceId);
            facePatchIds.append(facePatchId);
200
            faceFlip.append(fZone.flipMap()[i] ? true : false);
201
202
203
        }
    }

204
205
    faceId_.transfer(faceIds);
    facePatchId_.transfer(facePatchIds);
206
    faceFlip_.transfer(faceFlip);
207
    nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
208
209
210

    if (debug)
    {
211
        Pout<< "Original face zone size = " << fZone.size()
212
            << ", new size = " << faceId_.size() << endl;
213
214
215
216
    }
}


217
void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
218
{
219
    const label patchid = mesh_.boundaryMesh().findPatchID(regionName_);
220

221
    if (patchid < 0)
222
    {
223
        FatalErrorInFunction
224
            << type() << " " << name() << ": "
225
226
            << regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
            << "    Unknown patch name: " << regionName_
227
            << ". Valid patch names are: "
228
            << mesh_.boundaryMesh().names() << nl
229
230
231
            << exit(FatalError);
    }

232
    const polyPatch& pp = mesh_.boundaryMesh()[patchid];
233
234

    label nFaces = pp.size();
235
    if (isA<emptyPolyPatch>(pp))
236
237
238
239
240
241
    {
        nFaces = 0;
    }

    faceId_.setSize(nFaces);
    facePatchId_.setSize(nFaces);
242
    faceFlip_.setSize(nFaces);
243
    nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
244

245
    forAll(faceId_, facei)
246
    {
247
248
        faceId_[facei] = facei;
        facePatchId_[facei] = patchid;
249
        faceFlip_[facei] = false;
250
251
252
253
    }
}


254
void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
255
256
257
258
259
260
261
262
263
264
265
266
267
(
    faceList& faces,
    pointField& points
) const
{
    List<faceList> allFaces(Pstream::nProcs());
    List<pointField> allPoints(Pstream::nProcs());

    labelList globalFacesIs(faceId_);
    forAll(globalFacesIs, i)
    {
        if (facePatchId_[i] != -1)
        {
268
            label patchi = facePatchId_[i];
269
            globalFacesIs[i] += mesh_.boundaryMesh()[patchi].start();
270
271
272
273
274
275
        }
    }

    // Add local faces and points to the all* lists
    indirectPrimitivePatch pp
    (
276
277
        IndirectList<face>(mesh_.faces(), globalFacesIs),
        mesh_.points()
278
279
280
281
282
283
284
285
286
287
    );
    allFaces[Pstream::myProcNo()] = pp.localFaces();
    allPoints[Pstream::myProcNo()] = pp.localPoints();

    Pstream::gatherList(allFaces);
    Pstream::gatherList(allPoints);

    // Renumber and flatten
    label nFaces = 0;
    label nPoints = 0;
288
    forAll(allFaces, proci)
289
    {
290
291
        nFaces += allFaces[proci].size();
        nPoints += allPoints[proci].size();
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    }

    faces.setSize(nFaces);
    points.setSize(nPoints);

    nFaces = 0;
    nPoints = 0;

    // My own data first
    {
        const faceList& fcs = allFaces[Pstream::myProcNo()];
        forAll(fcs, i)
        {
            const face& f = fcs[i];
            face& newF = faces[nFaces++];
            newF.setSize(f.size());
            forAll(f, fp)
            {
                newF[fp] = f[fp] + nPoints;
            }
        }

        const pointField& pts = allPoints[Pstream::myProcNo()];
        forAll(pts, i)
        {
            points[nPoints++] = pts[i];
        }
    }

    // Other proc data follows
322
    forAll(allFaces, proci)
323
    {
324
        if (proci != Pstream::myProcNo())
325
        {
326
            const faceList& fcs = allFaces[proci];
327
328
329
330
331
332
333
334
335
336
337
            forAll(fcs, i)
            {
                const face& f = fcs[i];
                face& newF = faces[nFaces++];
                newF.setSize(f.size());
                forAll(f, fp)
                {
                    newF[fp] = f[fp] + nPoints;
                }
            }

338
            const pointField& pts = allPoints[proci];
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
            forAll(pts, i)
            {
                points[nPoints++] = pts[i];
            }
        }
    }

    // Merge
    labelList oldToNew;
    pointField newPoints;
    bool hasMerged = mergePoints
    (
        points,
        SMALL,
        false,
        oldToNew,
        newPoints
    );

    if (hasMerged)
    {
        if (debug)
        {
            Pout<< "Merged from " << points.size()
                << " down to " << newPoints.size() << " points" << endl;
        }

        points.transfer(newPoints);
        forAll(faces, i)
        {
            inplaceRenumber(oldToNew, faces[i]);
        }
    }
}


375
376
void Foam::functionObjects::fieldValues::surfaceFieldValue::
combineSurfaceGeometry
377
378
379
380
381
(
    faceList& faces,
    pointField& points
) const
{
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    if (regionType_ == stSurface)
    {
        const surfMesh& s = dynamicCast<const surfMesh>(obr());

        if (Pstream::parRun())
        {
            // Dimension as fraction of surface
            const scalar mergeDim = 1e-10*boundBox(s.points(), true).mag();

            labelList pointsMap;

            PatchTools::gatherAndMerge
            (
                mergeDim,
                primitivePatch
                (
                    SubList<face>(s.faces(), s.faces().size()),
                    s.points()
                ),
                points,
                faces,
                pointsMap
            );
        }
        else
        {
            faces = s.faces();
            points = s.points();
        }
    }
    else if (surfacePtr_.valid())
413
414
415
416
417
    {
        const sampledSurface& s = surfacePtr_();

        if (Pstream::parRun())
        {
418
            // Dimension as fraction of mesh bounding box
419
            const scalar mergeDim = 1e-10*mesh_.bounds().mag();
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

            labelList pointsMap;

            PatchTools::gatherAndMerge
            (
                mergeDim,
                primitivePatch
                (
                    SubList<face>(s.faces(), s.faces().size()),
                    s.points()
                ),
                points,
                faces,
                pointsMap
            );
        }
        else
        {
            faces = s.faces();
            points = s.points();
        }
    }
}


445
Foam::scalar
446
Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
447
448
449
{
    scalar totalArea;

450
451
452
453
454
455
456
    if (regionType_ == stSurface)
    {
        const surfMesh& s = dynamicCast<const surfMesh>(obr());

        totalArea = gSum(s.magSf());
    }
    else if (surfacePtr_.valid())
457
458
459
460
461
    {
        totalArea = gSum(surfacePtr_().magSf());
    }
    else
    {
462
        totalArea = gSum(filterField(mesh_.magSf()));
463
464
465
466
467
468
    }

    return totalArea;
}


469
470
// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //

471
472
473
474
475
476
477
478
479
480
481
bool Foam::functionObjects::fieldValues::surfaceFieldValue::needsSf() const
{
    // Many operations use the Sf field
    switch (operation_)
    {
        case opNone:
        case opSum:
        case opSumMag:
        case opAverage:
        case opMin:
        case opMax:
482
        {
483
            return false;
484
        }
485
        default:
486
        {
487
            return true;
488
        }
489
490
491
492
493
494
495
496
497
498
499
500
501
    }
}


bool Foam::functionObjects::fieldValues::surfaceFieldValue::needsWeight() const
{
    // Only a few operations use weight field
    switch (operation_)
    {
        case opWeightedSum:
        case opWeightedAverage:
        case opWeightedAreaAverage:
        case opWeightedAreaIntegrate:
502
        {
503
            return true;
504
        }
505
        default:
506
        {
507
            return false;
508
        }
509
510
511
512
    }
}


513
void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
514
515
516
(
    const dictionary& dict
)
517
{
518
    dict.lookup("name") >> regionName_;
519

520
    switch (regionType_)
521
522
523
524
    {
        case stFaceZone:
        {
            setFaceZoneFaces();
525
            surfacePtr_.clear();
526
527
528
529
530
            break;
        }
        case stPatch:
        {
            setPatchFaces();
531
532
533
534
535
536
537
538
539
540
541
542
            surfacePtr_.clear();
            break;
        }
        case stSurface:
        {
            const surfMesh& s = dynamicCast<const surfMesh>(obr());
            nFaces_ = returnReduce(s.size(), sumOp<label>());

            faceId_.clear();
            facePatchId_.clear();
            faceFlip_.clear();
            surfacePtr_.clear();
543
544
            break;
        }
545
546
        case stSampledSurface:
        {
547
548
549
550
551
552
553
554
555
556
557
558
559
560
            faceId_.clear();
            facePatchId_.clear();
            faceFlip_.clear();

            surfacePtr_ = sampledSurface::New
            (
                name(),
                mesh_,
                dict.subDict("sampledSurfaceDict")
            );
            surfacePtr_().update();
            nFaces_ =
                returnReduce(surfacePtr_().faces().size(), sumOp<label>());

561
562
            break;
        }
563
564
        default:
        {
565
            FatalErrorInFunction
566
                << type() << " " << name() << ": "
Mark OLESEN's avatar
Mark OLESEN committed
567
                << int(regionType_) << "(" << regionName_ << "):"
568
                << nl << "    Unknown region type. Valid region types are:"
Mark OLESEN's avatar
Mark OLESEN committed
569
570
                << regionTypeNames_ << nl
                << exit(FatalError);
571
572
573
        }
    }

574
575
    if (nFaces_ == 0)
    {
576
        FatalErrorInFunction
577
            << type() << " " << name() << ": "
578
            << regionTypeNames_[regionType_] << "(" << regionName_ << "):" << nl
579
            << "    Region has no faces" << exit(FatalError);
580
581
    }

582
583
584
585
586
    if (surfacePtr_.valid())
    {
        surfacePtr_().update();
    }

587
588
    totalArea_ = totalArea();

589
    Info<< type() << " " << name() << ":" << nl
590
        << "    operation     = ";
Andrew Heather's avatar
Andrew Heather committed
591

592
    if (postOperation_ != postOpNone)
Andrew Heather's avatar
Andrew Heather committed
593
    {
594
595
596
597
598
599
        Info<< postOperationTypeNames_[postOperation_] << '('
            << operationTypeNames_[operation_] << ')'  << nl;
    }
    else
    {
        Info<< operationTypeNames_[operation_] << nl;
600
    }
601
602
603
    Info<< "    total faces   = " << nFaces_ << nl
        << "    total area    = " << totalArea_ << nl;

604

605
606
    weightFieldName_ = "none";
    if (needsWeight())
607
    {
608
        if (dict.readIfPresent("weightField", weightFieldName_))
609
        {
610
611
612
613
614
615
616
617
            if (regionType_ == stSampledSurface)
            {
                FatalIOErrorInFunction(dict)
                    << "Cannot use weightField for sampledSurface"
                    << exit(FatalIOError);
            }

            Info<< "    weight field  = " << weightFieldName_ << nl;
618
619
620
        }
    }

621
    // Backwards compatibility for v1612+ and older
622
623
624
    List<word> orientedFields;
    if (dict.readIfPresent("orientedFields", orientedFields))
    {
625
626
627
628
629
        WarningInFunction
            << "The 'orientedFields' option is deprecated.  These fields can "
            << "and have been added to the standard 'fields' list."
            << endl;

630
        fields_.append(orientedFields);
Andrew Heather's avatar
Andrew Heather committed
631
632
    }

633

634
    surfaceWriterPtr_.clear();
635
    if (writeFields_)
636
    {
637
638
        const word surfaceFormat(dict.lookup("surfaceFormat"));

639
640
641
        if (surfaceFormat != "none")
        {
            surfaceWriterPtr_.reset
642
            (
643
644
645
646
647
648
649
650
651
652
                surfaceWriter::New
                (
                    surfaceFormat,
                    dict.subOrEmptyDict("formatOptions").
                        subOrEmptyDict(surfaceFormat)
                ).ptr()
            );

            Info<< "    surfaceFormat = " << surfaceFormat << nl;
        }
653
    }
654
655

    Info<< nl << endl;
656
657
658
}


659
660
661
662
void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
(
    Ostream& os
) const
663
{
664
    if (operation_ != opNone)
665
    {
666
667
        writeCommented(os, "Region type : ");
        os << regionTypeNames_[regionType_] << " " << regionName_ << endl;
668

669
670
671
672
        writeHeaderValue(os, "Faces", nFaces_);
        writeHeaderValue(os, "Area", totalArea_);
        writeHeaderValue(os, "Scale factor", scaleFactor_);

673
674
675
676
677
        if (weightFieldName_ != "none")
        {
            writeHeaderValue(os, "Weight field", weightFieldName_);
        }

678
        writeCommented(os, "Time");
679
680
        if (writeArea_)
        {
681
            os  << tab << "Area";
682
        }
683

684
        forAll(fields_, i)
685
        {
686
687
            os  << tab << operationTypeNames_[operation_]
                << "(" << fields_[i] << ")";
688
        }
689

690
        os  << endl;
691
    }
692
693
694
}


695
template<>
696
697
Foam::scalar
Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
698
699
700
701
702
703
704
705
706
707
(
    const Field<scalar>& values,
    const vectorField& Sf,
    const scalarField& weightField
) const
{
    switch (operation_)
    {
        case opSumDirection:
        {
708
            vector n(dict_.lookup("direction"));
709
            return gSum(pos(values*(Sf & n))*mag(values));
710
711
712
713
714
        }
        case opSumDirectionBalance:
        {
            vector n(dict_.lookup("direction"));
            const scalarField nv(values*(Sf & n));
715

716
            return gSum(pos(nv)*mag(values) - neg(nv)*mag(values));
717
718
719
720
721
722
723
724
725
726
        }
        default:
        {
            // Fall through to other operations
            return processSameTypeValues(values, Sf, weightField);
        }
    }
}


727
template<>
728
729
Foam::vector
Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
730
731
732
733
734
735
736
737
(
    const Field<vector>& values,
    const vectorField& Sf,
    const scalarField& weightField
) const
{
    switch (operation_)
    {
738
739
        case opSumDirection:
        {
740
741
742
            vector n(dict_.lookup("direction"));
            n /= mag(n) + ROOTVSMALL;

743
            const scalarField nv(n & values);
744
            return gSum(pos(nv)*n*(nv));
745
746
747
748
749
750
        }
        case opSumDirectionBalance:
        {
            vector n(dict_.lookup("direction"));
            n /= mag(n) + ROOTVSMALL;

751
            const scalarField nv(n & values);
752
            return gSum(pos(nv)*n*(nv));
753
        }
754
755
        case opAreaNormalAverage:
        {
756
757
            const scalar val = gSum(values & Sf)/gSum(mag(Sf));
            return vector(val, 0, 0);
758
759
760
        }
        case opAreaNormalIntegrate:
        {
761
762
            const scalar val = gSum(values & Sf);
            return vector(val, 0, 0);
763
764
765
766
767
768
769
770
771
772
        }
        default:
        {
            // Fall through to other operations
            return processSameTypeValues(values, Sf, weightField);
        }
    }
}


773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
template<>
Foam::tmp<Foam::scalarField>
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
(
    const Field<scalar>& weightField
)
{
    // pass through
    return weightField;
}


template<>
Foam::tmp<Foam::scalarField>
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
(
    const Field<scalar>& weightField,
    const vectorField& Sf
)
{
    // scalar * Area
    if (returnReduce(weightField.empty(), andOp<bool>()))
    {
        return mag(Sf);
    }
    else
    {
        return weightField * mag(Sf);
    }
}


template<>
Foam::tmp<Foam::scalarField>
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
(
    const Field<vector>& weightField,
    const vectorField& Sf
)
{
    // vector (dot) Area
    if (returnReduce(weightField.empty(), andOp<bool>()))
    {
        return mag(Sf);
    }
    else
    {
        return weightField & Sf;
    }
}


825
826
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

827
Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
828
829
830
831
832
833
834
(
    const word& name,
    const Time& runTime,
    const dictionary& dict
)
:
    fieldValue(name, runTime, dict, typeName),
835
    regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
836
    operation_(operationTypeNames_.read(dict.lookup("operation"))),
837
838
839
840
841
    postOperation_
    (
        postOperationTypeNames_
        [dict.lookupOrDefault<word>("postOperation", "none")]
    ),
842
843
844
845
846
    weightFieldName_("none"),
    writeArea_(dict.lookupOrDefault("writeArea", false)),
    nFaces_(0),
    faceId_(),
    facePatchId_(),
847
    faceFlip_()
848
849
{
    read(dict);
850
    writeFileHeader(file());
851
852
}

853

854
Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
855
856
857
(
    const word& name,
    const objectRegistry& obr,
858
    const dictionary& dict
859
860
)
:
861
    fieldValue(name, obr, dict, typeName),
862
    regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
863
    operation_(operationTypeNames_.read(dict.lookup("operation"))),
864
865
866
867
868
    postOperation_
    (
        postOperationTypeNames_
        [dict.lookupOrDefault<word>("postOperation", "none")]
    ),
869
    weightFieldName_("none"),
870
    writeArea_(dict.lookupOrDefault("writeArea", false)),
871
    nFaces_(0),
872
873
    faceId_(),
    facePatchId_(),
874
    faceFlip_()
875
{
876
    read(dict);
877
    writeFileHeader(file());
878
879
880
881
882
}


// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

883
Foam::functionObjects::fieldValues::surfaceFieldValue::~surfaceFieldValue()
884
885
886
887
888
{}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

889
bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
890
891
892
(
    const dictionary& dict
)
893
{
Andrew Heather's avatar
Andrew Heather committed
894
    fieldValue::read(dict);
895
    initialise(dict);
896

897
    return true;
898
899
900
}


901
bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
902
{
903
    if (surfacePtr_.valid())
904
    {
905
906
        surfacePtr_().update();
    }
907

908
    if (operation_ != opNone)
909
    {
910
911
912
913
914
915
        fieldValue::write();

        if (Pstream::master())
        {
            writeTime(file());
        }
916
    }
917

918
919
920
    if (writeArea_)
    {
        totalArea_ = totalArea();
921
922
        Log << "    total area = " << totalArea_ << endl;

923
        if (operation_ != opNone && Pstream::master())
924
        {
925
            file() << tab << totalArea_;
926
        }
927
    }
928

929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
    // Many operations use the Sf field
    vectorField Sf;
    if (needsSf())
    {
        if (regionType_ == stSurface)
        {
            const surfMesh& s = dynamicCast<const surfMesh>(obr());
            Sf = s.Sf();
        }
        else if (surfacePtr_.valid())
        {
            Sf = surfacePtr_().Sf();
        }
        else
        {
944
            Sf = filterField(mesh_.Sf());
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
        }
    }

    // Faces and points for surface format (if specified)
    faceList faces;
    pointField points;

    if (surfaceWriterPtr_.valid())
    {
        if (regionType_ == stSurface || surfacePtr_.valid())
        {
            combineSurfaceGeometry(faces, points);
        }
        else
        {
            combineMeshGeometry(faces, points);
        }
    }

    meshedSurfRef surfToWrite(points, faces);

    // Only a few weight types (scalar, vector)
967
968
    if (weightFieldName_ != "none")
    {
969
970
        if (validField<scalar>(weightFieldName_))
        {
971
            scalarField weightField
972
            (
973
                getFieldValues<scalar>(weightFieldName_, true)
974
            );
975

976
977
978
979
980
            // Process the fields
            writeAll(Sf, weightField, surfToWrite);
        }
        else if (validField<vector>(weightFieldName_))
        {
981
            vectorField weightField
982
            (
983
                getFieldValues<vector>(weightFieldName_, true)
984
            );
985

986
987
988
989
            // Process the fields
            writeAll(Sf, weightField, surfToWrite);
        }
        else
990
        {
991
992
993
994
            FatalErrorInFunction
                << "weightField " << weightFieldName_
                << " not found or an unsupported type"
                << abort(FatalError);
995
        }
996
    }
997
998
999
1000
    else
    {
        // Default is a zero-size scalar weight field (ie, weight = 1)
        scalarField weightField;
For faster browsing, not all history is shown. View entire blame