Skip to content
Snippets Groups Projects
Commit a59a6fb6 authored by Franjo's avatar Franjo
Browse files

Initial version of refinement thickness

parent e79abb42
Branches
Tags
No related merge requests found
Showing with 735 additions and 42 deletions
......@@ -47,7 +47,8 @@ meshOctreeCreator::meshOctreeCreator(meshOctree& mo)
meshDictPtr_(NULL),
hexRefinement_(false),
globalRefLevel_(0),
surfRefLevel_(mo.surface().size(), direction(0))
surfRefLevel_(mo.surface().size(), direction(0)),
surfRefThickness_(mo.surface().size(), 0.0)
{}
meshOctreeCreator::meshOctreeCreator
......@@ -61,7 +62,8 @@ meshOctreeCreator::meshOctreeCreator
meshDictPtr_(&dict),
hexRefinement_(false),
globalRefLevel_(0),
surfRefLevel_(mo.surface().size(), direction(0))
surfRefLevel_(mo.surface().size(), direction(0)),
surfRefThickness_(mo.surface().size(), 0.0)
{}
/*
......@@ -77,7 +79,8 @@ meshOctreeCreator::meshOctreeCreator
meshDict_(dict),
hexRefinement_(false),
globalRefLevel_(0),
surfRefLevel_(mo.surface().size(), direction(0))
surfRefLevel_(mo.surface().size(), direction(0)),
surfRefThickness_(mo.surface().size(), 0.0)
{
FatalErrorIn
(
......
......@@ -80,12 +80,16 @@ private:
//- refine boxes contained inside the objects for refinement
void refineBoxesContainedInObjects();
//- refine boxes intersected by surface meshes used as refinement sources
//- refine boxes intersected by surface meshes
//- used as refinement sources
void refineBoxesIntersectingSurfaces();
//- refine boxes near DATA boxes to get a nice smooth surface
void refineBoxesNearDataBoxes(const direction nLayers = 1);
//- refine boxes to satisfy distance requirements
bool refineBoxesRefinementDistance();
//- refine boxes of the given flag to the given size
void refineBoxes(const direction refLevel, const direction cubeType);
......@@ -107,6 +111,9 @@ private:
//- this list contains ref level for each surface triangle
List<direction> surfRefLevel_;
//- refinement thickness for each surface triangle
scalarList surfRefThickness_;
//- set the boundBox such that maxCellSize is achieved
void setRootCubeSizeAndRefParameters();
......@@ -127,15 +134,6 @@ public:
//- Construct from meshOctree and dictionary
meshOctreeCreator(meshOctree& mo, const IOdictionary& dict);
//- Construct from surface, dictionary and cell sizes
/* meshOctreeCreator
(
meshOctree& mo,
const IOdictionary& dict,
const volScalarField& localCellSize
);
*/
// Destructor
~meshOctreeCreator();
......
......@@ -156,6 +156,16 @@ void meshOctreeCreator::setRootCubeSizeAndRefParameters()
Info << "Requested boundary cell size corresponds to octree level "
<< label(boundaryRefLevel_) << endl;
if( meshDictPtr_->found("boundaryCellSizeRefinementThickness") )
{
const scalar s =
readScalar
(
meshDictPtr_->lookup("boundaryCellSizeRefinementThickness")
);
surfRefThickness_ = mag(s);
}
surfRefLevel_ = boundaryRefLevel_;
}
......@@ -367,6 +377,13 @@ void meshOctreeCreator::setRootCubeSizeAndRefParameters()
} while( !finished );
}
scalar refinementThickness(0.0);
if( patchDict.found("refinementThickness") )
{
refinementThickness =
readScalar(patchDict.lookup("refinementThickness"));
}
const direction level = globalRefLevel_ + nLevel;
if( patchToIndex.find(pName) != patchToIndex.end() )
......@@ -377,8 +394,16 @@ void meshOctreeCreator::setRootCubeSizeAndRefParameters()
forAll(surface, triI)
{
if( surface[triI].region() == patchI )
{
surfRefLevel_[triI] =
Foam::max(surfRefLevel_[triI], level);
surfRefThickness_[triI] =
Foam::max
(
surfRefThickness_[triI],
refinementThickness
);
}
}
}
if( setToIndex.find(pName) != setToIndex.end() )
......@@ -394,6 +419,12 @@ void meshOctreeCreator::setRootCubeSizeAndRefParameters()
const label triI = facetsInSubset[i];
surfRefLevel_[triI] =
Foam::max(surfRefLevel_[triI], level);
surfRefThickness_[triI] =
Foam::max
(
surfRefThickness_[triI],
refinementThickness
);
}
}
}
......@@ -444,7 +475,8 @@ void meshOctreeCreator::createOctreeBoxes()
//- make sure that INSIDE and UNKNOWN neighbours of DATA boxes
//- have the same or higher refinement level
refineBoxesNearDataBoxes(1);
//if( !refineBoxesRefinementDistance() )
refineBoxesNearDataBoxes(1);
//- distribute octree such that each processor has the same number
//- of leaf boxes which will be used as mesh cells
......
......@@ -130,6 +130,16 @@ public:
const direction nLayers = 1
) const;
//- mark additional layers around the leaves selected for refinement
//- given on a box-by-box basis
//- returns the number of boxes selected for refinement
label markAdditionalLayers
(
List<direction>& refineBox,
labelList& nLayers,
List<direction>& targetRefLevel
) const;
//- refine leaves marked for refinement
//- hexRefinement is activated when it is required to refine all
//- sons of the same father, if a single son gets marked for refinement
......
......@@ -28,6 +28,7 @@ Description
#include "meshOctreeModifier.H"
#include "triSurf.H"
#include "HashSet.H"
#include "helperFunctions.H"
# ifdef USE_OMP
#include <omp.h>
......@@ -163,6 +164,213 @@ void meshOctreeModifier::markAdditionalLayers
}
}
label meshOctreeModifier::markAdditionalLayers
(
List<direction>& refineBox,
labelList& nLayers,
List<direction>& targetRefLevel
) const
{
const FixedList<meshOctreeCubeCoordinates, 26>& rp =
octree_.regularityPositions_;
const LongList<meshOctreeCube*>& leaves = octree_.leaves_;
//- this is needed for parallel runs to reduce the length of messages
labelHashSet transferCoordinates;
FixedList<meshOctreeCube*, 26> neighbours;
labelList currentLayer(leaves.size());
forAll(targetRefLevel, leafI)
{
currentLayer[leafI] = targetRefLevel[leafI] ? 1 : 0;
}
//Info << "Current layer " << currentLayer << endl;
List<direction> targetRefLevelBefore = targetRefLevel;
Info << "Max nLayers" << max(nLayers) << endl;
bool changed;
label i(0), nMarked(0);
do
{
++i;
changed = false;
Info << "Iteration " << i << endl;
Info << "Max current layer " << max(currentLayer) << endl;
labelList newNLayers = nLayers;
labelList newCurrentLayer = currentLayer;
List<direction> newTargetRefLevel = targetRefLevel;
LongList<meshOctreeCubeCoordinates> processorChecks;
labelLongList processorNLayers;
LongList<direction> processorTargetLevels;
forAll(leaves, leafI)
{
if( currentLayer[leafI] != i )
continue;
const meshOctreeCube* oc = leaves[leafI];
forAll(rp, posI)
{
const meshOctreeCubeCoordinates cc
(
oc->coordinates() + rp[posI]
);
const label neiLabel = octree_.findLeafLabelForPosition(cc);
if( neiLabel > -1 )
{
neighbours[posI] = leaves[neiLabel];
}
else if( neiLabel == -1 )
{
neighbours[posI] = NULL;
}
else if( neiLabel == meshOctreeCubeBasic::OTHERPROC )
{
neighbours[posI] = NULL;
if( !transferCoordinates.found(leafI) )
{
processorChecks.append(oc->coordinates());
processorNLayers.append(nLayers[leafI]);
processorTargetLevels.append(targetRefLevel[leafI]);
transferCoordinates.insert(leafI);
}
}
}
forAll(neighbours, neiI)
{
const meshOctreeCube* nei = neighbours[neiI];
if( !nei ) continue;
if( !nei->isLeaf() ) continue;
if( i <= nLayers[leafI] )
{
newNLayers[nei->cubeLabel()] =
Foam::max(nLayers[nei->cubeLabel()], nLayers[leafI]);
newTargetRefLevel[nei->cubeLabel()] =
Foam::max
(
targetRefLevel[nei->cubeLabel()],
targetRefLevel[leafI]
);
changed = true;
newCurrentLayer[nei->cubeLabel()] = i+1;
}
}
}
if( octree_.neiProcs().size() )
{
std::map<label, LongList<meshOctreeCubeCoordinates> > eCoords;
std::map<label, labelLongList > eNLayers;
std::map<label, LongList<direction> > eTargetLevels;
forAll(octree_.neiProcs(), neiI)
{
const label neiProc = octree_.neiProcs()[neiI];
eCoords[neiProc] = processorChecks;
eNLayers[neiProc] = processorNLayers;
eTargetLevels[neiProc] = processorTargetLevels;
}
LongList<meshOctreeCubeCoordinates> receivedCoords;
help::exchangeMap(eCoords, receivedCoords);
labelLongList receivedNLayers;
help::exchangeMap(eNLayers, receivedNLayers);
LongList<direction> receivedTargetLevels;
help::exchangeMap(eTargetLevels, receivedTargetLevels);
if( receivedCoords.size() != receivedNLayers.size() )
FatalErrorIn
(
"label meshOctreeModifier::markAdditionalLayers("
"List<direction>&, labelList&, List<direction>&) const"
) << "Invalid list size" << abort(FatalError);
if( receivedCoords.size() != receivedTargetLevels.size() )
FatalErrorIn
(
"label meshOctreeModifier::markAdditionalLayers("
"List<direction>&, labelList&, List<direction>&) const"
) << "Invalid list size" << abort(FatalError);
//- check consistency with received cube coordinates
forAll(receivedCoords, ccI)
{
forAll(rp, posI)
{
const meshOctreeCubeCoordinates cc
(
receivedCoords[ccI] + rp[posI]
);
const meshOctreeCube* nei =
octree_.findCubeForPosition(cc);
if( !nei ) continue;
if( !nei->isLeaf() ) continue;
if( i <= receivedNLayers[ccI] )
{
newNLayers[nei->cubeLabel()] =
Foam::max
(
nLayers[nei->cubeLabel()],
receivedNLayers[ccI]
);
newTargetRefLevel[nei->cubeLabel()] =
Foam::max
(
targetRefLevel[nei->cubeLabel()],
receivedTargetLevels[ccI]
);
changed = true;
newCurrentLayer[nei->cubeLabel()] = i+1;
}
}
}
}
nLayers.transfer(newNLayers);
currentLayer.transfer(newCurrentLayer);
targetRefLevel.transfer(newTargetRefLevel);
//- exchange information with all processors
reduce(changed, maxOp<bool>());
} while( changed );
//- update refine data
forAll(targetRefLevel, leafI)
{
if
(
!refineBox[leafI] &&
(targetRefLevel[leafI] > leaves[leafI]->level())
)
{
refineBox[leafI] = 1;
++nMarked;
}
}
return nMarked;
}
void meshOctreeModifier::refineSelectedBoxes
(
List<direction>& refineBox,
......
......@@ -31,7 +31,7 @@ License
namespace Foam
{
defineTypeNameAndDebug(objectRefinement, 0);
defineRunTimeSelectionTable(objectRefinement, dictionary);
......@@ -40,7 +40,8 @@ defineRunTimeSelectionTable(objectRefinement, dictionary);
objectRefinement::objectRefinement()
:
name_(),
cellSize_()
cellSize_(),
refThickness_(0.0)
{}
......@@ -51,8 +52,11 @@ objectRefinement::objectRefinement
)
:
name_(name),
cellSize_(readScalar(dict.lookup("cellSize")))
cellSize_(readScalar(dict.lookup("cellSize"))),
refThickness_(0.0)
{
if( dict.found("refinementThickness") )
refThickness_ = readScalar(dict.lookup("refinementThickness"));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
......
......@@ -62,6 +62,9 @@ class objectRefinement
//- cell size for this object
scalar cellSize_;
//- refinement thickness fro this object
scalar refThickness_;
public:
// Runtime type information
......@@ -136,6 +139,18 @@ public:
return cellSize_;
}
//- set refinement thickness
void setRefinementThickness(const scalar refThickness)
{
refThickness_ = refThickness_;
}
//- return refinement thickness for this object
scalar refinementThickness() const
{
return refThickness_;
}
//- Return as dictionary of entries
virtual dictionary dict(bool ignoreType = false) const = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment