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-2017 OpenFOAM Foundation
9  Copyright (C) 2018-2022,2025 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 Application
28  topoSet
29 
30 Group
31  grpMeshManipulationUtilities
32 
33 Description
34  Operates on cellSets/faceSets/pointSets through a dictionary,
35  normally system/topoSetDict
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "argList.H"
40 #include "Time.H"
41 #include "polyMesh.H"
42 #include "topoSetSource.H"
43 #include "globalMeshData.H"
44 #include "timeSelector.H"
45 #include "IOobjectList.H"
46 #include "cellZoneSet.H"
47 #include "faceZoneSet.H"
48 #include "pointZoneSet.H"
49 #include "IOdictionary.H"
50 #include "namedDictionary.H"
51 
52 using namespace Foam;
53 
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55 
56 void printMesh(const Time& runTime, const polyMesh& mesh)
57 {
58  Info<< "Time:" << runTime.timeName()
59  << " cells:" << mesh.globalData().nTotalCells()
60  << " faces:" << mesh.globalData().nTotalFaces()
61  << " points:" << mesh.globalData().nTotalPoints()
62  << " patches:" << mesh.boundaryMesh().size()
63  << " bb:" << mesh.bounds() << nl;
64 }
65 
66 
67 template<class ZoneType>
68 void removeZone
69 (
71  const word& setName
72 )
73 {
74  label zoneID = zones.findZoneID(setName);
75 
76  if (zoneID != -1)
77  {
78  Info<< "Removing zone " << setName << " at index " << zoneID << endl;
79  // Shuffle to last position
80  labelList oldToNew(zones.size());
81  label newI = 0;
82  forAll(oldToNew, i)
83  {
84  if (i != zoneID)
85  {
86  oldToNew[i] = newI++;
87  }
88  }
89  oldToNew[zoneID] = newI;
90  zones.reorder(oldToNew);
91  // Remove last element
92  zones.setSize(zones.size()-1);
93  zones.clearAddressing();
94  if (!zones.write())
95  {
96  WarningInFunction << "Failed writing zone " << setName << endl;
97  }
98  fileHandler().flush();
99  }
100 }
101 
102 
103 // Physically remove a set
104 void removeSet
105 (
106  const polyMesh& mesh,
107  const word& setType,
108  const word& setName
109 )
110 {
111  // Remove the file
112  IOobjectList objects
113  (
114  mesh,
116  (
117  polyMesh::meshSubDir/"sets",
118  word::null,
121  ),
122  polyMesh::meshSubDir/"sets"
123  );
124 
125  if (objects.found(setName))
126  {
127  // Remove file
128  fileName object = objects[setName]->objectPath();
129  Info<< "Removing file " << object << endl;
130  rm(object);
131  }
132 
133  // See if zone
134  if (setType == cellZoneSet::typeName)
135  {
136  removeZone
137  (
138  const_cast<cellZoneMesh&>(mesh.cellZones()),
139  setName
140  );
141  }
142  else if (setType == faceZoneSet::typeName)
143  {
144  removeZone
145  (
146  const_cast<faceZoneMesh&>(mesh.faceZones()),
147  setName
148  );
149  }
150  else if (setType == pointZoneSet::typeName)
151  {
152  removeZone
153  (
154  const_cast<pointZoneMesh&>(mesh.pointZones()),
155  setName
156  );
157  }
158 }
159 
160 
161 polyMesh::readUpdateState meshReadUpdate(polyMesh& mesh)
162 {
164 
165  switch(stat)
166  {
167  case polyMesh::UNCHANGED:
168  {
169  Info<< " mesh not changed." << endl;
170  break;
171  }
173  {
174  Info<< " points moved; topology unchanged." << endl;
175  break;
176  }
178  {
179  Info<< " topology changed; patches unchanged." << nl
180  << " ";
181  printMesh(mesh.time(), mesh);
182  break;
183  }
185  {
186  Info<< " topology changed and patches changed." << nl
187  << " ";
188  printMesh(mesh.time(), mesh);
189 
190  break;
191  }
192  default:
193  {
195  << "Illegal mesh update state "
196  << stat << abort(FatalError);
197  break;
198  }
199  }
200  return stat;
201 }
202 
203 
204 // Lookup table to convert 'zone' types into their basic non-zone type
205 static const HashTable<word> basicType
206 ({
207  std::pair("cellZoneSet", "cellSet"),
208  std::pair("faceZoneSet", "faceSet"),
209  std::pair("pointZoneSet", "pointSet"),
210 });
211 
212 
213 int main(int argc, char *argv[])
214 {
216  (
217  "Operates on cellSets/faceSets/pointSets through a dictionary,"
218  " normally system/topoSetDict"
219  );
220 
221  timeSelector::addOptions(true, false); // constant(true), zero(false)
222 
223  argList::addOption("dict", "file", "Alternative topoSetDict");
224 
225  #include "addRegionOption.H"
227  (
228  "noSync",
229  "Do not synchronise selection across coupled patches"
230  );
231 
232  #include "setRootCase.H"
233  #include "createTime.H"
234 
236 
237  #include "createNamedPolyMesh.H"
238 
239  const bool noSync = args.found("noSync");
240 
241  const word dictName("topoSetDict");
242  #include "setSystemMeshDictionaryIO.H"
243 
244  Info<< "Reading " << dictIO.name() << nl << endl;
245 
246  IOdictionary topoSetDict(dictIO);
247 
248  // Read set construct info from dictionary
249  List<namedDictionary> actionEntries(topoSetDict.lookup("actions"));
250 
251  forAll(timeDirs, timei)
252  {
253  runTime.setTime(timeDirs[timei], timei);
254  Info<< "Time = " << runTime.timeName() << endl;
255 
256  // Optionally re-read mesh
257  meshReadUpdate(mesh);
258 
259  // Execute all actions
260  for (const namedDictionary& actionEntry : actionEntries)
261  {
262  const dictionary& dict = actionEntry.dict();
263  if (dict.empty())
264  {
265  continue;
266  }
267  const word setName(dict.get<word>("name"));
268  const word setType(dict.get<word>("type"));
269 
270  const topoSetSource::setAction action =
272 
273  autoPtr<topoSet> currentSet;
274 
275  switch (action)
276  {
277  case topoSetSource::NEW :
278  case topoSetSource::CLEAR :
279  {
280  currentSet = topoSet::New(setType, mesh, setName, 16384);
281  Info<< "Created "
282  << currentSet().type() << ' ' << setName << endl;
283  break;
284  }
285 
286  case topoSetSource::IGNORE :
287  continue; // Nothing to do
288  break;
289 
290  case topoSetSource::REMOVE :
291  // Nothing to load
292  break;
293 
294  default:
295  {
296  // Load set
297  currentSet = topoSet::New
298  (
299  setType,
300  mesh,
301  setName,
303  );
304 
305  Info<< "Read set "
306  << currentSet().type() << ' ' << setName
307  << " size:"
308  << returnReduce(currentSet().size(), sumOp<label>())
309  << endl;
310  }
311  }
312 
313  // Handle special actions (clear, invert) locally,
314  // the other actions through sources.
315  switch (action)
316  {
317  case topoSetSource::NEW :
318  case topoSetSource::ADD :
320  {
321  const word sourceType(dict.get<word>("source"));
322 
323  Info<< " Applying source " << sourceType << endl;
325  (
326  sourceType,
327  mesh,
328  dict.optionalSubDict("sourceInfo")
329  );
330 
331  source().applyToSet(action, currentSet());
332  // Synchronize for coupled patches.
333  if (!noSync) currentSet().sync(mesh);
334  if (!currentSet().write())
335  {
337  << "Failed writing set "
338  << currentSet().objectPath() << endl;
339  }
340  fileHandler().flush();
341  break;
342  }
343 
344  case topoSetSource::SUBSET :
345  {
346  const word sourceType(dict.get<word>("source"));
347 
348  Info<< " Applying source " << sourceType << endl;
350  (
351  sourceType,
352  mesh,
353  dict.optionalSubDict("sourceInfo")
354  );
355 
356  // Construct 'set' type equivalent of 'zoneSet'. This is
357  // done since we can ignore the flipMap of the
358  // elements we want to remove so bypass all the zone
359  // handling.
360  const auto typeFnd(basicType.find(setType));
361  autoPtr<topoSet> workSet
362  (
364  (
365  (typeFnd ? typeFnd() : setType),
366  mesh,
367  currentSet().name() + "_old2",
368  0 // size
369  )
370  );
371 
372  source().applyToSet(topoSetSource::NEW, workSet());
373 
374  // Combine new value of currentSet with old one.
375  currentSet().subset(workSet());
376 
377 
378  // Synchronize for coupled patches.
379  if (!noSync) currentSet().sync(mesh);
380  if (!currentSet().write())
381  {
383  << "Failed writing set "
384  << currentSet().objectPath() << endl;
385  }
386  fileHandler().flush();
387 
388  break;
389  }
390 
391  case topoSetSource::CLEAR :
392  {
393  Info<< " Clearing " << currentSet().type() << endl;
394  currentSet().clear();
395  if (!currentSet().write())
396  {
398  << "Failed writing set "
399  << currentSet().objectPath() << endl;
400  }
401  fileHandler().flush();
402 
403  break;
404  }
405 
406  case topoSetSource::INVERT :
407  {
408  Info<< " Inverting " << currentSet().type() << endl;
409  currentSet().invert(currentSet().maxSize(mesh));
410  if (!currentSet().write())
411  {
413  << "Failed writing set "
414  << currentSet().objectPath() << endl;
415  }
416  fileHandler().flush();
417 
418  break;
419  }
420 
421  case topoSetSource::REMOVE :
422  {
423  Info<< " Removing set" << endl;
424  removeSet(mesh, setType, setName);
425 
426  break;
427  }
428 
429  default:
431  << "Unhandled action: "
432  << topoSetSource::actionNames[action] << endl;
433  }
434 
435  if (currentSet)
436  {
437  Info<< " "
438  << currentSet().type() << ' '
439  << currentSet().name() << " now size "
440  << returnReduce(currentSet().size(), sumOp<label>())
441  << endl;
442  }
443  }
444  }
445 
446  Info<< "\nEnd\n" << endl;
447 
448  return 0;
449 }
450 
451 
452 // ************************************************************************* //
EnumType get(const word &enumName) const
The enumeration corresponding to the given name.
Definition: Enum.C:68
dictionary dict
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:477
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:944
static const Enum< setAction > actionNames
The setActions enum text. Names: "new", add", "subtract", "subset", "invert", "clear", "remove", "list", "ignore".
A class for handling file names.
Definition: fileName.H:72
List of IOobjects with searching and retrieving facilities. Implemented as a HashTable, so the various sorted methods should be used if traversing in parallel.
Definition: IOobjectList.H:55
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:844
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:130
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:652
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:205
Create a new set and ADD elements to it.
Add elements to current set.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Clear the set, possibly creating it.
const word dictName("faMeshDefinition")
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:412
void setSize(const label n)
Same as resize()
Definition: PtrList.H:360
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:518
A list of mesh zones.
void reorder(const labelUList &oldToNew, const bool check=false)
Reorder elements. Reordering must be unique (ie, shuffle).
Definition: UPtrList.C:62
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:255
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:389
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
Invert the elements in the current set.
Required Classes.
Remove the set (from the file system)
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
label nTotalPoints() const noexcept
Total global number of mesh points. Not compensated for duplicate points!
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:400
const dictionary & optionalSubDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary, otherwise return this dictionary.
Definition: dictionary.C:560
Required Classes.
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:670
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:724
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Definition: ZoneMesh.C:757
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:611
A class for handling words, derived from Foam::string.
Definition: word.H:63
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
Union of elements with current set.
setAction
Enumeration defining various actions.
Reading is optional [identical to LAZY_READ].
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
static const word null
An empty word.
Definition: word.H:84
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:400
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
const globalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: polyMesh.C:1296
static instantList selectIfPresent(Time &runTime, const argList &args)
If any time option provided return the set of times - as per select0() - otherwise return just the cu...
Definition: timeSelector.C:291
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:904
A HashTable similar to std::unordered_map.
Definition: HashTable.H:108
errorManip< error > abort(error &err)
Definition: errorManip.H:139
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
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:713
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
Definition: polyMesh.H:673
label nTotalCells() const noexcept
Total global number of mesh cells.
static autoPtr< topoSetSource > New(const word &topoSetSourceType, const polyMesh &mesh, const dictionary &dict)
Return a reference to the selected topoSetSource.
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
Definition: polyMesh.H:665
Subtract elements from current set.
#define WarningInFunction
Report a warning using Foam::Warning.
A tuple of keyType and dictionary, which can be used when reading named or unnamed dictionary entries...
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:681
messageStream Info
Information stream (stdout output on master, null elsewhere)
label nTotalFaces() const noexcept
Total global number of mesh faces. Not compensated for duplicate faces!
const boundBox & bounds() const noexcept
Return mesh bounding box.
Definition: polyMesh.H:619
IOobject dictIO
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:92
"ignore" no-op action
Foam::argList args(argc, argv)
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:171
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:101
Namespace for OpenFOAM.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1410