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-2024 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"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
39 
42 }
43 
44 const char* const Foam::faceZone::labelsName = "faceLabels";
45 
46 
47 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
48 
50 {
51  if (debug)
52  {
53  InfoInFunction << "Calculating primitive patch" << endl;
54  }
55 
56  if (patchPtr_)
57  {
59  << "primitive face zone patch already calculated"
60  << abort(FatalError);
61  }
62 
63  patchPtr_ =
65  (
66  faceList(size()),
67  zones().mesh().points()
68  );
69 
71 
72  const faceList& f = zones().mesh().faces();
73 
74  const labelList& addr = *this;
75  const boolList& flip = flipMap();
76 
77  forAll(addr, facei)
78  {
79  if (flip[facei])
80  {
81  patch[facei] = f[addr[facei]].reverseFace();
82  }
83  else
84  {
85  patch[facei] = f[addr[facei]];
86  }
87  }
88 
89  if (debug)
90  {
91  InfoInFunction << "Finished calculating primitive patch" << endl;
92  }
93 }
94 
95 
97 {
98  if (debug)
99  {
100  InfoInFunction << "Calculating master cells" << endl;
101  }
102 
103  // It is an error to attempt to recalculate edgeCells
104  // if the pointer is already set
105  if (masterCellsPtr_ || slaveCellsPtr_)
106  {
108  << "cell layers already calculated"
109  << abort(FatalError);
110  }
111  else
112  {
113  // Go through all the faces in the master zone. Choose the
114  // master or slave cell based on the face flip
115 
116  const labelList& own = zones().mesh().faceOwner();
117  const labelList& nei = zones().mesh().faceNeighbour();
118 
119  const labelList& mf = *this;
120 
121  const boolList& faceFlip = flipMap();
122 
123  masterCellsPtr_ = new labelList(mf.size());
124  labelList& mc = *masterCellsPtr_;
125 
126  slaveCellsPtr_ = new labelList(mf.size());
127  labelList& sc = *slaveCellsPtr_;
128 
129  forAll(mf, facei)
130  {
131  label ownCelli = own[mf[facei]];
132  label neiCelli =
133  (
134  zones().mesh().isInternalFace(mf[facei])
135  ? nei[mf[facei]]
136  : -1
137  );
138 
139  if (!faceFlip[facei])
140  {
141  // Face is oriented correctly, no flip needed
142  mc[facei] = neiCelli;
143  sc[facei] = ownCelli;
144  }
145  else
146  {
147  mc[facei] = ownCelli;
148  sc[facei] = neiCelli;
149  }
150  }
151  }
152 }
153 
154 
156 {
157  if (size() != flipMap_.size())
158  {
160  << "Size of addressing: " << size()
161  << " size of flip map: " << flipMap_.size()
162  << abort(FatalError);
163  }
164 
165  const labelList& mf = *this;
166 
167  // Note: nFaces, nCells might not be set yet on mesh so use owner size
168  const label nFaces = zones().mesh().faceOwner().size();
169 
170  bool hasWarned = false;
171  forAll(mf, i)
172  {
173  if (!hasWarned && (mf[i] < 0 || mf[i] >= nFaces))
174  {
176  << "Illegal face index " << mf[i] << " outside range 0.."
177  << nFaces-1 << endl;
178  hasWarned = true;
179  }
180  }
181 }
182 
183 
184 void Foam::faceZone::reset(const Map<bool>& newIndices)
185 {
186  clearAddressing();
187 
188  labelList& indices = *this;
189 
190  indices.setSize(newIndices.size());
191  flipMap_.setSize(newIndices.size());
192 
193  const List<Map<bool>::const_iterator> sortedNewIndices(newIndices.sorted());
194 
195  forAll(sortedNewIndices, i)
196  {
197  indices[i] = sortedNewIndices[i].key();
198  flipMap_[i] = sortedNewIndices[i]();
199  }
200 }
201 
202 
203 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
204 
206 (
207  const word& name,
208  const labelUList& addr,
209  const boolList& fm,
210  const faceZoneList& mz
211 )
212 :
213  Zone<faceZone, faceZoneList>(name, addr, mz),
214  flipMap_(fm),
215  patchPtr_(nullptr),
216  masterCellsPtr_(nullptr),
217  slaveCellsPtr_(nullptr),
218  mePtr_(nullptr)
219 {
220  checkAddressing();
221 }
222 
223 
225 (
226  const word& name,
227  labelList&& addr,
228  boolList&& fm,
229  const faceZoneList& mz
230 )
231 :
232  Zone<faceZone, faceZoneList>(name, move(addr), mz),
233  flipMap_(move(fm)),
234  patchPtr_(nullptr),
235  masterCellsPtr_(nullptr),
236  slaveCellsPtr_(nullptr),
237  mePtr_(nullptr)
238 {
239  checkAddressing();
240 }
241 
242 
244 (
245  const word& name,
246  const dictionary& dict,
247  const faceZoneList& mz
248 )
249 :
251  flipMap_(dict.lookup("flipMap")),
252  patchPtr_(nullptr),
253  masterCellsPtr_(nullptr),
254  slaveCellsPtr_(nullptr),
255  mePtr_(nullptr)
256 {
257  checkAddressing();
258 }
259 
260 
262 (
263  const faceZone& fz,
264  const labelUList& addr,
265  const boolList& fm,
266  const faceZoneList& mz
267 )
268 :
269  Zone<faceZone, faceZoneList>(fz, addr, mz),
270  flipMap_(fm),
271  patchPtr_(nullptr),
272  masterCellsPtr_(nullptr),
273  slaveCellsPtr_(nullptr),
274  mePtr_(nullptr)
275 {
276  checkAddressing();
277 }
278 
279 
281 (
282  const faceZone& fz,
283  labelList&& addr,
284  boolList&& fm,
285  const faceZoneList& mz
286 )
287 :
288  Zone<faceZone, faceZoneList>(fz, move(addr), mz),
289  flipMap_(move(fm)),
290  patchPtr_(nullptr),
291  masterCellsPtr_(nullptr),
292  slaveCellsPtr_(nullptr),
293  mePtr_(nullptr)
294 {
295  checkAddressing();
296 }
297 
298 
299 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
300 
302 {
303  clearAddressing();
304 }
305 
306 
307 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
308 
310 {
311  return zones_.mesh().faceCentres();
312 }
313 
314 
316 {
317  if (!patchPtr_)
318  {
319  calcFaceZonePatch();
320  }
321 
322  return *patchPtr_;
323 }
324 
325 
327 {
328  if (!masterCellsPtr_)
329  {
330  calcCellLayers();
331  }
332 
333  return *masterCellsPtr_;
334 }
335 
336 
338 {
339  if (!slaveCellsPtr_)
340  {
341  calcCellLayers();
342  }
343 
344  return *slaveCellsPtr_;
345 }
346 
347 
349 {
350  if (!mePtr_)
351  {
352  mePtr_ =
353  new labelList
354  (
355  patch().meshEdges
356  (
357  zones().mesh().edges(),
358  zones().mesh().pointEdges()
359  )
360  );
361  }
362 
363  return *mePtr_;
364 }
365 
366 
368 {
370 
371  deleteDemandDrivenData(patchPtr_);
372 
373  deleteDemandDrivenData(masterCellsPtr_);
374  deleteDemandDrivenData(slaveCellsPtr_);
375 
376  deleteDemandDrivenData(mePtr_);
377 }
378 
379 
381 (
382  const labelUList& addr,
383  const boolList& flipMap
384 )
385 {
386  clearAddressing();
387  labelList::operator=(addr);
388  flipMap_ = flipMap;
389 }
390 
391 
392 bool Foam::faceZone::checkDefinition(const bool report) const
393 {
394  return Zone::checkDefinition
395  (
396  zones().mesh().faces().size(),
397  report
398  );
399 }
400 
401 
402 bool Foam::faceZone::checkParallelSync(const bool report) const
403 {
404  const polyMesh& mesh = zones().mesh();
405  const polyBoundaryMesh& bm = mesh.boundaryMesh();
406 
407  bool hasError = false;
408 
409 
410  // Check that zone faces are synced
411  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
412 
413  {
414  boolList neiZoneFace(mesh.nFaces()-mesh.nInternalFaces(), false);
415  boolList neiZoneFlip(mesh.nFaces()-mesh.nInternalFaces(), false);
416  forAll(*this, i)
417  {
418  const label facei = operator[](i);
419 
420  if (!mesh.isInternalFace(facei))
421  {
422  neiZoneFace[facei-mesh.nInternalFaces()] = true;
423  neiZoneFlip[facei-mesh.nInternalFaces()] = flipMap()[i];
424  }
425  }
426  boolList myZoneFace(neiZoneFace);
427  syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
428  boolList myZoneFlip(neiZoneFlip);
429  syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
430 
431  forAll(*this, i)
432  {
433  const label facei = operator[](i);
434  const label patchi = bm.whichPatch(facei);
435 
436  if (patchi != -1 && bm[patchi].coupled())
437  {
438  const label bFacei = facei-mesh.nInternalFaces();
439 
440  // Check face in zone on both sides
441  if (myZoneFace[bFacei] != neiZoneFace[bFacei])
442  {
443  hasError = true;
444 
445  if (report)
446  {
447  Pout<< " ***Problem with faceZone " << name()
448  << ". Face " << facei
449  << " on coupled patch "
450  << bm[patchi].name()
451  << " is not consistent with its coupled neighbour."
452  << endl;
453  }
454  else
455  {
456  // w/o report - can stop checking now
457  break;
458  }
459  }
460  else if (myZoneFlip[bFacei] == neiZoneFlip[bFacei])
461  {
462  // Flip state should be opposite.
463  hasError = true;
464 
465  if (report)
466  {
467  Pout<< " ***Problem with faceZone " << name()
468  << ". Face " << facei
469  << " on coupled patch "
470  << bm[patchi].name()
471  << " does not have consistent flipMap"
472  << " across coupled faces."
473  << endl;
474  }
475  else
476  {
477  // w/o report - can stop checking now
478  break;
479  }
480  }
481  }
482  }
483  }
484 
485  return returnReduce(hasError, orOp<bool>());
486 }
487 
488 
489 void Foam::faceZone::insert(const Map<bool>& newIndices)
490 {
491  Map<bool> indices(*this, flipMap_);
492  indices.insert(newIndices);
493  reset(indices);
494 }
495 
496 
498 {
499  Zone::swap(fz);
500  flipMap_.swap(fz.flipMap_);
501 }
502 
503 
505 {
506  Map<bool> indices;
507  const labelList& faceMap = map.faceMap();
508  const labelList& reverseFaceMap = map.reverseFaceMap();
509  const labelHashSet& flipFaceFlux = map.flipFaceFlux();
510 
511  forAll(faceMap, facei)
512  {
513  const label i = localIndex(faceMap[facei]);
514  if (faceMap[facei] >= 0 && i != -1)
515  {
516  indices.insert
517  (
518  facei,
519  flipFaceFlux.found(facei)
520  ? !flipMap_[i]
521  : flipMap_[i]
522  );
523  }
524  }
525 
526  forAll(reverseFaceMap, facei)
527  {
528  const label i = localIndex(facei);
529  if (reverseFaceMap[facei] >= 0 && i != -1)
530  {
531  indices.insert
532  (
533  reverseFaceMap[facei],
534  flipFaceFlux.found(reverseFaceMap[facei])
535  ? !flipMap_[i]
536  : flipMap_[i]
537  );
538  }
539  }
540 
541  reset(indices);
542 }
543 
544 
546 {
547  if (patchPtr_)
548  {
549  patchPtr_->clearGeom();
550  }
551 }
552 
553 
555 {
556  os << nl << name() << nl << token::BEGIN_BLOCK << nl
557  << " type " << type() << token::END_STATEMENT << nl;
558 
559  writeEntry(os, this->labelsName, *this);
560  writeEntry(os, "flipMap", flipMap());
561 
562  os << token::END_BLOCK << endl;
563 }
564 
565 
566 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
567 
569 {
570  Zone::operator=(zn);
571  flipMap_ = zn.flipMap_;
572 }
573 
574 
576 {
577  Zone::operator=(move(zn));
578  flipMap_ = move(zn.flipMap_);
579 }
580 
581 
582 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Macros for easy insertion into run-time selection tables.
List< const_iterator > sorted() const
Return a sorted list of constant iterators.
Definition: HashTable.C:253
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
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:310
label size() const
Return the number of elements in the UList.
Definition: ListI.H:171
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
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:109
void swap(Zone &)
Swap two zones.
Definition: Zone.C:337
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:280
virtual void clearAddressing()
Clear addressing.
Definition: Zone.C:272
void operator=(const Zone &)
Assignment operator.
Definition: Zone.C:361
const faceZoneList & zones() const
Return ZonesType reference.
Definition: Zone.C:232
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:162
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:59
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: faceZone.C:392
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:204
void swap(faceZone &)
Swap two faceZones.
Definition: faceZone.C:497
const pointField & meshCentres() const
Return the mesh face centres.
Definition: faceZone.C:309
void operator=(const faceZone &)
Assignment to zone, clearing demand-driven data.
Definition: faceZone.C:568
boolList flipMap_
Flip map for all faces in the zone. Set to true if the.
Definition: faceZone.H:72
const primitiveFacePatch & patch() const
Return reference to primitive patch.
Definition: faceZone.C:315
const labelList & masterCells() const
Return labels of master cells (cells next to the master face.
Definition: faceZone.C:326
virtual void topoChange(const polyTopoChangeMap &)
Update zone using the given map.
Definition: faceZone.C:504
virtual void resetAddressing(const labelUList &, const boolList &)
Reset addressing and flip map (clearing demand-driven data)
Definition: faceZone.C:381
void calcCellLayers() const
Calculate master and slave face layer.
Definition: faceZone.C:96
void calcFaceZonePatch() const
Build primitive patch.
Definition: faceZone.C:49
void checkAddressing() const
Check addressing.
Definition: faceZone.C:155
faceZone(const word &name, const labelUList &addr, const boolList &fm, const faceZoneList &mz)
Construct from components.
Definition: faceZone.C:206
void reset(const Map< bool > &indices)
Reset the indices and flipMap from the given map.
Definition: faceZone.C:184
static const char *const labelsName
The name associated with the zone-labels dictionary entry.
Definition: faceZone.H:115
virtual void writeDict(Ostream &) const
Write dictionary.
Definition: faceZone.C:554
void insert(const Map< bool > &newIndices)
Insert given indices and corresponding face flips into zone.
Definition: faceZone.C:489
virtual void clearAddressing()
Clear addressing.
Definition: faceZone.C:367
virtual ~faceZone()
Destructor.
Definition: faceZone.C:301
virtual void movePoints(const pointField &)
Correct patch after moving points.
Definition: faceZone.C:545
primitiveFacePatch * patchPtr_
Primitive patch made out of correctly flipped faces.
Definition: faceZone.H:78
bool checkParallelSync(const bool report=false) const
Check whether all procs have faces synchronised. Return.
Definition: faceZone.C:402
const labelList & slaveCells() const
Return labels of slave cells.
Definition: faceZone.C:337
const labelList & meshEdges() const
Return global edge index for local edges.
Definition: faceZone.C:348
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:80
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1326
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:404
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
label nFaces() const
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &l)
Swap coupled boundary face values.
Definition: syncTools.H:436
@ BEGIN_BLOCK
Definition: token.H:113
@ END_BLOCK
Definition: token.H:114
@ END_STATEMENT
Definition: token.H:108
A class for handling words, derived from string.
Definition: word.H:62
#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.
Zone< faceZone, faceZoneList > faceZoneType
Definition: faceZone.C:37
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
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void writeEntry(Ostream &os, const HashTable< T, Key, Hash > &ht)
Definition: HashTableIO.C:96
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
defineTypeNameAndDebug(combustionModel, 0)
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
PrimitivePatch< List< face >, const pointField & > primitiveFacePatch
Foam::primitiveFacePatch.
error FatalError
defineTemplateRunTimeSelectionTable(fvLabelFieldSource, null)
List< face > faceList
Definition: faceListFwd.H:41
static const char nl
Definition: Ostream.H:266
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
labelList f(nPoints)
dictionary dict
volScalarField & p