Loading...
Searching...
No Matches
faceZone.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2017-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "faceZone.H"
30#include "faceZoneMesh.H"
31#include "polyMesh.H"
32#include "mapPolyMesh.H"
33#include "syncTools.H"
36// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37
38namespace Foam
39{
43}
44
45
46// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47
48void Foam::faceZone::setFlipMap(const bool val)
49{
50 // Match size for flipMap
51 flipMap_.resize_nocopy(this->size());
52 flipMap_ = val;
53}
54
55
56// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
57
58void Foam::faceZone::calcFaceZonePatch() const
59{
60 DebugInFunction << "Calculating primitive patch" << endl;
61
62 if (patchPtr_)
63 {
65 << "primitive face zone patch already calculated"
66 << abort(FatalError);
67 }
68
69 patchPtr_.reset
70 (
72 (
73 faceList(size()),
74 zoneMesh().mesh().points()
75 )
76 );
77 auto& patch = *patchPtr_;
78
79 const faceList& f = zoneMesh().mesh().faces();
80
81 const labelList& addr = *this;
82 const boolList& flips = flipMap();
83
84 forAll(addr, facei)
85 {
86 if (flips[facei])
87 {
88 patch[facei] = f[addr[facei]].reverseFace();
89 }
90 else
91 {
92 patch[facei] = f[addr[facei]];
93 }
94 }
95
96 DebugInfo << "Finished calculating primitive patch" << endl;
97}
98
99
100void Foam::faceZone::calcCellLayers() const
101{
102 DebugInFunction << "Calculating cell layers" << endl;
103
104 if (frontCellsPtr_ || backCellsPtr_)
105 {
107 << "cell layers already calculated"
108 << abort(FatalError);
109 }
110 else
111 {
112 // Go through all the faces in the zone.
113 // Choose the front/back cell based on the face flip
114
115 const labelList& own = zoneMesh().mesh().faceOwner();
116 const labelList& nei = zoneMesh().mesh().faceNeighbour();
117
118 const labelList& addr = *this;
119 const boolList& flips = flipMap();
120
121 frontCellsPtr_.reset(new labelList(addr.size()));
122 backCellsPtr_.reset(new labelList(addr.size()));
123
124 auto& fronts = *frontCellsPtr_;
125 auto& backs = *backCellsPtr_;
126
127 forAll(addr, facei)
128 {
129 const label ownCelli = own[addr[facei]];
130 const label neiCelli =
131 (
132 zoneMesh().mesh().isInternalFace(addr[facei])
133 ? nei[addr[facei]]
134 : -1
135 );
136
137 if (flips[facei])
138 {
139 fronts[facei] = ownCelli;
140 backs[facei] = neiCelli;
141 }
142 else
143 {
144 fronts[facei] = neiCelli;
145 backs[facei] = ownCelli;
146 }
147 }
148 }
149}
150
151
152// Foam::label Foam::faceZone::getLayerCell
153// (
154// const side which,
155// const label i
156// ) const
157// {
158// const label facei = labelList::operator[](i);
159// const bool flipped = flipMap_[i];
160//
161// if (which == side::FRONT ? flipped : !flipped)
162// {
163// return zoneMesh().mesh().faceOwner()[facei];
164// }
165// else if (zoneMesh().mesh().isInternalFace(facei))
166// {
167// return zoneMesh().mesh().faceNeighbour()[facei];
168// }
169// else
170// {
171// return -1;
172// }
173// }
174//
175//
176// Foam::label Foam::faceZone::frontCell(const label i) const
177// {
178// return getLayerCell(side::FRONT, i);
179// }
180//
181//
182// Foam::label Foam::faceZone::backCell(const label i) const
183// {
184// return getLayerCell(side::BACK, i);
185// }
186
187
188void Foam::faceZone::checkAddressing() const
189{
190 const labelList& addr = *this;
191
192 if (addr.size() != flipMap_.size())
193 {
195 << "Size of addressing: " << addr.size()
196 << " size of flip map: " << flipMap_.size()
197 << abort(FatalError);
198 }
199
200 // Note: nFaces, nCells might not be set yet on mesh so use owner size
201 const label nFaces = zoneMesh().mesh().faceOwner().size();
202
203 for (const label facei : addr)
204 {
205 if (facei < 0 || facei >= nFaces)
206 {
208 << "Illegal face index " << facei
209 << " outside range 0.." << nFaces-1 << endl;
210 break; // Only report once
212 }
213}
214
215
216// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
217
219:
220 zone(),
221 zoneMesh_(zm)
222{}
223
224
226(
227 const word& name,
228 const label index,
229 const faceZoneMesh& zm
231:
232 zone(name, index),
233 zoneMesh_(zm)
234{}
235
236
238(
239 const word& name,
240 const labelUList& addr,
241 const bool flipMapValue,
242 const label index,
243 const faceZoneMesh& zm
244)
245:
246 faceZone(name, index, zm)
247{
249 flipMap_.resize(labelList::size(), flipMapValue);
250
251 checkAddressing();
252}
253
254
256(
257 const word& name,
258 labelList&& addr,
259 const bool flipMapValue,
260 const label index,
261 const faceZoneMesh& zm
262)
263:
264 faceZone(name, index, zm)
267 flipMap_.resize(labelList::size(), flipMapValue);
268 checkAddressing();
269}
270
271
273(
274 const word& name,
275 const labelUList& addr,
276 const boolUList& fm,
277 const label index,
278 const faceZoneMesh& zm
279)
280:
281 faceZone(name, index, zm)
282{
284 flipMap_ = fm;
285
286 // TBD
287 // if (flipMap_.empty())
288 // {
289 // // An empty flipMap is treated like 'false' instead of as an error
290 // flipMap_.resize(labelList::size(), false);
291 // }
292
293 checkAddressing();
294}
295
296
298(
299 const word& name,
300 labelList&& addr,
301 boolList&& fm,
302 const label index,
303 const faceZoneMesh& zm
304)
305:
306 faceZone(name, index, zm)
307{
309 flipMap_.transfer(fm);
310
311 // TBD
312 // if (flipMap_.empty())
313 // {
314 // // An empty flipMap is treated like 'false' instead of as an error
315 // flipMap_.resize(labelList::size(), false);
316 // }
317
318 checkAddressing();
319}
320
321
323(
324 const word& name,
325 const dictionary& dict,
326 const label index,
327 const faceZoneMesh& zm
328)
329:
330 zone(name, dict, faceZone::labelsName(), index),
331 zoneMesh_(zm)
332{
333 dict.readEntry("flipMap", flipMap_, keyType::LITERAL);
334 checkAddressing();
335}
336
337
339(
340 const faceZone& originalZone,
341 const faceZoneMesh& zm,
342 const label newIndex
343)
344:
345 zone(originalZone, newIndex),
346 zoneMesh_(zm)
347{
348 flipMap_ = originalZone.flipMap();
349}
350
351
353(
354 const faceZone& originalZone,
356 const faceZoneMesh& zm,
357 const label newIndex
359:
360 zone(originalZone, labelList(), newIndex),
361 zoneMesh_(zm)
362{}
363
364
366(
367 const faceZone& originalZone,
369 const label index,
370 const faceZoneMesh& zm
372:
373 zone(originalZone, labelList(), index),
374 zoneMesh_(zm)
375{}
376
377
379(
380 const faceZone& originalZone,
381 const labelUList& addr,
382 const boolUList& fm,
383 const label index,
384 const faceZoneMesh& zm
385)
386:
387 faceZone(originalZone, Foam::zero{}, index, zm)
388{
390 flipMap_ = fm;
391
392 checkAddressing();
393}
394
395
397(
398 const faceZone& originalZone,
399 labelList&& addr,
400 boolList&& fm,
401 const label index,
402 const faceZoneMesh& zm
403)
404:
405 faceZone(originalZone, Foam::zero{}, index, zm)
406{
408 flipMap_.transfer(fm);
410 checkAddressing();
411}
412
413
414// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
415
416Foam::label Foam::faceZone::max_index() const noexcept
417{
418 return zoneMesh_.mesh().nFaces();
419}
420
421
422// void Foam::faceZone::sort()
423// {
424// clearAddressing();
425// auto& addr = static_cast<labelList&>(*this);
427// auto order = Foam::sortedOrder(addr);
428// addr = labelList(addr, order);
429// flipMap_ = boolList(flipMap_, order);
430// }
431
432
434{
435 if (!patchPtr_)
437 calcFaceZonePatch();
438 }
439 return *patchPtr_;
440}
441
442
444{
445 if (!frontCellsPtr_)
447 calcCellLayers();
448 }
449 return *frontCellsPtr_;
450}
451
452
454{
455 if (!backCellsPtr_)
457 calcCellLayers();
458 }
459 return *backCellsPtr_;
460}
461
462
464{
465 if (!mePtr_)
466 {
467 mePtr_.reset
468 (
469 new labelList
470 (
471 this->patch().meshEdges
472 (
473 zoneMesh().mesh().edges(),
474 zoneMesh().mesh().pointEdges()
475 )
476 )
477 );
478 }
479
480 return *mePtr_;
481}
482
483
484void Foam::faceZone::clearGeom()
485{
486 patchPtr_.reset(nullptr);
487 frontCellsPtr_.reset(nullptr);
488 backCellsPtr_.reset(nullptr);
489 mePtr_.reset(nullptr);
490}
491
492
494{
496 clearGeom();
497}
498
499
501{
503 flipMap_.clear();
504}
505
506
508{
509 if (this == &zn)
510 {
511 return; // Self-assignment is a no-op
512 }
513
515 labelList::transfer(static_cast<labelList&>(zn));
516 flipMap_.transfer(zn.flipMap_);
517 zn.clearAddressing();
518}
519
520
522{
523 if (this == &zn)
524 {
525 return; // Self-assignment is a no-op
526 }
529 labelList::operator=(static_cast<const labelList&>(zn));
530 flipMap_ = zn.flipMap_;
531}
532
533
535(
536 const labelUList& addr,
537 const bool flipMapValue
538)
542 setFlipMap(flipMapValue);
543}
544
545
547(
548 labelList&& addr,
549 const bool flipMapValue
550)
554 setFlipMap(flipMapValue);
555}
556
557
559(
560 const labelUList& addr,
561 const boolUList& flipMap
562)
566 flipMap_ = flipMap;
567}
568
569
571{
572 clearAddressing();
573
574 labelList newAddressing(size());
575 boolList newFlipMap(flipMap_.size());
576 label nFaces = 0;
577
578 const labelList& addr = *this;
579 const boolList& flips = flipMap();
580 const labelList& faceMap = mpm.reverseFaceMap();
581
582 forAll(addr, i)
583 {
584 const label facei = addr[i];
585
586 if (faceMap[facei] >= 0)
587 {
588 newAddressing[nFaces] = faceMap[facei];
589 newFlipMap[nFaces] = flips[i]; // Keep flip map
590 ++nFaces;
591 }
592 }
593
594 newAddressing.resize(nFaces);
595 newFlipMap.resize(nFaces);
596
597 labelList::transfer(newAddressing);
598 flipMap_.transfer(newFlipMap);
599}
600
601
602bool Foam::faceZone::checkParallelSync(const bool report) const
603{
604 const polyMesh& mesh = zoneMesh().mesh();
605 const polyBoundaryMesh& bm = mesh.boundaryMesh();
606
607 bool hasError = false;
608
609
610 // Check that zone faces are synced
611 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
612
613 {
614 const labelList& addr = *this;
615 const boolList& flips = flipMap();
616
617 boolList neiZoneFace(mesh.nBoundaryFaces(), false);
618 boolList neiZoneFlip(mesh.nBoundaryFaces(), false);
619
620 forAll(addr, i)
621 {
622 const label facei = addr[i];
623
624 if (!mesh.isInternalFace(facei))
625 {
626 const label bFacei = facei-mesh.nInternalFaces();
627 neiZoneFace[bFacei] = true;
628 neiZoneFlip[bFacei] = flips[i];
629 }
630 }
631 boolList myZoneFace(neiZoneFace);
632 boolList myZoneFlip(neiZoneFlip);
635
636 forAll(addr, i)
637 {
638 const label facei = addr[i];
639 const label patchi = bm.whichPatch(facei);
640
641 if (patchi != -1 && bm[patchi].coupled())
642 {
643 const label bFacei = facei-mesh.nInternalFaces();
644
645 // Check face in zone on both sides
646 if (myZoneFace[bFacei] != neiZoneFace[bFacei])
647 {
648 hasError = true;
649
650 if (report)
651 {
652 Pout<< " ***Problem with faceZone " << index()
653 << " named " << name()
654 << ". Face " << facei
655 << " on coupled patch " << bm[patchi].name()
656 << " is inconsistent with its coupled neighbour."
657 << endl;
658 }
659 else
660 {
661 // w/o report - can stop checking now
662 break;
663 }
664 }
665 else if (myZoneFlip[bFacei] == neiZoneFlip[bFacei])
666 {
667 // Flip state should be opposite.
668 hasError = true;
669
670 if (report)
671 {
672 Pout<< " ***Problem with faceZone " << index()
673 << " named " << name()
674 << ". Face " << facei
675 << " on coupled patch " << bm[patchi].name()
676 << " has inconsistent flipMap across coupled faces."
677 << endl;
678 }
679 else
680 {
681 // w/o report - can stop checking now
682 break;
683 }
684 }
685 }
687 }
688
689 return returnReduceOr(hasError);
690}
691
692
694{
695 if (patchPtr_)
696 {
697 patchPtr_->movePoints(pts);
698 }
699}
700
701
702void Foam::faceZone::write(Ostream& os) const
703{
706 flipMap_.writeEntry("flipMap", os);
707}
708
709
710// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
711
713{
714 if (this == &zn)
715 {
716 return; // Self-assignment is a no-op
717 }
718
719 clearAddressing();
720 labelList::operator=(static_cast<const labelList&>(zn));
721 flipMap_ = zn.flipMap_;
722}
723
724
725// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
726
727Foam::Ostream& Foam::operator<<(Ostream& os, const faceZone& zn)
728{
729 zn.write(os);
730 os.check(FUNCTION_NAME);
731 return os;
732}
733
734
735// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
const word & name() const noexcept
Return the object name.
Definition IOobjectI.H:205
void transfer(List< label > &list)
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
void operator=(const UList< label > &list)
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
void writeEntry(Ostream &os) const
label size() const noexcept
Definition UList.H:706
void size(const label n)
Definition UList.H:118
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
A subset of mesh faces organised as a primitive patch.
Definition faceZone.H:63
static constexpr const char * labelsName()
The name associated with the zone-labels dictionary entry.
Definition faceZone.H:143
const primitiveFacePatch & patch() const
Return [demand-driven] reference to an equivalent primitive patch, with faces oriented according to f...
Definition faceZone.C:426
const boolList & flipMap() const noexcept
Return face flip map.
Definition faceZone.H:389
virtual void clearPrimitives()
Clear primitive addressing.
Definition faceZone.C:493
virtual void resetAddressing(faceZone &&zn)
Move reset addressing and flip map from another zone.
Definition faceZone.C:500
virtual void write(Ostream &os) const
Write (dictionary entries).
Definition faceZone.C:695
virtual void updateMesh(const mapPolyMesh &mpm)
Update for changes in topology.
Definition faceZone.C:563
label max_index() const noexcept
The maximum index the zone may contain == mesh nFaces().
Definition faceZone.C:409
virtual void clearAddressing()
Clear addressing (remove lookup maps, patch/geometric information).
Definition faceZone.C:486
const labelList & backCells() const
The back cells layer. Cells on the negative normal side of faces.
Definition faceZone.C:446
const labelList & frontCells() const
The front cells layer. Cells on the positive normal side of faces.
Definition faceZone.C:436
virtual void movePoints(const pointField &pts)
Correct patch after moving points.
Definition faceZone.C:686
const faceZoneMesh & zoneMesh() const noexcept
Return reference to the zone mesh.
Definition faceZone.H:379
faceZone(const faceZone &)=delete
No copy construct.
virtual bool checkParallelSync(const bool report=false) const
Check whether all procs have faces synchronised.
Definition faceZone.C:595
void operator=(const faceZone &zn)
Assign addressing, clearing demand-driven data.
Definition faceZone.C:705
const labelList & meshEdges() const
Return global edge index for local edges.
Definition faceZone.C:456
@ LITERAL
String literal.
Definition keyType.H:82
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelList & reverseFaceMap() const noexcept
Reverse face map.
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
label whichPatch(const label meshFacei) const
Return patch index for a given mesh face index. Uses binary search.
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
label nInternalFaces() const noexcept
Number of internal faces.
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues, const bool parRun=UPstream::parRun())
Swap coupled boundary face values. Uses eqOp.
Definition syncTools.H:524
A class for handling words, derived from Foam::string.
Definition word.H:66
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
label index() const noexcept
The index of this zone in the zone list.
Base class for mesh zones.
Definition zone.H:63
virtual void clearPrimitives()
Clear primitive addressing.
Definition zone.C:168
virtual void write(Ostream &os) const
Write (dictionary entries).
Definition zone.C:218
zone()
Default construct: empty zone with name="", index=0.
Definition zone.C:37
virtual void clearAddressing()
Clear addressing (remove lookup maps and other auxiliary information).
Definition zone.C:162
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
bool coupled
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
Foam::faceZoneMesh.
auto & name
const pointField & points
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FUNCTION_NAME
#define DebugInFunction
Report an information message using Foam::Info.
const std::string patch
OpenFOAM patch number as a std::string.
Namespace for OpenFOAM.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
List< label > labelList
A List of labels.
Definition List.H:62
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with faceZone content on a polyMesh.
List< face > faceList
List of faces.
Definition faceListFwd.H:41
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
A PrimitivePatch with List storage for the faces, const reference for the point field.
errorManip< error > abort(error &err)
Definition errorManip.H:139
List< bool > boolList
A List of bools.
Definition List.H:60
UList< bool > boolUList
A UList of bools.
Definition UList.H:73
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
UList< label > labelUList
A UList of labels.
Definition UList.H:75
labelList f(nPoints)
#define defineRunTimeSelectionTable(baseType, argNames)
Define run-time selection table.
dictionary dict
const pointField & pts
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299