Merge branch 'polyhedralAMR-improvements' into CumulativeDevelopment-VukoVukcevic-nextRelease
This commit is contained in:
commit
2e170aa989
13 changed files with 680 additions and 239 deletions
|
@ -2930,15 +2930,19 @@ Foam::label Foam::polyhedralRefinement::faceConsistentRefinement
|
|||
const label curOwnLevel =
|
||||
cellsToRefine[own] ? cellLevel_[own] + 1 : cellLevel_[own];
|
||||
|
||||
if (neiLevel[i] > (curOwnLevel + 1))
|
||||
// Note: we are using more stringent 1:1 consistency across coupled
|
||||
// boundaries in order to simplify handling of edge based consistency
|
||||
// checks for parallel runs
|
||||
if (neiLevel[i] > curOwnLevel)
|
||||
{
|
||||
// Neighbour level is higher than owner level + 1, owner must be
|
||||
// Neighbour level is higher than owner level, owner must be
|
||||
// marked for refinement
|
||||
cellsToRefine[own] = true;
|
||||
++nAddCells;
|
||||
}
|
||||
|
||||
// Note: other possibility (that owner level is higher than neighbour
|
||||
// level + 1) is taken into account on the other side automatically
|
||||
// level) is taken into account on the other side automatically
|
||||
}
|
||||
|
||||
// Return number of added cells
|
||||
|
@ -2946,7 +2950,7 @@ Foam::label Foam::polyhedralRefinement::faceConsistentRefinement
|
|||
}
|
||||
|
||||
|
||||
Foam::label Foam::polyhedralRefinement::pointConsistentRefinement
|
||||
Foam::label Foam::polyhedralRefinement::edgeConsistentRefinement
|
||||
(
|
||||
boolList& cellsToRefine
|
||||
) const
|
||||
|
@ -2954,90 +2958,75 @@ Foam::label Foam::polyhedralRefinement::pointConsistentRefinement
|
|||
// Count number of cells that will be added
|
||||
label nAddCells = 0;
|
||||
|
||||
// Maximum surrounding cell refinement level for each point
|
||||
labelList maxRefLevel(mesh_.nPoints(), 0);
|
||||
// Algorithm: loop over all edges and visit all unique cell pairs sharing
|
||||
// this particular edge. Then, ensure 2:1 edge consistency by marking
|
||||
// cell with lower level for refinement
|
||||
|
||||
// Get point cells
|
||||
const labelListList& meshPointCells = mesh_.pointCells();
|
||||
// Get edge cells
|
||||
const labelListList& meshEdgeCells = mesh_.edgeCells();
|
||||
|
||||
// Loop through all points and collect maximum point level for each point
|
||||
forAll (maxRefLevel, pointI)
|
||||
// Loop through all mesh edges
|
||||
forAll (meshEdgeCells, edgeI)
|
||||
{
|
||||
// Get the cells for this point
|
||||
const labelList& curCells = meshPointCells[pointI];
|
||||
// Get current edge cells
|
||||
const labelList& curEdgeCells = meshEdgeCells[edgeI];
|
||||
|
||||
// Get reference to maximum pooint level for this point
|
||||
label& curMaxPointLevel = maxRefLevel[pointI];
|
||||
|
||||
// Find maximum refinement level for this point
|
||||
forAll (curCells, i)
|
||||
// Loop through all edge cells
|
||||
forAll (curEdgeCells, i)
|
||||
{
|
||||
// Get cell index and "future" cell level
|
||||
const label& curCellI = curCells[i];
|
||||
const label curCellLevel =
|
||||
cellsToRefine[curCellI]
|
||||
? cellLevel_[curCellI] + 1
|
||||
: cellLevel_[curCellI];
|
||||
// Get first cell index
|
||||
const label& cellI = curEdgeCells[i];
|
||||
|
||||
// Update maximum point level if the curCellLevel is higher
|
||||
curMaxPointLevel = max(curMaxPointLevel, curCellLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Sync maximum refinement level across coupled boundaries
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh_,
|
||||
maxRefLevel,
|
||||
maxEqOp<label>(),
|
||||
0, // Null value
|
||||
true // Apply separation for parallel cyclics
|
||||
);
|
||||
|
||||
// Now that the levels are synced, go through all points and add cells to
|
||||
// refine
|
||||
forAll (maxRefLevel, pointI)
|
||||
// Loop through remaining edge cells
|
||||
for (label j = i + 1; j < curEdgeCells.size(); ++j)
|
||||
{
|
||||
// Get the cells for this point
|
||||
const labelList& curCells = meshPointCells[pointI];
|
||||
// Get second cell index
|
||||
const label& cellJ = curEdgeCells[j];
|
||||
|
||||
// Loop through these point cells and set cells for refinement which
|
||||
// would end up having refinement level smaller than maximum level - 1
|
||||
forAll (curCells, i)
|
||||
{
|
||||
// Get cell index, reference to refinement flag and "future" cell
|
||||
// level
|
||||
const label& curCellI = curCells[i];
|
||||
bool& willBeRefined = cellsToRefine[curCellI];
|
||||
const label curCellLevel =
|
||||
willBeRefined
|
||||
? cellLevel_[curCellI] + 1
|
||||
: cellLevel_[curCellI];
|
||||
// Get levels of the two cells. If the cell is marked for
|
||||
// refinement, the level is current level + 1, otherwise it is
|
||||
// equal to the current level
|
||||
|
||||
if (curCellLevel < maxRefLevel[pointI] - 1)
|
||||
// Note: cellsToRefine flag for both cellI and cellJ might
|
||||
// change, this is why we need to recalculate cellI level here
|
||||
const label cellILevel =
|
||||
cellsToRefine[cellI]
|
||||
? cellLevel_[cellI] + 1
|
||||
: cellLevel_[cellI];
|
||||
|
||||
const label cellJLevel =
|
||||
cellsToRefine[cellJ]
|
||||
? cellLevel_[cellJ] + 1
|
||||
: cellLevel_[cellJ];
|
||||
|
||||
if (cellILevel > cellJLevel + 1)
|
||||
{
|
||||
if (!willBeRefined)
|
||||
{
|
||||
// Cell has not been marked for refinement, mark the cell for
|
||||
// refinement and increment the counter
|
||||
willBeRefined = true;
|
||||
// Level of cellI is higher than level of cellJ + 1, cellJ
|
||||
// must be marked for refinement
|
||||
cellsToRefine[cellJ] = true;
|
||||
++nAddCells;
|
||||
}
|
||||
else
|
||||
else if (cellJLevel > cellILevel + 1)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"label polyhedralRefinement::pointConsistentRefinement"
|
||||
"(boolList cellsToRefine) const"
|
||||
) << "Cell is marked for refinement, but the 4:1 point"
|
||||
<< " consistency cannot be ensured." << nl
|
||||
<< "Something went wrong before this step."
|
||||
<< endl;
|
||||
// Level of cellJ is higher than level of cellI + 1, cellI
|
||||
// must be marked for refinement
|
||||
cellsToRefine[cellI] = true;
|
||||
++nAddCells;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: in order to avoid very difficult and time-consuming parallelisation
|
||||
// of edge cell connectivity and edge cell values, we enforce a more
|
||||
// stringent face-based consistency across processor boundaries. Basically,
|
||||
// if a face-based consistency of 1:1 (not 2:1 as for ordinary faces) is
|
||||
// ensured, the edge-based consistency becomes a local operation (I'm not
|
||||
// 100% sure to be honest since there are countless variants when dealing
|
||||
// with arbitrary polyhedral cells).
|
||||
// See faceConsistentRefinement for details. VV, 17/Apr/2018.
|
||||
|
||||
// Return number of added cells
|
||||
return nAddCells;
|
||||
}
|
||||
|
||||
|
@ -3090,7 +3079,10 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
<< "Owner: " << own << ", neighbour: " << nei
|
||||
<< nl
|
||||
<< "Owner level: " << ownLevel
|
||||
<< ", neighbour level: " << neiLevel
|
||||
<< ", neighbour level: " << neiLevel << nl
|
||||
<< "This is probably because the refinement and "
|
||||
<< "unrefinement regions are very close." << nl
|
||||
<< "Try increasing nUnrefinementBufferLayers. "
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
@ -3115,7 +3107,10 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
<< "Owner: " << own << ", neighbour: " << nei
|
||||
<< nl
|
||||
<< "Owner level: " << ownLevel
|
||||
<< ", neighbour level: " << neiLevel
|
||||
<< ", neighbour level: " << neiLevel << nl
|
||||
<< "This is probably because the refinement and "
|
||||
<< "unrefinement regions are very close." << nl
|
||||
<< "Try increasing nUnrefinementBufferLayers. "
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
@ -3150,9 +3145,12 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
const label curOwnLevel =
|
||||
cellsToUnrefine[own] ? cellLevel_[own] - 1 : cellLevel_[own];
|
||||
|
||||
if (curOwnLevel < (neiLevel[i] - 1))
|
||||
// Note: we are using more stringent 1:1 consistency across coupled
|
||||
// boundaries in order to simplify handling of edge based consistency
|
||||
// checkes for parallel runs
|
||||
if (curOwnLevel < neiLevel[i])
|
||||
{
|
||||
// Owner level is smaller than neighbour level - 1, we must not
|
||||
// Owner level is smaller than neighbour level, we must not
|
||||
// unrefine owner
|
||||
|
||||
// Check whether the cell has not been marked for unrefinement
|
||||
|
@ -3168,7 +3166,10 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
<< "Owner: " << own
|
||||
<< nl
|
||||
<< "Owner level: " << curOwnLevel
|
||||
<< ", neighbour level: " << neiLevel[i]
|
||||
<< ", neighbour level: " << neiLevel[i] << nl
|
||||
<< "This is probably because the refinement and "
|
||||
<< "unrefinement regions are very close." << nl
|
||||
<< "Try increasing nUnrefinementBufferLayers. "
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
|
@ -3177,7 +3178,7 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
}
|
||||
|
||||
// Note: other possibility (that neighbour level is smaller than owner
|
||||
// level - 1) is taken into account on the other side automatically
|
||||
// level) is taken into account on the other side automatically
|
||||
}
|
||||
|
||||
// Return number of local cells removed from unrefinement
|
||||
|
@ -3185,100 +3186,129 @@ Foam::label Foam::polyhedralRefinement::faceConsistentUnrefinement
|
|||
}
|
||||
|
||||
|
||||
Foam::label Foam::polyhedralRefinement::pointConsistentUnrefinement
|
||||
Foam::label Foam::polyhedralRefinement::edgeConsistentUnrefinement
|
||||
(
|
||||
boolList& cellsToUnrefine
|
||||
) const
|
||||
{
|
||||
// Count number of cells removed from unrefinement
|
||||
// Count number of cells that will be removed
|
||||
label nRemCells = 0;
|
||||
|
||||
// Minimum cell refinement level for each point. Note: initialise with
|
||||
// labelMax
|
||||
labelList minRefLevel(mesh_.nPoints(), labelMax);
|
||||
// Algorithm: loop over all edges and visit all unique cell pairs sharing
|
||||
// this particular edge. Then, ensure 2:1 edge consistency by protecting the
|
||||
// cell with lower level from unrefinement
|
||||
|
||||
// Get point cells
|
||||
const labelListList& meshPointCells = mesh_.pointCells();
|
||||
// Get edge cells
|
||||
const labelListList& meshEdgeCells = mesh_.edgeCells();
|
||||
|
||||
// Loop through all points and collect minimum point level for each point
|
||||
forAll (minRefLevel, pointI)
|
||||
// Loop through all mesh edges
|
||||
forAll (meshEdgeCells, edgeI)
|
||||
{
|
||||
// Get the cell for this point
|
||||
const labelList& curCells = meshPointCells[pointI];
|
||||
// Get current edge cells
|
||||
const labelList& curEdgeCells = meshEdgeCells[edgeI];
|
||||
|
||||
// Get reference to minimum point level for this point
|
||||
label& curMinPointLevel = minRefLevel[pointI];
|
||||
|
||||
// Find minimum refinement level for this point
|
||||
forAll (curCells, i)
|
||||
// Loop through all edge cells
|
||||
forAll (curEdgeCells, i)
|
||||
{
|
||||
// Get cell index and "future" cell level
|
||||
const label& curCellI = curCells[i];
|
||||
const label curCellLevel =
|
||||
cellsToUnrefine[curCellI]
|
||||
? cellLevel_[curCellI] - 1
|
||||
: cellLevel_[curCellI];
|
||||
// Get first cell index
|
||||
const label& cellI = curEdgeCells[i];
|
||||
|
||||
// Update minimum point level if the curCellLevel is smaller
|
||||
curMinPointLevel = min(curMinPointLevel, curCellLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// Sync minimum refinement level across coupled boundaries
|
||||
syncTools::syncPointList
|
||||
(
|
||||
mesh_,
|
||||
minRefLevel,
|
||||
minEqOp<label>(),
|
||||
0, // Null value
|
||||
true // Apply separation for parallel cyclics
|
||||
);
|
||||
|
||||
// Now that the levels are synced, go through all points and protect some
|
||||
// cells from unrefinement
|
||||
forAll (minRefLevel, pointI)
|
||||
// Loop through remaining edge cells
|
||||
for (label j = i + 1; j < curEdgeCells.size(); ++j)
|
||||
{
|
||||
// Get the cells for this point
|
||||
const labelList& curCells = meshPointCells[pointI];
|
||||
// Get second cell index
|
||||
const label& cellJ = curEdgeCells[j];
|
||||
|
||||
// Loop through these point cells and protected cells from unrefinement
|
||||
// which would end up having refinement level greater than level + 1
|
||||
forAll (curCells, i)
|
||||
{
|
||||
// Get cell index, reference to unrefinement flag and "future" cell
|
||||
// level
|
||||
const label& curCellI = curCells[i];
|
||||
bool& willBeUnrefined = cellsToUnrefine[curCellI];
|
||||
const label curCellLevel =
|
||||
willBeUnrefined
|
||||
? cellLevel_[curCellI] - 1
|
||||
: cellLevel_[curCellI];
|
||||
// Get levels of the two cells. If the cell is marked for
|
||||
// unrefinement, the level is current level - 1, otherwise it is
|
||||
// equal to the current level
|
||||
|
||||
if (curCellLevel > minRefLevel[pointI] + 1)
|
||||
// Note: cellsToUnrefine flag for both cellI and cellJ might
|
||||
// change, this is why we need to recalculate cellI level here
|
||||
const label cellILevel =
|
||||
cellsToUnrefine[cellI]
|
||||
? cellLevel_[cellI] - 1
|
||||
: cellLevel_[cellI];
|
||||
|
||||
const label cellJLevel =
|
||||
cellsToUnrefine[cellJ]
|
||||
? cellLevel_[cellJ] - 1
|
||||
: cellLevel_[cellJ];
|
||||
|
||||
if (cellILevel < cellJLevel - 1)
|
||||
{
|
||||
if (willBeUnrefined)
|
||||
{
|
||||
// Cell has been marked for unrefinement, protect the cell
|
||||
// from unrefinement and increment the counter
|
||||
willBeUnrefined = false;
|
||||
++nRemCells;
|
||||
}
|
||||
else
|
||||
// Level of cellI is smaller than level of cellJ - 1, cellI
|
||||
// must be protected from unrefinement
|
||||
|
||||
// Check whether the cell has not been marked for
|
||||
// unrefinement
|
||||
if (!cellsToUnrefine[cellI])
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"label polyhedralRefinement::"
|
||||
"pointConsistentUnrefinement"
|
||||
"(boolList cellsToRefine) const"
|
||||
) << "Cell is not marked for unrefinement, but the 4:1"
|
||||
<< " point consistency cannot be ensured." << nl
|
||||
<< "Something went wrong before this step."
|
||||
<< endl;
|
||||
"edgeConsistentUnrefinement"
|
||||
"(boolList& cellsToUnrefine)"
|
||||
) << "Cell not marked for unrefinement, indicating a"
|
||||
<< " previous unnoticed problem with unrefinement."
|
||||
<< nl
|
||||
<< "cellI: " << cellI << ", cellJ: " << cellJ
|
||||
<< nl
|
||||
<< "Level of cellI: " << cellILevel
|
||||
<< ", level of cellJ: " << cellJLevel << nl
|
||||
<< "This is probably because the refinement and "
|
||||
<< "unrefinement regions are very close." << nl
|
||||
<< "Try increasing nUnrefinementBufferLayers. "
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
cellsToUnrefine[cellI] = false;
|
||||
++nRemCells;
|
||||
}
|
||||
else if (cellJLevel < cellILevel - 1)
|
||||
{
|
||||
// Level of cellJ is smaller than level of cellI - 1, cellJ
|
||||
// must be protected from unrefinement
|
||||
|
||||
// Check whether the cell has not been marked for
|
||||
// unrefinement
|
||||
if (!cellsToUnrefine[cellJ])
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"label polyhedralRefinement::"
|
||||
"edgeConsistentUnrefinement"
|
||||
"(boolList& cellsToUnrefine)"
|
||||
) << "Cell not marked for unrefinement, indicating a"
|
||||
<< " previous unnoticed problem with unrefinement."
|
||||
<< nl
|
||||
<< "cellI: " << cellI << ", cellJ: " << cellJ
|
||||
<< nl
|
||||
<< "Level of cellI: " << cellILevel
|
||||
<< ", level of cellJ: " << cellJLevel << nl
|
||||
<< "This is probably because the refinement and "
|
||||
<< "unrefinement regions are very close." << nl
|
||||
<< "Try increasing nUnrefinementBufferLayers. "
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
cellsToUnrefine[cellJ] = false;
|
||||
++nRemCells;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: in order to avoid very difficult and time-consuming parallelisation
|
||||
// of edge cell connectivity and edge cell values, we enforce a more
|
||||
// stringent face-based consistency across processor boundaries. Basically,
|
||||
// if a face-based consistency of 1:1 (not 2:1 as for ordinary faces) is
|
||||
// ensured, the edge-based consistency becomes a local operation (I'm not
|
||||
// 100% sure to be honest whether this is true all the time since there are
|
||||
// countless variants when dealing with arbitrary polyhedral cells).
|
||||
// See faceConsistentRefinement for details. VV, 3/Apr/2018.
|
||||
|
||||
// Return number of removed cells
|
||||
return nRemCells;
|
||||
}
|
||||
|
||||
|
@ -3328,11 +3358,18 @@ Foam::polyhedralRefinement::polyhedralRefinement
|
|||
faceRemover_(mesh_, GREAT), // Merge boundary faces wherever possible
|
||||
maxCells_(readLabel(dict.lookup("maxCells"))),
|
||||
maxRefinementLevel_(readLabel(dict.lookup("maxRefinementLevel"))),
|
||||
pointBasedConsistency_
|
||||
edgeBasedConsistency_
|
||||
(
|
||||
dict.lookupOrDefault<Switch>("pointBasedConsistency", true)
|
||||
dict.lookupOrDefault<Switch>("edgeBasedConsistency", true)
|
||||
),
|
||||
nBufferLayers_(readScalar(dict.lookup("nBufferLayers")))
|
||||
nRefinementBufferLayers_
|
||||
(
|
||||
readScalar(dict.lookup("nRefinementBufferLayers"))
|
||||
),
|
||||
nUnrefinementBufferLayers_
|
||||
(
|
||||
readScalar(dict.lookup("nUnrefinementBufferLayers"))
|
||||
)
|
||||
{
|
||||
// Calculate level 0 edge length
|
||||
calcLevel0EdgeLength();
|
||||
|
@ -3401,7 +3438,7 @@ Foam::polyhedralRefinement::polyhedralRefinement
|
|||
|
||||
// If the maximum refinementLevel is greater than 2 and the user insists on
|
||||
// not using point based refinement strategy, issue a warning
|
||||
if (!pointBasedConsistency_ && maxRefinementLevel_ > 2)
|
||||
if (!edgeBasedConsistency_ && maxRefinementLevel_ > 2)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
|
@ -3420,12 +3457,12 @@ Foam::polyhedralRefinement::polyhedralRefinement
|
|||
<< " 8:1 point conflicts."
|
||||
<< nl
|
||||
<< "In order to supress this message and use point based"
|
||||
<< " consistency checks, set pointBasedConsistency to true."
|
||||
<< " consistency checks, set edgeBasedConsistency to true."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Check number of buffer layers
|
||||
if (nBufferLayers_ < 0)
|
||||
// Check number of refinement buffer layers
|
||||
if (nRefinementBufferLayers_ < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
|
@ -3436,11 +3473,53 @@ Foam::polyhedralRefinement::polyhedralRefinement
|
|||
"\n const label index,"
|
||||
"\n const polyTopoChanger& mme"
|
||||
"\n)"
|
||||
) << "Negative nBufferLayers specified."
|
||||
) << "Negative nRefinementBufferLayers specified."
|
||||
<< nl
|
||||
<< "This is not allowed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Check number of unrefinement buffer layers
|
||||
if (nUnrefinementBufferLayers_ < 0)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"polyhedralRefinement::polyhedralRefinement"
|
||||
"\n("
|
||||
"\n const word& name,"
|
||||
"\n const dictionary& dict,"
|
||||
"\n const label index,"
|
||||
"\n const polyTopoChanger& mme"
|
||||
"\n)"
|
||||
) << "Negative nUnrefinementBufferLayers specified."
|
||||
<< nl
|
||||
<< "This is not allowed."
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Check whether the number of unrefinement buffer layers is smaller than
|
||||
// number of refinement buffer layers + 2
|
||||
if (nUnrefinementBufferLayers_ < nRefinementBufferLayers_ + 2)
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"polyhedralRefinement::polyhedralRefinement"
|
||||
"\n("
|
||||
"\n const word& name,"
|
||||
"\n const dictionary& dict,"
|
||||
"\n const label index,"
|
||||
"\n const polyTopoChanger& mme"
|
||||
"\n)"
|
||||
) << "Using " << nUnrefinementBufferLayers_
|
||||
<< " unrefinement buffer layers and " << nRefinementBufferLayers_
|
||||
<< " refinement buffer layers."
|
||||
<< nl
|
||||
<< "Make sure that the number of unrefinement buffer layers is "
|
||||
<< "at least nRefinementBufferLayers + 2" << nl
|
||||
<< "in order to avoid problems with point level inconsistency when "
|
||||
<< "refinement and unrefinement are performed in same iteration."
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3495,8 +3574,9 @@ void Foam::polyhedralRefinement::setCellsToRefine
|
|||
}
|
||||
}
|
||||
|
||||
// Extend cells across faces using a specified number of buffer layers
|
||||
for (label i = 0; i < nBufferLayers_; ++i)
|
||||
// Extend cells across faces using a specified number of refinement buffer
|
||||
// layers
|
||||
for (label i = 0; i < nRefinementBufferLayers_; ++i)
|
||||
{
|
||||
extendMarkedCellsAcrossFaces(refineCell);
|
||||
}
|
||||
|
@ -3515,11 +3595,11 @@ void Foam::polyhedralRefinement::setCellsToRefine
|
|||
// Reset counter at the beginning of each iteration
|
||||
nAddCells = 0;
|
||||
|
||||
if (pointBasedConsistency_)
|
||||
if (edgeBasedConsistency_)
|
||||
{
|
||||
// Check for 4:1 point based consistent refinement. Updates
|
||||
// Check for 4:1 edge based consistent refinement. Updates
|
||||
// cellsToRefine and returns number of cells added in this iteration
|
||||
nAddCells += pointConsistentRefinement(refineCell);
|
||||
nAddCells += edgeConsistentRefinement(refineCell);
|
||||
}
|
||||
|
||||
// Check for 2:1 face based consistent refinement. Updates cellsToRefine
|
||||
|
@ -3555,9 +3635,7 @@ void Foam::polyhedralRefinement::setCellsToRefine
|
|||
// Transfer the contents into the data member (ordinary list)
|
||||
cellsToRefine_.transfer(cellsToRefineDynamic);
|
||||
|
||||
Info<< "polyhedralRefinement::setCellsToRefine"
|
||||
<< "(const labelList& refinementCellCandidates)" << nl
|
||||
<< "Selected " << returnReduce(cellsToRefine_.size(), sumOp<label>())
|
||||
Info<< "Selected " << returnReduce(cellsToRefine_.size(), sumOp<label>())
|
||||
<< " cells to refine." << endl;
|
||||
}
|
||||
|
||||
|
@ -3708,10 +3786,9 @@ void Foam::polyhedralRefinement::setSplitPointsToUnrefine
|
|||
protectedCell[cellsToRefine_[i]] = true;
|
||||
}
|
||||
|
||||
// Extend protected cells across points using a specified number of buffer
|
||||
// layers + 1 in order to stay far away from cells that are going to be
|
||||
// refined
|
||||
for (label i = 0; i < nBufferLayers_ + 1; ++i)
|
||||
// Extend protected cells across points using a specified number of
|
||||
// unrefinement buffer layers
|
||||
for (label i = 0; i < nUnrefinementBufferLayers_ + 2; ++i)
|
||||
{
|
||||
extendMarkedCellsAcrossPoints(protectedCell);
|
||||
}
|
||||
|
@ -3771,12 +3848,12 @@ void Foam::polyhedralRefinement::setSplitPointsToUnrefine
|
|||
// Reset number of removed cells from unrefinement for this iteration
|
||||
nRemCells = 0;
|
||||
|
||||
if (pointBasedConsistency_)
|
||||
if (edgeBasedConsistency_)
|
||||
{
|
||||
// Check for 4:1 point based consistent unrefinement. Updates
|
||||
// Check for 4:1 edge based consistent unrefinement. Updates
|
||||
// cellsToUnrefine and returns number of removed cells from
|
||||
// unrefinement in this iteration
|
||||
nRemCells += pointConsistentUnrefinement(cellsToUnrefine);
|
||||
nRemCells += edgeConsistentUnrefinement(cellsToUnrefine);
|
||||
}
|
||||
|
||||
// Check for 2:1 face based consistent unrefinement. Updates
|
||||
|
@ -3843,9 +3920,7 @@ void Foam::polyhedralRefinement::setSplitPointsToUnrefine
|
|||
// Transfer the contents into the data member (ordinary list)
|
||||
splitPointsToUnrefine_.transfer(splitPointsToUnrefineDynamic);
|
||||
|
||||
Info<< "polyhedralRefinement::setSplitPointsToUnrefine"
|
||||
<< "(const labelList& unrefinementPointCandidates)" << nl
|
||||
<< "Selected "
|
||||
Info<< "Selected "
|
||||
<< returnReduce(splitPointsToUnrefine_.size(), sumOp<label>())
|
||||
<< " split points to unrefine." << endl;
|
||||
}
|
||||
|
@ -4063,8 +4138,9 @@ void Foam::polyhedralRefinement::write(Ostream& os) const
|
|||
<< name() << nl
|
||||
<< maxCells_ << nl
|
||||
<< maxRefinementLevel_ << nl
|
||||
<< pointBasedConsistency_ << nl
|
||||
<< nBufferLayers_ << endl;
|
||||
<< edgeBasedConsistency_ << nl
|
||||
<< nRefinementBufferLayers_ << nl
|
||||
<< nUnrefinementBufferLayers_ << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4081,9 +4157,11 @@ void Foam::polyhedralRefinement::writeDict(Ostream& os) const
|
|||
<< token::END_STATEMENT << nl
|
||||
<< " maxRefinementLevel " << maxRefinementLevel_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " pointBasedConsistency " << pointBasedConsistency_
|
||||
<< " edgeBasedConsistency " << edgeBasedConsistency_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " nBufferLayers " << nBufferLayers_
|
||||
<< " nRefinementBufferLayers " << nRefinementBufferLayers_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " nUnrefinementBufferLayers " << nUnrefinementBufferLayers_
|
||||
<< token::END_STATEMENT << nl
|
||||
<< " active " << active()
|
||||
<< token::END_STATEMENT << nl
|
||||
|
|
|
@ -124,11 +124,17 @@ private:
|
|||
//- Maximum number of refinement levels for a given cell
|
||||
label maxRefinementLevel_;
|
||||
|
||||
//- Switch whether to use point based consistency on refinement
|
||||
Switch pointBasedConsistency_;
|
||||
//- Switch whether to use edge based consistency on refinement
|
||||
Switch edgeBasedConsistency_;
|
||||
|
||||
//- Number of buffer layers for refinement
|
||||
label nBufferLayers_;
|
||||
label nRefinementBufferLayers_;
|
||||
|
||||
//- Number of buffer layers for unrefinement, controlling how far
|
||||
// the unrefinement region needs to be from current refinement
|
||||
// region. Therefore, this should always be at least
|
||||
// nRefinementBufferLayers + 2 to avoid level inconsistencies
|
||||
label nUnrefinementBufferLayers_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
@ -357,17 +363,17 @@ private:
|
|||
// is obtained. Returns local number of cells changed
|
||||
label faceConsistentRefinement(boolList& cellsToRefine) const;
|
||||
|
||||
//- Updates cellsToRefine such that a point consistent 4:1 refinement
|
||||
//- Updates cellsToRefine such that an edge consistent 4:1 refinement
|
||||
// is obtained. Returns local number of cells changed
|
||||
label pointConsistentRefinement(boolList& cellsToRefine) const;
|
||||
label edgeConsistentRefinement(boolList& cellsToRefine) const;
|
||||
|
||||
//- Updates cellsToUnrefine such that a face consistent 2:1
|
||||
// unrefinement is obtained. Returns local number of cells changed
|
||||
label faceConsistentUnrefinement(boolList& cellsToUnrefine) const;
|
||||
|
||||
//- Updates cellsToUnrefine such that a point consistent 4:1
|
||||
//- Updates cellsToUnrefine such that an edge consistent 4:1
|
||||
// unrefinement is obtained. Returns local number of cells changed
|
||||
label pointConsistentUnrefinement(boolList& cellsToUnrefine) const;
|
||||
label edgeConsistentUnrefinement(boolList& cellsToUnrefine) const;
|
||||
|
||||
|
||||
// Copy control
|
||||
|
|
|
@ -2491,6 +2491,9 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChanger::changeMesh()
|
|||
// Increment the morph index
|
||||
morphIndex_++;
|
||||
|
||||
// Mark the mesh as changing
|
||||
mesh_.changing(true);
|
||||
|
||||
return topoChangeMap;
|
||||
}
|
||||
else
|
||||
|
@ -2504,6 +2507,9 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChanger::changeMesh()
|
|||
|
||||
// Sync mesh update
|
||||
mesh_.syncUpdateMesh();
|
||||
|
||||
// Mark the mesh as changing
|
||||
mesh_.changing(true);
|
||||
}
|
||||
|
||||
return autoPtr<mapPolyMesh>(new mapPolyMesh(mesh_));
|
||||
|
|
|
@ -15,6 +15,7 @@ dynamicPolyRefinementFvMesh/dynamicPolyRefinementFvMesh.C
|
|||
dynamicPolyRefinementFvMesh/refinementSelection/refinementSelection/refinementSelection.C
|
||||
dynamicPolyRefinementFvMesh/refinementSelection/fieldBoundsRefinement/fieldBoundsRefinement.C
|
||||
dynamicPolyRefinementFvMesh/refinementSelection/minCellVolumeRefinement/minCellVolumeRefinement.C
|
||||
dynamicPolyRefinementFvMesh/refinementSelection/minCellSizeRefinement/minCellSizeRefinement.C
|
||||
dynamicPolyRefinementFvMesh/refinementSelection/minPatchDistanceRefinement/minPatchDistanceRefinement.C
|
||||
dynamicPolyRefinementFvMesh/refinementSelection/compositeRefinementSelection/compositeRefinementSelection.C
|
||||
|
||||
|
|
|
@ -20,8 +20,19 @@ dynamicFvMesh dynamicPolyRefinementFvMesh;
|
|||
dynamicPolyRefinementFvMeshCoeffs
|
||||
{
|
||||
// Dynamic mesh procedure controls
|
||||
|
||||
// Refine every refineInterval step
|
||||
refineInterval 1;
|
||||
|
||||
// Unrefine every unrefineInterval step
|
||||
unrefineInterval 1;
|
||||
|
||||
// Separate refinement/unrefinement steps. In case this is switched on,
|
||||
// if both refinement and unrefinement should have been performed in a
|
||||
// single step, unrefinement is skipped. Switched off by default, meaning
|
||||
// that it should be safe to perform both at the same time
|
||||
separateUpdates false;
|
||||
|
||||
// Refinement selection criteria
|
||||
refinementSelection
|
||||
{
|
||||
|
@ -47,11 +58,16 @@ dynamicPolyRefinementFvMeshCoeffs
|
|||
maxRefinementLevel 3;
|
||||
|
||||
// Number of buffer layers between refinement levels
|
||||
nBufferLayers 1;
|
||||
nRefinementBufferLayers 1;
|
||||
|
||||
// Whether to use point based consistency check. Needed when one allows more
|
||||
// than 2 refinement levels (automatically switched on in that case)
|
||||
pointBasedRefinement yes;
|
||||
// Number of buffer layers for unrefinement in order to run away from the
|
||||
// region that is getting refined at the same time in order to avoid point
|
||||
// level inconsistencies
|
||||
nUnrefinementBufferLayers 4;
|
||||
|
||||
// Whether to use edge based consistency check. Needed when one allows more
|
||||
// than 2 refinement levels (automatically switched on)
|
||||
edgeBasedConsistency yes;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,16 +49,30 @@ addToRunTimeSelectionTable
|
|||
|
||||
void Foam::dynamicPolyRefinementFvMesh::readDict()
|
||||
{
|
||||
// Read and check refinement interval
|
||||
// Read and check refinement and unrefinement intervals
|
||||
refineInterval_ = readLabel(refinementDict_.lookup("refineInterval"));
|
||||
if (refineInterval_ < 1)
|
||||
{
|
||||
FatalErrorIn("dynamicPolyRefinementFvMesh::readDict()")
|
||||
<< "Illegal refineInterval found: " << refineInterval_ << nl
|
||||
<< "The refineInterval controls the refinement/unrefinement"
|
||||
<< "The refineInterval controls the refinement"
|
||||
<< " trigerring within a certain time step and should be > 0"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
unrefineInterval_ = readLabel(refinementDict_.lookup("unrefineInterval"));
|
||||
if (refineInterval_ < 1)
|
||||
{
|
||||
FatalErrorIn("dynamicPolyRefinementFvMesh::readDict()")
|
||||
<< "Illegal unrefineInterval found: " << refineInterval_ << nl
|
||||
<< "The unrefineInterval controls the unrefinement"
|
||||
<< " trigerring within a certain time step and should be > 0"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Read separate updates switch
|
||||
separateUpdates_ =
|
||||
refinementDict_.lookupOrDefault<Switch>("separateUpdates", false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +100,11 @@ Foam::dynamicPolyRefinementFvMesh::dynamicPolyRefinementFvMesh
|
|||
).subDict(typeName + "Coeffs")
|
||||
),
|
||||
refineInterval_(readLabel(refinementDict_.lookup("refineInterval"))),
|
||||
unrefineInterval_(readLabel(refinementDict_.lookup("unrefineInterval"))),
|
||||
separateUpdates_
|
||||
(
|
||||
refinementDict_.lookupOrDefault<Switch>("separateUpdates", false)
|
||||
),
|
||||
curTimeIndex_(-1),
|
||||
|
||||
refinementSelectionPtr_(refinementSelection::New(*this, refinementDict_))
|
||||
|
@ -128,13 +147,29 @@ bool Foam::dynamicPolyRefinementFvMesh::update()
|
|||
|
||||
// Performing refinement/unrefinement when:
|
||||
// 1. We are at the first time step
|
||||
// 2. Time step is a multiplier of specified refineInterval
|
||||
// 3. Only once per time step
|
||||
// 2. Only once per time step
|
||||
// 3. Time step is a multiplier of specified refineInterval or
|
||||
// unrefineInterval
|
||||
|
||||
// Get time index
|
||||
const label timeID = time().timeIndex();
|
||||
|
||||
// Check whether to perform refinement and/or unrefinement
|
||||
const bool performRefinement = timeID % refineInterval_ == 0;
|
||||
|
||||
// Skip performing refinement/unrefinement in the same step if
|
||||
// separateUpdates flag is switched on
|
||||
bool performUnrefinement = timeID % unrefineInterval_ == 0;
|
||||
if (performRefinement && separateUpdates_)
|
||||
{
|
||||
performUnrefinement = false;
|
||||
}
|
||||
|
||||
if
|
||||
(
|
||||
time().timeIndex() > 0
|
||||
&& time().timeIndex() % refineInterval_ == 0
|
||||
&& curTimeIndex_ < time().timeIndex()
|
||||
timeID > 0
|
||||
&& curTimeIndex_ < timeID
|
||||
&& (performRefinement || performUnrefinement)
|
||||
)
|
||||
{
|
||||
// Update current time index to skip multiple topo changes per single
|
||||
|
@ -145,23 +180,47 @@ bool Foam::dynamicPolyRefinementFvMesh::update()
|
|||
polyhedralRefinement& polyRefModifier =
|
||||
refCast<polyhedralRefinement>(topoChanger_[0]);
|
||||
|
||||
// Get refinement candidates from refinement selection algorithm. Note:
|
||||
// return type is Xfer<labelList> so there's no copying
|
||||
const labelList refCandidates
|
||||
// Create empty list for refinement candidates
|
||||
labelList refCandidates;
|
||||
|
||||
// Collect refinement candidates from refinement selection algorithm in
|
||||
// case the refinement should be performed in this time step
|
||||
if (performRefinement)
|
||||
{
|
||||
// Note: return type is Xfer<labelList> so there's no copying (two
|
||||
// transfers are occuring)
|
||||
refCandidates.transfer
|
||||
(
|
||||
refinementSelectionPtr_->refinementCellCandidates()
|
||||
refinementSelectionPtr_->refinementCellCandidates()()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Skipping refinement for this time-step..." << endl;
|
||||
}
|
||||
|
||||
// Set cells to refine. Note: polyhedralRefinement ensures that face and
|
||||
// point consistent refinement is performed
|
||||
polyRefModifier.setCellsToRefine(refCandidates);
|
||||
|
||||
// Get unrefinement point candidates from refinement selection
|
||||
// algorithm. Note: return type is Xfer<labelList> so there's no copying
|
||||
const labelList unrefCandidates
|
||||
// Create empty list for unrefinement candidates
|
||||
labelList unrefCandidates;
|
||||
|
||||
// Collect unrefinement candidates from refinement selection algorithm
|
||||
// in case the unrefinement should be performed in this time step
|
||||
if (performUnrefinement)
|
||||
{
|
||||
// Note: return type is Xfer<labelList> so there's no copying (two
|
||||
// transfers are occuring)
|
||||
unrefCandidates.transfer
|
||||
(
|
||||
refinementSelectionPtr_->unrefinementPointCandidates()
|
||||
refinementSelectionPtr_->unrefinementPointCandidates()()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Skipping unrefinement for this time-step..." << endl;
|
||||
}
|
||||
|
||||
// Set split points to unrefine around.
|
||||
// Notes:
|
||||
|
@ -191,13 +250,25 @@ bool Foam::dynamicPolyRefinementFvMesh::update()
|
|||
// Perform refinement and unrefinement in one go
|
||||
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
||||
|
||||
// Output cell balance
|
||||
// Output cell balance if the topo change has been performed
|
||||
const label nOldCells =
|
||||
returnReduce(topoChangeMap->nOldCells(), sumOp<label>());
|
||||
const label sizeCellMap =
|
||||
returnReduce(topoChangeMap->cellMap().size(), sumOp<label>());
|
||||
|
||||
// If the size of cell map is different than zero, we actually performed
|
||||
// some topo changes
|
||||
if (sizeCellMap)
|
||||
{
|
||||
Info<< "Successfully performed polyhedral refinement. "
|
||||
<< "Changed from "
|
||||
<< returnReduce(topoChangeMap->nOldCells(), sumOp<label>())
|
||||
<< " to "
|
||||
<< returnReduce(topoChangeMap->cellMap().size(), sumOp<label>())
|
||||
<< "Changed from " << nOldCells << " to " << sizeCellMap
|
||||
<< " cells." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Refinement/unrefinement not performed in this time step "
|
||||
<< "since no cells were selected." << endl;
|
||||
}
|
||||
|
||||
return topoChangeMap->morphing();
|
||||
}
|
||||
|
|
|
@ -65,6 +65,13 @@ class dynamicPolyRefinementFvMesh
|
|||
//- Refinement interval
|
||||
label refineInterval_;
|
||||
|
||||
//- Unrefinement interval
|
||||
label unrefineInterval_;
|
||||
|
||||
//- Separate refinement/unrefinement: off by default, meaning that
|
||||
// refinement and unrefinement can be performed in the same step
|
||||
Switch separateUpdates_;
|
||||
|
||||
//- Current time index (helper variable to skip multiple topo changes in
|
||||
// a single time step)
|
||||
label curTimeIndex_;
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Author
|
||||
Vuko Vukcevic, Wikki Ltd. All rights reserved.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "minCellSizeRefinement.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(minCellSizeRefinement, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
refinementSelection,
|
||||
minCellSizeRefinement,
|
||||
dictionary
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::minCellSizeRefinement::minCellSizeRefinement
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
refinementSelection(mesh, dict),
|
||||
minDelta_(readScalar(coeffDict().lookup("minCellSize")))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor* * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::minCellSizeRefinement::~minCellSizeRefinement()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Xfer<Foam::labelList>
|
||||
Foam::minCellSizeRefinement::refinementCellCandidates() const
|
||||
{
|
||||
// Get cell sizes: cube root of cell volume (assuming cube cells)
|
||||
const scalarField cellSize = pow(mesh().V().field(), 1.0/3.0);
|
||||
|
||||
// Create storage for collection of cells. Assume that almost all of the
|
||||
// cells will be marked to prevent excessive resizing.
|
||||
dynamicLabelList refinementCandidates(mesh().nCells());
|
||||
|
||||
// Loop through cells and collect refinement candidates
|
||||
forAll (cellSize, cellI)
|
||||
{
|
||||
if (cellSize[cellI] > minDelta_)
|
||||
{
|
||||
// Cell is larger than the specified minimum, append cell for
|
||||
// potential refinement
|
||||
refinementCandidates.append(cellI);
|
||||
}
|
||||
}
|
||||
|
||||
// Print out some information
|
||||
Info<< "Selection algorithm " << type() << " selected "
|
||||
<< returnReduce(refinementCandidates.size(), sumOp<label>())
|
||||
<< " cells as refinement candidates."
|
||||
<< endl;
|
||||
|
||||
// Return the list in the Xfer container to prevent copying
|
||||
return refinementCandidates.xfer();
|
||||
}
|
||||
|
||||
|
||||
Foam::Xfer<Foam::labelList>
|
||||
Foam::minCellSizeRefinement::unrefinementPointCandidates() const
|
||||
{
|
||||
// Mark all points as unrefinement candidates since only split points may be
|
||||
// considered for actual unrefinement and since this refinement criterion
|
||||
// will be usually used in combination with others. VV, 15/Mar/2018.
|
||||
|
||||
// All points are unrefinement candidates
|
||||
labelList unrefinementCandidates(mesh().nPoints());
|
||||
|
||||
forAll (unrefinementCandidates, pointI)
|
||||
{
|
||||
unrefinementCandidates[pointI] = pointI;
|
||||
}
|
||||
|
||||
// Print out some information
|
||||
Info<< "Selection algorithm " << type() << " selected "
|
||||
<< returnReduce(unrefinementCandidates.size(), sumOp<label>())
|
||||
<< " points as unrefinement candidates."
|
||||
<< endl;
|
||||
|
||||
// Return the list in the Xfer container to prevent copying
|
||||
return unrefinementCandidates.xfer();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,111 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::minCellSizeRefinement
|
||||
|
||||
Description
|
||||
Selection of refinement cells based on a minimum cell size. Assumes that
|
||||
cells are mostly cubic and compares the minimum cell size with V^1/3, where
|
||||
V is the cell volume. If the cell size is larger than the specified one,
|
||||
cell gets selected for refinement.
|
||||
|
||||
SourceFiles
|
||||
minCellSizeRefinement.C
|
||||
|
||||
Author
|
||||
Vuko Vukcevic, Wikki Ltd. All rights reserved.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef minCellSizeRefinement_H
|
||||
#define minCellSizeRefinement_H
|
||||
|
||||
#include "refinementSelection.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class minCellSizeRefinement Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class minCellSizeRefinement
|
||||
:
|
||||
public refinementSelection
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Minimum cell size
|
||||
scalar minDelta_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
minCellSizeRefinement(const minCellSizeRefinement&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const minCellSizeRefinement&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("minCellSizeRefinement");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
minCellSizeRefinement(const fvMesh& mesh, const dictionary& dict);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~minCellSizeRefinement();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Selection of refinement/unrefinement candidates
|
||||
|
||||
//- Return transferable list of cells to refine
|
||||
virtual Xfer<labelList> refinementCellCandidates() const;
|
||||
|
||||
//- Return transferable list of split points to unrefine
|
||||
virtual Xfer<labelList> unrefinementPointCandidates() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -105,6 +105,7 @@ class isoSurface
|
|||
//- Reference to mesh
|
||||
const fvMesh& mesh_;
|
||||
|
||||
//- Point values
|
||||
const scalarField& pVals_;
|
||||
|
||||
//- Input volScalarField with separated coupled patches rewritten
|
||||
|
@ -119,7 +120,6 @@ class isoSurface
|
|||
//- When to merge points
|
||||
const scalar mergeDistance_;
|
||||
|
||||
|
||||
//- Whether face might be cut
|
||||
List<cellCutType> faceCutType_;
|
||||
|
||||
|
@ -446,7 +446,6 @@ public:
|
|||
const GeometricField<Type, fvPatchField, volMesh>& cCoords,
|
||||
const Field<Type>& pCoords
|
||||
) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -572,13 +572,13 @@ bool Foam::sampledIsoSurface::expire()
|
|||
facesPtr_.clear();
|
||||
subMeshPtr_.clear();
|
||||
|
||||
// already marked as expired
|
||||
// Already marked as expired
|
||||
if (prevTimeIndex_ == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// force update
|
||||
// Force update
|
||||
prevTimeIndex_ = -1;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ void Foam::sampledCuttingPlane::createGeometry()
|
|||
pointDistance_.clear();
|
||||
cellDistancePtr_.clear();
|
||||
|
||||
// Clear derived data
|
||||
clearGeom();
|
||||
|
||||
// Get any subMesh
|
||||
if (zoneID_.index() != -1 && !subMeshPtr_.valid())
|
||||
|
@ -311,6 +313,12 @@ Foam::sampledCuttingPlane::~sampledCuttingPlane()
|
|||
|
||||
bool Foam::sampledCuttingPlane::needsUpdate() const
|
||||
{
|
||||
// Update for changing mesh
|
||||
if (mesh().changing())
|
||||
{
|
||||
needsUpdate_ = true;
|
||||
}
|
||||
|
||||
return needsUpdate_;
|
||||
}
|
||||
|
||||
|
@ -327,6 +335,9 @@ bool Foam::sampledCuttingPlane::expire()
|
|||
// Clear any stored topologies
|
||||
facesPtr_.clear();
|
||||
|
||||
// Clear derived data
|
||||
clearGeom();
|
||||
|
||||
// already marked as expired
|
||||
if (needsUpdate_)
|
||||
{
|
||||
|
|
|
@ -68,10 +68,10 @@ class sampledCuttingPlane
|
|||
//- Whether to recalculate cell values as average of point values
|
||||
const Switch average_;
|
||||
|
||||
//- zone name/index (if restricted to zones)
|
||||
//- Zone name/index (if restricted to zones)
|
||||
mutable cellZoneID zoneID_;
|
||||
|
||||
//- for zones: patch to put exposed faces into
|
||||
//- For zones: patch to put exposed faces into
|
||||
mutable word exposedPatchName_;
|
||||
|
||||
//- Track if the surface needs an update
|
||||
|
@ -90,7 +90,7 @@ class sampledCuttingPlane
|
|||
//- Constructed iso surface
|
||||
autoPtr<isoSurface> isoSurfPtr_;
|
||||
|
||||
//- triangles converted to faceList
|
||||
//- Triangles converted to faceList
|
||||
mutable autoPtr<faceList> facesPtr_;
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ class sampledCuttingPlane
|
|||
//- Create iso surface
|
||||
void createGeometry();
|
||||
|
||||
//- sample field on faces
|
||||
//- Sample field on faces
|
||||
template <class Type>
|
||||
tmp<Field<Type> > sampleField
|
||||
(
|
||||
|
@ -129,8 +129,7 @@ public:
|
|||
);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
//- Destructor
|
||||
virtual ~sampledCuttingPlane();
|
||||
|
||||
|
||||
|
@ -177,67 +176,75 @@ public:
|
|||
return isoSurfPtr_();
|
||||
}
|
||||
|
||||
//- sample field on surface
|
||||
|
||||
// Sample
|
||||
|
||||
//- Sample field on surface
|
||||
virtual tmp<scalarField> sample
|
||||
(
|
||||
const volScalarField&
|
||||
) const;
|
||||
|
||||
//- sample field on surface
|
||||
//- Sample field on surface
|
||||
virtual tmp<vectorField> sample
|
||||
(
|
||||
const volVectorField&
|
||||
) const;
|
||||
|
||||
//- sample field on surface
|
||||
//- Sample field on surface
|
||||
virtual tmp<sphericalTensorField> sample
|
||||
(
|
||||
const volSphericalTensorField&
|
||||
) const;
|
||||
|
||||
//- sample field on surface
|
||||
//- Sample field on surface
|
||||
virtual tmp<symmTensorField> sample
|
||||
(
|
||||
const volSymmTensorField&
|
||||
) const;
|
||||
|
||||
//- sample field on surface
|
||||
//- Sample field on surface
|
||||
virtual tmp<tensorField> sample
|
||||
(
|
||||
const volTensorField&
|
||||
) const;
|
||||
|
||||
|
||||
//- interpolate field on surface
|
||||
// Interpolate
|
||||
|
||||
//- Interpolate field on surface
|
||||
virtual tmp<scalarField> interpolate
|
||||
(
|
||||
const interpolation<scalar>&
|
||||
) const;
|
||||
|
||||
//- interpolate field on surface
|
||||
//- Interpolate field on surface
|
||||
virtual tmp<vectorField> interpolate
|
||||
(
|
||||
const interpolation<vector>&
|
||||
) const;
|
||||
|
||||
//- interpolate field on surface
|
||||
//- Interpolate field on surface
|
||||
virtual tmp<sphericalTensorField> interpolate
|
||||
(
|
||||
const interpolation<sphericalTensor>&
|
||||
) const;
|
||||
|
||||
//- interpolate field on surface
|
||||
//- Interpolate field on surface
|
||||
virtual tmp<symmTensorField> interpolate
|
||||
(
|
||||
const interpolation<symmTensor>&
|
||||
) const;
|
||||
|
||||
//- interpolate field on surface
|
||||
//- Interpolate field on surface
|
||||
virtual tmp<tensorField> interpolate
|
||||
(
|
||||
const interpolation<tensor>&
|
||||
) const;
|
||||
|
||||
|
||||
// Output
|
||||
|
||||
//- Write
|
||||
virtual void print(Ostream&) const;
|
||||
};
|
||||
|
|
Reference in a new issue