diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C index c5ebc807cc..3313726b9f 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C @@ -1082,7 +1082,29 @@ int main(int argc, char *argv[]) if (!limitDict.empty()) { - Info<< "Read refinement shells in = " + Info<< "Read limit shells in = " + << mesh.time().cpuTimeIncrement() << " s" << nl << endl; + } + + + // Optionally read directional refinement shells + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + const dictionary dirRefDict + ( + refineDict.subOrEmptyDict("directionalRefinementRegions") + ); + + if (!dirRefDict.empty()) + { + Info<< "Reading directional refinement shells." << endl; + } + + shellSurfaces dirShells(allGeometry, dirRefDict); + + if (!dirRefDict.empty()) + { + Info<< "Read directional refinement shells in = " << mesh.time().cpuTimeIncrement() << " s" << nl << endl; } @@ -1119,6 +1141,7 @@ int main(int argc, char *argv[]) surfaces, // for surface intersection refinement features, // for feature edges/point based refinement shells, // for volume (inside/outside) refinement + dirShells, // vol volume directional refinement limitShells // limit of volume refinement ); Info<< "Calculated surface intersections in = " diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict index d2c3a1a690..640aaa9790 100644 --- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict +++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMeshDict @@ -49,6 +49,14 @@ geometry max (3.5 2 0.5); } + // Shell for directional refinement + refinementBox + { + type searchableBox; + min (1.5 1 -0.5); + max (3.5 2 0.5); + } + sphere.stl { type triSurfaceMesh; @@ -278,6 +286,21 @@ castellatedMeshControls } + directionalRefinementRegions + { + refinementBox // Closed surface + { + mode inside; + levelIncrement // Specification of additional refinement + ( + (0 (1 0 0)) // For level 0 cells: add one level refinement in x + (1 (1 0 0)) // For level 1 cells: add one level refinement in x + ); + } + } + + + // Optionally limit refinement in geometric region. This limits all // refinement (from features, refinementSurfaces, refinementRegions) // in a given geometric region. The syntax is exactly the same as for the diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C index 98a2620231..8cfe94a498 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C @@ -1222,6 +1222,7 @@ Foam::meshRefinement::meshRefinement const refinementSurfaces& surfaces, const refinementFeatures& features, const shellSurfaces& shells, + const shellSurfaces& dirShells, const shellSurfaces& limitShells ) : @@ -1232,6 +1233,7 @@ Foam::meshRefinement::meshRefinement surfaces_(surfaces), features_(features), shells_(shells), + dirShells_(dirShells), limitShells_(limitShells), meshCutter_ ( diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H index fd36951239..e7c8883888 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H @@ -161,6 +161,9 @@ private: //- All shell-refinement interaction const shellSurfaces& shells_; + //- All directional shell-refinement interaction + const shellSurfaces& dirShells_; + //- All limit-refinement interaction const shellSurfaces& limitShells_; @@ -807,8 +810,9 @@ public: const bool overwrite, const refinementSurfaces&, const refinementFeatures&, - const shellSurfaces&, - const shellSurfaces& + const shellSurfaces&, // omnidirectional refinement + const shellSurfaces&, // directional refinement + const shellSurfaces& // limit refinement ); @@ -861,6 +865,12 @@ public: return shells_; } + //- Reference to directional shell-refinement shells + const shellSurfaces& dirShells() const + { + return dirShells_; + } + //- Reference to meshcutting engine const hexRef8& meshCutter() const { @@ -1037,6 +1047,14 @@ public: const scalar maxLoadUnbalance ); + //- Directionally refine in direction cmpt + autoPtr directionalRefine + ( + const string& msg, + const direction cmpt, + const labelList& cellsToRefine + ); + // Baffle handling diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C index 22863c4b80..53728b952a 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C @@ -41,6 +41,11 @@ License #include "cellSet.H" #include "treeDataCell.H" +#include "cellCuts.H" +#include "refineCell.H" +#include "hexCellLooper.H" +#include "meshCutter.H" + // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // namespace Foam @@ -2624,4 +2629,63 @@ Foam::meshRefinement::balanceAndRefine } +Foam::autoPtr Foam::meshRefinement::directionalRefine +( + const string& msg, + const direction cmpt, + const labelList& cellsToRefine +) +{ + // Set splitting direction + vector refDir(Zero); + refDir[cmpt] = 1; + List refCells(cellsToRefine.size()); + forAll(cellsToRefine, i) + { + refCells[i] = refineCell(cellsToRefine[i], refDir); + } + + // How to walk circumference of cells + hexCellLooper cellWalker(mesh_); + + // Analyse cuts + cellCuts cuts(mesh_, cellWalker, refCells); + + // Cell cutter + Foam::meshCutter meshRefiner(mesh_); + + polyTopoChange meshMod(mesh_); + + // Insert mesh refinement into polyTopoChange. + meshRefiner.setRefinement(cuts, meshMod); + + autoPtr morphMap = meshMod.changeMesh(mesh_, false); + + // Update fields + mesh_.updateMesh(morphMap); + + // Move mesh (since morphing does not do this) + if (morphMap().hasMotionPoints()) + { + mesh_.movePoints(morphMap().preMotionPoints()); + } + else + { + // Delete mesh volumes. + mesh_.clearOut(); + } + + // Reset the instance for if in overwrite mode + mesh_.setInstance(timeName()); + + // Update stored refinement pattern + meshRefiner.updateMesh(morphMap); + + // Update intersection info + updateMesh(morphMap, getChangedFaces(morphMap, cellsToRefine)); + + return morphMap; +} + + // ************************************************************************* // diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C index 955afee4e7..b984ef4f10 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C @@ -584,6 +584,7 @@ Foam::shellSurfaces::shellSurfaces modes_.setSize(shellI); distances_.setSize(shellI); levels_.setSize(shellI); + dirLevels_.setSize(shellI); extendedGapLevel_.setSize(shellI); extendedGapMode_.setSize(shellI); @@ -615,6 +616,31 @@ Foam::shellSurfaces::shellSurfaces setAndCheckLevels(shellI, dict.lookup("levels")); + // Directional refinement + // ~~~~~~~~~~~~~~~~~~~~~~ + + if (dict.readIfPresent("levelIncrement", dirLevels_[shellI])) + { + if (modes_[shellI] == INSIDE) + { + Info<< "Additional directional refinement level" + << " for all cells inside " << geomName << endl; + } + else if (modes_[shellI] == OUTSIDE) + { + Info<< "Additional directional refinement level" + << " for all cells outside " << geomName << endl; + } + else + { + FatalIOErrorInFunction(shellsDict) + << "Unsupported mode " + << refineModeNames_[modes_[shellI]] + << exit(FatalIOError); + } + } + + // Gap specification // ~~~~~~~~~~~~~~~~~ @@ -824,4 +850,74 @@ void Foam::shellSurfaces::findLevel } +void Foam::shellSurfaces::findDirectionalLevel +( + const pointField& pt, + const labelList& ptLevel, + const labelList& dirLevel, // directional level + const direction dir, + labelList& shell +) const +{ + shell.setSize(pt.size()); + shell = -1; + + List volType; + + // Current back to original + DynamicList