mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge remote-tracking branch 'origin/develop' into develop-pre-release
This commit is contained in:
@ -1082,7 +1082,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (!limitDict.empty())
|
||||
{
|
||||
Info<< "Read refinement shells in = "
|
||||
Info<< "Read limit shells in = "
|
||||
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
|
||||
}
|
||||
|
||||
|
||||
@ -49,6 +49,14 @@ geometry
|
||||
max (3.5 2 0.5);
|
||||
}
|
||||
|
||||
// Shell for directional refinement
|
||||
wakeBox
|
||||
{
|
||||
type searchableBox;
|
||||
min (1.5 1 -0.5);
|
||||
max (3.5 2 0.5);
|
||||
}
|
||||
|
||||
sphere.stl
|
||||
{
|
||||
type triSurfaceMesh;
|
||||
@ -257,8 +265,8 @@ castellatedMeshControls
|
||||
// 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
|
||||
// // that in small gaps we're getting more cells.
|
||||
// // The specification is
|
||||
// // - numGapCells : minimum number of cells in the gap
|
||||
// // (usually >3; lower than this might not
|
||||
// // resolve correctly)
|
||||
@ -275,9 +283,33 @@ castellatedMeshControls
|
||||
// // whilst doing the gap-level refinement.
|
||||
// //gapMode inside; // inside/outside/mixed
|
||||
//}
|
||||
|
||||
//wakeBox
|
||||
//{
|
||||
// mode inside;
|
||||
// // Dummy base level
|
||||
// levels ((10000 0));
|
||||
//
|
||||
// // Optional directional refinement (after all other refinement)
|
||||
// // Directional refinement
|
||||
// // for all cells according to 'mode' ('inside' or 'outside';
|
||||
// // 'distance' not supported) and within certain range. E.g.
|
||||
// // - for all cells with level 2-5
|
||||
// // - do one split in x direction
|
||||
// levelIncrement (2 5 (1 0 0));
|
||||
//
|
||||
// // Note
|
||||
// // - ignores 'levels' and gap* settings.
|
||||
// // - the cellLevel/pointLevels files are no longer consistent
|
||||
// // with the mesh, the resulting mesh is no longer compatible
|
||||
// // with e.g. dynamic refinement/unrefinement.
|
||||
// // - cellLevel will include any directional refinement
|
||||
// // (i.e. it will be the maximum of all three directions)
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
@ -1564,6 +1564,7 @@ void Foam::hexRef8::walkFaceFromMid
|
||||
Foam::label Foam::hexRef8::faceConsistentRefinement
|
||||
(
|
||||
const bool maxSet,
|
||||
const labelUList& cellLevel,
|
||||
bitSet& refineCell
|
||||
) const
|
||||
{
|
||||
@ -1573,10 +1574,10 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
|
||||
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||
{
|
||||
label own = mesh_.faceOwner()[facei];
|
||||
label nei = mesh_.faceNeighbour()[facei];
|
||||
label ownLevel = cellLevel[own] + refineCell.get(own);
|
||||
|
||||
label ownLevel = cellLevel_[own] + refineCell.get(own);
|
||||
label neiLevel = cellLevel_[nei] + refineCell.get(nei);
|
||||
label nei = mesh_.faceNeighbour()[facei];
|
||||
label neiLevel = cellLevel[nei] + refineCell.get(nei);
|
||||
|
||||
if (ownLevel > (neiLevel+1))
|
||||
{
|
||||
@ -1613,7 +1614,7 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
|
||||
{
|
||||
label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
|
||||
|
||||
neiLevel[i] = cellLevel_[own] + refineCell.get(own);
|
||||
neiLevel[i] = cellLevel[own] + refineCell.get(own);
|
||||
}
|
||||
|
||||
// Swap to neighbour
|
||||
@ -1623,7 +1624,7 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
|
||||
forAll(neiLevel, i)
|
||||
{
|
||||
label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
|
||||
label ownLevel = cellLevel_[own] + refineCell.get(own);
|
||||
label ownLevel = cellLevel[own] + refineCell.get(own);
|
||||
|
||||
if (ownLevel > (neiLevel[i]+1))
|
||||
{
|
||||
@ -1650,6 +1651,7 @@ Foam::label Foam::hexRef8::faceConsistentRefinement
|
||||
// Debug: check if wanted refinement is compatible with 2:1
|
||||
void Foam::hexRef8::checkWantedRefinementLevels
|
||||
(
|
||||
const labelUList& cellLevel,
|
||||
const labelList& cellsToRefine
|
||||
) const
|
||||
{
|
||||
@ -1658,10 +1660,10 @@ void Foam::hexRef8::checkWantedRefinementLevels
|
||||
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||
{
|
||||
label own = mesh_.faceOwner()[facei];
|
||||
label nei = mesh_.faceNeighbour()[facei];
|
||||
label ownLevel = cellLevel[own] + refineCell.get(own);
|
||||
|
||||
label ownLevel = cellLevel_[own] + refineCell.get(own);
|
||||
label neiLevel = cellLevel_[nei] + refineCell.get(nei);
|
||||
label nei = mesh_.faceNeighbour()[facei];
|
||||
label neiLevel = cellLevel[nei] + refineCell.get(nei);
|
||||
|
||||
if (mag(ownLevel-neiLevel) > 1)
|
||||
{
|
||||
@ -1669,11 +1671,11 @@ void Foam::hexRef8::checkWantedRefinementLevels
|
||||
dumpCell(nei);
|
||||
FatalErrorInFunction
|
||||
<< "cell:" << own
|
||||
<< " current level:" << cellLevel_[own]
|
||||
<< " current level:" << cellLevel[own]
|
||||
<< " level after refinement:" << ownLevel
|
||||
<< nl
|
||||
<< "neighbour cell:" << nei
|
||||
<< " current level:" << cellLevel_[nei]
|
||||
<< " current level:" << cellLevel[nei]
|
||||
<< " level after refinement:" << neiLevel
|
||||
<< nl
|
||||
<< "which does not satisfy 2:1 constraints anymore."
|
||||
@ -1689,7 +1691,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
|
||||
{
|
||||
label own = mesh_.faceOwner()[i+mesh_.nInternalFaces()];
|
||||
|
||||
neiLevel[i] = cellLevel_[own] + refineCell.get(own);
|
||||
neiLevel[i] = cellLevel[own] + refineCell.get(own);
|
||||
}
|
||||
|
||||
// Swap to neighbour
|
||||
@ -1701,7 +1703,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
|
||||
label facei = i + mesh_.nInternalFaces();
|
||||
|
||||
label own = mesh_.faceOwner()[facei];
|
||||
label ownLevel = cellLevel_[own] + refineCell.get(own);
|
||||
label ownLevel = cellLevel[own] + refineCell.get(own);
|
||||
|
||||
if (mag(ownLevel - neiLevel[i]) > 1)
|
||||
{
|
||||
@ -1715,7 +1717,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
|
||||
<< " on patch " << patchi << " "
|
||||
<< mesh_.boundaryMesh()[patchi].name()
|
||||
<< " owner cell " << own
|
||||
<< " current level:" << cellLevel_[own]
|
||||
<< " current level:" << cellLevel[own]
|
||||
<< " level after refinement:" << ownLevel
|
||||
<< nl
|
||||
<< " (coupled) neighbour cell will get refinement "
|
||||
@ -2251,6 +2253,7 @@ Foam::hexRef8::hexRef8
|
||||
|
||||
Foam::labelList Foam::hexRef8::consistentRefinement
|
||||
(
|
||||
const labelUList& cellLevel,
|
||||
const labelList& cellsToRefine,
|
||||
const bool maxSet
|
||||
) const
|
||||
@ -2264,7 +2267,12 @@ Foam::labelList Foam::hexRef8::consistentRefinement
|
||||
|
||||
while (true)
|
||||
{
|
||||
label nChanged = faceConsistentRefinement(maxSet, refineCell);
|
||||
label nChanged = faceConsistentRefinement
|
||||
(
|
||||
maxSet,
|
||||
cellLevel,
|
||||
refineCell
|
||||
);
|
||||
|
||||
reduce(nChanged, sumOp<label>());
|
||||
|
||||
@ -2286,7 +2294,7 @@ Foam::labelList Foam::hexRef8::consistentRefinement
|
||||
|
||||
if (debug)
|
||||
{
|
||||
checkWantedRefinementLevels(newCellsToRefine);
|
||||
checkWantedRefinementLevels(cellLevel, newCellsToRefine);
|
||||
}
|
||||
|
||||
return newCellsToRefine;
|
||||
@ -3089,11 +3097,11 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement2
|
||||
refineCell.set(celli);
|
||||
}
|
||||
}
|
||||
faceConsistentRefinement(true, refineCell);
|
||||
faceConsistentRefinement(true, cellLevel_, refineCell);
|
||||
|
||||
while (true)
|
||||
{
|
||||
label nChanged = faceConsistentRefinement(true, refineCell);
|
||||
label nChanged = faceConsistentRefinement(true, cellLevel_, refineCell);
|
||||
|
||||
reduce(nChanged, sumOp<label>());
|
||||
|
||||
@ -3141,7 +3149,7 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement2
|
||||
|
||||
const bitSet savedRefineCell(refineCell);
|
||||
|
||||
label nChanged = faceConsistentRefinement(true, refineCell);
|
||||
label nChanged = faceConsistentRefinement(true, cellLevel_, refineCell);
|
||||
|
||||
{
|
||||
cellSet cellsOut2
|
||||
|
||||
@ -300,11 +300,16 @@ class hexRef8
|
||||
label faceConsistentRefinement
|
||||
(
|
||||
const bool maxSet,
|
||||
const labelUList& cellLevel,
|
||||
bitSet& refineCell
|
||||
) const;
|
||||
|
||||
//- Check wanted refinement for 2:1 consistency
|
||||
void checkWantedRefinementLevels(const labelList&) const;
|
||||
void checkWantedRefinementLevels
|
||||
(
|
||||
const labelUList& cellLevel,
|
||||
const labelList&
|
||||
) const;
|
||||
|
||||
|
||||
// Cellshape recognition
|
||||
@ -420,10 +425,25 @@ public:
|
||||
// removes cells to refine (maxSet = false)
|
||||
labelList consistentRefinement
|
||||
(
|
||||
const labelUList& cellLevel,
|
||||
const labelList& cellsToRefine,
|
||||
const bool maxSet
|
||||
) const;
|
||||
|
||||
//- Given valid mesh and current cell level and proposed
|
||||
// cells to refine calculate any clashes (due to 2:1) and return
|
||||
// ok list of cells to refine.
|
||||
// Either adds cells to refine to set (maxSet = true) or
|
||||
// removes cells to refine (maxSet = false)
|
||||
labelList consistentRefinement
|
||||
(
|
||||
const labelList& cellsToRefine,
|
||||
const bool maxSet
|
||||
) const
|
||||
{
|
||||
return consistentRefinement(cellLevel_, cellsToRefine, maxSet);
|
||||
}
|
||||
|
||||
//- Like consistentRefinement but slower:
|
||||
//
|
||||
// - specify number of cells between consecutive refinement levels
|
||||
|
||||
@ -807,8 +807,8 @@ public:
|
||||
const bool overwrite,
|
||||
const refinementSurfaces&,
|
||||
const refinementFeatures&,
|
||||
const shellSurfaces&,
|
||||
const shellSurfaces&
|
||||
const shellSurfaces&, // omnidirectional refinement
|
||||
const shellSurfaces& // limit refinement
|
||||
);
|
||||
|
||||
|
||||
@ -1038,6 +1038,24 @@ public:
|
||||
);
|
||||
|
||||
|
||||
//- Calculate list of cells to directionally refine
|
||||
labelList directionalRefineCandidates
|
||||
(
|
||||
const label maxGlobalCells,
|
||||
const label maxLocalCells,
|
||||
const labelList& currentLevel,
|
||||
const direction dir
|
||||
) const;
|
||||
|
||||
//- Directionally refine in direction cmpt
|
||||
autoPtr<mapPolyMesh> directionalRefine
|
||||
(
|
||||
const string& msg,
|
||||
const direction cmpt,
|
||||
const labelList& cellsToRefine
|
||||
);
|
||||
|
||||
|
||||
// Baffle handling
|
||||
|
||||
//- Split off unreachable areas of mesh.
|
||||
|
||||
@ -41,6 +41,11 @@ License
|
||||
#include "cellSet.H"
|
||||
#include "treeDataCell.H"
|
||||
|
||||
#include "cellCuts.H"
|
||||
#include "refineCell.H"
|
||||
#include "hexCellLooper.H"
|
||||
#include "meshCutter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -2073,7 +2078,7 @@ Foam::labelList Foam::meshRefinement::refineCandidates
|
||||
label nAllowRefine = labelMax / Pstream::nProcs();
|
||||
|
||||
// Marked for refinement (>= 0) or not (-1). Actual value is the
|
||||
// index of the surface it intersects.
|
||||
// index of the surface it intersects / shell it is inside.
|
||||
labelList refineCell(mesh_.nCells(), -1);
|
||||
label nRefine = 0;
|
||||
|
||||
@ -2624,4 +2629,163 @@ Foam::meshRefinement::balanceAndRefine
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::meshRefinement::directionalRefineCandidates
|
||||
(
|
||||
const label maxGlobalCells,
|
||||
const label maxLocalCells,
|
||||
const labelList& currentLevel,
|
||||
const direction dir
|
||||
) const
|
||||
{
|
||||
const labelList& cellLevel = meshCutter_.cellLevel();
|
||||
const pointField& cellCentres = mesh_.cellCentres();
|
||||
|
||||
label totNCells = mesh_.globalData().nTotalCells();
|
||||
|
||||
labelList cellsToRefine;
|
||||
|
||||
if (totNCells >= maxGlobalCells)
|
||||
{
|
||||
Info<< "No cells marked for refinement since reached limit "
|
||||
<< maxGlobalCells << '.' << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable refinement shortcut. nAllowRefine is per processor limit.
|
||||
label nAllowRefine = labelMax / Pstream::nProcs();
|
||||
|
||||
// Marked for refinement (>= 0) or not (-1). Actual value is the
|
||||
// index of the surface it intersects / shell it is inside
|
||||
labelList refineCell(mesh_.nCells(), -1);
|
||||
label nRefine = 0;
|
||||
|
||||
// Find cells inside the shells with directional levels
|
||||
labelList insideShell;
|
||||
shells_.findDirectionalLevel
|
||||
(
|
||||
cellCentres,
|
||||
cellLevel,
|
||||
currentLevel, // current directional level
|
||||
dir,
|
||||
insideShell
|
||||
);
|
||||
|
||||
// Mark for refinement
|
||||
forAll(insideShell, celli)
|
||||
{
|
||||
if (insideShell[celli] >= 0)
|
||||
{
|
||||
bool reachedLimit = !markForRefine
|
||||
(
|
||||
insideShell[celli], // mark with any positive value
|
||||
nAllowRefine,
|
||||
refineCell[celli],
|
||||
nRefine
|
||||
);
|
||||
|
||||
if (reachedLimit)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Stopped refining cells"
|
||||
<< " since reaching my cell limit of "
|
||||
<< mesh_.nCells()+nAllowRefine << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Limit refinement
|
||||
// ~~~~~~~~~~~~~~~~
|
||||
|
||||
{
|
||||
label nUnmarked = unmarkInternalRefinement(refineCell, nRefine);
|
||||
if (nUnmarked > 0)
|
||||
{
|
||||
Info<< "Unmarked for refinement due to limit shells"
|
||||
<< " : " << nUnmarked << " cells." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Pack cells-to-refine
|
||||
// ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
cellsToRefine.setSize(nRefine);
|
||||
nRefine = 0;
|
||||
|
||||
forAll(refineCell, cellI)
|
||||
{
|
||||
if (refineCell[cellI] != -1)
|
||||
{
|
||||
cellsToRefine[nRefine++] = cellI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cellsToRefine;
|
||||
}
|
||||
|
||||
|
||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::directionalRefine
|
||||
(
|
||||
const string& msg,
|
||||
const direction cmpt,
|
||||
const labelList& cellsToRefine
|
||||
)
|
||||
{
|
||||
// Set splitting direction
|
||||
vector refDir(Zero);
|
||||
refDir[cmpt] = 1;
|
||||
List<refineCell> refCells(cellsToRefine.size());
|
||||
forAll(cellsToRefine, i)
|
||||
{
|
||||
refCells[i] = refineCell(cellsToRefine[i], refDir);
|
||||
}
|
||||
|
||||
// How to walk circumference of cells
|
||||
hexCellLooper cellWalker(mesh_);
|
||||
|
||||
// Analyse cuts
|
||||
cellCuts cuts(mesh_, cellWalker, refCells);
|
||||
|
||||
// Cell cutter
|
||||
Foam::meshCutter meshRefiner(mesh_);
|
||||
|
||||
polyTopoChange meshMod(mesh_);
|
||||
|
||||
// Insert mesh refinement into polyTopoChange.
|
||||
meshRefiner.setRefinement(cuts, meshMod);
|
||||
|
||||
autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh_, false);
|
||||
|
||||
// Update fields
|
||||
mesh_.updateMesh(morphMap);
|
||||
|
||||
// Move mesh (since morphing does not do this)
|
||||
if (morphMap().hasMotionPoints())
|
||||
{
|
||||
mesh_.movePoints(morphMap().preMotionPoints());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete mesh volumes.
|
||||
mesh_.clearOut();
|
||||
}
|
||||
|
||||
// Reset the instance for if in overwrite mode
|
||||
mesh_.setInstance(timeName());
|
||||
|
||||
// Update stored refinement pattern
|
||||
meshRefiner.updateMesh(morphMap);
|
||||
|
||||
// Update intersection info
|
||||
updateMesh(morphMap, getChangedFaces(morphMap, cellsToRefine));
|
||||
|
||||
return morphMap;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -584,6 +584,7 @@ Foam::shellSurfaces::shellSurfaces
|
||||
modes_.setSize(shellI);
|
||||
distances_.setSize(shellI);
|
||||
levels_.setSize(shellI);
|
||||
dirLevels_.setSize(shellI);
|
||||
|
||||
extendedGapLevel_.setSize(shellI);
|
||||
extendedGapMode_.setSize(shellI);
|
||||
@ -615,6 +616,52 @@ Foam::shellSurfaces::shellSurfaces
|
||||
setAndCheckLevels(shellI, dict.lookup("levels"));
|
||||
|
||||
|
||||
// Directional refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
dirLevels_[shellI] = Tuple2<labelPair,labelVector>
|
||||
(
|
||||
labelPair(labelMax, labelMin),
|
||||
labelVector::zero
|
||||
);
|
||||
const entry* levelPtr = dict.lookupEntryPtr
|
||||
(
|
||||
"levelIncrement",
|
||||
false,
|
||||
true
|
||||
);
|
||||
if (levelPtr)
|
||||
{
|
||||
// Do reading ourselves since using labelPair would require
|
||||
// additional bracket pair
|
||||
Istream& is = levelPtr->stream();
|
||||
|
||||
is.readBegin("levelIncrement");
|
||||
is >> dirLevels_[shellI].first().first()
|
||||
>> dirLevels_[shellI].first().second()
|
||||
>> dirLevels_[shellI].second();
|
||||
is.readEnd("levelIncrement");
|
||||
|
||||
if (modes_[shellI] == INSIDE)
|
||||
{
|
||||
Info<< "Additional directional refinement level"
|
||||
<< " for all cells inside " << geomName << endl;
|
||||
}
|
||||
else if (modes_[shellI] == OUTSIDE)
|
||||
{
|
||||
Info<< "Additional directional refinement level"
|
||||
<< " for all cells outside " << geomName << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(shellsDict)
|
||||
<< "Unsupported mode "
|
||||
<< refineModeNames_[modes_[shellI]]
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Gap specification
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
@ -745,6 +792,17 @@ Foam::labelList Foam::shellSurfaces::maxGapLevel() const
|
||||
}
|
||||
|
||||
|
||||
Foam::labelPairList Foam::shellSurfaces::directionalSelectLevel() const
|
||||
{
|
||||
labelPairList levels(dirLevels_.size());
|
||||
forAll(dirLevels_, shelli)
|
||||
{
|
||||
levels[shelli] = dirLevels_[shelli].first();
|
||||
}
|
||||
return levels;
|
||||
}
|
||||
|
||||
|
||||
void Foam::shellSurfaces::findHigherLevel
|
||||
(
|
||||
const pointField& pt,
|
||||
@ -824,4 +882,72 @@ void Foam::shellSurfaces::findLevel
|
||||
}
|
||||
|
||||
|
||||
void Foam::shellSurfaces::findDirectionalLevel
|
||||
(
|
||||
const pointField& pt,
|
||||
const labelList& ptLevel,
|
||||
const labelList& dirLevel, // directional level
|
||||
const direction dir,
|
||||
labelList& shell
|
||||
) const
|
||||
{
|
||||
shell.setSize(pt.size());
|
||||
shell = -1;
|
||||
|
||||
List<volumeType> volType;
|
||||
|
||||
// Current back to original
|
||||
DynamicList<label> candidateMap(pt.size());
|
||||
|
||||
forAll(shells_, shelli)
|
||||
{
|
||||
if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
|
||||
{
|
||||
const labelPair& selectLevels = dirLevels_[shelli].first();
|
||||
const label addLevel = dirLevels_[shelli].second()[dir];
|
||||
|
||||
// Collect the cells that are of the right original level
|
||||
candidateMap.clear();
|
||||
forAll(ptLevel, celli)
|
||||
{
|
||||
label level = ptLevel[celli];
|
||||
|
||||
if
|
||||
(
|
||||
level >= selectLevels.first()
|
||||
&& level <= selectLevels.second()
|
||||
&& dirLevel[celli] < level+addLevel
|
||||
)
|
||||
{
|
||||
candidateMap.append(celli);
|
||||
}
|
||||
}
|
||||
|
||||
// Do geometric test
|
||||
pointField candidatePt(pt, candidateMap);
|
||||
allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
|
||||
|
||||
// Extract selected cells
|
||||
forAll(candidateMap, i)
|
||||
{
|
||||
if
|
||||
(
|
||||
(
|
||||
modes_[shelli] == INSIDE
|
||||
&& volType[i] == volumeType::INSIDE
|
||||
)
|
||||
|| (
|
||||
modes_[shelli] == OUTSIDE
|
||||
&& volType[i] == volumeType::OUTSIDE
|
||||
)
|
||||
)
|
||||
{
|
||||
shell[candidateMap[i]] = shelli;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -39,6 +39,7 @@ SourceFiles
|
||||
#include "searchableSurface.H"
|
||||
#include "Enum.H"
|
||||
#include "Tuple2.H"
|
||||
#include "labelVector.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -85,6 +86,9 @@ private:
|
||||
//- Per shell per distance the refinement level
|
||||
labelListList levels_;
|
||||
|
||||
//- Per shell any additional directional refinement
|
||||
List<Tuple2<labelPair,labelVector>> dirLevels_;
|
||||
|
||||
|
||||
// Gap level refinement
|
||||
|
||||
@ -171,7 +175,6 @@ public:
|
||||
return shells_;
|
||||
}
|
||||
|
||||
|
||||
// Query
|
||||
|
||||
//- Highest shell level
|
||||
@ -180,6 +183,9 @@ public:
|
||||
//- Highest shell gap level
|
||||
labelList maxGapLevel() const;
|
||||
|
||||
//- Min and max cell level for directional refinement
|
||||
labelPairList directionalSelectLevel() const;
|
||||
|
||||
//- Find shell level higher than ptLevel
|
||||
void findHigherLevel
|
||||
(
|
||||
@ -215,6 +221,16 @@ public:
|
||||
const labelList& ptLevel,
|
||||
labelList& shell
|
||||
) const;
|
||||
|
||||
//- Find any shell (or -1) with higher wanted directional level
|
||||
void findDirectionalLevel
|
||||
(
|
||||
const pointField& pt,
|
||||
const labelList& ptLevel, // omnidirectional level
|
||||
const labelList& dirLevel, // directional level
|
||||
const direction dir,
|
||||
labelList& shell
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ License
|
||||
#include "IOmanip.H"
|
||||
#include "labelVector.H"
|
||||
#include "profiling.H"
|
||||
#include "searchableSurfaces.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -1573,6 +1574,217 @@ Foam::label Foam::snappyRefineDriver::shellRefine
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::snappyRefineDriver::directionalShellRefine
|
||||
(
|
||||
const refinementParameters& refineParams,
|
||||
const label maxIter
|
||||
)
|
||||
{
|
||||
addProfiling(shell, "snappyHexMesh::refine::directionalShell");
|
||||
const fvMesh& mesh = meshRefiner_.mesh();
|
||||
const shellSurfaces& shells = meshRefiner_.shells();
|
||||
|
||||
labelList& cellLevel =
|
||||
const_cast<labelIOList&>(meshRefiner_.meshCutter().cellLevel());
|
||||
labelList& pointLevel =
|
||||
const_cast<labelIOList&>(meshRefiner_.meshCutter().pointLevel());
|
||||
|
||||
|
||||
// Determine the minimum and maximum cell levels that are candidates for
|
||||
// directional refinement
|
||||
const labelPairList dirSelect(shells.directionalSelectLevel());
|
||||
label overallMinLevel = labelMax;
|
||||
label overallMaxLevel = labelMin;
|
||||
forAll(dirSelect, shelli)
|
||||
{
|
||||
overallMinLevel = min(dirSelect[shelli].first(), overallMinLevel);
|
||||
overallMaxLevel = max(dirSelect[shelli].second(), overallMaxLevel);
|
||||
}
|
||||
|
||||
if (overallMinLevel > overallMaxLevel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Maintain directional refinement levels
|
||||
List<labelVector> dirCellLevel(cellLevel.size());
|
||||
forAll(cellLevel, celli)
|
||||
{
|
||||
label l = cellLevel[celli];
|
||||
dirCellLevel[celli] = labelVector(l, l, l);
|
||||
}
|
||||
|
||||
label iter;
|
||||
for (iter = 0; iter < maxIter; iter++)
|
||||
{
|
||||
Info<< nl
|
||||
<< "Directional shell refinement iteration " << iter << nl
|
||||
<< "----------------------------------------" << nl
|
||||
<< endl;
|
||||
|
||||
label nAllRefine = 0;
|
||||
|
||||
for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||
{
|
||||
// Select the cells that need to be refined in certain direction:
|
||||
//
|
||||
// - cell inside/outside shell
|
||||
// - original cellLevel (using mapping) mentioned in levelIncrement
|
||||
// - dirCellLevel not yet up to cellLevel+levelIncrement
|
||||
|
||||
|
||||
// Extract component of directional level
|
||||
labelList currentLevel(dirCellLevel.size());
|
||||
forAll(dirCellLevel, celli)
|
||||
{
|
||||
currentLevel[celli] = dirCellLevel[celli][dir];
|
||||
}
|
||||
|
||||
labelList candidateCells
|
||||
(
|
||||
meshRefiner_.directionalRefineCandidates
|
||||
(
|
||||
refineParams.maxGlobalCells(),
|
||||
refineParams.maxLocalCells(),
|
||||
currentLevel,
|
||||
dir
|
||||
)
|
||||
);
|
||||
|
||||
// Extend to keep 2:1 ratio
|
||||
labelList cellsToRefine
|
||||
(
|
||||
meshRefiner_.meshCutter().consistentRefinement
|
||||
(
|
||||
currentLevel,
|
||||
candidateCells,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "Determined cells to refine in = "
|
||||
<< mesh.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
label nCellsToRefine = cellsToRefine.size();
|
||||
reduce(nCellsToRefine, sumOp<label>());
|
||||
|
||||
Info<< "Selected for direction " << vector::componentNames[dir]
|
||||
<< " refinement : " << nCellsToRefine
|
||||
<< " cells (out of " << mesh.globalData().nTotalCells()
|
||||
<< ')' << endl;
|
||||
|
||||
nAllRefine += nCellsToRefine;
|
||||
|
||||
// Stop when no cells to refine or have done minimum necessary
|
||||
// iterations and not enough cells to refine.
|
||||
if (nCellsToRefine > 0)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
const_cast<Time&>(mesh.time())++;
|
||||
}
|
||||
|
||||
const bitSet isRefineCell(mesh.nCells(), cellsToRefine);
|
||||
|
||||
autoPtr<mapPolyMesh> map
|
||||
(
|
||||
meshRefiner_.directionalRefine
|
||||
(
|
||||
"directional refinement iteration " + name(iter),
|
||||
dir,
|
||||
cellsToRefine
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "Refined mesh in = "
|
||||
<< mesh.time().cpuTimeIncrement() << " s" << endl;
|
||||
|
||||
meshRefinement::updateList
|
||||
(
|
||||
map().cellMap(),
|
||||
labelVector(0, 0, 0),
|
||||
dirCellLevel
|
||||
);
|
||||
|
||||
// Note: edges will have been split. The points might have
|
||||
// inherited pointLevel from either side of the edge which
|
||||
// might not be the same for coupled edges so sync
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh,
|
||||
pointLevel,
|
||||
maxEqOp<label>(),
|
||||
labelMin
|
||||
);
|
||||
|
||||
forAll(map().cellMap(), celli)
|
||||
{
|
||||
if (isRefineCell[map().cellMap()[celli]])
|
||||
{
|
||||
dirCellLevel[celli][dir]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Do something with the pointLevel. See discussion about the
|
||||
// cellLevel. Do we keep min/max ?
|
||||
forAll(map().pointMap(), pointi)
|
||||
{
|
||||
label oldPointi = map().pointMap()[pointi];
|
||||
if (map().reversePointMap()[oldPointi] != pointi)
|
||||
{
|
||||
// Is added point (splitting an edge)
|
||||
pointLevel[pointi]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nAllRefine == 0)
|
||||
{
|
||||
Info<< "Stopping refining since no cells selected."
|
||||
<< nl << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
meshRefiner_.printMeshInfo
|
||||
(
|
||||
debug,
|
||||
"After directional refinement iteration " + name(iter)
|
||||
);
|
||||
|
||||
if (debug&meshRefinement::MESH)
|
||||
{
|
||||
Pout<< "Writing directional refinement iteration "
|
||||
<< iter << " mesh to time " << meshRefiner_.timeName() << endl;
|
||||
meshRefiner_.write
|
||||
(
|
||||
meshRefinement::debugType(debug),
|
||||
meshRefinement::writeType
|
||||
(
|
||||
meshRefinement::writeLevel()
|
||||
| meshRefinement::WRITEMESH
|
||||
),
|
||||
mesh.time().path()/meshRefiner_.timeName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust cellLevel from dirLevel? As max? Or the min?
|
||||
// For now: use max. The idea is that if there is a wall
|
||||
// any directional refinement is likely to be aligned with
|
||||
// the wall (wall layers) so any snapping/layering would probably
|
||||
// want to use this highest refinement level.
|
||||
|
||||
forAll(cellLevel, celli)
|
||||
{
|
||||
cellLevel[celli] = cmptMax(dirCellLevel[celli]);
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
||||
void Foam::snappyRefineDriver::baffleAndSplitMesh
|
||||
(
|
||||
const refinementParameters& refineParams,
|
||||
@ -2065,6 +2277,13 @@ void Foam::snappyRefineDriver::doRefine
|
||||
10 // maxIter
|
||||
);
|
||||
|
||||
// Directional shell refinement
|
||||
directionalShellRefine
|
||||
(
|
||||
refineParams,
|
||||
100 // maxIter
|
||||
);
|
||||
|
||||
// Introduce baffles at surface intersections. Remove sections unreachable
|
||||
// from keepPoint.
|
||||
baffleAndSplitMesh
|
||||
|
||||
@ -36,6 +36,8 @@ SourceFiles
|
||||
|
||||
#include "wordPairHashTable.H"
|
||||
#include "labelList.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "labelVector.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -135,13 +137,22 @@ class snappyRefineDriver
|
||||
const label nBufferLayers
|
||||
);
|
||||
|
||||
//- Remove all cells inside/outside shell
|
||||
//- Refine all cells inside/outside shell
|
||||
label shellRefine
|
||||
(
|
||||
const refinementParameters& refineParams,
|
||||
const label maxIter
|
||||
);
|
||||
|
||||
// Directional refinement
|
||||
|
||||
//- Refine (directional) all cells inside/outside shell
|
||||
label directionalShellRefine
|
||||
(
|
||||
const refinementParameters& refineParams,
|
||||
const label maxIter
|
||||
);
|
||||
|
||||
//- Add baffles and remove unreachable cells
|
||||
void baffleAndSplitMesh
|
||||
(
|
||||
|
||||
12
tutorials/mesh/snappyHexMesh/aerofoilNACA0012_directionalRefinement/Allrun
Executable file
12
tutorials/mesh/snappyHexMesh/aerofoilNACA0012_directionalRefinement/Allrun
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # Run from this directory
|
||||
|
||||
# Source tutorial run functions
|
||||
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
||||
|
||||
application="$(getApplication)"
|
||||
|
||||
runApplication blockMesh
|
||||
runApplication snappyHexMesh
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -0,0 +1,47 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
location "constant";
|
||||
object thermophysicalProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
thermoType
|
||||
{
|
||||
type hePsiThermo;
|
||||
mixture pureMixture;
|
||||
transport const;
|
||||
thermo hConst;
|
||||
equationOfState perfectGas;
|
||||
specie specie;
|
||||
energy sensibleInternalEnergy;
|
||||
}
|
||||
|
||||
mixture // air at room temperature (293 K)
|
||||
{
|
||||
specie
|
||||
{
|
||||
molWeight 28.9;
|
||||
}
|
||||
thermodynamics
|
||||
{
|
||||
Cp 1005;
|
||||
Hf 0;
|
||||
}
|
||||
transport
|
||||
{
|
||||
mu 1.82e-05;
|
||||
Pr 0.71;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object turbulenceProperties;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
simulationType RAS;
|
||||
|
||||
RAS
|
||||
{
|
||||
RASModel kOmegaSST;
|
||||
turbulence on;
|
||||
printCoeffs on;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,85 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object blockMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
scale 1;
|
||||
|
||||
vertices
|
||||
(
|
||||
(-0.5 -0.1 -0.5)
|
||||
( 2 -0.1 -0.5)
|
||||
( 2 0.1 -0.5)
|
||||
(-0.5 0.1 -0.5)
|
||||
(-0.5 -0.1 0.5)
|
||||
( 2 -0.1 0.5)
|
||||
( 2 0.1 0.5)
|
||||
(-0.5 0.1 0.5)
|
||||
);
|
||||
|
||||
blocks
|
||||
(
|
||||
hex (0 1 2 3 4 5 6 7) (25 2 10) simpleGrading (1 1 1)
|
||||
);
|
||||
|
||||
edges
|
||||
(
|
||||
);
|
||||
|
||||
boundary
|
||||
(
|
||||
frontAndBack
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(3 7 6 2)
|
||||
(1 5 4 0)
|
||||
);
|
||||
}
|
||||
inlet
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(0 4 7 3)
|
||||
);
|
||||
}
|
||||
outlet
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(2 6 5 1)
|
||||
);
|
||||
}
|
||||
lowerWall
|
||||
{
|
||||
type wall;
|
||||
faces
|
||||
(
|
||||
(0 3 2 1)
|
||||
);
|
||||
}
|
||||
upperWall
|
||||
{
|
||||
type patch;
|
||||
faces
|
||||
(
|
||||
(4 5 6 7)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,48 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object controlDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
application snappyHexMesh;
|
||||
|
||||
startFrom startTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
stopAt endTime;
|
||||
|
||||
endTime 1000;
|
||||
|
||||
deltaT 1;
|
||||
|
||||
writeControl timeStep;
|
||||
|
||||
writeInterval 50;
|
||||
|
||||
purgeWrite 0;
|
||||
|
||||
writeFormat ascii;
|
||||
|
||||
writePrecision 8;
|
||||
|
||||
writeCompression off;
|
||||
|
||||
timeFormat general;
|
||||
|
||||
timePrecision 6;
|
||||
|
||||
runTimeModifiable true;
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,74 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object fvSchemes;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
ddtSchemes
|
||||
{
|
||||
default steadyState;
|
||||
}
|
||||
|
||||
gradSchemes
|
||||
{
|
||||
default Gauss linear;
|
||||
|
||||
limited cellLimited Gauss linear 1;
|
||||
grad(U) $limited;
|
||||
grad(k) $limited;
|
||||
grad(omega) $limited;
|
||||
}
|
||||
|
||||
divSchemes
|
||||
{
|
||||
default none;
|
||||
|
||||
div(phi,U) bounded Gauss linearUpwind limited;
|
||||
|
||||
turbulence bounded Gauss upwind;
|
||||
energy bounded Gauss linearUpwind limited;
|
||||
|
||||
div(phi,k) $turbulence;
|
||||
div(phi,omega) $turbulence;
|
||||
|
||||
div(phi,e) $energy;
|
||||
div(phi,K) $energy;
|
||||
div(phi,Ekp) $energy;
|
||||
|
||||
div(phid,p) Gauss upwind;
|
||||
div((phi|interpolate(rho)),p) bounded Gauss upwind;
|
||||
|
||||
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
|
||||
}
|
||||
|
||||
laplacianSchemes
|
||||
{
|
||||
default Gauss linear corrected;
|
||||
}
|
||||
|
||||
interpolationSchemes
|
||||
{
|
||||
default linear;
|
||||
}
|
||||
|
||||
snGradSchemes
|
||||
{
|
||||
default corrected;
|
||||
}
|
||||
|
||||
wallDist
|
||||
{
|
||||
method meshWave;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,65 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: dev |
|
||||
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object fvSolution;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
solvers
|
||||
{
|
||||
p
|
||||
{
|
||||
solver GAMG;
|
||||
smoother GaussSeidel;
|
||||
tolerance 1e-6;
|
||||
relTol 0.01;
|
||||
}
|
||||
|
||||
"(U|k|omega|e)"
|
||||
{
|
||||
solver PBiCGStab;
|
||||
preconditioner DILU;
|
||||
tolerance 1e-6;
|
||||
relTol 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
SIMPLE
|
||||
{
|
||||
residualControl
|
||||
{
|
||||
p 1e-4;
|
||||
U 1e-4;
|
||||
"(k|omega|e)" 1e-4;
|
||||
}
|
||||
|
||||
nNonOrthogonalCorrectors 0;
|
||||
pMinFactor 0.1;
|
||||
pMaxFactor 2;
|
||||
}
|
||||
|
||||
relaxationFactors
|
||||
{
|
||||
fields
|
||||
{
|
||||
p 0.7;
|
||||
rho 0.01;
|
||||
}
|
||||
equations
|
||||
{
|
||||
U 0.3;
|
||||
e 0.7;
|
||||
"(k|omega)" 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,21 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: plus |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object meshQualityDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Include defaults parameters from master dictionary
|
||||
#includeEtc "caseDicts/meshQualityDict"
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,317 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: plus |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
object snappyHexMeshDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Which of the steps to run
|
||||
castellatedMesh true;
|
||||
snap true;
|
||||
addLayers false;
|
||||
|
||||
|
||||
// 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
|
||||
{
|
||||
NACA0012
|
||||
{
|
||||
type triSurfaceMesh;
|
||||
file "NACA0012.obj";
|
||||
}
|
||||
wake
|
||||
{
|
||||
type searchableBox;
|
||||
min (0.8 -0.1 -0.1);
|
||||
max (2.0 0.1 0.1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 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 100000;
|
||||
|
||||
// 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 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)
|
||||
minRefinementCells 100;
|
||||
|
||||
// Number of buffer layers between different levels.
|
||||
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||
// refinement.
|
||||
nCellsBetweenLevels 1;
|
||||
|
||||
|
||||
|
||||
// Explicit feature edge refinement
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Specifies a level for any cell intersected by its edges.
|
||||
// This is a featureEdgeMesh, read from constant/triSurface for now.
|
||||
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
|
||||
{
|
||||
NACA0012
|
||||
{
|
||||
// Surface-wise min and max refinement level
|
||||
level (2 2);
|
||||
|
||||
// Optional specification of patch type (default is wall). No
|
||||
// constraint types (cyclic, symmetry) etc. are allowed.
|
||||
patchInfo
|
||||
{
|
||||
type wall;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve sharp angles on fridges
|
||||
resolveFeatureAngle 60;
|
||||
|
||||
|
||||
// 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
|
||||
// descending 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
|
||||
{
|
||||
wake
|
||||
{
|
||||
mode inside;
|
||||
|
||||
// Disable uniform refinement
|
||||
levels ((10000 0));
|
||||
|
||||
// Optional: directional refinement
|
||||
// (after all other refinement). Directional refinement
|
||||
// for all cells according to 'mode' ('inside' or 'outside';
|
||||
// 'distance' not supported) and within certain range. E.g.
|
||||
// - for all cells with level 0-1
|
||||
// - do one split in y and z direction. Note:the resulting mesh is
|
||||
// no longer compatible with e.g. dynamic
|
||||
// refinement/unrefinement.
|
||||
levelIncrement (0 1 (0 1 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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 locationInMesh is kept.
|
||||
// NOTE: This point should never be on a face, always inside a cell, even
|
||||
// after refinement.
|
||||
locationInMesh (-0.499 -0.0999 -0.499);
|
||||
|
||||
|
||||
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||
// are only on the boundary of corresponding cellZones or also allow
|
||||
// free-standing zone faces. Not used if there are no faceZones.
|
||||
allowFreeStandingZoneFaces true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Settings for the snapping.
|
||||
snapControls
|
||||
{
|
||||
//- Number of patch smoothing iterations before finding correspondence
|
||||
// to surface
|
||||
nSmoothPatch 3;
|
||||
|
||||
//- Relative distance for points to be attracted by surface feature point
|
||||
// or edge. True distance is this factor times local
|
||||
// maximum edge length.
|
||||
tolerance 2.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;
|
||||
|
||||
|
||||
// Feature snapping
|
||||
|
||||
//- Number of feature edge snapping iterations.
|
||||
// Leave out altogether to disable.
|
||||
nFeatureSnapIter 10;
|
||||
|
||||
//- Detect (geometric) features by sampling the surface (default=false)
|
||||
implicitFeatureSnap true;
|
||||
|
||||
//- Use castellatedMeshControls::features (default = true)
|
||||
explicitFeatureSnap false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
// Per final patch (so not geometry!) the layer information
|
||||
layers
|
||||
{
|
||||
"two.*"
|
||||
{
|
||||
nSurfaceLayers 3;
|
||||
}
|
||||
ground
|
||||
{
|
||||
nSurfaceLayers 3;
|
||||
}
|
||||
igloo
|
||||
{
|
||||
nSurfaceLayers 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Expansion factor for layer mesh
|
||||
expansionRatio 1.0;
|
||||
|
||||
// Wanted thickness of final added cell layer. If multiple layers
|
||||
// is the thickness of the layer furthest away from the wall.
|
||||
// Relative to undistorted size of cell outside layer.
|
||||
// See relativeSizes parameter.
|
||||
finalLayerThickness 0.5;
|
||||
|
||||
// Minimum thickness of cell layer. If for any reason layer
|
||||
// cannot be above minThickness do not add layer.
|
||||
// Relative to undistorted size of cell outside layer.
|
||||
// See relativeSizes parameter.
|
||||
minThickness 0.05;
|
||||
|
||||
// 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 17x! (didn't do anything in 17x)
|
||||
nGrow 0;
|
||||
|
||||
|
||||
// Advanced settings
|
||||
|
||||
// When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||
// are perpendicular
|
||||
featureAngle 180;
|
||||
|
||||
// Maximum number of snapping relaxation iterations. Should stop
|
||||
// before upon reaching a correct mesh.
|
||||
nRelaxIter 5;
|
||||
|
||||
// Stop layer growth on highly warped cells
|
||||
maxFaceThicknessRatio 0.5;
|
||||
|
||||
// Smooth layer thickness over surface patches
|
||||
nSmoothThickness 10;
|
||||
|
||||
|
||||
|
||||
//- Use displacementMotionSolver to shrink mesh
|
||||
meshShrinker displacementMotionSolver;
|
||||
|
||||
//- Use laplacian for shrinking
|
||||
solver displacementLaplacian;
|
||||
|
||||
displacementLaplacianCoeffs
|
||||
{
|
||||
diffusivity quadratic inverseDistance ("two.*" igloo);
|
||||
}
|
||||
|
||||
|
||||
// Create buffer region for new layer terminations
|
||||
nBufferCellsNoExtrude -1; //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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Generic mesh quality settings. At any undoable phase these determine
|
||||
// where to undo.
|
||||
meshQualityControls
|
||||
{
|
||||
#include "meshQualityDict"
|
||||
|
||||
// Advanced
|
||||
|
||||
//- Number of error distribution iterations
|
||||
nSmoothScale 4;
|
||||
//- Amount to scale back displacement at error points
|
||||
errorReduction 0.75;
|
||||
}
|
||||
|
||||
|
||||
// Advanced
|
||||
|
||||
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
|
||||
// Note: the write tolerance needs to be higher than this.
|
||||
mergeTolerance 1e-6;
|
||||
|
||||
//writeFlags (scalarLevels);
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user