FreeFOAM The Cross-Platform CFD Toolkit
layerParameters.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) 1991-2010 OpenCFD Ltd.
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 "layerParameters.H"
31 #include <OSspecific/regExp.H>
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
40 // Read the number of layers from dictionary. Per patch 0 or the number
41 // of layers.
42 Foam::labelList Foam::layerParameters::readNumLayers
43 (
44  const PtrList<dictionary>& surfaceDicts,
45  const refinementSurfaces& refineSurfaces,
46  const labelList& globalToPatch,
47  const polyBoundaryMesh& boundaryMesh
48 )
49 {
50  // Per surface the number of layers
51  labelList globalSurfLayers(surfaceDicts.size());
52  // Per surface, per region the number of layers
53  List<Map<label> > regionSurfLayers(surfaceDicts.size());
54 
55  const labelList& surfaceIndices = refineSurfaces.surfaces();
56 
57  forAll(surfaceDicts, surfI)
58  {
59  const dictionary& dict = surfaceDicts[surfI];
60 
61  globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
62 
63  if (dict.found("regions"))
64  {
65  // Per-region layer information
66 
67  PtrList<dictionary> regionDicts(dict.lookup("regions"));
68 
69  const wordList& regionNames =
70  refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
71 
72  forAll(regionDicts, dictI)
73  {
74  const dictionary& regionDict = regionDicts[dictI];
75 
76  const word regionName(regionDict.lookup("name"));
77 
78  label regionI = findIndex(regionNames, regionName);
79 
80  label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
81 
82  Info<< " region " << regionName << ':'<< nl
83  << " surface layers:" << nLayers << nl;
84 
85  regionSurfLayers[surfI].insert(regionI, nLayers);
86  }
87  }
88  }
89 
90 
91  // Transfer per surface/region information into patchwise region info
92 
93  labelList nLayers(boundaryMesh.size(), 0);
94 
95  forAll(surfaceIndices, surfI)
96  {
97  const wordList& regionNames =
98  refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
99 
100  forAll(regionNames, regionI)
101  {
102  const word& regionName = regionNames[regionI];
103 
104  label global = refineSurfaces.globalRegion(surfI, regionI);
105 
106  label patchI = globalToPatch[global];
107 
108  // Initialise to surface-wise layers
109  nLayers[patchI] = globalSurfLayers[surfI];
110 
111  // Override with region specific data if available
113  regionSurfLayers[surfI].find(regionI);
114 
115  if (iter != regionSurfLayers[surfI].end())
116  {
117  nLayers[patchI] = iter();
118  }
119 
120  // Check
121  if (nLayers[patchI] < 0)
122  {
124  (
125  "layerParameters::readNumLayers(..)"
126  ) << "Illegal number of layers " << nLayers[patchI]
127  << " for surface "
128  << refineSurfaces.names()[surfI]
129  << " region " << regionName << endl
130  << exit(FatalError);
131  }
132  }
133  }
134  return nLayers;
135 }
136 
137 
138 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
139 
140 // Construct from dictionary
141 Foam::layerParameters::layerParameters
142 (
143  const PtrList<dictionary>& surfaceDicts,
144  const refinementSurfaces& refineSurfaces,
145  const labelList& globalToPatch,
146  const dictionary& dict,
147  const polyBoundaryMesh& boundaryMesh
148 )
149 :
150  numLayers_
151  (
152  readNumLayers
153  (
154  surfaceDicts,
155  refineSurfaces,
156  globalToPatch,
157  boundaryMesh
158  )
159  ),
160  expansionRatio_
161  (
162  numLayers_.size(),
163  readScalar(dict.lookup("expansionRatio"))
164  ),
165  relativeSizes_(false),
166  finalLayerThickness_
167  (
168  numLayers_.size(),
169  readScalar(dict.lookup("finalLayerRatio"))
170  ),
171  minThickness_
172  (
173  numLayers_.size(),
174  readScalar(dict.lookup("minThickness"))
175  ),
176  featureAngle_(readScalar(dict.lookup("featureAngle"))),
177  concaveAngle_
178  (
179  dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
180  ),
181  nGrow_(readLabel(dict.lookup("nGrow"))),
182  nSmoothSurfaceNormals_
183  (
184  readLabel(dict.lookup("nSmoothSurfaceNormals"))
185  ),
186  nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
187  nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
188  maxFaceThicknessRatio_
189  (
190  readScalar(dict.lookup("maxFaceThicknessRatio"))
191  ),
192  layerTerminationCos_
193  (
194  Foam::cos
195  (
196  0.5
197  * featureAngle_
199  )
200  ),
201  maxThicknessToMedialRatio_
202  (
203  readScalar(dict.lookup("maxThicknessToMedialRatio"))
204  ),
205  minMedianAxisAngleCos_
206  (
207  Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
209  ),
210  nBufferCellsNoExtrude_
211  (
212  readLabel(dict.lookup("nBufferCellsNoExtrude"))
213  ),
214  nSnap_(readLabel(dict.lookup("nSnap"))),
215  nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
216  nRelaxedIter_(labelMax)
217 {
218  if (dict.found("nRelaxedIter"))
219  {
220  dict.lookup("nRelaxedIter") >> nRelaxedIter_;
221  }
222 
223  if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
224  {
225  FatalErrorIn("layerParameters::layerParameters(..)")
226  << "Layer iterations should be >= 0." << endl
227  << "nLayerIter:" << nLayerIter_
228  << " nRelaxedIter:" << nRelaxedIter_
229  << exit(FatalError);
230  }
231 }
232 
233 
234 // Construct from dictionary
235 Foam::layerParameters::layerParameters
236 (
237  const dictionary& dict,
238  const polyBoundaryMesh& boundaryMesh
239 )
240 :
241  numLayers_(boundaryMesh.size(), 0),
242  expansionRatio_
243  (
244  boundaryMesh.size(),
245  readScalar(dict.lookup("expansionRatio"))
246  ),
247  relativeSizes_(dict.lookup("relativeSizes")),
248  finalLayerThickness_
249  (
250  boundaryMesh.size(),
251  readScalar(dict.lookup("finalLayerThickness"))
252  ),
253  minThickness_
254  (
255  boundaryMesh.size(),
256  readScalar(dict.lookup("minThickness"))
257  ),
258  featureAngle_(readScalar(dict.lookup("featureAngle"))),
259  concaveAngle_
260  (
261  dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
262  ),
263  nGrow_(readLabel(dict.lookup("nGrow"))),
264  nSmoothSurfaceNormals_
265  (
266  readLabel(dict.lookup("nSmoothSurfaceNormals"))
267  ),
268  nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
269  nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
270  maxFaceThicknessRatio_
271  (
272  readScalar(dict.lookup("maxFaceThicknessRatio"))
273  ),
274  layerTerminationCos_
275  (
276  Foam::cos
277  (
278  0.5
279  * featureAngle_
281  )
282  ),
283  maxThicknessToMedialRatio_
284  (
285  readScalar(dict.lookup("maxThicknessToMedialRatio"))
286  ),
287  minMedianAxisAngleCos_
288  (
289  Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
291  ),
292  nBufferCellsNoExtrude_
293  (
294  readLabel(dict.lookup("nBufferCellsNoExtrude"))
295  ),
296  nSnap_(readLabel(dict.lookup("nRelaxIter"))),
297  nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
298  nRelaxedIter_(labelMax)
299 {
300  if (dict.found("nRelaxedIter"))
301  {
302  dict.lookup("nRelaxedIter") >> nRelaxedIter_;
303  }
304  if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
305  {
306  FatalErrorIn("layerParameters::layerParameters(..)")
307  << "Layer iterations should be >= 0." << endl
308  << "nLayerIter:" << nLayerIter_
309  << " nRelaxedIter:" << nRelaxedIter_
310  << exit(FatalError);
311  }
312 
313 
314  const dictionary& layersDict = dict.subDict("layers");
315 
316  forAll(boundaryMesh, patchI)
317  {
318  const word& patchName = boundaryMesh[patchI].name();
319 
320  if (layersDict.found(patchName))
321  {
322  const dictionary& layerDict = layersDict.subDict(patchName);
323 
324  numLayers_[patchI] =
325  readLabel(layerDict.lookup("nSurfaceLayers"));
326 
327  layerDict.readIfPresent
328  (
329  "expansionRatio",
330  expansionRatio_[patchI]
331  );
332  layerDict.readIfPresent
333  (
334  "finalLayerThickness",
335  finalLayerThickness_[patchI]
336  );
337  layerDict.readIfPresent
338  (
339  "minThickness",
340  minThickness_[patchI]
341  );
342  }
343  }
344 
345 
346  // Check whether layer specification matches any patches
347  const List<keyType> wildCards = layersDict.keys(true);
348 
349  forAll(wildCards, i)
350  {
351  regExp re(wildCards[i]);
352 
353  bool hasMatch = false;
354  forAll(boundaryMesh, patchI)
355  {
356  if (re.match(boundaryMesh[patchI].name()))
357  {
358  hasMatch = true;
359  break;
360  }
361  }
362  if (!hasMatch)
363  {
364  IOWarningIn("layerParameters::layerParameters(..)", layersDict)
365  << "Wildcard layer specification for " << wildCards[i]
366  << " does not match any patch." << endl;
367  }
368  }
369 
370  const List<keyType> nonWildCards = layersDict.keys(false);
371 
372  forAll(nonWildCards, i)
373  {
374  if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
375  {
376  IOWarningIn("layerParameters::layerParameters(..)", layersDict)
377  << "Layer specification for " << nonWildCards[i]
378  << " does not match any patch." << endl;
379  }
380  }
381 }
382 
383 
384 // ************************ vim: set sw=4 sts=4 et: ************************ //