Merge remote-tracking branch 'origin/develop' into develop-pre-release

This commit is contained in:
mattijs
2018-05-21 17:03:58 +01:00
20 changed files with 25328 additions and 27 deletions

View File

@ -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;
}

View File

@ -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;
@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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;
}
}
}
}
}
// ************************************************************************* //

View File

@ -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;
};

View File

@ -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

View File

@ -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
(

View 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
#------------------------------------------------------------------------------

View File

@ -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;
}
}
// ************************************************************************* //

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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)
);
}
);
// ************************************************************************* //

View File

@ -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;
// ************************************************************************* //

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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;
}
}
// ************************************************************************* //

View File

@ -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"
// ************************************************************************* //

View File

@ -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);
// ************************************************************************* //