mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: snappyHexMesh: directional refinement parallel
This commit is contained in:
@ -1572,190 +1572,6 @@ Foam::label Foam::snappyRefineDriver::shellRefine
|
||||
|
||||
return iter;
|
||||
}
|
||||
//XXXXXXXXXX
|
||||
Foam::List<Foam::direction> Foam::snappyRefineDriver::faceDirection() const
|
||||
{
|
||||
const fvMesh& mesh = meshRefiner_.mesh();
|
||||
|
||||
List<direction> faceDir(mesh.nFaces());
|
||||
|
||||
vectorField nf(mesh.faceAreas());
|
||||
nf /= mag(nf);
|
||||
|
||||
forAll(nf, facei)
|
||||
{
|
||||
const vector& n = nf[facei];
|
||||
if (mag(n[0]) > 0.5)
|
||||
{
|
||||
faceDir[facei] = 0;
|
||||
}
|
||||
else if (mag(n[1]) > 0.5)
|
||||
{
|
||||
faceDir[facei] = 1;
|
||||
}
|
||||
else if (mag(n[2]) > 0.5)
|
||||
{
|
||||
faceDir[facei] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return faceDir;
|
||||
}
|
||||
Foam::label Foam::snappyRefineDriver::faceConsistentRefinement
|
||||
(
|
||||
const PackedBoolList& isDirFace,
|
||||
const List<labelVector>& dirCellLevel,
|
||||
const direction dir,
|
||||
const bool maxSet,
|
||||
PackedBoolList& refineCell
|
||||
) const
|
||||
{
|
||||
const fvMesh& mesh = meshRefiner_.mesh();
|
||||
|
||||
label nChanged = 0;
|
||||
|
||||
// Internal faces.
|
||||
for (label facei = 0; facei < mesh.nInternalFaces(); facei++)
|
||||
{
|
||||
if (isDirFace[facei])
|
||||
{
|
||||
label own = mesh.faceOwner()[facei];
|
||||
label ownLevel = dirCellLevel[own][dir] + refineCell.get(own);
|
||||
|
||||
label nei = mesh.faceNeighbour()[facei];
|
||||
label neiLevel = dirCellLevel[nei][dir] + refineCell.get(nei);
|
||||
|
||||
if (ownLevel > (neiLevel+1))
|
||||
{
|
||||
if (maxSet)
|
||||
{
|
||||
refineCell.set(nei);
|
||||
}
|
||||
else
|
||||
{
|
||||
refineCell.unset(own);
|
||||
}
|
||||
nChanged++;
|
||||
}
|
||||
else if (neiLevel > (ownLevel+1))
|
||||
{
|
||||
if (maxSet)
|
||||
{
|
||||
refineCell.set(own);
|
||||
}
|
||||
else
|
||||
{
|
||||
refineCell.unset(nei);
|
||||
}
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Coupled faces. Swap owner level to get neighbouring cell level.
|
||||
// (only boundary faces of neiLevel used)
|
||||
labelList neiLevel(mesh.nFaces()-mesh.nInternalFaces());
|
||||
|
||||
forAll(neiLevel, i)
|
||||
{
|
||||
label own = mesh.faceOwner()[i+mesh.nInternalFaces()];
|
||||
|
||||
neiLevel[i] = dirCellLevel[own][dir] + refineCell.get(own);
|
||||
}
|
||||
|
||||
// Swap to neighbour
|
||||
syncTools::swapBoundaryFaceList(mesh, neiLevel);
|
||||
|
||||
// Now we have neighbour value see which cells need refinement
|
||||
forAll(neiLevel, i)
|
||||
{
|
||||
label facei = i+mesh.nInternalFaces();
|
||||
if (isDirFace[facei])
|
||||
{
|
||||
label own = mesh.faceOwner()[facei];
|
||||
label ownLevel = dirCellLevel[own][dir] + refineCell.get(own);
|
||||
|
||||
if (ownLevel > (neiLevel[i]+1))
|
||||
{
|
||||
if (!maxSet)
|
||||
{
|
||||
refineCell.unset(own);
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
else if (neiLevel[i] > (ownLevel+1))
|
||||
{
|
||||
if (maxSet)
|
||||
{
|
||||
refineCell.set(own);
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nChanged;
|
||||
}
|
||||
Foam::labelList Foam::snappyRefineDriver::consistentDirectionalRefinement
|
||||
(
|
||||
const direction dir,
|
||||
const List<labelVector>& dirCellLevel,
|
||||
const labelUList& candidateCells,
|
||||
const bool maxSet
|
||||
) const
|
||||
{
|
||||
const fvMesh& mesh = meshRefiner_.mesh();
|
||||
|
||||
const List<direction> faceDir(faceDirection());
|
||||
|
||||
PackedBoolList isDirFace(mesh.nFaces());
|
||||
forAll(faceDir, facei)
|
||||
{
|
||||
if (faceDir[facei] == dir)
|
||||
{
|
||||
isDirFace[facei] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop, modifying cellsToRefine, until no more changes to due to 2:1
|
||||
// conflicts.
|
||||
// maxSet = false : unselect cells to refine
|
||||
// maxSet = true : select cells to refine
|
||||
|
||||
// Go to straight boolList.
|
||||
PackedBoolList isRefineCell(mesh.nCells());
|
||||
isRefineCell.set(candidateCells);
|
||||
|
||||
while (true)
|
||||
{
|
||||
label nChanged = faceConsistentRefinement
|
||||
(
|
||||
isDirFace,
|
||||
dirCellLevel,
|
||||
dir,
|
||||
maxSet,
|
||||
isRefineCell
|
||||
);
|
||||
|
||||
reduce(nChanged, sumOp<label>());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "snappyRefineDriver::consistentDirectionalRefinement"
|
||||
<< " : Changed " << nChanged
|
||||
<< " refinement levels due to 2:1 conflicts."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if (nChanged == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return isRefineCell.used();
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::snappyRefineDriver::directionalShellRefine
|
||||
@ -1770,6 +1586,8 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
|
||||
|
||||
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
|
||||
@ -1889,6 +1707,17 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
|
||||
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]])
|
||||
@ -1896,6 +1725,18 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
|
||||
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]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -146,26 +146,6 @@ class snappyRefineDriver
|
||||
|
||||
// Directional refinement
|
||||
|
||||
//- Calculate direction of face (using geometry)
|
||||
List<direction> faceDirection() const;
|
||||
|
||||
//- Check if level across (directed) face obeys 2:1
|
||||
label faceConsistentRefinement
|
||||
(
|
||||
const PackedBoolList& isDirFace,
|
||||
const List<labelVector>& dirCellLevel,
|
||||
const direction dir,
|
||||
const bool maxSet,
|
||||
PackedBoolList& refineCell
|
||||
) const;
|
||||
//- Make sure 2:1 refinement in given direction
|
||||
labelList consistentDirectionalRefinement
|
||||
(
|
||||
const direction dir,
|
||||
const List<labelVector>& dirCellLevel,
|
||||
const labelUList& candidateCells,
|
||||
const bool maxSet
|
||||
) const;
|
||||
//- Refine (directional) all cells inside/outside shell
|
||||
label directionalShellRefine
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user