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