snappyHexMesh : refine based on curvature
This commit is contained in:
parent
227727d413
commit
27c3d0c23b
@ -1342,6 +1342,17 @@ int main(int argc, char *argv[])
|
||||
const snapParameters snapParams(snapDict, dryRun);
|
||||
|
||||
|
||||
Info<< "Setting refinement level of surface to be consistent"
|
||||
<< " with curvature." << endl;
|
||||
surfaces.setCurvatureMinLevelFields
|
||||
(
|
||||
refineParams.curvature(),
|
||||
meshRefiner.meshCutter().level0EdgeLength()
|
||||
);
|
||||
Info<< "Checked curvature refinement in = "
|
||||
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||
|
||||
|
||||
|
||||
// Add all the cellZones and faceZones
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -230,6 +230,21 @@ castellatedMeshControls
|
||||
// outside locations. Default is only after all refinement has
|
||||
// been done.
|
||||
//leakLevel 10;
|
||||
|
||||
// Additional refinement for regions of high curvature. Expressed
|
||||
// (bit similar to gapLevel) as:
|
||||
// - number of cells per radius of curvature. (usually 1 is
|
||||
// good enough)
|
||||
// - starting cell level? Not used at the moment.
|
||||
// - maximum cell level. This can be smaller or larger than the
|
||||
// max 'surface' level
|
||||
// - minumum curvature radius to ignore (expressed as a cell level).
|
||||
// This can be used to avoid detecting small sharp surface
|
||||
// features. Set to -1 to ignore.
|
||||
// (sometimes you want more refinement than sharp features since
|
||||
// these can be done with feature edge snapping (so can leave
|
||||
// level (0 0))
|
||||
//curvatureLevel (10 0 10 -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,6 +471,19 @@ private:
|
||||
label& nRefine
|
||||
) const;
|
||||
|
||||
//- Refine cells containing triangles with high refinement level
|
||||
// (currently due to high curvature or being inside shell with
|
||||
// high level)
|
||||
label markSurfaceFieldRefinement
|
||||
(
|
||||
const label nAllowRefine,
|
||||
const labelList& neiLevel,
|
||||
const pointField& neiCc,
|
||||
|
||||
labelList& refineCell,
|
||||
label& nRefine
|
||||
) const;
|
||||
|
||||
//- Helper: count number of normals1 that are in normals2
|
||||
label countMatches
|
||||
(
|
||||
@ -479,6 +492,18 @@ private:
|
||||
const scalar tol = 1e-6
|
||||
) const;
|
||||
|
||||
//- Detect if two intersection points are high curvature (w.r.t.
|
||||
// lengthscale
|
||||
bool highCurvature
|
||||
(
|
||||
const scalar minCosAngle,
|
||||
const scalar lengthScale,
|
||||
const point& p0,
|
||||
const vector& n0,
|
||||
const point& p1,
|
||||
const vector& n1
|
||||
) const;
|
||||
|
||||
//- Mark cells for surface curvature based refinement. Marks if
|
||||
// local curvature > curvature or if on different regions
|
||||
// (markDifferingRegions)
|
||||
|
@ -1833,4 +1833,120 @@ Foam::label Foam::meshRefinement::markSmallFeatureRefinement
|
||||
}
|
||||
|
||||
|
||||
////XXXXXXXX
|
||||
Foam::label Foam::meshRefinement::markSurfaceFieldRefinement
|
||||
(
|
||||
const label nAllowRefine,
|
||||
const labelList& neiLevel,
|
||||
const pointField& neiCc,
|
||||
|
||||
labelList& refineCell,
|
||||
label& nRefine
|
||||
) const
|
||||
{
|
||||
const labelList& cellLevel = meshCutter_.cellLevel();
|
||||
const labelList& surfaceIndices = surfaces_.surfaces();
|
||||
|
||||
label oldNRefine = nRefine;
|
||||
|
||||
//- Force calculation of tetBasePt
|
||||
(void)mesh_.tetBasePtIs();
|
||||
(void)mesh_.cellTree();
|
||||
const indexedOctree<treeDataCell>& tree = mesh_.cellTree();
|
||||
|
||||
|
||||
forAll(surfaceIndices, surfI)
|
||||
{
|
||||
label geomI = surfaceIndices[surfI];
|
||||
const searchableSurface& geom = surfaces_.geometry()[geomI];
|
||||
|
||||
// Get the element index in a roundabout way. Problem is e.g.
|
||||
// distributed surface where local indices differ from global
|
||||
// ones (needed for getRegion call)
|
||||
|
||||
pointField ctrs;
|
||||
labelList region;
|
||||
labelList minLevelField;
|
||||
{
|
||||
// Representative local coordinates and bounding sphere
|
||||
scalarField radiusSqr;
|
||||
geom.boundingSpheres(ctrs, radiusSqr);
|
||||
|
||||
List<pointIndexHit> info;
|
||||
geom.findNearest(ctrs, radiusSqr, info);
|
||||
|
||||
forAll(info, i)
|
||||
{
|
||||
if (!info[i].hit())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "fc:" << ctrs[i]
|
||||
<< " radius:" << radiusSqr[i]
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
geom.getRegion(info, region);
|
||||
geom.getField(info, minLevelField);
|
||||
}
|
||||
|
||||
if (minLevelField.size() != geom.size())
|
||||
{
|
||||
Pout<< "** no minLevelField" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
label nOldRefine = 0;
|
||||
|
||||
forAll(ctrs, i)
|
||||
{
|
||||
label cellI = -1;
|
||||
if (tree.nodes().size() && tree.bb().contains(ctrs[i]))
|
||||
{
|
||||
cellI = tree.findInside(ctrs[i]);
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
cellI != -1
|
||||
&& refineCell[cellI] == -1
|
||||
&& minLevelField[i] > cellLevel[cellI]
|
||||
)
|
||||
{
|
||||
if
|
||||
(
|
||||
!markForRefine
|
||||
(
|
||||
surfI,
|
||||
nAllowRefine,
|
||||
refineCell[cellI],
|
||||
nRefine
|
||||
)
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "For surface " << geom.name() << " found "
|
||||
<< returnReduce(nRefine-nOldRefine, sumOp<label>())
|
||||
<< " cells containing cached refinement field" << endl;
|
||||
|
||||
if
|
||||
(
|
||||
returnReduce(nRefine, sumOp<label>())
|
||||
> returnReduce(nAllowRefine, sumOp<label>())
|
||||
)
|
||||
{
|
||||
Info<< "Reached refinement limit." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return returnReduce(nRefine-oldNRefine, sumOp<label>());
|
||||
}
|
||||
////XXXXXXXXX
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
@ -1109,6 +1109,71 @@ Foam::label Foam::meshRefinement::countMatches
|
||||
}
|
||||
|
||||
|
||||
//XXXXXX
|
||||
//bool Foam::meshRefinement::highCurvature
|
||||
//(
|
||||
// const scalar minCosAngle,
|
||||
// const point& p0,
|
||||
// const vector& n0,
|
||||
// const point& p1,
|
||||
// const vector& n1
|
||||
//) const
|
||||
//{
|
||||
// return ((n0&n1) < minCosAngle);
|
||||
//}
|
||||
bool Foam::meshRefinement::highCurvature
|
||||
(
|
||||
const scalar minCosAngle,
|
||||
const scalar lengthScale,
|
||||
const point& p0,
|
||||
const vector& n0,
|
||||
const point& p1,
|
||||
const vector& n1
|
||||
) const
|
||||
{
|
||||
const scalar cosAngle = (n0&n1);
|
||||
|
||||
if (cosAngle < minCosAngle)
|
||||
{
|
||||
// Sharp feature, independent of intersection points
|
||||
return true;
|
||||
}
|
||||
else if (cosAngle > 1-1e-6)
|
||||
{
|
||||
// Co-planar
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate radius of curvature
|
||||
|
||||
vector axis(n0 ^ n1);
|
||||
const plane pl0(p0, (n0 ^ axis));
|
||||
const scalar r1 = pl0.normalIntersect(p1, n1);
|
||||
|
||||
//const point radiusPoint(p1+r1*n1);
|
||||
//DebugVar(radiusPoint);
|
||||
const plane pl1(p1, (n1 ^ axis));
|
||||
const scalar r0 = pl1.normalIntersect(p0, n0);
|
||||
|
||||
//const point radiusPoint(p0+r0*n0);
|
||||
//DebugVar(radiusPoint);
|
||||
//- Take average radius. Bit ad hoc
|
||||
const scalar radius = 0.5*(mag(r1)+mag(r0));
|
||||
|
||||
if (radius < lengthScale)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//XXXXX
|
||||
|
||||
|
||||
// Mark cells for surface curvature based refinement.
|
||||
Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
(
|
||||
@ -1187,9 +1252,12 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
// Test for all intersections (with surfaces of higher max level than
|
||||
// minLevel) and cache per cell the interesting inter
|
||||
labelListList cellSurfLevels(mesh_.nCells());
|
||||
List<pointList> cellSurfLocations(mesh_.nCells());
|
||||
List<vectorList> cellSurfNormals(mesh_.nCells());
|
||||
|
||||
{
|
||||
// Per segment the intersection point of the surfaces
|
||||
List<pointList> surfaceLocation;
|
||||
// Per segment the normals of the surfaces
|
||||
List<vectorList> surfaceNormal;
|
||||
// Per segment the list of levels of the surfaces
|
||||
@ -1205,6 +1273,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
labelList(surfaces_.maxLevel().size(), 0), // min level
|
||||
surfaces_.maxLevel(),
|
||||
|
||||
surfaceLocation,
|
||||
surfaceNormal,
|
||||
surfaceLevel
|
||||
);
|
||||
@ -1216,12 +1285,14 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
labelList visitOrder;
|
||||
forAll(surfaceNormal, pointI)
|
||||
{
|
||||
pointList& pLocations = surfaceLocation[pointI];
|
||||
vectorList& pNormals = surfaceNormal[pointI];
|
||||
labelList& pLevel = surfaceLevel[pointI];
|
||||
|
||||
sortedOrder(pNormals, visitOrder, normalLess(pNormals));
|
||||
sortedOrder(pNormals, visitOrder, normalLess(pLocations));
|
||||
|
||||
pNormals = List<point>(pNormals, visitOrder);
|
||||
pLocations = List<point>(pLocations, visitOrder);
|
||||
pNormals = List<vector>(pNormals, visitOrder);
|
||||
pLevel = labelUIndList(pLevel, visitOrder);
|
||||
}
|
||||
|
||||
@ -1236,6 +1307,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
label faceI = testFaces[i];
|
||||
label own = mesh_.faceOwner()[faceI];
|
||||
|
||||
const pointList& fPoints = surfaceLocation[i];
|
||||
const vectorList& fNormals = surfaceNormal[i];
|
||||
const labelList& fLevels = surfaceLevel[i];
|
||||
|
||||
@ -1244,6 +1316,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
if (fLevels[hitI] > cellLevel[own])
|
||||
{
|
||||
cellSurfLevels[own].append(fLevels[hitI]);
|
||||
cellSurfLocations[own].append(fPoints[hitI]);
|
||||
cellSurfNormals[own].append(fNormals[hitI]);
|
||||
}
|
||||
|
||||
@ -1253,6 +1326,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
if (fLevels[hitI] > cellLevel[nei])
|
||||
{
|
||||
cellSurfLevels[nei].append(fLevels[hitI]);
|
||||
cellSurfLocations[nei].append(fPoints[hitI]);
|
||||
cellSurfNormals[nei].append(fNormals[hitI]);
|
||||
}
|
||||
}
|
||||
@ -1266,7 +1340,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
if (debug)
|
||||
{
|
||||
label nSet = 0;
|
||||
label nNormals = 9;
|
||||
label nNormals = 0;
|
||||
forAll(cellSurfNormals, cellI)
|
||||
{
|
||||
const vectorList& normals = cellSurfNormals[cellI];
|
||||
@ -1296,21 +1370,38 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
for
|
||||
(
|
||||
label cellI = 0;
|
||||
!reachedLimit && cellI < cellSurfNormals.size();
|
||||
!reachedLimit && cellI < cellSurfLocations.size();
|
||||
cellI++
|
||||
)
|
||||
{
|
||||
const pointList& points = cellSurfLocations[cellI];
|
||||
const vectorList& normals = cellSurfNormals[cellI];
|
||||
const labelList& levels = cellSurfLevels[cellI];
|
||||
|
||||
// Current cell size
|
||||
const scalar cellSize =
|
||||
meshCutter_.level0EdgeLength()/pow(2.0, cellLevel[cellI]);
|
||||
|
||||
// n^2 comparison of all normals in a cell
|
||||
for (label i = 0; !reachedLimit && i < normals.size(); i++)
|
||||
{
|
||||
for (label j = i+1; !reachedLimit && j < normals.size(); j++)
|
||||
{
|
||||
if ((normals[i] & normals[j]) < curvature)
|
||||
//if ((normals[i] & normals[j]) < curvature)
|
||||
if
|
||||
(
|
||||
highCurvature
|
||||
(
|
||||
curvature,
|
||||
cellSize,
|
||||
points[i],
|
||||
normals[i],
|
||||
points[j],
|
||||
normals[j]
|
||||
)
|
||||
)
|
||||
{
|
||||
label maxLevel = max(levels[i], levels[j]);
|
||||
const label maxLevel = max(levels[i], levels[j]);
|
||||
|
||||
if (cellLevel[cellI] < maxLevel)
|
||||
{
|
||||
@ -1358,8 +1449,10 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
label own = mesh_.faceOwner()[faceI];
|
||||
label nei = mesh_.faceNeighbour()[faceI];
|
||||
|
||||
const pointList& ownPoints = cellSurfLocations[own];
|
||||
const vectorList& ownNormals = cellSurfNormals[own];
|
||||
const labelList& ownLevels = cellSurfLevels[own];
|
||||
const pointList& neiPoints = cellSurfLocations[nei];
|
||||
const vectorList& neiNormals = cellSurfNormals[nei];
|
||||
const labelList& neiLevels = cellSurfLevels[nei];
|
||||
|
||||
@ -1379,13 +1472,30 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
|
||||
if (!ownIsSubset && !neiIsSubset)
|
||||
{
|
||||
// Current average cell size. Is min? max? average?
|
||||
const scalar cellSize =
|
||||
meshCutter_.level0EdgeLength()
|
||||
/ pow(2.0, min(cellLevel[own], cellLevel[nei]));
|
||||
|
||||
// n^2 comparison of between ownNormals and neiNormals
|
||||
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
||||
{
|
||||
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
||||
{
|
||||
// Have valid data on both sides. Check curvature.
|
||||
if ((ownNormals[i] & neiNormals[j]) < curvature)
|
||||
//if ((ownNormals[i] & neiNormals[j]) < curvature)
|
||||
if
|
||||
(
|
||||
highCurvature
|
||||
(
|
||||
curvature,
|
||||
cellSize,
|
||||
ownPoints[i],
|
||||
ownNormals[i],
|
||||
neiPoints[j],
|
||||
neiNormals[j]
|
||||
)
|
||||
)
|
||||
{
|
||||
// See which side to refine.
|
||||
if (cellLevel[own] < ownLevels[i])
|
||||
@ -1441,7 +1551,11 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
}
|
||||
|
||||
|
||||
// Send over surface normal to neighbour cell.
|
||||
// Send over surface point/normal to neighbour cell.
|
||||
// labelListList neiSurfaceLevel;
|
||||
// syncTools::swapBoundaryCellList(mesh_, cellSurfLevels, neiSurfaceLevel);
|
||||
List<vectorList> neiSurfacePoints;
|
||||
syncTools::swapBoundaryCellList(mesh_, cellSurfLocations, neiSurfacePoints);
|
||||
List<vectorList> neiSurfaceNormals;
|
||||
syncTools::swapBoundaryCellList(mesh_, cellSurfNormals, neiSurfaceNormals);
|
||||
|
||||
@ -1456,9 +1570,13 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
label own = mesh_.faceOwner()[faceI];
|
||||
label bFaceI = faceI - mesh_.nInternalFaces();
|
||||
|
||||
const pointList& ownPoints = cellSurfLocations[own];
|
||||
const vectorList& ownNormals = cellSurfNormals[own];
|
||||
const labelList& ownLevels = cellSurfLevels[own];
|
||||
|
||||
const pointList& neiPoints = neiSurfacePoints[bFaceI];
|
||||
const vectorList& neiNormals = neiSurfaceNormals[bFaceI];
|
||||
//const labelList& neiLevels = neiSurfaceLevel[bFacei];
|
||||
|
||||
// Special case: owner normals set is a subset of the neighbour
|
||||
// normals. Do not do curvature refinement since other cell's normals
|
||||
@ -1475,13 +1593,30 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
||||
|
||||
if (!ownIsSubset && !neiIsSubset)
|
||||
{
|
||||
// Current average cell size. Is min? max? average?
|
||||
const scalar cellSize =
|
||||
meshCutter_.level0EdgeLength()
|
||||
/ pow(2.0, min(cellLevel[own], neiLevel[bFaceI]));
|
||||
|
||||
// n^2 comparison of between ownNormals and neiNormals
|
||||
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
||||
{
|
||||
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
||||
{
|
||||
// Have valid data on both sides. Check curvature.
|
||||
if ((ownNormals[i] & neiNormals[j]) < curvature)
|
||||
//if ((ownNormals[i] & neiNormals[j]) < curvature)
|
||||
if
|
||||
(
|
||||
highCurvature
|
||||
(
|
||||
curvature,
|
||||
cellSize,
|
||||
ownPoints[i],
|
||||
ownNormals[i],
|
||||
neiPoints[j],
|
||||
neiNormals[j]
|
||||
)
|
||||
)
|
||||
{
|
||||
if (cellLevel[own] < ownLevels[i])
|
||||
{
|
||||
@ -2205,25 +2340,46 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
||||
// Refinement based on features smaller than cell size
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if
|
||||
(
|
||||
smallFeatureRefinement
|
||||
&& (planarCos >= -1 && planarCos <= 1)
|
||||
&& max(shells_.maxGapLevel()) > 0
|
||||
)
|
||||
if (smallFeatureRefinement)
|
||||
{
|
||||
label nGap = markSmallFeatureRefinement
|
||||
label nGap = 0;
|
||||
if
|
||||
(
|
||||
planarCos,
|
||||
nAllowRefine,
|
||||
neiLevel,
|
||||
neiCc,
|
||||
planarCos >= -1
|
||||
&& planarCos <= 1
|
||||
&& max(shells_.maxGapLevel()) > 0
|
||||
)
|
||||
{
|
||||
nGap = markSmallFeatureRefinement
|
||||
(
|
||||
planarCos,
|
||||
nAllowRefine,
|
||||
neiLevel,
|
||||
neiCc,
|
||||
|
||||
refineCell,
|
||||
nRefine
|
||||
);
|
||||
refineCell,
|
||||
nRefine
|
||||
);
|
||||
}
|
||||
Info<< "Marked for refinement due to close opposite surfaces "
|
||||
<< ": " << nGap << " cells." << endl;
|
||||
|
||||
label nCurv = 0;
|
||||
if (max(surfaces_.maxCurvatureLevel()) > 0)
|
||||
{
|
||||
nCurv = markSurfaceFieldRefinement
|
||||
(
|
||||
nAllowRefine,
|
||||
neiLevel,
|
||||
neiCc,
|
||||
|
||||
refineCell,
|
||||
nRefine
|
||||
);
|
||||
Info<< "Marked for refinement"
|
||||
<< " due to curvature "
|
||||
<< ": " << nCurv << " cells." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,6 +38,8 @@ License
|
||||
// For dictionary::get wrapper
|
||||
#include "meshRefinement.H"
|
||||
|
||||
#include "OBJstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList Foam::refinementSurfaces::findHigherLevel
|
||||
@ -194,15 +196,14 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
labelList globalMaxLevel(surfI, Zero);
|
||||
labelList globalLevelIncr(surfI, Zero);
|
||||
|
||||
FixedList<label, 3> nullGapLevel;
|
||||
nullGapLevel[0] = 0;
|
||||
nullGapLevel[1] = 0;
|
||||
nullGapLevel[2] = 0;
|
||||
|
||||
const FixedList<label, 3> nullGapLevel({0, 0, 0});
|
||||
List<FixedList<label, 3>> globalGapLevel(surfI);
|
||||
List<volumeType> globalGapMode(surfI);
|
||||
boolList globalGapSelf(surfI);
|
||||
|
||||
const FixedList<label, 4> nullCurvLevel({0, 0, 0, -1});
|
||||
List<FixedList<label, 4>> globalCurvLevel(surfI);
|
||||
|
||||
scalarField globalAngle(surfI, -GREAT);
|
||||
PtrList<dictionary> globalPatchInfo(surfI);
|
||||
|
||||
@ -216,6 +217,7 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
List<Map<FixedList<label, 3>>> regionGapLevel(surfI);
|
||||
List<Map<volumeType>> regionGapMode(surfI);
|
||||
List<Map<bool>> regionGapSelf(surfI);
|
||||
List<Map<FixedList<label, 4>>> regionCurvLevel(surfI);
|
||||
List<Map<scalar>> regionAngle(surfI);
|
||||
List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
|
||||
List<Map<label>> regionBlockLevel(surfI);
|
||||
@ -307,6 +309,19 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
globalGapSelf[surfI] =
|
||||
dict.getOrDefault<bool>("gapSelf", true);
|
||||
|
||||
globalCurvLevel[surfI] = nullCurvLevel;
|
||||
if (dict.readIfPresent("curvatureLevel", globalCurvLevel[surfI]))
|
||||
{
|
||||
if (globalCurvLevel[surfI][0] <= 0)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Illegal curvatureLevel specification for surface "
|
||||
<< names_[surfI]
|
||||
<< " : curvatureLevel:" << globalCurvLevel[surfI]
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
|
||||
const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
|
||||
|
||||
// Surface zones
|
||||
@ -435,6 +450,20 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
)
|
||||
);
|
||||
|
||||
FixedList<label, 4> curvSpec(nullCurvLevel);
|
||||
if (regionDict.readIfPresent("curvatureLevel", curvSpec))
|
||||
{
|
||||
if (curvSpec[0] <= 0)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Illegal curvatureLevel specification for surface "
|
||||
<< names_[surfI]
|
||||
<< " : curvatureLevel:" << curvSpec
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
regionCurvLevel[surfI].insert(regionI, curvSpec);
|
||||
|
||||
if (regionDict.found("perpendicularAngle"))
|
||||
{
|
||||
regionAngle[surfI].insert
|
||||
@ -505,6 +534,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
extendedGapMode_ = volumeType::UNKNOWN;
|
||||
selfProximity_.setSize(nRegions);
|
||||
selfProximity_ = true;
|
||||
extendedCurvatureLevel_.setSize(nRegions);
|
||||
extendedCurvatureLevel_ = nullCurvLevel;
|
||||
perpendicularAngle_.setSize(nRegions);
|
||||
perpendicularAngle_ = -GREAT;
|
||||
patchInfo_.setSize(nRegions);
|
||||
@ -531,6 +562,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
extendedGapLevel_[globalRegionI] = globalGapLevel[surfI];
|
||||
extendedGapMode_[globalRegionI] = globalGapMode[surfI];
|
||||
selfProximity_[globalRegionI] = globalGapSelf[surfI];
|
||||
extendedCurvatureLevel_[globalRegionI] =
|
||||
globalCurvLevel[surfI];
|
||||
perpendicularAngle_[globalRegionI] = globalAngle[surfI];
|
||||
if (globalPatchInfo.set(surfI))
|
||||
{
|
||||
@ -560,6 +593,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
||||
regionGapMode[surfI][iter.key()];
|
||||
selfProximity_[globalRegionI] =
|
||||
regionGapSelf[surfI][iter.key()];
|
||||
extendedCurvatureLevel_[globalRegionI] =
|
||||
regionCurvLevel[surfI][iter.key()];
|
||||
}
|
||||
forAllConstIters(regionAngle[surfI], iter)
|
||||
{
|
||||
@ -713,6 +748,26 @@ Foam::labelList Foam::refinementSurfaces::maxGapLevel() const
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::refinementSurfaces::maxCurvatureLevel() const
|
||||
{
|
||||
labelList surfaceMax(surfaces_.size(), Zero);
|
||||
|
||||
forAll(surfaces_, surfI)
|
||||
{
|
||||
const wordList& regionNames = allGeometry_[surfaces_[surfI]].regions();
|
||||
|
||||
forAll(regionNames, regionI)
|
||||
{
|
||||
label globalI = globalRegion(surfI, regionI);
|
||||
const FixedList<label, 4>& gapInfo =
|
||||
extendedCurvatureLevel_[globalI];
|
||||
surfaceMax[surfI] = max(surfaceMax[surfI], gapInfo[2]);
|
||||
}
|
||||
}
|
||||
return surfaceMax;
|
||||
}
|
||||
|
||||
|
||||
// Precalculate the refinement level for every element of the searchable
|
||||
// surface.
|
||||
void Foam::refinementSurfaces::setMinLevelFields(const shellSurfaces& shells)
|
||||
@ -763,13 +818,15 @@ void Foam::refinementSurfaces::setMinLevelFields(const shellSurfaces& shells)
|
||||
|
||||
// In case of triangulated surfaces only cache value if triangle
|
||||
// centre and vertices are in same shell
|
||||
if (isA<triSurface>(geom))
|
||||
const auto* tsPtr = isA<const triSurface>(geom);
|
||||
|
||||
if (tsPtr)
|
||||
{
|
||||
label nUncached = 0;
|
||||
|
||||
// Check if points differing from ctr level
|
||||
|
||||
const triSurface& ts = refCast<const triSurface>(geom);
|
||||
const triSurface& ts = *tsPtr;
|
||||
const pointField& points = ts.points();
|
||||
|
||||
// Determine minimum expected level to avoid having to
|
||||
@ -845,6 +902,312 @@ void Foam::refinementSurfaces::setMinLevelFields(const shellSurfaces& shells)
|
||||
}
|
||||
|
||||
|
||||
// Precalculate the refinement level for every element of the searchable
|
||||
// surface.
|
||||
void Foam::refinementSurfaces::setCurvatureMinLevelFields
|
||||
(
|
||||
const scalar cosAngle,
|
||||
const scalar level0EdgeLength
|
||||
)
|
||||
{
|
||||
const labelList maxCurvLevel(maxCurvatureLevel());
|
||||
|
||||
|
||||
forAll(surfaces_, surfI)
|
||||
{
|
||||
// Check if there is a specification of the extended curvature
|
||||
if (maxCurvLevel[surfI] <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const searchableSurface& geom = allGeometry_[surfaces_[surfI]];
|
||||
|
||||
const auto* tsPtr = isA<const triSurface>(geom);
|
||||
|
||||
// Cache the refinement level (max of surface level and shell level)
|
||||
// on a per-element basis. Only makes sense if there are lots of
|
||||
// elements. Possibly should have 'enough' elements to have fine
|
||||
// enough resolution but for now just make sure we don't catch e.g.
|
||||
// searchableBox (size=6)
|
||||
if (tsPtr)
|
||||
{
|
||||
// Representative local coordinates and bounding sphere
|
||||
pointField ctrs;
|
||||
scalarField radiusSqr;
|
||||
geom.boundingSpheres(ctrs, radiusSqr);
|
||||
|
||||
labelList minLevelField(ctrs.size(), Zero);
|
||||
//labelList surfMin(ctrs.size(), Zero);
|
||||
labelList surfMax(ctrs.size(), Zero);
|
||||
labelList nCurvCells(ctrs.size(), Zero);
|
||||
labelList curvIgnore(ctrs.size(), -1);
|
||||
{
|
||||
// Get the element index in a roundabout way. Problem is e.g.
|
||||
// distributed surface where local indices differ from global
|
||||
// ones (needed for getRegion call)
|
||||
List<pointIndexHit> info;
|
||||
geom.findNearest(ctrs, radiusSqr, info);
|
||||
|
||||
// Get per element the region
|
||||
labelList region;
|
||||
geom.getRegion(info, region);
|
||||
|
||||
// See if a cached level field available (from e.g. shells)
|
||||
labelList cachedField;
|
||||
geom.getField(info, cachedField);
|
||||
|
||||
// From the region get the surface-wise refinement level
|
||||
forAll(minLevelField, i)
|
||||
{
|
||||
if (info[i].hit()) //Note: should not be necessary
|
||||
{
|
||||
const label globali = globalRegion(surfI, region[i]);
|
||||
curvIgnore[i] = extendedCurvatureLevel_[globali][3];
|
||||
nCurvCells[i] = extendedCurvatureLevel_[globali][0];
|
||||
//surfMin[i] = extendedCurvatureLevel_[globali][1];
|
||||
surfMax[i] = extendedCurvatureLevel_[globali][2];
|
||||
|
||||
minLevelField[i] = minLevel(surfI, region[i]);
|
||||
if (cachedField.size() > i)
|
||||
{
|
||||
minLevelField[i] =
|
||||
max(minLevelField[i], cachedField[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate per-triangle curvature. This is the max of the
|
||||
// measured point-based curvature + some constraints.
|
||||
scalarField cellCurv(ctrs.size(), Zero);
|
||||
{
|
||||
// Walk surface and detect sharp features. Returns maximum
|
||||
// curvature (per surface point. Note: returns per point, not
|
||||
// per localpoint)
|
||||
const auto& ts = *tsPtr;
|
||||
auto tcurv(triSurfaceTools::curvatures(ts));
|
||||
auto& curv = tcurv.ref();
|
||||
|
||||
// Reset curvature on sharp edges (and neighbours since
|
||||
// curvature uses extended stencil)
|
||||
{
|
||||
const auto& edgeFaces = ts.edgeFaces();
|
||||
const auto& edges = ts.edges();
|
||||
const auto& points = ts.points();
|
||||
const auto& mp = ts.meshPoints();
|
||||
|
||||
bitSet isOnSharpEdge(points.size());
|
||||
forAll(edgeFaces, edgei)
|
||||
{
|
||||
const auto& eFaces = edgeFaces[edgei];
|
||||
const edge meshE(mp, edges[edgei]);
|
||||
|
||||
if (eFaces.size() == 2)
|
||||
{
|
||||
const auto& f0 = ts[eFaces[0]];
|
||||
const auto& f1 = ts[eFaces[1]];
|
||||
|
||||
const vector n0 = f0.unitNormal(points);
|
||||
|
||||
const int dir0 = f0.edgeDirection(meshE);
|
||||
const int dir1 = f1.edgeDirection(meshE);
|
||||
vector n1 = f1.unitNormal(points);
|
||||
if (dir0 == dir1)
|
||||
{
|
||||
// Flip since use edge in same direction
|
||||
// (should not be the case for 'proper'
|
||||
// surfaces)
|
||||
n1 = -n1;
|
||||
}
|
||||
|
||||
if ((n0&n1) < cosAngle)
|
||||
{
|
||||
isOnSharpEdge.set(meshE[0]);
|
||||
isOnSharpEdge.set(meshE[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extend by one layer
|
||||
{
|
||||
bitSet oldOnSharpEdge(isOnSharpEdge);
|
||||
isOnSharpEdge = false;
|
||||
for (const auto& f : ts)
|
||||
{
|
||||
for (const label pointi : f)
|
||||
{
|
||||
if (oldOnSharpEdge[pointi])
|
||||
{
|
||||
// Mark all points on triangle
|
||||
isOnSharpEdge.set(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Unmark curvature
|
||||
autoPtr<OBJstream> str;
|
||||
//if (debug)
|
||||
//{
|
||||
// str.reset
|
||||
// (
|
||||
// new OBJstream
|
||||
// (
|
||||
// "sharpEdgePoints_"
|
||||
// + geom.name()
|
||||
// + ".obj"
|
||||
// )
|
||||
// );
|
||||
// Info<< "Writing sharp edge points to "
|
||||
// << str().name() << endl;
|
||||
//}
|
||||
|
||||
for (const label pointi : isOnSharpEdge)
|
||||
{
|
||||
// Reset measured point-based curvature
|
||||
curv[pointi] = 0.0;
|
||||
if (str)
|
||||
{
|
||||
str().write(points[pointi]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset curvature on -almost- sharp edges.
|
||||
// This resets the point-based curvature if the edge
|
||||
// is considered to be a sharp edge based on its actual
|
||||
// curvature. This is only used if the 'ignore' level is
|
||||
// given.
|
||||
{
|
||||
// Pass 1: accumulate constraints on the points - get
|
||||
// the minimum of curvature constraints on the
|
||||
// connected triangles. Looks at user-specified
|
||||
// min curvature - does not use actual measured
|
||||
// curvature
|
||||
scalarField pointMinCurv(ts.nPoints(), VGREAT);
|
||||
|
||||
forAll(ts, i)
|
||||
{
|
||||
// Is ignore level given for surface
|
||||
const label level = curvIgnore[i];
|
||||
if (level >= 0)
|
||||
{
|
||||
// Convert to (inv) size
|
||||
const scalar length = level0EdgeLength/(2<<level);
|
||||
const scalar invLength = 1.0/length;
|
||||
for (const label pointi : ts[i])
|
||||
{
|
||||
if
|
||||
(
|
||||
invLength < pointMinCurv[pointi]
|
||||
&& curv[pointi] > SMALL
|
||||
)
|
||||
{
|
||||
//Pout<< "** at location:"
|
||||
// << ts.points()[pointi]
|
||||
// << " measured curv:" << curv[pointi]
|
||||
// << " radius:" << 1.0/curv[pointi]
|
||||
// << " ignore level:" << level
|
||||
// << " ignore radius:" << length
|
||||
// << " resetting minCurv to "
|
||||
// << invLength
|
||||
// << endl;
|
||||
}
|
||||
|
||||
pointMinCurv[pointi] =
|
||||
min(pointMinCurv[pointi], invLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clip curvature (should do nothing for most points unless
|
||||
// ignore-level is triggered)
|
||||
forAll(pointMinCurv, pointi)
|
||||
{
|
||||
if (pointMinCurv[pointi] < curv[pointi])
|
||||
{
|
||||
//Pout<< "** at location:" << ts.points()[pointi]
|
||||
// << " measured curv:" << curv[pointi]
|
||||
// << " radius:" << 1.0/curv[pointi]
|
||||
// << " cellLimit:" << pointMinCurv[pointi]
|
||||
// << endl;
|
||||
|
||||
// Set up to ignore point
|
||||
//curv[pointi] = pointMinCurv[pointi];
|
||||
curv[pointi] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
forAll(ts, i)
|
||||
{
|
||||
const auto& f = ts[i];
|
||||
// Take max curvature (= min radius of curvature)
|
||||
cellCurv[i] = max(curv[f[0]], max(curv[f[1]], curv[f[2]]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if(debug)
|
||||
//{
|
||||
// const scalar maxCurv = gMax(cellCurv);
|
||||
// if (maxCurv > SMALL)
|
||||
// {
|
||||
// const scalar r = scalar(1.0)/maxCurv;
|
||||
//
|
||||
// Pout<< "For geometry " << geom.name()
|
||||
// << " have curvature max " << maxCurv
|
||||
// << " which equates to radius:" << r
|
||||
// << " which equates to refinement level "
|
||||
// << log2(level0EdgeLength/r)
|
||||
// << endl;
|
||||
// }
|
||||
//}
|
||||
|
||||
forAll(cellCurv, i)
|
||||
{
|
||||
if (cellCurv[i] > SMALL && nCurvCells[i] > 0)
|
||||
{
|
||||
//- ?If locally have a cached field override the
|
||||
// surface-based level ignore any curvature?
|
||||
//if (minLevelField[i] > surfMin[i])
|
||||
//{
|
||||
// // Ignore curvature
|
||||
//}
|
||||
//else
|
||||
//if (surfMin[i] == surfMax[i])
|
||||
//{
|
||||
// // Ignore curvature. Bypass calculation below.
|
||||
//}
|
||||
//else
|
||||
{
|
||||
// Re-work the curvature into a radius and into a
|
||||
// number of cells
|
||||
const scalar r = scalar(1.0)/cellCurv[i];
|
||||
const scalar level =
|
||||
log2(nCurvCells[i]*level0EdgeLength/r);
|
||||
const label l = round(level);
|
||||
|
||||
if (l > minLevelField[i] && l <= surfMax[i])
|
||||
{
|
||||
minLevelField[i] = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Store minLevelField on surface
|
||||
const_cast<searchableSurface&>(geom).setField(minLevelField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Find intersections of edge. Return -1 or first surface with higher minLevel
|
||||
// number.
|
||||
void Foam::refinementSurfaces::findHigherIntersection
|
||||
|
@ -110,6 +110,9 @@ class refinementSurfaces
|
||||
// (in gap refinement)
|
||||
boolList selfProximity_;
|
||||
|
||||
//- From global region number to curvature specification
|
||||
List<FixedList<label, 4>> extendedCurvatureLevel_;
|
||||
|
||||
//- From global region number to perpendicular angle
|
||||
scalarField perpendicularAngle_;
|
||||
|
||||
@ -263,6 +266,19 @@ public:
|
||||
return selfProximity_;
|
||||
}
|
||||
|
||||
//- From global region number to specification of curvature
|
||||
// refinement: 4 labels specifying
|
||||
// - minimum wanted number of cells in the curvature radius
|
||||
// - ?minimum cell level when to start trying to detect gaps
|
||||
// - maximum cell level to refine to (so do not detect curvature if
|
||||
// celllevel >= maximum level)
|
||||
// - minimum radius to ignore (expressed as refinement level).
|
||||
// This can be used to ignore feature-edges. Set to -1 to ignore.
|
||||
const List<FixedList<label, 4>>& extendedCurvatureLevel() const
|
||||
{
|
||||
return extendedCurvatureLevel_;
|
||||
}
|
||||
|
||||
//- From global region number to perpendicular angle
|
||||
const scalarField& perpendicularAngle() const
|
||||
{
|
||||
@ -307,12 +323,23 @@ public:
|
||||
//- Per surface the maximum extendedGapLevel over all its regions
|
||||
labelList maxGapLevel() const;
|
||||
|
||||
//- Calculate minLevelFields
|
||||
//- Per surface the maximum curvatureLevel over all its regions
|
||||
labelList maxCurvatureLevel() const;
|
||||
|
||||
//- Calculate minLevelFields according to both surface- and
|
||||
// shell-based levels
|
||||
void setMinLevelFields
|
||||
(
|
||||
const shellSurfaces& shells
|
||||
);
|
||||
|
||||
//- Update minLevelFields according to (triSurface-only) curvature
|
||||
void setCurvatureMinLevelFields
|
||||
(
|
||||
const scalar cosAngle,
|
||||
const scalar level0EdgeLength
|
||||
);
|
||||
|
||||
////- Helper: count number of triangles per region
|
||||
//static labelList countRegions(const triSurface&);
|
||||
|
||||
|
@ -230,10 +230,16 @@ Foam::label Foam::snappyRefineDriver::smallFeatureRefine
|
||||
label iter = 0;
|
||||
|
||||
// See if any surface has an extendedGapLevel
|
||||
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
|
||||
labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
|
||||
const labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
|
||||
const labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
|
||||
const labelList curvMaxLevel(meshRefiner_.surfaces().maxCurvatureLevel());
|
||||
|
||||
if (max(surfaceMaxLevel) == 0 && max(shellMaxLevel) == 0)
|
||||
if
|
||||
(
|
||||
max(surfaceMaxLevel) == 0
|
||||
&& max(shellMaxLevel) == 0
|
||||
&& max(curvMaxLevel) == 0
|
||||
)
|
||||
{
|
||||
return iter;
|
||||
}
|
||||
@ -3382,6 +3388,7 @@ void Foam::snappyRefineDriver::doRefine
|
||||
(
|
||||
max(meshRefiner_.surfaces().maxGapLevel()) > 0
|
||||
|| max(meshRefiner_.shells().maxGapLevel()) > 0
|
||||
|| max(meshRefiner_.surfaces().maxCurvatureLevel()) > 0
|
||||
)
|
||||
{
|
||||
// In case we use automatic gap level refinement do some pre-refinement
|
||||
|
12
tutorials/mesh/snappyHexMesh/block_with_curvature/Allclean
Executable file
12
tutorials/mesh/snappyHexMesh/block_with_curvature/Allclean
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
cleanCase0
|
||||
|
||||
# Remove surface and features
|
||||
rm -rf constant/triSurface
|
||||
rm -rf constant/extendedFeatureEdgeMesh
|
||||
|
||||
#------------------------------------------------------------------------------
|
18
tutorials/mesh/snappyHexMesh/block_with_curvature/Allrun
Executable file
18
tutorials/mesh/snappyHexMesh/block_with_curvature/Allrun
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
mkdir -p constant/triSurface
|
||||
|
||||
cp -f \
|
||||
resources/geometry/curvature-box.stl.gz \
|
||||
constant/triSurface
|
||||
|
||||
runApplication surfaceFeatureExtract
|
||||
|
||||
runApplication blockMesh
|
||||
|
||||
runApplication snappyHexMesh -overwrite
|
||||
|
||||
#------------------------------------------------------------------------------
|
@ -0,0 +1,6 @@
|
||||
testcase to demonstrate surface-curvature-based refinement.
|
||||
- starts from a single cell
|
||||
- has uniform surface refinement 0
|
||||
- but has curvature detection to refine up to 10
|
||||
- also uses limitRegions to not refine half the domain (in x direction)
|
||||
- note that there is still refinement bleeding due to the 2:1 limitation
|
Binary file not shown.
@ -0,0 +1,58 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object blockMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
scale 1;
|
||||
|
||||
vertices
|
||||
(
|
||||
( 0 -0.2 0)
|
||||
( 0.5 -0.2 0)
|
||||
( 0.5 0.3 0)
|
||||
( 0 0.3 0)
|
||||
( 0 -0.2 0.5)
|
||||
( 0.5 -0.2 0.5)
|
||||
( 0.5 0.3 0.5)
|
||||
( 0 0.3 0.5)
|
||||
);
|
||||
|
||||
blocks
|
||||
(
|
||||
// hex (0 1 2 3 4 5 6 7) (15 10 10) simpleGrading (1 1 1)
|
||||
hex (0 1 2 3 4 5 6 7) (1 1 1) simpleGrading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
();
|
||||
|
||||
boundary
|
||||
(
|
||||
allBoundary
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(3 7 6 2)
|
||||
(1 5 4 0) //back
|
||||
(2 6 5 1) //outlet
|
||||
(0 4 7 3) //inlet
|
||||
(0 3 2 1) //lowerWall
|
||||
(4 5 6 7) //upperWall
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,55 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object controlDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//DebugSwitches
|
||||
//{
|
||||
// fvGeometryScheme 1;
|
||||
// highAspectRatio 1;
|
||||
// basic 1;
|
||||
//}
|
||||
|
||||
application simpleFoam;
|
||||
|
||||
startFrom startTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
stopAt endTime;
|
||||
|
||||
endTime 15000;
|
||||
|
||||
deltaT 1;
|
||||
|
||||
writeControl timeStep;
|
||||
|
||||
writeInterval 5000;
|
||||
|
||||
purgeWrite 2;
|
||||
|
||||
writeFormat binary;
|
||||
|
||||
writePrecision 15;
|
||||
|
||||
writeCompression off;
|
||||
|
||||
timeFormat general;
|
||||
|
||||
timePrecision 8;
|
||||
|
||||
runTimeModifiable false;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,53 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object fvSchemes;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
ddtSchemes
|
||||
{
|
||||
}
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
}
|
||||
|
||||
divSchemes
|
||||
{
|
||||
}
|
||||
|
||||
laplacianSchemes
|
||||
{
|
||||
}
|
||||
|
||||
interpolationSchemes
|
||||
{
|
||||
}
|
||||
|
||||
snGradSchemes
|
||||
{
|
||||
}
|
||||
|
||||
wallDist
|
||||
{
|
||||
}
|
||||
|
||||
geometry
|
||||
{
|
||||
type highAspectRatio;
|
||||
minAspect 10;
|
||||
maxAspect 100;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,22 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object fvSolution;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
solvers
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,78 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object meshQualityDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 65;
|
||||
|
||||
//- Max skewness allowed. Set to <0 to disable.
|
||||
maxBoundarySkewness 20;
|
||||
maxInternalSkewness 4;
|
||||
|
||||
//- Max concaveness allowed. Is angle (in degrees) below which concavity
|
||||
// is allowed. 0 is straight face, <0 would be convex face.
|
||||
// Set to 180 to disable.
|
||||
maxConcave 80;
|
||||
|
||||
//- Minimum pyramid volume. Is absolute volume of cell pyramid.
|
||||
// Set to a sensible fraction of the smallest cell volume expected.
|
||||
// Set to very negative number (e.g. -1E30) to disable.
|
||||
minVol 1e-13;
|
||||
|
||||
//- Minimum quality of the tet formed by the face-centre
|
||||
// and variable base point minimum decomposition triangles and
|
||||
// the cell centre. Set to very negative number (e.g. -1E30) to
|
||||
// disable.
|
||||
// <0 = inside out tet,
|
||||
// 0 = flat tet
|
||||
// 1 = regular tet
|
||||
minTetQuality 1e-15;
|
||||
|
||||
//- Minimum face area. Set to <0 to disable.
|
||||
minArea -1;
|
||||
|
||||
//- Minimum face twist. Set to <-1 to disable. dot product of face normal
|
||||
// (itself the average of the triangle normals)
|
||||
// and face centre triangles normal
|
||||
minTwist 0.02;
|
||||
|
||||
//- Minimum normalised cell determinant. This is the determinant of all
|
||||
// the areas of internal faces. It is a measure of how much of the
|
||||
// outside area of the cell is to other cells. The idea is that if all
|
||||
// outside faces of the cell are 'floating' (zeroGradient) the
|
||||
// 'fixedness' of the cell is determined by the area of the internal faces.
|
||||
// 1 = hex, <= 0 = folded or flattened illegal cell
|
||||
minDeterminant 0.001;
|
||||
|
||||
//- Relative position of face in relation to cell centres (0.5 for orthogonal
|
||||
// mesh) (0 -> 0.5)
|
||||
minFaceWeight 0.05;
|
||||
|
||||
//- Volume ratio of neighbouring cells (0 -> 1)
|
||||
minVolRatio 0.01;
|
||||
|
||||
//- Per triangle normal compared to that of preceding triangle. Must be >0
|
||||
// for Fluent compatibility
|
||||
minTriangleTwist -1;
|
||||
|
||||
|
||||
//- If >0 : preserve cells with all points on the surface if the
|
||||
// resulting volume after snapping (by approximation) is larger than
|
||||
// minVolCollapseRatio times old volume (i.e. not collapsed to flat cell).
|
||||
// If <0 : delete always.
|
||||
//minVolCollapseRatio 0.1;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,587 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object snappyHexMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Which of the steps to run
|
||||
castellatedMesh true;
|
||||
snap false;
|
||||
addLayers false;
|
||||
|
||||
|
||||
// Optional: single region surfaces get patch names according to
|
||||
// surface only. Multi-region surfaces get patch name
|
||||
// surface "_ "region. Default is true
|
||||
// singleRegionName false;
|
||||
|
||||
// Optional: avoid patch-face merging. Allows mesh to be used for
|
||||
// refinement/unrefinement
|
||||
// mergePatchFaces false; // default true
|
||||
|
||||
// Optional: preserve all generated patches. Default is to remove
|
||||
// zero-sized patches.
|
||||
// keepPatches true;
|
||||
|
||||
|
||||
// Geometry. Definition of all surfaces. All surfaces are of class
|
||||
// searchableSurface.
|
||||
// Surfaces are used
|
||||
// - to specify refinement for any mesh cell intersecting it
|
||||
// - to specify refinement for any mesh cell inside/outside/near
|
||||
// - to 'snap' the mesh boundary to the surface
|
||||
geometry
|
||||
{
|
||||
box_limit
|
||||
{
|
||||
type box;
|
||||
min (-1000 -1000 -1000);
|
||||
max (0.125 1000 1000);
|
||||
}
|
||||
cylinder_all
|
||||
{
|
||||
//- Radius 0.1m
|
||||
type triSurfaceMesh;
|
||||
file curvature-box.stl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Settings for the castellatedMesh generation.
|
||||
castellatedMeshControls
|
||||
{
|
||||
|
||||
// Refinement parameters
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// If local number of cells is >= maxLocalCells on any processor
|
||||
// switches from from refinement followed by balancing
|
||||
// (current method) to (weighted) balancing before refinement.
|
||||
maxLocalCells 1000000;
|
||||
|
||||
// Overall cell limit (approximately). Refinement will stop immediately
|
||||
// upon reaching this number so a refinement level might not complete.
|
||||
// Note that this is the number of cells before removing the part which
|
||||
// is not 'visible' from the keepPoint. The final number of cells might
|
||||
// actually be a lot less.
|
||||
maxGlobalCells 20000000;
|
||||
|
||||
// The surface refinement loop might spend lots of iterations refining just
|
||||
// a few cells. This setting will cause refinement to stop if
|
||||
// <= minRefinementCells cells are selected for refinement. Note: it will
|
||||
// at least do one iteration unless
|
||||
// a: the number of cells to refine is 0
|
||||
// b: minRefinementCells = -1. This is a special value indicating
|
||||
// no refinement.
|
||||
minRefinementCells 0;
|
||||
|
||||
// Allow a certain level of imbalance during refining
|
||||
// (since balancing is quite expensive)
|
||||
// Expressed as fraction of perfect balance (= overall number of cells /
|
||||
// nProcs). 0=balance always.
|
||||
maxLoadUnbalance 0.10;
|
||||
|
||||
// Number of buffer layers between different levels.
|
||||
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||
// refinement.
|
||||
nCellsBetweenLevels 4;
|
||||
|
||||
|
||||
// Explicit feature edge refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies a level for any cell intersected by explicitly provided
|
||||
// edges.
|
||||
// This is a featureEdgeMesh, read from constant/triSurface for now.
|
||||
// Specify 'levels' in the same way as the 'distance' mode in the
|
||||
// refinementRegions (see below). The old specification
|
||||
// level 2;
|
||||
// is equivalent to
|
||||
// levels ((0 2));
|
||||
|
||||
features
|
||||
(
|
||||
);
|
||||
|
||||
|
||||
// Surface based refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies two levels for every surface. The first is the minimum level,
|
||||
// every cell intersecting a surface gets refined up to the minimum level.
|
||||
// The second level is the maximum level. Cells that 'see' multiple
|
||||
// intersections where the intersections make an
|
||||
// angle > resolveFeatureAngle get refined up to the maximum level.
|
||||
|
||||
refinementSurfaces
|
||||
{
|
||||
cylinder_all
|
||||
{
|
||||
// Surface-wise min and max refinement level. max level is only used
|
||||
// for sharp angles (see 'resolveFeatureAngle')
|
||||
level (0 0);
|
||||
|
||||
// Additional refinement for regions of high curvature. Expressed
|
||||
// (bit similar to gapLevel) as:
|
||||
// - number of cells per radius of curvature. (usually 1 is
|
||||
// good enough)
|
||||
// - starting cell level? Not used at the moment.
|
||||
// - maximum cell level. This can be smaller or larger than the
|
||||
// max 'surface' level
|
||||
// - minumum curvature radius to ignore (expressed as a cell level).
|
||||
// This can be used to avoid detecting small sharp surface
|
||||
// features. Set to -1 to ignore.
|
||||
//
|
||||
// Sometimes you want more refinement than sharp features since
|
||||
// these can be done with feature edge snapping (so can leave
|
||||
// 'level (0 0)')
|
||||
curvatureLevel (10 0 10 -1);
|
||||
|
||||
// To trigger small feature refinement
|
||||
//gapLevel (1 0 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Feature angle:
|
||||
// - used if min and max refinement level of a surface differ
|
||||
// - used if feature snapping (see snapControls below) is used
|
||||
resolveFeatureAngle 45;
|
||||
|
||||
|
||||
// Region-wise refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies refinement level for cells in relation to a surface. One of
|
||||
// three modes
|
||||
// - distance. 'levels' specifies per distance to the surface the
|
||||
// wanted refinement level. The distances need to be specified in
|
||||
// increasing order.
|
||||
// - inside. 'levels' is only one entry and only the level is used. All
|
||||
// cells inside the surface get refined up to the level. The surface
|
||||
// needs to be closed for this to be possible.
|
||||
// - outside. Same but cells outside.
|
||||
|
||||
refinementRegions
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
// refinementRegions; the cell level now specifies the upper limit
|
||||
// for any cell. (a special setting is cell level -1 which will remove
|
||||
// any cells inside the region). Note that it does not override the
|
||||
// refinement constraints given by the nCellsBetweenLevels setting.
|
||||
limitRegions
|
||||
{
|
||||
box_limit
|
||||
{
|
||||
mode inside;
|
||||
|
||||
// Don't refine at all inside 'box_limit'
|
||||
levels ((10000 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mesh selection
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
// After refinement patches get added for all refinementSurfaces and
|
||||
// all cells intersecting the surfaces get put into these patches. The
|
||||
// section reachable from the location(s)InMesh is kept.
|
||||
// NOTE: This point should never be on a face, always inside a cell, even
|
||||
// after refinement.
|
||||
//
|
||||
// There are two different ways of specifying the regions to keep:
|
||||
// 1. a single locationInMesh. This is the unzoned part of the mesh.
|
||||
// All the 'zoned' surfaces are marked as such
|
||||
// in the refinementSurfaces with the faceZone and cellZone keywords.
|
||||
// It is illegal to have the locationInMesh inside a surface for which
|
||||
// a cellZone is specified.
|
||||
//
|
||||
// or
|
||||
//
|
||||
// 2. multiple locationsInMesh, with per location the name of the cellZone.
|
||||
// This uses walking to determine zones and automatically creates
|
||||
// faceZones on the outside of cellZones. The special name 'none' is
|
||||
// used to indicate the unzoned/background part of the mesh.
|
||||
|
||||
|
||||
// Ad 1. Specify a single location and how to treat faces inbetween
|
||||
// cellZones
|
||||
locationInMesh (0.101 0.101 0.101);
|
||||
|
||||
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||
// are only on the boundary of corresponding cellZones.
|
||||
// Not used if there are no faceZones. The behaviour has changed
|
||||
// with respect to previous versions:
|
||||
// true : all intersections with surface are put in faceZone
|
||||
// (same behaviour as before)
|
||||
// false : depending on the type of surface intersected:
|
||||
// - if intersecting surface has faceZone only (so no cellZone)
|
||||
// leave in faceZone (so behave as if set to true) (= changed
|
||||
// behaviour)
|
||||
// - if intersecting surface has faceZone and cellZone
|
||||
// remove if inbetween same cellZone or if on boundary
|
||||
// (same behaviour as before)
|
||||
allowFreeStandingZoneFaces true;
|
||||
|
||||
|
||||
|
||||
// 2. Specify multiple locations with optional cellZones for the
|
||||
// regions (use cellZone "none" to specify the unzoned cells)
|
||||
// FaceZones are automatically constructed from the
|
||||
// names of the cellZones: <cellZoneA> _to_ <cellZoneB>
|
||||
// where the cellZoneA is the lowest numbered cellZone (non-cellZone
|
||||
// cells are in a special region called "none" which is always
|
||||
// last).
|
||||
|
||||
|
||||
|
||||
|
||||
// Optional locations that should not be reachable from
|
||||
// location(s)InMesh
|
||||
// locationsOutsideMesh ((100 100 100));
|
||||
|
||||
// Optional: do not remove cells likely to give snapping problems
|
||||
// handleSnapProblems false;
|
||||
|
||||
// Optional: switch off topological test for cells to-be-squashed
|
||||
// and use geometric test instead
|
||||
//useTopologicalSnapDetection false;
|
||||
|
||||
// Optional: do not refine surface cells with opposite faces of
|
||||
// differing refinement levels
|
||||
//interfaceRefine false;
|
||||
|
||||
// Optional: use an erosion instead of region assignment to allocate
|
||||
// left-over cells to the background region (i.e. make cellZones
|
||||
// consistent with the intersections of the surface).
|
||||
// Erosion is specified as a number of erosion iterations.
|
||||
// Erosion has less chance of bleeding and changing the zone
|
||||
// for a complete region.
|
||||
//nCellZoneErodeIter 2;
|
||||
}
|
||||
|
||||
// Settings for the snapping.
|
||||
snapControls
|
||||
{
|
||||
// Number of patch smoothing iterations before finding correspondence
|
||||
// to surface
|
||||
nSmoothPatch 3;
|
||||
|
||||
// Optional: number of smoothing iterations for internal points on
|
||||
// refinement interfaces. This will reduce non-orthogonality on
|
||||
// refinement interfaces.
|
||||
//nSmoothInternal $nSmoothPatch;
|
||||
|
||||
// Maximum relative distance for points to be attracted by surface.
|
||||
// True distance is this factor times local maximum edge length.
|
||||
tolerance 1.0;
|
||||
|
||||
// Number of mesh displacement relaxation iterations.
|
||||
nSolveIter 30;
|
||||
|
||||
// Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
// (wip) disable snapping to opposite near surfaces (revert to 22x
|
||||
// behaviour)
|
||||
// detectNearSurfacesSnap false;
|
||||
|
||||
|
||||
// Feature snapping
|
||||
|
||||
// Number of feature edge snapping iterations.
|
||||
// Leave out altogether to disable.
|
||||
nFeatureSnapIter 10;
|
||||
|
||||
// Detect (geometric only) features by sampling the surface
|
||||
// (default=false).
|
||||
implicitFeatureSnap false;
|
||||
|
||||
// Use castellatedMeshControls::features (default = true)
|
||||
explicitFeatureSnap true;
|
||||
|
||||
// Detect features between multiple surfaces
|
||||
// (only for explicitFeatureSnap, default = false)
|
||||
multiRegionFeatureSnap false;
|
||||
|
||||
|
||||
//- When to run face splitting (never at first iteration, always
|
||||
// at last iteration). Is interval. Default -1 (disabled)
|
||||
//nFaceSplitInterval 5;
|
||||
|
||||
|
||||
// (wip) Optional for explicit feature snapping:
|
||||
//- Detect baffle edges. Default is true.
|
||||
//detectBaffles false;
|
||||
//- On any faces where points are on multiple regions (see
|
||||
// multiRegionFeatureSnap) have the other points follow these points
|
||||
// instead of having their own independent movement, i.e. have snapping
|
||||
// to multi-region edges/points take priority. This might aid snapping
|
||||
// to sharp edges that are also region edges. The default is false.
|
||||
//releasePoints true;
|
||||
//- Walk along feature edges, adding missing ones. Default is true.
|
||||
//stringFeatures false;
|
||||
//- If diagonal attraction also attract other face points. Default is
|
||||
// false
|
||||
//avoidDiagonal true;
|
||||
//- When splitting what concave faces to leave intact. Default is 45
|
||||
// degrees.
|
||||
//concaveAngle 30;
|
||||
//- When splitting the minimum area ratio of faces. If face split
|
||||
// causes ratio of area less than this do not split. Default is 0.3
|
||||
//minAreaRatio 0.3;
|
||||
//- Attract points only to the surface they originate from. Default
|
||||
// false. This can improve snapping of intersecting surfaces.
|
||||
strictRegionSnap true;
|
||||
}
|
||||
|
||||
// Settings for the layer addition.
|
||||
addLayersControls
|
||||
{
|
||||
// Are the thickness parameters below relative to the undistorted
|
||||
// size of the refined cell outside layer (true) or absolute sizes (false).
|
||||
relativeSizes true;
|
||||
|
||||
// Layer thickness specification. This can be specified in one of following
|
||||
// ways:
|
||||
// - expansionRatio and finalLayerThickness (cell nearest internal mesh)
|
||||
// - expansionRatio and firstLayerThickness (cell on surface)
|
||||
// - overall thickness and firstLayerThickness
|
||||
// - overall thickness and finalLayerThickness
|
||||
// - overall thickness and expansionRatio
|
||||
//
|
||||
// Note: the mode thus selected is global, i.e. one cannot override the
|
||||
// mode on a per-patch basis (only the values can be overridden)
|
||||
|
||||
// Expansion factor for layer mesh
|
||||
expansionRatio 1.5;
|
||||
|
||||
// Wanted thickness of the layer furthest away from the wall.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
finalLayerThickness 0.3;
|
||||
|
||||
// Wanted thickness of the layer next to the wall.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
//firstLayerThickness 0.3;
|
||||
|
||||
// Wanted overall thickness of layers.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
//thickness 0.5
|
||||
|
||||
|
||||
// Minimum overall thickness of total layers. If for any reason layer
|
||||
// cannot be above minThickness do not add layer.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer..
|
||||
minThickness 0.1;
|
||||
|
||||
|
||||
// Per final patch or faceZone (so not geometry!) the layer information
|
||||
// Note: This behaviour changed after 21x. Any non-mentioned patches
|
||||
// now slide unless:
|
||||
// - nSurfaceLayers is explicitly mentioned to be 0.
|
||||
// - angle to nearest surface < slipFeatureAngle (see below)
|
||||
layers
|
||||
{
|
||||
"internalFace.*" {nSurfaceLayers 20; }
|
||||
aerofoil
|
||||
{
|
||||
nSurfaceLayers 20;
|
||||
}
|
||||
}
|
||||
|
||||
// If points get not extruded do nGrow layers of connected faces that are
|
||||
// also not grown. This helps convergence of the layer addition process
|
||||
// close to features.
|
||||
// Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x)
|
||||
nGrow -1;
|
||||
|
||||
// Advanced settings
|
||||
|
||||
|
||||
// Static analysis of starting mesh
|
||||
|
||||
// When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||
// are perpendicular. Note: was not working correctly < 1806
|
||||
featureAngle 180;
|
||||
|
||||
// When to merge patch faces. Default is featureAngle. Useful when
|
||||
// featureAngle is large.
|
||||
//mergePatchFacesAngle 45;
|
||||
|
||||
// Stop layer growth on highly warped cells
|
||||
maxFaceThicknessRatio 1000;//0.5;
|
||||
|
||||
|
||||
// Patch displacement
|
||||
|
||||
// Number of smoothing iterations of surface normals
|
||||
nSmoothSurfaceNormals 1;
|
||||
|
||||
// Smooth layer thickness over surface patches
|
||||
nSmoothThickness 10;
|
||||
|
||||
|
||||
|
||||
// Choice of mesh shrinking algorithm
|
||||
|
||||
// Optional mesh shrinking algorithm (default is displacementMedialAxis)
|
||||
// The displacementMotionSolver is a wrapper around the displacement
|
||||
// motion solvers. It needs specification of the solver to use and
|
||||
// its control dictionary.
|
||||
//meshShrinker displacementMotionSolver;
|
||||
//solver displacementLaplacian;
|
||||
//displacementLaplacianCoeffs
|
||||
//{
|
||||
// diffusivity quadratic inverseDistance
|
||||
// (
|
||||
// sphere.stl_firstSolid
|
||||
// maxY
|
||||
// );
|
||||
//}
|
||||
// Note that e.g. displacementLaplacian needs entries in
|
||||
// fvSchemes, fvSolution. Also specify a minIter > 1 when solving
|
||||
// cellDisplacement since otherwise solution might not be sufficiently
|
||||
// accurate on points.
|
||||
|
||||
|
||||
// Medial axis analysis (for use with default displacementMedialAxis)
|
||||
|
||||
// Angle used to pick up medial axis points
|
||||
// Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130
|
||||
// in 1.7.x.
|
||||
minMedialAxisAngle 90;
|
||||
|
||||
// Reduce layer growth where ratio thickness to medial
|
||||
// distance is large
|
||||
maxThicknessToMedialRatio 0.3;
|
||||
|
||||
// Number of smoothing iterations of interior mesh movement direction
|
||||
nSmoothNormals 3;
|
||||
|
||||
// Optional: limit the number of steps walking away from the surface.
|
||||
// Default is unlimited.
|
||||
//nMedialAxisIter 10;
|
||||
|
||||
// Optional: smooth displacement after medial axis determination.
|
||||
// default is 0.
|
||||
//nSmoothDisplacement 90;
|
||||
|
||||
// (wip)Optional: do not extrude any point where
|
||||
// (false) : all surrounding faces are not fully extruded
|
||||
// (true) : all surrounding points are not extruded
|
||||
// Default is false.
|
||||
//detectExtrusionIsland true;
|
||||
|
||||
// Optional: do not extrude around sharp edges if both faces are not
|
||||
// fully extruded i.e. if one of the faces on either side would
|
||||
// become a wedge.
|
||||
// Default is 0.5*featureAngle. Set to -180 always attempt extrusion
|
||||
//layerTerminationAngle 25;
|
||||
|
||||
// Optional: disable shrinking of edges that have one (or two) points
|
||||
// on an extruded patch.
|
||||
// Default is false to enable single/two cell thick channels to still
|
||||
// have layers. In <=1806 this was true by default. On larger gaps it
|
||||
// should have no effect.
|
||||
//disableWallEdges true;
|
||||
|
||||
// Optional: at non-patched sides allow mesh to slip if extrusion
|
||||
// direction makes angle larger than slipFeatureAngle. Default is
|
||||
// 0.5*featureAngle.
|
||||
slipFeatureAngle 10;
|
||||
|
||||
// Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
|
||||
// Mesh shrinking
|
||||
|
||||
// Create buffer region for new layer terminations, i.e. gradually
|
||||
// step down number of layers. Set to <0 to terminate layer in one go.
|
||||
nBufferCellsNoExtrude 0;
|
||||
|
||||
// Overall max number of layer addition iterations. The mesher will
|
||||
// exit if it reaches this number of iterations; possibly with an
|
||||
// illegal mesh.
|
||||
nLayerIter 50;
|
||||
|
||||
// Max number of iterations after which relaxed meshQuality controls
|
||||
// get used. Up to nRelaxedIter it uses the settings in
|
||||
// meshQualityControls,
|
||||
// after nRelaxedIter it uses the values in
|
||||
// meshQualityControls::relaxed.
|
||||
nRelaxedIter 0;
|
||||
|
||||
// Additional reporting: if there are just a few faces where there
|
||||
// are mesh errors (after adding the layers) print their face centres.
|
||||
// This helps in tracking down problematic mesh areas.
|
||||
//additionalReporting true;
|
||||
}
|
||||
|
||||
// Generic mesh quality settings. At any undoable phase these determine
|
||||
// where to undo.
|
||||
meshQualityControls
|
||||
{
|
||||
// Specify mesh quality constraints in separate dictionary so can
|
||||
// be reused (e.g. checkMesh -meshQuality)
|
||||
#include "meshQualityDict"
|
||||
|
||||
minDeterminant 1e-8;
|
||||
|
||||
// Optional : some meshing phases allow usage of relaxed rules.
|
||||
// See e.g. addLayersControls::nRelaxedIter.
|
||||
relaxed
|
||||
{
|
||||
// Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 75;
|
||||
minTetQuality -1e30;
|
||||
minTwist -1;
|
||||
}
|
||||
|
||||
|
||||
// Advanced
|
||||
|
||||
// Number of error distribution iterations
|
||||
nSmoothScale 4;
|
||||
// amount to scale back displacement at error points
|
||||
errorReduction 0.75;
|
||||
}
|
||||
|
||||
|
||||
// Debug flags
|
||||
//debugFlags
|
||||
//(
|
||||
// mesh // write intermediate meshes
|
||||
//);
|
||||
|
||||
|
||||
//// Format for writing lines. E.g. leak path. Default is vtk format.
|
||||
//setFormat ensight;
|
||||
|
||||
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
|
||||
// Note: the write tolerance needs to be higher than this.
|
||||
mergeTolerance 1e-6;
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,622 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object snappyHexMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Which of the steps to run
|
||||
castellatedMesh true;
|
||||
snap false;
|
||||
addLayers false;
|
||||
|
||||
|
||||
// Optional: single region surfaces get patch names according to
|
||||
// surface only. Multi-region surfaces get patch name
|
||||
// surface "_ "region. Default is true
|
||||
// singleRegionName false;
|
||||
|
||||
// Optional: avoid patch-face merging. Allows mesh to be used for
|
||||
// refinement/unrefinement
|
||||
// mergePatchFaces false; // default true
|
||||
|
||||
// Optional: preserve all generated patches. Default is to remove
|
||||
// zero-sized patches.
|
||||
// keepPatches true;
|
||||
|
||||
|
||||
// Geometry. Definition of all surfaces. All surfaces are of class
|
||||
// searchableSurface.
|
||||
// Surfaces are used
|
||||
// - to specify refinement for any mesh cell intersecting it
|
||||
// - to specify refinement for any mesh cell inside/outside/near
|
||||
// - to 'snap' the mesh boundary to the surface
|
||||
geometry
|
||||
{
|
||||
all
|
||||
{
|
||||
type box;
|
||||
min (-1000 -1000 -1000);
|
||||
max (1000 1000 1000);
|
||||
}
|
||||
cylinder_all
|
||||
{
|
||||
//- Radius 0.1m
|
||||
type triSurfaceMesh;
|
||||
file curvature-box.stl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Settings for the castellatedMesh generation.
|
||||
castellatedMeshControls
|
||||
{
|
||||
|
||||
// Refinement parameters
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// If local number of cells is >= maxLocalCells on any processor
|
||||
// switches from from refinement followed by balancing
|
||||
// (current method) to (weighted) balancing before refinement.
|
||||
maxLocalCells 1000000;
|
||||
|
||||
// Overall cell limit (approximately). Refinement will stop immediately
|
||||
// upon reaching this number so a refinement level might not complete.
|
||||
// Note that this is the number of cells before removing the part which
|
||||
// is not 'visible' from the keepPoint. The final number of cells might
|
||||
// actually be a lot less.
|
||||
maxGlobalCells 20000000;
|
||||
|
||||
// The surface refinement loop might spend lots of iterations refining just
|
||||
// a few cells. This setting will cause refinement to stop if
|
||||
// <= minRefinementCells cells are selected for refinement. Note: it will
|
||||
// at least do one iteration unless
|
||||
// a: the number of cells to refine is 0
|
||||
// b: minRefinementCells = -1. This is a special value indicating
|
||||
// no refinement.
|
||||
minRefinementCells 0;
|
||||
|
||||
// Allow a certain level of imbalance during refining
|
||||
// (since balancing is quite expensive)
|
||||
// Expressed as fraction of perfect balance (= overall number of cells /
|
||||
// nProcs). 0=balance always.
|
||||
maxLoadUnbalance 0.10;
|
||||
|
||||
// Number of buffer layers between different levels.
|
||||
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||
// refinement.
|
||||
nCellsBetweenLevels 4;
|
||||
|
||||
|
||||
// Explicit feature edge refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies a level for any cell intersected by explicitly provided
|
||||
// edges.
|
||||
// This is a featureEdgeMesh, read from constant/triSurface for now.
|
||||
// Specify 'levels' in the same way as the 'distance' mode in the
|
||||
// refinementRegions (see below). The old specification
|
||||
// level 2;
|
||||
// is equivalent to
|
||||
// levels ((0 2));
|
||||
|
||||
features
|
||||
(
|
||||
);
|
||||
|
||||
|
||||
// Surface based refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies two levels for every surface. The first is the minimum level,
|
||||
// every cell intersecting a surface gets refined up to the minimum level.
|
||||
// The second level is the maximum level. Cells that 'see' multiple
|
||||
// intersections where the intersections make an
|
||||
// angle > resolveFeatureAngle get refined up to the maximum level.
|
||||
|
||||
refinementSurfaces
|
||||
{
|
||||
cylinder_all
|
||||
{
|
||||
// Surface-wise min and max refinement level. max level is only used
|
||||
// for sharp angles (see 'resolveFeatureAngle')
|
||||
level (0 0);
|
||||
|
||||
// Additional refinement for regions of high curvature. Expressed
|
||||
// (bit similar to gapLevel) as:
|
||||
// - number of cells per radius of curvature. (usually 1 is
|
||||
// good enough)
|
||||
// - starting cell level? Not used at the moment.
|
||||
// - maximum cell level. This can be smaller or larger than the
|
||||
// max 'surface' level
|
||||
// - minumum curvature radius to ignore (expressed as a cell level).
|
||||
// This can be used to avoid detecting small sharp surface
|
||||
// features. Set to -1 to ignore.
|
||||
//
|
||||
// Sometimes you want more refinement than sharp features since
|
||||
// these can be done with feature edge snapping (so can leave
|
||||
// 'level (0 0)')
|
||||
curvatureLevel (10 0 10 -1);
|
||||
|
||||
// To trigger small feature refinement
|
||||
//gapLevel (1 0 1);
|
||||
}
|
||||
}
|
||||
|
||||
//- looking at triangle mesh itself? E.g. cables with 3 triangles do not need
|
||||
//refinement.
|
||||
//- what about 90 degree angles. Do NOT refine.
|
||||
//Refine always. With chamfer: currently not
|
||||
// detected. So curvature refinement is just extension of resolveFeatureAngle
|
||||
// mechanism.
|
||||
//- disconnected surfaces. Currently not needed. Can also only be on single patch.
|
||||
//- triangle clouds. Currently not needed.
|
||||
//- limited to volume as well (like gapLevel). Not currently. Happy with either
|
||||
// - global (like resolveFeatureAngle)
|
||||
// - per patch (like resolveFeatureAngle)
|
||||
|
||||
// Feature angle:
|
||||
// - used if min and max refinement level of a surface differ
|
||||
// - used if feature snapping (see snapControls below) is used
|
||||
resolveFeatureAngle 45;
|
||||
|
||||
|
||||
// Region-wise refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies refinement level for cells in relation to a surface. One of
|
||||
// three modes
|
||||
// - distance. 'levels' specifies per distance to the surface the
|
||||
// wanted refinement level. The distances need to be specified in
|
||||
// increasing order.
|
||||
// - inside. 'levels' is only one entry and only the level is used. All
|
||||
// cells inside the surface get refined up to the level. The surface
|
||||
// needs to be closed for this to be possible.
|
||||
// - outside. Same but cells outside.
|
||||
|
||||
refinementRegions
|
||||
{
|
||||
all
|
||||
{
|
||||
mode inside;
|
||||
|
||||
// Dummy base level
|
||||
levels ((10000 0));
|
||||
|
||||
// If cells
|
||||
// - have level 0..9
|
||||
// - and are in a gap < 3 cell sizes across
|
||||
// - with the gap on the inside ('inside'), outside ('outside')
|
||||
// or both ('mixed') of the surface
|
||||
// refine them
|
||||
//gapLevel (4 0 10);
|
||||
//gapMode outside;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
// refinementRegions; the cell level now specifies the upper limit
|
||||
// for any cell. (a special setting is cell level -1 which will remove
|
||||
// any cells inside the region). Note that it does not override the
|
||||
// refinement constraints given by the nCellsBetweenLevels setting.
|
||||
limitRegions
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Mesh selection
|
||||
// ~~~~~~~~~~~~~~
|
||||
|
||||
// After refinement patches get added for all refinementSurfaces and
|
||||
// all cells intersecting the surfaces get put into these patches. The
|
||||
// section reachable from the location(s)InMesh is kept.
|
||||
// NOTE: This point should never be on a face, always inside a cell, even
|
||||
// after refinement.
|
||||
//
|
||||
// There are two different ways of specifying the regions to keep:
|
||||
// 1. a single locationInMesh. This is the unzoned part of the mesh.
|
||||
// All the 'zoned' surfaces are marked as such
|
||||
// in the refinementSurfaces with the faceZone and cellZone keywords.
|
||||
// It is illegal to have the locationInMesh inside a surface for which
|
||||
// a cellZone is specified.
|
||||
//
|
||||
// or
|
||||
//
|
||||
// 2. multiple locationsInMesh, with per location the name of the cellZone.
|
||||
// This uses walking to determine zones and automatically creates
|
||||
// faceZones on the outside of cellZones. The special name 'none' is
|
||||
// used to indicate the unzoned/background part of the mesh.
|
||||
|
||||
|
||||
// Ad 1. Specify a single location and how to treat faces inbetween
|
||||
// cellZones
|
||||
locationInMesh (0.101 0.101 0.101);
|
||||
|
||||
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||
// are only on the boundary of corresponding cellZones.
|
||||
// Not used if there are no faceZones. The behaviour has changed
|
||||
// with respect to previous versions:
|
||||
// true : all intersections with surface are put in faceZone
|
||||
// (same behaviour as before)
|
||||
// false : depending on the type of surface intersected:
|
||||
// - if intersecting surface has faceZone only (so no cellZone)
|
||||
// leave in faceZone (so behave as if set to true) (= changed
|
||||
// behaviour)
|
||||
// - if intersecting surface has faceZone and cellZone
|
||||
// remove if inbetween same cellZone or if on boundary
|
||||
// (same behaviour as before)
|
||||
allowFreeStandingZoneFaces true;
|
||||
|
||||
|
||||
|
||||
// 2. Specify multiple locations with optional cellZones for the
|
||||
// regions (use cellZone "none" to specify the unzoned cells)
|
||||
// FaceZones are automatically constructed from the
|
||||
// names of the cellZones: <cellZoneA> _to_ <cellZoneB>
|
||||
// where the cellZoneA is the lowest numbered cellZone (non-cellZone
|
||||
// cells are in a special region called "none" which is always
|
||||
// last).
|
||||
|
||||
|
||||
|
||||
|
||||
// Optional locations that should not be reachable from
|
||||
// location(s)InMesh
|
||||
// locationsOutsideMesh ((100 100 100));
|
||||
|
||||
// Optional: do not remove cells likely to give snapping problems
|
||||
// handleSnapProblems false;
|
||||
|
||||
// Optional: switch off topological test for cells to-be-squashed
|
||||
// and use geometric test instead
|
||||
//useTopologicalSnapDetection false;
|
||||
|
||||
// Optional: do not refine surface cells with opposite faces of
|
||||
// differing refinement levels
|
||||
//interfaceRefine false;
|
||||
|
||||
// Optional: use an erosion instead of region assignment to allocate
|
||||
// left-over cells to the background region (i.e. make cellZones
|
||||
// consistent with the intersections of the surface).
|
||||
// Erosion is specified as a number of erosion iterations.
|
||||
// Erosion has less chance of bleeding and changing the zone
|
||||
// for a complete region.
|
||||
//nCellZoneErodeIter 2;
|
||||
}
|
||||
|
||||
// Settings for the snapping.
|
||||
snapControls
|
||||
{
|
||||
// Number of patch smoothing iterations before finding correspondence
|
||||
// to surface
|
||||
nSmoothPatch 3;
|
||||
|
||||
// Optional: number of smoothing iterations for internal points on
|
||||
// refinement interfaces. This will reduce non-orthogonality on
|
||||
// refinement interfaces.
|
||||
//nSmoothInternal $nSmoothPatch;
|
||||
|
||||
// Maximum relative distance for points to be attracted by surface.
|
||||
// True distance is this factor times local maximum edge length.
|
||||
tolerance 1.0;
|
||||
|
||||
// Number of mesh displacement relaxation iterations.
|
||||
nSolveIter 30;
|
||||
|
||||
// Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
// (wip) disable snapping to opposite near surfaces (revert to 22x
|
||||
// behaviour)
|
||||
// detectNearSurfacesSnap false;
|
||||
|
||||
|
||||
// Feature snapping
|
||||
|
||||
// Number of feature edge snapping iterations.
|
||||
// Leave out altogether to disable.
|
||||
nFeatureSnapIter 10;
|
||||
|
||||
// Detect (geometric only) features by sampling the surface
|
||||
// (default=false).
|
||||
implicitFeatureSnap false;
|
||||
|
||||
// Use castellatedMeshControls::features (default = true)
|
||||
explicitFeatureSnap true;
|
||||
|
||||
// Detect features between multiple surfaces
|
||||
// (only for explicitFeatureSnap, default = false)
|
||||
multiRegionFeatureSnap false;
|
||||
|
||||
|
||||
//- When to run face splitting (never at first iteration, always
|
||||
// at last iteration). Is interval. Default -1 (disabled)
|
||||
//nFaceSplitInterval 5;
|
||||
|
||||
|
||||
// (wip) Optional for explicit feature snapping:
|
||||
//- Detect baffle edges. Default is true.
|
||||
//detectBaffles false;
|
||||
//- On any faces where points are on multiple regions (see
|
||||
// multiRegionFeatureSnap) have the other points follow these points
|
||||
// instead of having their own independent movement, i.e. have snapping
|
||||
// to multi-region edges/points take priority. This might aid snapping
|
||||
// to sharp edges that are also region edges. The default is false.
|
||||
//releasePoints true;
|
||||
//- Walk along feature edges, adding missing ones. Default is true.
|
||||
//stringFeatures false;
|
||||
//- If diagonal attraction also attract other face points. Default is
|
||||
// false
|
||||
//avoidDiagonal true;
|
||||
//- When splitting what concave faces to leave intact. Default is 45
|
||||
// degrees.
|
||||
//concaveAngle 30;
|
||||
//- When splitting the minimum area ratio of faces. If face split
|
||||
// causes ratio of area less than this do not split. Default is 0.3
|
||||
//minAreaRatio 0.3;
|
||||
//- Attract points only to the surface they originate from. Default
|
||||
// false. This can improve snapping of intersecting surfaces.
|
||||
strictRegionSnap true;
|
||||
}
|
||||
|
||||
// Settings for the layer addition.
|
||||
addLayersControls
|
||||
{
|
||||
// Are the thickness parameters below relative to the undistorted
|
||||
// size of the refined cell outside layer (true) or absolute sizes (false).
|
||||
relativeSizes true;
|
||||
|
||||
// Layer thickness specification. This can be specified in one of following
|
||||
// ways:
|
||||
// - expansionRatio and finalLayerThickness (cell nearest internal mesh)
|
||||
// - expansionRatio and firstLayerThickness (cell on surface)
|
||||
// - overall thickness and firstLayerThickness
|
||||
// - overall thickness and finalLayerThickness
|
||||
// - overall thickness and expansionRatio
|
||||
//
|
||||
// Note: the mode thus selected is global, i.e. one cannot override the
|
||||
// mode on a per-patch basis (only the values can be overridden)
|
||||
|
||||
// Expansion factor for layer mesh
|
||||
expansionRatio 1.5;
|
||||
|
||||
// Wanted thickness of the layer furthest away from the wall.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
finalLayerThickness 0.3;
|
||||
|
||||
// Wanted thickness of the layer next to the wall.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
//firstLayerThickness 0.3;
|
||||
|
||||
// Wanted overall thickness of layers.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer.
|
||||
//thickness 0.5
|
||||
|
||||
|
||||
// Minimum overall thickness of total layers. If for any reason layer
|
||||
// cannot be above minThickness do not add layer.
|
||||
// If relativeSizes this is relative to undistorted size of cell
|
||||
// outside layer..
|
||||
minThickness 0.1;
|
||||
|
||||
|
||||
// Per final patch or faceZone (so not geometry!) the layer information
|
||||
// Note: This behaviour changed after 21x. Any non-mentioned patches
|
||||
// now slide unless:
|
||||
// - nSurfaceLayers is explicitly mentioned to be 0.
|
||||
// - angle to nearest surface < slipFeatureAngle (see below)
|
||||
layers
|
||||
{
|
||||
"internalFace.*" {nSurfaceLayers 20; }
|
||||
aerofoil
|
||||
{
|
||||
nSurfaceLayers 20;
|
||||
}
|
||||
}
|
||||
|
||||
// If points get not extruded do nGrow layers of connected faces that are
|
||||
// also not grown. This helps convergence of the layer addition process
|
||||
// close to features.
|
||||
// Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x)
|
||||
nGrow -1;
|
||||
|
||||
// Advanced settings
|
||||
|
||||
|
||||
// Static analysis of starting mesh
|
||||
|
||||
// When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||
// are perpendicular. Note: was not working correctly < 1806
|
||||
featureAngle 180;
|
||||
|
||||
// When to merge patch faces. Default is featureAngle. Useful when
|
||||
// featureAngle is large.
|
||||
//mergePatchFacesAngle 45;
|
||||
|
||||
// Stop layer growth on highly warped cells
|
||||
maxFaceThicknessRatio 1000;//0.5;
|
||||
|
||||
|
||||
// Patch displacement
|
||||
|
||||
// Number of smoothing iterations of surface normals
|
||||
nSmoothSurfaceNormals 1;
|
||||
|
||||
// Smooth layer thickness over surface patches
|
||||
nSmoothThickness 10;
|
||||
|
||||
|
||||
|
||||
// Choice of mesh shrinking algorithm
|
||||
|
||||
// Optional mesh shrinking algorithm (default is displacementMedialAxis)
|
||||
// The displacementMotionSolver is a wrapper around the displacement
|
||||
// motion solvers. It needs specification of the solver to use and
|
||||
// its control dictionary.
|
||||
//meshShrinker displacementMotionSolver;
|
||||
//solver displacementLaplacian;
|
||||
//displacementLaplacianCoeffs
|
||||
//{
|
||||
// diffusivity quadratic inverseDistance
|
||||
// (
|
||||
// sphere.stl_firstSolid
|
||||
// maxY
|
||||
// );
|
||||
//}
|
||||
// Note that e.g. displacementLaplacian needs entries in
|
||||
// fvSchemes, fvSolution. Also specify a minIter > 1 when solving
|
||||
// cellDisplacement since otherwise solution might not be sufficiently
|
||||
// accurate on points.
|
||||
|
||||
|
||||
// Medial axis analysis (for use with default displacementMedialAxis)
|
||||
|
||||
// Angle used to pick up medial axis points
|
||||
// Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130
|
||||
// in 1.7.x.
|
||||
minMedialAxisAngle 90;
|
||||
|
||||
// Reduce layer growth where ratio thickness to medial
|
||||
// distance is large
|
||||
maxThicknessToMedialRatio 0.3;
|
||||
|
||||
// Number of smoothing iterations of interior mesh movement direction
|
||||
nSmoothNormals 3;
|
||||
|
||||
// Optional: limit the number of steps walking away from the surface.
|
||||
// Default is unlimited.
|
||||
//nMedialAxisIter 10;
|
||||
|
||||
// Optional: smooth displacement after medial axis determination.
|
||||
// default is 0.
|
||||
//nSmoothDisplacement 90;
|
||||
|
||||
// (wip)Optional: do not extrude any point where
|
||||
// (false) : all surrounding faces are not fully extruded
|
||||
// (true) : all surrounding points are not extruded
|
||||
// Default is false.
|
||||
//detectExtrusionIsland true;
|
||||
|
||||
// Optional: do not extrude around sharp edges if both faces are not
|
||||
// fully extruded i.e. if one of the faces on either side would
|
||||
// become a wedge.
|
||||
// Default is 0.5*featureAngle. Set to -180 always attempt extrusion
|
||||
//layerTerminationAngle 25;
|
||||
|
||||
// Optional: disable shrinking of edges that have one (or two) points
|
||||
// on an extruded patch.
|
||||
// Default is false to enable single/two cell thick channels to still
|
||||
// have layers. In <=1806 this was true by default. On larger gaps it
|
||||
// should have no effect.
|
||||
//disableWallEdges true;
|
||||
|
||||
// Optional: at non-patched sides allow mesh to slip if extrusion
|
||||
// direction makes angle larger than slipFeatureAngle. Default is
|
||||
// 0.5*featureAngle.
|
||||
slipFeatureAngle 10;
|
||||
|
||||
// Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
|
||||
// Mesh shrinking
|
||||
|
||||
// Create buffer region for new layer terminations, i.e. gradually
|
||||
// step down number of layers. Set to <0 to terminate layer in one go.
|
||||
nBufferCellsNoExtrude 0;
|
||||
|
||||
// Overall max number of layer addition iterations. The mesher will
|
||||
// exit if it reaches this number of iterations; possibly with an
|
||||
// illegal mesh.
|
||||
nLayerIter 50;
|
||||
|
||||
// Max number of iterations after which relaxed meshQuality controls
|
||||
// get used. Up to nRelaxedIter it uses the settings in
|
||||
// meshQualityControls,
|
||||
// after nRelaxedIter it uses the values in
|
||||
// meshQualityControls::relaxed.
|
||||
nRelaxedIter 0;
|
||||
|
||||
// Additional reporting: if there are just a few faces where there
|
||||
// are mesh errors (after adding the layers) print their face centres.
|
||||
// This helps in tracking down problematic mesh areas.
|
||||
//additionalReporting true;
|
||||
}
|
||||
|
||||
// Generic mesh quality settings. At any undoable phase these determine
|
||||
// where to undo.
|
||||
meshQualityControls
|
||||
{
|
||||
// Specify mesh quality constraints in separate dictionary so can
|
||||
// be reused (e.g. checkMesh -meshQuality)
|
||||
#include "meshQualityDict"
|
||||
|
||||
minDeterminant 1e-8;
|
||||
|
||||
// Optional : some meshing phases allow usage of relaxed rules.
|
||||
// See e.g. addLayersControls::nRelaxedIter.
|
||||
relaxed
|
||||
{
|
||||
// Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||
maxNonOrtho 75;
|
||||
minTetQuality -1e30;
|
||||
minTwist -1;
|
||||
}
|
||||
|
||||
|
||||
// Advanced
|
||||
|
||||
// Number of error distribution iterations
|
||||
nSmoothScale 4;
|
||||
// amount to scale back displacement at error points
|
||||
errorReduction 0.75;
|
||||
}
|
||||
|
||||
// Advanced
|
||||
|
||||
// Debug flags
|
||||
debugFlags
|
||||
(
|
||||
// mesh // write intermediate meshes
|
||||
// intersections // write current mesh intersections as .obj files
|
||||
// featureSeeds // write information about explicit feature edge
|
||||
// // refinement
|
||||
// attraction // write attraction as .obj files
|
||||
// layerInfo // write information about layers
|
||||
);
|
||||
//
|
||||
//// Write flags
|
||||
//writeFlags
|
||||
//(
|
||||
// scalarLevels // write volScalarField with cellLevel for postprocessing
|
||||
// layerSets // write cellSets, faceSets of faces in layer
|
||||
// layerFields // write volScalarField for layer coverage
|
||||
//);
|
||||
|
||||
|
||||
//// Format for writing lines. E.g. leak path. Default is vtk format.
|
||||
//setFormat ensight;
|
||||
|
||||
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
|
||||
// Note: the write tolerance needs to be higher than this.
|
||||
mergeTolerance 1e-6;
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,60 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object surfaceFeatureExtractDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- temp dictionary with common settings
|
||||
_surfaceExtract
|
||||
{
|
||||
// Extract raw features (none | extractFromFile | extractFromSurface)
|
||||
extractionMethod extractFromSurface;
|
||||
|
||||
// Mark edges whose adjacent surface normals are at an angle less
|
||||
// than includedAngle as features
|
||||
// - 0 : selects no edges
|
||||
// - 180: selects all edges
|
||||
includedAngle 120;
|
||||
|
||||
// Output surface curvature
|
||||
curvature true;
|
||||
|
||||
// Do not mark region edges
|
||||
geometricTestOnly yes;
|
||||
|
||||
// Generate additional intersection features (none | self | region)
|
||||
intersectionMethod none;
|
||||
|
||||
// Tolerance for surface intersections
|
||||
// tolerance 1e-3;
|
||||
|
||||
// Output options:
|
||||
|
||||
// Write features to obj format for postprocessing
|
||||
writeObj yes;
|
||||
|
||||
// Write closeness/curvature/proximity fields as VTK for postprocessing
|
||||
writeVTK yes;
|
||||
}
|
||||
|
||||
|
||||
curvature-box.stl
|
||||
{
|
||||
$_surfaceExtract;
|
||||
}
|
||||
|
||||
|
||||
//- Remove temp from dictionary so it doesn't think it is a surface
|
||||
#remove _surfaceExtract
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user