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 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
27Application
28 topoSet
29
30Group
31 grpMeshManipulationUtilities
32
33Description
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
52using namespace Foam;
53
54// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55
56void 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
67template<class ZoneType>
68void 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 }
99 }
100}
101
102
103// Physically remove a set
104void 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,
115 mesh.time().findInstance
116 (
117 polyMesh::meshSubDir/"sets",
119 IOobject::READ_IF_PRESENT,
120 mesh.facesInstance()
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
162{
163 polyMesh::readUpdateState stat = mesh.readUpdate();
164
165 switch(stat)
166 {
167 case polyMesh::UNCHANGED:
168 {
169 Info<< " mesh not changed." << endl;
170 break;
171 }
172 case polyMesh::POINTS_MOVED:
173 {
174 Info<< " points moved; topology unchanged." << endl;
175 break;
176 }
177 case polyMesh::TOPO_CHANGE:
178 {
179 Info<< " topology changed; patches unchanged." << nl
180 << " ";
181 printMesh(mesh.time(), mesh);
182 break;
183 }
184 case polyMesh::TOPO_PATCH_CHANGE:
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
205int main(int argc, char *argv[])
206{
207 argList::addNote
208 (
209 "Operates on cellSets/faceSets/pointSets through a dictionary,"
210 " normally system/topoSetDict"
211 );
212
213 timeSelector::addOptions(true, false); // constant(true), zero(false)
214
215 argList::addOption("dict", "file", "Alternative topoSetDict");
216
217 #include "addRegionOption.H"
218 argList::addBoolOption
219 (
220 "noSync",
221 "Do not synchronise selection across coupled patches"
222 );
223
224 #include "setRootCase.H"
225 #include "createTime.H"
226
227 instantList timeDirs = timeSelector::selectIfPresent(runTime, args);
228
229 #include "createNamedPolyMesh.H"
230
231 const bool noSync = args.found("noSync");
232
233 const word dictName("topoSetDict");
235
236 Info<< "Reading " << dictIO.name() << nl << endl;
237
238 IOdictionary topoSetDict(dictIO);
239
240 // Read set construct info from dictionary
241 List<namedDictionary> actionEntries(topoSetDict.lookup("actions"));
242
243 forAll(timeDirs, timeI)
244 {
245 runTime.setTime(timeDirs[timeI], timeI);
246 Info<< "Time = " << runTime.timeName() << endl;
247
248 // Optionally re-read mesh
249 meshReadUpdate(mesh);
250
251 // Execute all actions
252 for (const namedDictionary& actionEntry : actionEntries)
253 {
254 const dictionary& dict = actionEntry.dict();
255 if (dict.empty())
256 {
257 continue;
258 }
259 const word setName(dict.get<word>("name"));
260 const word setType(dict.get<word>("type"));
261
262 const topoSetSource::setAction action =
263 topoSetSource::actionNames.get("action", dict);
264
265 autoPtr<topoSet> currentSet;
266
267 switch (action)
268 {
269 case topoSetSource::NEW :
270 case topoSetSource::CLEAR :
271 {
272 currentSet = topoSet::New(setType, mesh, setName, 16384);
273 Info<< "Created "
274 << currentSet().type() << ' ' << setName << endl;
275 break;
276 }
277
278 case topoSetSource::IGNORE :
279 continue; // Nothing to do
280 break;
281
282 case topoSetSource::REMOVE :
283 // Nothing to load
284 break;
285
286 default:
287 {
288 // Load set
289 currentSet = topoSet::New
290 (
291 setType,
292 mesh,
293 setName,
294 IOobject::MUST_READ
295 );
296
297 Info<< "Read set "
298 << currentSet().type() << ' ' << setName
299 << " size:"
300 << returnReduce(currentSet().size(), sumOp<label>())
301 << endl;
302 }
303 }
304
305 // Handle special actions (clear, invert) locally,
306 // the other actions through sources.
307 switch (action)
308 {
309 case topoSetSource::NEW :
310 case topoSetSource::ADD :
311 case topoSetSource::SUBTRACT :
312 {
313 const word sourceType(dict.get<word>("source"));
314
315 Info<< " Applying source " << sourceType << endl;
316 autoPtr<topoSetSource> source = topoSetSource::New
317 (
318 sourceType,
319 mesh,
320 dict.optionalSubDict("sourceInfo")
321 );
322
323 source().applyToSet(action, currentSet());
324 // Synchronize for coupled patches.
325 if (!noSync) currentSet().sync(mesh);
326 if (!currentSet().write())
327 {
329 << "Failed writing set "
330 << currentSet().objectPath() << endl;
331 }
332 fileHandler().flush();
333 break;
334 }
335
336 case topoSetSource::SUBSET :
337 {
338 const word sourceType(dict.get<word>("source"));
339
340 Info<< " Applying source " << sourceType << endl;
341 autoPtr<topoSetSource> source = topoSetSource::New
342 (
343 sourceType,
344 mesh,
345 dict.optionalSubDict("sourceInfo")
346 );
347
348 // Backup current set.
349 autoPtr<topoSet> oldSet
350 (
351 topoSet::New
352 (
353 setType,
354 mesh,
355 currentSet().name() + "_old2",
356 currentSet()
357 )
358 );
359
360 currentSet().clear();
361 source().applyToSet(topoSetSource::NEW, currentSet());
362
363 // Combine new value of currentSet with old one.
364 currentSet().subset(oldSet());
365 // Synchronize for coupled patches.
366 if (!noSync) currentSet().sync(mesh);
367 if (!currentSet().write())
368 {
370 << "Failed writing set "
371 << currentSet().objectPath() << endl;
372 }
373 fileHandler().flush();
374
375 break;
376 }
377
378 case topoSetSource::CLEAR :
379 {
380 Info<< " Clearing " << currentSet().type() << endl;
381 currentSet().clear();
382 if (!currentSet().write())
383 {
385 << "Failed writing set "
386 << currentSet().objectPath() << endl;
387 }
388 fileHandler().flush();
389
390 break;
391 }
392
393 case topoSetSource::INVERT :
394 {
395 Info<< " Inverting " << currentSet().type() << endl;
396 currentSet().invert(currentSet().maxSize(mesh));
397 if (!currentSet().write())
398 {
400 << "Failed writing set "
401 << currentSet().objectPath() << endl;
402 }
403 fileHandler().flush();
404
405 break;
406 }
407
408 case topoSetSource::REMOVE :
409 {
410 Info<< " Removing set" << endl;
411 removeSet(mesh, setType, setName);
412
413 break;
414 }
415
416 default:
418 << "Unhandled action: "
419 << topoSetSource::actionNames[action] << endl;
420 }
421
422 if (currentSet)
423 {
424 Info<< " "
425 << currentSet().type() << ' '
426 << currentSet().name() << " now size "
427 << returnReduce(currentSet().size(), sumOp<label>())
428 << endl;
429 }
430 }
431 }
432
433 Info<< "\nEnd\n" << endl;
434
435 return 0;
436}
437
438
439// ************************************************************************* //
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:59
void setSize(const label newLen)
Same as resize()
Definition: PtrList.H:151
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
void reorder(const labelUList &oldToNew, const bool check=false)
Definition: UPtrList.C:69
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
A list of mesh zones.
Definition: ZoneMesh.H:69
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
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void clear() noexcept
Same as reset(nullptr)
Definition: autoPtr.H:176
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A class for handling file names.
Definition: fileName.H:76
virtual void flush() const
Forcibly wait until all output done. Flush any cached data.
A tuple of keyType and dictionary, which can be used when reading named or unnamed dictionary entries...
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:91
virtual bool write(const bool valid=true) const
Write using setting from DB.
setAction
Enumeration defining various actions.
A class for handling words, derived from Foam::string.
Definition: word.H:68
dynamicFvMesh & mesh
engineTime & runTime
Required Variables.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const word dictName("faMeshDefinition")
const labelIOList & zoneID
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: MSwindows.C:1012
const fileOperation & fileHandler()
Get current file handler.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
errorManip< error > abort(error &err)
Definition: errorManip.H:144
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.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
runTime write()
dictionary dict
IOobject dictIO
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333