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