Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / meshes / polyMesh / zones / faceZone / faceZone.C
blob4a930df112af39cc0241011879aeec5ff9ec3579
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "faceZone.H"
27 #include "addToRunTimeSelectionTable.H"
28 #include "faceZoneMesh.H"
29 #include "polyMesh.H"
30 #include "primitiveMesh.H"
31 #include "demandDrivenData.H"
32 #include "mapPolyMesh.H"
33 #include "syncTools.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 namespace Foam
39     defineTypeNameAndDebug(faceZone, 0);
40     defineRunTimeSelectionTable(faceZone, dictionary);
41     addToRunTimeSelectionTable(faceZone, faceZone, dictionary);
44 const char* const Foam::faceZone::labelsName = "faceLabels";
46 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
48 void Foam::faceZone::calcFaceZonePatch() const
50     if (debug)
51     {
52         Info<< "void faceZone::calcFaceZonePatch() const : "
53             << "Calculating primitive patch"
54             << endl;
55     }
57     if (patchPtr_)
58     {
59         FatalErrorIn
60         (
61             "void faceZone::calcFaceZonePatch() const"
62         )   << "primitive face zone patch already calculated"
63             << abort(FatalError);
64     }
66     patchPtr_ =
67         new primitiveFacePatch
68         (
69             faceList(size()),
70             zoneMesh().mesh().points()
71         );
73     primitiveFacePatch& patch = *patchPtr_;
75     const faceList& f = zoneMesh().mesh().faces();
77     const labelList& addr = *this;
78     const boolList& flip = flipMap();
80     forAll(addr, faceI)
81     {
82         if (flip[faceI])
83         {
84             patch[faceI] = f[addr[faceI]].reverseFace();
85         }
86         else
87         {
88             patch[faceI] = f[addr[faceI]];
89         }
90     }
92     if (debug)
93     {
94         Info<< "void faceZone::calcFaceZonePatch() const : "
95             << "Finished calculating primitive patch"
96             << endl;
97     }
101 void Foam::faceZone::calcCellLayers() const
103     if (debug)
104     {
105         Info<< "void Foam::faceZone::calcCellLayers() const : "
106             << "calculating master cells"
107             << endl;
108     }
110     // It is an error to attempt to recalculate edgeCells
111     // if the pointer is already set
112     if (masterCellsPtr_ || slaveCellsPtr_)
113     {
114         FatalErrorIn("void faceZone::calcCellLayers() const")
115             << "cell layers already calculated"
116             << abort(FatalError);
117     }
118     else
119     {
120         // Go through all the faces in the master zone.  Choose the
121         // master or slave cell based on the face flip
123         const labelList& own = zoneMesh().mesh().faceOwner();
124         const labelList& nei = zoneMesh().mesh().faceNeighbour();
126         const labelList& mf = *this;
128         const boolList& faceFlip = flipMap();
130         masterCellsPtr_ = new labelList(mf.size());
131         labelList& mc = *masterCellsPtr_;
133         slaveCellsPtr_ = new labelList(mf.size());
134         labelList& sc = *slaveCellsPtr_;
136         forAll(mf, faceI)
137         {
138             label ownCellI = own[mf[faceI]];
139             label neiCellI =
140             (
141                 zoneMesh().mesh().isInternalFace(mf[faceI])
142               ? nei[mf[faceI]]
143               : -1
144             );
146             if (!faceFlip[faceI])
147             {
148                 // Face is oriented correctly, no flip needed
149                 mc[faceI] = neiCellI;
150                 sc[faceI] = ownCellI;
151             }
152             else
153             {
154                 mc[faceI] = ownCellI;
155                 sc[faceI] = neiCellI;
156             }
157         }
158         //Info<< "masterCells: " << mc << endl;
159         //Info<< "slaveCells: " << sc << endl;
160     }
164 void Foam::faceZone::checkAddressing() const
166     if (size() != flipMap_.size())
167     {
168         FatalErrorIn("void Foam::faceZone::checkAddressing() const")
169             << "Different sizes of the addressing and flipMap arrays.  "
170             << "Size of addressing: " << size()
171             << " size of flip map: " << flipMap_.size()
172             << abort(FatalError);
173     }
177 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
179 // Construct from components
180 Foam::faceZone::faceZone
182     const word& name,
183     const labelUList& addr,
184     const boolList& fm,
185     const label index,
186     const faceZoneMesh& zm
189     zone(name, addr, index),
190     flipMap_(fm),
191     zoneMesh_(zm),
192     patchPtr_(NULL),
193     masterCellsPtr_(NULL),
194     slaveCellsPtr_(NULL),
195     mePtr_(NULL)
197     checkAddressing();
201 Foam::faceZone::faceZone
203     const word& name,
204     const Xfer<labelList>& addr,
205     const Xfer<boolList>& fm,
206     const label index,
207     const faceZoneMesh& zm
210     zone(name, addr, index),
211     flipMap_(fm),
212     zoneMesh_(zm),
213     patchPtr_(NULL),
214     masterCellsPtr_(NULL),
215     slaveCellsPtr_(NULL),
216     mePtr_(NULL)
218     checkAddressing();
222 Foam::faceZone::faceZone
224     const word& name,
225     const dictionary& dict,
226     const label index,
227     const faceZoneMesh& zm
230     zone(name, dict, this->labelsName, index),
231     flipMap_(dict.lookup("flipMap")),
232     zoneMesh_(zm),
233     patchPtr_(NULL),
234     masterCellsPtr_(NULL),
235     slaveCellsPtr_(NULL),
236     mePtr_(NULL)
238     checkAddressing();
242 Foam::faceZone::faceZone
244     const faceZone& fz,
245     const labelUList& addr,
246     const boolList& fm,
247     const label index,
248     const faceZoneMesh& zm
251     zone(fz, addr, index),
252     flipMap_(fm),
253     zoneMesh_(zm),
254     patchPtr_(NULL),
255     masterCellsPtr_(NULL),
256     slaveCellsPtr_(NULL),
257     mePtr_(NULL)
259     checkAddressing();
263 Foam::faceZone::faceZone
265     const faceZone& fz,
266     const Xfer<labelList>& addr,
267     const Xfer<boolList>& fm,
268     const label index,
269     const faceZoneMesh& zm
272     zone(fz, addr, index),
273     flipMap_(fm),
274     zoneMesh_(zm),
275     patchPtr_(NULL),
276     masterCellsPtr_(NULL),
277     slaveCellsPtr_(NULL),
278     mePtr_(NULL)
280     checkAddressing();
284 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
286 Foam::faceZone::~faceZone()
288     clearAddressing();
292 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
294 const Foam::faceZoneMesh& Foam::faceZone::zoneMesh() const
296     return zoneMesh_;
300 Foam::label Foam::faceZone::whichFace(const label globalFaceID) const
302     return zone::localID(globalFaceID);
306 const Foam::primitiveFacePatch& Foam::faceZone::operator()() const
308     if (!patchPtr_)
309     {
310         calcFaceZonePatch();
311     }
313     return *patchPtr_;
317 const Foam::labelList& Foam::faceZone::masterCells() const
319     if (!masterCellsPtr_)
320     {
321         calcCellLayers();
322     }
324     return *masterCellsPtr_;
328 const Foam::labelList& Foam::faceZone::slaveCells() const
330     if (!slaveCellsPtr_)
331     {
332         calcCellLayers();
333     }
335     return *slaveCellsPtr_;
339 const Foam::labelList& Foam::faceZone::meshEdges() const
341     if (!mePtr_)
342     {
343         //labelList faceCells(size());
344         //
345         //const labelList& own = zoneMesh().mesh().faceOwner();
346         //
347         //const labelList& faceLabels = *this;
348         //
349         //forAll(faceCells, faceI)
350         //{
351         //    faceCells[faceI] = own[faceLabels[faceI]];
352         //}
353         //
354         //mePtr_ =
355         //    new labelList
356         //    (
357         //        operator()().meshEdges
358         //        (
359         //            zoneMesh().mesh().edges(),
360         //            zoneMesh().mesh().cellEdges(),
361         //            faceCells
362         //        )
363         //    );
365         mePtr_ =
366             new labelList
367             (
368                 operator()().meshEdges
369                 (
370                     zoneMesh().mesh().edges(),
371                     zoneMesh().mesh().pointEdges()
372                 )
373             );
374     }
376     return *mePtr_;
380 void Foam::faceZone::clearAddressing()
382     zone::clearAddressing();
384     deleteDemandDrivenData(patchPtr_);
386     deleteDemandDrivenData(masterCellsPtr_);
387     deleteDemandDrivenData(slaveCellsPtr_);
389     deleteDemandDrivenData(mePtr_);
393 void Foam::faceZone::resetAddressing
395     const labelUList& addr,
396     const boolList& flipMap
399     clearAddressing();
400     labelList::operator=(addr);
401     flipMap_ = flipMap;
405 void Foam::faceZone::updateMesh(const mapPolyMesh& mpm)
407     clearAddressing();
409     labelList newAddressing(size());
410     boolList newFlipMap(flipMap_.size());
411     label nFaces = 0;
413     const labelList& faceMap = mpm.reverseFaceMap();
415     forAll(*this, i)
416     {
417         const label faceI = operator[](i);
419         if (faceMap[faceI] >= 0)
420         {
421             newAddressing[nFaces] = faceMap[faceI];
422             newFlipMap[nFaces] = flipMap_[i];       // Keep flip map.
423             nFaces++;
424         }
425     }
427     newAddressing.setSize(nFaces);
428     newFlipMap.setSize(nFaces);
430     transfer(newAddressing);
431     flipMap_.transfer(newFlipMap);
435 bool Foam::faceZone::checkDefinition(const bool report) const
437     return zone::checkDefinition(zoneMesh().mesh().faces().size(), report);
441 bool Foam::faceZone::checkParallelSync(const bool report) const
443     const polyMesh& mesh = zoneMesh().mesh();
444     const polyBoundaryMesh& bm = mesh.boundaryMesh();
446     bool hasError = false;
449     // Check that zone faces are synced
450     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
452     {
453         boolList neiZoneFace(mesh.nFaces()-mesh.nInternalFaces(), false);
454         boolList neiZoneFlip(mesh.nFaces()-mesh.nInternalFaces(), false);
455         forAll(*this, i)
456         {
457             const label faceI = operator[](i);
459             if (!mesh.isInternalFace(faceI))
460             {
461                 neiZoneFace[faceI-mesh.nInternalFaces()] = true;
462                 neiZoneFlip[faceI-mesh.nInternalFaces()] = flipMap()[i];
463             }
464         }
465         boolList myZoneFace(neiZoneFace);
466         syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
467         boolList myZoneFlip(neiZoneFlip);
468         syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
470         forAll(*this, i)
471         {
472             const label faceI = operator[](i);
473             const label patchI = bm.whichPatch(faceI);
475             if (patchI != -1 && bm[patchI].coupled())
476             {
477                 const label bFaceI = faceI-mesh.nInternalFaces();
479                 // Check face in zone on both sides
480                 if (myZoneFace[bFaceI] != neiZoneFace[bFaceI])
481                 {
482                     hasError = true;
484                     if (report)
485                     {
486                         Pout<< " ***Problem with faceZone " << index()
487                             << " named " << name()
488                             << ". Face " << faceI
489                             << " on coupled patch "
490                             << bm[patchI].name()
491                             << " is not consistent with its coupled neighbour."
492                             << endl;
493                     }
494                     else
495                     {
496                         // w/o report - can stop checking now
497                         break;
498                     }
499                 }
500                 else if (myZoneFlip[bFaceI] == neiZoneFlip[bFaceI])
501                 {
502                     // Flip state should be opposite.
503                     hasError = true;
505                     if (report)
506                     {
507                         Pout<< " ***Problem with faceZone " << index()
508                             << " named " << name()
509                             << ". Face " << faceI
510                             << " on coupled patch "
511                             << bm[patchI].name()
512                             << " does not have consistent flipMap"
513                             << " across coupled faces."
514                             << endl;
515                     }
516                     else
517                     {
518                         // w/o report - can stop checking now
519                         break;
520                     }
521                 }
522             }
523         }
524     }
526     return returnReduce(hasError, orOp<bool>());
530 void Foam::faceZone::movePoints(const pointField& p)
532     if (patchPtr_)
533     {
534         patchPtr_->movePoints(p);
535     }
538 void Foam::faceZone::write(Ostream& os) const
540     os  << nl << name()
541         << nl << static_cast<const labelList&>(*this)
542         << nl << flipMap();
546 void Foam::faceZone::writeDict(Ostream& os) const
548     os  << nl << name() << nl << token::BEGIN_BLOCK << nl
549         << "    type " << type() << token::END_STATEMENT << nl;
551     writeEntry(this->labelsName, os);
552     flipMap().writeEntry("flipMap", os);
554     os  << token::END_BLOCK << endl;
558 // * * * * * * * * * * * * * * * Ostream Operator  * * * * * * * * * * * * * //
560 Foam::Ostream& Foam::operator<<(Ostream& os, const faceZone& zn)
562     zn.write(os);
563     os.check("Ostream& operator<<(Ostream&, const faceZone&");
564     return os;
568 // ************************************************************************* //