Commit a59a6fb6 authored by Franjo's avatar Franjo

Initial version of refinement thickness

parent e79abb42
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment