regionToCell.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) 2015-2020 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 "regionToCell.H"
30 #include "regionSplit.H"
31 #include "emptyPolyPatch.H"
32 #include "cellSet.H"
33 #include "syncTools.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(regionToCell, 0);
41  addToRunTimeSelectionTable(topoSetSource, regionToCell, word);
42  addToRunTimeSelectionTable(topoSetSource, regionToCell, istream);
43  addToRunTimeSelectionTable(topoSetCellSource, regionToCell, word);
44  addToRunTimeSelectionTable(topoSetCellSource, regionToCell, istream);
45 }
46 
47 
48 Foam::topoSetSource::addToUsageTable Foam::regionToCell::usage_
49 (
50  regionToCell::typeName,
51  "\n Usage: regionToCell subCellSet (pt0 .. ptn) nErode\n\n"
52  " Select all cells in the connected region containing"
53  " points (pt0..ptn).\n"
54 );
55 
56 
57 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 
59 void Foam::regionToCell::markRegionFaces
60 (
61  const boolList& selectedCell,
62  boolList& regionFace
63 ) const
64 {
65  // Internal faces
66  const labelList& faceOwner = mesh_.faceOwner();
67  const labelList& faceNeighbour = mesh_.faceNeighbour();
68  forAll(faceNeighbour, facei)
69  {
70  if
71  (
72  selectedCell[faceOwner[facei]]
73  != selectedCell[faceNeighbour[facei]]
74  )
75  {
76  regionFace[facei] = true;
77  }
78  }
79 
80  // Swap neighbour selectedCell state
81  boolList nbrSelected;
82  syncTools::swapBoundaryCellList(mesh_, selectedCell, nbrSelected);
83 
84  // Boundary faces
85  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
86  forAll(pbm, patchi)
87  {
88  const polyPatch& pp = pbm[patchi];
89  const labelUList& faceCells = pp.faceCells();
90  forAll(faceCells, i)
91  {
92  label facei = pp.start()+i;
93  label bFacei = facei-mesh_.nInternalFaces();
94  if (selectedCell[faceCells[i]] != nbrSelected[bFacei])
95  {
96  regionFace[facei] = true;
97  }
98  }
99  }
100 }
101 
102 
103 Foam::boolList Foam::regionToCell::findRegions
104 (
105  const bool verbose,
106  const regionSplit& cellRegion
107 ) const
108 {
109  boolList keepRegion(cellRegion.nRegions(), false);
110 
111  forAll(insidePoints_, i)
112  {
113  // Find the region containing the insidePoint
114 
115  label celli = mesh_.findCell(insidePoints_[i]);
116 
117  label keepRegionI = -1;
118  label keepProci = -1;
119  if (celli != -1)
120  {
121  keepRegionI = cellRegion[celli];
122  keepProci = Pstream::myProcNo();
123  }
124  reduce(keepRegionI, maxOp<label>());
125  keepRegion[keepRegionI] = true;
126 
127  reduce(keepProci, maxOp<label>());
128 
129  if (keepProci == -1)
130  {
132  << "Did not find " << insidePoints_[i]
133  << " in mesh." << " Mesh bounds are " << mesh_.bounds()
134  << exit(FatalError);
135  }
136 
137  if (verbose)
138  {
139  Info<< " Found location " << insidePoints_[i]
140  << " in cell " << celli << " on processor " << keepProci
141  << " in global region " << keepRegionI
142  << " out of " << cellRegion.nRegions() << " regions." << endl;
143  }
144  }
145 
146  return keepRegion;
147 }
148 
149 
150 void Foam::regionToCell::unselectOutsideRegions
151 (
152  boolList& selectedCell
153 ) const
154 {
155  // Determine faces on the edge of selectedCell
156  boolList blockedFace(mesh_.nFaces(), false);
157  markRegionFaces(selectedCell, blockedFace);
158 
159  // Determine regions
160  regionSplit cellRegion(mesh_, blockedFace);
161 
162  // Determine regions containing insidePoints_
163  boolList keepRegion(findRegions(verbose_, cellRegion));
164 
165  // Go back to bool per cell
166  forAll(cellRegion, celli)
167  {
168  if (!keepRegion[cellRegion[celli]])
169  {
170  selectedCell[celli] = false;
171  }
172  }
173 }
174 
175 
176 void Foam::regionToCell::shrinkRegions
177 (
178  boolList& selectedCell
179 ) const
180 {
181  // Select points on unselected cells and boundary
182  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183 
184  boolList boundaryPoint(mesh_.nPoints(), false);
185 
186  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
187 
188  forAll(pbm, patchi)
189  {
190  const polyPatch& pp = pbm[patchi];
191 
192  if (!pp.coupled() && !isA<emptyPolyPatch>(pp))
193  {
194  forAll(pp, i)
195  {
196  const face& f = pp[i];
197  forAll(f, fp)
198  {
199  boundaryPoint[f[fp]] = true;
200  }
201  }
202  }
203  }
204 
205  forAll(selectedCell, celli)
206  {
207  if (!selectedCell[celli])
208  {
209  const labelList& cPoints = mesh_.cellPoints(celli);
210  forAll(cPoints, i)
211  {
212  boundaryPoint[cPoints[i]] = true;
213  }
214  }
215  }
216 
217  syncTools::syncPointList(mesh_, boundaryPoint, orEqOp<bool>(), false);
218 
219 
220  // Select all cells using these points
221  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
222 
223  label nChanged = 0;
224  forAll(boundaryPoint, pointi)
225  {
226  if (boundaryPoint[pointi])
227  {
228  const labelList& pCells = mesh_.pointCells(pointi);
229  forAll(pCells, i)
230  {
231  label celli = pCells[i];
232  if (selectedCell[celli])
233  {
234  selectedCell[celli] = false;
235  nChanged++;
236  }
237  }
238  }
239  }
240  Info<< " Eroded "
241  << returnReduce(nChanged, sumOp<label>())
242  << " cells." << endl;
243 }
244 
245 
246 void Foam::regionToCell::erode
247 (
248  boolList& selectedCell
249 ) const
250 {
251  //Info<< "Entering shrinkRegions:" << count(selectedCell) << endl;
252  //generateField("selectedCell_before", selectedCell)().write();
253 
254  // Now erode and see which regions get disconnected
255  boolList shrunkSelectedCell(selectedCell);
256 
257  for (label iter = 0; iter < nErode_; iter++)
258  {
259  shrinkRegions(shrunkSelectedCell);
260  }
261 
262  //Info<< "After shrinking:" << count(shrunkSelectedCell) << endl;
263  //generateField("shrunkSelectedCell", shrunkSelectedCell)().write();
264 
265 
266  // Determine faces on the edge of shrunkSelectedCell
267  boolList blockedFace(mesh_.nFaces(), false);
268  markRegionFaces(shrunkSelectedCell, blockedFace);
269 
270  // Find disconnected regions
271  regionSplit cellRegion(mesh_, blockedFace);
272 
273  // Determine regions containing insidePoints
274  boolList keepRegion(findRegions(verbose_, cellRegion));
275 
276 
277  // Extract cells in regions that are not to be kept.
278  boolList removeCell(mesh_.nCells(), false);
279  forAll(cellRegion, celli)
280  {
281  if (shrunkSelectedCell[celli] && !keepRegion[cellRegion[celli]])
282  {
283  removeCell[celli] = true;
284  }
285  }
286 
287  //Info<< "removeCell before:" << count(removeCell) << endl;
288  //generateField("removeCell_before", removeCell)().write();
289 
290 
291  // Grow removeCell
292  for (label iter = 0; iter < nErode_; iter++)
293  {
294  // Grow selected cell in regions that are not for keeping
295  boolList boundaryPoint(mesh_.nPoints(), false);
296  forAll(removeCell, celli)
297  {
298  if (removeCell[celli])
299  {
300  const labelList& cPoints = mesh_.cellPoints(celli);
301  forAll(cPoints, i)
302  {
303  boundaryPoint[cPoints[i]] = true;
304  }
305  }
306  }
307  syncTools::syncPointList(mesh_, boundaryPoint, orEqOp<bool>(), false);
308 
309  // Select all cells using these points
310 
311  label nChanged = 0;
312  forAll(boundaryPoint, pointi)
313  {
314  if (boundaryPoint[pointi])
315  {
316  const labelList& pCells = mesh_.pointCells(pointi);
317  forAll(pCells, i)
318  {
319  label celli = pCells[i];
320  if (!removeCell[celli])
321  {
322  removeCell[celli] = true;
323  nChanged++;
324  }
325  }
326  }
327  }
328  }
329 
330  //Info<< "removeCell after:" << count(removeCell) << endl;
331  //generateField("removeCell_after", removeCell)().write();
332 
333 
334  // Unmark removeCell
335  forAll(removeCell, celli)
336  {
337  if (removeCell[celli])
338  {
339  selectedCell[celli] = false;
340  }
341  }
342 }
343 
344 
345 void Foam::regionToCell::combine(topoSet& set, const bool add) const
346 {
347  // Note: wip. Select cells first
348  boolList selectedCell(mesh_.nCells(), true);
349 
350  if (setName_.size() && setName_ != "none")
351  {
352  Info<< " Loading subset " << setName_
353  << " to delimit search region."
354  << endl;
355 
356  cellSet subSet(mesh_, setName_);
357 
358  selectedCell = false;
359  for (const label celli : subSet)
360  {
361  selectedCell[celli] = true;
362  }
363  }
364 
365 
366  unselectOutsideRegions(selectedCell);
367 
368  if (nErode_ > 0)
369  {
370  erode(selectedCell);
371  }
372 
373 
374  forAll(selectedCell, celli)
375  {
376  if (selectedCell[celli])
377  {
378  addOrDelete(set, celli, add);
379  }
380  }
381 }
382 
383 
384 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
385 
387 (
388  const polyMesh& mesh,
389  const word& setName,
390  const pointField& insidePoints,
391  const label nErode
392 )
393 :
395  setName_(setName),
396  insidePoints_(insidePoints),
397  nErode_(nErode)
398 {}
399 
400 
402 (
403  const polyMesh& mesh,
404  const dictionary& dict
405 )
406 :
408  setName_(dict.getOrDefault<word>("set", "none")),
409  insidePoints_
410  (
411  dict.getCompat<pointField>("insidePoints", {{ "insidePoint", 0 }})
412  ),
413  nErode_(dict.getCheckOrDefault<label>("nErode", 0, labelMinMax::ge(0)))
414 {}
415 
416 
418 (
419  const polyMesh& mesh,
420  Istream& is
421 )
422 :
424  setName_(checkIs(is)),
425  insidePoints_(checkIs(is)),
426  nErode_(readLabel(checkIs(is)))
427 {}
428 
429 
430 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
431 
433 (
434  const topoSetSource::setAction action,
435  topoSet& set
436 ) const
437 {
438  if (action == topoSetSource::ADD || action == topoSetSource::NEW)
439  {
440  if (verbose_)
441  {
442  Info<< " Adding all cells of connected region "
443  << "containing points "
444  << insidePoints_ << " ..." << endl;
445  }
446 
447  combine(set, true);
448  }
449  else if (action == topoSetSource::SUBTRACT)
450  {
451  if (verbose_)
452  {
453  Info<< " Removing all cells of connected region "
454  << "containing points "
455  << insidePoints_ << " ..." << endl;
456  }
457 
458  combine(set, false);
459  }
460 }
461 
462 
463 // ************************************************************************* //
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::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
regionToCell.H
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::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::regionToCell::applyToSet
virtual void applyToSet(const topoSetSource::setAction action, topoSet &set) const
Apply specified action to the topoSet.
Definition: regionToCell.C:433
Foam::dictionary::getCompat
T getCompat(const word &keyword, std::initializer_list< std::pair< const char *, int >> compat, enum keyType::option=keyType::REGEX) const
Definition: dictionaryTemplates.C:134
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
Foam::regionToCell::regionToCell
regionToCell(const polyMesh &mesh, const word &setName, const pointField &insidePoints, const label nErode)
Construct from components.
Definition: regionToCell.C:387
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
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::topoSet
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:63
Foam::dictionary::getCheckOrDefault
T getCheckOrDefault(const word &keyword, const T &deflt, const Predicate &pred, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:209
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
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
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::MinMax::ge
static MinMax< T > ge(const T &minVal)
A semi-infinite range from minVal to the type max.
Definition: MinMaxI.H:31
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
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::topoSetCellSource
The topoSetCellSource is a intermediate class for handling topoSet sources for selecting cells.
Definition: topoSetCellSource.H:54
insidePoints
insidePoints((1 2 3))
cellSet.H
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.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