ENH: snappyHexMesh: updated directional refinement

This commit is contained in:
mattijs
2017-12-13 12:27:25 +00:00
parent 88fac3ed9f
commit 52231e7836
7 changed files with 128 additions and 129 deletions

View File

@ -1087,28 +1087,6 @@ int main(int argc, char *argv[])
} }
// Optionally read directional refinement shells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const dictionary dirRefDict
(
refineDict.subOrEmptyDict("directionalRefinementRegions")
);
if (!dirRefDict.empty())
{
Info<< "Reading directional refinement shells." << endl;
}
shellSurfaces dirShells(allGeometry, dirRefDict);
if (!dirRefDict.empty())
{
Info<< "Read directional refinement shells in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
}
// Read feature meshes // Read feature meshes
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
@ -1141,7 +1119,6 @@ int main(int argc, char *argv[])
surfaces, // for surface intersection refinement surfaces, // for surface intersection refinement
features, // for feature edges/point based refinement features, // for feature edges/point based refinement
shells, // for volume (inside/outside) refinement shells, // for volume (inside/outside) refinement
dirShells, // vol volume directional refinement
limitShells // limit of volume refinement limitShells // limit of volume refinement
); );
Info<< "Calculated surface intersections in = " Info<< "Calculated surface intersections in = "

View File

