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