faceZone.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "faceZone.H"
27 #include "faceZoneList.H"
28 #include "polyMesh.H"
29 #include "polyTopoChangeMap.H"
30 #include "syncTools.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
37 }
38 
39 const char* const Foam::faceZone::labelsName = "faceLabels";
40 
41 
42 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43 
44 void Foam::faceZone::calcFaceZonePatch() const
45 {
46  if (debug)
47  {
48  InfoInFunction << "Calculating primitive patch" << endl;
49  }
50 
51  if (patchPtr_)
52  {
54  << "primitive face zone patch already calculated"
55  << abort(FatalError);
56  }
57 
58  patchPtr_ =
60  (
61  faceList(size()),
62  zones().mesh().points()
63  );
64 
65  primitiveFacePatch& patch = *patchPtr_;
66 
67  const faceList& f = zones().mesh().faces();
68 
69  const labelList& addr = *this;
70 
71  if (oriented_)
72  {
73  forAll(addr, facei)
74  {
75  if (flipMap_[facei])
76  {
77  patch[facei] = f[addr[facei]].reverseFace();
78  }
79  else
80  {
81  patch[facei] = f[addr[facei]];
82  }
83  }
84  }
85  else
86  {
87  forAll(addr, facei)
88  {
89  patch[facei] = f[addr[facei]];
90  }
91  }
92 
93  if (debug)
94  {
95  InfoInFunction << "Finished calculating primitive patch" << endl;
96  }
97 }
98 
99 
100 void Foam::faceZone::checkAddressing() const
101 {
102  if (oriented_ && size() != flipMap_.size())
103  {
105  << "Size of addressing: " << size()
106  << " size of flip map: " << flipMap_.size()
107  << abort(FatalError);
108  }
109 
110  const labelList& mf = *this;
111 
112  // Note: nFaces, nCells might not be set yet on mesh so use owner size
113  const label nFaces = zones().mesh().faceOwner().size();
114 
115  bool hasWarned = false;
116  forAll(mf, i)
117  {
118  if (!hasWarned && (mf[i] < 0 || mf[i] >= nFaces))
119  {
121  << "Illegal face index " << mf[i] << " outside range 0.."
122  << nFaces-1 << endl;
123  hasWarned = true;
124  }
125  }
126 }
127 
128 
129 void Foam::faceZone::reset(const Map<bool>& newIndices)
130 {
131  clearAddressing();
132  oriented_ = true;
133 
134  labelList& indices = *this;
135 
136  indices.setSize(newIndices.size());
137  flipMap_.setSize(newIndices.size());
138 
139  const List<Map<bool>::const_iterator> sortedNewIndices(newIndices.sorted());
140 
141  forAll(sortedNewIndices, i)
142  {
143  indices[i] = sortedNewIndices[i].key();
144  flipMap_[i] = sortedNewIndices[i]();
145  }
146 }
147 
148 
149 void Foam::faceZone::reset(const labelHashSet& newIndices)
150 {
151  clearAddressing();
152  oriented_ = false;
153  flipMap_.clear();
154  labelList::operator=(newIndices.sortedToc());
155 }
156 
157 
158 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
159 
161 (
162  const word& name,
163  const labelUList& addr,
164  const boolList& fm,
165  const faceZoneList& mz,
166  const bool moveUpdate,
167  const bool topoUpdate
168 )
169 :
170  Zone<faceZone, faceZoneList>(name, addr, mz, moveUpdate, topoUpdate),
171  oriented_(true),
172  flipMap_(fm),
173  patchPtr_(nullptr),
174  mePtr_(nullptr)
175 {
176  checkAddressing();
177 }
178 
179 
181 (
182  const word& name,
183  const labelUList& addr,
184  const faceZoneList& mz,
185  const bool moveUpdate,
186  const bool topoUpdate
187 )
188 :
189  Zone<faceZone, faceZoneList>(name, addr, mz, moveUpdate, topoUpdate),
190  oriented_(false),
191  patchPtr_(nullptr),
192  mePtr_(nullptr)
193 {
194  checkAddressing();
195 }
196 
197 
199 (
200  const word& name,
201  labelList&& addr,
202  boolList&& fm,
203  const faceZoneList& mz,
204  const bool moveUpdate,
205  const bool topoUpdate
206 )
207 :
208  Zone<faceZone, faceZoneList>(name, move(addr), mz, moveUpdate, topoUpdate),
209  oriented_(true),
210  flipMap_(move(fm)),
211  patchPtr_(nullptr),
212  mePtr_(nullptr)
213 {
214  checkAddressing();
215 }
216 
217 
219 (
220  const word& name,
221  labelList&& addr,
222  const faceZoneList& mz,
223  const bool moveUpdate,
224  const bool topoUpdate
225 )
226 :
227  Zone<faceZone, faceZoneList>(name, move(addr), mz, moveUpdate, topoUpdate),
228  oriented_(false),
229  patchPtr_(nullptr),
230  mePtr_(nullptr)
231 {
232  checkAddressing();
233 }
234 
235 
237 (
238  const word& name,
239  const dictionary& dict,
240  const faceZoneList& mz
241 )
242 :
244  oriented_(dict.found("flipMap")),
245  flipMap_(dict.lookupOrDefault("flipMap", boolList::null())),
246  patchPtr_(nullptr),
247  mePtr_(nullptr)
248 {
249  checkAddressing();
250 }
251 
252 
254 (
255  const faceZone& fz,
256  const word& name,
257  const labelUList& addr,
258  const boolList& fm,
259  const faceZoneList& mz
260 )
261 :
262  Zone<faceZone, faceZoneList>(fz, name, addr, mz),
263  oriented_(true),
264  flipMap_(fm),
265  patchPtr_(nullptr),
266  mePtr_(nullptr)
267 {
268  checkAddressing();
269 }
270 
271 
273 (
274  const faceZone& fz,
275  const word& name,
276  const labelUList& addr,
277  const faceZoneList& mz
278 )
279 :
280  Zone<faceZone, faceZoneList>(fz, name, addr, mz),
281  oriented_(false),
282  patchPtr_(nullptr),
283  mePtr_(nullptr)
284 {
285  checkAddressing();
286 }
287 
288 
290 (
291  const faceZone& fz,
292  labelList&& addr,
293  boolList&& fm,
294  const faceZoneList& mz
295 )
296 :
297  Zone<faceZone, faceZoneList>(fz, fz.name(), move(addr), mz),
298  oriented_(true),
299  flipMap_(move(fm)),
300  patchPtr_(nullptr),
301  mePtr_(nullptr)
302 {
303  checkAddressing();
304 }
305 
306 
308 (
309  const faceZone& fz,
310  labelList&& addr,
311  const faceZoneList& mz
312 )
313 :
314  Zone<faceZone, faceZoneList>(fz, fz.name(), move(addr), mz),
315  oriented_(false),
316  patchPtr_(nullptr),
317  mePtr_(nullptr)
318 {
319  checkAddressing();
320 }
321 
322 
324 {
325  if (oriented_)
326  {
327  return autoPtr<faceZone>
328  (
329  new faceZone(*this, name(), *this, flipMap(), zones())
330  );
331  }
332  else
333  {
334  return autoPtr<faceZone>
335  (
336  new faceZone(*this, name(), *this, zones())
337  );
338  }
339 }
340 
341 
343 {
344  if (oriented_)
345  {
346  return autoPtr<faceZone>
347  (
348  new faceZone(*this, name, *this, flipMap(), zones())
349  );
350  }
351  else
352  {
353  return autoPtr<faceZone>
354  (
355  new faceZone(*this, name, *this, zones())
356  );
357  }
358 }
359 
360 
363 {
364  if (oriented_)
365  {
366  return autoPtr<faceZone>
367  (
368  new faceZone(*this, name(), *this, flipMap(), mz)
369  );
370  }
371  else
372  {
373  return autoPtr<faceZone>
374  (
375  new faceZone(*this, name(), *this, mz)
376  );
377  }
378 }
379 
380 
382 (
383  const labelUList& addr,
384  const boolList& fm,
385  const faceZoneList& mz
386 ) const
387 {
388  return autoPtr<faceZone>
389  (
390  new faceZone(*this, name(), addr, fm, mz)
391  );
392 }
393 
394 
396 (
397  const labelUList& addr,
398  const faceZoneList& mz
399 ) const
400 {
401  return autoPtr<faceZone>
402  (
403  new faceZone(*this, name(), addr, mz)
404  );
405 }
406 
407 
408 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
409 
411 {
412  clearAddressing();
413 }
414 
415 
416 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
417 
419 {
420  if (!patchPtr_)
421  {
422  calcFaceZonePatch();
423  }
424 
425  return *patchPtr_;
426 }
427 
428 
430 {
431  if (!mePtr_)
432  {
433  mePtr_ =
434  new labelList
435  (
436  patch().meshEdges
437  (
438  zones().mesh().edges(),
439  zones().mesh().pointEdges()
440  )
441  );
442  }
443 
444  return *mePtr_;
445 }
446 
447 
449 {
451 
452  deleteDemandDrivenData(patchPtr_);
453  deleteDemandDrivenData(mePtr_);
454 }
455 
456 
458 (
459  const labelUList& addr,
460  const boolList& flipMap
461 )
462 {
463  clearAddressing();
464  labelList::operator=(addr);
465  oriented_ = true;
466  flipMap_ = flipMap;
467 }
468 
469 
471 (
472  const labelUList& addr
473 )
474 {
475  clearAddressing();
476  labelList::operator=(addr);
477  oriented_ = false;
478  flipMap_.clear();
479 }
480 
481 
482 bool Foam::faceZone::checkDefinition(const bool report) const
483 {
484  return Zone::checkDefinition
485  (
486  zones().mesh().faces().size(),
487  report
488  );
489 }
490 
491 
492 bool Foam::faceZone::checkParallelSync(const bool report) const
493 {
494  const polyMesh& mesh = zones().mesh();
495  const polyBoundaryMesh& bm = mesh.boundary();
496 
497  bool hasError = false;
498 
499 
500  // Check that zone faces are synced
501  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
502 
503  {
504  boolList neiZoneFace(mesh.nFaces() - mesh.nInternalFaces(), false);
505  boolList neiZoneFlip(mesh.nFaces() - mesh.nInternalFaces(), false);
506 
507  if (oriented_)
508  {
509  forAll(*this, i)
510  {
511  const label facei = operator[](i);
512 
513  if (!mesh.isInternalFace(facei))
514  {
515  neiZoneFace[facei - mesh.nInternalFaces()] = true;
516  neiZoneFlip[facei - mesh.nInternalFaces()] = flipMap_[i];
517  }
518  }
519  }
520  else
521  {
522  forAll(*this, i)
523  {
524  const label facei = operator[](i);
525 
526  if (!mesh.isInternalFace(facei))
527  {
528  neiZoneFace[facei - mesh.nInternalFaces()] = true;
529  }
530  }
531  }
532 
533  boolList myZoneFace(neiZoneFace);
535 
536  boolList myZoneFlip(neiZoneFlip);
537  if (oriented_)
538  {
540  }
541 
542  forAll(*this, i)
543  {
544  const label facei = operator[](i);
545  const label patchi = bm.whichPatch(facei);
546 
547  if (patchi != -1 && bm[patchi].coupled())
548  {
549  const label bFacei = facei - mesh.nInternalFaces();
550 
551  // Check face in zone on both sides
552  if (myZoneFace[bFacei] != neiZoneFace[bFacei])
553  {
554  hasError = true;
555 
556  if (report)
557  {
558  Pout<< " ***Problem with faceZone " << name()
559  << ". Face " << facei
560  << " on coupled patch "
561  << bm[patchi].name()
562  << " is not consistent with its coupled neighbour."
563  << endl;
564  }
565  else
566  {
567  // w/o report - can stop checking now
568  break;
569  }
570  }
571  else if (oriented_ && myZoneFlip[bFacei] == neiZoneFlip[bFacei])
572  {
573  // Flip state should be opposite.
574  hasError = true;
575 
576  if (report)
577  {
578  Pout<< " ***Problem with faceZone " << name()
579  << ". Face " << facei
580  << " on coupled patch "
581  << bm[patchi].name()
582  << " does not have consistent flipMap"
583  << " across coupled faces."
584  << endl;
585  }
586  else
587  {
588  // w/o report - can stop checking now
589  break;
590  }
591  }
592  }
593  }
594  }
595 
596  return returnReduce(hasError, orOp<bool>());
597 }
598 
599 
600 void Foam::faceZone::insert(const Map<bool>& newIndices)
601 {
602  if (!oriented_)
603  {
605  << "Attempt to insert oriented faces into the unoriented faceZone "
606  << name()
607  << exit(FatalError);
608  }
609 
610  Map<bool> indices(*this, flipMap_);
611  indices.insert(newIndices);
612  reset(indices);
613 }
614 
615 
616 void Foam::faceZone::insert(const labelHashSet& newIndices)
617 {
618  if (oriented_)
619  {
621  << "Attempt to insert unoriented faces into the oriented faceZone "
622  << name()
623  << exit(FatalError);
624  }
625 
626  labelHashSet indices(*this);
627  indices.insert(newIndices);
628  reset(indices);
629 }
630 
631 
633 {
634  Zone::swap(fz);
635  Swap(oriented_, fz.oriented_);
636  flipMap_.swap(fz.flipMap_);
637 }
638 
639 
641 {
642  // topoChange update of generated zones is necessary
643  // as part of redistribution which uses topoChange
644  // to add meshes
645  // if (!topoUpdate_)
646  {
647  clearAddressing();
648 
649  if (oriented_)
650  {
651  const labelList& faceMap = map.faceMap();
652  const labelList& reverseFaceMap = map.reverseFaceMap();
653  const labelHashSet& flipFaceFlux = map.flipFaceFlux();
654 
655  Map<bool> newIndicesMap;
656 
657  forAll(faceMap, facei)
658  {
659  const label i = localIndex(faceMap[facei]);
660  if (faceMap[facei] >= 0 && i != -1)
661  {
662  newIndicesMap.insert
663  (
664  facei,
665  flipFaceFlux.found(facei)
666  ? !flipMap_[i]
667  : flipMap_[i]
668  );
669  }
670  }
671 
672  forAll(reverseFaceMap, facei)
673  {
674  const label i = localIndex(facei);
675  if (reverseFaceMap[facei] >= 0 && i != -1)
676  {
677  newIndicesMap.insert
678  (
679  reverseFaceMap[facei],
680  flipFaceFlux.found(reverseFaceMap[facei])
681  ? !flipMap_[i]
682  : flipMap_[i]
683  );
684  }
685  }
686 
687  reset(newIndicesMap);
688  }
689  else
690  {
692  }
693  }
694 }
695 
696 
698 {
699  if (patchPtr_)
700  {
701  patchPtr_->clearGeom();
702  }
703 }
704 
705 
707 {
708  os << nl << name() << nl << token::BEGIN_BLOCK << nl;
709  writeEntry(os, this->labelsName, *this);
710  if (oriented_)
711  {
712  writeEntry(os, "flipMap", flipMap_);
713  }
714  os << token::END_BLOCK << endl;
715 }
716 
717 
718 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
719 
721 {
722  Zone::operator=(zn);
723  oriented_ = zn.oriented_;
724  if (oriented_)
725  {
726  flipMap_ = zn.flipMap_;
727  }
728 }
729 
730 
732 {
733  Zone::operator=(move(zn));
734  oriented_ = zn.oriented_;
735  if (oriented_)
736  {
737  flipMap_ = move(zn.flipMap_);
738  }
739 }
740 
741 
743 {
744  Zone::operator=(lst);
745  oriented_ = false;
746  flipMap_.clear();
747 }
748 
749 
751 {
752  Zone::operator=(move(lst));
753  oriented_ = false;
754  flipMap_.clear();
755 }
756 
757 
758 // ************************************************************************* //
bool found
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:109
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
const word & name() const
Return name.
Definition: IOobject.H:307
label size() const
Return the number of elements in the UList.
Definition: ListI.H:171
void operator=(const UList< label > &)
Assignment to UList operator. Takes linear time.
Definition: List.C:376
void setSize(const label)
Reset size of List.
Definition: List.C:281
A HashTable to objects of type <T> with a label key.
Definition: Map.H:52
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:57
A list of faces which address into the list of points.
const MeshType & mesh() const
Return the mesh reference.
Definition: ZoneList.H:117
Base class for zones.
Definition: Zone.H:68
void swap(Zone &)
Swap two zones.
Definition: Zone.C:319
void topoChange(const labelList &map, const labelList &reverseMap)
Update the addressing using the maps provided.
Definition: Zone.C:79
bool checkDefinition(const label maxSize, const bool report=false) const
Check zone definition with max size given. Return true if in error.
Definition: Zone.C:261
void clearAddressing()
Clear addressing.
Definition: Zone.C:253
void operator=(const Zone &)
Assignment operator.
Definition: Zone.C:343
const faceZoneList & zones() const
Return ZonesType reference.
Definition: Zone.C:213
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Named list of face indices representing a sub-set of the mesh faces.
Definition: faceZone.H:66
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: faceZone.C:482
void swap(faceZone &)
Swap two faceZones.
Definition: faceZone.C:632
void operator=(const faceZone &)
Assignment to zone, clearing demand-driven data.
Definition: faceZone.C:720
faceZone(const word &name, const labelUList &addr, const boolList &fm, const faceZoneList &mz, const bool moveUpdate=false, const bool topoUpdate=false)
Construct from components.
Definition: faceZone.C:161
const primitiveFacePatch & patch() const
Return reference to primitive patch.
Definition: faceZone.C:418
autoPtr< faceZone > clone() const
Construct and return a clone.
Definition: faceZone.C:323
void topoChange(const polyTopoChangeMap &)
Update zone using the given map.
Definition: faceZone.C:640
void resetAddressing(const labelUList &, const boolList &)
Reset addressing and flip map (clearing demand-driven data)
Definition: faceZone.C:458
static const char *const labelsName
The name associated with the zone-labels dictionary entry.
Definition: faceZone.H:109
void writeDict(Ostream &) const
Write dictionary.
Definition: faceZone.C:706
void insert(const Map< bool > &newIndices)
Insert given indices and corresponding face flips into zone.
Definition: faceZone.C:600
void clearAddressing()
Clear addressing.
Definition: faceZone.C:448
~faceZone()
Destructor.
Definition: faceZone.C:410
void movePoints(const pointField &)
Correct patch after moving points.
Definition: faceZone.C:697
bool checkParallelSync(const bool report=false) const
Check whether all procs have faces synchronised. Return.
Definition: faceZone.C:492
const labelList & meshEdges() const
Return global edge index for local edges.
Definition: faceZone.C:429
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:932
Motion of the mesh specified as a list of pointMeshMovers.
Foam::polyBoundaryMesh.
label whichPatch(const label faceIndex) const
Return patch index for a given face label.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1308
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelHashSet & flipFaceFlux() const
Map of flipped face flux faces.
const labelList & reverseFaceMap() const
Reverse face map.
const labelList & faceMap() const
Old face map.
label nInternalFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
label nFaces() const
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &l)
Swap coupled boundary face values.
Definition: syncTools.H:436
@ BEGIN_BLOCK
Definition: token.H:114
@ END_BLOCK
Definition: token.H:115
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
Foam::faceZoneList.
label patchi
const pointField & points
#define WarningInFunction
Report a warning using Foam::Warning.
#define InfoInFunction
Report an information message using Foam::Info.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:213
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
Foam::primitiveFacePatch.
error FatalError
void Swap(T &a, T &b)
Definition: Swap.H:43
List< face > faceList
Definition: faceListFwd.H:41
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
void writeEntry(Ostream &os, const word &key, const DimensionedFieldFunction< DimensionedFieldType > &f)
static const char nl
Definition: Ostream.H:297
labelList f(nPoints)
dictionary dict
volScalarField & p