@ -50,7 +50,7 @@ geometry
} }
// Shell for directional refinement // Shell for directional refinement
refinementBox wakeBox
{ {
type searchableBox; type searchableBox;
min (1.5 1 -0.5); min (1.5 1 -0.5);
@ -265,8 +265,8 @@ castellatedMeshControls
// mode inside; // mode inside;
// levels ((1.0 4)); // levels ((1.0 4));
// // Optional override of uniform refinement level such // // Optional override of uniform refinement level such
// // that in small gaps we're getting more cells. // // that in small gaps we're getting more cells.
// // The specification is // // The specification is
// // - numGapCells : minimum number of cells in the gap // // - numGapCells : minimum number of cells in the gap
// // (usually >3; lower than this might not // // (usually >3; lower than this might not
// // resolve correctly) // // resolve correctly)
@ -283,20 +283,29 @@ castellatedMeshControls
// // whilst doing the gap-level refinement. // // whilst doing the gap-level refinement.
// //gapMode inside; // inside/outside/mixed // //gapMode inside; // inside/outside/mixed
//} //}
}
//wakeBox
directionalRefinementRegions //{
{ // mode inside;
refinementBox // Closed surface // // Dummy base level
{ // levels ((10000 0));
mode inside; //
levelIncrement // Specification of additional refinement // // Optional directional refinement (after all other refinement)
( // // Directional refinement
(0 (1 0 0)) // For level 0 cells: add one level refinement in x // // for all cells according to 'mode' ('inside' or 'outside';
(1 (1 0 0)) // For level 1 cells: add one level refinement in x // // '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)
//}
} }

View File

@ -1222,7 +1222,6 @@ Foam::meshRefinement::meshRefinement
const refinementSurfaces& surfaces, const refinementSurfaces& surfaces,
const refinementFeatures& features, const refinementFeatures& features,
const shellSurfaces& shells, const shellSurfaces& shells,
const shellSurfaces& dirShells,
const shellSurfaces& limitShells const shellSurfaces& limitShells
) )
: :
@ -1233,7 +1232,6 @@ Foam::meshRefinement::meshRefinement
surfaces_(surfaces), surfaces_(surfaces),
features_(features), features_(features),
shells_(shells), shells_(shells),
dirShells_(dirShells),
limitShells_(limitShells), limitShells_(limitShells),
meshCutter_ meshCutter_
( (

View File

@ -161,9 +161,6 @@ private:
//- All shell-refinement interaction //- All shell-refinement interaction
const shellSurfaces& shells_; const shellSurfaces& shells_;
//- All directional shell-refinement interaction
const shellSurfaces& dirShells_;
//- All limit-refinement interaction //- All limit-refinement interaction
const shellSurfaces& limitShells_; const shellSurfaces& limitShells_;
@ -811,7 +808,6 @@ public:
const refinementSurfaces&, const refinementSurfaces&,
const refinementFeatures&, const refinementFeatures&,
const shellSurfaces&, // omnidirectional refinement const shellSurfaces&, // omnidirectional refinement
const shellSurfaces&, // directional refinement
const shellSurfaces& // limit refinement const shellSurfaces& // limit refinement
); );
@ -865,12 +861,6 @@ public:
return shells_; return shells_;
} }
//- Reference to directional shell-refinement shells
const shellSurfaces& dirShells() const
{
return dirShells_;
}
//- Reference to meshcutting engine //- Reference to meshcutting engine
const hexRef8& meshCutter() const const hexRef8& meshCutter() const
{ {

View File

@ -619,8 +619,29 @@ Foam::shellSurfaces::shellSurfaces
// Directional refinement // Directional refinement
// ~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~
if (dict.readIfPresent("levelIncrement", dirLevels_[shellI])) 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) if (modes_[shellI] == INSIDE)
{ {
Info<< "Additional directional refinement level" Info<< "Additional directional refinement level"
@ -771,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 void Foam::shellSurfaces::findHigherLevel
( (
const pointField& pt, const pointField& pt,
@ -871,33 +903,31 @@ void Foam::shellSurfaces::findDirectionalLevel
{ {
if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE) if (modes_[shelli] == INSIDE || modes_[shelli] == OUTSIDE)
{ {
const LevelAndDirList& shellLevels = dirLevels_[shelli]; const labelPair& selectLevels = dirLevels_[shelli].first();
const label addLevel = dirLevels_[shelli].second()[dir];
// Collect the cells that are of the right original level // Collect the cells that are of the right original level
candidateMap.clear(); candidateMap.clear();
forAll(ptLevel, celli) forAll(ptLevel, celli)
{ {
label level = ptLevel[celli]; label level = ptLevel[celli];
forAll(shellLevels, leveli)
{
label selectLevel = shellLevels[leveli].first();
label addLevel = shellLevels[leveli].second()[dir];
if if
( (
level == selectLevel level >= selectLevels.first()
&& dirLevel[celli] < level+addLevel && level <= selectLevels.second()
) && dirLevel[celli] < level+addLevel
{ )
candidateMap.append(celli); {
break; candidateMap.append(celli);
}
} }
} }
// Do geometric test
pointField candidatePt(pt, candidateMap); pointField candidatePt(pt, candidateMap);
allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType); allGeometry_[shells_[shelli]].getVolumeType(candidatePt, volType);
// Extract selected cells
forAll(candidateMap, i) forAll(candidateMap, i)
{ {
if if

View File

@ -46,10 +46,6 @@ SourceFiles
namespace Foam namespace Foam
{ {
typedef Tuple2<label,labelVector> LevelAndDir;
typedef List<LevelAndDir> LevelAndDirList;
typedef List<LevelAndDirList> LevelAndDirListList;
class searchableSurfaces; class searchableSurfaces;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -90,8 +86,8 @@ private:
//- Per shell per distance the refinement level //- Per shell per distance the refinement level
labelListList levels_; labelListList levels_;
//- Per shell, per refinement level additional directional refinement //- Per shell any additional directional refinement
LevelAndDirListList dirLevels_; List<Tuple2<labelPair,labelVector>> dirLevels_;
// Gap level refinement // Gap level refinement
@ -179,14 +175,6 @@ public:
return shells_; return shells_;
} }
//- Raw access to directional refinement
// Per shell a list of (level + additional level)
const LevelAndDirListList& dirLevels() const
{
return dirLevels_;
}
// Query // Query
//- Highest shell level //- Highest shell level
@ -195,6 +183,9 @@ public:
//- Highest shell gap level //- Highest shell gap level
labelList maxGapLevel() const; labelList maxGapLevel() const;
//- Min and max cell level for directional refinement
labelPairList directionalSelectLevel() const;
//- Find shell level higher than ptLevel //- Find shell level higher than ptLevel
void findHigherLevel void findHigherLevel
( (

View File

@ -1766,7 +1766,7 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
{ {
addProfiling(shell, "snappyHexMesh::refine::directionalShell"); addProfiling(shell, "snappyHexMesh::refine::directionalShell");
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
const shellSurfaces& shells = meshRefiner_.dirShells(); const shellSurfaces& shells = meshRefiner_.shells();
labelList& cellLevel = labelList& cellLevel =
const_cast<labelIOList&>(meshRefiner_.meshCutter().cellLevel()); const_cast<labelIOList&>(meshRefiner_.meshCutter().cellLevel());
@ -1774,19 +1774,13 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
// Determine the minimum and maximum cell levels that are candidates for // Determine the minimum and maximum cell levels that are candidates for
// directional refinement // directional refinement
const labelPairList dirSelect(shells.directionalSelectLevel());
label overallMinLevel = labelMax; label overallMinLevel = labelMax;
label overallMaxLevel = labelMin; label overallMaxLevel = labelMin;
forAll(dirSelect, shelli)
{ {
const LevelAndDirListList& dirLevels = shells.dirLevels(); overallMinLevel = min(dirSelect[shelli].first(), overallMinLevel);
forAll(dirLevels, shelli) overallMaxLevel = max(dirSelect[shelli].second(), overallMaxLevel);
{
const LevelAndDirList& dirLevel = dirLevels[shelli];
forAll(dirLevel, i)
{
overallMinLevel = min(dirLevel[i].first(), overallMinLevel);
overallMaxLevel = max(dirLevel[i].first(), overallMaxLevel);
}
}
} }
if (overallMinLevel > overallMaxLevel) if (overallMinLevel > overallMaxLevel)
@ -1889,43 +1883,45 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
// iterations and not enough cells to refine. // iterations and not enough cells to refine.
if (nCellsToRefine == 0) if (nCellsToRefine == 0)
{ {
Info<< "Not refining direction " << dir //Info<< "Not refining direction " << dir
<< " since too few cells selected." // << " since too few cells selected." << nl << endl;
<< nl << endl;
break;
} }
else
if (debug)
{ {
const_cast<Time&>(mesh.time())++; if (debug)
}
PackedBoolList isRefineCell(mesh.nCells());
isRefineCell.set(cellsToRefine);
autoPtr<mapPolyMesh> map
(
meshRefiner_.directionalRefine
(
"directional refinement iteration " + name(iter),
dir,
cellsToRefine
)
);
meshRefinement::updateList
(
map().cellMap(),
labelVector(0, 0, 0),
dirCellLevel
);
forAll(map().cellMap(), celli)
{
if (isRefineCell[map().cellMap()[celli]])
{ {
dirCellLevel[celli][dir]++; const_cast<Time&>(mesh.time())++;
}
PackedBoolList isRefineCell(mesh.nCells());
isRefineCell.set(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
);
forAll(map().cellMap(), celli)
{
if (isRefineCell[map().cellMap()[celli]])
{
dirCellLevel[celli][dir]++;
}
} }
} }
} }
@ -1946,8 +1942,8 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
if (debug&meshRefinement::MESH) if (debug&meshRefinement::MESH)
{ {
Pout<< "Writing directional refinement iteration " + name(iter) Pout<< "Writing directional refinement iteration "
<< " mesh to time " << meshRefiner_.timeName() << endl; << iter << " mesh to time " << meshRefiner_.timeName() << endl;
meshRefiner_.write meshRefiner_.write
( (
meshRefinement::debugType(debug), meshRefinement::debugType(debug),
@ -1961,8 +1957,16 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
} }
} }
// Adjust cellLevel from dirLevel? // Adjust cellLevel from dirLevel? As max? Or the min?
// Is cellLevel the max of dirLevel? 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; return iter;
} }