faceZone.C 13.4 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
Mark Olesen's avatar
Mark Olesen committed
5
    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6
7
8
9
10
     \\/     M anipulation  |
-------------------------------------------------------------------------------
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
27
28
29
30
31
32

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

#include "faceZone.H"
#include "addToRunTimeSelectionTable.H"
#include "faceZoneMesh.H"
#include "polyMesh.H"
#include "primitiveMesh.H"
#include "demandDrivenData.H"
#include "mapPolyMesh.H"
mattijs's avatar
mattijs committed
33
#include "syncTools.H"
34
35
36
37
38
39
40
41
42
43

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

namespace Foam
{
    defineTypeNameAndDebug(faceZone, 0);
    defineRunTimeSelectionTable(faceZone, dictionary);
    addToRunTimeSelectionTable(faceZone, faceZone, dictionary);
}

44
45
const char* const Foam::faceZone::labelsName = "faceLabels";

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

void Foam::faceZone::calcFaceZonePatch() const
{
    if (debug)
    {
        Info<< "void faceZone::calcFaceZonePatch() const : "
            << "Calculating primitive patch"
            << endl;
    }

    if (patchPtr_)
    {
        FatalErrorIn
        (
            "void faceZone::calcFaceZonePatch() const"
        )   << "primitive face zone patch already calculated"
            << abort(FatalError);
    }

    patchPtr_ =
        new primitiveFacePatch
        (
            faceList(size()),
            zoneMesh().mesh().points()
        );

    primitiveFacePatch& patch = *patchPtr_;

    const faceList& f = zoneMesh().mesh().faces();

    const labelList& addr = *this;
    const boolList& flip = flipMap();

80
    forAll(addr, faceI)
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
    {
        if (flip[faceI])
        {
            patch[faceI] = f[addr[faceI]].reverseFace();
        }
        else
        {
            patch[faceI] = f[addr[faceI]];
        }
    }

    if (debug)
    {
        Info<< "void faceZone::calcFaceZonePatch() const : "
            << "Finished calculating primitive patch"
            << endl;
    }
}


