FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

layerParameters.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "layerParameters.H"
00027 #include <OpenFOAM/polyBoundaryMesh.H>
00028 #include <OpenFOAM/mathematicalConstants.H>
00029 #include <autoMesh/refinementSurfaces.H>
00030 #include <meshTools/searchableSurfaces.H>
00031 #include <OSspecific/regExp.H>
00032 
00033 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00034 
00035 const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
00036 
00037 
00038 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00039 
00040 // Read the number of layers from dictionary. Per patch 0 or the number
00041 // of layers.
00042 Foam::labelList Foam::layerParameters::readNumLayers
00043 (
00044     const PtrList<dictionary>& surfaceDicts,
00045     const refinementSurfaces& refineSurfaces,
00046     const labelList& globalToPatch,
00047     const polyBoundaryMesh& boundaryMesh
00048 )
00049 {
00050     // Per surface the number of layers
00051     labelList globalSurfLayers(surfaceDicts.size());
00052     // Per surface, per region the number of layers
00053     List<Map<label> > regionSurfLayers(surfaceDicts.size());
00054 
00055     const labelList& surfaceIndices = refineSurfaces.surfaces();
00056 
00057     forAll(surfaceDicts, surfI)
00058     {
00059         const dictionary& dict = surfaceDicts[surfI];
00060 
00061         globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
00062 
00063         if (dict.found("regions"))
00064         {
00065             // Per-region layer information
00066 
00067             PtrList<dictionary> regionDicts(dict.lookup("regions"));
00068 
00069             const wordList& regionNames =
00070                 refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
00071 
00072             forAll(regionDicts, dictI)
00073             {
00074                 const dictionary& regionDict = regionDicts[dictI];
00075 
00076                 const word regionName(regionDict.lookup("name"));
00077 
00078                 label regionI = findIndex(regionNames, regionName);
00079 
00080                 label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
00081 
00082                 Info<< "    region " << regionName << ':'<< nl
00083                     << "        surface layers:" << nLayers << nl;
00084 
00085                 regionSurfLayers[surfI].insert(regionI, nLayers);
00086             }
00087         }
00088     }
00089 
00090 
00091     // Transfer per surface/region information into patchwise region info
00092 
00093     labelList nLayers(boundaryMesh.size(), 0);
00094 
00095     forAll(surfaceIndices, surfI)
00096     {
00097         const wordList& regionNames =
00098             refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
00099 
00100         forAll(regionNames, regionI)
00101         {
00102             const word& regionName = regionNames[regionI];
00103 
00104             label global = refineSurfaces.globalRegion(surfI, regionI);
00105 
00106             label patchI = globalToPatch[global];
00107 
00108             // Initialise to surface-wise layers
00109             nLayers[patchI] = globalSurfLayers[surfI];
00110 
00111             // Override with region specific data if available
00112             Map<label>::const_iterator iter =
00113                 regionSurfLayers[surfI].find(regionI);
00114 
00115             if (iter != regionSurfLayers[surfI].end())
00116             {
00117                 nLayers[patchI] = iter();
00118             }
00119 
00120             // Check
00121             if (nLayers[patchI] < 0)
00122             {
00123                 FatalErrorIn
00124                 (
00125                     "layerParameters::readNumLayers(..)"
00126                 )   << "Illegal number of layers " << nLayers[patchI]
00127                     << " for surface "
00128                     << refineSurfaces.names()[surfI]
00129                     << " region " << regionName << endl
00130                     << exit(FatalError);
00131             }
00132         }
00133     }
00134     return nLayers;
00135 }
00136 
00137 
00138 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00139 
00140 // Construct from dictionary
00141 Foam::layerParameters::layerParameters
00142 (
00143     const PtrList<dictionary>& surfaceDicts,
00144     const refinementSurfaces& refineSurfaces,
00145     const labelList& globalToPatch,
00146     const dictionary& dict,
00147     const polyBoundaryMesh& boundaryMesh
00148 )
00149 :
00150     numLayers_
00151     (
00152         readNumLayers
00153         (
00154             surfaceDicts,
00155             refineSurfaces,
00156             globalToPatch,
00157             boundaryMesh
00158         )
00159     ),
00160     expansionRatio_
00161     (
00162         numLayers_.size(),
00163         readScalar(dict.lookup("expansionRatio"))
00164     ),
00165     relativeSizes_(false),
00166     finalLayerThickness_
00167     (
00168         numLayers_.size(),
00169         readScalar(dict.lookup("finalLayerRatio"))
00170     ),
00171     minThickness_
00172     (
00173         numLayers_.size(),
00174         readScalar(dict.lookup("minThickness"))
00175     ),
00176     featureAngle_(readScalar(dict.lookup("featureAngle"))),
00177     concaveAngle_
00178     (
00179         dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
00180     ),
00181     nGrow_(readLabel(dict.lookup("nGrow"))),
00182     nSmoothSurfaceNormals_
00183     (
00184         readLabel(dict.lookup("nSmoothSurfaceNormals"))
00185     ),
00186     nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
00187     nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
00188     maxFaceThicknessRatio_
00189     (
00190         readScalar(dict.lookup("maxFaceThicknessRatio"))
00191     ),
00192     layerTerminationCos_
00193     (
00194         Foam::cos
00195         (
00196             0.5
00197           * featureAngle_
00198           * mathematicalConstant::pi/180.
00199         )
00200     ),
00201     maxThicknessToMedialRatio_
00202     (
00203         readScalar(dict.lookup("maxThicknessToMedialRatio"))
00204     ),
00205     minMedianAxisAngleCos_
00206     (
00207         Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
00208       * mathematicalConstant::pi/180.
00209     ),
00210     nBufferCellsNoExtrude_
00211     (
00212         readLabel(dict.lookup("nBufferCellsNoExtrude"))
00213     ),
00214     nSnap_(readLabel(dict.lookup("nSnap"))),
00215     nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
00216     nRelaxedIter_(labelMax)
00217 {
00218     if (dict.found("nRelaxedIter"))
00219     {
00220         dict.lookup("nRelaxedIter") >> nRelaxedIter_;
00221     }
00222 
00223     if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
00224     {
00225         FatalErrorIn("layerParameters::layerParameters(..)")
00226             << "Layer iterations should be >= 0." << endl
00227             << "nLayerIter:" << nLayerIter_
00228             << " nRelaxedIter:" << nRelaxedIter_
00229             << exit(FatalError);
00230     }
00231 }
00232 
00233 
00234 // Construct from dictionary
00235 Foam::layerParameters::layerParameters
00236 (
00237     const dictionary& dict,
00238     const polyBoundaryMesh& boundaryMesh
00239 )
00240 :
00241     numLayers_(boundaryMesh.size(), 0),
00242     expansionRatio_
00243     (
00244         boundaryMesh.size(),
00245         readScalar(dict.lookup("expansionRatio"))
00246     ),
00247     relativeSizes_(dict.lookup("relativeSizes")),
00248     finalLayerThickness_
00249     (
00250         boundaryMesh.size(),
00251         readScalar(dict.lookup("finalLayerThickness"))
00252     ),
00253     minThickness_
00254     (
00255         boundaryMesh.size(),
00256         readScalar(dict.lookup("minThickness"))
00257     ),
00258     featureAngle_(readScalar(dict.lookup("featureAngle"))),
00259     concaveAngle_
00260     (
00261         dict.lookupOrDefault("concaveAngle", defaultConcaveAngle)
00262     ),
00263     nGrow_(readLabel(dict.lookup("nGrow"))),
00264     nSmoothSurfaceNormals_
00265     (
00266         readLabel(dict.lookup("nSmoothSurfaceNormals"))
00267     ),
00268     nSmoothNormals_(readLabel(dict.lookup("nSmoothNormals"))),
00269     nSmoothThickness_(readLabel(dict.lookup("nSmoothThickness"))),
00270     maxFaceThicknessRatio_
00271     (
00272         readScalar(dict.lookup("maxFaceThicknessRatio"))
00273     ),
00274     layerTerminationCos_
00275     (
00276         Foam::cos
00277         (
00278             0.5
00279           * featureAngle_
00280           * mathematicalConstant::pi/180.
00281         )
00282     ),
00283     maxThicknessToMedialRatio_
00284     (
00285         readScalar(dict.lookup("maxThicknessToMedialRatio"))
00286     ),
00287     minMedianAxisAngleCos_
00288     (
00289         Foam::cos(readScalar(dict.lookup("minMedianAxisAngle")))
00290       * mathematicalConstant::pi/180.
00291     ),
00292     nBufferCellsNoExtrude_
00293     (
00294         readLabel(dict.lookup("nBufferCellsNoExtrude"))
00295     ),
00296     nSnap_(readLabel(dict.lookup("nRelaxIter"))),
00297     nLayerIter_(readLabel(dict.lookup("nLayerIter"))),
00298     nRelaxedIter_(labelMax)
00299 {
00300     if (dict.found("nRelaxedIter"))
00301     {
00302         dict.lookup("nRelaxedIter") >> nRelaxedIter_;
00303     }
00304     if (nLayerIter_ < 0 || nRelaxedIter_ < 0)
00305     {
00306         FatalErrorIn("layerParameters::layerParameters(..)")
00307             << "Layer iterations should be >= 0." << endl
00308             << "nLayerIter:" << nLayerIter_
00309             << " nRelaxedIter:" << nRelaxedIter_
00310             << exit(FatalError);
00311     }
00312 
00313 
00314     const dictionary& layersDict = dict.subDict("layers");
00315 
00316     forAll(boundaryMesh, patchI)
00317     {
00318         const word& patchName = boundaryMesh[patchI].name();
00319 
00320         if (layersDict.found(patchName))
00321         {
00322             const dictionary& layerDict = layersDict.subDict(patchName);
00323 
00324             numLayers_[patchI] =
00325                 readLabel(layerDict.lookup("nSurfaceLayers"));
00326 
00327             layerDict.readIfPresent
00328             (
00329                 "expansionRatio",
00330                 expansionRatio_[patchI]
00331             );
00332             layerDict.readIfPresent
00333             (
00334                 "finalLayerThickness",
00335                 finalLayerThickness_[patchI]
00336             );
00337             layerDict.readIfPresent
00338             (
00339                 "minThickness",
00340                 minThickness_[patchI]
00341             );
00342         }
00343     }
00344 
00345 
00346     // Check whether layer specification matches any patches
00347     const List<keyType> wildCards = layersDict.keys(true);
00348 
00349     forAll(wildCards, i)
00350     {
00351         regExp re(wildCards[i]);
00352 
00353         bool hasMatch = false;
00354         forAll(boundaryMesh, patchI)
00355         {
00356             if (re.match(boundaryMesh[patchI].name()))
00357             {
00358                 hasMatch = true;
00359                 break;
00360             }
00361         }
00362         if (!hasMatch)
00363         {
00364             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
00365                 << "Wildcard layer specification for " << wildCards[i]
00366                 << " does not match any patch." << endl;
00367         }
00368     }
00369 
00370     const List<keyType> nonWildCards = layersDict.keys(false);
00371 
00372     forAll(nonWildCards, i)
00373     {
00374         if (boundaryMesh.findPatchID(nonWildCards[i]) == -1)
00375         {
00376             IOWarningIn("layerParameters::layerParameters(..)", layersDict)
00377                 << "Layer specification for " << nonWildCards[i]
00378                 << " does not match any patch." << endl;
00379         }
00380     }
00381 }
00382 
00383 
00384 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines