Loading...
Searching...
No Matches
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-2024 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#include "ListOps.H"
39// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40
41namespace Foam
42{
47}
48
49
50// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51
53{
54 if (flipMap_.size() == addressing_.size())
55 {
56 labelList order(Foam::sortedOrder(addressing_));
57 addressing_ = labelUIndList(addressing_, order)();
58 flipMap_ = boolUIndList(flipMap_, order)();
59 }
60 else
61 {
62 Foam::sort(addressing_);
63 flipMap_.resize_nocopy(addressing_.size());
64 flipMap_ = false;
65 }
66
68 faceSet::reserve(addressing_.size());
69 faceSet::set(addressing_);
70}
71
72
73// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
74
76(
77 const polyMesh& mesh,
78 const word& name,
79 const label initialCapacity,
82:
83 faceSet(mesh, name, initialCapacity, wOpt), // Construct no-read
84 mesh_(mesh)
85{}
86
87
89(
90 const polyMesh& mesh,
91 const word& name,
94)
95:
96 faceZoneSet(mesh, name, label(0), wOpt) // Construct no-read
97{
98 const auto& zones = mesh.faceZones();
99 const auto* zonePtr = zones.cfindZone(name);
100
101 if (!zonePtr)
102 {
104 {
106 << "Zone named " << name << " not found. "
107 << "List of available zone names: " << zones.names() << nl
108 << exit(FatalError);
109 }
110 }
111 else if (IOobjectOption::isAnyRead(rOpt))
112 {
113 const auto& zn = *zonePtr;
114 addressing_ = zn.addressing();
115 flipMap_ = zn.flipMap();
117
118 updateSet();
119 check(mesh.nFaces());
120}
121
122
124(
125 const polyMesh& mesh,
126 const word& name,
127 const topoSet& set,
129)
130:
131 faceZoneSet(mesh, name, label(0), wOpt) // Construct no-read
132{
133 const auto* zonePtr = isA<faceZoneSet>(set);
134
135 if (zonePtr)
136 {
137 addressing_ = zonePtr->addressing();
138 flipMap_ = zonePtr->flipMap();
139 }
140 else
141 {
142 // No flipMap for faceSet - handled in updateSet()
143 addressing_ = set.sortedToc();
144 }
146 updateSet();
147}
148
149
150// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151
152void Foam::faceZoneSet::invert(const label maxLen)
153{
154 // Count
155 label n = 0;
156
157 for (label id = 0; id < maxLen; ++id)
158 {
159 if (!topoSet::contains(id))
160 {
161 ++n;
162 }
163 }
164
165 // Fill
166 addressing_.resize_nocopy(n);
167 flipMap_.resize_nocopy(n);
168 n = 0;
169
170 for (label id = 0; id < maxLen; ++id)
171 {
172 if (!topoSet::contains(id))
173 {
174 addressing_[n] = id;
175 flipMap_[n] = false; //? or true?
176 ++n;
177 }
178 }
179 updateSet();
180}
181
182
183void Foam::faceZoneSet::subset
184(
185 const word& setName,
186 const labelUList& setAddressing,
187 const UList<bool>& setFlipMap
188)
189{
190 label nConflict = 0;
191
192 DynamicList<label> newAddressing(addressing_.size());
193 DynamicList<bool> newFlipMap(flipMap_.size());
194
195 Map<label> faceToIndex(invertToMap(addressing_));
196
197 forAll(setAddressing, i)
198 {
199 const label facei = setAddressing[i];
200
201 const auto iter = faceToIndex.cfind(facei);
202
203 if (iter.good())
204 {
205 const label index = iter.val();
206
207 if (setFlipMap.size() && (setFlipMap[i] != flipMap_[index]))
208 {
209 ++nConflict;
210 }
211 newAddressing.append(facei);
212 newFlipMap.append(flipMap_[index]);
213 }
214 }
215
216 if (nConflict)
217 {
219 << "subset : there are " << nConflict
220 << " faces with different orientation in faceZoneSets "
221 << name() << " and " << setName << endl;
222 }
224 addressing_.transfer(newAddressing);
225 flipMap_.transfer(newFlipMap);
226 updateSet();
227}
228
229
230void Foam::faceZoneSet::subset(const topoSet& set)
231{
232 const auto* zonePtr = isA<faceZoneSet>(set);
233
234 if (zonePtr)
235 {
236 subset(zonePtr->name(), zonePtr->addressing(), zonePtr->flipMap());
237 }
238 else
239 {
240 // Assume a faceSet. Ignore flipMap
241 subset
242 (
243 set.name(),
246 );
247 }
248}
249
250
251void Foam::faceZoneSet::subset(const labelUList& elems)
252{
254}
255
256
257void Foam::faceZoneSet::addSet
258(
259 const word& setName,
260 const labelUList& setAddressing,
261 const UList<bool>& setFlipMap
262)
263{
264 label nConflict = 0;
265
266 DynamicList<label> newAddressing(addressing_);
267 DynamicList<bool> newFlipMap(flipMap_);
268
269 Map<label> faceToIndex(invertToMap(addressing_));
270
271 forAll(setAddressing, i)
272 {
273 const label facei = setAddressing[i];
274 const auto iter = faceToIndex.cfind(facei);
275
276 if (iter.good())
277 {
278 const label index = iter.val();
279
280 if (setFlipMap.size() && (setFlipMap[i] != flipMap_[index]))
281 {
282 ++nConflict;
283 }
284 }
285 else
286 {
287 newAddressing.append(facei);
288 newFlipMap.append(setFlipMap.size() ? setFlipMap[i] : false);
289 }
290 }
291
292 if (nConflict > 0)
293 {
295 << "addSet : there are " << nConflict
296 << " faces with different orientation in faceZonesSets "
297 << name() << " and " << setName << endl;
298 }
300 addressing_.transfer(newAddressing);
301 flipMap_.transfer(newFlipMap);
302 updateSet();
303}
304
305
306void Foam::faceZoneSet::addSet(const topoSet& set)
307{
308 const auto* zonePtr = isA<faceZoneSet>(set);
309
310 if (zonePtr)
311 {
312 addSet(zonePtr->name(), zonePtr->addressing(), zonePtr->flipMap());
313 }
314 else
315 {
316 // Assume a faceSet. Ignore flipMap
317 addSet
318 (
319 set.name(),
322 );
323 }
324}
325
326
327void Foam::faceZoneSet::addSet(const labelUList& elems)
328{
329 addSet(word::null, elems, boolList::null());
330}
331
332
333void Foam::faceZoneSet::subtractSet
334(
335 const word& setName,
336 const labelUList& setAddressing,
337 const UList<bool>& setFlipMap
338)
339{
340 label nConflict = 0;
341
342 DynamicList<label> newAddressing(addressing_.size());
343 DynamicList<bool> newFlipMap(flipMap_.size());
344
345 Map<label> faceToIndex(invertToMap(setAddressing));
346
347 forAll(addressing_, i)
348 {
349 const label facei = addressing_[i];
350
351 const auto iter = faceToIndex.cfind(facei);
352
353 if (iter.good())
354 {
355 const label index = iter.val();
356
357 if (setFlipMap.size() && (setFlipMap[index] != flipMap_[i]))
358 {
359 ++nConflict;
360 }
361 }
362 else
363 {
364 // Not found in zoneSet so add
365 newAddressing.append(facei);
366 newFlipMap.append(setFlipMap.size() ? setFlipMap[i] : false);
367 }
368 }
369
370 if (nConflict > 0)
371 {
373 << "subtractSet : there are " << nConflict
374 << " faces with different orientation in faceZonesSets "
375 << name() << " and " << setName << endl;
376 }
378 addressing_.transfer(newAddressing);
379 flipMap_.transfer(newFlipMap);
380 updateSet();
381}
382
383
384void Foam::faceZoneSet::subtractSet(const topoSet& set)
385{
386 const auto* zonePtr = isA<faceZoneSet>(set);
387
388 if (zonePtr)
389 {
390 subtractSet(zonePtr->name(), zonePtr->addressing(), zonePtr->flipMap());
391 }
392 else
393 {
394 // Assume a faceSet. Ignore flipMap
395 subtractSet
396 (
397 set.name(),
400 );
401 }
402}
403
405void Foam::faceZoneSet::subtractSet(const labelUList& elems)
406{
407 subtractSet(word::null, elems, boolList::null());
408}
409
410
412{
413 // This routine serves two purposes
414 // 1. make sure that any previous faceZoneSet manipulation is
415 // consistent across coupled boundaries
416 // 2. push faceZone contents to faceSet (looses flip bit)
417
418
419 // Collect all current zone info
420 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
421
422 // 0 : not in faceZone
423 // 1 : in faceZone and unflipped
424 //-1 : in faceZone and flipped
425 const label UNFLIPPED = 1;
426 const label FLIPPED = -1;
427 labelList myZoneFace(mesh.nFaces(), Zero);
428
429 forAll(addressing_, i)
430 {
431 const label facei = addressing_[i];
432 myZoneFace[facei] =
433 (
434 flipMap_[i]
435 ? FLIPPED
436 : UNFLIPPED
437 );
438 }
439
440 labelList neiZoneFace
441 (
442 SubList<label>
443 (
444 myZoneFace,
445 mesh.nBoundaryFaces(),
446 mesh.nInternalFaces()
447 )
448 );
450
451
452 const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
453
454
455 // Rebuild faceZone addressing and flipMap
456 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
457
458 const labelHashSet& set = *this;
459
460 DynamicList<label> newAddressing(set.size());
461 DynamicList<bool> newFlipMap(set.size());
462
463 for (const label facei : set)
464 {
465 // See if any info from original. If so maintain flipMap.
466 if (facei < mesh.nInternalFaces())
467 {
468 newAddressing.append(facei);
469 newFlipMap.append(myZoneFace[facei] == FLIPPED);
470 }
471 else
472 {
473 const label myStat = myZoneFace[facei];
474 const label neiStat = neiZoneFace[facei-mesh.nInternalFaces()];
475
476 if (myStat == 0)
477 {
478 // My face was not in zone. Check neighbour
479
480 if (neiStat == UNFLIPPED)
481 {
482 // Neighbour is unflipped so I am flipped
483 newAddressing.append(facei);
484 newFlipMap.append(true);
485 }
486 else if (neiStat == FLIPPED)
487 {
488 newAddressing.append(facei);
489 newFlipMap.append(false);
490 }
491 else //if (neiStat == 0)
492 {
493 // neighbour face not in zone either. Masterface decides.
494 newAddressing.append(facei);
495 newFlipMap.append(!isMasterFace[facei]);
496 }
497 }
498 else
499 {
500 if (myStat == neiStat)
501 {
502 // Conflict. masterFace wins
503 newAddressing.append(facei);
504 if (isMasterFace[facei])
505 {
506 newFlipMap.append(myStat == FLIPPED);
507 }
508 else
509 {
510 newFlipMap.append(neiStat == UNFLIPPED);
511 }
512 }
513 else
514 {
515 newAddressing.append(facei);
516 newFlipMap.append(myStat == FLIPPED);
517 }
518 }
519 }
520 }
521
522 addressing_.transfer(newAddressing);
523 flipMap_.transfer(newFlipMap);
524 updateSet();
525}
526
527
528Foam::label Foam::faceZoneSet::maxSize(const polyMesh& mesh) const
530 return mesh.nFaces();
531}
532
533
535(
536 IOstreamOption streamOpt,
537 const bool writeOnProc
538) const
539{
540 // Write shadow faceSet
541 const word oldTypeName = typeName;
542 const_cast<word&>(type()) = faceSet::typeName;
543 bool ok = faceSet::writeObject(streamOpt, writeOnProc);
544 const_cast<word&>(type()) = oldTypeName;
545
546 // Modify faceZone
547 auto& zones = const_cast<polyMesh&>(mesh_).faceZones();
548 auto* zonePtr = zones.findZone(name());
549
550 if (zonePtr)
551 {
552 zonePtr->resetAddressing(addressing_, flipMap_);
553 }
554 else
555 {
556 zones.emplace_back
557 (
558 name(),
559 addressing_,
560 flipMap_,
561 zones.size(), // zoneID
562 zones
563 );
564 }
565 zones.clearAddressing();
567 return ok && zones.write(writeOnProc);
568}
569
570
571void Foam::faceZoneSet::updateMesh(const mapPolyMesh& morphMap)
572{
573 DynamicList<label> newAddressing(addressing_.size());
574 DynamicList<bool> newFlipMap(flipMap_.size());
575
576 forAll(addressing_, i)
577 {
578 label facei = addressing_[i];
579 label newFacei = morphMap.reverseFaceMap()[facei];
580 if (newFacei >= 0)
581 {
582 newAddressing.push_back(newFacei);
583 newFlipMap.push_back(flipMap_[i]);
584 }
585 }
586
587 addressing_.transfer(newAddressing);
588 flipMap_.transfer(newFlipMap);
590 updateSet();
591}
592
593
595(
596 Ostream& os,
597 const primitiveMesh& mesh,
598 const label maxLen
599) const
600{
601 faceSet::writeDebug(os, mesh, maxLen);
602}
603
604
605// ************************************************************************* //
Various functions to operate on Lists.
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.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void append(const T &val)
Copy append an element to the end of this list.
void push_back(const T &val)
Copy append an element to the end of this list.
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition HashTable.C:729
void clearStorage()
Remove all entries from table and the table itself.
Definition HashTable.C:767
label size() const noexcept
The number of elements in table.
Definition HashTable.H:358
bool isAnyRead() const noexcept
True if any reading may be required (ie, != NO_READ).
static bool isReadRequired(readOption opt) noexcept
True if (MUST_READ | READ_MODIFIED) bits are set.
readOption
Enumeration defining read preferences.
writeOption
Enumeration defining write preferences.
static bool isAnyRead(readOption opt) noexcept
True if any reading may be required (ie, != NO_READ).
A simple container for options an IOstream can normally have.
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
static const List< bool > & null() noexcept
Definition List.H:138
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
faceSet(const IOobject &io)
Construct from IOobject. No checking.
Definition faceSet.C:41
virtual void writeDebug(Ostream &os, const primitiveMesh &, const label maxLen) const
Write maxLen items with label and coordinates.
Definition faceSet.C:237
Like faceSet but -reads data from faceZone -updates faceZone when writing.
Definition faceZoneSet.H:50
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write faceZone using stream options.
virtual void invert(const label maxLen)
Invert contents.
faceZoneSet(const polyMesh &mesh, const word &name, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, IOobjectOption::writeOption wOpt=IOobjectOption::NO_WRITE)
Construct from objectRegistry and name.
Definition faceZoneSet.C:82
virtual label maxSize(const polyMesh &mesh) const
Return max index+1.
virtual void sync(const polyMesh &mesh)
Sync faceZoneSet across coupled patches.
virtual void writeDebug(Ostream &os, const primitiveMesh &, const label maxLen) const
Write maxLen items with label and coordinates.
virtual void updateMesh(const mapPolyMesh &morphMap)
Update any stored data for new labels.
void updateSet()
Sort addressing and make faceSet part consistent with addressing.
Definition faceZoneSet.C:45
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelList & reverseFaceMap() const noexcept
Reverse face map.
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
void clearAddressing(const bool isMeshUpdate=false)
Clear addressing.
Cell-face mesh analysis engine.
label nInternalFaces() const noexcept
Number of internal faces.
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write using stream options.
static bitSet getMasterFaces(const polyMesh &mesh)
Get per face whether it is uncoupled or a master of a coupled set of faces.
Definition syncTools.C:119
static void swapBoundaryFaceList(const polyMesh &mesh, UList< T > &faceValues, const bool parRun=UPstream::parRun())
Swap coupled boundary face values. Uses eqOp.
Definition syncTools.H:524
General set of labels of mesh quantity (points, cells, faces).
Definition topoSet.H:63
virtual bool contains(const label id) const
Has the given index?
Definition topoSet.C:533
virtual bool set(const label id)
Set an index.
Definition topoSet.C:545
virtual void check(const label maxSize)
Check limits on addressable range.
Definition topoSet.C:252
A class for handling words, derived from Foam::string.
Definition word.H:66
static const word null
An empty word.
Definition word.H:84
#define defineTypeName(Type)
Define the typeName.
Definition className.H:113
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
auto & name
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
Map< label > invertToMap(const labelUList &values)
Create inverse mapping, which is a lookup table into the given list.
Definition ListOps.C:105
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
UIndirectList< label > labelUIndList
UIndirectList of labels.
List< T > subset(const BoolListType &select, const UList< T > &input, const bool invert=false)
Extract elements of the input list when select is true.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
void sort(UList< T > &list)
Sort the list.
Definition UList.C:283
UIndirectList< bool > boolUIndList
UIndirectList of bools.
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299