1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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"
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
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)
59 const dictionary& dict = surfaceDicts[surfI];
61 globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
63 if (dict.found("regions"))
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)
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);
91 // Transfer per surface/region information into patchwise region info
93 labelList nLayers(boundaryMesh.size(), 0);
95 forAll(surfaceIndices, surfI)
97 const wordList& regionNames =
98 refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
100 forAll(regionNames, regionI)
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())
117 nLayers[patchI] = iter();
121 if (nLayers[patchI] < 0)
125 "layerParameters::readNumLayers(..)"
126 ) << "Illegal number of layers " << nLayers[patchI]
128 << refineSurfaces.names()[surfI]
129 << " region " << regionName << endl
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
163 readScalar(dict.lookup("expansionRatio"))
165 relativeSizes_(false),
169 readScalar(dict.lookup("finalLayerRatio"))
174 readScalar(dict.lookup("minThickness"))
176 featureAngle_(readScalar(dict.lookup("featureAngle"))),
179 dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
181 nGrow_(readLabel(dict.lookup("nGrow"))),
182 nSmoothSurfaceNormals_
184 readLabel(dict.lookup("nSmoothSurfaceNormals"))
186 nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
187 nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
188 maxFaceThicknessRatio_
190 readScalar(dict.lookup("maxFaceThicknessRatio"))
194 Foam::cos(degToRad(0.5*featureAngle_))
196 maxThicknessToMedialRatio_
198 readScalar(dict.lookup("maxThicknessToMedialRatio"))
200 minMedianAxisAngleCos_
202 Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
204 nBufferCellsNoExtrude_
206 readLabel(dict.lookup("nBufferCellsNoExtrude"))
208 nSnap_(readLabel(dict.lookup("nSnap"))),
209 nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
210 nRelaxedIter_(labelMax)
214 WarningIn("layerParameters::layerParameters(..)")
215 << "The nGrow parameter effect has changed with respect to 1.6.x."
217 << "Please set nGrow=0 for 1.6.x behaviour."
221 dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
223 if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
225 FatalErrorIn("layerParameters::layerParameters(..)")
226 << "Layer iterations should be >= 0." << endl
227 << "nLayerIter:" << nLayerIter_
228 << " nRelaxedIter:" << nRelaxedIter_
234 // Construct from dictionary
235 Foam::layerParameters::layerParameters
237 const dictionary& dict,
238 const polyBoundaryMesh& boundaryMesh
241 numLayers_(boundaryMesh.size(), 0),
245 readScalar(dict.lookup("expansionRatio"))
247 relativeSizes_(dict.lookup("relativeSizes")),
251 readScalar(dict.lookup("finalLayerThickness"))
256 readScalar(dict.lookup("minThickness"))
258 featureAngle_(readScalar(dict.lookup("featureAngle"))),
261 dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
263 nGrow_(readLabel(dict.lookup("nGrow"))),
264 nSmoothSurfaceNormals_
266 readLabel(dict.lookup("nSmoothSurfaceNormals"))
268 nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
269 nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
270 maxFaceThicknessRatio_
272 readScalar(dict.lookup("maxFaceThicknessRatio"))
276 Foam::cos(degToRad(0.5*featureAngle_))
278 maxThicknessToMedialRatio_
280 readScalar(dict.lookup("maxThicknessToMedialRatio"))
282 minMedianAxisAngleCos_
284 Foam::cos(degToRad(readScalar(dict.lookup("minMedianAxisAngle"))))
286 nBufferCellsNoExtrude_
288 readLabel(dict.lookup("nBufferCellsNoExtrude"))
290 nSnap_(readLabel(dict.lookup("nRelaxIter"))),
291 nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
292 nRelaxedIter_(labelMax)
296 WarningIn("layerParameters::layerParameters(..)")
297 << "The nGrow parameter effect has changed with respect to 1.6.x."
299 << "Please set nGrow=0 for 1.6.x behaviour."
303 dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
305 if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
307 FatalErrorIn("layerParameters::layerParameters(..)")
308 << "Layer iterations should be >= 0." << endl
309 << "nLayerIter:" << nLayerIter_
310 << " nRelaxedIter:" << nRelaxedIter_
315 const dictionary& layersDict = dict.subDict("layers");
317 forAll(boundaryMesh, patchI)
319 const word& patchName = boundaryMesh[patchI].name();
321 if (layersDict.found(patchName))
323 const dictionary& layerDict = layersDict.subDict(patchName);
326 readLabel(layerDict.lookup("nSurfaceLayers"));
328 layerDict.readIfPresent
331 expansionRatio_[patchI]
333 layerDict.readIfPresent
335 "finalLayerThickness",
336 finalLayerThickness_[patchI]
338 layerDict.readIfPresent
341 minThickness_[patchI]
347 // Check whether layer specification matches any patches
348 const List<keyType> wildCards = layersDict.keys(true);
352 regExp re(wildCards[i]);
354 bool hasMatch = false;
355 forAll(boundaryMesh, patchI)
357 if (re.match(boundaryMesh[patchI].name()))
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;
372 const List<keyType> nonWildCards = layersDict.keys(false);
374 forAll(nonWildCards, i)
376 if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
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;
387 // ************************************************************************* //