ENH: New cell size function point insertion algorithm

This commit is contained in:
laurence
2013-04-15 16:59:59 +01:00
parent c4b8448d53
commit 5bb8b8c31e
18 changed files with 455 additions and 14 deletions

View File

@ -156,6 +156,12 @@ public:
// Query
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const = 0;
virtual void initialVertices
(
pointField& pts,

View File

@ -162,6 +162,17 @@ Foam::fileControl::~fileControl()
// alignment = cellAlignment(pt);
//}
void Foam::fileControl::cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const
{
return;
}
void Foam::fileControl::initialVertices
(
pointField& pts,

View File

@ -114,6 +114,12 @@ public:
// Edit
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const;
virtual void initialVertices
(
pointField& pts,

View File

@ -174,6 +174,7 @@ Foam::searchableSurfaceControl::searchableSurfaceControl
searchableSurface_(geometryToConformTo.geometry()[surfaceName_]),
geometryToConformTo_(geometryToConformTo),
cellSizeFunctions_(1),
regionToCellSizeFunctions_(geometryToConformTo_.patchNames().size(), 0),
maxPriority_(-1)
{
Info<< indent << "Master settings:" << endl;
@ -244,6 +245,8 @@ Foam::searchableSurfaceControl::searchableSurfaceControl
);
Info<< decrIndent;
regionToCellSizeFunctions_[regionID] = nRegionCellSizeFunctions;
nRegionCellSizeFunctions++;
}
else
@ -272,6 +275,16 @@ Foam::searchableSurfaceControl::searchableSurfaceControl
)
);
const wordList& regionNames = geometryToConformTo_.patchNames();
forAll(regionNames, regionI)
{
if (regionToCellSizeFunctions_[regionI] == -1)
{
regionToCellSizeFunctions_[regionI] = nRegionCellSizeFunctions;
}
}
cellSizeFunctions_.transfer(regionCellSizeFunctions);
}
@ -404,6 +417,56 @@ void Foam::searchableSurfaceControl::initialVertices
}
void Foam::searchableSurfaceControl::cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const
{
const pointField& points = searchableSurface_.points();
const scalar nearFeatDistSqrCoeff = 1e-8;
forAll(points, pI)
{
// Is the point in the extendedFeatureEdgeMesh? If so get the
// point normal, otherwise get the surface normal from
// searchableSurface
pointField ptField(1, points[pI]);
scalarField distField(1, nearFeatDistSqrCoeff);
List<pointIndexHit> infoList(1, pointIndexHit());
searchableSurface_.findNearest(ptField, distField, infoList);
if (infoList[0].hit())
{
vectorField normals(1);
searchableSurface_.getNormal(infoList, normals);
labelList region(1, -1);
searchableSurface_.getRegion(infoList, region);
const cellSizeFunction& sizeFunc =
sizeFunctions()[regionToCellSizeFunctions_[region[0]]];
pointField extraPts;
scalarField extraSizes;
sizeFunc.sizeLocations
(
infoList[0],
normals[0],
extraPts,
extraSizes
);
pts.append(extraPts);
sizes.append(extraSizes);
}
}
}
bool Foam::searchableSurfaceControl::cellSize
(
const Foam::point& pt,

View File

@ -63,6 +63,8 @@ class searchableSurfaceControl
PtrList<cellSizeFunction> cellSizeFunctions_;
labelList regionToCellSizeFunctions_;
label maxPriority_;
@ -143,6 +145,12 @@ public:
// tensor& alignment
// ) const;
virtual void cellSizeFunctionVertices
(
DynamicList<Foam::point>& pts,
DynamicList<scalar>& sizes
) const;
virtual void initialVertices
(
pointField& pts,

View File

@ -271,16 +271,12 @@ void Foam::controlMeshRefinement::initialMeshPopulation
List<Vb> vertices(pts.size());
// Clip the minimum size
forAll(vertices, vI)
for (label vI = 0; vI < pts.size(); ++vI)
{
vertices[vI] = Vb(pts[vI], Vb::vtInternalNearBoundary);
vertices[vI].targetCellSize() = max
(
min
(
sizes[vI],
shapeController_.cellSize(pts[vI])
),
sizes[vI],
shapeController_.minimumCellSize()
);
vertices[vI].alignment() = alignments[vI];
@ -403,6 +399,135 @@ void Foam::controlMeshRefinement::initialMeshPopulation
<< endl;
}
forAll(controlFunctions, fI)
{
const cellSizeAndAlignmentControl& controlFunction =
controlFunctions[fI];
const Switch& forceInsertion =
controlFunction.forceInitialPointInsertion();
Info<< "Inserting points from " << controlFunction.name()
<< " (" << controlFunction.type() << ")" << endl;
Info<< " Force insertion is " << forceInsertion.asText() << endl;
DynamicList<Foam::point> extraPts;
DynamicList<scalar> extraSizes;
controlFunction.cellSizeFunctionVertices(extraPts, extraSizes);
List<Vb> vertices(extraPts.size());
// Clip the minimum size
for (label vI = 0; vI < extraPts.size(); ++vI)
{
vertices[vI] = Vb(extraPts[vI], Vb::vtUnassigned);
vertices[vI].targetCellSize() = max
(
extraSizes[vI],
shapeController_.minimumCellSize()
);
}
label nRejected = 0;
PackedBoolList keepVertex(vertices.size(), true);
forAll(vertices, vI)
{
bool keep = true;
pointFromPoint pt = topoint(vertices[vI].point());
if (Pstream::parRun())
{
keep = decomposition().positionOnThisProcessor(pt);
}
if (geometryToConformTo_.wellOutside(pt, SMALL))
{
keep = false;
}
if (!keep)
{
keepVertex[vI] = false;
}
}
inplaceSubset(keepVertex, vertices);
const label preInsertedSize = mesh_.number_of_vertices();
forAll(vertices, vI)
{
bool insertPoint = false;
pointFromPoint pt(topoint(vertices[vI].point()));
if
(
mesh_.dimension() < 3
|| mesh_.is_infinite
(
mesh_.locate(vertices[vI].point())
)
)
{
insertPoint = true;
}
const scalar interpolatedCellSize = shapeController_.cellSize(pt);
const scalar calculatedCellSize = vertices[vI].targetCellSize();
if (debug)
{
Info<< "Point = " << pt << nl
<< " Size(interp) = " << interpolatedCellSize << nl
<< " Size(calc) = " << calculatedCellSize << nl
<< endl;
}
const scalar sizeDiff =
mag(interpolatedCellSize - calculatedCellSize);
if (debug)
{
Info<< " size difference = " << sizeDiff << endl;
}
// @todo Also need to base it on the alignments
if (sizeDiff/interpolatedCellSize > 0.1)
{
insertPoint = true;
}
if (forceInsertion || insertPoint)
{
mesh_.insert
(
pt,
calculatedCellSize,
vertices[vI].alignment(),
Vb::vtInternal
);
}
}
//mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
Info<< " Inserted "
<< returnReduce
(
label(mesh_.number_of_vertices()) - preInsertedSize,
sumOp<label>()
)
<< "/" << returnReduce(vertices.size(), sumOp<label>())
<< endl;
}
// Change cell size function of bounding points to be consistent
// with their nearest neighbours
// for

View File

@ -173,6 +173,14 @@ public:
return coeffsDict_;
}
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const = 0;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -95,6 +95,48 @@ scalar linearDistance::sizeFunction
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool linearDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
if (sideMode_ == rmBothsides)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize_;
shapePts[1] = pt + n*distance_;
shapeSizes[1] = distanceCellSize_;
}
else if (sideMode_ == smInside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize_;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize_;
}
return false;
}
bool linearDistance::cellSize(const point& pt, scalar& size) const
{
size = 0;
@ -183,6 +225,7 @@ bool linearDistance::setCellSize(const pointField& pts)
// (
// pointField(1, pt),
// scalarField(1, distanceSqr_),
// regionIndices_,
// hits
// );
@ -201,14 +244,7 @@ bool linearDistance::setCellSize(const pointField& pts)
// }
// }
// // Force recalculation of the interpolation
// if (!pts.empty())
// {
// surfaceCellSizeFunction_().recalculateInterpolation();
// }
// return true;
return false;
}

