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 -------------------------------------------------------------------------------
10 License
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 
37 namespace Foam
38 {
39  defineTypeNameAndDebug(regionsToCell, 0);
40  addToRunTimeSelectionTable(topoSetSource, regionsToCell, word);
41  addToRunTimeSelectionTable(topoSetSource, regionsToCell, istream);
42  addToRunTimeSelectionTable(topoSetCellSource, regionsToCell, word);
43  addToRunTimeSelectionTable(topoSetCellSource, regionsToCell, istream);
45  (
46  topoSetCellSource,
47  regionsToCell,
48  word,
49  regions
50  );
52  (
53  topoSetCellSource,
54  regionsToCell,
55  istream,
56  regions
57  );
58 }
59 
60 
61 Foam::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 
72 void 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 
120 Foam::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 
181 void 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 
207 void 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 
274 void 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 
375 void 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,
418  const pointField& insidePoints,
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 // ************************************************************************* //
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::topoSetSource::ADD
Add elements to current set.
Definition: topoSetSource.H:103
Foam::BitOps::set
void set(List< bool > &bools, const labelRange &range)
Set the specified range 'on' in a boolList.
Definition: BitOps.C:37
Foam::regionsToCell::applyToSet
virtual void applyToSet(const topoSetSource::setAction action, topoSet &set) const
Apply specified action to the topoSet.
Definition: regionsToCell.C:463
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionaryI.H:87
Foam::topoSetSource::addToUsageTable
Class with constructor to add usage string to table.
Definition: topoSetSource.H:129
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:65
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:444
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::topoSetSource::setAction
setAction
Enumeration defining the valid actions.
Definition: topoSetSource.H:100
Foam::topoSetSource::NEW
Create a new set and ADD elements to it.
Definition: topoSetSource.H:104
syncTools.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::syncTools::syncPointList
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
Definition: syncToolsTemplates.C:721
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
regionsToCell.H
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::Field< vector >
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
Foam::ListListOps::combine
AccessType combine(const UList< T > &lists, AccessOp aop=accessOp< T >())
Combines sub-lists into a single list.
Definition: ListListOps.C:69
Foam::polyMesh::faceOwner
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1107
regionSplit.H
Foam::addNamedToRunTimeSelectionTable
addNamedToRunTimeSelectionTable(topoSetCellSource, badQualityToCell, word, badQuality)
Foam::topoSet
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:63
Foam::syncTools::swapBoundaryCellList
static void swapBoundaryCellList(const polyMesh &mesh, const UList< T > &cellData, List< T > &neighbourCellData)
Swap to obtain neighbour cell values for all boundary faces.
Definition: syncToolsTemplates.C:1392
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:386
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::add
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:939
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::topoSetSource::SUBTRACT
Subtract elements from current set.
Definition: topoSetSource.H:105
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
emptyPolyPatch.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::polyMesh::CELL_TETS
Definition: polyMesh.H:109
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
nErode
nErode
Definition: regionsToCell.H:39
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
f
labelList f(nPoints)
Foam::readLabel
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:66
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const noexcept
Number of internal faces.
Definition: primitiveMeshI.H:78
Foam::List< bool >
Foam::topoSetCellSource
The topoSetCellSource is a intermediate class for handling topoSet sources for selecting cells.
Definition: topoSetCellSource.H:54
insidePoints
insidePoints((1 2 3))
Foam::regionsToCell::regionsToCell
regionsToCell(const polyMesh &mesh, const word &setName, const pointField &insidePoints, const label nErode)
Construct from components.
Definition: regionsToCell.C:415
cellSet.H
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::labelHashSet
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
Foam::topoSetSource::mesh_
const polyMesh & mesh_
Reference to the mesh.
Definition: topoSetSource.H:156
Foam::dictionary::getOrDefault
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:148
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::polyMesh::faceNeighbour
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1113