faceZoneSet.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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2018-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "faceZoneSet.H"
30#include "mapPolyMesh.H"
31#include "polyMesh.H"
32#include "setToFaceZone.H"
33#include "setsToFaceZone.H"
34#include "syncTools.H"
35
37
38// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39
40namespace Foam
41{
46}
47
48
49// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50
52{
53 labelList order(sortedOrder(addressing_));
54 addressing_ = labelUIndList(addressing_, order)();
55 flipMap_ = boolUIndList(flipMap_, order)();
56
58 faceSet::resize(2*addressing_.size());
59 faceSet::set(addressing_);
60}
61
62
63// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
64
66(
67 const polyMesh& mesh,
68 const word& name,
69 readOption r,
71)
72:
73 faceSet(mesh, name, 1024), // do not read faceSet
74 mesh_(mesh),
75 addressing_(),
76 flipMap_()
77{
78 const faceZoneMesh& faceZones = mesh.faceZones();
79 label zoneID = faceZones.findZoneID(name);
80
81 if
82 (
85 || (r == IOobject::READ_IF_PRESENT && zoneID != -1)
86 )
87 {
88 const faceZone& fz = faceZones[zoneID];
89 addressing_ = fz.addressing();
90 flipMap_ = fz.flipMap();
91 }
92
93 updateSet();
94
95 check(mesh.nFaces());
96}
97
98
100(
101 const polyMesh& mesh,
102 const word& name,
103 const label size,
105)
106:
107 faceSet(mesh, name, size, w),
108 mesh_(mesh),
109 addressing_(),
110 flipMap_()
111{
112 updateSet();
113}
114
115
117(
118 const polyMesh& mesh,
119 const word& name,
120 const topoSet& set,
122)
123:
124 faceSet(mesh, name, set.size(), w),
125 mesh_(mesh),
126 addressing_(refCast<const faceZoneSet>(set).addressing()),
127 flipMap_(refCast<const faceZoneSet>(set).flipMap())
128{
129 updateSet();
130}
131
132
133// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
134
135void Foam::faceZoneSet::invert(const label maxLen)
136{
137 // Count
138 label n = 0;
139
140 for (label facei = 0; facei < maxLen; ++facei)
141 {
142 if (!found(facei))
143 {
144 ++n;
145 }
146 }
147
148 // Fill
149 addressing_.setSize(n);
150 flipMap_.setSize(n);
151 n = 0;
152
153 for (label facei = 0; facei < maxLen; ++facei)
154 {
155 if (!found(facei))
156 {
157 addressing_[n] = facei;
158 flipMap_[n] = false; //? or true?
159 ++n;
160 }
161 }
162 updateSet();
163}
164
165
167{
168 label nConflict = 0;
169
170 DynamicList<label> newAddressing(addressing_.size());
171 DynamicList<bool> newFlipMap(flipMap_.size());
172
173 Map<label> faceToIndex(addressing_.size());
174 forAll(addressing_, i)
175 {
176 faceToIndex.insert(addressing_[i], i);
177 }
178
179 const faceZoneSet& zoneSet = refCast<const faceZoneSet>(set);
180
181 forAll(zoneSet.addressing(), i)
182 {
183 const label facei = zoneSet.addressing()[i];
184
185 const auto iter = faceToIndex.cfind(facei);
186
187 if (iter.found())
188 {
189 const label index = *iter;
190
191 if (zoneSet.flipMap()[i] != flipMap_[index])
192 {
193 ++nConflict;
194 }
195 newAddressing.append(facei);
196 newFlipMap.append(flipMap_[index]);
197 }
198 }
199
200 if (nConflict > 0)
201 {
203 << "subset : there are " << nConflict
204 << " faces with different orientation in faceZonesSets "
205 << name() << " and " << set.name() << endl;
206 }
207
208 addressing_.transfer(newAddressing);
209 flipMap_.transfer(newFlipMap);
210 updateSet();
211}
212
213
215{
216 label nConflict = 0;
217
218 DynamicList<label> newAddressing(addressing_);
219 DynamicList<bool> newFlipMap(flipMap_);
220
221 Map<label> faceToIndex(addressing_.size());
222 forAll(addressing_, i)
223 {
224 faceToIndex.insert(addressing_[i], i);
225 }
226
227 const faceZoneSet& zoneSet = refCast<const faceZoneSet>(set);
228
229 forAll(zoneSet.addressing(), i)
230 {
231 label facei = zoneSet.addressing()[i];
232
233 const auto iter = faceToIndex.cfind(facei);
234
235 if (iter.found())
236 {
237 const label index = *iter;
238
239 if (zoneSet.flipMap()[i] != flipMap_[index])
240 {
241 ++nConflict;
242 }
243 }
244 else
245 {
246 newAddressing.append(facei);
247 newFlipMap.append(zoneSet.flipMap()[i]);
248 }
249 }
250
251 if (nConflict > 0)
252 {
254 << "addSet : there are " << nConflict
255 << " faces with different orientation in faceZonesSets "
256 << name() << " and " << set.name() << endl;
257 }
258
259 addressing_.transfer(newAddressing);
260 flipMap_.transfer(newFlipMap);
261 updateSet();
262}
263
264
266{
267 label nConflict = 0;
268
269 DynamicList<label> newAddressing(addressing_.size());
270 DynamicList<bool> newFlipMap(flipMap_.size());
271
272 const faceZoneSet& zoneSet = refCast<const faceZoneSet>(set);
273
274 Map<label> faceToIndex(zoneSet.addressing().size());
275 forAll(zoneSet.addressing(), i)
276 {
277 faceToIndex.insert(zoneSet.addressing()[i], i);
278 }
279
280 forAll(addressing_, i)
281 {
282 const label facei = addressing_[i];
283
284 const auto iter = faceToIndex.cfind(facei);
285
286 if (iter.found())
287 {
288 const label index = *iter;
289
290 if (zoneSet.flipMap()[index] != flipMap_[i])
291 {
292 ++nConflict;
293 }
294 }
295 else
296 {
297 // Not found in zoneSet so add
298 newAddressing.append(facei);
299 newFlipMap.append(zoneSet.flipMap()[i]);
300 }
301 }
302
303 if (nConflict > 0)
304 {
306 << "subtractSet : there are " << nConflict
307 << " faces with different orientation in faceZonesSets "
308 << name() << " and " << set.name() << endl;
309 }
310
311 addressing_.transfer(newAddressing);
312 flipMap_.transfer(newFlipMap);
313 updateSet();
314}
315
316
318{
319 // Make sure that the faceZone is consistent with the faceSet
320 {
321 const labelHashSet zoneSet(addressing_);
322
323 // Elements that are in zone but not faceSet, and
324 // elements that are in faceSet but not in zone
325 labelHashSet badSet(*this ^ zoneSet);
326
327 const label nBad = returnReduce(badSet.size(), sumOp<label>());
328
329 if (nBad)
330 {
331 WarningInFunction << "Detected " << nBad
332 << " faces that are in the faceZone but not"
333 << " in the faceSet or vice versa."
334 << " The faceZoneSet should only be manipulated"
335 << " using " << setsToFaceZone::typeName
336 << " or " << setToFaceZone::typeName << endl;
337 }
338 }
339
340
341 // Make sure that on coupled faces orientation is opposite. Pushes
342 // master orientation to slave in case of conflict.
343
344
345 // 0 : not in faceZone
346 // 1 : in faceZone and unflipped
347 //-1 : in faceZone and flipped
348 const label UNFLIPPED = 1;
349 const label FLIPPED = -1;
350 labelList myZoneFace(mesh.nBoundaryFaces(), Zero);
351
352 forAll(addressing_, i)
353 {
354 const label bFacei = addressing_[i]-mesh.nInternalFaces();
355
356 if (bFacei >= 0)
357 {
358 if (flipMap_[i])
359 {
360 myZoneFace[bFacei] = FLIPPED;
361 }
362 else
363 {
364 myZoneFace[bFacei] = UNFLIPPED;
365 }
366 }
367 }
368
369 labelList neiZoneFace(myZoneFace);
371
372
373 const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
374
375
376 // Rebuild faceZone addressing and flipMap
377 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
378
379 DynamicList<label> newAddressing(addressing_.size());
380 DynamicList<bool> newFlipMap(flipMap_.size());
381
382 forAll(addressing_, i)
383 {
384 const label facei = addressing_[i];
385 if (facei < mesh.nInternalFaces())
386 {
387 newAddressing.append(facei);
388 newFlipMap.append(flipMap_[i]);
389 }
390 }
391
392 for (label facei = mesh.nInternalFaces(); facei < mesh.nFaces(); facei++)
393 {
394 label myStat = myZoneFace[facei-mesh.nInternalFaces()];
395 label neiStat = neiZoneFace[facei-mesh.nInternalFaces()];
396
397 if (myStat == 0)
398 {
399 if (neiStat == UNFLIPPED)
400 {
401 // Neighbour is unflipped so I am flipped
402 newAddressing.append(facei);
403 newFlipMap.append(true);
404 }
405 else if (neiStat == FLIPPED)
406 {
407 newAddressing.append(facei);
408 newFlipMap.append(false);
409 }
410 }
411 else
412 {
413 if (myStat == neiStat)
414 {
415 // Conflict. masterFace wins
416 newAddressing.append(facei);
417 if (isMasterFace[facei])
418 {
419 newFlipMap.append(myStat == FLIPPED);
420 }
421 else
422 {
423 newFlipMap.append(neiStat == UNFLIPPED);
424 }
425 }
426 else
427 {
428 newAddressing.append(facei);
429 newFlipMap.append(myStat == FLIPPED);
430 }
431 }
432 }
433
434 addressing_.transfer(newAddressing);
435 flipMap_.transfer(newFlipMap);
436 updateSet();
437}
438
439
440Foam::label Foam::faceZoneSet::maxSize(const polyMesh& mesh) const
441{
442 return mesh.nFaces();
443}
444
445
447(
448 IOstreamOption streamOpt,
449 const bool valid
450) const
451{
452 // Write shadow faceSet
453 word oldTypeName = typeName;
454 const_cast<word&>(type()) = faceSet::typeName;
455 bool ok = faceSet::writeObject(streamOpt, valid);
456 const_cast<word&>(type()) = oldTypeName;
457
458 // Modify faceZone
459 faceZoneMesh& faceZones = const_cast<polyMesh&>(mesh_).faceZones();
460 label zoneID = faceZones.findZoneID(name());
461
462 if (zoneID == -1)
463 {
464 zoneID = faceZones.size();
465
466 faceZones.setSize(zoneID+1);
467 faceZones.set
468 (
469 zoneID,
470 new faceZone
471 (
472 name(),
473 addressing_,
474 flipMap_,
475 zoneID,
476 faceZones
477 )
478 );
479 }
480 else
481 {
482 faceZones[zoneID].resetAddressing(addressing_, flipMap_);
483 }
484 faceZones.clearAddressing();
485
486 return ok && faceZones.write(valid);
487}
488
489
491{
492 // faceZone
493 labelList newAddressing(addressing_.size());
494 boolList newFlipMap(flipMap_.size(), false);
495
496 label n = 0;
497 forAll(addressing_, i)
498 {
499 label facei = addressing_[i];
500 label newFacei = morphMap.reverseFaceMap()[facei];
501 if (newFacei >= 0)
502 {
503 newAddressing[n] = newFacei;
504 newFlipMap[n] = flipMap_[i];
505 n++;
506 }
507 }
508 newAddressing.setSize(n);
509 newFlipMap.setSize(n);
510
511 addressing_.transfer(newAddressing);
512 flipMap_.transfer(newFlipMap);
513
514 updateSet();
515}
516
517
519(
520 Ostream& os,
521 const primitiveMesh& mesh,
522 const label maxLen
523) const
524{
525 faceSet::writeDebug(os, mesh, maxLen);
526}
527
528
529// ************************************************************************* //
bool found
label n
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
label maxSize() const
The max row length used.
void invert()
Return the matrix inverse into itself if no elem is equal to zero.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:141
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:52
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:65
writeOption
Enumeration defining the write options.
Definition: IOobject.H:186
readOption
Enumeration defining the read options.
Definition: IOobject.H:177
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:180
The IOstreamOption is a simple container for options an IOstream can normally have.
void setSize(const label n)
Alias for resize()
Definition: List.H:218
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
void clearStorage()
Clear the list and delete storage.
Definition: PackedListI.H:520
const T * set(const label i) const
Definition: PtrList.H:138
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:525
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:715
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options.
A list of face labels.
Definition: faceSet.H:54
Like faceSet but -reads data from faceZone -updates faceZone when writing.
Definition: faceZoneSet.H:54
const boolList & flipMap() const noexcept
Definition: faceZoneSet.H:117
virtual void subtractSet(const topoSet &set)
Subtract elements present in set.
Definition: faceZoneSet.C:265
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write faceZone using stream options.
Definition: faceZoneSet.C:447
const labelList & addressing() const noexcept
Definition: faceZoneSet.H:106
virtual void addSet(const topoSet &set)
Add elements present in set.
Definition: faceZoneSet.C:214
virtual void subset(const topoSet &set)
Subset contents. Only elements present in both sets remain.
Definition: faceZoneSet.C:166
void updateSet()
Sort addressing and make faceSet part consistent with addressing.
Definition: faceZoneSet.C:51
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:67
const boolList & flipMap() const noexcept
Return face flip map.
Definition: faceZone.H:272
void sync()
Do all: synchronise all IOFields and objectRegistry.
Definition: syncObjects.C:70
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:162
const labelList & reverseFaceMap() const
Reverse face map.
Definition: mapPolyMesh.H:501
void updateMesh()
Update for new mesh topology.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:498
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:79
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
label nInternalFaces() const noexcept
Number of internal faces.
label nFaces() const noexcept
Number of mesh faces.
void writeDebug() const
Debug write.
virtual bool write(const bool valid=true) const
Write using setting from DB.
static bitSet getMasterFaces(const polyMesh &mesh)
Definition: syncTools.C:126
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues)
Swap coupled boundary face values. Uses eqOp.
Definition: syncTools.H:445
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:67
virtual void check(const label maxSize)
Check limits on addressable range.
Definition: topoSet.C:203
bool set() const
Are all the vector set.
Definition: triadI.H:76
A class for handling words, derived from Foam::string.
Definition: word.H:68
const labelList & addressing() const noexcept
The addressing used by the zone.
Definition: zone.H:147
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
dynamicFvMesh & mesh
OBJstream os(runTime.globalPath()/outputName)
const labelIOList & zoneID
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
To & refCast(From &r)
Reference type cast template function.
Definition: typeInfo.H:131
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
UIndirectList< bool > boolUIndList
UIndirectList of bools.
Definition: IndirectList.H:67
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
UIndirectList< label > labelUIndList
UIndirectList of labels.
Definition: IndirectList.H:68
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
static const char *const typeName
The type name used in ensight case files.