Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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
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
39Foam::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 {
116 FatalIOErrorInFunction(dict)
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);
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(
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
312Foam::List<Foam::pointField> Foam::refinementParameters::zonePoints
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// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void append(const T &val)
Copy append an element to the end of this list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition Switch.H:81
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
label find(const T &val) const
Find index of the first occurrence of the value.
Definition UList.C:160
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition dictionary.C:441
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition dictionary.C:625
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
label toLocal(const label proci, const label i) const
From global to local on proci.
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
bool isLocal(const label proci, const label i) const
Is on processor proci.
label toGlobal(const label proci, const label i) const
From local to global on proci.
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
static Type get(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX, const Type &deflt=Zero)
Wrapper around dictionary::get which does not exit.
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition polyMesh.C:1496
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition polyMesh.C:884
const boundBox & bounds() const noexcept
Return mesh bounding box.
Definition polyMesh.H:617
label nCells() const noexcept
Number of mesh cells.
static labelList unzonedLocations(const wordList &zonesInMesh)
Extract indices of unnamed locations ('keepPoints').
labelList addCellZonesToMesh(polyMesh &) const
Add cellZones to mesh. Return indices of cellZones (or -1).
static labelList zonedLocations(const wordList &zonesInMesh)
Extract indices of named locations (so excludes 'keepPoints').
const pointField & locationsOutsideMesh() const
Optional points which are checked to be outside the mesh.
static labelList findCells(const bool checkInsideMesh, const polyMesh &, const pointField &locations)
Checks that cells are in mesh. Returns cells (or -1) they.
const pointField & locationsInMesh() const
Areas to keep.
static List< pointField > zonePoints(const pointField &locationsInMesh, const wordList &zonesInMesh, const pointField &locationsOutsideMesh)
Helper: per zone (entry in zonesInMesh) the locations with.
dictionary getZoneInfo(const word &fzName, surfaceZonesInfo::faceZoneType &faceType) const
Get patchInfo and faceType for faceZone.
const wordList & zonesInMesh() const
Per area the zone name.
faceZoneType
What to do with faceZone faces.
static const Enum< faceZoneType > faceZoneTypeNames
static label addCellZone(const word &name, const labelList &addressing, polyMesh &mesh)
A class for handling words, derived from Foam::string.
Definition word.H:66
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
const labelIOList & zoneIDs
Definition correctPhi.H:59
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
List< word > wordList
List of word.
Definition fileName.H:60
List< label > labelList
A List of labels.
Definition List.H:62
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
vector point
Point is a vector.
Definition point.H:37
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
dimensionedScalar cos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Unit conversion functions.