/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . Application snappyHexMesh Group grpMeshGenerationUtilities Description Automatic split hex mesher. Refines and snaps to surface. \*---------------------------------------------------------------------------*/ #include "argList.H" #include "Time.H" #include "fvMesh.H" #include "snappyRefineDriver.H" #include "snappySnapDriver.H" #include "snappyLayerDriver.H" #include "searchableSurfaces.H" #include "refinementSurfaces.H" #include "refinementFeatures.H" #include "shellSurfaces.H" #include "decompositionMethod.H" #include "noDecomp.H" #include "fvMeshDistribute.H" #include "wallPolyPatch.H" #include "refinementParameters.H" #include "snapParameters.H" #include "layerParameters.H" #include "vtkSetWriter.H" #include "faceSet.H" #include "motionSmoother.H" #include "polyTopoChange.H" #include "cellModeller.H" #include "uindirectPrimitivePatch.H" #include "surfZoneIdentifierList.H" #include "UnsortedMeshedSurface.H" #include "MeshedSurface.H" #include "globalIndex.H" #include "IOmanip.H" #include "decompositionModel.H" #include "fvMeshTools.H" #include "profiling.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Convert size (as fraction of defaultCellSize) to refinement level label sizeCoeffToRefinement ( const scalar level0Coeff, // ratio of hex cell size v.s. defaultCellSize const scalar sizeCoeff ) { return round(::log(level0Coeff/sizeCoeff)/::log(2)); } autoPtr createRefinementSurfaces ( const searchableSurfaces& allGeometry, const dictionary& surfacesDict, const dictionary& shapeControlDict, const label gapLevelIncrement, const scalar level0Coeff ) { autoPtr surfacePtr; // Count number of surfaces. label surfi = 0; forAll(allGeometry.names(), geomi) { const word& geomName = allGeometry.names()[geomi]; if (surfacesDict.found(geomName)) { surfi++; } } labelList surfaces(surfi); wordList names(surfi); PtrList surfZones(surfi); labelList regionOffset(surfi); labelList globalMinLevel(surfi, 0); labelList globalMaxLevel(surfi, 0); labelList globalLevelIncr(surfi, 0); PtrList globalPatchInfo(surfi); List> regionMinLevel(surfi); List> regionMaxLevel(surfi); List> regionLevelIncr(surfi); List> regionAngle(surfi); List>> regionPatchInfo(surfi); HashSet unmatchedKeys(surfacesDict.toc()); surfi = 0; forAll(allGeometry.names(), geomi) { const word& geomName = allGeometry.names()[geomi]; const entry* ePtr = surfacesDict.lookupEntryPtr(geomName, false, true); if (ePtr) { const dictionary& shapeDict = ePtr->dict(); unmatchedKeys.erase(ePtr->keyword()); names[surfi] = geomName; surfaces[surfi] = geomi; const searchableSurface& surface = allGeometry[geomi]; // Find the index in shapeControlDict // Invert surfaceCellSize to get the refinementLevel const word scsFuncName = shapeDict.lookup("surfaceCellSizeFunction"); const dictionary& scsDict = shapeDict.subDict(scsFuncName + "Coeffs"); const scalar surfaceCellSize = readScalar(scsDict.lookup("surfaceCellSizeCoeff")); const label refLevel = sizeCoeffToRefinement ( level0Coeff, surfaceCellSize ); globalMinLevel[surfi] = refLevel; globalMaxLevel[surfi] = refLevel; globalLevelIncr[surfi] = gapLevelIncrement; // Surface zones surfZones.set(surfi, new surfaceZonesInfo(surface, shapeDict)); // Global perpendicular angle if (shapeDict.found("patchInfo")) { globalPatchInfo.set ( surfi, shapeDict.subDict("patchInfo").clone() ); } // Per region override of patchInfo if (shapeDict.found("regions")) { const dictionary& regionsDict = shapeDict.subDict("regions"); const wordList& regionNames = allGeometry[surfaces[surfi]].regions(); forAll(regionNames, regioni) { if (regionsDict.found(regionNames[regioni])) { // Get the dictionary for region const dictionary& regionDict = regionsDict.subDict ( regionNames[regioni] ); if (regionDict.found("patchInfo")) { regionPatchInfo[surfi].insert ( regioni, regionDict.subDict("patchInfo").clone() ); } } } } // Per region override of cellSize if (shapeDict.found("regions")) { const dictionary& shapeControlRegionsDict = shapeDict.subDict("regions"); const wordList& regionNames = allGeometry[surfaces[surfi]].regions(); forAll(regionNames, regioni) { if (shapeControlRegionsDict.found(regionNames[regioni])) { const dictionary& shapeControlRegionDict = shapeControlRegionsDict.subDict ( regionNames[regioni] ); const word scsFuncName = shapeControlRegionDict.lookup ( "surfaceCellSizeFunction" ); const dictionary& scsDict = shapeControlRegionDict.subDict ( scsFuncName + "Coeffs" ); const scalar surfaceCellSize = readScalar ( scsDict.lookup("surfaceCellSizeCoeff") ); const label refLevel = sizeCoeffToRefinement ( level0Coeff, surfaceCellSize ); regionMinLevel[surfi].insert(regioni, refLevel); regionMaxLevel[surfi].insert(regioni, refLevel); regionLevelIncr[surfi].insert(regioni, 0); } } } surfi++; } } // Calculate local to global region offset label nRegions = 0; forAll(surfaces, surfi) { regionOffset[surfi] = nRegions; nRegions += allGeometry[surfaces[surfi]].regions().size(); } // Rework surface specific information into information per global region labelList minLevel(nRegions, 0); labelList maxLevel(nRegions, 0); labelList gapLevel(nRegions, -1); PtrList patchInfo(nRegions); forAll(globalMinLevel, surfi) { label nRegions = allGeometry[surfaces[surfi]].regions().size(); // Initialise to global (i.e. per surface) for (label i = 0; i < nRegions; i++) { label globalRegioni = regionOffset[surfi] + i; minLevel[globalRegioni] = globalMinLevel[surfi]; maxLevel[globalRegioni] = globalMaxLevel[surfi]; gapLevel[globalRegioni] = maxLevel[globalRegioni] + globalLevelIncr[surfi]; if (globalPatchInfo.set(surfi)) { patchInfo.set ( globalRegioni, globalPatchInfo[surfi].clone() ); } } // Overwrite with region specific information forAllConstIter(Map