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