mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
snappyHexMesh : refine based on curvature
This commit is contained in:
@ -1342,6 +1342,17 @@ int main(int argc, char *argv[])
|
|||||||
const snapParameters snapParams(snapDict, dryRun);
|
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
|
// Add all the cellZones and faceZones
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@ -230,6 +230,21 @@ castellatedMeshControls
|
|||||||
// outside locations. Default is only after all refinement has
|
// outside locations. Default is only after all refinement has
|
||||||
// been done.
|
// been done.
|
||||||
//leakLevel 10;
|
//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
|
label& nRefine
|
||||||
) const;
|
) 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
|
//- Helper: count number of normals1 that are in normals2
|
||||||
label countMatches
|
label countMatches
|
||||||
(
|
(
|
||||||
@ -479,6 +492,18 @@ private:
|
|||||||
const scalar tol = 1e-6
|
const scalar tol = 1e-6
|
||||||
) const;
|
) 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
|
//- Mark cells for surface curvature based refinement. Marks if
|
||||||
// local curvature > curvature or if on different regions
|
// local curvature > curvature or if on different regions
|
||||||
// (markDifferingRegions)
|
// (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.
|
// Mark cells for surface curvature based refinement.
|
||||||
Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
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
|
// Test for all intersections (with surfaces of higher max level than
|
||||||
// minLevel) and cache per cell the interesting inter
|
// minLevel) and cache per cell the interesting inter
|
||||||
labelListList cellSurfLevels(mesh_.nCells());
|
labelListList cellSurfLevels(mesh_.nCells());
|
||||||
|
List<pointList> cellSurfLocations(mesh_.nCells());
|
||||||
List<vectorList> cellSurfNormals(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
|
// Per segment the normals of the surfaces
|
||||||
List<vectorList> surfaceNormal;
|
List<vectorList> surfaceNormal;
|
||||||
// Per segment the list of levels of the surfaces
|
// 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
|
labelList(surfaces_.maxLevel().size(), 0), // min level
|
||||||
surfaces_.maxLevel(),
|
surfaces_.maxLevel(),
|
||||||
|
|
||||||
|
surfaceLocation,
|
||||||
surfaceNormal,
|
surfaceNormal,
|
||||||
surfaceLevel
|
surfaceLevel
|
||||||
);
|
);
|
||||||
@ -1216,12 +1285,14 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
labelList visitOrder;
|
labelList visitOrder;
|
||||||
forAll(surfaceNormal, pointI)
|
forAll(surfaceNormal, pointI)
|
||||||
{
|
{
|
||||||
|
pointList& pLocations = surfaceLocation[pointI];
|
||||||
vectorList& pNormals = surfaceNormal[pointI];
|
vectorList& pNormals = surfaceNormal[pointI];
|
||||||
labelList& pLevel = surfaceLevel[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);
|
pLevel = labelUIndList(pLevel, visitOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1236,6 +1307,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
label faceI = testFaces[i];
|
label faceI = testFaces[i];
|
||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
|
||||||
|
const pointList& fPoints = surfaceLocation[i];
|
||||||
const vectorList& fNormals = surfaceNormal[i];
|
const vectorList& fNormals = surfaceNormal[i];
|
||||||
const labelList& fLevels = surfaceLevel[i];
|
const labelList& fLevels = surfaceLevel[i];
|
||||||
|
|
||||||
@ -1244,6 +1316,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
if (fLevels[hitI] > cellLevel[own])
|
if (fLevels[hitI] > cellLevel[own])
|
||||||
{
|
{
|
||||||
cellSurfLevels[own].append(fLevels[hitI]);
|
cellSurfLevels[own].append(fLevels[hitI]);
|
||||||
|
cellSurfLocations[own].append(fPoints[hitI]);
|
||||||
cellSurfNormals[own].append(fNormals[hitI]);
|
cellSurfNormals[own].append(fNormals[hitI]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,6 +1326,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
if (fLevels[hitI] > cellLevel[nei])
|
if (fLevels[hitI] > cellLevel[nei])
|
||||||
{
|
{
|
||||||
cellSurfLevels[nei].append(fLevels[hitI]);
|
cellSurfLevels[nei].append(fLevels[hitI]);
|
||||||
|
cellSurfLocations[nei].append(fPoints[hitI]);
|
||||||
cellSurfNormals[nei].append(fNormals[hitI]);
|
cellSurfNormals[nei].append(fNormals[hitI]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1266,7 +1340,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
label nSet = 0;
|
label nSet = 0;
|
||||||
label nNormals = 9;
|
label nNormals = 0;
|
||||||
forAll(cellSurfNormals, cellI)
|
forAll(cellSurfNormals, cellI)
|
||||||
{
|
{
|
||||||
const vectorList& normals = cellSurfNormals[cellI];
|
const vectorList& normals = cellSurfNormals[cellI];
|
||||||
@ -1296,21 +1370,38 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
for
|
for
|
||||||
(
|
(
|
||||||
label cellI = 0;
|
label cellI = 0;
|
||||||
!reachedLimit && cellI < cellSurfNormals.size();
|
!reachedLimit && cellI < cellSurfLocations.size();
|
||||||
cellI++
|
cellI++
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
const pointList& points = cellSurfLocations[cellI];
|
||||||
const vectorList& normals = cellSurfNormals[cellI];
|
const vectorList& normals = cellSurfNormals[cellI];
|
||||||
const labelList& levels = cellSurfLevels[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
|
// n^2 comparison of all normals in a cell
|
||||||
for (label i = 0; !reachedLimit && i < normals.size(); i++)
|
for (label i = 0; !reachedLimit && i < normals.size(); i++)
|
||||||
{
|
{
|
||||||
for (label j = i+1; !reachedLimit && j < normals.size(); j++)
|
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)
|
if (cellLevel[cellI] < maxLevel)
|
||||||
{
|
{
|
||||||
@ -1358,8 +1449,10 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
const pointList& ownPoints = cellSurfLocations[own];
|
||||||
const vectorList& ownNormals = cellSurfNormals[own];
|
const vectorList& ownNormals = cellSurfNormals[own];
|
||||||
const labelList& ownLevels = cellSurfLevels[own];
|
const labelList& ownLevels = cellSurfLevels[own];
|
||||||
|
const pointList& neiPoints = cellSurfLocations[nei];
|
||||||
const vectorList& neiNormals = cellSurfNormals[nei];
|
const vectorList& neiNormals = cellSurfNormals[nei];
|
||||||
const labelList& neiLevels = cellSurfLevels[nei];
|
const labelList& neiLevels = cellSurfLevels[nei];
|
||||||
|
|
||||||
@ -1379,13 +1472,30 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
|
|
||||||
if (!ownIsSubset && !neiIsSubset)
|
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
|
// n^2 comparison of between ownNormals and neiNormals
|
||||||
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
||||||
{
|
{
|
||||||
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
||||||
{
|
{
|
||||||
// Have valid data on both sides. Check curvature.
|
// 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.
|
// See which side to refine.
|
||||||
if (cellLevel[own] < ownLevels[i])
|
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;
|
List<vectorList> neiSurfaceNormals;
|
||||||
syncTools::swapBoundaryCellList(mesh_, cellSurfNormals, neiSurfaceNormals);
|
syncTools::swapBoundaryCellList(mesh_, cellSurfNormals, neiSurfaceNormals);
|
||||||
|
|
||||||
@ -1456,9 +1570,13 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
label own = mesh_.faceOwner()[faceI];
|
label own = mesh_.faceOwner()[faceI];
|
||||||
label bFaceI = faceI - mesh_.nInternalFaces();
|
label bFaceI = faceI - mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
const pointList& ownPoints = cellSurfLocations[own];
|
||||||
const vectorList& ownNormals = cellSurfNormals[own];
|
const vectorList& ownNormals = cellSurfNormals[own];
|
||||||
const labelList& ownLevels = cellSurfLevels[own];
|
const labelList& ownLevels = cellSurfLevels[own];
|
||||||
|
|
||||||
|
const pointList& neiPoints = neiSurfacePoints[bFaceI];
|
||||||
const vectorList& neiNormals = neiSurfaceNormals[bFaceI];
|
const vectorList& neiNormals = neiSurfaceNormals[bFaceI];
|
||||||
|
//const labelList& neiLevels = neiSurfaceLevel[bFacei];
|
||||||
|
|
||||||
// Special case: owner normals set is a subset of the neighbour
|
// Special case: owner normals set is a subset of the neighbour
|
||||||
// normals. Do not do curvature refinement since other cell's normals
|
// normals. Do not do curvature refinement since other cell's normals
|
||||||
@ -1475,13 +1593,30 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
|
|||||||
|
|
||||||
if (!ownIsSubset && !neiIsSubset)
|
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
|
// n^2 comparison of between ownNormals and neiNormals
|
||||||
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
for (label i = 0; !reachedLimit && i < ownNormals.size(); i++)
|
||||||
{
|
{
|
||||||
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
for (label j = 0; !reachedLimit && j < neiNormals.size(); j++)
|
||||||
{
|
{
|
||||||
// Have valid data on both sides. Check curvature.
|
// 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])
|
if (cellLevel[own] < ownLevels[i])
|
||||||
{
|
{
|
||||||
@ -2205,14 +2340,17 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
|||||||
// Refinement based on features smaller than cell size
|
// Refinement based on features smaller than cell size
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if (smallFeatureRefinement)
|
||||||
|
{
|
||||||
|
label nGap = 0;
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
smallFeatureRefinement
|
planarCos >= -1
|
||||||
&& (planarCos >= -1 && planarCos <= 1)
|
&& planarCos <= 1
|
||||||
&& max(shells_.maxGapLevel()) > 0
|
&& max(shells_.maxGapLevel()) > 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
label nGap = markSmallFeatureRefinement
|
nGap = markSmallFeatureRefinement
|
||||||
(
|
(
|
||||||
planarCos,
|
planarCos,
|
||||||
nAllowRefine,
|
nAllowRefine,
|
||||||
@ -2222,8 +2360,26 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
|||||||
refineCell,
|
refineCell,
|
||||||
nRefine
|
nRefine
|
||||||
);
|
);
|
||||||
|
}
|
||||||
Info<< "Marked for refinement due to close opposite surfaces "
|
Info<< "Marked for refinement due to close opposite surfaces "
|
||||||
<< ": " << nGap << " cells." << endl;
|
<< ": " << 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 |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2020 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -38,6 +38,8 @@ License
|
|||||||
// For dictionary::get wrapper
|
// For dictionary::get wrapper
|
||||||
#include "meshRefinement.H"
|
#include "meshRefinement.H"
|
||||||
|
|
||||||
|
#include "OBJstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::labelList Foam::refinementSurfaces::findHigherLevel
|
Foam::labelList Foam::refinementSurfaces::findHigherLevel
|
||||||
@ -194,15 +196,14 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
labelList globalMaxLevel(surfI, Zero);
|
labelList globalMaxLevel(surfI, Zero);
|
||||||
labelList globalLevelIncr(surfI, Zero);
|
labelList globalLevelIncr(surfI, Zero);
|
||||||
|
|
||||||
FixedList<label, 3> nullGapLevel;
|
const FixedList<label, 3> nullGapLevel({0, 0, 0});
|
||||||
nullGapLevel[0] = 0;
|
|
||||||
nullGapLevel[1] = 0;
|
|
||||||
nullGapLevel[2] = 0;
|
|
||||||
|
|
||||||
List<FixedList<label, 3>> globalGapLevel(surfI);
|
List<FixedList<label, 3>> globalGapLevel(surfI);
|
||||||
List<volumeType> globalGapMode(surfI);
|
List<volumeType> globalGapMode(surfI);
|
||||||
boolList globalGapSelf(surfI);
|
boolList globalGapSelf(surfI);
|
||||||
|
|
||||||
|
const FixedList<label, 4> nullCurvLevel({0, 0, 0, -1});
|
||||||
|
List<FixedList<label, 4>> globalCurvLevel(surfI);
|
||||||
|
|
||||||
scalarField globalAngle(surfI, -GREAT);
|
scalarField globalAngle(surfI, -GREAT);
|
||||||
PtrList<dictionary> globalPatchInfo(surfI);
|
PtrList<dictionary> globalPatchInfo(surfI);
|
||||||
|
|
||||||
@ -216,6 +217,7 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
List<Map<FixedList<label, 3>>> regionGapLevel(surfI);
|
List<Map<FixedList<label, 3>>> regionGapLevel(surfI);
|
||||||
List<Map<volumeType>> regionGapMode(surfI);
|
List<Map<volumeType>> regionGapMode(surfI);
|
||||||
List<Map<bool>> regionGapSelf(surfI);
|
List<Map<bool>> regionGapSelf(surfI);
|
||||||
|
List<Map<FixedList<label, 4>>> regionCurvLevel(surfI);
|
||||||
List<Map<scalar>> regionAngle(surfI);
|
List<Map<scalar>> regionAngle(surfI);
|
||||||
List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
|
List<Map<autoPtr<dictionary>>> regionPatchInfo(surfI);
|
||||||
List<Map<label>> regionBlockLevel(surfI);
|
List<Map<label>> regionBlockLevel(surfI);
|
||||||
@ -307,6 +309,19 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
globalGapSelf[surfI] =
|
globalGapSelf[surfI] =
|
||||||
dict.getOrDefault<bool>("gapSelf", true);
|
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]];
|
const searchableSurface& surface = allGeometry_[surfaces_[surfI]];
|
||||||
|
|
||||||
// Surface zones
|
// 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"))
|
if (regionDict.found("perpendicularAngle"))
|
||||||
{
|
{
|
||||||
regionAngle[surfI].insert
|
regionAngle[surfI].insert
|
||||||
@ -505,6 +534,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
extendedGapMode_ = volumeType::UNKNOWN;
|
extendedGapMode_ = volumeType::UNKNOWN;
|
||||||
selfProximity_.setSize(nRegions);
|
selfProximity_.setSize(nRegions);
|
||||||
selfProximity_ = true;
|
selfProximity_ = true;
|
||||||
|
extendedCurvatureLevel_.setSize(nRegions);
|
||||||
|
extendedCurvatureLevel_ = nullCurvLevel;
|
||||||
perpendicularAngle_.setSize(nRegions);
|
perpendicularAngle_.setSize(nRegions);
|
||||||
perpendicularAngle_ = -GREAT;
|
perpendicularAngle_ = -GREAT;
|
||||||
patchInfo_.setSize(nRegions);
|
patchInfo_.setSize(nRegions);
|
||||||
@ -531,6 +562,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
extendedGapLevel_[globalRegionI] = globalGapLevel[surfI];
|
extendedGapLevel_[globalRegionI] = globalGapLevel[surfI];
|
||||||
extendedGapMode_[globalRegionI] = globalGapMode[surfI];
|
extendedGapMode_[globalRegionI] = globalGapMode[surfI];
|
||||||
selfProximity_[globalRegionI] = globalGapSelf[surfI];
|
selfProximity_[globalRegionI] = globalGapSelf[surfI];
|
||||||
|
extendedCurvatureLevel_[globalRegionI] =
|
||||||
|
globalCurvLevel[surfI];
|
||||||
perpendicularAngle_[globalRegionI] = globalAngle[surfI];
|
perpendicularAngle_[globalRegionI] = globalAngle[surfI];
|
||||||
if (globalPatchInfo.set(surfI))
|
if (globalPatchInfo.set(surfI))
|
||||||
{
|
{
|
||||||
@ -560,6 +593,8 @@ Foam::refinementSurfaces::refinementSurfaces
|
|||||||
regionGapMode[surfI][iter.key()];
|
regionGapMode[surfI][iter.key()];
|
||||||
selfProximity_[globalRegionI] =
|
selfProximity_[globalRegionI] =
|
||||||
regionGapSelf[surfI][iter.key()];
|
regionGapSelf[surfI][iter.key()];
|
||||||
|
extendedCurvatureLevel_[globalRegionI] =
|
||||||
|
regionCurvLevel[surfI][iter.key()];
|
||||||
}
|
}
|
||||||
forAllConstIters(regionAngle[surfI], iter)
|
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
|
// Precalculate the refinement level for every element of the searchable
|
||||||
// surface.
|
// surface.
|
||||||
void Foam::refinementSurfaces::setMinLevelFields(const shellSurfaces& shells)
|
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
|
// In case of triangulated surfaces only cache value if triangle
|
||||||
// centre and vertices are in same shell
|
// centre and vertices are in same shell
|
||||||
if (isA<triSurface>(geom))
|
const auto* tsPtr = isA<const triSurface>(geom);
|
||||||
|
|
||||||
|
if (tsPtr)
|
||||||
{
|
{
|
||||||
label nUncached = 0;
|
label nUncached = 0;
|
||||||
|
|
||||||
// Check if points differing from ctr level
|
// Check if points differing from ctr level
|
||||||
|
|
||||||
const triSurface& ts = refCast<const triSurface>(geom);
|
const triSurface& ts = *tsPtr;
|
||||||
const pointField& points = ts.points();
|
const pointField& points = ts.points();
|
||||||
|
|
||||||
// Determine minimum expected level to avoid having to
|
// 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
|
// Find intersections of edge. Return -1 or first surface with higher minLevel
|
||||||
// number.
|
// number.
|
||||||
void Foam::refinementSurfaces::findHigherIntersection
|
void Foam::refinementSurfaces::findHigherIntersection
|
||||||
|
|||||||
@ -110,6 +110,9 @@ class refinementSurfaces
|
|||||||
// (in gap refinement)
|
// (in gap refinement)
|
||||||
boolList selfProximity_;
|
boolList selfProximity_;
|
||||||
|
|
||||||
|
//- From global region number to curvature specification
|
||||||
|
List<FixedList<label, 4>> extendedCurvatureLevel_;
|
||||||
|
|
||||||
//- From global region number to perpendicular angle
|
//- From global region number to perpendicular angle
|
||||||
scalarField perpendicularAngle_;
|
scalarField perpendicularAngle_;
|
||||||
|
|
||||||
@ -263,6 +266,19 @@ public:
|
|||||||
return selfProximity_;
|
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
|
//- From global region number to perpendicular angle
|
||||||
const scalarField& perpendicularAngle() const
|
const scalarField& perpendicularAngle() const
|
||||||
{
|
{
|
||||||
@ -307,12 +323,23 @@ public:
|
|||||||
//- Per surface the maximum extendedGapLevel over all its regions
|
//- Per surface the maximum extendedGapLevel over all its regions
|
||||||
labelList maxGapLevel() const;
|
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
|
void setMinLevelFields
|
||||||
(
|
(
|
||||||
const shellSurfaces& shells
|
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
|
////- Helper: count number of triangles per region
|
||||||
//static labelList countRegions(const triSurface&);
|
//static labelList countRegions(const triSurface&);
|
||||||
|
|
||||||
|
|||||||
@ -230,10 +230,16 @@ Foam::label Foam::snappyRefineDriver::smallFeatureRefine
|
|||||||
label iter = 0;
|
label iter = 0;
|
||||||
|
|
||||||
// See if any surface has an extendedGapLevel
|
// See if any surface has an extendedGapLevel
|
||||||
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
|
const labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
|
||||||
labelList shellMaxLevel(meshRefiner_.shells().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;
|
return iter;
|
||||||
}
|
}
|
||||||
@ -3382,6 +3388,7 @@ void Foam::snappyRefineDriver::doRefine
|
|||||||
(
|
(
|
||||||
max(meshRefiner_.surfaces().maxGapLevel()) > 0
|
max(meshRefiner_.surfaces().maxGapLevel()) > 0
|
||||||
|| max(meshRefiner_.shells().maxGapLevel()) > 0
|
|| max(meshRefiner_.shells().maxGapLevel()) > 0
|
||||||
|
|| max(meshRefiner_.surfaces().maxCurvatureLevel()) > 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// In case we use automatic gap level refinement do some pre-refinement
|
// 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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user