faceZoneSet.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 "faceZoneSet.H"
27 #include "polyTopoChangeMap.H"
28 #include "polyMesh.H"
29 #include "setToFaceZone.H"
30 #include "setsToFaceZone.H"
31 #include "syncTools.H"
32 
34 
35 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 defineTypeNameAndDebug(faceZoneSet, 0);
43 
44 addToRunTimeSelectionTable(topoSet, faceZoneSet, word);
45 addToRunTimeSelectionTable(topoSet, faceZoneSet, size);
46 addToRunTimeSelectionTable(topoSet, faceZoneSet, set);
47 
48 
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 
52 {
53  labelList order;
54  sortedOrder(addressing_, order);
55  addressing_ = UIndirectList<label>(addressing_, order)();
56  flipMap_ = UIndirectList<bool>(flipMap_, order)();
57 
59  faceSet::resize(2*addressing_.size());
60  forAll(addressing_, i)
61  {
62  faceSet::insert(addressing_[i]);
63  }
64 }
65 
66 
67 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
68 
70 (
71  const polyMesh& mesh,
72  const word& name,
73  readOption r,
74  writeOption w
75 )
76 :
77  faceSet(mesh, name, 1000), // do not read faceSet
78  mesh_(mesh),
79  addressing_(0),
80  flipMap_(0)
81 {
82  const meshFaceZones& faceZones = mesh.faceZones();
83  label zoneID = faceZones.findZoneID(name);
84 
85  if
86  (
87  (r == IOobject::MUST_READ)
89  || (r == IOobject::READ_IF_PRESENT && zoneID != -1)
90  )
91  {
92  const faceZone& fz = faceZones[zoneID];
93  addressing_ = fz;
94  flipMap_ = fz.flipMap();
95  }
96 
97  updateSet();
98 
99  check(mesh.nFaces());
100 }
101 
102 
104 (
105  const polyMesh& mesh,
106  const word& name,
107  const label size,
108  writeOption w
109 )
110 :
111  faceSet(mesh, name, size, w),
112  mesh_(mesh),
113  addressing_(0),
114  flipMap_(0)
115 {
116  updateSet();
117 }
118 
119 
121 (
122  const polyMesh& mesh,
123  const word& name,
124  const topoSet& set,
125  writeOption w
126 )
127 :
128  faceSet(mesh, name, set.size(), w),
129  mesh_(mesh),
130  addressing_(refCast<const faceZoneSet>(set).addressing()),
131  flipMap_(refCast<const faceZoneSet>(set).flipMap())
132 {
133  updateSet();
134 }
135 
136 
137 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
138 
140 {}
141 
142 
143 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
144 
145 void faceZoneSet::invert(const label maxLen)
146 {
147  // Count
148  label n = 0;
149 
150  for (label facei = 0; facei < maxLen; facei++)
151  {
152  if (!found(facei))
153  {
154  n++;
155  }
156  }
157 
158  // Fill
159  addressing_.setSize(n);
160  flipMap_.setSize(n);
161  n = 0;
162 
163  for (label facei = 0; facei < maxLen; facei++)
164  {
165  if (!found(facei))
166  {
167  addressing_[n] = facei;
168  flipMap_[n] = false; //? or true?
169  n++;
170  }
171  }
172  updateSet();
173 }
174 
175 
176 void faceZoneSet::subset(const topoSet& set)
177 {
178  label nConflict = 0;
179 
180  DynamicList<label> newAddressing(addressing_.size());
181  DynamicList<bool> newFlipMap(flipMap_.size());
182 
183  Map<label> faceToIndex(addressing_.size());
184  forAll(addressing_, i)
185  {
186  faceToIndex.insert(addressing_[i], i);
187  }
188 
189  const faceZoneSet& fSet = refCast<const faceZoneSet>(set);
190 
191  forAll(fSet.addressing(), i)
192  {
193  label facei = fSet.addressing()[i];
194 
195  Map<label>::const_iterator iter = faceToIndex.find(facei);
196 
197  if (iter != faceToIndex.end())
198  {
199  label index = iter();
200 
201  if (fSet.flipMap()[i] != flipMap_[index])
202  {
203  nConflict++;
204  }
205  newAddressing.append(facei);
206  newFlipMap.append(flipMap_[index]);
207  }
208  }
209 
210  if (nConflict > 0)
211  {
213  << "subset : there are " << nConflict
214  << " faces with different orientation in faceZonesSets "
215  << name() << " and " << set.name() << endl;
216  }
217 
218  addressing_.transfer(newAddressing);
219  flipMap_.transfer(newFlipMap);
220  updateSet();
221 }
222 
223 
224 void faceZoneSet::addSet(const topoSet& set)
225 {
226  label nConflict = 0;
227 
228  DynamicList<label> newAddressing(addressing_);
229  DynamicList<bool> newFlipMap(flipMap_);
230 
231  Map<label> faceToIndex(addressing_.size());
232  forAll(addressing_, i)
233  {
234  faceToIndex.insert(addressing_[i], i);
235  }
236 
237  const faceZoneSet& fSet = refCast<const faceZoneSet>(set);
238 
239  forAll(fSet.addressing(), i)
240  {
241  label facei = fSet.addressing()[i];
242 
243  Map<label>::const_iterator iter = faceToIndex.find(facei);
244 
245  if (iter != faceToIndex.end())
246  {
247  label index = iter();
248 
249  if (fSet.flipMap()[i] != flipMap_[index])
250  {
251  nConflict++;
252  }
253  }
254  else
255  {
256  newAddressing.append(facei);
257  newFlipMap.append(fSet.flipMap()[i]);
258  }
259  }
260 
261  if (nConflict > 0)
262  {
264  << "addSet : there are " << nConflict
265  << " faces with different orientation in faceZonesSets "
266  << name() << " and " << set.name() << endl;
267  }
268 
269  addressing_.transfer(newAddressing);
270  flipMap_.transfer(newFlipMap);
271  updateSet();
272 }
273 
274 
276 {
277  label nConflict = 0;
278 
279  DynamicList<label> newAddressing(addressing_.size());
280  DynamicList<bool> newFlipMap(flipMap_.size());
281 
282  const faceZoneSet& fSet = refCast<const faceZoneSet>(set);
283 
284  Map<label> faceToIndex(fSet.addressing().size());
285  forAll(fSet.addressing(), i)
286  {
287  faceToIndex.insert(fSet.addressing()[i], i);
288  }
289 
290  forAll(addressing_, i)
291  {
292  label facei = addressing_[i];
293 
294  Map<label>::const_iterator iter = faceToIndex.find(facei);
295 
296  if (iter != faceToIndex.end())
297  {
298  label index = iter();
299 
300  if (fSet.flipMap()[index] != flipMap_[i])
301  {
302  nConflict++;
303  }
304  }
305  else
306  {
307  // Not found in fSet so add
308  newAddressing.append(facei);
309  newFlipMap.append(fSet.flipMap()[i]);
310  }
311  }
312 
313  if (nConflict > 0)
314  {
316  << "deleteSet : there are " << nConflict
317  << " faces with different orientation in faceZonesSets "
318  << name() << " and " << set.name() << endl;
319  }
320 
321  addressing_.transfer(newAddressing);
322  flipMap_.transfer(newFlipMap);
323  updateSet();
324 }
325 
326 
327 void faceZoneSet::sync(const polyMesh& mesh)
328 {
329  // Make sure that the faceZone is consistent with the faceSet
330  {
331  const labelHashSet zoneSet(addressing_);
332 
333  // Get elements that are in zone but not faceSet
334  labelHashSet badSet(zoneSet);
335  badSet -= *this;
336 
337  // Add elements that are in faceSet but not in zone
338  labelHashSet fSet(*this);
339  fSet -= zoneSet;
340 
341  badSet += fSet;
342 
343  label nBad = returnReduce(badSet.size(), sumOp<label>());
344 
345  if (nBad)
346  {
347  WarningInFunction << "Detected " << nBad
348  << " faces that are in the faceZone but not"
349  << " in the faceSet or vice versa."
350  << " The faceZoneSet should only be manipulated"
351  << " using " << setsToFaceZone::typeName
352  << " or " << setToFaceZone::typeName << endl;
353  }
354  }
355 
356 
357  // Make sure that on coupled faces orientation is opposite. Pushes
358  // master orientation to slave in case of conflict.
359 
360 
361  // 0 : not in faceZone
362  // 1 : in faceZone and unflipped
363  //-1 : in faceZone and flipped
364  const label UNFLIPPED = 1;
365  const label FLIPPED = -1;
366  labelList myZoneFace(mesh.nFaces()-mesh.nInternalFaces(), 0);
367 
368  forAll(addressing_, i)
369  {
370  label bFacei = addressing_[i]-mesh.nInternalFaces();
371 
372  if (bFacei >= 0)
373  {
374  if (flipMap_[i])
375  {
376  myZoneFace[bFacei] = FLIPPED;
377  }
378  else
379  {
380  myZoneFace[bFacei] = UNFLIPPED;
381  }
382  }
383  }
384 
385  labelList neiZoneFace(myZoneFace);
386  syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
387 
388 
389  const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
390 
391 
392  // Rebuild faceZone addressing and flipMap
393  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
394 
395  DynamicList<label> newAddressing(addressing_.size());
396  DynamicList<bool> newFlipMap(flipMap_.size());
397 
398  forAll(addressing_, i)
399  {
400  label facei = addressing_[i];
401  if (facei < mesh.nInternalFaces())
402  {
403  newAddressing.append(facei);
404  newFlipMap.append(flipMap_[i]);
405  }
406  }
407 
408  for (label facei = mesh.nInternalFaces(); facei < mesh.nFaces(); facei++)
409  {
410  label myStat = myZoneFace[facei-mesh.nInternalFaces()];
411  label neiStat = neiZoneFace[facei-mesh.nInternalFaces()];
412 
413  if (myStat == 0)
414  {
415  if (neiStat == UNFLIPPED)
416  {
417  // Neighbour is unflipped so I am flipped
418  newAddressing.append(facei);
419  newFlipMap.append(true);
420  }
421  else if (neiStat == FLIPPED)
422  {
423  newAddressing.append(facei);
424  newFlipMap.append(false);
425  }
426  }
427  else
428  {
429  if (myStat == neiStat)
430  {
431  // Conflict. masterFace wins
432  newAddressing.append(facei);
433  if (isMasterFace[facei])
434  {
435  newFlipMap.append(myStat == FLIPPED);
436  }
437  else
438  {
439  newFlipMap.append(neiStat == UNFLIPPED);
440  }
441  }
442  else
443  {
444  newAddressing.append(facei);
445  newFlipMap.append(myStat == FLIPPED);
446  }
447  }
448  }
449 
450  addressing_.transfer(newAddressing);
451  flipMap_.transfer(newFlipMap);
452  updateSet();
453 }
454 
455 
457 {
458  return mesh.nFaces();
459 }
460 
461 
463 (
467  const bool write
468 ) const
469 {
470  // Write shadow faceSet
471  word oldTypeName = typeName;
472  const_cast<word&>(type()) = faceSet::typeName;
473  bool ok = faceSet::writeObject(s, v, c, write);
474  const_cast<word&>(type()) = oldTypeName;
475 
476  // Modify faceZone
477  meshFaceZones& faceZones = const_cast<polyMesh&>(mesh_).faceZones();
478  label zoneID = faceZones.findZoneID(name());
479 
480  if (zoneID == -1)
481  {
482  zoneID = faceZones.size();
483 
484  faceZones.setSize(zoneID+1);
485  faceZones.set
486  (
487  zoneID,
488  new faceZone
489  (
490  name(),
491  addressing_,
492  flipMap_,
493  zoneID,
494  faceZones
495  )
496  );
497  }
498  else
499  {
500  faceZones[zoneID].resetAddressing(addressing_, flipMap_);
501  }
502  faceZones.clearAddressing();
503 
504  return ok && faceZones.write(write);
505 }
506 
507 
509 {
510  // faceZone
511  labelList newAddressing(addressing_.size());
512  boolList newFlipMap(flipMap_.size());
513 
514  label n = 0;
515  forAll(addressing_, i)
516  {
517  label facei = addressing_[i];
518  label newFacei = map.reverseFaceMap()[facei];
519  if (newFacei >= 0)
520  {
521  newAddressing[n] = newFacei;
522  newFlipMap[n] = flipMap_[i];
523  n++;
524  }
525  }
526  newAddressing.setSize(n);
527  newFlipMap.setSize(n);
528 
529  addressing_.transfer(newAddressing);
530  flipMap_.transfer(newFlipMap);
531 
532  updateSet();
533 }
534 
535 
537 (
538  Ostream& os,
539  const primitiveMesh& mesh,
540  const label maxLen
541 ) const
542 {
543  faceSet::writeDebug(os, mesh, maxLen);
544 }
545 
546 
547 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
548 
549 } // End namespace Foam
550 
551 // ************************************************************************* //
const boolList & flipMap() const
Definition: faceZoneSet.H:118
label findZoneID(const word &zoneName) const
Find zone index given a name.
Definition: MeshZones.C:341
faceZoneSet(const polyMesh &mesh, const word &name, readOption r=MUST_READ, writeOption w=NO_WRITE)
Construct from objectRegistry and name.
Definition: faceZoneSet.C:70
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
writeOption
Enumeration defining the write options.
Definition: IOobject.H:125
const word & name() const
Return name.
Definition: IOobject.H:315
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112
label nInternalFaces() const
virtual void topoChange(const polyTopoChangeMap &map)
Update any stored data for new labels.
Definition: faceZoneSet.C:508
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:74
label nFaces() const
virtual void invert(const label maxLen)
Invert contents. (insert all members 0..maxLen-1 which were not in.
Definition: faceZoneSet.C:145
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
const boolList & flipMap() const
Return face flip map.
Definition: faceZone.H:249
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
readOption
Enumeration defining the read options.
Definition: IOobject.H:116
bool insert(const label &key)
Insert a new entry.
Definition: HashSet.H:111
virtual void deleteSet(const topoSet &set)
Delete elements present in set.
Definition: faceZoneSet.C:275
static PackedBoolList getMasterFaces(const polyMesh &)
Get per face whether it is uncoupled or a master of a.
Definition: syncTools.C:153
void check(const label maxLabel)
Check validity of contents.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Macros for easy insertion into run-time selection tables.
virtual void writeDebug(Ostream &os, const primitiveMesh &, const label maxLen) const
Write maxLen items with label and coordinates.
Definition: faceSet.C:165
virtual ~faceZoneSet()
Destructor.
Definition: faceZoneSet.C:139
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:142
const labelList & reverseFaceMap() const
Reverse face map.
virtual void writeDebug(Ostream &os, const primitiveMesh &, const label maxLen) const
Write maxLen items with label and coordinates.
Definition: faceZoneSet.C:537
virtual label maxSize(const polyMesh &mesh) const
Return max index+1.
Definition: faceZoneSet.C:456
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
bool found(const label &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:113
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.
label size() const
Return the number of elements in the list.
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:86
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:193
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:54
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
faceSet(const IOobject &obj)
Construct from IOobject.
Definition: faceSet.C:49
virtual void subset(const topoSet &set)
Subset contents. Only elements present in both sets remain.
Definition: faceZoneSet.C:176
defineTypeNameAndDebug(combustionModel, 0)
virtual void sync(const polyMesh &mesh)
Sync faceZoneSet across coupled patches.
Definition: faceZoneSet.C:327
void updateSet()
Sort addressing and make faceSet part consistent with addressing.
Definition: faceZoneSet.C:51
Like faceSet but -reads data from faceZone -updates faceZone when writing.
Definition: faceZoneSet.H:49
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:61
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
void setSize(const label)
Reset size of List.
Definition: List.C:281
A bit-packed bool list.
#define WarningInFunction
Report a warning using Foam::Warning.
virtual void addSet(const topoSet &set)
Add elements present in set.
Definition: faceZoneSet.C:224
const meshFaceZones & faceZones() const
Return face zones.
Definition: polyMesh.H:495
A List with indirect addressing.
Definition: fvMatrix.H:106
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
Version number type.
Definition: IOstream.H:96
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool write=true) const
Write faceZone.
Definition: faceZoneSet.C:463
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool write) const
Write using given format, version and compression.
label n
void resize(const label newSize)
Resize the hash table for efficiency.
Definition: HashTable.C:432
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
virtual bool write(const bool write=true) const
Write using setting from DB.
void clearAddressing()
Clear addressing.
Definition: MeshZones.C:387
const labelList & addressing() const
Definition: faceZoneSet.H:107
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
Namespace for OpenFOAM.
void clearStorage()
Clear the table entries and the table itself.
Definition: HashTable.C:492