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-2019 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 "faceZoneMesh.H"
29 #include "polyMesh.H"
30 #include "primitiveMesh.H"
31 #include "demandDrivenData.H"
32 #include "mapPolyMesh.H"
33 #include "syncTools.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(faceZone, 0);
40  defineRunTimeSelectionTable(faceZone, dictionary);
41  addToRunTimeSelectionTable(faceZone, faceZone, dictionary);
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  zoneMesh().mesh().points()
68  );
69 
70  primitiveFacePatch& patch = *patchPtr_;
71 
72  const faceList& f = zoneMesh().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 = zoneMesh().mesh().faceOwner();
117  const labelList& nei = zoneMesh().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  zoneMesh().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 = zoneMesh().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 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
185 
187 (
188  const word& name,
189  const labelUList& addr,
190  const boolList& fm,
191  const label index,
192  const faceZoneMesh& zm
193 )
194 :
195  zone(name, addr, index),
196  flipMap_(fm),
197  zoneMesh_(zm),
198  patchPtr_(nullptr),
199  masterCellsPtr_(nullptr),
200  slaveCellsPtr_(nullptr),
201  mePtr_(nullptr)
202 {
203  checkAddressing();
204 }
205 
206 
208 (
209  const word& name,
210  labelList&& addr,
211  boolList&& fm,
212  const label index,
213  const faceZoneMesh& zm
214 )
215 :
216  zone(name, move(addr), index),
217  flipMap_(move(fm)),
218  zoneMesh_(zm),
219  patchPtr_(nullptr),
220  masterCellsPtr_(nullptr),
221  slaveCellsPtr_(nullptr),
222  mePtr_(nullptr)
223 {
224  checkAddressing();
225 }
226 
227 
229 (
230  const word& name,
231  const dictionary& dict,
232  const label index,
233  const faceZoneMesh& zm
234 )
235 :
236  zone(name, dict, this->labelsName, index),
237  flipMap_(dict.lookup("flipMap")),
238  zoneMesh_(zm),
239  patchPtr_(nullptr),
240  masterCellsPtr_(nullptr),
241  slaveCellsPtr_(nullptr),
242  mePtr_(nullptr)
243 {
244  checkAddressing();
245 }
246 
247 
249 (
250  const faceZone& fz,
251  const labelUList& addr,
252  const boolList& fm,
253  const label index,
254  const faceZoneMesh& zm
255 )
256 :
257  zone(fz, addr, index),
258  flipMap_(fm),
259  zoneMesh_(zm),
260  patchPtr_(nullptr),
261  masterCellsPtr_(nullptr),
262  slaveCellsPtr_(nullptr),
263  mePtr_(nullptr)
264 {
265  checkAddressing();
266 }
267 
268 
270 (
271  const faceZone& fz,
272  labelList&& addr,
273  boolList&& fm,
274  const label index,
275  const faceZoneMesh& zm
276 )
277 :
278  zone(fz, move(addr), index),
279  flipMap_(move(fm)),
280  zoneMesh_(zm),
281  patchPtr_(nullptr),
282  masterCellsPtr_(nullptr),
283  slaveCellsPtr_(nullptr),
284  mePtr_(nullptr)
285 {
286  checkAddressing();
287 }
288 
289 
290 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
291 
293 {
294  clearAddressing();
295 }
296 
297 
298 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
299 
301 {
302  return zoneMesh_;
303 }
304 
305 
306 Foam::label Foam::faceZone::whichFace(const label globalFaceID) const
307 {
308  return zone::localID(globalFaceID);
309 }
310 
311 
313 {
314  if (!patchPtr_)
315  {
316  calcFaceZonePatch();
317  }
318 
319  return *patchPtr_;
320 }
321 
322 
324 {
325  if (!masterCellsPtr_)
326  {
327  calcCellLayers();
328  }
329 
330  return *masterCellsPtr_;
331 }
332 
333 
335 {
336  if (!slaveCellsPtr_)
337  {
338  calcCellLayers();
339  }
340 
341  return *slaveCellsPtr_;
342 }
343 
344 
346 {
347  if (!mePtr_)
348  {
349  mePtr_ =
350  new labelList
351  (
352  operator()().meshEdges
353  (
354  zoneMesh().mesh().edges(),
355  zoneMesh().mesh().pointEdges()
356  )
357  );
358  }
359 
360  return *mePtr_;
361 }
362 
363 
365 {
367 
368  deleteDemandDrivenData(patchPtr_);
369 
370  deleteDemandDrivenData(masterCellsPtr_);
371  deleteDemandDrivenData(slaveCellsPtr_);
372 
373  deleteDemandDrivenData(mePtr_);
374 }
375 
376 
378 (
379  const labelUList& addr,
380  const boolList& flipMap
381 )
382 {
383  clearAddressing();
384  labelList::operator=(addr);
385  flipMap_ = flipMap;
386 }
387 
388 
390 {
391  clearAddressing();
392 
393  labelList newAddressing(size());
394  boolList newFlipMap(flipMap_.size());
395  label nFaces = 0;
396 
397  const labelList& faceMap = mpm.reverseFaceMap();
398 
399  forAll(*this, i)
400  {
401  const label facei = operator[](i);
402 
403  if (faceMap[facei] >= 0)
404  {
405  newAddressing[nFaces] = faceMap[facei];
406  newFlipMap[nFaces] = flipMap_[i]; // Keep flip map.
407  nFaces++;
408  }
409  }
410 
411  newAddressing.setSize(nFaces);
412  newFlipMap.setSize(nFaces);
413 
414  transfer(newAddressing);
415  flipMap_.transfer(newFlipMap);
416 }
417 
418 
419 bool Foam::faceZone::checkDefinition(const bool report) const
420 {
421  return zone::checkDefinition(zoneMesh().mesh().faces().size(), report);
422 }
423 
424 
425 bool Foam::faceZone::checkParallelSync(const bool report) const
426 {
427  const polyMesh& mesh = zoneMesh().mesh();
428  const polyBoundaryMesh& bm = mesh.boundaryMesh();
429 
430  bool hasError = false;
431 
432 
433  // Check that zone faces are synced
434  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
435 
436  {
437  boolList neiZoneFace(mesh.nFaces()-mesh.nInternalFaces(), false);
438  boolList neiZoneFlip(mesh.nFaces()-mesh.nInternalFaces(), false);
439  forAll(*this, i)
440  {
441  const label facei = operator[](i);
442 
443  if (!mesh.isInternalFace(facei))
444  {
445  neiZoneFace[facei-mesh.nInternalFaces()] = true;
446  neiZoneFlip[facei-mesh.nInternalFaces()] = flipMap()[i];
447  }
448  }
449  boolList myZoneFace(neiZoneFace);
450  syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
451  boolList myZoneFlip(neiZoneFlip);
452  syncTools::swapBoundaryFaceList(mesh, neiZoneFlip);
453 
454  forAll(*this, i)
455  {
456  const label facei = operator[](i);
457  const label patchi = bm.whichPatch(facei);
458 
459  if (patchi != -1 && bm[patchi].coupled())
460  {
461  const label bFacei = facei-mesh.nInternalFaces();
462 
463  // Check face in zone on both sides
464  if (myZoneFace[bFacei] != neiZoneFace[bFacei])
465  {
466  hasError = true;
467 
468  if (report)
469  {
470  Pout<< " ***Problem with faceZone " << index()
471  << " named " << name()
472  << ". Face " << facei
473  << " on coupled patch "
474  << bm[patchi].name()
475  << " is not consistent with its coupled neighbour."
476  << endl;
477  }
478  else
479  {
480  // w/o report - can stop checking now
481  break;
482  }
483  }
484  else if (myZoneFlip[bFacei] == neiZoneFlip[bFacei])
485  {
486  // Flip state should be opposite.
487  hasError = true;
488 
489  if (report)
490  {
491  Pout<< " ***Problem with faceZone " << index()
492  << " named " << name()
493  << ". Face " << facei
494  << " on coupled patch "
495  << bm[patchi].name()
496  << " does not have consistent flipMap"
497  << " across coupled faces."
498  << endl;
499  }
500  else
501  {
502  // w/o report - can stop checking now
503  break;
504  }
505  }
506  }
507  }
508  }
509 
510  return returnReduce(hasError, orOp<bool>());
511 }
512 
513 
515 {
516  if (patchPtr_)
517  {
518  patchPtr_->movePoints(p);
519  }
520 }
521 
523 {
524  os << nl << name()
525  << nl << static_cast<const labelList&>(*this)
526  << nl << flipMap();
527 }
528 
529 
531 {
532  os << nl << name() << nl << token::BEGIN_BLOCK << nl
533  << " type " << type() << token::END_STATEMENT << nl;
534 
535  writeEntry(os, this->labelsName, *this);
536  writeEntry(os, "flipMap", flipMap());
537 
538  os << token::END_BLOCK << endl;
539 }
540 
541 
542 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
543 
545 {
546  clearAddressing();
547  zone::operator=(zn);
548  flipMap_ = zn.flipMap_;
549 }
550 
551 
553 {
554  clearAddressing();
555  zone::operator=(move(zn));
556  flipMap_ = move(zn.flipMap_);
557 }
558 
559 
560 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
561 
563 {
564  zn.write(os);
565  os.check("Ostream& operator<<(Ostream&, const faceZone&");
566  return os;
567 }
568 
569 
570 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:434
virtual void clearAddressing()
Clear addressing.
Definition: zone.C:183
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
virtual void resetAddressing(const labelUList &, const boolList &)
Reset addressing and flip map (clearing demand-driven data)
Definition: faceZone.C:378
const word & name() const
Return name.
Definition: IOobject.H:295
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:530
void calcFaceZonePatch() const
Build primitive patch.
Definition: faceZone.C:49
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
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:292
label nFaces() const
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
List< face > faceList
Definition: faceListFwd.H:43
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
const labelList & masterCells() const
Return labels of master cells (cells next to the master face.
Definition: faceZone.C:323
virtual bool checkParallelSync(const bool report=false) const
Check whether all procs have faces synchronised. Return.
Definition: faceZone.C:425
label whichFace(const label globalCellID) const
Helper function to re-direct to zone::localID(...)
Definition: faceZone.C:306
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
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:514
faceZone(const word &name, const labelUList &addr, const boolList &fm, const label index, const faceZoneMesh &zm)
Construct from components.
Definition: faceZone.C:187
void calcCellLayers() const
Calculate master and slave face layer.
Definition: faceZone.C:96
A list of faces which address into the list of points.
dynamicFvMesh & mesh
const pointField & points
Base class for zones.
Definition: zone.H:57
A class for handling words, derived from string.
Definition: word.H:59
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:544
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:345
void checkAddressing() const
Check addressing.
Definition: faceZone.C:155
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:522
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
static const char nl
Definition: Ostream.H:265
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
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:334
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
virtual void clearAddressing()
Clear addressing.
Definition: faceZone.C:364
static const char *const labelsName
The name associated with the zone-labels dictionary entry.
Definition: faceZone.H:121
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:80
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
virtual void updateMesh(const mapPolyMesh &)
Update for changes in topology.
Definition: faceZone.C:389
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:419
const faceZoneMesh & zoneMesh() const
Return zoneMesh reference.
Definition: faceZone.C:300
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:74
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &l)
Swap coupled boundary face values.
Definition: syncTools.H:430
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:64
volScalarField & p
void deleteDemandDrivenData(DataPtr &dataPtr)
Foam::faceZoneMesh.
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:312
const labelList & reverseFaceMap() const
Reverse face map.
Definition: mapPolyMesh.H:490
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:583
#define InfoInFunction
Report an information message using Foam::Info.