void Foam::faceZone::calcCellLayers() const
{
    if (debug)
    {
        Info<< "void Foam::faceZone::calcCellLayers() const : "
            << "calculating master cells"
            << endl;
    }

    // It is an error to attempt to recalculate edgeCells
    // if the pointer is already set
    if (masterCellsPtr_ || slaveCellsPtr_)
    {
        FatalErrorIn("void faceZone::calcCellLayers() const")
            << "cell layers already calculated"
            << abort(FatalError);
    }
    else
    {
        // Go through all the faces in the master zone.  Choose the
        // master or slave cell based on the face flip

        const labelList& own = zoneMesh().mesh().faceOwner();
        const labelList& nei = zoneMesh().mesh().faceNeighbour();

        const labelList& mf = *this;

        const boolList& faceFlip = flipMap();

        masterCellsPtr_ = new labelList(mf.size());
        labelList& mc = *masterCellsPtr_;

        slaveCellsPtr_ = new labelList(mf.size());
        labelList& sc = *slaveCellsPtr_;

136
        forAll(mf, faceI)
137
        {
mattijs's avatar
mattijs committed
138
139
140
141
142
143
144
145
            label ownCellI = own[mf[faceI]];
            label neiCellI =
            (
                zoneMesh().mesh().isInternalFace(mf[faceI])
              ? nei[mf[faceI]]
              : -1
            );

146
147
148
            if (!faceFlip[faceI])
            {
                // Face is oriented correctly, no flip needed
mattijs's avatar
mattijs committed
149
150
                mc[faceI] = neiCellI;
                sc[faceI] = ownCellI;
151
152
153
            }
            else
            {
mattijs's avatar
mattijs committed
154
155
                mc[faceI] = ownCellI;
                sc[faceI] = neiCellI;
156
157
            }
        }
Mark Olesen's avatar
Mark Olesen committed
158
159
        //Info<< "masterCells: " << mc << endl;
        //Info<< "slaveCells: " << sc << endl;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    }
}


void Foam::faceZone::checkAddressing() const
{
    if (size() != flipMap_.size())
    {
        FatalErrorIn("void Foam::faceZone::checkAddressing() const")
            << "Different sizes of the addressing and flipMap arrays.  "
            << "Size of addressing: " << size()
            << " size of flip map: " << flipMap_.size()
            << abort(FatalError);
    }
}


// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

// Construct from components
Foam::faceZone::faceZone
(
    const word& name,
    const labelList& addr,
    const boolList& fm,
    const label index,
    const faceZoneMesh& zm
)
:
189
    zone(name, addr, index),
190
191
192
193
194
    flipMap_(fm),
    zoneMesh_(zm),
    patchPtr_(NULL),
    masterCellsPtr_(NULL),
    slaveCellsPtr_(NULL),
195
    mePtr_(NULL)
196
197
198
199
200
{
    checkAddressing();
}


201
202
203
Foam::faceZone::faceZone
(
    const word& name,
Mark Olesen's avatar
Mark Olesen committed
204
205
    const Xfer<labelList>& addr,
    const Xfer<boolList>& fm,
206
207
208
209
    const label index,
    const faceZoneMesh& zm
)
:
210
    zone(name, addr, index),
211
212
213
214
215
    flipMap_(fm),
    zoneMesh_(zm),
    patchPtr_(NULL),
    masterCellsPtr_(NULL),
    slaveCellsPtr_(NULL),
216
    mePtr_(NULL)
217
218
219
220
221
{
    checkAddressing();
}


222
223
224
225
226
227
228
229
Foam::faceZone::faceZone
(
    const word& name,
    const dictionary& dict,
    const label index,
    const faceZoneMesh& zm
)
:
230
    zone(name, dict, this->labelsName, index),
231
232
233
234
235
    flipMap_(dict.lookup("flipMap")),
    zoneMesh_(zm),
    patchPtr_(NULL),
    masterCellsPtr_(NULL),
    slaveCellsPtr_(NULL),
236
    mePtr_(NULL)
237
238
239
240
241
242
243
244
245
246
247
248
249
250
{
    checkAddressing();
}


Foam::faceZone::faceZone
(
    const faceZone& fz,
    const labelList& addr,
    const boolList& fm,
    const label index,
    const faceZoneMesh& zm
)
:
251
    zone(fz, addr, index),
252
253
254
255
256
    flipMap_(fm),
    zoneMesh_(zm),
    patchPtr_(NULL),
    masterCellsPtr_(NULL),
    slaveCellsPtr_(NULL),
257
    mePtr_(NULL)
258
259
260
261
262
{
    checkAddressing();
}


263
264
265
Foam::faceZone::faceZone
(
    const faceZone& fz,
Mark Olesen's avatar
Mark Olesen committed
266
267
    const Xfer<labelList>& addr,
    const Xfer<boolList>& fm,
268
269
270
271
    const label index,
    const faceZoneMesh& zm
)
:
272
    zone(fz, addr, index),
273
274
275
276
277
    flipMap_(fm),
    zoneMesh_(zm),
    patchPtr_(NULL),
    masterCellsPtr_(NULL),
    slaveCellsPtr_(NULL),
278
    mePtr_(NULL)
279
280
281
282
283
{
    checkAddressing();
}


284
285
286
287
288
289
290
291
292
293
// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::faceZone::~faceZone()
{
    clearAddressing();
}


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

294
const Foam::faceZoneMesh& Foam::faceZone::zoneMesh() const
295
{
296
    return zoneMesh_;
297
298
299
}


300
Foam::label Foam::faceZone::whichFace(const label globalFaceID) const
301
{
302
    return zone::localID(globalFaceID);
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
}


const Foam::primitiveFacePatch& Foam::faceZone::operator()() const
{
    if (!patchPtr_)
    {
        calcFaceZonePatch();
    }

    return *patchPtr_;
}


const Foam::labelList& Foam::faceZone::masterCells() const
{
    if (!masterCellsPtr_)
    {
        calcCellLayers();
    }

    return *masterCellsPtr_;
}


const Foam::labelList& Foam::faceZone::slaveCells() const
{
    if (!slaveCellsPtr_)
    {
        calcCellLayers();
    }

    return *slaveCellsPtr_;
}


const Foam::labelList& Foam::faceZone::meshEdges() const
{
    if (!mePtr_)
    {
mattijs's avatar
mattijs committed
343
344
345
346
347
348
        //labelList faceCells(size());
        //
        //const labelList& own = zoneMesh().mesh().faceOwner();
        //
        //const labelList& faceLabels = *this;
        //
349
        //forAll(faceCells, faceI)
mattijs's avatar
mattijs committed
350
351
352
353
354
355
356
357
358
359
360
361
362
363
        //{
        //    faceCells[faceI] = own[faceLabels[faceI]];
        //}
        //
        //mePtr_ =
        //    new labelList
        //    (
        //        operator()().meshEdges
        //        (
        //            zoneMesh().mesh().edges(),
        //            zoneMesh().mesh().cellEdges(),
        //            faceCells
        //        )
        //    );
364
365
366
367
368
369
370

        mePtr_ =
            new labelList
            (
                operator()().meshEdges
                (
                    zoneMesh().mesh().edges(),
mattijs's avatar
mattijs committed
371
                    zoneMesh().mesh().pointEdges()
372
373
374
375
376
377
378
379
380
381
                )
            );
    }

    return *mePtr_;
}


void Foam::faceZone::clearAddressing()
{
382
383
    zone::clearAddressing();

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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
    deleteDemandDrivenData(patchPtr_);

    deleteDemandDrivenData(masterCellsPtr_);
    deleteDemandDrivenData(slaveCellsPtr_);

    deleteDemandDrivenData(mePtr_);
}


void Foam::faceZone::resetAddressing
(
    const labelList& addr,
    const boolList& flipMap
)
{
    clearAddressing();
    labelList::operator=(addr);
    flipMap_ = flipMap;
}


void Foam::faceZone::updateMesh(const mapPolyMesh& mpm)
{
    clearAddressing();

    labelList newAddressing(size());
    boolList newFlipMap(flipMap_.size());
    label nFaces = 0;

    const labelList& faceMap = mpm.reverseFaceMap();

    forAll(*this, i)
    {
        label faceI = operator[](i);

        if (faceMap[faceI] >= 0)
        {
            newAddressing[nFaces] = faceMap[faceI];
            newFlipMap[nFaces] = flipMap_[i];       // Keep flip map.
            nFaces++;
        }
    }

    newAddressing.setSize(nFaces);
    newFlipMap.setSize(nFaces);

    transfer(newAddressing);
    flipMap_.transfer(newFlipMap);
}


bool Foam::faceZone::checkDefinition(const bool report) const
{
437
    return zone::checkDefinition(zoneMesh().mesh().faces().size(), report);
438
439
440
}


mattijs's avatar
mattijs committed
441
442
443
444
445
bool Foam::faceZone::checkParallelSync(const bool report) const
{
    const polyMesh& mesh = zoneMesh().mesh();
    const polyBoundaryMesh& bm = mesh.boundaryMesh();

446
    bool hasError = false;
mattijs's avatar
mattijs committed
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465


    // Check that zone faces are synced
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    {
        boolList neiZoneFace(mesh.nFaces()-mesh.nInternalFaces(), false);
        boolList neiZoneFlip(mesh.nFaces()-mesh.nInternalFaces(), false);
        forAll(*this, i)
        {
            label faceI = operator[](i);

            if (!mesh.isInternalFace(faceI))
            {
                neiZoneFace[faceI-mesh.nInternalFaces()] = true;
                neiZoneFlip[faceI-mesh.nInternalFaces()] = flipMap()[i];
            }
        }
        boolList myZoneFace(neiZoneFace);
466
        syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
mattijs's avatar
mattijs committed
467
        boolList myZoneFlip(neiZoneFlip);
468
        syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
mattijs's avatar
mattijs committed
469
470
471
472
473
474
475
476
477
478
479
480
481
482

        forAll(*this, i)
        {
            label faceI = operator[](i);

            label patchI = bm.whichPatch(faceI);

            if (patchI != -1 && bm[patchI].coupled())
            {
                label bFaceI = faceI-mesh.nInternalFaces();

                // Check face in zone on both sides
                if (myZoneFace[bFaceI] != neiZoneFace[bFaceI])
                {
483
                    hasError = true;
mattijs's avatar
mattijs committed
484
485
486
487
488
489
490
491
492
493
494

                    if (report)
                    {
                        Pout<< " ***Problem with faceZone " << index()
                            << " named " << name()
                            << ". Face " << faceI
                            << " on coupled patch "
                            << bm[patchI].name()
                            << " is not consistent with its coupled neighbour."
                            << endl;
                    }
495
496
497
498
499
                    else
                    {
                        // w/o report - can stop checking now
                        break;
                    }
mattijs's avatar
mattijs committed
500
                }
501
                else if (myZoneFlip[bFaceI] == neiZoneFlip[bFaceI])
mattijs's avatar
mattijs committed
502
                {
503
                    // Flip state should be opposite.
504
                    hasError = true;
mattijs's avatar
mattijs committed
505
506
507
508
509
510
511
512
513
514
515
516

                    if (report)
                    {
                        Pout<< " ***Problem with faceZone " << index()
                            << " named " << name()
                            << ". Face " << faceI
                            << " on coupled patch "
                            << bm[patchI].name()
                            << " does not have consistent flipMap"
                            << " across coupled faces."
                            << endl;
                    }
517
518
519
520
521
                    else
                    {
                        // w/o report - can stop checking now
                        break;
                    }
mattijs's avatar
mattijs committed
522
523
524
525
526
                }
            }
        }
    }

527
    return returnReduce(hasError, orOp<bool>());
mattijs's avatar
mattijs committed
528
529
530
}


531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
void Foam::faceZone::movePoints(const pointField& p)
{
    if (patchPtr_)
    {
        patchPtr_->movePoints(p);
    }
}

void Foam::faceZone::write(Ostream& os) const
{
    os  << nl << name()
        << nl << static_cast<const labelList&>(*this)
        << nl << flipMap();
}


void Foam::faceZone::writeDict(Ostream& os) const
{
    os  << nl << name() << nl << token::BEGIN_BLOCK << nl
        << "    type " << type() << token::END_STATEMENT << nl;

552
    writeEntry(this->labelsName, os);
553
554
555
556
557
558
559
560
    flipMap().writeEntry("flipMap", os);

    os  << token::END_BLOCK << endl;
}


// * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //

561
Foam::Ostream& Foam::operator<<(Ostream& os, const faceZone& zn)
562
{
563
564
    zn.write(os);
    os.check("Ostream& operator<<(Ostream&, const faceZone&");
565
566
567
568
569
    return os;
}


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