regionsToCell.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) 2016-2020 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "regionsToCell.H"
29#include "regionSplit.H"
30#include "emptyPolyPatch.H"
31#include "cellSet.H"
32#include "syncTools.H"
34
35// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36
37namespace Foam
38{
45 (
48 word,
49 regions
50 );
52 (
55 istream,
56 regions
57 );
58}
59
60
61Foam::topoSetSource::addToUsageTable Foam::regionsToCell::usage_
62(
63 regionsToCell::typeName,
64 "\n Usage: regionsToCell subCellSet (pt0 .. ptn) nErode\n\n"
65 " Select all cells in the connected region containing"
66 " points (pt0..ptn).\n"
67);
68
69
70// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
71
72void Foam::regionsToCell::markRegionFaces
73(
74 const boolList& selectedCell,
75 boolList& regionFace
76) const
77{
78 // Internal faces
79 const labelList& faceOwner = mesh_.faceOwner();
80 const labelList& faceNeighbour = mesh_.faceNeighbour();
81 forAll(faceNeighbour, faceI)
82 {
83 if
84 (
85 selectedCell[faceOwner[faceI]]
86 != selectedCell[faceNeighbour[faceI]]
87 )
88 {
89 regionFace[faceI] = true;
90 }
91 }
92
93 // Swap neighbour selectedCell state
94 boolList nbrSelected;
95 syncTools::swapBoundaryCellList(mesh_, selectedCell, nbrSelected);
96
97 // Boundary faces
98 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
99 forAll(pbm, patchI)
100 {
101 const polyPatch& pp = pbm[patchI];
102 const labelUList& faceCells = pp.faceCells();
103 forAll(faceCells, i)
104 {
105 label faceI = pp.start()+i;
106 label bFaceI = faceI-mesh_.nInternalFaces();
107 if
108 (
109 selectedCell[faceCells[i]]
110 != selectedCell[nbrSelected[bFaceI]]
111 )
112 {
113 regionFace[faceI] = true;
114 }
115 }
116 }
117}
118
119
120Foam::boolList Foam::regionsToCell::findRegions
121(
122 const bool verbose,
123 const boolList& selectedCell,
124 const regionSplit& cellRegion
125) const
126{
127 boolList keepRegion(cellRegion.nRegions(), false);
128
129 for (const point& insidePt : insidePoints_)
130 {
131 // Find the region containing the insidePoint
132
133 //label cellI = mesh_.findCell(insidePt);
134 label cellI = -1;
135 forAll(selectedCell, index)
136 {
137 if
138 (
139 selectedCell[index]
140 && mesh_.pointInCell(insidePt, index, polyMesh::CELL_TETS)
141 )
142 {
143 cellI = index;
144 break;
145 }
146 }
147
148 label keepRegionI = -1;
149 label keepProcI = -1;
150 if (cellI != -1)
151 {
152 keepRegionI = cellRegion[cellI];
153 keepProcI = Pstream::myProcNo();
154 }
155 reduce(keepRegionI, maxOp<label>());
156 keepRegion[keepRegionI] = true;
157
158 reduce(keepProcI, maxOp<label>());
159
160 if (keepProcI == -1)
161 {
163 << "Did not find " << insidePt
164 << " in mesh." << " Mesh bounds are " << mesh_.bounds()
165 << exit(FatalError);
166 }
167
168 if (verbose)
169 {
170 Info<< " Found location " << insidePt
171 << " in cell " << cellI << " on processor " << keepProcI
172 << " in global region " << keepRegionI
173 << " out of " << cellRegion.nRegions() << " regions." << endl;
174 }
175 }
176
177 return keepRegion;
178}
179
180
181void Foam::regionsToCell::unselectOutsideRegions
182(
183 boolList& selectedCell
184) const
185{
186 // Determine faces on the edge of selectedCell
187 boolList blockedFace(mesh_.nFaces(), false);
188 markRegionFaces(selectedCell, blockedFace);
189
190 // Determine regions
191 regionSplit cellRegion(mesh_, blockedFace);
192
193 // Determine regions containing insidePoints_
194 boolList keepRegion(findRegions(verbose_, selectedCell, cellRegion));
195
196 // Go back to bool per cell
197 forAll(cellRegion, cellI)
198 {
199 if (!keepRegion[cellRegion[cellI]])
200 {
201 selectedCell[cellI] = false;
202 }
203 }
204}
205
206
207void Foam::regionsToCell::shrinkRegions
208(
209 boolList& selectedCell
210) const
211{
212 // Select points on unselected cells and boundary
213 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
214
215 boolList boundaryPoint(mesh_.nPoints(), false);
216
217 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
218
219 for (const polyPatch& pp : pbm)
220 {
221 if (!pp.coupled() && !isA<emptyPolyPatch>(pp))
222 {
223 forAll(pp, i)
224 {
225 const face& f = pp[i];
226 forAll(f, fp)
227 {
228 boundaryPoint[f[fp]] = true;
229 }
230 }
231 }
232 }
233
234 forAll(selectedCell, cellI)
235 {
236 if (!selectedCell[cellI])
237 {
238 const labelList& cPoints = mesh_.cellPoints(cellI);
239 forAll(cPoints, i)
240 {
241 boundaryPoint[cPoints[i]] = true;
242 }
243 }
244 }
245
246 syncTools::syncPointList(mesh_, boundaryPoint, orEqOp<bool>(), false);
247
248
249 // Select all cells using these points
250 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
251
252 label nChanged = 0;
253 forAll(boundaryPoint, pointI)
254 {
255 if (boundaryPoint[pointI])
256 {
257 const labelList& pCells = mesh_.pointCells(pointI);
258 forAll(pCells, i)
259 {
260 label cellI = pCells[i];
261 if (selectedCell[cellI])
262 {
263 selectedCell[cellI] = false;
264 nChanged++;
265 }
266 }
267 }
268 }
269 Info<< " Eroded " << returnReduce(nChanged, sumOp<label>())
270 << " cells." << endl;
271}
272
273
274void Foam::regionsToCell::erode
275(
276 boolList& selectedCell
277) const
278{
279 //Info<< "Entering shrinkRegions:" << count(selectedCell) << endl;
280 //generateField("selectedCell_before", selectedCell)().write();
281
282 // Now erode and see which regions get disconnected
283 boolList shrunkSelectedCell(selectedCell);
284
285 for (label iter = 0; iter < nErode_; iter++)
286 {
287 shrinkRegions(shrunkSelectedCell);
288 }
289
290 //Info<< "After shrinking:" << count(shrunkSelectedCell) << endl;
291 //generateField("shrunkSelectedCell", shrunkSelectedCell)().write();
292
293
294
295 // Determine faces on the edge of shrunkSelectedCell
296 boolList blockedFace(mesh_.nFaces(), false);
297 markRegionFaces(shrunkSelectedCell, blockedFace);
298
299 // Find disconnected regions
300 regionSplit cellRegion(mesh_, blockedFace);
301
302 // Determine regions containing insidePoints
303 boolList keepRegion(findRegions(verbose_, shrunkSelectedCell, cellRegion));
304
305
306 // Extract cells in regions that are not to be kept.
307 boolList removeCell(mesh_.nCells(), false);
308 forAll(cellRegion, cellI)
309 {
310 if (shrunkSelectedCell[cellI] && !keepRegion[cellRegion[cellI]])
311 {
312 removeCell[cellI] = true;
313 }
314 }
315
316 //Info<< "removeCell before:" << count(removeCell) << endl;
317 //generateField("removeCell_before", removeCell)().write();
318
319
320
321 // Grow removeCell
322 for (label iter = 0; iter < nErode_; iter++)
323 {
324 // Grow selected cell in regions that are not for keeping
325 boolList boundaryPoint(mesh_.nPoints(), false);
326 forAll(removeCell, cellI)
327 {
328 if (removeCell[cellI])
329 {
330 const labelList& cPoints = mesh_.cellPoints(cellI);
331 forAll(cPoints, i)
332 {
333 boundaryPoint[cPoints[i]] = true;
334 }
335 }
336 }
337 syncTools::syncPointList(mesh_, boundaryPoint, orEqOp<bool>(), false);
338
339 // Select all cells using these points
340
341 label nChanged = 0;
342 forAll(boundaryPoint, pointI)
343 {
344 if (boundaryPoint[pointI])
345 {
346 const labelList& pCells = mesh_.pointCells(pointI);
347 forAll(pCells, i)
348 {
349 label cellI = pCells[i];
350 if (!removeCell[cellI])
351 {
352 removeCell[cellI] = true;
353 nChanged++;
354 }
355 }
356 }
357 }
358 }
359
360 //Info<< "removeCell after:" << count(removeCell) << endl;
361 //generateField("removeCell_after", removeCell)().write();
362
363
364 // Unmark removeCell
365 forAll(removeCell, cellI)
366 {
367 if (removeCell[cellI])
368 {
369 selectedCell[cellI] = false;
370 }
371 }
372}
373
374
375void Foam::regionsToCell::combine(topoSet& set, const bool add) const
376{
377 // Note: wip. Select cells first
378 boolList selectedCell(mesh_.nCells(), true);
379
380 if (setName_.size() && setName_ != "none")
381 {
382 Info<< " Loading subset " << setName_ << " to delimit search region."
383 << endl;
384 cellSet subSet(mesh_, setName_);
385
386 selectedCell = false;
387 for (const label celli : static_cast<const labelHashSet&>(subSet))
388 {
389 selectedCell[celli] = true;
390 }
391 }
392
393
394 unselectOutsideRegions(selectedCell);
395
396 if (nErode_ > 0)
397 {
398 erode(selectedCell);
399 }
400
401
402 forAll(selectedCell, cellI)
403 {
404 if (selectedCell[cellI])
405 {
406 addOrDelete(set, cellI, add);
407 }
408 }
409}
410
411
412// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
413
415(
416 const polyMesh& mesh,
417 const word& setName,
419 const label nErode
420)
421:
423 setName_(setName),
424 insidePoints_(insidePoints),
425 nErode_(nErode)
426{}
427
428
430(
431 const polyMesh& mesh,
432 const dictionary& dict
433)
434:
436 setName_(dict.getOrDefault<word>("set", "none")),
437 insidePoints_
438 (
439 dict.found("insidePoints")
440 ? dict.lookup("insidePoints")
441 : dict.lookup("insidePoint")
442 ),
443 nErode_(dict.getOrDefault<label>("nErode", 0))
444{}
445
446
448(
449 const polyMesh& mesh,
450 Istream& is
451)
452:
454 setName_(checkIs(is)),
455 insidePoints_(checkIs(is)),
456 nErode_(readLabel(checkIs(is)))
457{}
458
459
460// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
461
463(
464 const topoSetSource::setAction action,
465 topoSet& set
466) const
467{
468 if (action == topoSetSource::ADD || action == topoSetSource::NEW)
469 {
470 if (verbose_)
471 {
472 Info<< " Adding all cells of connected region "
473 << "containing points "
474 << insidePoints_ << " ..." << endl;
475 }
476
477 combine(set, true);
478 }
479 else if (action == topoSetSource::SUBTRACT)
480 {
481 if (verbose_)
482 {
483 Info<< " Removing all cells of connected region "
484 << "containing points "
485 << insidePoints_ << " ..." << endl;
486 }
487
488 combine(set, false);
489 }
490}
491
492
493// ************************************************************************* //
bool found
Macros for easy insertion into run-time selection tables.
#define addNamedToRunTimeSelectionTable(baseType, thisType, argNames, lookupName)
Add to construction table with 'lookupName' as the key.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1121
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:456
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1127
label nInternalFaces() const noexcept
Number of internal faces.
int myProcNo() const noexcept
Return processor number.
Lookup type of boundary radiation properties.
Definition: lookup.H:66
TopoSetSource. Select cells belonging to topological connected region (that contains given points)
Definition: regionsToCell.H:71
virtual void applyToSet(const topoSetSource::setAction action, topoSet &set) const
Apply specified action to the topoSet.
static void swapBoundaryCellList(const polyMesh &mesh, const UList< T > &cellData, List< T > &neighbourCellData)
Swap to obtain neighbour cell values for all boundary faces.
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
The topoSetCellSource is a intermediate class for handling topoSet sources for selecting cells.
Class with constructor to add usage string to table.
Base class of a source for a topoSet.
Definition: topoSetSource.H:68
setAction
Enumeration defining various actions.
@ SUBTRACT
Subtract elements from current set.
@ ADD
Add elements to current set.
@ NEW
Create a new set and ADD elements to it.
const polyMesh & mesh_
Reference to the mesh.
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:67
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Namespace for OpenFOAM.
List< label > labelList
A List of labels.
Definition: List.H:66
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
messageStream Info
Information stream (stdout output on master, null elsewhere)
vector point
Point is a vector.
Definition: point.H:43
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
List< bool > boolList
A List of bools.
Definition: List.H:64
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
error FatalError
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
labelList f(nPoints)
nErode
Definition: regionsToCell.H:39
insidePoints((1 2 3))
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333