Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / mesh / autoMesh / autoHexMesh / autoHexMeshDriver / layerParameters / layerParameters.C
blob87cab4ac410ace7df993863af12209e772d188ed
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "layerParameters.H"
27 #include "polyBoundaryMesh.H"
28 #include "unitConversion.H"
29 #include "refinementSurfaces.H"
30 #include "searchableSurfaces.H"
31 #include "regExp.H"
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
38 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
40 // Read the number of layers from dictionary. Per patch 0 or the number
41 // of layers.
42 Foam::labelList Foam::layerParameters::readNumLayers
44     const PtrList<dictionary>& surfaceDicts,
45     const refinementSurfaces& refineSurfaces,
46     const labelList& globalToPatch,
47     const polyBoundaryMesh& boundaryMesh
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());
55     const labelList& surfaceIndices = refineSurfaces.surfaces();
57     forAll(surfaceDicts, surfI)
58     {
59         const dictionary& dict = surfaceDicts[surfI];
61         globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
63         if (dict.found("regions"))
64         {
65             // Per-region layer information
67             PtrList<dictionary> regionDicts(dict.lookup("regions"));
69             const wordList& regionNames =
70                 refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
72             forAll(regionDicts, dictI)
73             {
74                 const dictionary& regionDict = regionDicts[dictI];
76                 const word regionName(regionDict.lookup("name"));
78                 label regionI = findIndex(regionNames, regionName);
80                 label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
82                 Info<< "    region " << regionName << ':'<< nl
83                     << "        surface layers:" << nLayers << nl;
85                 regionSurfLayers[surfI].insert(regionI, nLayers);
86             }
87         }
88     }
91     // Transfer per surface/region information into patchwise region info
93     labelList nLayers(boundaryMesh.size(), 0);
95     forAll(surfaceIndices, surfI)
96     {
97         const wordList& regionNames =
98             refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
100         forAll(regionNames, regionI)
101         {
102             const word& regionName = regionNames[regionI];
104             label global = refineSurfaces.globalRegion(surfI, regionI);
106             label patchI = globalToPatch[global];
108             // Initialise to surface-wise layers
109             nLayers[patchI] = globalSurfLayers[surfI];
111             // Override with region specific data if available
112             Map<label>::const_iterator iter =
113                 regionSurfLayers[surfI].find(regionI);
115             if (iter != regionSurfLayers[surfI].end())
116             {
117                 nLayers[patchI] = iter();
118             }
120             // Check
121             if (nLayers[patchI] < 0)
122             {
123                 FatalErrorIn
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;
138 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
140 // Construct from dictionary
141 Foam::layerParameters::layerParameters
143     const PtrList<dictionary>& surfaceDicts,
144     const refinementSurfaces& refineSurfaces,
145     const labelList& globalToPatch,
146     const dictionary& dict,
147     const polyBoundaryMesh& boundaryMesh
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(degToRad(0.5*featureAngle_))
195     ),
196     maxThicknessToMedialRatio_
197     (
198         readScalar(dict.lookup("maxThicknessToMedialRatio"))
199     ),
200     minMedianAxisAngleCos_
201     (
202         Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
203     ),
204     nBufferCellsNoExtrude_
205     (
206         readLabel(dict.lookup("nBufferCellsNoExtrude"))
207     ),
208     nSnap_(readLabel(dict.lookup("nSnap"))),
209     nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
210     nRelaxedIter_(labelMax)
212     if (nGrow_ > 0)
213     {
214         WarningIn("layerParameters::layerParameters(..)")
215             << "The nGrow parameter effect has changed with respect to 1.6.x."
216             << endl
217             << "Please set nGrow=0 for 1.6.x behaviour."
218             << endl;
219     }
221     dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
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     }
234 // Construct from dictionary
235 Foam::layerParameters::layerParameters
237     const dictionary& dict,
238     const polyBoundaryMesh& boundaryMesh
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(degToRad(0.5*featureAngle_))
277     ),
278     maxThicknessToMedialRatio_
279     (
280         readScalar(dict.lookup("maxThicknessToMedialRatio"))
281     ),
282     minMedianAxisAngleCos_
283     (
284         Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
285     ),
286     nBufferCellsNoExtrude_
287     (
288         readLabel(dict.lookup("nBufferCellsNoExtrude"))
289     ),
290     nSnap_(readLabel(dict.lookup("nRelaxIter"))),
291     nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
292     nRelaxedIter_(labelMax)
294     if (nGrow_ > 0)
295     {
296         WarningIn("layerParameters::layerParameters(..)")
297             << "The nGrow parameter effect has changed with respect to 1.6.x."
298             << endl
299             << "Please set nGrow=0 for 1.6.x behaviour."
300             << endl;
301     }
303     dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
305     if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
306     {
307         FatalErrorIn("layerParameters::layerParameters(..)")
308             << "Layer iterations should be >= 0." << endl
309             << "nLayerIter:" << nLayerIter_
310             << " nRelaxedIter:" << nRelaxedIter_
311             << exit(FatalError);
312     }
315     const dictionary& layersDict = dict.subDict("layers");
317     forAll(boundaryMesh, patchI)
318     {
319         const word& patchName = boundaryMesh[patchI].name();
321         if (layersDict.found(patchName))
322         {
323             const dictionary& layerDict = layersDict.subDict(patchName);
325             numLayers_[patchI] =
326                 readLabel(layerDict.lookup("nSurfaceLayers"));
328             layerDict.readIfPresent
329             (
330                 "expansionRatio",
331                 expansionRatio_[patchI]
332             );
333             layerDict.readIfPresent
334             (
335                 "finalLayerThickness",
336                 finalLayerThickness_[patchI]
337             );
338             layerDict.readIfPresent
339             (
340                 "minThickness",
341                 minThickness_[patchI]
342             );
343         }
344     }
347     // Check whether layer specification matches any patches
348     const List<keyType> wildCards = layersDict.keys(true);
350     forAll(wildCards, i)
351     {
352         regExp re(wildCards[i]);
354         bool hasMatch = false;
355         forAll(boundaryMesh, patchI)
356         {
357             if (re.match(boundaryMesh[patchI].name()))
358             {
359                 hasMatch = true;
360                 break;
361             }
362         }
363         if (!hasMatch)
364         {
365             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
366                 << "Wildcard layer specification for " << wildCards[i]
367                 << " does not match any patch." << endl
368                 << "Valid patches are " << boundaryMesh.names() << endl;
369         }
370     }
372     const List<keyType> nonWildCards = layersDict.keys(false);
374     forAll(nonWildCards, i)
375     {
376         if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
377         {
378             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
379                 << "Layer specification for " << nonWildCards[i]
380                 << " does not match any patch." << endl
381                 << "Valid patches are " << boundaryMesh.names() << endl;
382         }
383     }
387 // ************************************************************************* //