1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 A subset of mesh faces.
27 \*---------------------------------------------------------------------------*/
30 #include "addToRunTimeSelectionTable.H"
31 #include "faceZoneMesh.H"
33 #include "primitiveMesh.H"
34 #include "demandDrivenData.H"
35 #include "mapPolyMesh.H"
36 #include "syncTools.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(faceZone, 0);
43 defineRunTimeSelectionTable(faceZone, dictionary);
44 addToRunTimeSelectionTable(faceZone, faceZone, dictionary);
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
49 void Foam::faceZone::calcFaceZonePatch() const
53 Info<< "void faceZone::calcFaceZonePatch() const : "
54 << "Calculating primitive patch"
62 "void faceZone::calcFaceZonePatch() const"
63 ) << "primitive face zone patch already calculated"
68 new primitiveFacePatch
71 zoneMesh().mesh().allPoints()
74 primitiveFacePatch& patch = *patchPtr_;
76 const faceList& f = zoneMesh().mesh().allFaces();
78 const labelList& addr = *this;
79 const boolList& flip = flipMap();
85 patch[faceI] = f[addr[faceI]].reverseFace();
89 patch[faceI] = f[addr[faceI]];
95 Info<< "void faceZone::calcFaceZonePatch() const : "
96 << "Finished calculating primitive patch"
102 const Foam::Map<Foam::label>& Foam::faceZone::faceLookupMap() const
104 if (!faceLookupMapPtr_)
109 return *faceLookupMapPtr_;
113 void Foam::faceZone::calcFaceLookupMap() const
117 Info<< "void faceZone::calcFaceLookupMap() const : "
118 << "Calculating face lookup map"
122 if (faceLookupMapPtr_)
126 "void faceZone::calcFaceLookupMap() const"
127 ) << "face lookup map already calculated"
128 << abort(FatalError);
131 const labelList& addr = *this;
133 faceLookupMapPtr_ = new Map<label>(2*addr.size());
134 Map<label>& flm = *faceLookupMapPtr_;
138 flm.insert(addr[faceI], faceI);
143 Info<< "void faceZone::calcFaceLookupMap() const : "
144 << "Finished calculating face lookup map"
150 void Foam::faceZone::calcCellLayers() const
154 Info<< "void Foam::faceZone::calcCellLayers() const : "
155 << "calculating master cells"
159 // It is an error to attempt to recalculate edgeCells
160 // if the pointer is already set
161 if (masterCellsPtr_ || slaveCellsPtr_)
163 FatalErrorIn("void faceZone::calcCellLayers() const")
164 << "cell layers already calculated"
165 << abort(FatalError);
169 // Go through all the faces in the master zone. Choose the
170 // master or slave cell based on the face flip
171 const polyMesh& mesh = zoneMesh().mesh();
173 const labelList& own = mesh.faceOwner();
174 const labelList& nei = mesh.faceNeighbour();
176 const labelList& mf = *this;
178 const boolList& faceFlip = flipMap();
180 masterCellsPtr_ = new labelList(mf.size());
181 labelList& mc = *masterCellsPtr_;
183 slaveCellsPtr_ = new labelList(mf.size());
184 labelList& sc = *slaveCellsPtr_;
191 if (!faceFlip[faceI])
193 // Face is oriented correctly, no flip needed
194 // Master is the neighbour, with normal pointing into it
195 // Bug fix, HJ, 7/Mar/2011
196 if (mesh.isInternalFace(mf[faceI]))
198 curMc = nei[mf[faceI]];
199 curSc = own[mf[faceI]];
201 else if (mf[faceI] < mesh.nFaces())
204 curSc = own[mf[faceI]];
210 // Master is the owner, with normal pointing into it
211 // Bug fix, HJ, 7/Mar/2011
212 if (mesh.isInternalFace(mf[faceI]))
214 curMc = own[mf[faceI]];
215 curSc = nei[mf[faceI]];
217 else if (mf[faceI] < mesh.nFaces())
219 curMc = own[mf[faceI]];
232 void Foam::faceZone::checkAddressing() const
234 if (size() != flipMap_.size())
236 FatalErrorIn("void Foam::faceZone::checkAddressing() const")
237 << "Different sizes of the addressing and flipMap arrays. "
238 << "Size of addressing: " << size()
239 << " size of flip map: " << flipMap_.size()
240 << abort(FatalError);
245 void Foam::faceZone::clearAddressing()
247 deleteDemandDrivenData(patchPtr_);
249 deleteDemandDrivenData(masterCellsPtr_);
250 deleteDemandDrivenData(slaveCellsPtr_);
252 deleteDemandDrivenData(mePtr_);
253 deleteDemandDrivenData(faceLookupMapPtr_);
257 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
259 // Construct from components
260 Foam::faceZone::faceZone
263 const labelList& addr,
266 const faceZoneMesh& zm
275 masterCellsPtr_(NULL),
276 slaveCellsPtr_(NULL),
278 faceLookupMapPtr_(NULL)
284 Foam::faceZone::faceZone
287 const Xfer<labelList>& addr,
288 const Xfer<boolList>& fm,
290 const faceZoneMesh& zm
299 masterCellsPtr_(NULL),
300 slaveCellsPtr_(NULL),
302 faceLookupMapPtr_(NULL)
308 // Construct from dictionary
309 Foam::faceZone::faceZone
312 const dictionary& dict,
314 const faceZoneMesh& zm
317 labelList(dict.lookup("faceLabels")),
319 flipMap_(dict.lookup("flipMap")),
323 masterCellsPtr_(NULL),
324 slaveCellsPtr_(NULL),
326 faceLookupMapPtr_(NULL)
332 // Construct given the original zone and resetting the
333 // face list and zone mesh information
334 Foam::faceZone::faceZone
337 const labelList& addr,
340 const faceZoneMesh& zm
349 masterCellsPtr_(NULL),
350 slaveCellsPtr_(NULL),
352 faceLookupMapPtr_(NULL)
358 Foam::faceZone::faceZone
361 const Xfer<labelList>& addr,
362 const Xfer<boolList>& fm,
364 const faceZoneMesh& zm
373 masterCellsPtr_(NULL),
374 slaveCellsPtr_(NULL),
376 faceLookupMapPtr_(NULL)
382 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
384 Foam::faceZone::~faceZone()
390 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
392 Foam::label Foam::faceZone::whichFace(const label globalFaceID) const
394 const Map<label>& flm = faceLookupMap();
396 Map<label>::const_iterator flmIter = flm.find(globalFaceID);
398 if (flmIter == flm.end())
409 const Foam::faceZoneMesh& Foam::faceZone::zoneMesh() const
415 const Foam::primitiveFacePatch& Foam::faceZone::operator()() const
426 const Foam::labelList& Foam::faceZone::masterCells() const
428 if (!masterCellsPtr_)
433 return *masterCellsPtr_;
437 const Foam::labelList& Foam::faceZone::slaveCells() const
444 return *slaveCellsPtr_;
448 const Foam::labelList& Foam::faceZone::meshEdges() const
452 // Old form. Under testing: merge, HJ, 17/Aug/2010
453 //labelList faceCells(size());
455 //const labelList& own = zoneMesh().mesh().faceOwner();
457 //const labelList& faceLabels = *this;
459 //forAll (faceCells, faceI)
461 // faceCells[faceI] = own[faceLabels[faceI]];
467 // operator()().meshEdges
469 // zoneMesh().mesh().edges(),
470 // zoneMesh().mesh().cellEdges(),
478 operator()().meshEdges
480 zoneMesh().mesh().edges(),
481 zoneMesh().mesh().pointEdges()
490 void Foam::faceZone::resetAddressing
492 const labelList& addr,
493 const boolList& flipMap
497 labelList::operator=(addr);
502 void Foam::faceZone::updateMesh()
508 bool Foam::faceZone::checkDefinition(const bool report) const
510 const labelList& addr = *this;
512 bool boundaryError = false;
516 if (addr[i] < 0 || addr[i] >= zoneMesh().mesh().allFaces().size())
518 boundaryError = true;
524 "bool faceZone::checkDefinition("
525 "const bool report) const"
526 ) << "Zone " << name()
527 << " contains invalid face label " << addr[i] << nl
528 << "Valid face labels are 0.."
529 << zoneMesh().mesh().allFaces().size() - 1 << endl;
533 return boundaryError;
537 bool Foam::faceZone::checkParallelSync(const bool report) const
539 const polyMesh& mesh = zoneMesh().mesh();
540 const polyBoundaryMesh& bm = mesh.boundaryMesh();
542 bool boundaryError = false;
545 // Check that zone faces are synced
546 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
549 boolList neiZoneFace(mesh.nFaces() - mesh.nInternalFaces(), false);
550 boolList neiZoneFlip(mesh.nFaces() - mesh.nInternalFaces(), false);
554 label faceI = operator[](i);
556 // Only check live faces
557 if (faceI < mesh.nFaces())
559 if (!mesh.isInternalFace(faceI))
561 neiZoneFace[faceI - mesh.nInternalFaces()] = true;
562 neiZoneFlip[faceI - mesh.nInternalFaces()] = flipMap()[i];
567 boolList myZoneFace(neiZoneFace);
568 syncTools::swapBoundaryFaceList(mesh, neiZoneFace, false);
569 boolList myZoneFlip(neiZoneFlip);
570 syncTools::swapBoundaryFaceList(mesh, neiZoneFlip, false);
574 label faceI = operator[](i);
576 // Only check live faces
577 if (faceI < mesh.nFaces())
579 label patchI = bm.whichPatch(faceI);
581 if (patchI != -1 && isA<cyclicPolyPatch>(bm[patchI]))
583 label bFaceI = faceI-mesh.nInternalFaces();
585 // Check face in zone on both sides
586 if (myZoneFace[bFaceI] != neiZoneFace[bFaceI])
588 boundaryError = true;
592 Pout<< " ***Problem with faceZone " << index()
593 << " named " << name()
594 << ". Face " << faceI
595 << " on coupled patch "
597 << " is not consistent with its "
598 << "coupled neighbour."
603 // Flip state should be opposite.
604 if (myZoneFlip[bFaceI] == neiZoneFlip[bFaceI])
606 boundaryError = true;
610 Pout<< " ***Problem with faceZone " << index()
611 << " named " << name()
612 << ". Face " << faceI
613 << " on coupled patch "
615 << " does not have consistent flipMap"
616 << " across coupled faces."
625 return returnReduce(boundaryError, orOp<bool>());
629 void Foam::faceZone::movePoints(const pointField& p)
633 patchPtr_->movePoints(p);
637 void Foam::faceZone::write(Ostream& os) const
640 << nl << static_cast<const labelList&>(*this)
645 void Foam::faceZone::writeDict(Ostream& os) const
647 os << nl << name() << nl << token::BEGIN_BLOCK << incrIndent << nl
648 << indent << "type " << type() << token::END_STATEMENT << nl;
650 writeEntry("faceLabels", os);
651 flipMap().writeEntry("flipMap", os);
653 os << decrIndent << token::END_BLOCK << endl;
657 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
659 Foam::Ostream& Foam::operator<<(Ostream& os, const faceZone& p)
662 os.check("Ostream& operator<<(Ostream& f, const faceZone& p");
667 // ************************************************************************* //