View File

@ -94,6 +94,15 @@ public:
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -79,8 +79,31 @@ scalar linearSpatial::sizeFunction(const point& pt) const
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool linearSpatial::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
if (sideMode_ == rmBothsides)
{
}
else if (sideMode_ == smInside)
{
}
else if (sideMode_ == smOutside)
{
}
return false;
}
bool linearSpatial::cellSize
(
const point& pt,

View File

@ -98,6 +98,15 @@ public:
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -160,6 +160,59 @@ scalar surfaceOffsetLinearDistance::sizeFunction
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool surfaceOffsetLinearDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
const scalar offsetCellSize =
surfaceCellSizeFunction_().interpolate(pt, hitPt.index());
if (sideMode_ == rmBothsides)
{
shapePts.resize(4);
shapeSizes.resize(4);
shapePts[0] = pt - n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt - n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
shapePts[2] = pt + n*surfaceOffset_;
shapeSizes[2] = offsetCellSize;
shapePts[3] = pt + n*totalDistance_;
shapeSizes[3] = distanceCellSize_;
}
else if (sideMode_ == smInside)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt - n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt + n*surfaceOffset_;
shapeSizes[0] = offsetCellSize;
shapePts[1] = pt + n*totalDistance_;
shapeSizes[1] = distanceCellSize_;
}
return true;
}
bool surfaceOffsetLinearDistance::cellSize
(
const point& pt,

View File

@ -98,6 +98,14 @@ public:
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -60,6 +60,21 @@ uniform::uniform
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool uniform::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
shapePts.setSize(0);
shapeSizes.setSize(0);
return true;
}
bool uniform::cellSize
(
const point& pt,

View File

@ -79,6 +79,14 @@ public:
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -65,6 +65,52 @@ uniformDistance::uniformDistance
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool uniformDistance::sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const
{
const Foam::point& pt = hitPt.hitPoint();
const scalar distanceCellSize =
surfaceCellSizeFunction_().interpolate(pt, hitPt.index());
if (sideMode_ == rmBothsides)
{
shapePts.resize(2);
shapeSizes.resize(2);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
shapePts[1] = pt + n*distance_;
shapeSizes[1] = distanceCellSize;
}
else if (sideMode_ == smInside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
}
else if (sideMode_ == smOutside)
{
shapePts.resize(1);
shapeSizes.resize(1);
shapePts[0] = pt - n*distance_;
shapeSizes[0] = distanceCellSize;
}
return false;
}
bool uniformDistance::cellSize
(
const point& pt,

View File

@ -85,6 +85,14 @@ public:
// Member Functions
virtual bool sizeLocations
(
const pointIndexHit& hitPt,
const vector& n,
pointField& shapePts,
scalarField& shapeSizes
) const;
//- Modify scalar argument to the cell size specified by function.
// Return a boolean specifying if the function was used, i.e. false if
// the point was not in range of the surface for a spatially varying

View File

@ -594,7 +594,6 @@ void Foam::conformalVoronoiMesh::updateSizesAndAlignments
!Pstream::parRun()
&& runTime_.run()
&& runTime_.timeIndex()
% cvMeshControls().sizeAndAlignmentRebuildFrequency() == 0
)
{
storeSizesAndAlignments(storePts);