diff --git a/etc/caseDicts/annotated/snappyHexMeshDict b/etc/caseDicts/annotated/snappyHexMeshDict index a775ea3b65a1f8ee64f6aec75cb137d7490ecc64..6d1562baa7cca1756ee10cad7cdf9934e70e854a 100644 --- a/etc/caseDicts/annotated/snappyHexMeshDict +++ b/etc/caseDicts/annotated/snappyHexMeshDict @@ -282,6 +282,7 @@ castellatedMeshControls // // cell selection. Default is 'mixed' i.e. keep cells // // whilst doing the gap-level refinement. // //gapMode inside; // inside/outside/mixed + // //gapSelf false; // ignore gaps in same surface //} //wakeBox diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H index 69916ef29ead6a91dee2052d0f6215f02da0f03f..8b0fbaa8567d8db0016c9d4c83d1fa1986918776 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H @@ -434,6 +434,7 @@ private: const label nRefine, labelList& cellMap, + labelList& gapShell, List<FixedList<label, 3>>& shellGapInfo, List<volumeType>& shellGapMode ) const; diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementGapRefine.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementGapRefine.C index 81aadd5b6a8da0da67608e540ec2edb350c0e3fb..60621e2cd9f8a20e91b23807198c686f87b339fb 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementGapRefine.C +++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementGapRefine.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2015 OpenFOAM Foundation - Copyright (C) 2015-2016 OpenCFD Ltd. + Copyright (C) 2015-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -94,6 +94,7 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement // Collect cells to test for inside/outside in shell labelList cellToCompact(mesh_.nCells(), -1); labelList bFaceToCompact(mesh_.nBoundaryFaces(), -1); + labelList gapShell; List<FixedList<label, 3>> shellGapInfo; List<volumeType> shellGapMode; { @@ -135,22 +136,69 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement ( compactToCc, compactToLevel, + + gapShell, shellGapInfo, shellGapMode ); } + //const fileName dir(mesh_.time().path()/timeName()); + //if (debug) + //{ + // mkDir(dir); + // OBJstream insideStr(dir/"insideShell.obj"); + // OBJstream outsideStr(dir/"outsideShell.obj"); + // Pout<< "Writing points to:" << nl + // << " inside : " << insideStr.name() << nl + // << " outside: " << outsideStr.name() << nl + // << endl; + // + // forAll(cellToCompact, celli) + // { + // const label compacti = cellToCompact[celli]; + // + // if (compacti != -1) + // { + // if (gapShell[compacti] != -1) + // { + // insideStr.write(mesh_.cellCentres()[celli]); + // } + // else + // { + // outsideStr.write(mesh_.cellCentres()[celli]); + // } + // } + // } + // forAll(bFaceToCompact, bFacei) + // { + // const label compacti = bFaceToCompact[bFacei]; + // if (compacti != -1) + // { + // if (gapShell[compacti] != -1) + // { + // insideStr.write(neiCc[bFacei]); + // } + // else + // { + // outsideStr.write(neiCc[bFacei]); + // } + // } + // } + //} + + const List<FixedList<label, 3>>& extendedGapLevel = surfaces_.extendedGapLevel(); const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode(); + const boolList& extendedGapSelf = surfaces_.gapSelf(); labelList ccSurface1; List<pointIndexHit> ccHit1; labelList ccRegion1; vectorField ccNormal1; - { labelList ccSurface2; List<pointIndexHit> ccHit2; @@ -218,6 +266,7 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement shellGapMode[compactI], extendedGapLevel[globalRegionI], extendedGapMode[globalRegionI], + gapInfo, gapMode ); @@ -266,6 +315,7 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement shellGapMode[compactI], extendedGapLevel[globalRegionI], extendedGapMode[globalRegionI], + gapInfo, gapMode ); @@ -320,6 +370,7 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement shellGapMode[compactI], extendedGapLevel[globalRegionI], extendedGapMode[globalRegionI], + gapInfo, gapMode ); @@ -402,7 +453,33 @@ Foam::label Foam::meshRefinement::markSurfaceGapRefinement forAll(surf1, i) { - if (surf1[i] != -1 && surf2[i] != -1) + // Combine selfProx of shell and surfaces. Ignore regions for + // now + const label cellI = cellMap[i]; + const label shelli = + ( + cellToCompact[cellI] != -1 + ? gapShell[cellToCompact[cellI]] + : -1 + ); + + bool selfProx = true; + if (shelli != -1) + { + selfProx = shells_.gapSelf()[shelli][0]; + } + if (surf1[i] != -1 && selfProx) + { + const label globalRegioni = surfaces_.globalRegion(surf1[i], 0); + selfProx = extendedGapSelf[globalRegioni]; + } + + if + ( + surf1[i] != -1 + && surf2[i] != -1 + && (surf2[i] != surf1[i] || selfProx) + ) { // Found intersection with surface. Check opposite normal. label cellI = cellMap[i]; @@ -1000,6 +1077,7 @@ void Foam::meshRefinement::selectGapCandidates const label nRefine, labelList& cellMap, + labelList& gapShell, List<FixedList<label, 3>>& shellGapInfo, List<volumeType>& shellGapMode ) const @@ -1029,6 +1107,8 @@ void Foam::meshRefinement::selectGapCandidates ( pointField(cellCentres, cellMap), labelUIndList(cellLevel, cellMap)(), + + gapShell, shellGapInfo, shellGapMode ); @@ -1051,6 +1131,7 @@ void Foam::meshRefinement::selectGapCandidates map.setSize(compactI); cellMap = labelUIndList(cellMap, map)(); + gapShell = labelUIndList(gapShell, map)(); shellGapInfo = UIndirectList<FixedList<label, 3>>(shellGapInfo, map)(); shellGapMode = UIndirectList<volumeType>(shellGapMode, map)(); } @@ -1062,6 +1143,7 @@ void Foam::meshRefinement::mergeGapInfo const volumeType shellGapMode, const FixedList<label, 3>& surfGapInfo, const volumeType surfGapMode, + FixedList<label, 3>& gapInfo, volumeType& gapMode ) const @@ -1114,6 +1196,7 @@ Foam::label Foam::meshRefinement::markInternalGapRefinement const List<FixedList<label, 3>>& extendedGapLevel = surfaces_.extendedGapLevel(); const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode(); + const boolList& extendedGapSelf = surfaces_.gapSelf(); // Get the gap level for the shells const labelList maxLevel(shells_.maxGapLevel()); @@ -1124,6 +1207,7 @@ Foam::label Foam::meshRefinement::markInternalGapRefinement { // Collect cells to test labelList cellMap; + labelList gapShell; List<FixedList<label, 3>> shellGapInfo; List<volumeType> shellGapMode; selectGapCandidates @@ -1132,6 +1216,7 @@ Foam::label Foam::meshRefinement::markInternalGapRefinement nRefine, cellMap, + gapShell, shellGapInfo, shellGapMode ); @@ -1194,8 +1279,10 @@ Foam::label Foam::meshRefinement::markInternalGapRefinement ( shellGapInfo[i], shellGapMode[i], + extendedGapLevel[globalRegionI], extendedGapMode[globalRegionI], + gapInfo, gapMode ); @@ -1288,15 +1375,35 @@ Foam::label Foam::meshRefinement::markInternalGapRefinement // Extract cell based gap size forAll(surf1, i) { - if (surf1[i] != -1 && surf2[i] != -1) + // Combine selfProx of shell and surfaces. Ignore regions for + // now + const label shelli = gapShell[map[i]]; + + bool selfProx = true; + if (shelli != -1) + { + selfProx = shells_.gapSelf()[shelli][0]; + } + if (surf1[i] != -1 && selfProx) + { + const label globalRegioni = surfaces_.globalRegion(surf1[i], 0); + selfProx = extendedGapSelf[globalRegioni]; + } + + if + ( + surf1[i] != -1 + && surf2[i] != -1 + && (surf2[i] != surf1[i] || selfProx) + ) { // Found intersections with surface. Check for // - small gap // - coplanar normals - label cellI = cellMap[i]; + const label cellI = cellMap[i]; - scalar d2 = magSqr(hit1[i].hitPoint()-hit2[i].hitPoint()); + const scalar d2 = magSqr(hit1[i].hitPoint()-hit2[i].hitPoint()); if ( @@ -1479,6 +1586,7 @@ Foam::label Foam::meshRefinement::markSmallFeatureRefinement const List<FixedList<label, 3>>& extendedGapLevel = surfaces_.extendedGapLevel(); const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode(); + const boolList& extendedGapSelf = surfaces_.gapSelf(); label oldNRefine = nRefine; @@ -1535,10 +1643,13 @@ Foam::label Foam::meshRefinement::markSmallFeatureRefinement // applicable specification (minLevel <= celllevel < maxLevel) List<FixedList<label, 3>> shellGapInfo; List<volumeType> shellGapMode; + labelList gapShell; shells_.findHigherGapLevel ( ctrs, labelList(ctrs.size(), Zero), + + gapShell, shellGapInfo, shellGapMode ); @@ -1566,8 +1677,10 @@ Foam::label Foam::meshRefinement::markSmallFeatureRefinement ( shellGapInfo[i], shellGapMode[i], + extendedGapLevel[globalRegionI], extendedGapMode[globalRegionI], + gapInfo, gapMode ); @@ -1647,7 +1760,25 @@ Foam::label Foam::meshRefinement::markSmallFeatureRefinement forAll(surfaceHit, i) { - if (surfaceHit[i] != -1) // && surf2[i] != -1) + // Combine selfProx of shell and surfaces. Ignore regions for + // now + const label shelli = gapShell[map[i]]; + bool selfProx = true; + if (shelli != -1) + { + selfProx = shells_.gapSelf()[shelli][0]; + } + if (surfI != -1 && selfProx) + { + const label globalRegioni = surfaces_.globalRegion(surfI, 0); + selfProx = extendedGapSelf[globalRegioni]; + } + + if + ( + surfaceHit[i] != -1 + && (surfaceHit[i] != surfI || selfProx) + ) { // Found intersection with surface. Check coplanar normals. label cellI = cellMap[i]; diff --git a/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.C b/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.C index 44bbbbdb67303d46a9a10ec12f2dcbb8bb2eacee..c82f64f89a7f4f8389b714ea4cc063b1654c2799 100644 --- a/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.C +++ b/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.C @@ -201,6 +201,7 @@ Foam::refinementSurfaces::refinementSurfaces List<FixedList<label, 3>> globalGapLevel(surfI); List<volumeType> globalGapMode(surfI); + boolList globalGapSelf(surfI); scalarField globalAngle(surfI, -GREAT); PtrList<dictionary> globalPatchInfo(surfI); @@ -213,6 +214,7 @@ Foam::refinementSurfaces::refinementSurfaces List<Map<label>> regionLevelIncr(surfI); List<Map<FixedList<label, 3>>> regionGapLevel(surfI); List<Map<volumeType>> regionGapMode(surfI); + List<Map<bool>> regionGapSelf(surfI); List<Map<scalar>> regionAngle(surfI); List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI); List<Map<label>> regionBlockLevel(surfI); @@ -300,6 +302,8 @@ Foam::refinementSurfaces::refinementSurfaces << exit(FatalIOError); } + globalGapSelf[surfI] = + dict.getOrDefault<bool>("gapSelf", true); const searchableSurface& surface = allGeometry_[surfaces_[surfI]]; @@ -418,7 +422,15 @@ Foam::refinementSurfaces::refinementSurfaces << " gapMode:" << gapModeSpec.str() << exit(FatalIOError); } - + regionGapSelf[surfI].insert + ( + regionI, + regionDict.getOrDefault<bool> + ( + "gapSelf", + true + ) + ); if (regionDict.found("perpendicularAngle")) { @@ -484,6 +496,8 @@ Foam::refinementSurfaces::refinementSurfaces extendedGapLevel_ = nullGapLevel; extendedGapMode_.setSize(nRegions); extendedGapMode_ = volumeType::UNKNOWN; + selfProximity_.setSize(nRegions); + selfProximity_ = true; perpendicularAngle_.setSize(nRegions); perpendicularAngle_ = -GREAT; patchInfo_.setSize(nRegions); @@ -507,6 +521,7 @@ Foam::refinementSurfaces::refinementSurfaces + globalLevelIncr[surfI]; extendedGapLevel_[globalRegionI] = globalGapLevel[surfI]; extendedGapMode_[globalRegionI] = globalGapMode[surfI]; + selfProximity_[globalRegionI] = globalGapSelf[surfI]; perpendicularAngle_[globalRegionI] = globalAngle[surfI]; if (globalPatchInfo.set(surfI)) { @@ -533,6 +548,8 @@ Foam::refinementSurfaces::refinementSurfaces regionGapLevel[surfI][iter.key()]; extendedGapMode_[globalRegionI] = regionGapMode[surfI][iter.key()]; + selfProximity_[globalRegionI] = + regionGapSelf[surfI][iter.key()]; } forAllConstIters(regionAngle[surfI], iter) { diff --git a/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.H b/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.H index d5219f77b0a455de70e48aa57ae3614b7294bda0..c96ad7e71156d4a8e85fd767b1a05aa1c6389a1a 100644 --- a/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.H +++ b/src/mesh/snappyHexMesh/refinementSurfaces/refinementSurfaces.H @@ -102,6 +102,10 @@ class refinementSurfaces //- From global region number to side of surface to detect List<volumeType> extendedGapMode_; + //- From global region number to whether to allow selfProximity + // (in gap refinement) + boolList selfProximity_; + //- From global region number to perpendicular angle scalarField perpendicularAngle_; @@ -241,6 +245,13 @@ public: return extendedGapMode_; } + //- From global region number to whether to detect gaps to same + // surface (in gap refinement) + const boolList& gapSelf() const + { + return selfProximity_; + } + //- From global region number to perpendicular angle const scalarField& perpendicularAngle() const { diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C index 711071da652545014a13629e96cbd8183fc29915..a0b4393250c79fce30b72fcb9555c59aa60bc26a 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.C @@ -610,6 +610,7 @@ Foam::shellSurfaces::shellSurfaces extendedGapLevel_.setSize(shellI); extendedGapMode_.setSize(shellI); + selfProximity_.setSize(shellI); FixedList<label, 3> nullGapLevel; nullGapLevel[0] = 0; @@ -724,6 +725,13 @@ Foam::shellSurfaces::shellSurfaces extendedGapMode_[shellI] = volumeType("gapMode", dict, volumeType::MIXED); + // Detect self-intersections + selfProximity_[shellI].setSize + ( + regionNames.size(), + dict.getOrDefault<bool>("gapSelf", true) + ); + // Override on a per-region basis? @@ -756,6 +764,13 @@ Foam::shellSurfaces::shellSurfaces regionDict, volumeType::MIXED ); + + selfProximity_[shellI][regionI] = + regionDict.getOrDefault<bool> + ( + "gapSelf", + true + ); } } } diff --git a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H index 25ac724f9df3ada43f4dc16202e565a122f1b6a6..cf3822cea090a9837ee1d086166cabde39fd5ec9 100644 --- a/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H +++ b/src/mesh/snappyHexMesh/shellSurfaces/shellSurfaces.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2015 OpenCFD Ltd. + Copyright (C) 2015-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -116,6 +116,9 @@ private: //- Per shell, per region the small-gap level specification List<List<volumeType>> extendedGapMode_; + //- Per shell, per region whether to allow selfProximity refinement + boolListList selfProximity_; + // Private data @@ -206,6 +209,13 @@ public: return extendedGapMode_; } + //- Per shell, per region whether to test for gap with same surface + const boolListList& gapSelf() const + { + return selfProximity_; + } + + // Query //- Highest shell level