cellSetOption.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) 2017-2023 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 "cellSetOption.H"
30 #include "cellSet.H"
31 #include "cellBitSet.H"
32 #include "volFields.H"
33 #include "cellCellStencilObject.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39  namespace fv
40  {
41  defineTypeNameAndDebug(cellSetOption, 0);
42  }
43 }
44 
45 
46 const Foam::Enum
47 <
49 >
51 ({
52  { selectionModeType::smAll, "all" },
53  { selectionModeType::smGeometric, "geometric" },
54  { selectionModeType::smPoints, "points" },
55  { selectionModeType::smMovingPoints, "movingPoints" },
56  { selectionModeType::smCellSet, "cellSet" },
57  { selectionModeType::smCellZone, "cellZone" },
58  { selectionModeType::smCellType, "cellType" }
59 });
60 
61 
62 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
63 
64 void Foam::fv::cellSetOption::setSelection(const dictionary& dict)
65 {
67 
68  switch (selectionMode_)
69  {
70  case smAll:
71  {
72  break;
73  }
74  case smGeometric:
75  {
76  geometricSelection_ = dict.subDict("selection");
77  break;
78  }
79  case smPoints:
80  {
81  dict.readEntry("points", points_);
82  break;
83  }
84  case smMovingPoints:
85  {
86  const dictionary& mpsDict = dict.subDict("movingPoints");
87 
88  movingPoints_.resize_null(mpsDict.size());
89 
90  label pointi = 0;
91  for (const entry& dEntry : mpsDict)
92  {
93  const word& key = dEntry.keyword();
94 
95  movingPoints_.set
96  (
97  pointi,
98  Function1<point>::New
99  (
100  key,
101  mpsDict,
102  &mesh_
103  )
104  );
105  ++pointi;
106  }
107  break;
108  }
109  case smCellSet:
110  {
112  dict.readEntry("cellSet", selectionNames_.first());
113  break;
114  }
115  case smCellZone:
116  {
117  if
118  (
119  !dict.readIfPresent("cellZones", selectionNames_)
121  )
122  {
124  dict.readEntry("cellZone", selectionNames_.first());
125  }
126  break;
127  }
128  case smCellType:
129  {
130  break;
131  }
132  default:
133  {
135  << "Unknown selectionMode "
137  << ". Valid selectionMode types : "
139  << exit(FatalError);
140  }
141  }
142 }
143 
144 
146 {
147  // Set volume information
148 
149  scalar sumVol = 0;
150  for (const label celli : cells_)
151  {
152  sumVol += mesh_.V()[celli];
153  }
154  reduce(sumVol, sumOp<scalar>());
155 
156  const scalar old(V_);
157  V_ = sumVol;
158 
159  // Compare volume values, stringified using current write precision
160  if
161  (
164  )
165  {
167  << "- selected " << returnReduce(cells_.size(), sumOp<label>())
168  << " cell(s) with volume " << V_ << endl;
169  }
170 }
171 
172 
174 {
175  switch (selectionMode_)
176  {
177  case smAll:
178  {
179  Info<< indent << "- selecting all cells" << endl;
180 
181  cells_ = identity(mesh_.nCells());
182  break;
183  }
184  case smGeometric:
185  {
186  Info<< indent << "- selecting cells geometrically" << endl;
187 
188  bitSet selectedCells
189  (
190  // verbosity = true
191  cellBitSet::select(mesh_, geometricSelection_, true)
192  );
193 
194  // From bitSet -> labels
195  cells_ = selectedCells.sortedToc();
196  break;
197  }
198  case smPoints:
199  {
200  Info<< indent << "- selecting cells using points" << endl;
201 
202  labelHashSet selectedCells;
203 
204  for (const point& p : points_)
205  {
206  const label celli = mesh_.findCell(p);
207 
208  const bool found = (celli >= 0);
209 
210  if (found)
211  {
212  selectedCells.insert(celli);
213  }
214 
215  if (!returnReduceOr(found))
216  {
218  << "No owner cell found for point " << p << endl;
219  }
220  }
221 
222  cells_ = selectedCells.sortedToc();
223  break;
224  }
225  case smMovingPoints:
226  {
227  Info<< indent << "- selecting cells using moving points" << endl;
228 
229  const scalar t = mesh_.time().timeOutputValue();
230 
231  labelHashSet selectedCells;
232 
233  forAll(movingPoints_, i)
234  {
235  if (!movingPoints_.set(i))
236  {
237  continue;
238  }
239 
240  const point p(movingPoints_[i].value(t));
241 
242  const label celli = mesh_.findCell(p);
243 
244  const bool found = (celli >= 0);
245 
246  // Ensure that only one processor inserts this cell
247  label proci = -1;
248  if (found)
249  {
250  proci = Pstream::myProcNo();
251  }
252  reduce(proci, maxOp<label>());
253 
254  if (found && (proci == Pstream::myProcNo()))
255  {
256  selectedCells.insert(celli);
257  }
258 
259  if (!returnReduceOr(found))
260  {
262  << "No owner cell found for point " << p << endl;
263  }
264  }
265 
266  cells_ = selectedCells.sortedToc();
267  break;
268  }
269  case smCellSet:
270  {
271  Info<< indent
272  << "- selecting cells using cellSet "
273  << zoneName() << endl;
274 
275  cells_ = cellSet(mesh_, zoneName()).sortedToc();
276  break;
277  }
278  case smCellZone:
279  {
280  Info<< indent
281  << "- selecting cells using cellZones "
282  << flatOutput(selectionNames_) << nl;
283 
284  const auto& zones = mesh_.cellZones();
285 
286  // Also handles groups, multiple zones etc ...
287  labelList zoneIDs = zones.indices(selectionNames_);
288 
289  if (zoneIDs.empty())
290  {
292  << "No matching cellZones: "
293  << flatOutput(selectionNames_) << nl
294  << "Valid zones : "
295  << flatOutput(zones.names()) << nl
296  << "Valid groups: "
297  << flatOutput(zones.groupNames())
298  << nl
299  << exit(FatalError);
300  }
301 
302  if (zoneIDs.size() == 1)
303  {
304  cells_ = zones[zoneIDs.first()];
305  // TBD: Foam::sort(cells_);
306  }
307  else
308  {
309  cells_ = zones.selection(zoneIDs).sortedToc();
310  }
311  break;
312  }
313  case smCellType:
314  {
315  labelHashSet selectedCells;
316  const cellCellStencilObject& overlap = Stencil::New(mesh_);
317  const labelList& cellTypes = overlap.cellTypes();
318  forAll(cellTypes, celli)
319  {
320  if (cellTypes[celli] == cellCellStencil::POROUS)
321  {
322  selectedCells.insert(celli);
323  }
324  cells_ = selectedCells.sortedToc();
325  }
326  break;
327  }
328  default:
329  {
331  << "Unknown selectionMode "
332  << selectionModeTypeNames_[selectionMode_]
333  << ". Valid selectionMode types are "
334  << selectionModeTypeNames_
335  << exit(FatalError);
336  }
337  }
338 
339  if
340  (
341  !(smAll == selectionMode_ || smMovingPoints == selectionMode_)
342  && returnReduceAnd(cells_.empty())
343  )
344  {
346  << "No cells selected!" << endl;
347  }
348 }
349 
350 
351 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
352 
354 (
355  const word& name,
356  const word& modelType,
357  const dictionary& dict,
358  const fvMesh& mesh
359 )
360 :
361  fv::option(name, modelType, dict, mesh),
362  selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)),
363  updateSelection_(false),
364  timeStart_(-1),
365  duration_(0),
366  selectionNames_(),
367  points_(),
368  movingPoints_(),
369  geometricSelection_(),
370  V_(0)
371 {
372  Info<< incrIndent;
373  read(dict);
377  Info<< decrIndent;
378 }
379 
380 
381 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
382 
384 {
385  if (fv::option::isActive() && inTimeLimits(mesh_.time().value()))
386  {
387  // Update the cell set if the mesh is changing
388  if (mesh_.changing())
389  {
390  if (mesh_.topoChanging())
391  {
392  setCellSelection();
393  // Force printing of new set volume
394  V_ = -GREAT;
395  }
396  else if
397  (
398  selectionMode_ == smGeometric
399  || selectionMode_ == smPoints
400  || selectionMode_ == smCellType
401  || selectionMode_ == smMovingPoints
402  )
403  {
404  // Geometric selection mode(s)
405  setCellSelection();
406  }
407 
408  // Report new volume (if changed)
409  setVol();
410  }
411  else if (selectionMode_ == smMovingPoints)
412  {
413  // Update the cell selection if it moves
414  setCellSelection();
415  setVol();
416  }
417 
418  return true;
419  }
420 
421  return false;
422 }
423 
424 
426 {
427  if (!fv::option::read(dict))
428  {
429  return false;
430  }
431 
432  timeStart_ = -1;
433 
434  if (coeffs_.readIfPresent("timeStart", timeStart_))
435  {
436  coeffs_.readEntry("duration", duration_);
437  }
438 
439  // Do not read and set selections unless users request
440  updateSelection_ = coeffs_.getOrDefault("updateSelection", false);
441 
442  if (updateSelection_)
443  {
444  setSelection(coeffs_);
445  setCellSelection();
446  setVol();
447  }
448 
449  return true;
450 }
451 
452 
453 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
selectionModeType selectionMode_
Cell selection mode.
dictionary dict
const labelIOList & zoneIDs
Definition: correctPhi.H:59
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:493
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
defineTypeNameAndDebug(atmAmbientTurbSource, 0)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const fvMesh & mesh_
Reference to the mesh database.
Definition: fvOption.H:142
static const Type & New(const Mesh &mesh, Args &&... args)
Get existing or create a new MeshObject. Registered with typeName.
Definition: MeshObject.C:53
PtrList< Function1< point > > movingPoints_
List of points for "movingPoints" selectionMode.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:666
T & first()
Access first element of the list, position [0].
Definition: UList.H:853
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:423
virtual bool read(const dictionary &dict)
Read source dictionary.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
const word & timeName() const noexcept
Return the current time name.
Definition: TimeStateI.H:30
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
static const Enum< selectionModeType > selectionModeTypeNames_
List of selection mode type names.
cellSetOption(const word &name, const word &modelType, const dictionary &dict, const fvMesh &mesh)
Construct from components.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
wordRes selectionNames_
Face selection names (for set or zone selections)
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
virtual bool isActive()
Is the source active?
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:137
A class for handling words, derived from Foam::string.
Definition: word.H:63
labelList fv(nPoints)
const cellCellStencilObject & overlap
Definition: correctPhi.H:57
virtual bool read(const dictionary &dict)
Read source dictionary.
Definition: fvOptionIO.C:48
const labelList & cellTypes
Definition: setCellMask.H:27
static bitSet select(const polyMesh &mesh, const dictionary &dict, const bool verbosity=false)
Return a cell selection according to the dictionary specification of actions.
Definition: cellBitSet.C:90
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:511
selectionModeType
Enumeration for selection mode types.
dictionary geometricSelection_
Dictionary entries for "geometric" (topoSetCellSource) selection.
void setCellSelection()
Set the cell selection based on user input selection mode.
void setSelection(const dictionary &dict)
Set cell selection name or points selection from dictionary input.
Definition: cellSetOption.C:57
vector point
Point is a vector.
Definition: point.H:37
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
List< point > points_
List of points for "points" selectionMode.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool isActive()
Is the source active?
Definition: fvOption.C:112
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:502
dictionary coeffs_
Dictionary containing source coefficients.
Definition: fvOption.H:152
bool found
Namespace for OpenFOAM.
void setVol()
Recalculate the volume.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225