Commit 7347c8e5 authored by Franjo's avatar Franjo
Browse files

Merge branch 'enhancement-penetrationThicknessRefinement-t11' into development

parents e79abb42 f2cb3e93
......@@ -38,6 +38,79 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void checkMeshDict::checkBasicSettings() const
{
//- check if maxCellSize is valid
const scalar maxCellSize = readScalar(meshDict_.lookup("maxCellSize"));
if( maxCellSize < 0 )
FatalErrorIn
(
"void checkMeshDict::checkBasicSettings() const"
) << "maxCellSize is negative! Cannot generate the mesh!!"
<< exit(FatalError);
//- check if boundaryCellSize makes sense
if( meshDict_.found("boundaryCellSize") )
{
const scalar bcs = readScalar(meshDict_.lookup("boundaryCellSize"));
if( bcs < 0 )
{
WarningIn
(
"void checkMeshDict::checkBasicSettings() const"
) << "Boundary cell size is negative!!" << endl;
}
if( meshDict_.found("boundaryCellSizeRefinementThickness") )
{
const scalar thickness =
readScalar
(
meshDict_.lookup("boundaryCellSizeRefinementThickness")
);
if( thickness < 0 )
{
WarningIn
(
"void checkMeshDict::checkBasicSettings() const"
) << "Boundary cell size refinement thickness is negative!!"
<< endl;
}
}
}
//- check if minCellSize is valid
if( meshDict_.found("minCellSize") )
{
const scalar mcs = readScalar(meshDict_.lookup("minCellSize"));
if( mcs < 0 )
{
FatalErrorIn
(
"void checkMeshDict::checkBasicSettings() const"
) << "Minimum cell size for automatic refinement is negative!!"
<< exit(FatalError);
}
}
//- check if keepCellsIntersectingBoundary can be read correctly
if( meshDict_.found("keepCellsIntersectingBoundary") )
{
const bool keep =
readBool(meshDict_.lookup("keepCellsIntersectingBoundary"));
if( keep && meshDict_.found("checkForGluedMesh") )
{
readBool(meshDict_.lookup("checkForGluedMesh"));
}
}
}
void checkMeshDict::checkPatchCellSize() const
{
if( meshDict_.found("patchCellSize") )
......@@ -92,14 +165,14 @@ void checkMeshDict::checkLocalRefinementLevel() const
{
const scalar cs = readScalar(dict.lookup("cellSize"));
if( cs > 0.0 )
continue;
WarningIn
(
if( cs < 0.0 )
{
WarningIn
(
"void checkMeshDict::checkLocalRefinementLevel() const"
) << "Cell size for " << entries[dictI]
<< " is negative" << endl;
) << "Cell size for " << entries[dictI]
<< " is negative" << endl;
}
}
else if( dict.found("additionalRefinementLevels") )
{
......@@ -107,13 +180,13 @@ void checkMeshDict::checkLocalRefinementLevel() const
readLabel(dict.lookup("additionalRefinementLevels"));
if( nLevels > 0 )
continue;
WarningIn
(
{
WarningIn
(
"void checkMeshDict::checkLocalRefinementLevel() const"
) << "Refinement level for " << entries[dictI]
<< " is negative" << endl;
) << "Refinement level for " << entries[dictI]
<< " is negative" << endl;
}
}
else
{
......@@ -124,6 +197,21 @@ void checkMeshDict::checkLocalRefinementLevel() const
<< " additionalRefinementLevels or cellSize"
<< "for " << entries[dictI] << exit(FatalError);
}
if( dict.found("refinementThickness") )
{
const scalar s =
readScalar(dict.lookup("refinementThickness"));
if( s < 0 )
{
WarningIn
(
"void checkMeshDict::checkLocalRefinementLevel() const"
) << "Refinement thickness for " << entries[dictI]
<< " is negative" << endl;
}
}
}
}
else
......@@ -223,6 +311,27 @@ void checkMeshDict::checkObjectRefinements() const
);
}
}
forAll(refObjects, oI)
{
if( refObjects[oI].cellSize() < 0.0 )
{
WarningIn
(
"void checkMeshDict::checkObjectRefinements() const"
) << "Cell size specified for object " << refObjects[oI].name()
<< " is negative!!" << endl;
}
if( refObjects[oI].refinementThickness() < 0.0 )
{
WarningIn
(
"void checkMeshDict::checkObjectRefinements() const"
) << "Refinement thickness specified for object "
<< refObjects[oI].name() << " is negative!!" << endl;
}
}
}
}
......@@ -238,7 +347,8 @@ void checkMeshDict::checkSurfaceRefinements() const
{
if( surfaces.isDict(surfaceSources[surfI]) )
{
const dictionary& dict = surfaces.subDict(surfaceSources[surfI]);
const dictionary& dict =
surfaces.subDict(surfaceSources[surfI]);
if( dict.found("surfaceFile") )
{
......@@ -247,50 +357,73 @@ void checkMeshDict::checkSurfaceRefinements() const
if( !isFile(fName) )
FatalErrorIn
(
"void checkMeshDict::checkSurfaceRefinements() const"
"void checkMeshDict::checkSurfaceRefinements() const"
) << "Surface file " << fName
<< " does not exist or is not readable!!"
<< exit(FatalError);
}
else
{
FatalErrorIn
(
"void checkMeshDict::checkSurfaceRefinements() const"
) << "Missing surfaceFile for entry "
<< surfaceSources[surfI] << exit(FatalError);
}
if( dict.found("cellSize") )
{
const scalar cs = readScalar(dict.lookup("cellSize"));
if( cs < VSMALL )
FatalErrorIn
(
"void checkMeshDict::"
"checkSurfaceRefinements() const"
) << "Cell size for surface " << fName
<< " is extremely small or negative!!"
<< exit(FatalError);
}
else if( dict.found("additionalRefinementLevels") )
{
const label nLev =
readLabel(dict.lookup("additionalRefinementLevels"));
if( dict.found("cellSize") )
{
const scalar cs = readScalar(dict.lookup("cellSize"));
if( nLev < 0 )
{
FatalErrorIn
(
"void checkMeshDict::"
"checkSurfaceRefinements() const"
) << "Number refinement levels for surface " << fName
<< " is negative!!"
<< exit(FatalError);
}
}
else
if( cs < VSMALL )
FatalErrorIn
(
"void checkMeshDict::"
"checkSurfaceRefinements() const"
) << "Cell size for entry " << surfaceSources[surfI]
<< " is extremely small or negative!!"
<< exit(FatalError);
}
else if( dict.found("additionalRefinementLevels") )
{
const label nLev =
readLabel(dict.lookup("additionalRefinementLevels"));
if( nLev < 0 )
{
FatalErrorIn
(
"void checkMeshDict::checkSurfaceRefinements() const"
) << "Missing cellSize or additionalRefinementLevels"
<< " for surface " << fName
"void checkMeshDict::"
"checkSurfaceRefinements() const"
) << "Number refinement levels for entry "
<< surfaceSources[surfI] << " is negative!!"
<< exit(FatalError);
}
}
else
{
FatalErrorIn
(
"void checkMeshDict::checkSurfaceRefinements() const"
) << "Missing cellSize or additionalRefinementLevels"
<< " for entry " << surfaceSources[surfI]
<< exit(FatalError);
}
if( dict.found("refinementThickness") )
{
const scalar cs =
readScalar(dict.lookup("refinementThickness"));
if( cs < VSMALL )
WarningIn
(
"void checkMeshDict::"
"checkSurfaceRefinements() const"
) << "Refinement thickness for entry "
<< surfaceSources[surfI]
<< " is extremely small or negative!!" << endl;
}
}
else
{
......@@ -431,6 +564,8 @@ void checkMeshDict::checkRenameBoundary() const
void checkMeshDict::checkEntries() const
{
checkBasicSettings();
checkPatchCellSize();
checkSubsetCellSize();
......
......@@ -54,6 +54,9 @@ class checkMeshDict
IOdictionary& meshDict_;
// Private member functions
//- check settings for cell size in meshDict
void checkBasicSettings() const;
//- check patchCellSize entry
void checkPatchCellSize() const;
......
......@@ -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,7 +80,8 @@ 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
......@@ -107,6 +108,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 +131,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();
......
......@@ -55,7 +55,7 @@ void meshOctreeCreator::refineBoundary()
const LongList<meshOctreeCube*>& leaves = octreeModifier.leavesAccess();
//- refine DATA boxes to the given level
Info << "Refining data boxes to the given size" << endl;
Info << "Refining boundary boxes to the given size" << endl;
label nMarked;
do
......@@ -67,6 +67,9 @@ void meshOctreeCreator::refineBoundary()
# endif
List<direction> refineCubes(leaves.size(), direction(0));
labelList nLayers(leaves.size(), 0);
List<direction> targetLevel(leaves.size(), direction(0));
bool useNLayers(false);
//- select boxes which need to be refined
# ifdef USE_OMP
......@@ -87,20 +90,56 @@ void meshOctreeCreator::refineBoundary()
const VRWGraph& containedTriangles =
oc.slotPtr()->containedTriangles_;
const scalar cs = oc.size(octree_.rootBox());
bool refine(false);
forAllRow(containedTriangles, elRowI, tI)
{
const label triI = containedTriangles(elRowI, tI);
if( surfRefLevel_[triI] > oc.level() )
{
++nMarked;
refineCubes[leafI] = 1;
break;
refine = true;
}
if( surfRefThickness_[triI] > VSMALL )
{
useNLayers = true;
nLayers[leafI] =
Foam::max
(
nLayers[leafI],
Foam::max(label(surfRefThickness_[triI]/cs), 1)
);
targetLevel[leafI] =
Foam::max(targetLevel[leafI], surfRefLevel_[triI]);
}
}
if( refine )
{
refineCubes[leafI] = 1;
++nMarked;
}
}
}
//- mark additional boxes for refinement to achieve
//- correct refinement distance
reduce(useNLayers, maxOp<label>());
if( useNLayers )
{
nMarked +=
octreeModifier.markAdditionalLayers
(
refineCubes,
nLayers,
targetLevel
);
}
//- refine boxes
octreeModifier.refineSelectedBoxes(refineCubes, hexRefinement_);
......@@ -133,7 +172,7 @@ void meshOctreeCreator::refineBoundary()
} while( nMarked );
Info << "Finished refining data boxes" << endl;
Info << "Finished refining boundary boxes" << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -198,16 +237,23 @@ void meshOctreeCreator::refineBoxesContainedInObjects()
scalar s(readScalar(meshDictPtr_->lookup("maxCellSize")));
List<direction> refLevels(refObjects.size(), globalRefLevel_);
scalarList refThickness(refObjects.size(), 0.0);
forAll(refThickness, oI)
refThickness[oI] = refObjects[oI].refinementThickness();
label nMarked;
do
{
nMarked = 0;
forAll(refObjects, oI)
{
if( refObjects[oI].cellSize() <= s * (1.+SMALL) )
{
++nMarked;
++refLevels[oI];
}
}
s /= 2.0;
......@@ -239,6 +285,9 @@ void meshOctreeCreator::refineBoxesContainedInObjects()
nMarked = 0;
List<direction> refineCubes(leaves.size(), direction(0));
labelList nLayers(leaves.size(), 0);
List<direction> targetRefLevel(leaves.size(), direction(0));
bool useNLayers(false);
//- select boxes which need to be refined
# ifdef USE_OMP
......@@ -255,21 +304,55 @@ void meshOctreeCreator::refineBoxesContainedInObjects()
boundBox bb;
oc.cubeBox(rootBox, bb.min(), bb.max());
bool refine(false);
forAll(refObjects, oI)
if(
(oc.level() < refLevels[oI]) &&
refObjects[oI].intersectsObject(bb)
)
{
if( refObjects[oI].intersectsObject(bb) )
{
# ifdef DEBUGSearch
Info << "Marking leaf " << leafI
<< " for refinement" << endl;
# endif
++nMarked;
refineCubes[leafI] = 1;
break;
if( oc.level() < refLevels[oI] )
refine = true;
if( refThickness[oI] > VSMALL )
{
const scalar cs = bb.max().x() - bb.min().x();
nLayers[leafI] =
Foam::max
(
nLayers[leafI],
Foam::max(label(refThickness[oI]/cs), 1)
);
targetRefLevel[leafI] =
Foam::max(targetRefLevel[leafI], refLevels[oI]);
useNLayers = true;
}
}
}
if( refine )
{
refineCubes[leafI] = 1;
++nMarked;
}
}
//- mark additional boxes for refinement to achieve
//- correct refinement distance
reduce(useNLayers, maxOp<label>());
if( useNLayers )
{
nMarked +=
octreeModifier.markAdditionalLayers
(
refineCubes,
nLayers,
targetRefLevel
);
}
//- refine boxes
......@@ -327,6 +410,7 @@ void meshOctreeCreator::refineBoxesIntersectingSurfaces()
const wordList surfaces = surfDict.toc();
PtrList<triSurf> surfaceMeshesPtr(surfaces.size());
List<direction> refLevels(surfaces.size(), globalRefLevel_);
scalarList refThickness(surfaces.size());
//- load surface meshes into memory
forAll(surfaceMeshesPtr, surfI)
......@@ -367,6 +451,12 @@ void meshOctreeCreator::refineBoxesIntersectingSurfaces()
readLabel(dict.lookup("additionalRefinementLevels"));
}
if( dict.found("refinementThickness") )
{
refThickness[surfI] =
readScalar(dict.lookup("refinementThickness"));
}
//- set the refinement level for the current surface
refLevels[surfI] += addLevel;
}
......@@ -384,7 +474,7 @@ void meshOctreeCreator::refineBoxesIntersectingSurfaces()
const vector tol = SMALL * rootBox.span();
meshOctreeModifier octreeModifier(octree_);
const LongList<meshOctreeCube*>& leaves = octreeModifier.leavesAccess();
DynList<label> leavesInBox;
DynList<label> leavesInBox, intersectedLeaves;
do
{
......@@ -395,6 +485,9 @@ void meshOctreeCreator::refineBoxesIntersectingSurfaces()
nMarked = 0;
List<direction> refineCubes(leaves.size(), direction(0));
labelList nLayers(leaves.size(), 0);
List<direction> targetRefLevel(leaves.size(), direction(0));
bool useNLayers(false);
//- select boxes which need to be refined
forAll(surfaceMeshesPtr, surfI)
......@@ -404,7 +497,8 @@ void meshOctreeCreator::refineBoxesIntersectingSurfaces()
# ifdef USE_OMP