ENH: snappyHexMesh: optional parameter for additional printing in layering
[OpenFOAM-2.0.x.git] / src / mesh / autoMesh / autoHexMesh / autoHexMeshDriver / layerParameters / layerParameters.C
blobd1f66fb6e93d15974f6ec47bd7ff2f07eccb0f68
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
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),
293     additionalReporting_(dict.lookupOrDefault("additionalReporting", false))
295     if (nGrow_ > 0)
296     {
297         WarningIn("layerParameters::layerParameters(..)")
298             << "The nGrow parameter effect has changed with respect to 1.6.x."
299             << endl
300             << "Please set nGrow=0 for 1.6.x behaviour."
301             << endl;
302     }
304     dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
306     if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
307     {
308         FatalErrorIn("layerParameters::layerParameters(..)")
309             << "Layer iterations should be >= 0." << endl
310             << "nLayerIter:" << nLayerIter_
311             << " nRelaxedIter:" << nRelaxedIter_
312             << exit(FatalError);
313     }
316     const dictionary& layersDict = dict.subDict("layers");
318     forAll(boundaryMesh, patchI)
319     {
320         const word& patchName = boundaryMesh[patchI].name();
322         if (layersDict.found(patchName))
323         {
324             const dictionary& layerDict = layersDict.subDict(patchName);
326             numLayers_[patchI] =
327                 readLabel(layerDict.lookup("nSurfaceLayers"));
329             layerDict.readIfPresent
330             (
331                 "expansionRatio",
332                 expansionRatio_[patchI]
333             );
334             layerDict.readIfPresent
335             (
336                 "finalLayerThickness",
337                 finalLayerThickness_[patchI]
338             );
339             layerDict.readIfPresent
340             (
341                 "minThickness",
342                 minThickness_[patchI]
343             );
344         }
345     }
348     // Check whether layer specification matches any patches
349     const List<keyType> wildCards = layersDict.keys(true);
351     forAll(wildCards, i)
352     {
353         regExp re(wildCards[i]);
355         bool hasMatch = false;
356         forAll(boundaryMesh, patchI)
357         {
358             if (re.match(boundaryMesh[patchI].name()))
359             {
360                 hasMatch = true;
361                 break;
362             }
363         }
364         if (!hasMatch)
365         {
366             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
367                 << "Wildcard layer specification for " << wildCards[i]
368                 << " does not match any patch." << endl
369                 << "Valid patches are " << boundaryMesh.names() << endl;
370         }
371     }
373     const List<keyType> nonWildCards = layersDict.keys(false);
375     forAll(nonWildCards, i)
376     {
377         if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
378         {
379             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
380                 << "Layer specification for " << nonWildCards[i]
381                 << " does not match any patch." << endl
382                 << "Valid patches are " << boundaryMesh.names() << endl;
383         }
384     }
388 // ************************************************************************* //