/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- 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 . \*----------------------------------------------------------------------------*/ #include "refinementSurfaces.H" #include "Time.H" #include "searchableSurfaces.H" #include "shellSurfaces.H" #include "triSurfaceMesh.H" #include "labelPair.H" #include "searchableSurfacesQueries.H" #include "UPtrList.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam { template<> const char* Foam::NamedEnum::names[] = { "inside", "outside", "insidePoint", "none" }; } const Foam::NamedEnum Foam::refinementSurfaces::areaSelectionAlgoNames; // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::refinementSurfaces::refinementSurfaces ( const searchableSurfaces& allGeometry, const dictionary& surfacesDict ) : allGeometry_(allGeometry), surfaces_(surfacesDict.size()), names_(surfacesDict.size()), faceZoneNames_(surfacesDict.size()), cellZoneNames_(surfacesDict.size()), zoneInside_(surfacesDict.size(), NONE), zoneInsidePoints_(surfacesDict.size()), regionOffset_(surfacesDict.size()) { // Wilcard specification : loop over all surface, all regions // and try to find a match. // Count number of surfaces. label surfI = 0; forAll(allGeometry.names(), geomI) { const word& geomName = allGeometry_.names()[geomI]; if (surfacesDict.found(geomName)) { surfI++; } } // Size lists surfaces_.setSize(surfI); names_.setSize(surfI); faceZoneNames_.setSize(surfI); cellZoneNames_.setSize(surfI); zoneInside_.setSize(surfI, NONE); regionOffset_.setSize(surfI); labelList globalMinLevel(surfI, 0); labelList globalMaxLevel(surfI, 0); scalarField globalAngle(surfI, -GREAT); PtrList globalPatchInfo(surfI); List > regionMinLevel(surfI); List > regionMaxLevel(surfI); List > regionAngle(surfI); List > > regionPatchInfo(surfI); surfI = 0; forAll(allGeometry.names(), geomI) { const word& geomName = allGeometry_.names()[geomI]; if (surfacesDict.found(geomName)) { const dictionary& dict = surfacesDict.subDict(geomName); names_[surfI] = geomName; surfaces_[surfI] = geomI; const labelPair refLevel(dict.lookup("level")); globalMinLevel[surfI] = refLevel[0]; globalMaxLevel[surfI] = refLevel[1]; // Global zone names per surface if (dict.readIfPresent("faceZone", faceZoneNames_[surfI])) { // Read optional entry to determine inside of faceZone word method; bool hasSide = dict.readIfPresent("cellZoneInside", method); if (hasSide) { zoneInside_[surfI] = areaSelectionAlgoNames[method]; if (zoneInside_[surfI] == INSIDEPOINT) { dict.lookup("insidePoint") >> zoneInsidePoints_[surfI]; } } else { // Check old syntax bool inside; if (dict.readIfPresent("zoneInside", inside)) { hasSide = true; zoneInside_[surfI] = (inside ? INSIDE : OUTSIDE); } } // Read optional cellZone name if (dict.readIfPresent("cellZone", cellZoneNames_[surfI])) { if ( ( zoneInside_[surfI] == INSIDE || zoneInside_[surfI] == OUTSIDE ) && !allGeometry_[surfaces_[surfI]].hasVolumeType() ) { IOWarningIn ( "refinementSurfaces::refinementSurfaces(..)", dict ) << "Illegal entry zoneInside " << areaSelectionAlgoNames[zoneInside_[surfI]] << " for faceZone " << faceZoneNames_[surfI] << " since surface " << names_[surfI] << " is not closed." << endl; } } else if (hasSide) { IOWarningIn ( "refinementSurfaces::refinementSurfaces(..)", dict ) << "Unused entry zoneInside for faceZone " << faceZoneNames_[surfI] << " since no cellZone specified." << endl; } } // Global perpendicular angle if (dict.found("patchInfo")) { globalPatchInfo.set ( surfI, dict.subDict("patchInfo").clone() ); } dict.readIfPresent("perpendicularAngle", globalAngle[surfI]); if (dict.found("regions")) { const dictionary& regionsDict = dict.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] ); const labelPair refLevel(regionDict.lookup("level")); regionMinLevel[surfI].insert(regionI, refLevel[0]); regionMaxLevel[surfI].insert(regionI, refLevel[1]); if (regionDict.found("perpendicularAngle")) { regionAngle[surfI].insert ( regionI, readScalar ( regionDict.lookup("perpendicularAngle") ) ); } if (regionDict.found("patchInfo")) { regionPatchInfo[surfI].insert ( regionI, regionDict.subDict("patchInfo").clone() ); } } } } 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 minLevel_.setSize(nRegions); minLevel_ = 0; maxLevel_.setSize(nRegions); maxLevel_ = 0; perpendicularAngle_.setSize(nRegions); perpendicularAngle_ = -GREAT; patchInfo_.setSize(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]; perpendicularAngle_[globalRegionI] = globalAngle[surfI]; if (globalPatchInfo.set(surfI)) { patchInfo_.set ( globalRegionI, globalPatchInfo[surfI].clone() ); } } // Overwrite with region specific information forAllConstIter(Map