From 4c08b463fd629c4df2b65b79289f5e0af22b0db0 Mon Sep 17 00:00:00 2001 From: Henry Weller Date: Wed, 18 Mar 2020 18:06:55 +0000 Subject: [PATCH] snappyHexMesh::shellSurfaces: Added support for span refinement based on internal or external "closeness" The closeness option in surfaceFeatures set in surfaceFeaturesDict, e.g. closeness { // Output the closeness of surface points to other surface elements. pointCloseness yes; } calculates and writes both the internal and external surface "closeness" measures either of which could be used to set the span refinement in snappyHexMesh depending on which side of the surface is being meshed which is specified with either refinement mode "insideSpan" or "externalSpan", e.g. in the tutorials/mesh/snappyHexMesh/pipe case the inside of the pipe is meshed and refined based on the internal span using the following specification: refinementRegions { pipeWall { mode insideSpan; levels ((1000 2)); cellsAcrossSpan 40; } } --- .../shellSurfaces/shellSurfaces.C | 172 ++++++++++-------- .../shellSurfaces/shellSurfaces.H | 20 +- .../pipe/system/snappyHexMeshDict | 2 +- 3 files changed, 107 insertions(+), 87 deletions(-) diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C index 2e41708985..e38249a595 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C @@ -24,128 +24,123 @@ License \*---------------------------------------------------------------------------*/ #include "shellSurfaces.H" -#include "searchableSurface.H" -#include "boundBox.H" -#include "triSurfaceMesh.H" #include "refinementSurfaces.H" #include "searchableSurfaces.H" #include "orientedSurface.H" -#include "pointIndexHit.H" #include "volumeType.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - namespace Foam { template<> const char* -NamedEnum:: +NamedEnum:: names[] = { "inside", "outside", "distance", - "span" + "insideSpan", + "outsideSpan" }; -const NamedEnum shellSurfaces::refineModeNames_; - -} // End namespace Foam +} +const Foam::NamedEnum + Foam::shellSurfaces::refineModeNames_; // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::shellSurfaces::setAndCheckLevels ( - const label shellI, + const label shelli, const List>& distLevels ) { - if (modes_[shellI] != DISTANCE && distLevels.size() != 1) + if (modes_[shelli] != refineMode::distance && distLevels.size() != 1) { FatalErrorInFunction << "For refinement mode " - << refineModeNames_[modes_[shellI]] + << refineModeNames_[modes_[shelli]] << " specify only one distance+level." << " (its distance gets discarded)" << exit(FatalError); } + // Extract information into separate distance and level - distances_[shellI].setSize(distLevels.size()); - levels_[shellI].setSize(distLevels.size()); + distances_[shelli].setSize(distLevels.size()); + levels_[shelli].setSize(distLevels.size()); forAll(distLevels, j) { - distances_[shellI][j] = distLevels[j].first(); - levels_[shellI][j] = distLevels[j].second(); + distances_[shelli][j] = distLevels[j].first(); + levels_[shelli][j] = distLevels[j].second(); // Check in incremental order if (j > 0) { if ( - (distances_[shellI][j] <= distances_[shellI][j-1]) - || (levels_[shellI][j] > levels_[shellI][j-1]) + (distances_[shelli][j] <= distances_[shelli][j-1]) + || (levels_[shelli][j] > levels_[shelli][j-1]) ) { FatalErrorInFunction << "For refinement mode " - << refineModeNames_[modes_[shellI]] + << refineModeNames_[modes_[shelli]] << " : Refinement should be specified in order" << " of increasing distance" << " (and decreasing refinement level)." << endl - << "Distance:" << distances_[shellI][j] - << " refinementLevel:" << levels_[shellI][j] + << "Distance:" << distances_[shelli][j] + << " refinementLevel:" << levels_[shelli][j] << exit(FatalError); } } } - const searchableSurface& shell = allGeometry_[shells_[shellI]]; + const searchableSurface& shell = allGeometry_[shells_[shelli]]; - if (modes_[shellI] == DISTANCE) + if (modes_[shelli] == refineMode::distance) { Info<< "Refinement level according to distance to " << shell.name() << endl; - forAll(levels_[shellI], j) + + forAll(levels_[shelli], j) { - Info<< " level " << levels_[shellI][j] - << " for all cells within " << distances_[shellI][j] + Info<< " level " << levels_[shelli][j] + << " for all cells within " << distances_[shelli][j] << " metre." << endl; } } else { - if (!allGeometry_[shells_[shellI]].hasVolumeType()) + if (!allGeometry_[shells_[shelli]].hasVolumeType()) { FatalErrorInFunction << "Shell " << shell.name() << " does not support testing for " - << refineModeNames_[modes_[shellI]] << endl + << refineModeNames_[modes_[shelli]] << endl << "Probably it is not closed." << exit(FatalError); } - if (modes_[shellI] == INSIDE) + if (modes_[shelli] == refineMode::inside) { - Info<< "Refinement level " << levels_[shellI][0] + Info<< "Refinement level " << levels_[shelli][0] << " for all cells inside " << shell.name() << endl; } else { - Info<< "Refinement level " << levels_[shellI][0] + Info<< "Refinement level " << levels_[shelli][0] << " for all cells outside " << shell.name() << endl; } } } -// Specifically orient triSurfaces using a calculated point outside. -// Done since quite often triSurfaces not of consistent orientation which -// is (currently) necessary for sideness calculation void Foam::shellSurfaces::orient() { // Determine outside point. @@ -153,11 +148,11 @@ void Foam::shellSurfaces::orient() bool hasSurface = false; - forAll(shells_, shellI) + forAll(shells_, shelli) { - const searchableSurface& s = allGeometry_[shells_[shellI]]; + const searchableSurface& s = allGeometry_[shells_[shelli]]; - if (modes_[shellI] != DISTANCE && isA(s)) + if (modes_[shelli] != refineMode::distance && isA(s)) { const triSurfaceMesh& shell = refCast(s); @@ -188,11 +183,15 @@ void Foam::shellSurfaces::orient() // Info<< "Using point " << outsidePt << " to orient shells" << endl; - forAll(shells_, shellI) + forAll(shells_, shelli) { - const searchableSurface& s = allGeometry_[shells_[shellI]]; + const searchableSurface& s = allGeometry_[shells_[shelli]]; - if (modes_[shellI] != DISTANCE && isA(s)) + if + ( + modes_[shelli] != refineMode::distance + && isA(s) + ) { triSurfaceMesh& shell = const_cast ( @@ -254,18 +253,18 @@ Foam::scalar Foam::shellSurfaces::interpolate void Foam::shellSurfaces::findHigherLevel ( const pointField& pt, - const label shellI, + const label shelli, const scalar level0EdgeLength, labelList& maxLevel ) const { - const labelList& levels = levels_[shellI]; + const labelList& levels = levels_[shelli]; - if (modes_[shellI] == DISTANCE) + if (modes_[shelli] == refineMode::distance) { // Distance mode. - const scalarField& distances = distances_[shellI]; + const scalarField& distances = distances_[shelli]; // Collect all those points that have a current maxLevel less than // (any of) the shell. Also collect the furthest distance allowable @@ -296,7 +295,7 @@ void Foam::shellSurfaces::findHigherLevel // Do the expensive nearest test only for the candidate points. List nearInfo; - allGeometry_[shells_[shellI]].findNearest + allGeometry_[shells_[shelli]].findNearest ( candidates, candidateDistSqr, @@ -322,10 +321,14 @@ void Foam::shellSurfaces::findHigherLevel } } } - else if (modes_[shellI] == SPAN) + else if + ( + modes_[shelli] == refineMode::insideSpan + || modes_[shelli] == refineMode::outsideSpan + ) { const triSurfaceMesh& tsm = - refCast(allGeometry_[shells_[shellI]]); + refCast(allGeometry_[shells_[shelli]]); // Collect all those points that have a current maxLevel less than // the maximum and furthest distance allowable for the shell. @@ -341,7 +344,7 @@ void Foam::shellSurfaces::findHigherLevel { candidates[candidateI] = pt[pointi]; candidateMap[candidateI] = pointi; - candidateDistSqr[candidateI] = sqr(distances_[shellI][0]); + candidateDistSqr[candidateI] = sqr(distances_[shelli][0]); candidateI++; } } @@ -361,7 +364,7 @@ void Foam::shellSurfaces::findHigherLevel // Minimum span for the maximum level specified const scalar minSpan ( - cellsAcrossSpan_[shellI]*level0EdgeLength/(1 << (levels[0] - 1)) + cellsAcrossSpan_[shelli]*level0EdgeLength/(1 << (levels[0] - 1)) ); // Update maxLevel @@ -374,7 +377,7 @@ void Foam::shellSurfaces::findHigherLevel interpolate ( tsm, - closeness_[shellI], + closeness_[shelli], nearInfo[candidateI].rawPoint(), nearInfo[candidateI].index() ) @@ -384,7 +387,7 @@ void Foam::shellSurfaces::findHigherLevel { const label level ( - log2(cellsAcrossSpan_[shellI]*level0EdgeLength/span) + 1 + log2(cellsAcrossSpan_[shelli]*level0EdgeLength/span) + 1 ); maxLevel[candidateMap[candidateI]] = min(levels[0], level); @@ -421,7 +424,7 @@ void Foam::shellSurfaces::findHigherLevel // Do the expensive nearest test only for the candidate points. List volType; - allGeometry_[shells_[shellI]].getVolumeType(candidates, volType); + allGeometry_[shells_[shelli]].getVolumeType(candidates, volType); forAll(volType, i) { @@ -430,11 +433,11 @@ void Foam::shellSurfaces::findHigherLevel if ( ( - modes_[shellI] == INSIDE + modes_[shelli] == refineMode::inside && volType[i] == volumeType::inside ) || ( - modes_[shellI] == OUTSIDE + modes_[shelli] == refineMode::outside && volType[i] == volumeType::outside ) ) @@ -459,27 +462,27 @@ Foam::shellSurfaces::shellSurfaces // Wildcard specification : loop over all surfaces and try to find a match. // Count number of shells. - label shellI = 0; + label shelli = 0; forAll(allGeometry.names(), geomI) { const word& geomName = allGeometry_.names()[geomI]; if (shellsDict.found(geomName)) { - shellI++; + shelli++; } } // Size lists - shells_.setSize(shellI); - modes_.setSize(shellI); - distances_.setSize(shellI); - levels_.setSize(shellI); - cellsAcrossSpan_.setSize(shellI); - closeness_.setSize(shellI); + shells_.setSize(shelli); + modes_.setSize(shelli); + distances_.setSize(shelli); + levels_.setSize(shelli); + cellsAcrossSpan_.setSize(shelli); + closeness_.setSize(shelli); HashSet unmatchedKeys(shellsDict.toc()); - shellI = 0; + shelli = 0; forAll(allGeometry_.names(), geomI) { @@ -492,32 +495,42 @@ Foam::shellSurfaces::shellSurfaces const dictionary& dict = ePtr->dict(); unmatchedKeys.erase(ePtr->keyword()); - shells_[shellI] = geomI; - modes_[shellI] = refineModeNames_.read(dict.lookup("mode")); + shells_[shelli] = geomI; + modes_[shelli] = refineModeNames_.read(dict.lookup("mode")); // Read pairs of distance+level - setAndCheckLevels(shellI, dict.lookup("levels")); + setAndCheckLevels(shelli, dict.lookup("levels")); - if (modes_[shellI] == SPAN) + if + ( + modes_[shelli] == refineMode::insideSpan + || modes_[shelli] == refineMode::outsideSpan + ) { const searchableSurface& surface = allGeometry_[geomI]; if (isA(surface)) { - dict.lookup("cellsAcrossSpan") >> cellsAcrossSpan_[shellI]; + dict.lookup("cellsAcrossSpan") >> cellsAcrossSpan_[shelli]; const triSurfaceMesh& tsm = refCast(surface); closeness_.set ( - shellI, + shelli, new triSurfacePointScalarField ( IOobject ( surface.name() - + ".closeness.internalPointCloseness", + + ".closeness." + + ( + modes_[shelli] == refineMode::insideSpan + ? "internal" + : "external" + ) + + "PointCloseness", surface.searchableSurface::time().constant(), "triSurface", surface.searchableSurface::time(), @@ -534,12 +547,14 @@ Foam::shellSurfaces::shellSurfaces FatalIOErrorInFunction(shellsDict) << "Surface " << surface.name() << " is not a triSurface as required by" - " refinement mode " << refineModeNames_[SPAN] + " refinement modes " + << refineModeNames_[refineMode::insideSpan] + << " and " << refineModeNames_[refineMode::outsideSpan] << exit(FatalIOError); } } - shellI++; + shelli++; } } @@ -563,14 +578,15 @@ Foam::shellSurfaces::shellSurfaces // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -// Highest shell level Foam::label Foam::shellSurfaces::maxLevel() const { label overallMax = 0; - forAll(levels_, shellI) + + forAll(levels_, shelli) { - overallMax = max(overallMax, max(levels_[shellI])); + overallMax = max(overallMax, max(levels_[shelli])); } + return overallMax; } @@ -586,9 +602,9 @@ void Foam::shellSurfaces::findHigherLevel // Maximum level of any shell. Start off with level of point. maxLevel = ptLevel; - forAll(shells_, shellI) + forAll(shells_, shelli) { - findHigherLevel(pt, shellI, level0EdgeLength, maxLevel); + findHigherLevel(pt, shelli, level0EdgeLength, maxLevel); } } diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H index 36197918d1..debae13326 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H @@ -58,12 +58,13 @@ public: // Public data types //- Volume refinement controls - enum refineMode + enum class refineMode { - INSIDE, // Refine all inside shell - OUTSIDE, // ,, outside - DISTANCE, // Refine based on distance to shell - SPAN // Refine based on distance across span + inside, // Refine all inside shell + outside, // ,, outside + distance, // Refine based on distance to shell + insideSpan, // Refine based on distance internal span + outsideSpan // Refine based on distance external span }; @@ -96,7 +97,7 @@ private: // Private Data //- refineMode names - static const NamedEnum refineModeNames_; + static const NamedEnum refineModeNames_; // Private Member Functions @@ -104,10 +105,13 @@ private: //- Helper function for initialisation. void setAndCheckLevels ( - const label shellI, + const label shelli, const List>& ); + //- Specifically orient triSurfaces using a calculated point outside. + // Done since quite often triSurfaces not of consistent orientation + // which is (currently) necessary for sideness calculation void orient(); //- Interpolate the surface closeness field to the given point @@ -123,7 +127,7 @@ private: void findHigherLevel ( const pointField& pt, - const label shellI, + const label shelli, const scalar level0EdgeLength, labelList& maxLevel ) const; diff --git a/tutorials/mesh/snappyHexMesh/pipe/system/snappyHexMeshDict b/tutorials/mesh/snappyHexMesh/pipe/system/snappyHexMeshDict index 1717339138..41f87f5070 100644 --- a/tutorials/mesh/snappyHexMesh/pipe/system/snappyHexMeshDict +++ b/tutorials/mesh/snappyHexMesh/pipe/system/snappyHexMeshDict @@ -61,7 +61,7 @@ castellatedMeshControls { pipeWall { - mode span; + mode insideSpan; levels ((1000 2)); cellsAcrossSpan 40; }