refinementParameters.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-2015 OpenFOAM Foundation
9  Copyright (C) 2015-2020,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 "refinementParameters.H"
30 #include "unitConversion.H"
31 #include "polyMesh.H"
32 #include "globalIndex.H"
33 #include "Tuple2.H"
34 #include "wallPolyPatch.H"
35 #include "meshRefinement.H"
36 
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
39 Foam::refinementParameters::refinementParameters
40 (
41  const dictionary& dict,
42  const bool dryRun
43 )
44 :
45  maxGlobalCells_
46  (
47  meshRefinement::get<label>(dict, "maxGlobalCells", dryRun)
48  ),
49  maxLocalCells_
50  (
51  meshRefinement::get<label>(dict, "maxLocalCells", dryRun)
52  ),
53  minRefineCells_
54  (
55  meshRefinement::get<label>(dict, "minRefinementCells", dryRun)
56  ),
57  planarAngle_
58  (
59  dict.getOrDefault
60  (
61  "planarAngle",
62  dict.get<scalar>("resolveFeatureAngle")
63  )
64  ),
65  nBufferLayers_
66  (
67  meshRefinement::get<label>(dict, "nCellsBetweenLevels", dryRun)
68  ),
69  locationsOutsideMesh_
70  (
71  dict.getOrDefault
72  (
73  "locationsOutsideMesh",
74  pointField(0)
75  )
76  ),
77  useLeakClosure_(dict.getOrDefault<bool>("useLeakClosure", false)),
78  faceZoneControls_(dict.subOrEmptyDict("faceZoneControls")),
79  allowFreeStandingZoneFaces_
80  (
81  meshRefinement::get<bool>(dict, "allowFreeStandingZoneFaces", dryRun)
82  ),
83  useTopologicalSnapDetection_
84  (
85  dict.getOrDefault("useTopologicalSnapDetection", true)
86  ),
87  maxLoadUnbalance_(dict.getOrDefault<scalar>("maxLoadUnbalance", 0)),
88  maxCellUnbalance_(dict.getOrDefault<label>("maxCellUnbalance", -1)),
89  handleSnapProblems_
90  (
91  dict.getOrDefault<Switch>("handleSnapProblems", true)
92  ),
93  interfaceRefine_
94  (
95  dict.getOrDefault<Switch>("interfaceRefine", true)
96  ),
97  nErodeCellZone_(dict.getOrDefault<label>("nCellZoneErodeIter", 0)),
98  nFilterIter_(dict.getOrDefault<label>("nFilterIter", 2)),
99  minCellFraction_(dict.getOrDefault<scalar>("minCellFraction", 0)),
100  nMinCells_(dict.getOrDefault<label>("nMinCells", 0)),
101  balanceAtEnd_
102  (
103  dict.getOrDefault("balanceAtEnd", false)
104  ),
105  dryRun_(dryRun)
106 {
107  point locationInMesh;
108  List<Tuple2<point, word>> pointsToZone;
109  if (dict.readIfPresent("locationInMesh", locationInMesh))
110  {
111  locationsInMesh_.append(locationInMesh);
112  zonesInMesh_.append("none"); // special name for no cellZone
113 
114  if (dict.found("locationsInMesh"))
115  {
117  << "Cannot both specify 'locationInMesh' and 'locationsInMesh'"
118  << exit(FatalIOError);
119  }
120  }
121  else if (dict.readIfPresent("locationsInMesh", pointsToZone))
122  {
123  List<Tuple2<point, word>> pointsToZone(dict.lookup("locationsInMesh"));
124  label nZones = locationsInMesh_.size();
125  locationsInMesh_.setSize(nZones+pointsToZone.size());
126  zonesInMesh_.setSize(locationsInMesh_.size());
127 
128  forAll(pointsToZone, i)
129  {
130  locationsInMesh_[nZones] = pointsToZone[i].first();
131  zonesInMesh_[nZones] = pointsToZone[i].second();
132  if (zonesInMesh_[nZones].empty())
133  {
134  zonesInMesh_[nZones] = "none";
135  }
136  nZones++;
137  }
138  }
139  else
140  {
142  << "No 'locationInMesh' or 'locationsInMesh' provided"
143  << endl;
144  }
145 
146 
147  const scalar featAngle
148  (
149  meshRefinement::get<scalar>(dict, "resolveFeatureAngle", dryRun)
150  );
151 
152  if (featAngle < 0 || featAngle > 180)
153  {
154  curvature_ = -GREAT;
155  }
156  else
157  {
158  curvature_ = Foam::cos(degToRad(featAngle));
159  }
160 }
161 
162 
163 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
164 
166 (
167  const word& fzName,
169 ) const
170 {
171  dictionary patchInfo;
172  patchInfo.add("type", wallPolyPatch::typeName);
173  faceType = surfaceZonesInfo::INTERNAL;
174 
175  if (faceZoneControls_.found(fzName))
176  {
177  const dictionary& fzDict = faceZoneControls_.subDict(fzName);
178 
179  if (fzDict.found("patchInfo"))
180  {
181  patchInfo = fzDict.subDict("patchInfo");
182  }
183 
184  word faceTypeName;
185  if (fzDict.readIfPresent("faceType", faceTypeName))
186  {
187  faceType = surfaceZonesInfo::faceZoneTypeNames[faceTypeName];
188  }
189  }
190  return patchInfo;
191 }
192 
193 
195 (
196  polyMesh& mesh
197 ) const
198 {
199  labelList zoneIDs(zonesInMesh_.size(), -1);
200  forAll(zonesInMesh_, i)
201  {
202  if (!zonesInMesh_[i].empty() && zonesInMesh_[i] != "none")
203  {
205  (
206  zonesInMesh_[i], // name
207  labelList(0), // addressing
208  mesh
209  );
210  }
211  }
212  return zoneIDs;
213 }
214 
215 
217 (
218  const bool checkInsideMesh,
219  const polyMesh& mesh,
220  const pointField& locations
221 )
222 {
223  // Force calculation of tet-diag decomposition (for use in findCell)
224  (void)mesh.tetBasePtIs();
225 
226  // Global calculation engine
227  globalIndex globalCells(mesh.nCells());
228 
229  // Cell label per point
230  labelList cellLabels(locations.size());
231 
232  forAll(locations, i)
233  {
234  const point& location = locations[i];
235 
236  label localCellI = mesh.findCell(location, polyMesh::FACE_DIAG_TRIS);
237 
238  label globalCellI = -1;
239 
240  if (localCellI != -1)
241  {
242  globalCellI = globalCells.toGlobal(localCellI);
243  }
244 
245  reduce(globalCellI, maxOp<label>());
246 
247  if (checkInsideMesh && globalCellI == -1)
248  {
250  << "Point " << location
251  << " is not inside the mesh or on a face or edge." << nl
252  << "Bounding box of the mesh:" << mesh.bounds()
253  << exit(FatalError);
254  }
255 
256 
257  label procI = globalCells.whichProcID(globalCellI);
258  label procCellI = globalCells.toLocal(procI, globalCellI);
259 
260  Info<< "Found point " << location << " in cell " << procCellI
261  << " on processor " << procI << endl;
262 
263  if (globalCells.isLocal(globalCellI))
264  {
265  cellLabels[i] = localCellI;
266  }
267  else
268  {
269  cellLabels[i] = -1;
270  }
271  }
272  return cellLabels;
273 }
274 
275 
277 (
278  const wordList& zonesInMesh
279 )
280 {
281  DynamicList<label> indices(zonesInMesh.size());
282 
283  forAll(zonesInMesh, i)
284  {
285  if (!zonesInMesh[i].empty() && zonesInMesh[i] != "none")
286  {
287  indices.append(i);
288  }
289  }
290  return indices;
291 }
292 
293 
295 (
296  const wordList& zonesInMesh
297 )
298 {
299  DynamicList<label> indices(0);
300 
301  forAll(zonesInMesh, i)
302  {
303  if (zonesInMesh[i].empty() || zonesInMesh[i] == "none")
304  {
305  indices.append(i);
306  }
307  }
308  return indices;
309 }
310 
311 
313 (
314  const pointField& locationsInMesh,
315  const wordList& zonesInMesh,
316  const pointField& locationsOutsideMesh
317 )
318 {
319  // Sort locations according to zone. Add outside as last element
320  DynamicList<pointField> allLocations(zonesInMesh.size()+1);
321  DynamicList<word> allZoneNames(allLocations.size());
322 
323  forAll(zonesInMesh, i)
324  {
325  const word name
326  (
327  zonesInMesh[i].empty()
328  ? "none"
329  : zonesInMesh[i]
330  );
331  const point& pt = locationsInMesh[i];
332 
333  const label index = allZoneNames.find(name);
334  if (index == -1)
335  {
336  allZoneNames.append(name);
337  allLocations.append(pointField(1, pt));
338  }
339  else
340  {
341  allLocations[index].append(pt);
342  }
343  }
344 
345  allZoneNames.append("outside");
346  allLocations.append(locationsOutsideMesh);
347 
348  return List<pointField>(std::move(allLocations));
349 }
350 
351 
352 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
const labelIOList & zoneIDs
Definition: correctPhi.H:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
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
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:517
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:899
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
Unit conversion functions.
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
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
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, any/none. Also accepts 0/1 as a string and shortcuts t/f, y/n.
Definition: Switch.H:77
static const Enum< faceZoneType > faceZoneTypeNames
dictionary getZoneInfo(const word &fzName, surfaceZonesInfo::faceZoneType &faceType) const
Get patchInfo and faceType for faceZone.
labelList addCellZonesToMesh(polyMesh &) const
Add cellZones to mesh. Return indices of cellZones (or -1)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
static labelList zonedLocations(const wordList &zonesInMesh)
Extract indices of named locations (so excludes &#39;keepPoints&#39;)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
List< word > wordList
List of word.
Definition: fileName.H:59
vector point
Point is a vector.
Definition: point.H:37
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
label nCells() const noexcept
Number of mesh cells.
static labelList findCells(const bool checkInsideMesh, const polyMesh &, const pointField &locations)
Checks that cells are in mesh. Returns cells (or -1) they.
static List< pointField > zonePoints(const pointField &locationsInMesh, const wordList &zonesInMesh, const pointField &locationsOutsideMesh)
Helper: per zone (entry in zonesInMesh) the locations with.
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.
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1511
messageStream Info
Information stream (stdout output on master, null elsewhere)
const boundBox & bounds() const noexcept
Return mesh bounding box.
Definition: polyMesh.H:616
faceZoneType
What to do with faceZone faces.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
List< label > labelList
A List of labels.
Definition: List.H:62
static labelList unzonedLocations(const wordList &zonesInMesh)
Extract indices of unnamed locations (&#39;keepPoints&#39;)
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static label addCellZone(const word &name, const labelList &addressing, polyMesh &mesh)