Commit 4caacddd authored by Andrew Heather's avatar Andrew Heather
Browse files

Merge branch 'feature-snappyHexMesh-gapRefinement' into 'develop'

Feature snappy hex mesh gap refinement

Adding automatic gap refinement capability

See merge request !2
parents 95eb7cc6 4927f97c
......@@ -1075,6 +1075,26 @@ int main(int argc, char *argv[])
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Optionally read limit shells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const dictionary limitDict(refineDict.subOrEmptyDict("limitRegions"));
if (!limitDict.empty())
{
Info<< "Reading limit shells." << endl;
}
shellSurfaces limitShells(allGeometry, limitDict);
if (!limitDict.empty())
{
Info<< "Read refinement shells in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
}
// Read feature meshes
// ~~~~~~~~~~~~~~~~~~~
......@@ -1105,7 +1125,8 @@ int main(int argc, char *argv[])
overwrite, // overwrite mesh files?
surfaces, // for surface intersection refinement
features, // for feature edges/point based refinement
shells // for volume (inside/outside) refinement
shells, // for volume (inside/outside) refinement
limitShells // limit of volume refinement
);
Info<< "Calculated surface intersections in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
......
......@@ -95,10 +95,10 @@ castellatedMeshControls
// actually be a lot less.
maxGlobalCells 2000000;
// The surface refinement loop might spend lots of iterations refining just a
// few cells. This setting will cause refinement to stop if <= minimumRefine
// are selected for refinement. Note: it will at least do one iteration
// (unless the number of cells to refine is 0)
// The surface refinement loop might spend lots of iterations refining just
// a few cells. This setting will cause refinement to stop if
// <= minimumRefine cells are selected for refinement. Note: it will
// at least do one iteration (unless the number of cells to refine is 0)
minRefinementCells 0;
// Allow a certain level of imbalance during refining
......@@ -244,11 +244,27 @@ castellatedMeshControls
}
//sphere.stl
//{
// mode distance;
// levels ((1.0 5) (2.0 3));
// mode inside;
// levels ((1.0 4));
// // Optional override of uniform refinement level such
// // that in small gaps we're getting more cells.
// // The specification is
// // - numGapCells : minimum number of cells in the gap
// // - minLevel : min refinement level at which to kick in
// // - maxLevel : upper refinement level
// // All three settings can be overridden on a surface by
// // surface basis in the refinementSurfaces section.
// gapLevel (<numGapCells> <minLevel> <maxlevel>);
//}
}
// Limit refinement in geometric region
limitRegions
{
}
// Mesh selection
// ~~~~~~~~~~~~~~
......
......@@ -59,6 +59,8 @@ parallel/Allwmake $targetType $*
wmake $targetType ODE
wmake $targetType randomProcesses
wmake $targetType fvMotionSolver
transportModels/Allwmake $targetType $*
thermophysicalModels/Allwmake $targetType $*
TurbulenceModels/Allwmake $targetType $*
......@@ -69,7 +71,6 @@ mesh/Allwmake $targetType $*
renumber/Allwmake $targetType $*
fvAgglomerationMethods/Allwmake $targetType $*
wmake $targetType fvMotionSolver
wmake $targetType engine
wmake $targetType fvOptions
wmake $targetType regionCoupled
......
......@@ -2,8 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -95,6 +95,12 @@ public:
t_(t)
{}
//- Construct from integer
explicit volumeType(const int t)
:
t_(static_cast<volumeType::type>(t))
{}
// Member Functions
......
......@@ -15,6 +15,7 @@ $(autoHexMesh)/meshRefinement/meshRefinement.C
$(autoHexMesh)/meshRefinement/meshRefinementMerge.C
$(autoHexMesh)/meshRefinement/meshRefinementProblemCells.C
$(autoHexMesh)/meshRefinement/meshRefinementRefine.C
$(autoHexMesh)/meshRefinement/meshRefinementGapRefine.C
$(autoHexMesh)/meshRefinement/patchFaceOrientation.C
$(autoHexMesh)/refinementFeatures/refinementFeatures.C
......
......@@ -105,7 +105,10 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
......@@ -179,6 +182,128 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
}
Foam::label Foam::autoRefineDriver::smallFeatureRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter = 0;
// See if any surface has an extendedGapLevel
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
if (max(surfaceMaxLevel) == 0 && max(shellMaxLevel) == 0)
{
return iter;
}
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Small surface feature refinement iteration " << iter << nl
<< "--------------------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
true, // smallFeatureRefinement
false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if (nCellsToRefine == 0)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"small feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"small feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
(
const refinementParameters& refineParams,
......@@ -218,7 +343,10 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
false, // internalRefinement
true, // surfaceRefinement
true, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
......@@ -352,7 +480,10 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
false, // smallFeatureRefinement
true, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
......@@ -527,6 +658,148 @@ Foam::label Foam::autoRefineDriver::gapOnlyRefine
}
Foam::label Foam::autoRefineDriver::bigGapOnlyRefine
(
const refinementParameters& refineParams,
const bool spreadGapSize,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter = 0;
// See if any surface has an extendedGapLevel
labelList surfaceMaxLevel(meshRefiner_.surfaces().maxGapLevel());
labelList shellMaxLevel(meshRefiner_.shells().maxGapLevel());
label overallMaxLevel(max(max(surfaceMaxLevel), max(shellMaxLevel)));
if (overallMaxLevel == 0)
{
return iter;
}
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Big gap refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.locationsInMesh(),
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement
true, // bigGapRefinement
spreadGapSize, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromBigGap." << endl;
cellSet c(mesh, "candidateCellsFromBigGap", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"big gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"big gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::danglingCellRefine
(
const refinementParameters& refineParams,
......@@ -1108,7 +1381,10 @@ Foam::label Foam::autoRefineDriver::shellRefine
true, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
false, // smallFeatureRefinement
false, // gapRefinement
false, // bigGapRefinement
false, // spreadGapSize
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
......@@ -1630,6 +1906,13 @@ void Foam::autoRefineDriver::doRefine
0 // min cells to refine
);
// Refine cells that contain a gap
smallFeatureRefine
(
refineParams,
100 // maxIter
);
// Refine based on surface
surfaceOnlyRefine
(
......@@ -1650,6 +1933,14 @@ void Foam::autoRefineDriver::doRefine
1 // nBufferLayers
);
// Refine consistently across narrow gaps (a form of shell refinement)
bigGapOnlyRefine
(
refineParams,
true, // spreadGapSize
100 // maxIter
);
// Internal mesh refinement
shellRefine
(
......
......@@ -84,6 +84,13 @@ class autoRefineDriver
const label minRefine
);
//- Refine all cells containing small surface features
label smallFeatureRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Refine all cells interacting with the surface
label surfaceOnlyRefine
(
......@@ -98,6 +105,14 @@ class autoRefineDriver
const label maxIter
);
//- Refine all cells in large gaps
label bigGapOnlyRefine
(
const refinementParameters& refineParams,
const bool spreadGapSize,
const label maxIter
);
//- Refine cells with almost all sides refined
label danglingCellRefine
(
......
......@@ -215,6 +215,55 @@ void Foam::meshRefinement::calcNeighbourData
}
void Foam::meshRefinement::calcCellCellRays
(
const pointField& neiCc,
const labelList& neiLevel,
const labelList& testFaces,
pointField& start,
pointField& end,
labelList& minLevel
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
start.setSize(testFaces.size());
end.setSize(testFaces.size());
minLevel.setSize(testFaces.size());
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(ROOTSMALL*(end-start));
start -= smallVec;
end += smallVec;
}
}
// Find intersections of edges (given by their two endpoints) with surfaces.
// Returns first intersection if there are more than one.
void Foam::meshRefinement::updateIntersections(const labelList& changedFaces)
......@@ -1187,7 +1236,8 @@ Foam::meshRefinement::meshRefinement
const bool overwrite,
const refinementSurfaces& surfaces,
const refinementFeatures& features,
const shellSurfaces& shells
const shellSurfaces& shells,
const shellSurfaces& limitShells
)
:
mesh_(mesh),
......@@ -1197,6 +1247,7 @@ Foam::meshRefinement::meshRefinement
surfaces_(surfaces),
features_(features),
shells_(shells),
limitShells_(limitShells),
meshCutter_
(
mesh,
......
......@@ -34,6 +34,7 @@ Description
SourceFiles
meshRefinement.C
meshRefinementBaffles.C
meshRefinementGapRefine.C
meshRefinementMerge.C
meshRefinementProblemCells.C
meshRefinementRefine.C
......@@ -53,6 +54,8 @@ SourceFiles