1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
162 // numLayers_.size(),
163 // readScalar(dict.lookup("expansionRatio"))
165 // relativeSizes_(false),
166 // finalLayerThickness_
168 // numLayers_.size(),
169 // readScalar(dict.lookup("finalLayerRatio"))
173 // numLayers_.size(),
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"))
192 // layerTerminationCos_
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_
229 // << exit(FatalError);
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),
293 additionalReporting_(dict.lookupOrDefault("additionalReporting", false))
297 WarningIn("layerParameters::layerParameters(..)")
298 << "The nGrow parameter effect has changed with respect to 1.6.x."
300 << "Please set nGrow=0 for 1.6.x behaviour."
304 dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
306 if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
308 FatalErrorIn("layerParameters::layerParameters(..)")
309 << "Layer iterations should be >= 0." << endl
310 << "nLayerIter:" << nLayerIter_
311 << " nRelaxedIter:" << nRelaxedIter_
316 const dictionary& layersDict = dict.subDict("layers");
318 forAll(boundaryMesh, patchI)
320 const word& patchName = boundaryMesh[patchI].name();
322 if (layersDict.found(patchName))
324 const dictionary& layerDict = layersDict.subDict(patchName);
327 readLabel(layerDict.lookup("nSurfaceLayers"));
329 layerDict.readIfPresent
332 expansionRatio_[patchI]
334 layerDict.readIfPresent
336 "finalLayerThickness",
337 finalLayerThickness_[patchI]
339 layerDict.readIfPresent
342 minThickness_[patchI]
348 // Check whether layer specification matches any patches
349 const List<keyType> wildCards = layersDict.keys(true);
353 regExp re(wildCards[i]);
355 bool hasMatch = false;
356 forAll(boundaryMesh, patchI)
358 if (re.match(boundaryMesh[patchI].name()))
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;
373 const List<keyType> nonWildCards = layersDict.keys(false);
375 forAll(nonWildCards, i)
377 if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
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;
388 // ************************************************************************* //