topoSet.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-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 "topoSet.H"
30 #include "mapPolyMesh.H"
31 #include "polyMesh.H"
32 #include "boundBox.H"
33 #include "Time.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(topoSet, 0);
40  defineRunTimeSelectionTable(topoSet, word);
41  defineRunTimeSelectionTable(topoSet, size);
42  defineRunTimeSelectionTable(topoSet, set);
43 
45  (
46  debug::debugSwitch("disallowGenericSets", 0)
47  );
48 }
49 
50 
51 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
52 
55 (
56  const word& setType,
57  const polyMesh& mesh,
58  const word& name,
61 )
62 {
63  auto* ctorPtr = wordConstructorTable(setType);
64 
65  if (!ctorPtr)
66  {
68  (
69  "set",
70  setType,
71  *wordConstructorTablePtr_
72  ) << exit(FatalError);
73  }
74 
75  return autoPtr<topoSet>(ctorPtr(mesh, name, rOpt, wOpt));
76 }
77 
78 
81 (
82  const word& setType,
83  const polyMesh& mesh,
84  const word& name,
85  const label size,
87 )
88 {
89  auto* ctorPtr = sizeConstructorTable(setType);
90 
91  if (!ctorPtr)
92  {
94  (
95  "set",
96  setType,
97  *sizeConstructorTablePtr_
98  ) << exit(FatalError);
99  }
101  return autoPtr<topoSet>(ctorPtr(mesh, name, size, wOpt));
102 }
103 
104 
107 (
108  const word& setType,
109  const polyMesh& mesh,
110  const word& name,
111  const topoSet& set,
113 )
114 {
115  auto* ctorPtr = setConstructorTable(setType);
116 
117  if (!ctorPtr)
118  {
120  (
121  "set",
122  setType,
123  *setConstructorTablePtr_
124  ) << exit(FatalError);
125  }
126 
127  return autoPtr<topoSet>(ctorPtr(mesh, name, set, wOpt));
128 }
129 
130 
131 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
132 
134 (
135  const polyMesh& mesh,
136  const word& name
137 )
138 {
139  return mesh.facesInstance()/mesh.meshDir()/"sets"/name;
140 }
141 
142 
143 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
144 
146 (
147  const word& wantedType,
148  labelHashSet& contents
149 )
150 {
151  if (isReadRequired() || (isReadOptional() && headerOk()))
152  {
153  Istream& is = readStream(wantedType);
154 
155  if (is.good())
156  {
157  is >> contents;
158  close();
159  }
160  return true;
161  }
162 
163  return false;
164 }
165 
166 
167 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
168 
169 // Update stored cell numbers using map.
170 // Do in two passes to prevent allocation if nothing changed.
172 {
173  labelHashSet& labels = *this;
174 
175  // Iterate over map to see if anything changed
176 
177  bool changed = false;
178 
179  for (const label oldId : labels)
180  {
181  if (oldId < 0 || oldId >= map.size())
182  {
184  << "Illegal content " << oldId << " of set:" << name()
185  << " of type " << type() << nl
186  << "Value should be between [0," << map.size() << ')'
187  << endl
188  << abort(FatalError);
189  }
190 
191  const label newId = map[oldId];
192 
193  if (newId != oldId)
194  {
195  changed = true;
196  #ifdef FULLDEBUG
197  continue; // Check all elements in FULLDEBUG mode
198  #endif
199  break;
200  }
201  }
202 
203  if (!changed)
204  {
205  return;
206  }
207 
208 
209  // Relabel. Use second labelHashSet to prevent overlapping.
210 
211  labelHashSet newLabels(2*labels.size());
212 
213  for (const label oldId : labels)
214  {
215  const label newId = map[oldId];
216 
217  if (newId >= 0)
218  {
219  newLabels.set(newId);
220  }
221  }
222 
223  labels.transfer(newLabels);
224 }
225 
226 
227 void Foam::topoSet::checkLabels(const labelUList& labels, const label maxSize)
228 {
229  for (const label oldId : labels)
230  {
231  if (oldId < 0 || oldId >= maxSize)
232  {
234  << "Illegal content " << oldId << " of set:" << name()
235  << " of type " << type() << nl
236  << "Value should be between [0," << maxSize << ')' << nl
237  << abort(FatalError);
238  }
239  }
240 }
241 
242 
243 void Foam::topoSet::checkLabels(const labelHashSet& labels, const label maxSize)
244 {
245  for (const label oldId : labels)
246  {
247  if (oldId < 0 || oldId >= maxSize)
248  {
250  << "Illegal content " << oldId << " of set:" << name()
251  << " of type " << type() << nl
252  << "Value should be between [0," << maxSize << ')' << nl
253  << abort(FatalError);
254  }
255  }
256 }
257 
258 
259 void Foam::topoSet::check(const label maxSize)
260 {
261  checkLabels(*this, maxSize);
262 }
263 
264 
265 // Write maxElem elements, starting at iter. Updates iter
266 Foam::label Foam::topoSet::writeDebug
267 (
268  Ostream& os,
269  const label maxElem,
271 ) const
272 {
273  label n = 0;
274 
275  for (; (iter != cend()) && (n < maxElem); ++iter)
276  {
277  if (n && ((n % 10) == 0))
278  {
279  os << nl;
280  }
281  os << iter.key() << ' ';
282 
283  ++n;
284  }
286  return n;
287 }
288 
289 
290 // Write maxElem elements, starting at iter. Updates iter
291 Foam::label Foam::topoSet::writeDebug
292 (
293  Ostream& os,
294  const pointField& coords,
295  const label maxElem,
297 ) const
298 {
299  label n = 0;
300 
301  for (; (iter != cend()) && (n < maxElem); ++iter)
302  {
303  if (n && ((n % 3) == 0))
304  {
305  os << nl;
306  }
307  os << iter.key() << coords[iter.key()] << ' ';
308 
309  ++n;
310  }
311 
312  return n;
313 }
314 
315 
317 (
318  Ostream& os,
319  const pointField& coords,
320  const label maxLen
321 ) const
322 {
323  // Bounding box of contents.
324  boundBox bb(pointField(coords, toc()), true);
325 
326  os << "Set bounding box: min = "
327  << bb.min() << " max = " << bb.max() << " metres." << nl << endl;
328 
330 
331  if (size() <= maxLen)
332  {
333  writeDebug(os, coords, maxLen, iter);
334  }
335  else
336  {
337  const label halfLen = maxLen/2;
338 
339  os << "Size larger than " << maxLen << ". Printing first and last "
340  << halfLen << " elements:" << nl << endl;
341 
342  label n = writeDebug(os, coords, halfLen, iter);
343 
344  os << nl << " .." << nl << endl;
345 
346  for (; n < size() - halfLen; ++n)
347  {
348  ++iter;
349  }
350 
351  writeDebug(os, coords, halfLen, iter);
352  }
353 }
354 
355 
356 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
357 
359 (
360  const polyMesh& mesh,
361  const word& name,
365 )
366 {
367  IOobject io
368  (
369  name,
371  (
372  mesh.meshDir()/"sets",
373  word::null,
376  ),
377  polyMesh::meshSubDir/"sets",
378  mesh,
379  rOpt,
380  wOpt,
381  reg
382  );
383 
384  if (!io.typeHeaderOk<topoSet>(false) && disallowGenericSets != 0)
385  {
386  DebugInfo<< "Setting no read for set " << name << endl;
388  }
389 
390  return io;
391 }
392 
393 
395 (
396  const Time& runTime,
397  const word& name,
401 )
402 {
403  return IOobject
404  (
405  name,
407  (
408  polyMesh::meshSubDir/"sets",
409  word::null,
411 
412  // The stop instance with "polyMesh/faces"
414  (
416  "faces",
418  )
419  ),
420  polyMesh::meshSubDir/"sets",
421  runTime,
422  rOpt,
423  wOpt,
424  reg
425  );
426 }
427 
428 
429 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
430 
431 Foam::topoSet::topoSet(const IOobject& io, const word& wantedType)
432 :
433  regIOobject(io)
434 {
435  readIOcontents(wantedType, static_cast<labelHashSet&>(*this));
436 }
437 
440 :
441  regIOobject(io)
442 {}
443 
444 
445 Foam::topoSet::topoSet(const IOobject& io, const label initialCapacity)
446 :
447  regIOobject(io),
448  labelHashSet(initialCapacity)
449 {}
450 
451 
453 :
454  regIOobject(io),
455  labelHashSet(labels)
456 {}
457 
458 
460 :
461  regIOobject(io),
462  labelHashSet(std::move(labels))
463 {}
464 
465 
467 (
468  const polyMesh& mesh,
469  const word& wantedType,
470  const word& name,
474 )
475 :
476  regIOobject(findIOobject(mesh, name, rOpt, wOpt, reg))
477 {
478  readIOcontents(wantedType, static_cast<labelHashSet&>(*this));
479 }
480 
481 
483 (
484  const polyMesh& mesh,
485  const word& name,
486  const label initialCapacity,
489 )
490 :
491  regIOobject(findIOobject(mesh, name, IOobject::NO_READ, wOpt, reg)),
492  labelHashSet(initialCapacity)
493 {}
494 
495 
497 (
498  const polyMesh& mesh,
499  const word& name,
500  const labelHashSet& labels,
503 )
504 :
505  regIOobject(findIOobject(mesh, name, IOobject::NO_READ, wOpt, reg)),
506  labelHashSet(labels)
507 {}
508 
509 
511 (
512  const polyMesh& mesh,
513  const word& name,
514  labelHashSet&& labels,
517 )
518 :
519  regIOobject(findIOobject(mesh, name, IOobject::NO_READ, wOpt, reg)),
520  labelHashSet(std::move(labels))
521 {}
522 
523 
525 (
526  const polyMesh& mesh,
527  const word& name,
528  const labelUList& labels,
531 )
532 :
533  regIOobject(findIOobject(mesh, name, IOobject::NO_READ, wOpt, reg)),
534  labelHashSet(labels)
535 {}
536 
537 
538 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
540 bool Foam::topoSet::contains(const label id) const
541 {
542  return static_cast<const labelHashSet&>(*this).contains(id);
543 }
544 
546 bool Foam::topoSet::found(const label id) const
547 {
548  return static_cast<const labelHashSet&>(*this).contains(id);
549 }
550 
552 bool Foam::topoSet::set(const label id)
553 {
554  return static_cast<labelHashSet&>(*this).set(id);
555 }
556 
558 bool Foam::topoSet::unset(const label id)
559 {
560  return static_cast<labelHashSet&>(*this).unset(id);
561 }
562 
564 void Foam::topoSet::set(const labelUList& labels)
565 {
566  static_cast<labelHashSet&>(*this).set(labels);
567 }
568 
570 void Foam::topoSet::unset(const labelUList& labels)
571 {
572  static_cast<labelHashSet&>(*this).unset(labels);
573 }
574 
575 
576 void Foam::topoSet::invert(const label maxLen)
577 {
578  // Retain a copy of the original (current) set.
579  labelHashSet original
580  (
581  std::move(static_cast<labelHashSet&>(*this))
582  );
583 
584  clear(); // Maybe don't trust the previous move operation
585  reserve(Foam::max(64, (maxLen - original.size())));
586 
587  for (label id = 0; id < maxLen; ++id)
588  {
589  if (!original.contains(id))
590  {
591  labelHashSet::set(id);
592  }
593  }
594 }
595 
596 
598 {
599  // Only retain entries found in both sets
600  static_cast<labelHashSet&>(*this) &= set;
601 }
602 
603 
604 void Foam::topoSet::subset(const labelUList& elems)
605 {
606  // Only retain entries found in both sets
607  auto& currentSet = static_cast<labelHashSet&>(*this);
608 
609  DynamicList<label> newElems(Foam::min(elems.size(), currentSet.size()));
610 
611  for (const label elem : elems)
612  {
613  if (currentSet.contains(elem))
614  {
615  newElems.push_back(elem);
616  }
617  }
618  if (newElems.size() < currentSet.size())
619  {
620  currentSet = newElems;
621  }
622 }
623 
624 
626 {
627  // Add entries to the set
628  static_cast<labelHashSet&>(*this) |= set;
629 }
630 
631 
633 {
634  // Add entries to the set
635  static_cast<labelHashSet&>(*this).set(elems);
636 }
637 
638 
640 {
641  // Subtract entries from the set
642  static_cast<labelHashSet&>(*this) -= set;
643 }
644 
645 
647 {
648  // Subtract entries from the set
649  static_cast<labelHashSet&>(*this).unset(elems);
650 }
651 
653 void Foam::topoSet::sync(const polyMesh&)
654 {
656 }
657 
658 
659 void Foam::topoSet::writeDebug(Ostream& os, const label maxLen) const
660 {
662 
663  if (size() <= maxLen)
664  {
665  writeDebug(os, maxLen, iter);
666  }
667  else
668  {
669  const label halfLen = maxLen/2;
670 
671  os << "Size larger than " << maxLen << ". Printing first and last "
672  << halfLen << " elements:" << nl << endl;
673 
674  label n = writeDebug(os, halfLen, iter);
675 
676  os << nl << " .." << nl << endl;
677 
678  for (; n < size() - halfLen; ++n)
679  {
680  ++iter;
681  }
682 
683  writeDebug(os, halfLen, iter);
684  }
685 }
686 
689 {
690  return (os << *this).good();
691 }
692 
695 {
697 }
698 
699 
701 {
702  IOobject io
703  (
704  "dummy",
706  polyMesh::meshSubDir/"sets",
707  mesh
708  );
709  fileName setsDir(io.path());
710 
711  if (debug) DebugVar(setsDir);
712 
713  if (isDir(setsDir))
714  {
715  rmDir(setsDir);
716  }
717 }
718 
719 
720 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
721 
722 void Foam::topoSet::operator=(const topoSet& rhs)
723 {
725 }
726 
727 
728 // ************************************************************************* //
virtual void subset(const labelUList &elems)
Subset contents. Only elements present in both sets remain.
Definition: topoSet.C:597
virtual bool writeData(Ostream &) const
Write contents.
Definition: topoSet.C:681
writeOption
Enumeration defining write preferences.
bool set(const Key &key)
Same as insert (no value to overwrite)
Definition: HashSet.H:240
void operator=(const topoSet &)
Copy labelHashSet part only.
Definition: topoSet.C:715
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
A class for handling file names.
Definition: fileName.H:72
readOption readOpt() const noexcept
Get the read option.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:859
virtual bool unset(const label id)
Unset an index.
Definition: topoSet.C:551
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
static int disallowGenericSets
Debug switch to disallow the use of generic sets.
Definition: topoSet.H:151
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
int debugSwitch(const char *name, const int deflt=0)
Lookup debug switch or add default value.
Definition: debug.C:222
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:411
engineTime & runTime
virtual bool set(const label id)
Set an index.
Definition: topoSet.C:545
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
void operator=(const this_type &rhs)
Copy assign.
Definition: HashSet.H:445
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
#define FatalErrorInLookup(lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalError.
Definition: error.H:615
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
virtual bool contains(const label id) const
Has the given index?
Definition: topoSet.C:533
fileName path() const
The complete path for the object (with instance, local,...).
Definition: IOobject.C:480
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
static IOobject findIOobject(const polyMesh &mesh, const word &name, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, IOobjectOption::writeOption wOpt=IOobjectOption::NO_WRITE, IOobjectOption::registerOption reg=IOobjectOption::LEGACY_REGISTER)
Find IOobject in the polyMesh/sets/ (used as constructor helper)
Definition: topoSet.C:352
bool unset(const Key &key)
Unset the specified key - same as erase.
Definition: HashSet.H:250
static void removeFiles(const polyMesh &)
Helper: remove all sets files from mesh instance.
Definition: topoSet.C:693
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
bool contains(const Key &key) const
True if hashed key is contained (found) in table.
Definition: HashTableI.H:72
word findInstance(const fileName &directory, const word &name=word::null, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, const word &stopInstance=word::null, const bool constant_fallback=true) const
Return time instance (location) of directory containing the file name (eg, used in reading mesh data)...
Definition: Time.C:725
A class for handling words, derived from Foam::string.
Definition: word.H:63
topoSet(const topoSet &)=delete
No copy construct.
Reading is optional [identical to LAZY_READ].
static const word null
An empty word.
Definition: word.H:84
void checkLabels(const labelUList &labels, const label maxSize)
Check limits on addressable range.
Definition: topoSet.C:220
constexpr auto cend(const C &c) -> decltype(c.end())
Return const_iterator to the end of the container c.
Definition: stdFoam.H:223
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
virtual void addSet(const labelUList &elems)
Add given elements to the set.
Definition: topoSet.C:625
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (respects is_globalIOobject trait) and check its info.
bool rmDir(const fileName &directory, const bool silent=false, const bool emptyOnly=false)
Remove a directory and its contents recursively,.
Definition: POSIX.C:1433
#define DebugInfo
Report an information message using Foam::Info.
static autoPtr< topoSet > New(const word &setType, const polyMesh &mesh, const word &name, IOobjectOption::readOption rOpt=IOobjectOption::MUST_READ, IOobjectOption::writeOption wOpt=IOobjectOption::NO_WRITE)
Return a pointer to a toposet read from file.
Definition: topoSet.C:48
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
label writeDebug(Ostream &os, const label maxElem, labelHashSet::const_iterator &iter) const
Write part of contents nicely formatted.
Definition: topoSet.C:260
virtual void updateLabels(const labelUList &map)
Update map from map.
Definition: topoSet.C:164
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:59
registerOption
Enumeration for use with registerObject(). Values map to bool (false/true)
virtual bool found(const label id) const
Has the given index?
Definition: topoSet.C:539
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
surface1 clear()
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:841
Nothing to be read.
triangles reserve(surf.size())
virtual void subtractSet(const labelUList &elems)
Subtract given elements from the set.
Definition: topoSet.C:639
virtual void sync(const polyMesh &mesh)
Sync set across coupled patches.
Definition: topoSet.C:646
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:68
virtual void invert(const label maxLen)
Invert contents.
Definition: topoSet.C:569
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
label n
typename parent_type::const_key_iterator const_iterator
A const_iterator, returning reference to the key.
Definition: HashSet.H:131
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
#define DebugVar(var)
Report a variable name and value.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:75
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
const_iterator cbegin() const
Definition: HashSet.C:475
virtual void check(const label maxSize)
Check limits on addressable range.
Definition: topoSet.C:252
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:696
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
virtual void updateMesh(const mapPolyMesh &morphMap)
Update any stored data for new labels. Not implemented.
Definition: topoSet.C:687
List< label > toc(const UList< bool > &bools)
Return the (sorted) values corresponding to &#39;true&#39; entries.
Definition: BitOps.C:158
static fileName localPath(const polyMesh &mesh, const word &name)
Name of file set will use.
Definition: topoSet.C:127
bool readIOcontents(const word &wantedType, labelHashSet &contents)
Read into labelHashSet if IOobject flags set. Return true if read.
Definition: topoSet.C:139
Namespace for OpenFOAM.
readOption
Enumeration defining read preferences.