ENH: snappyHexMesh: directional refinement parallel

This commit is contained in:
mattijs
2017-12-28 14:45:47 +00:00
parent 97e00442f0
commit 41f3ae3495
2 changed files with 25 additions and 204 deletions

View File

@ -1572,190 +1572,6 @@ Foam::label Foam::snappyRefineDriver::shellRefine
return iter; 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 Foam::label Foam::snappyRefineDriver::directionalShellRefine
@ -1770,6 +1586,8 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
labelList& cellLevel = labelList& cellLevel =
const_cast<labelIOList&>(meshRefiner_.meshCutter().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 // Determine the minimum and maximum cell levels that are candidates for
@ -1889,6 +1707,17 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
dirCellLevel 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) forAll(map().cellMap(), celli)
{ {
if (isRefineCell[map().cellMap()[celli]]) if (isRefineCell[map().cellMap()[celli]])
@ -1896,6 +1725,18 @@ Foam::label Foam::snappyRefineDriver::directionalShellRefine
dirCellLevel[celli][dir]++; 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]++;
}
}
} }
} }

View File

@ -146,26 +146,6 @@ class snappyRefineDriver
// Directional refinement // 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 //- Refine (directional) all cells inside/outside shell
label directionalShellRefine label directionalShellRefine
( (