mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: cvMesh: split refinement and smoothing of background mesh
This commit is contained in:
@ -29,6 +29,10 @@ $(cellSizeAndAlignmentControl)/searchableSurfaceControl/searchableSurfaceControl
|
|||||||
|
|
||||||
cellShapeControl/cellAspectRatioControl/cellAspectRatioControl.C
|
cellShapeControl/cellAspectRatioControl/cellAspectRatioControl.C
|
||||||
|
|
||||||
|
cellShapeControl/smoothAlignmentSolver/smoothAlignmentSolver.C
|
||||||
|
|
||||||
|
cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
|
||||||
|
|
||||||
/*cellSizeControlSurfaces/cellSizeControlSurfaces.C*/
|
/*cellSizeControlSurfaces/cellSizeControlSurfaces.C*/
|
||||||
|
|
||||||
cellSizeFunctions = cellSizeControlSurfaces/cellSizeFunction
|
cellSizeFunctions = cellSizeControlSurfaces/cellSizeFunction
|
||||||
|
|||||||
@ -31,213 +31,16 @@ License
|
|||||||
#include "searchableSurfaceControl.H"
|
#include "searchableSurfaceControl.H"
|
||||||
#include "cellSizeFunction.H"
|
#include "cellSizeFunction.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(cellShapeControl, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
template <class Triangulation, class Type>
|
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::cellShapeControl::filterFarPoints
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
const Field<Type>& field
|
|
||||||
)
|
|
||||||
{
|
|
||||||
tmp<Field<Type> > tNewField(new Field<Type>(field.size()));
|
|
||||||
Field<Type>& newField = tNewField();
|
|
||||||
|
|
||||||
label added = 0;
|
|
||||||
label count = 0;
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename Triangulation::Finite_vertices_iterator vit =
|
|
||||||
mesh.finite_vertices_begin();
|
|
||||||
vit != mesh.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (vit->real())
|
|
||||||
{
|
|
||||||
newField[added++] = field[count];
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
newField.resize(added);
|
|
||||||
|
|
||||||
return tNewField;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
Foam::autoPtr<Foam::mapDistribute> Foam::cellShapeControl::buildReferredMap
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
labelList& indices
|
|
||||||
)
|
|
||||||
{
|
|
||||||
globalIndex globalIndexing(mesh.vertexCount());
|
|
||||||
|
|
||||||
DynamicList<label> dynIndices(mesh.vertexCount()/10);
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename Triangulation::Finite_vertices_iterator vit =
|
|
||||||
mesh.finite_vertices_begin();
|
|
||||||
vit != mesh.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (vit->referred())
|
|
||||||
{
|
|
||||||
dynIndices.append
|
|
||||||
(
|
|
||||||
globalIndexing.toGlobal(vit->procIndex(), vit->index())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
indices.transfer(dynIndices);
|
|
||||||
|
|
||||||
List<Map<label> > compactMap;
|
|
||||||
return autoPtr<mapDistribute>
|
|
||||||
(
|
|
||||||
new mapDistribute
|
|
||||||
(
|
|
||||||
globalIndexing,
|
|
||||||
indices,
|
|
||||||
compactMap
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
Foam::autoPtr<Foam::mapDistribute> Foam::cellShapeControl::buildMap
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
labelListList& pointPoints
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pointPoints.setSize(mesh.vertexCount());
|
|
||||||
|
|
||||||
globalIndex globalIndexing(mesh.vertexCount());
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename Triangulation::Finite_vertices_iterator vit =
|
|
||||||
mesh.finite_vertices_begin();
|
|
||||||
vit != mesh.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!vit->real())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<typename Triangulation::Vertex_handle> adjVerts;
|
|
||||||
mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
|
|
||||||
|
|
||||||
DynamicList<label> indices(adjVerts.size());
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename std::list<typename Triangulation::Vertex_handle>::
|
|
||||||
const_iterator adjVertI = adjVerts.begin();
|
|
||||||
adjVertI != adjVerts.end();
|
|
||||||
++adjVertI
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typename Triangulation::Vertex_handle vh = *adjVertI;
|
|
||||||
|
|
||||||
if (!vh->farPoint())
|
|
||||||
{
|
|
||||||
indices.append
|
|
||||||
(
|
|
||||||
globalIndexing.toGlobal(vh->procIndex(), vh->index())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pointPoints[vit->index()].transfer(indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Map<label> > compactMap;
|
|
||||||
return autoPtr<mapDistribute>
|
|
||||||
(
|
|
||||||
new mapDistribute
|
|
||||||
(
|
|
||||||
globalIndexing,
|
|
||||||
pointPoints,
|
|
||||||
compactMap
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
Foam::tmp<Foam::triadField> Foam::cellShapeControl::buildAlignmentField
|
|
||||||
(
|
|
||||||
const Triangulation& mesh
|
|
||||||
)
|
|
||||||
{
|
|
||||||
tmp<triadField> tAlignments
|
|
||||||
(
|
|
||||||
new triadField(mesh.vertexCount(), triad::unset)
|
|
||||||
);
|
|
||||||
triadField& alignments = tAlignments();
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename Triangulation::Finite_vertices_iterator vit =
|
|
||||||
mesh.finite_vertices_begin();
|
|
||||||
vit != mesh.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!vit->real())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
alignments[vit->index()] = vit->alignment();
|
|
||||||
}
|
|
||||||
|
|
||||||
return tAlignments;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
Foam::tmp<Foam::pointField> Foam::cellShapeControl::buildPointField
|
|
||||||
(
|
|
||||||
const Triangulation& mesh
|
|
||||||
)
|
|
||||||
{
|
|
||||||
tmp<pointField> tPoints
|
|
||||||
(
|
|
||||||
new pointField(mesh.vertexCount(), point(GREAT, GREAT, GREAT))
|
|
||||||
);
|
|
||||||
pointField& points = tPoints();
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
typename Triangulation::Finite_vertices_iterator vit =
|
|
||||||
mesh.finite_vertices_begin();
|
|
||||||
vit != mesh.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!vit->real())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
points[vit->index()] = topoint(vit->point());
|
|
||||||
}
|
|
||||||
|
|
||||||
return tPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -261,7 +64,7 @@ Foam::cellShapeControl::cellShapeControl
|
|||||||
(
|
(
|
||||||
runTime,
|
runTime,
|
||||||
motionDict.subDict("shapeControlFunctions"),
|
motionDict.subDict("shapeControlFunctions"),
|
||||||
geometryToConformTo,
|
geometryToConformTo_,
|
||||||
defaultCellSize_
|
defaultCellSize_
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
@ -300,16 +103,7 @@ Foam::scalar Foam::cellShapeControl::cellSize(const point& pt) const
|
|||||||
|
|
||||||
scalar size = 0;
|
scalar size = 0;
|
||||||
|
|
||||||
label nFarPoints = 0;
|
if (shapeControlMesh_.dimension() < 3 || shapeControlMesh_.is_infinite(ch))
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
|
||||||
{
|
|
||||||
if (ch->vertex(pI)->farPoint())
|
|
||||||
{
|
|
||||||
nFarPoints++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shapeControlMesh_.is_infinite(ch))
|
|
||||||
{
|
{
|
||||||
// if (nFarPoints != 0)
|
// if (nFarPoints != 0)
|
||||||
// {
|
// {
|
||||||
@ -323,22 +117,25 @@ Foam::scalar Foam::cellShapeControl::cellSize(const point& pt) const
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Look up nearest point
|
// Find nearest surface
|
||||||
cellShapeControlMesh::Vertex_handle nearV =
|
size = sizeAndAlignment_.cellSize(pt);
|
||||||
shapeControlMesh_.nearest_vertex
|
|
||||||
(
|
|
||||||
toPoint<cellShapeControlMesh::Point>(pt)
|
|
||||||
);
|
|
||||||
|
|
||||||
size = nearV->targetCellSize();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
label nFarPoints = 0;
|
||||||
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
|
{
|
||||||
|
if (ch->vertex(pI)->farPoint())
|
||||||
|
{
|
||||||
|
nFarPoints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nFarPoints != 0)
|
if (nFarPoints != 0)
|
||||||
{
|
{
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
{
|
{
|
||||||
if (!ch->vertex(pI)->farPoint())
|
if (!ch->vertex(pI)->uninitialised())
|
||||||
{
|
{
|
||||||
size = ch->vertex(pI)->targetCellSize();
|
size = ch->vertex(pI)->targetCellSize();
|
||||||
return size;
|
return size;
|
||||||
@ -368,54 +165,58 @@ Foam::tensor Foam::cellShapeControl::cellAlignment(const point& pt) const
|
|||||||
|
|
||||||
tensor alignment = tensor::zero;
|
tensor alignment = tensor::zero;
|
||||||
|
|
||||||
label nFarPoints = 0;
|
if (shapeControlMesh_.dimension() < 3 || shapeControlMesh_.is_infinite(ch))
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
|
||||||
{
|
{
|
||||||
if (ch->vertex(pI)->farPoint())
|
alignment = tensor::I;
|
||||||
{
|
|
||||||
nFarPoints++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shapeControlMesh_.is_infinite(ch) || nFarPoints == 4)
|
|
||||||
{
|
|
||||||
Pout<< "At Infinite vertex" << endl;
|
|
||||||
|
|
||||||
if (nFarPoints != 0)
|
|
||||||
{
|
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
|
||||||
{
|
|
||||||
if (!ch->vertex(pI)->farPoint())
|
|
||||||
{
|
|
||||||
alignment = ch->vertex(pI)->alignment();
|
|
||||||
return alignment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cellShapeControlMesh::Vertex_handle nearV =
|
|
||||||
// shapeControlMesh_.nearest_vertex
|
|
||||||
// (
|
|
||||||
// toPoint<cellShapeControlMesh::Point>(pt)
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// alignment = nearV->alignment();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// forAll(bary, pI)
|
label nFarPoints = 0;
|
||||||
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
|
{
|
||||||
|
if (ch->vertex(pI)->farPoint())
|
||||||
|
{
|
||||||
|
nFarPoints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (nFarPoints != 0)
|
||||||
// {
|
// {
|
||||||
// alignment += bary[pI]*ch->vertex(pI)->alignment();
|
// for (label pI = 0; pI < 4; ++pI)
|
||||||
|
// {
|
||||||
|
// if (!ch->vertex(pI)->farPoint())
|
||||||
|
// {
|
||||||
|
// alignment = ch->vertex(pI)->alignment();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
triad tri;
|
||||||
|
|
||||||
cellShapeControlMesh::Vertex_handle nearV =
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
shapeControlMesh_.nearest_vertex_in_cell
|
{
|
||||||
(
|
if (bary[pI] > SMALL)
|
||||||
toPoint<cellShapeControlMesh::Point>(pt),
|
{
|
||||||
ch
|
tri += triad(bary[pI]*ch->vertex(pI)->alignment());
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alignment = nearV->alignment();
|
tri.normalize();
|
||||||
|
tri.orthogonalize();
|
||||||
|
// tri = tri.sortxyz();
|
||||||
|
|
||||||
|
alignment = tri;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cellShapeControlMesh::Vertex_handle nearV =
|
||||||
|
// shapeControlMesh_.nearest_vertex_in_cell
|
||||||
|
// (
|
||||||
|
// toPoint<cellShapeControlMesh::Point>(pt),
|
||||||
|
// ch
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// alignment = nearV->alignment();
|
||||||
}
|
}
|
||||||
|
|
||||||
return alignment;
|
return alignment;
|
||||||
@ -437,491 +238,81 @@ void Foam::cellShapeControl::cellSizeAndAlignment
|
|||||||
alignment = tensor::zero;
|
alignment = tensor::zero;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
label nFarPoints = 0;
|
if (shapeControlMesh_.dimension() < 3 || shapeControlMesh_.is_infinite(ch))
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
|
||||||
{
|
{
|
||||||
if (ch->vertex(pI)->farPoint())
|
// Find nearest surface
|
||||||
{
|
size = sizeAndAlignment_.cellSize(pt);
|
||||||
nFarPoints++;
|
alignment = tensor::I;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shapeControlMesh_.is_infinite(ch))
|
|
||||||
{
|
|
||||||
if (nFarPoints != 0)
|
|
||||||
{
|
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
|
||||||
{
|
|
||||||
if (!ch->vertex(pI)->farPoint())
|
|
||||||
{
|
|
||||||
size = ch->vertex(pI)->targetCellSize();
|
|
||||||
alignment = ch->vertex(pI)->alignment();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cellShapeControlMesh::Vertex_handle nearV =
|
|
||||||
// shapeControlMesh_.nearest_vertex
|
|
||||||
// (
|
|
||||||
// toPoint<cellShapeControlMesh::Point>(pt)
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// size = nearV->targetCellSize();
|
|
||||||
// alignment = nearV->alignment();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
label nFarPoints = 0;
|
||||||
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
|
{
|
||||||
|
if (ch->vertex(pI)->farPoint())
|
||||||
|
{
|
||||||
|
nFarPoints++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (nFarPoints != 0)
|
if (nFarPoints != 0)
|
||||||
{
|
{
|
||||||
for (label pI = 0; pI < 4; ++pI)
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
{
|
{
|
||||||
if (!ch->vertex(pI)->farPoint())
|
if (!ch->vertex(pI)->uninitialised())
|
||||||
{
|
{
|
||||||
size = ch->vertex(pI)->targetCellSize();
|
size = ch->vertex(pI)->targetCellSize();
|
||||||
alignment = ch->vertex(pI)->alignment();
|
alignment = ch->vertex(pI)->alignment();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// triad tri;
|
triad tri;
|
||||||
|
|
||||||
forAll(bary, pI)
|
for (label pI = 0; pI < 4; ++pI)
|
||||||
{
|
{
|
||||||
size += bary[pI]*ch->vertex(pI)->targetCellSize();
|
size += bary[pI]*ch->vertex(pI)->targetCellSize();
|
||||||
|
|
||||||
// triad triTmp2 = ch->vertex(pI)->alignment();
|
if (bary[pI] > SMALL)
|
||||||
// tri += triTmp2*bary[pI];
|
{
|
||||||
|
tri += triad(bary[pI]*ch->vertex(pI)->alignment());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tri.normalize();
|
tri.normalize();
|
||||||
// tri.orthogonalize();
|
tri.orthogonalize();
|
||||||
// tri = tri.sortxyz();
|
// tri = tri.sortxyz();
|
||||||
|
|
||||||
|
alignment = tri;
|
||||||
|
|
||||||
|
// cellShapeControlMesh::Vertex_handle nearV =
|
||||||
|
// shapeControlMesh_.nearest_vertex
|
||||||
|
// (
|
||||||
|
// toPoint<cellShapeControlMesh::Point>(pt)
|
||||||
|
// );
|
||||||
//
|
//
|
||||||
// alignment = tri;
|
// alignment = nearV->alignment();
|
||||||
|
|
||||||
cellShapeControlMesh::Vertex_handle nearV =
|
|
||||||
shapeControlMesh_.nearest_vertex
|
|
||||||
(
|
|
||||||
toPoint<cellShapeControlMesh::Point>(pt)
|
|
||||||
);
|
|
||||||
|
|
||||||
alignment = nearV->alignment();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
for (label dir = 0; dir < 3; dir++)
|
||||||
void Foam::cellShapeControl::initialMeshPopulation
|
|
||||||
(
|
|
||||||
const autoPtr<backgroundMeshDecomposition>& decomposition
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Need to pass in the background mesh decomposition so that can test if
|
|
||||||
// a point to insert is on the processor.
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
{
|
||||||
shapeControlMesh_.insertBoundingPoints(decomposition().procBounds());
|
const triad v = alignment;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shapeControlMesh_.insertBoundingPoints(allGeometry_.bounds());
|
|
||||||
}
|
|
||||||
|
|
||||||
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
|
if (!v.set(dir) || size == 0)
|
||||||
sizeAndAlignment_.controlFunctions();
|
|
||||||
|
|
||||||
forAll(controlFunctions, fI)
|
|
||||||
{
|
|
||||||
const cellSizeAndAlignmentControl& controlFunction =
|
|
||||||
controlFunctions[fI];
|
|
||||||
|
|
||||||
Info<< "Inserting points from " << controlFunction.name()
|
|
||||||
<< " (" << controlFunction.type() << ")" << endl;
|
|
||||||
|
|
||||||
pointField pts;
|
|
||||||
scalarField sizes;
|
|
||||||
triadField alignments;
|
|
||||||
|
|
||||||
controlFunction.initialVertices(pts, sizes, alignments);
|
|
||||||
|
|
||||||
List<Vb> vertices(pts.size());
|
|
||||||
|
|
||||||
// Clip the minimum size
|
|
||||||
forAll(vertices, vI)
|
|
||||||
{
|
{
|
||||||
vertices[vI] = Vb(pts[vI], Vb::vtInternal);
|
FatalErrorIn
|
||||||
vertices[vI].targetCellSize() = max(sizes[vI], minimumCellSize_);
|
|
||||||
vertices[vI].alignment() = alignments[vI];
|
|
||||||
}
|
|
||||||
|
|
||||||
pts.clear();
|
|
||||||
sizes.clear();
|
|
||||||
alignments.clear();
|
|
||||||
|
|
||||||
label nRejected = 0;
|
|
||||||
|
|
||||||
PackedBoolList keepVertex(vertices.size(), true);
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
forAll(vertices, vI)
|
|
||||||
{
|
|
||||||
const bool onProc = decomposition().positionOnThisProcessor
|
|
||||||
(
|
|
||||||
topoint(vertices[vI].point())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!onProc)
|
|
||||||
{
|
|
||||||
keepVertex[vI] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inplaceSubset(keepVertex, vertices);
|
|
||||||
|
|
||||||
const label preInsertedSize = shapeControlMesh_.number_of_vertices();
|
|
||||||
|
|
||||||
shapeControlMesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
|
|
||||||
|
|
||||||
Info<< " Inserted "
|
|
||||||
<< returnReduce
|
|
||||||
(
|
|
||||||
shapeControlMesh_.number_of_vertices()
|
|
||||||
- preInsertedSize, sumOp<label>()
|
|
||||||
)
|
|
||||||
<< "/" << vertices.size()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::cellShapeControl::refineMesh
|
|
||||||
(
|
|
||||||
const autoPtr<backgroundMeshDecomposition>& decomposition
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const pointField cellCentres(shapeControlMesh_.cellCentres());
|
|
||||||
|
|
||||||
Info<< " Created cell centres" << endl;
|
|
||||||
|
|
||||||
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
|
|
||||||
sizeAndAlignment_.controlFunctions();
|
|
||||||
|
|
||||||
DynamicList<Vb> verts(shapeControlMesh_.number_of_vertices());
|
|
||||||
|
|
||||||
forAll(cellCentres, cellI)
|
|
||||||
{
|
|
||||||
const Foam::point& pt = cellCentres[cellI];
|
|
||||||
|
|
||||||
if (!geometryToConformTo_.inside(pt))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalarList bary;
|
|
||||||
cellShapeControlMesh::Cell_handle ch;
|
|
||||||
|
|
||||||
shapeControlMesh_.barycentricCoords(pt, bary, ch);
|
|
||||||
|
|
||||||
if (shapeControlMesh_.is_infinite(ch))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar interpolatedSize = 0;
|
|
||||||
forAll(bary, pI)
|
|
||||||
{
|
|
||||||
interpolatedSize += bary[pI]*ch->vertex(pI)->targetCellSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
label lastPriority = labelMax;
|
|
||||||
scalar lastCellSize = GREAT;
|
|
||||||
forAll(controlFunctions, fI)
|
|
||||||
{
|
|
||||||
const cellSizeAndAlignmentControl& controlFunction =
|
|
||||||
controlFunctions[fI];
|
|
||||||
|
|
||||||
if (controlFunction.priority() > lastPriority)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isA<searchableSurfaceControl>(controlFunction))
|
|
||||||
{
|
|
||||||
const cellSizeFunction& sizeFunction =
|
|
||||||
dynamicCast<const searchableSurfaceControl>
|
|
||||||
(
|
|
||||||
controlFunction
|
|
||||||
).sizeFunction();
|
|
||||||
|
|
||||||
scalar cellSize = 0;
|
|
||||||
if (sizeFunction.cellSize(pt, cellSize))
|
|
||||||
{
|
|
||||||
if (controlFunction.priority() == lastPriority)
|
|
||||||
{
|
|
||||||
if (cellSize < lastCellSize)
|
|
||||||
{
|
|
||||||
lastCellSize = cellSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastCellSize = cellSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastPriority = controlFunction.priority();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
lastCellSize < GREAT
|
|
||||||
//&& mag(interpolatedSize - lastCellSize)/lastCellSize > 0.2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
if (!decomposition().positionOnThisProcessor(pt))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
verts.append
|
|
||||||
(
|
(
|
||||||
Vb
|
"Foam::conformalVoronoiMesh::setVertexSizeAndAlignment()"
|
||||||
(
|
) << "Point has bad alignment! "
|
||||||
toPoint<cellShapeControlMesh::Point>(pt),
|
<< pt << " " << size << " " << alignment << nl
|
||||||
Vb::vtInternal
|
<< "Bary Coords = " << bary << nl
|
||||||
)
|
<< ch->vertex(0)->info() << nl
|
||||||
);
|
<< ch->vertex(1)->info() << nl
|
||||||
verts.last().targetCellSize() = lastCellSize;
|
<< ch->vertex(2)->info() << nl
|
||||||
verts.last().alignment() = triad::unset;
|
<< ch->vertex(3)->info()
|
||||||
}
|
<< abort(FatalError);
|
||||||
}
|
|
||||||
|
|
||||||
shapeControlMesh_.insertPoints(verts);
|
|
||||||
|
|
||||||
return verts.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::cellShapeControl::smoothMesh()
|
|
||||||
{
|
|
||||||
label maxSmoothingIterations = readLabel(lookup("maxSmoothingIterations"));
|
|
||||||
scalar minResidual = 0;
|
|
||||||
|
|
||||||
labelListList pointPoints;
|
|
||||||
autoPtr<mapDistribute> meshDistributor = buildMap
|
|
||||||
(
|
|
||||||
shapeControlMesh_,
|
|
||||||
pointPoints
|
|
||||||
);
|
|
||||||
|
|
||||||
triadField alignments(buildAlignmentField(shapeControlMesh_));
|
|
||||||
pointField points(buildPointField(shapeControlMesh_));
|
|
||||||
// Setup the sizes and alignments on each point
|
|
||||||
triadField fixedAlignments(shapeControlMesh_.vertexCount(), triad::unset);
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
CellSizeDelaunay::Finite_vertices_iterator vit =
|
|
||||||
shapeControlMesh_.finite_vertices_begin();
|
|
||||||
vit != shapeControlMesh_.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (vit->real())
|
|
||||||
{
|
|
||||||
fixedAlignments[vit->index()] = vit->alignment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< nl << "Smoothing alignments" << endl;
|
|
||||||
|
|
||||||
for (label iter = 0; iter < maxSmoothingIterations; iter++)
|
|
||||||
{
|
|
||||||
Info<< "Iteration " << iter;
|
|
||||||
|
|
||||||
meshDistributor().distribute(points);
|
|
||||||
meshDistributor().distribute(alignments);
|
|
||||||
|
|
||||||
scalar residual = 0;
|
|
||||||
|
|
||||||
triadField triadAv(alignments.size(), triad::unset);
|
|
||||||
|
|
||||||
forAll(pointPoints, pI)
|
|
||||||
{
|
|
||||||
const labelList& pPoints = pointPoints[pI];
|
|
||||||
|
|
||||||
if (pPoints.empty())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
triad& newTriad = triadAv[pI];
|
|
||||||
|
|
||||||
forAll(pPoints, adjPointI)
|
|
||||||
{
|
|
||||||
const label adjPointIndex = pPoints[adjPointI];
|
|
||||||
|
|
||||||
scalar dist = mag(points[pI] - points[adjPointIndex]);
|
|
||||||
|
|
||||||
triad tmpTriad = alignments[adjPointIndex];
|
|
||||||
|
|
||||||
for (direction dir = 0; dir < 3; dir++)
|
|
||||||
{
|
|
||||||
if (tmpTriad.set(dir))
|
|
||||||
{
|
|
||||||
tmpTriad[dir] *= (1.0/dist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newTriad += tmpTriad;
|
|
||||||
}
|
|
||||||
|
|
||||||
newTriad.normalize();
|
|
||||||
newTriad.orthogonalize();
|
|
||||||
newTriad = newTriad.sortxyz();
|
|
||||||
|
|
||||||
// Enforce the boundary conditions
|
|
||||||
const triad& fixedAlignment = fixedAlignments[pI];
|
|
||||||
|
|
||||||
label nFixed = 0;
|
|
||||||
|
|
||||||
forAll(fixedAlignment, dirI)
|
|
||||||
{
|
|
||||||
if (fixedAlignment.set(dirI))
|
|
||||||
{
|
|
||||||
nFixed++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nFixed == 1)
|
|
||||||
{
|
|
||||||
forAll(fixedAlignment, dirI)
|
|
||||||
{
|
|
||||||
if (fixedAlignment.set(dirI))
|
|
||||||
{
|
|
||||||
newTriad.align(fixedAlignment[dirI]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nFixed == 2)
|
|
||||||
{
|
|
||||||
forAll(fixedAlignment, dirI)
|
|
||||||
{
|
|
||||||
if (fixedAlignment.set(dirI))
|
|
||||||
{
|
|
||||||
newTriad[dirI] = fixedAlignment[dirI];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newTriad[dirI] = triad::unset[dirI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newTriad.orthogonalize();
|
|
||||||
}
|
|
||||||
else if (nFixed == 3)
|
|
||||||
{
|
|
||||||
forAll(fixedAlignment, dirI)
|
|
||||||
{
|
|
||||||
if (fixedAlignment.set(dirI))
|
|
||||||
{
|
|
||||||
newTriad[dirI] = fixedAlignment[dirI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const triad& oldTriad = alignments[pI];
|
|
||||||
|
|
||||||
for (direction dir = 0; dir < 3; ++dir)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
newTriad.set(dir)
|
|
||||||
&& oldTriad.set(dir)
|
|
||||||
//&& !fixedAlignment.set(dir)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
scalar dotProd = (oldTriad[dir] & newTriad[dir]);
|
|
||||||
scalar diff = mag(dotProd) - 1.0;
|
|
||||||
|
|
||||||
residual += mag(diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (iter == 198 || iter == 199)
|
|
||||||
// {
|
|
||||||
// Info<< "Triad" << nl
|
|
||||||
// << " Fixed (" << nFixed << ") = " << fixedAlignment
|
|
||||||
// << nl
|
|
||||||
// << " Old = " << oldTriad << nl
|
|
||||||
// << " Pre-Align= " << triadAv[pI] << nl
|
|
||||||
// << " New = " << newTriad << nl
|
|
||||||
// << " Residual = " << residual << endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(alignments, pI)
|
|
||||||
{
|
|
||||||
alignments[pI] = triadAv[pI].sortxyz();
|
|
||||||
}
|
|
||||||
|
|
||||||
reduce(residual, sumOp<scalar>());
|
|
||||||
|
|
||||||
Info<< ", Residual = " << residual << endl;
|
|
||||||
|
|
||||||
if (iter > 0 && residual <= minResidual)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meshDistributor().distribute(alignments);
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
CellSizeDelaunay::Finite_vertices_iterator vit =
|
|
||||||
shapeControlMesh_.finite_vertices_begin();
|
|
||||||
vit != shapeControlMesh_.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (vit->real())
|
|
||||||
{
|
|
||||||
vit->alignment() = alignments[vit->index()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
labelList referredPoints;
|
|
||||||
autoPtr<mapDistribute> referredDistributor = buildReferredMap
|
|
||||||
(
|
|
||||||
shapeControlMesh_,
|
|
||||||
referredPoints
|
|
||||||
);
|
|
||||||
|
|
||||||
alignments.setSize(shapeControlMesh_.vertexCount());
|
|
||||||
referredDistributor().distribute(alignments);
|
|
||||||
|
|
||||||
label referredI = 0;
|
|
||||||
for
|
|
||||||
(
|
|
||||||
CellSizeDelaunay::Finite_vertices_iterator vit =
|
|
||||||
shapeControlMesh_.finite_vertices_begin();
|
|
||||||
vit != shapeControlMesh_.finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (vit->referred())
|
|
||||||
{
|
|
||||||
vit->alignment() = alignments[referredPoints[referredI++]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,33 +84,6 @@ class cellShapeControl
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
template <class Triangulation, class Type>
|
|
||||||
tmp<Field<Type> > filterFarPoints
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
const Field<Type>& field
|
|
||||||
);
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
autoPtr<mapDistribute> buildMap
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
labelListList& pointPoints
|
|
||||||
);
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
autoPtr<mapDistribute> buildReferredMap
|
|
||||||
(
|
|
||||||
const Triangulation& mesh,
|
|
||||||
labelList& indices
|
|
||||||
);
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
tmp<triadField> buildAlignmentField(const Triangulation& mesh);
|
|
||||||
|
|
||||||
template <class Triangulation>
|
|
||||||
tmp<pointField> buildPointField(const Triangulation& mesh);
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
cellShapeControl(const cellShapeControl&);
|
cellShapeControl(const cellShapeControl&);
|
||||||
|
|
||||||
@ -155,6 +128,8 @@ public:
|
|||||||
|
|
||||||
inline const cellSizeAndAlignmentControls& sizeAndAlignment() const;
|
inline const cellSizeAndAlignmentControls& sizeAndAlignment() const;
|
||||||
|
|
||||||
|
inline const scalar& minimumCellSize() const;
|
||||||
|
|
||||||
|
|
||||||
// Query
|
// Query
|
||||||
|
|
||||||
@ -172,29 +147,6 @@ public:
|
|||||||
scalar& size,
|
scalar& size,
|
||||||
tensor& alignment
|
tensor& alignment
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
|
||||||
|
|
||||||
void initialMeshPopulation
|
|
||||||
(
|
|
||||||
const autoPtr<backgroundMeshDecomposition>& decomposition
|
|
||||||
);
|
|
||||||
|
|
||||||
label refineMesh
|
|
||||||
(
|
|
||||||
const autoPtr<backgroundMeshDecomposition>& decomposition
|
|
||||||
);
|
|
||||||
|
|
||||||
void smoothMesh();
|
|
||||||
|
|
||||||
//- Add a control point with a specified size and alignment
|
|
||||||
// virtual void addControlPoint
|
|
||||||
// (
|
|
||||||
// const point& pt,
|
|
||||||
// const scalar& size,
|
|
||||||
// const tensor& alignment
|
|
||||||
// );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -52,4 +52,17 @@ Foam::cellShapeControl::aspectRatio() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::cellSizeAndAlignmentControls&
|
||||||
|
Foam::cellShapeControl::sizeAndAlignment() const
|
||||||
|
{
|
||||||
|
return sizeAndAlignment_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::scalar& Foam::cellShapeControl::minimumCellSize() const
|
||||||
|
{
|
||||||
|
return minimumCellSize_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -24,6 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "cellShapeControlMesh.H"
|
#include "cellShapeControlMesh.H"
|
||||||
|
#include "cellSizeAndAlignmentControls.H"
|
||||||
#include "pointIOField.H"
|
#include "pointIOField.H"
|
||||||
#include "scalarIOField.H"
|
#include "scalarIOField.H"
|
||||||
#include "tensorIOField.H"
|
#include "tensorIOField.H"
|
||||||
@ -36,9 +37,7 @@ License
|
|||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
defineTypeNameAndDebug(cellShapeControlMesh, 0);
|
defineTypeNameAndDebug(cellShapeControlMesh, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -537,12 +536,9 @@ void Foam::cellShapeControlMesh::barycentricCoords
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Use the previous cell handle as a hint on where to start searching
|
// Use the previous cell handle as a hint on where to start searching
|
||||||
ch = locate
|
ch = locate(toPoint<Point>(pt));
|
||||||
(
|
|
||||||
Point(pt.x(), pt.y(), pt.z())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!is_infinite(ch))
|
if (dimension() > 2 && !is_infinite(ch))
|
||||||
{
|
{
|
||||||
oldCellHandle_ = ch;
|
oldCellHandle_ = ch;
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,8 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class cellSizeAndAlignmentControls;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class cellShapeControlMesh Declaration
|
Class cellShapeControlMesh Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|||||||
@ -48,7 +48,7 @@ Foam::cellSizeAndAlignmentControl::cellSizeAndAlignmentControl
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
runTime_(runTime),
|
runTime_(runTime),
|
||||||
@ -64,7 +64,7 @@ Foam::cellSizeAndAlignmentControl::New
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
word cellSizeAndAlignmentControlTypeName
|
word cellSizeAndAlignmentControlTypeName
|
||||||
@ -72,7 +72,7 @@ Foam::cellSizeAndAlignmentControl::New
|
|||||||
controlFunctionDict.lookup("type")
|
controlFunctionDict.lookup("type")
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< nl << "Selecting cellSizeAndAlignmentControl "
|
Info<< " Selecting cellSizeAndAlignmentControl "
|
||||||
<< cellSizeAndAlignmentControlTypeName << endl;
|
<< cellSizeAndAlignmentControlTypeName << endl;
|
||||||
|
|
||||||
dictionaryConstructorTable::iterator cstrIter =
|
dictionaryConstructorTable::iterator cstrIter =
|
||||||
@ -101,7 +101,7 @@ Foam::cellSizeAndAlignmentControl::New
|
|||||||
runTime,
|
runTime,
|
||||||
name,
|
name,
|
||||||
controlFunctionDict,
|
controlFunctionDict,
|
||||||
allGeometry
|
geometryToConformTo
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,9 +91,9 @@ public:
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
),
|
),
|
||||||
(runTime, name, controlFunctionDict, allGeometry)
|
(runTime, name, controlFunctionDict, geometryToConformTo)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ public:
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,7 @@ License
|
|||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
defineTypeNameAndDebug(cellSizeAndAlignmentControls, 0);
|
defineTypeNameAndDebug(cellSizeAndAlignmentControls, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -116,12 +114,12 @@ Foam::cellSizeAndAlignmentControls::cellSizeAndAlignmentControls
|
|||||||
(
|
(
|
||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const dictionary& shapeControlDict,
|
const dictionary& shapeControlDict,
|
||||||
const conformationSurfaces& allGeometry,
|
const conformationSurfaces& geometryToConformTo,
|
||||||
const scalar defaultCellSize
|
const scalar defaultCellSize
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
shapeControlDict_(shapeControlDict),
|
shapeControlDict_(shapeControlDict),
|
||||||
allGeometry_(allGeometry),
|
geometryToConformTo_(geometryToConformTo),
|
||||||
controlFunctions_(shapeControlDict_.size()),
|
controlFunctions_(shapeControlDict_.size()),
|
||||||
defaultCellSize_(defaultCellSize)
|
defaultCellSize_(defaultCellSize)
|
||||||
{
|
{
|
||||||
@ -136,6 +134,8 @@ Foam::cellSizeAndAlignmentControls::cellSizeAndAlignmentControls
|
|||||||
shapeControlDict_.subDict(shapeControlEntryName)
|
shapeControlDict_.subDict(shapeControlEntryName)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Info<< nl << "Shape Control : " << shapeControlEntryName << endl;
|
||||||
|
|
||||||
controlFunctions_.set
|
controlFunctions_.set
|
||||||
(
|
(
|
||||||
functionI,
|
functionI,
|
||||||
@ -144,7 +144,7 @@ Foam::cellSizeAndAlignmentControls::cellSizeAndAlignmentControls
|
|||||||
runTime,
|
runTime,
|
||||||
shapeControlEntryName,
|
shapeControlEntryName,
|
||||||
controlFunctionDict,
|
controlFunctionDict,
|
||||||
allGeometry
|
geometryToConformTo
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ class cellSizeAndAlignmentControls
|
|||||||
|
|
||||||
const dictionary& shapeControlDict_;
|
const dictionary& shapeControlDict_;
|
||||||
|
|
||||||
const conformationSurfaces& allGeometry_;
|
const conformationSurfaces& geometryToConformTo_;
|
||||||
|
|
||||||
PtrList<cellSizeAndAlignmentControl> controlFunctions_;
|
PtrList<cellSizeAndAlignmentControl> controlFunctions_;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ public:
|
|||||||
(
|
(
|
||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const dictionary& shapeControlDict,
|
const dictionary& shapeControlDict,
|
||||||
const conformationSurfaces& allGeometry,
|
const conformationSurfaces& geometryToConformTo,
|
||||||
const scalar defaultCellSize
|
const scalar defaultCellSize
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -96,11 +96,17 @@ public:
|
|||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
const PtrList<cellSizeAndAlignmentControl>& controlFunctions() const
|
inline const PtrList<cellSizeAndAlignmentControl>&
|
||||||
|
controlFunctions() const
|
||||||
{
|
{
|
||||||
return controlFunctions_;
|
return controlFunctions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const conformationSurfaces& geometryToConformTo() const
|
||||||
|
{
|
||||||
|
return geometryToConformTo_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Query
|
// Query
|
||||||
|
|
||||||
|
|||||||
@ -58,7 +58,7 @@ Foam::fileControl::fileControl
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
cellSizeAndAlignmentControl
|
cellSizeAndAlignmentControl
|
||||||
@ -66,7 +66,7 @@ Foam::fileControl::fileControl
|
|||||||
runTime,
|
runTime,
|
||||||
name,
|
name,
|
||||||
controlFunctionDict,
|
controlFunctionDict,
|
||||||
allGeometry
|
geometryToConformTo
|
||||||
),
|
),
|
||||||
pointsFile_(controlFunctionDict.lookup("pointsFile")),
|
pointsFile_(controlFunctionDict.lookup("pointsFile")),
|
||||||
sizesFile_(controlFunctionDict.lookup("sizesFile")),
|
sizesFile_(controlFunctionDict.lookup("sizesFile")),
|
||||||
|
|||||||
@ -85,7 +85,7 @@ public:
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
|
|||||||
@ -158,7 +158,7 @@ Foam::searchableSurfaceControl::searchableSurfaceControl
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
cellSizeAndAlignmentControl
|
cellSizeAndAlignmentControl
|
||||||
@ -166,11 +166,11 @@ Foam::searchableSurfaceControl::searchableSurfaceControl
|
|||||||
runTime,
|
runTime,
|
||||||
name,
|
name,
|
||||||
controlFunctionDict,
|
controlFunctionDict,
|
||||||
allGeometry
|
geometryToConformTo
|
||||||
),
|
),
|
||||||
surfaceName_(controlFunctionDict.lookupOrDefault<word>("surface", name)),
|
surfaceName_(controlFunctionDict.lookupOrDefault<word>("surface", name)),
|
||||||
searchableSurface_(allGeometry.geometry()[surfaceName_]),
|
searchableSurface_(geometryToConformTo.geometry()[surfaceName_]),
|
||||||
allGeometry_(allGeometry),
|
geometryToConformTo_(geometryToConformTo),
|
||||||
cellSizeFunction_
|
cellSizeFunction_
|
||||||
(
|
(
|
||||||
cellSizeFunction::New(controlFunctionDict, searchableSurface_)
|
cellSizeFunction::New(controlFunctionDict, searchableSurface_)
|
||||||
@ -579,7 +579,7 @@ void Foam::searchableSurfaceControl::initialVertices
|
|||||||
|
|
||||||
pointIndexHit info;
|
pointIndexHit info;
|
||||||
label infoFeature;
|
label infoFeature;
|
||||||
allGeometry_.findFeaturePointNearest
|
geometryToConformTo_.findFeaturePointNearest
|
||||||
(
|
(
|
||||||
pts[pI],
|
pts[pI],
|
||||||
nearFeatDistSqrCoeff,
|
nearFeatDistSqrCoeff,
|
||||||
@ -592,7 +592,7 @@ void Foam::searchableSurfaceControl::initialVertices
|
|||||||
if (info.hit())
|
if (info.hit())
|
||||||
{
|
{
|
||||||
const extendedFeatureEdgeMesh& features =
|
const extendedFeatureEdgeMesh& features =
|
||||||
allGeometry_.features()[infoFeature];
|
geometryToConformTo_.features()[infoFeature];
|
||||||
|
|
||||||
vectorField norms = features.featurePointNormals(info.index());
|
vectorField norms = features.featurePointNormals(info.index());
|
||||||
|
|
||||||
@ -608,7 +608,7 @@ void Foam::searchableSurfaceControl::initialVertices
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
allGeometry_.findEdgeNearest
|
geometryToConformTo_.findEdgeNearest
|
||||||
(
|
(
|
||||||
pts[pI],
|
pts[pI],
|
||||||
nearFeatDistSqrCoeff,
|
nearFeatDistSqrCoeff,
|
||||||
@ -619,7 +619,7 @@ void Foam::searchableSurfaceControl::initialVertices
|
|||||||
if (info.hit())
|
if (info.hit())
|
||||||
{
|
{
|
||||||
const extendedFeatureEdgeMesh& features =
|
const extendedFeatureEdgeMesh& features =
|
||||||
allGeometry_.features()[infoFeature];
|
geometryToConformTo_.features()[infoFeature];
|
||||||
|
|
||||||
vectorField norms = features.edgeNormals(info.index());
|
vectorField norms = features.edgeNormals(info.index());
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class searchableSurfaceControl
|
|||||||
//- Reference to the searchableSurface object holding the geometry data
|
//- Reference to the searchableSurface object holding the geometry data
|
||||||
const searchableSurface& searchableSurface_;
|
const searchableSurface& searchableSurface_;
|
||||||
|
|
||||||
const conformationSurfaces& allGeometry_;
|
const conformationSurfaces& geometryToConformTo_;
|
||||||
|
|
||||||
autoPtr<cellSizeFunction> cellSizeFunction_;
|
autoPtr<cellSizeFunction> cellSizeFunction_;
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& controlFunctionDict,
|
const dictionary& controlFunctionDict,
|
||||||
const conformationSurfaces& allGeometry
|
const conformationSurfaces& geometryToConformTo
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
|
|||||||
@ -0,0 +1,683 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "controlMeshRefinement.H"
|
||||||
|
#include "cellSizeAndAlignmentControl.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(controlMeshRefinement, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::controlMeshRefinement::detectEdge
|
||||||
|
(
|
||||||
|
point a,
|
||||||
|
point b,
|
||||||
|
DynamicList<Vb>& pointsFound
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const Foam::point midpoint = 0.5*(a + b);
|
||||||
|
const scalar h = mag(a - b);
|
||||||
|
|
||||||
|
scalar cellSizeA = sizeControls_.cellSize(a);
|
||||||
|
scalar cellSizeMid = sizeControls_.cellSize(midpoint);
|
||||||
|
scalar cellSizeB = sizeControls_.cellSize(b);
|
||||||
|
|
||||||
|
scalar firstDerivative = (cellSizeA - cellSizeB)/h;
|
||||||
|
|
||||||
|
scalar secondDerivative =
|
||||||
|
(
|
||||||
|
cellSizeB
|
||||||
|
- 2*cellSizeMid
|
||||||
|
+ cellSizeA
|
||||||
|
)
|
||||||
|
/magSqr(h/2.0);
|
||||||
|
|
||||||
|
// Info<< a << " " << midpoint << " " << b << endl;
|
||||||
|
// Info<< " length = " << h << endl;
|
||||||
|
// Info<< "size(a) = " << cellSizeA << endl;
|
||||||
|
// Info<< "size(m) = " << cellSizeMid << endl;
|
||||||
|
// Info<< "size(b) = " << cellSizeB << endl;
|
||||||
|
// Info<< " f' = " << firstDerivative << endl;
|
||||||
|
// Info<< " f'' = " << secondDerivative << endl;
|
||||||
|
|
||||||
|
if (mag(secondDerivative) < 1e-1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mag(a - b) < 1e-1*cellSizeMid)
|
||||||
|
{
|
||||||
|
if (geometryToConformTo_.outside(midpoint))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Info<< " Point Added" << endl;
|
||||||
|
|
||||||
|
pointsFound.append
|
||||||
|
(
|
||||||
|
Vb
|
||||||
|
(
|
||||||
|
toPoint<cellShapeControlMesh::Point>(midpoint),
|
||||||
|
Vb::vtInternal
|
||||||
|
)
|
||||||
|
);
|
||||||
|
pointsFound.last().targetCellSize() =
|
||||||
|
sizeControls_.cellSize(midpoint);
|
||||||
|
pointsFound.last().alignment() = triad::unset;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
detectEdge(a, midpoint, pointsFound);
|
||||||
|
detectEdge(midpoint, b, pointsFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::DynamicList<Vb>
|
||||||
|
Foam::controlMeshRefinement::findDiscontinuities(const linePointRef& l) const
|
||||||
|
{
|
||||||
|
DynamicList<Vb> verts(2);
|
||||||
|
|
||||||
|
// Divide up the line into a reasonable number of intervals
|
||||||
|
|
||||||
|
|
||||||
|
// Call detectEdge on each interval
|
||||||
|
detectEdge(l.start(), l.end(), verts);
|
||||||
|
|
||||||
|
if (verts.size())
|
||||||
|
{
|
||||||
|
Info<< l << " has " << verts.size() << " discontinuities" << endl;
|
||||||
|
|
||||||
|
OFstream str("plotSizes_" + name(verts.size()));
|
||||||
|
|
||||||
|
forAll(verts, vI)
|
||||||
|
{
|
||||||
|
scalar x =
|
||||||
|
mag(topoint(verts[vI].point()) - l.start())
|
||||||
|
/mag(l.end() - l.start());
|
||||||
|
|
||||||
|
str << x << " " << verts[vI].targetCellSize() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// forAll(verts, vI)
|
||||||
|
// {
|
||||||
|
// Info<< verts[vI].info();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
return verts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::controlMeshRefinement::controlMeshRefinement
|
||||||
|
(
|
||||||
|
cellShapeControl& shapeController
|
||||||
|
)
|
||||||
|
:
|
||||||
|
shapeController_(shapeController),
|
||||||
|
mesh_(shapeController.shapeControlMesh()),
|
||||||
|
sizeControls_(shapeController.sizeAndAlignment()),
|
||||||
|
geometryToConformTo_(sizeControls_.geometryToConformTo())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::controlMeshRefinement::~controlMeshRefinement()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::controlMeshRefinement::initialMeshPopulation
|
||||||
|
(
|
||||||
|
const autoPtr<backgroundMeshDecomposition>& decomposition
|
||||||
|
)
|
||||||
|
{
|
||||||
|
autoPtr<boundBox> overallBoundBox;
|
||||||
|
|
||||||
|
// Need to pass in the background mesh decomposition so that can test if
|
||||||
|
// a point to insert is on the processor.
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
overallBoundBox.set(new boundBox(decomposition().procBounds()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
overallBoundBox.set
|
||||||
|
(
|
||||||
|
new boundBox(geometryToConformTo_.geometry().bounds())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh_.insertBoundingPoints
|
||||||
|
(
|
||||||
|
overallBoundBox(),
|
||||||
|
sizeControls_
|
||||||
|
);
|
||||||
|
|
||||||
|
const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
|
||||||
|
sizeControls_.controlFunctions();
|
||||||
|
|
||||||
|
forAll(controlFunctions, fI)
|
||||||
|
{
|
||||||
|
const cellSizeAndAlignmentControl& controlFunction =
|
||||||
|
controlFunctions[fI];
|
||||||
|
|
||||||
|
Info<< "Inserting points from " << controlFunction.name()
|
||||||
|
<< " (" << controlFunction.type() << ")" << endl;
|
||||||
|
|
||||||
|
pointField pts;
|
||||||
|
scalarField sizes;
|
||||||
|
triadField alignments;
|
||||||
|
|
||||||
|
controlFunction.initialVertices(pts, sizes, alignments);
|
||||||
|
|
||||||
|
List<Vb> vertices(pts.size());
|
||||||
|
|
||||||
|
// Clip the minimum size
|
||||||
|
forAll(vertices, vI)
|
||||||
|
{
|
||||||
|
vertices[vI] = Vb(pts[vI], Vb::vtInternalNearBoundary);
|
||||||
|
vertices[vI].targetCellSize() = max
|
||||||
|
(
|
||||||
|
sizes[vI],
|
||||||
|
shapeController_.minimumCellSize()
|
||||||
|
);
|
||||||
|
vertices[vI].alignment() = alignments[vI];
|
||||||
|
}
|
||||||
|
|
||||||
|
pts.clear();
|
||||||
|
sizes.clear();
|
||||||
|
alignments.clear();
|
||||||
|
|
||||||
|
label nRejected = 0;
|
||||||
|
|
||||||
|
PackedBoolList keepVertex(vertices.size(), true);
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
forAll(vertices, vI)
|
||||||
|
{
|
||||||
|
const bool onProc = decomposition().positionOnThisProcessor
|
||||||
|
(
|
||||||
|
topoint(vertices[vI].point())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!onProc)
|
||||||
|
{
|
||||||
|
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 triad interpolatedAlignment =
|
||||||
|
shapeController_.cellAlignment(pt);
|
||||||
|
const scalar calculatedCellSize = vertices[vI].targetCellSize();
|
||||||
|
const triad calculatedAlignment = vertices[vI].alignment();
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< "Point = " << pt << nl
|
||||||
|
<< " Size(interp) = " << interpolatedCellSize << nl
|
||||||
|
<< " Size(calc) = " << calculatedCellSize << nl
|
||||||
|
<< " Align(interp) = " << interpolatedAlignment << nl
|
||||||
|
<< " Align(calc) = " << calculatedAlignment << nl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalar sizeDiff =
|
||||||
|
mag(interpolatedCellSize - calculatedCellSize);
|
||||||
|
const scalar alignmentDiff =
|
||||||
|
diff(interpolatedAlignment, calculatedAlignment);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Info<< " size difference = " << sizeDiff
|
||||||
|
<< ", alignment difference = " << alignmentDiff << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo Also need to base it on the alignments
|
||||||
|
if
|
||||||
|
(
|
||||||
|
sizeDiff/interpolatedCellSize > 0.1
|
||||||
|
|| alignmentDiff > 0.15
|
||||||
|
)
|
||||||
|
{
|
||||||
|
insertPoint = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insertPoint)
|
||||||
|
{
|
||||||
|
mesh_.insert
|
||||||
|
(
|
||||||
|
pt,
|
||||||
|
calculatedCellSize,
|
||||||
|
vertices[vI].alignment(),
|
||||||
|
Vb::vtInternalNearBoundary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//mesh_.rangeInsertWithInfo(vertices.begin(), vertices.end());
|
||||||
|
|
||||||
|
Info<< " Inserted "
|
||||||
|
<< returnReduce
|
||||||
|
(
|
||||||
|
label(mesh_.number_of_vertices()) - preInsertedSize,
|
||||||
|
sumOp<label>()
|
||||||
|
)
|
||||||
|
<< "/" << returnReduce(vertices.size(), sumOp<label>())
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::controlMeshRefinement::refineMesh
|
||||||
|
(
|
||||||
|
const autoPtr<backgroundMeshDecomposition>& decomposition
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Iterate over cell size mesh edges" << endl;
|
||||||
|
|
||||||
|
DynamicList<Vb> verts(mesh_.number_of_vertices());
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
CellSizeDelaunay::Finite_edges_iterator eit =
|
||||||
|
mesh_.finite_edges_begin();
|
||||||
|
eit != mesh_.finite_edges_end();
|
||||||
|
++eit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CellSizeDelaunay::Cell_handle c = eit->first;
|
||||||
|
CellSizeDelaunay::Vertex_handle vA = c->vertex(eit->second);
|
||||||
|
CellSizeDelaunay::Vertex_handle vB = c->vertex(eit->third);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mesh_.is_infinite(vA)
|
||||||
|
|| mesh_.is_infinite(vB)
|
||||||
|
|| (vA->referred() && vB->referred())
|
||||||
|
|| (vA->referred() && vA->procIndex() > vB->procIndex())
|
||||||
|
|| (vB->referred() && vB->procIndex() > vA->procIndex())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointFromPoint ptA(topoint(vA->point()));
|
||||||
|
pointFromPoint ptB(topoint(vB->point()));
|
||||||
|
|
||||||
|
linePointRef l(ptA, ptB);
|
||||||
|
|
||||||
|
// Info<< "Edge " << l << endl;
|
||||||
|
//
|
||||||
|
// Info<< vA->info() << vB->info();
|
||||||
|
|
||||||
|
const Foam::point midPoint = l.centre();
|
||||||
|
const scalar length = l.mag();
|
||||||
|
|
||||||
|
scalar evaluatedSize = sizeControls_.cellSize(midPoint);
|
||||||
|
scalar interpolatedSize =
|
||||||
|
(vA->targetCellSize() + vB->targetCellSize())/2;
|
||||||
|
|
||||||
|
const scalar diff = mag(interpolatedSize - evaluatedSize);
|
||||||
|
|
||||||
|
// Info<< " Evaluated size = " << evaluatedSize << nl
|
||||||
|
// << " Interpolated size = " << interpolatedSize << nl
|
||||||
|
// << " vA cell size = " << vA->targetCellSize() << nl
|
||||||
|
// << " vB cell size = " << vB->targetCellSize() << endl;
|
||||||
|
|
||||||
|
// verts.append(findDiscontinuities(l));
|
||||||
|
|
||||||
|
if (diff/interpolatedSize > 0.1)
|
||||||
|
{
|
||||||
|
// Create a new point
|
||||||
|
// Walk along the edge, placing points where the gradient in cell
|
||||||
|
// size changes
|
||||||
|
if (vA->targetCellSize() <= vB->targetCellSize())
|
||||||
|
{
|
||||||
|
// Walk from vA
|
||||||
|
const label nPoints = length/vA->targetCellSize();
|
||||||
|
|
||||||
|
if (nPoints == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar prevSize = vA->targetCellSize();
|
||||||
|
|
||||||
|
for (label pI = 1; pI < nPoints; ++pI)
|
||||||
|
{
|
||||||
|
const Foam::point testPt =
|
||||||
|
topoint(vA->point()) + pI*l.vec()/nPoints;
|
||||||
|
|
||||||
|
// if (geometryToConformTo_.outside(testPt))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
scalar testPtSize = sizeControls_.cellSize(testPt);
|
||||||
|
|
||||||
|
if (mag(testPtSize - prevSize) < 1e-3*testPtSize)
|
||||||
|
{
|
||||||
|
// Info<< "Adding " << testPt << " " << testPtSize
|
||||||
|
// << endl;
|
||||||
|
verts.append
|
||||||
|
(
|
||||||
|
Vb
|
||||||
|
(
|
||||||
|
toPoint<cellShapeControlMesh::Point>(testPt),
|
||||||
|
Vb::vtInternal
|
||||||
|
)
|
||||||
|
);
|
||||||
|
verts.last().targetCellSize() = testPtSize;
|
||||||
|
verts.last().alignment() = triad::unset;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevSize = testPtSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Walk from vB
|
||||||
|
const label nPoints = length/vB->targetCellSize();
|
||||||
|
|
||||||
|
if (nPoints == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar prevSize = vA->targetCellSize();
|
||||||
|
|
||||||
|
for (label pI = 1; pI < nPoints; ++pI)
|
||||||
|
{
|
||||||
|
const Foam::point testPt =
|
||||||
|
topoint(vB->point()) - pI*l.vec()/nPoints;
|
||||||
|
|
||||||
|
// if (geometryToConformTo_.outside(testPt))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
scalar testPtSize = sizeControls_.cellSize(testPt);
|
||||||
|
|
||||||
|
if (mag(testPtSize - prevSize) < 1e-3*testPtSize)
|
||||||
|
//if (testPtSize > prevSize)// || testPtSize < prevSize)
|
||||||
|
{
|
||||||
|
// Info<< "Adding " << testPt << " " << testPtSize
|
||||||
|
// << endl;
|
||||||
|
verts.append
|
||||||
|
(
|
||||||
|
Vb
|
||||||
|
(
|
||||||
|
toPoint<cellShapeControlMesh::Point>(testPt),
|
||||||
|
Vb::vtInternal
|
||||||
|
)
|
||||||
|
);
|
||||||
|
verts.last().targetCellSize() = testPtSize;
|
||||||
|
verts.last().alignment() = triad::unset;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevSize = testPtSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const pointField cellCentres(mesh_.cellCentres());
|
||||||
|
//
|
||||||
|
// Info<< " Created cell centres" << endl;
|
||||||
|
//
|
||||||
|
// const PtrList<cellSizeAndAlignmentControl>& controlFunctions =
|
||||||
|
// sizeControls_.controlFunctions();
|
||||||
|
//
|
||||||
|
// DynamicList<Vb> verts(mesh_.number_of_vertices());
|
||||||
|
//
|
||||||
|
// forAll(cellCentres, cellI)
|
||||||
|
// {
|
||||||
|
// Foam::point pt = cellCentres[cellI];
|
||||||
|
//
|
||||||
|
// if (!geometryToConformTo_.inside(pt))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// scalarList bary;
|
||||||
|
// cellShapeControlMesh::Cell_handle ch;
|
||||||
|
//
|
||||||
|
// mesh_.barycentricCoords(pt, bary, ch);
|
||||||
|
//
|
||||||
|
// if (mesh_.is_infinite(ch))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// scalar interpolatedSize = 0;
|
||||||
|
// forAll(bary, pI)
|
||||||
|
// {
|
||||||
|
// interpolatedSize += bary[pI]*ch->vertex(pI)->targetCellSize();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// label lastPriority = labelMin;
|
||||||
|
// scalar lastCellSize = GREAT;
|
||||||
|
// forAll(controlFunctions, fI)
|
||||||
|
// {
|
||||||
|
// const cellSizeAndAlignmentControl& controlFunction =
|
||||||
|
// controlFunctions[fI];
|
||||||
|
//
|
||||||
|
// if (controlFunction.priority() < lastPriority)
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (isA<searchableSurfaceControl>(controlFunction))
|
||||||
|
// {
|
||||||
|
// const cellSizeFunction& sizeFunction =
|
||||||
|
// dynamicCast<const searchableSurfaceControl>
|
||||||
|
// (
|
||||||
|
// controlFunction
|
||||||
|
// ).sizeFunction();
|
||||||
|
//
|
||||||
|
// scalar cellSize = 0;
|
||||||
|
// if (sizeFunction.cellSize(pt, cellSize))
|
||||||
|
// {
|
||||||
|
// if (controlFunction.priority() == lastPriority)
|
||||||
|
// {
|
||||||
|
// if (cellSize < lastCellSize)
|
||||||
|
// {
|
||||||
|
// lastCellSize = cellSize;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// lastCellSize = cellSize;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lastPriority = controlFunction.priority();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const scalar diff = mag(interpolatedSize - lastCellSize);
|
||||||
|
//
|
||||||
|
// if (diff/interpolatedSize > 0.1)
|
||||||
|
// {
|
||||||
|
// bool pointFound = false;
|
||||||
|
//
|
||||||
|
// // Travel along lines to each tet point
|
||||||
|
// for (label vI = 0; vI < 4; ++vI)
|
||||||
|
// {
|
||||||
|
// if (pointFound)
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pointFromPoint tetVertex = topoint(ch->vertex(vI)->point());
|
||||||
|
// scalar tetVertexSize = sizeControls_.cellSize(tetVertex);
|
||||||
|
//
|
||||||
|
// if (tetVertexSize < interpolatedSize)
|
||||||
|
// {
|
||||||
|
// linePointRef l(tetVertex, pt);
|
||||||
|
//
|
||||||
|
// label nTestPoints = l.mag()/tetVertexSize;
|
||||||
|
//
|
||||||
|
// for (label i = 1; i < nTestPoints; ++i)
|
||||||
|
// {
|
||||||
|
// const Foam::point testPt
|
||||||
|
// (
|
||||||
|
// tetVertex
|
||||||
|
// + l.vec()*i/nTestPoints
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// scalar testPtSize = sizeControls_.cellSize(testPt);
|
||||||
|
//
|
||||||
|
// if (testPtSize > tetVertexSize)
|
||||||
|
// {
|
||||||
|
// pt = testPt;
|
||||||
|
// lastCellSize = testPtSize;
|
||||||
|
// pointFound = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// linePointRef l(pt, tetVertex);
|
||||||
|
//
|
||||||
|
// label nTestPoints = l.mag()/tetVertexSize;
|
||||||
|
//
|
||||||
|
// for (label i = 1; i < nTestPoints; ++i)
|
||||||
|
// {
|
||||||
|
// const Foam::point testPt
|
||||||
|
// (
|
||||||
|
// tetVertex
|
||||||
|
// + l.vec()*i/nTestPoints
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// scalar testPtSize = sizeControls_.cellSize(testPt);
|
||||||
|
//
|
||||||
|
// if (testPtSize < interpolatedSize)
|
||||||
|
// {
|
||||||
|
// pt = testPt;
|
||||||
|
// lastCellSize = testPtSize;
|
||||||
|
// pointFound = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Decide whether to insert or not
|
||||||
|
// if (lastCellSize < GREAT)
|
||||||
|
// {
|
||||||
|
// if (!geometryToConformTo_.inside(pt))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (Pstream::parRun())
|
||||||
|
// {
|
||||||
|
// if (!decomposition().positionOnThisProcessor(pt))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// verts.append
|
||||||
|
// (
|
||||||
|
// Vb
|
||||||
|
// (
|
||||||
|
// toPoint<cellShapeControlMesh::Point>(pt),
|
||||||
|
// Vb::vtInternal
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// verts.last().targetCellSize() = lastCellSize;
|
||||||
|
// verts.last().alignment() = triad::unset;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
mesh_.insertPoints(verts);
|
||||||
|
|
||||||
|
return verts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::controlMeshRefinement
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
controlMeshRefinementI.H
|
||||||
|
controlMeshRefinement.C
|
||||||
|
controlMeshRefinementIO.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef controlMeshRefinement_H
|
||||||
|
#define controlMeshRefinement_H
|
||||||
|
|
||||||
|
#include "cellShapeControl.H"
|
||||||
|
#include "cellShapeControlMesh.H"
|
||||||
|
#include "cellSizeAndAlignmentControls.H"
|
||||||
|
#include "conformationSurfaces.H"
|
||||||
|
#include "backgroundMeshDecomposition.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class controlMeshRefinement Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class controlMeshRefinement
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
const cellShapeControl& shapeController_;
|
||||||
|
|
||||||
|
cellShapeControlMesh& mesh_;
|
||||||
|
|
||||||
|
const cellSizeAndAlignmentControls& sizeControls_;
|
||||||
|
|
||||||
|
const conformationSurfaces& geometryToConformTo_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
bool detectEdge
|
||||||
|
(
|
||||||
|
point a,
|
||||||
|
point b,
|
||||||
|
DynamicList<Vb>& pointsFound
|
||||||
|
) const;
|
||||||
|
|
||||||
|
DynamicList<Vb> findDiscontinuities(const linePointRef& l) const;
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
controlMeshRefinement(const controlMeshRefinement&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const controlMeshRefinement&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
ClassName("controlMeshRefinement");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
controlMeshRefinement(cellShapeControl& shapeController);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~controlMeshRefinement();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
// Check
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
void initialMeshPopulation
|
||||||
|
(
|
||||||
|
const autoPtr<backgroundMeshDecomposition>& decomposition
|
||||||
|
);
|
||||||
|
|
||||||
|
label refineMesh
|
||||||
|
(
|
||||||
|
const autoPtr<backgroundMeshDecomposition>& decomposition
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,488 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "smoothAlignmentSolver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template <class Triangulation, class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type> > Foam::smoothAlignmentSolver::filterFarPoints
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
const Field<Type>& field
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<Field<Type> > tNewField(new Field<Type>(field.size()));
|
||||||
|
Field<Type>& newField = tNewField();
|
||||||
|
|
||||||
|
label added = 0;
|
||||||
|
label count = 0;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename Triangulation::Finite_vertices_iterator vit =
|
||||||
|
mesh.finite_vertices_begin();
|
||||||
|
vit != mesh.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vit->real())
|
||||||
|
{
|
||||||
|
newField[added++] = field[count];
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
newField.resize(added);
|
||||||
|
|
||||||
|
return tNewField;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
Foam::autoPtr<Foam::mapDistribute> Foam::smoothAlignmentSolver::buildReferredMap
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
labelList& indices
|
||||||
|
)
|
||||||
|
{
|
||||||
|
globalIndex globalIndexing(mesh.vertexCount());
|
||||||
|
|
||||||
|
DynamicList<label> dynIndices(mesh.vertexCount()/10);
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename Triangulation::Finite_vertices_iterator vit =
|
||||||
|
mesh.finite_vertices_begin();
|
||||||
|
vit != mesh.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vit->referred())
|
||||||
|
{
|
||||||
|
dynIndices.append
|
||||||
|
(
|
||||||
|
globalIndexing.toGlobal(vit->procIndex(), vit->index())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indices.transfer(dynIndices);
|
||||||
|
|
||||||
|
List<Map<label> > compactMap;
|
||||||
|
return autoPtr<mapDistribute>
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndexing,
|
||||||
|
indices,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
Foam::autoPtr<Foam::mapDistribute> Foam::smoothAlignmentSolver::buildMap
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
labelListList& pointPoints
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pointPoints.setSize(mesh.vertexCount());
|
||||||
|
|
||||||
|
globalIndex globalIndexing(mesh.vertexCount());
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename Triangulation::Finite_vertices_iterator vit =
|
||||||
|
mesh.finite_vertices_begin();
|
||||||
|
vit != mesh.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!vit->real())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<typename Triangulation::Vertex_handle> adjVerts;
|
||||||
|
mesh.finite_adjacent_vertices(vit, std::back_inserter(adjVerts));
|
||||||
|
|
||||||
|
DynamicList<label> indices(adjVerts.size());
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename std::list<typename Triangulation::Vertex_handle>::
|
||||||
|
const_iterator adjVertI = adjVerts.begin();
|
||||||
|
adjVertI != adjVerts.end();
|
||||||
|
++adjVertI
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typename Triangulation::Vertex_handle vh = *adjVertI;
|
||||||
|
|
||||||
|
if (!vh->farPoint())
|
||||||
|
{
|
||||||
|
indices.append
|
||||||
|
(
|
||||||
|
globalIndexing.toGlobal(vh->procIndex(), vh->index())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pointPoints[vit->index()].transfer(indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<label> > compactMap;
|
||||||
|
return autoPtr<mapDistribute>
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
globalIndexing,
|
||||||
|
pointPoints,
|
||||||
|
compactMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
Foam::tmp<Foam::triadField> Foam::smoothAlignmentSolver::buildAlignmentField
|
||||||
|
(
|
||||||
|
const Triangulation& mesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<triadField> tAlignments
|
||||||
|
(
|
||||||
|
new triadField(mesh.vertexCount(), triad::unset)
|
||||||
|
);
|
||||||
|
triadField& alignments = tAlignments();
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename Triangulation::Finite_vertices_iterator vit =
|
||||||
|
mesh.finite_vertices_begin();
|
||||||
|
vit != mesh.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!vit->real())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
alignments[vit->index()] = vit->alignment();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tAlignments;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
Foam::tmp<Foam::pointField> Foam::smoothAlignmentSolver::buildPointField
|
||||||
|
(
|
||||||
|
const Triangulation& mesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<pointField> tPoints
|
||||||
|
(
|
||||||
|
new pointField(mesh.vertexCount(), point(GREAT, GREAT, GREAT))
|
||||||
|
);
|
||||||
|
pointField& points = tPoints();
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
typename Triangulation::Finite_vertices_iterator vit =
|
||||||
|
mesh.finite_vertices_begin();
|
||||||
|
vit != mesh.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!vit->real())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
points[vit->index()] = topoint(vit->point());
|
||||||
|
}
|
||||||
|
|
||||||
|
return tPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::smoothAlignmentSolver::smoothAlignmentSolver(cellShapeControlMesh& mesh)
|
||||||
|
:
|
||||||
|
mesh_(mesh)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::smoothAlignmentSolver::~smoothAlignmentSolver()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::smoothAlignmentSolver::smoothAlignments
|
||||||
|
(
|
||||||
|
const label maxSmoothingIterations
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar minResidual = 0;
|
||||||
|
|
||||||
|
labelListList pointPoints;
|
||||||
|
autoPtr<mapDistribute> meshDistributor = buildMap
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
pointPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
triadField alignments(buildAlignmentField(mesh_));
|
||||||
|
pointField points(buildPointField(mesh_));
|
||||||
|
// Setup the sizes and alignments on each point
|
||||||
|
triadField fixedAlignments(mesh_.vertexCount(), triad::unset);
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
CellSizeDelaunay::Finite_vertices_iterator vit =
|
||||||
|
mesh_.finite_vertices_begin();
|
||||||
|
vit != mesh_.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vit->real())
|
||||||
|
{
|
||||||
|
fixedAlignments[vit->index()] = vit->alignment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl << "Smoothing alignments" << endl;
|
||||||
|
|
||||||
|
for (label iter = 0; iter < maxSmoothingIterations; iter++)
|
||||||
|
{
|
||||||
|
Info<< "Iteration " << iter;
|
||||||
|
|
||||||
|
meshDistributor().distribute(points);
|
||||||
|
meshDistributor().distribute(alignments);
|
||||||
|
|
||||||
|
scalar residual = 0;
|
||||||
|
|
||||||
|
triadField triadAv(alignments.size(), triad::unset);
|
||||||
|
|
||||||
|
forAll(pointPoints, pI)
|
||||||
|
{
|
||||||
|
const labelList& pPoints = pointPoints[pI];
|
||||||
|
|
||||||
|
if (pPoints.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
triad& newTriad = triadAv[pI];
|
||||||
|
|
||||||
|
forAll(pPoints, adjPointI)
|
||||||
|
{
|
||||||
|
const label adjPointIndex = pPoints[adjPointI];
|
||||||
|
|
||||||
|
scalar dist = mag(points[pI] - points[adjPointIndex]);
|
||||||
|
|
||||||
|
triad tmpTriad = alignments[adjPointIndex];
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < 3; dir++)
|
||||||
|
{
|
||||||
|
if (tmpTriad.set(dir))
|
||||||
|
{
|
||||||
|
tmpTriad[dir] *= 1.0/(dist + SMALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newTriad += tmpTriad;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTriad.normalize();
|
||||||
|
newTriad.orthogonalize();
|
||||||
|
// newTriad = newTriad.sortxyz();
|
||||||
|
|
||||||
|
// Enforce the boundary conditions
|
||||||
|
const triad& fixedAlignment = fixedAlignments[pI];
|
||||||
|
|
||||||
|
label nFixed = 0;
|
||||||
|
|
||||||
|
forAll(fixedAlignment, dirI)
|
||||||
|
{
|
||||||
|
if (fixedAlignment.set(dirI))
|
||||||
|
{
|
||||||
|
nFixed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nFixed == 1)
|
||||||
|
{
|
||||||
|
forAll(fixedAlignment, dirI)
|
||||||
|
{
|
||||||
|
if (fixedAlignment.set(dirI))
|
||||||
|
{
|
||||||
|
newTriad.align(fixedAlignment[dirI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nFixed == 2)
|
||||||
|
{
|
||||||
|
forAll(fixedAlignment, dirI)
|
||||||
|
{
|
||||||
|
if (fixedAlignment.set(dirI))
|
||||||
|
{
|
||||||
|
newTriad[dirI] = fixedAlignment[dirI];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newTriad[dirI] = triad::unset[dirI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newTriad.orthogonalize();
|
||||||
|
}
|
||||||
|
else if (nFixed == 3)
|
||||||
|
{
|
||||||
|
forAll(fixedAlignment, dirI)
|
||||||
|
{
|
||||||
|
if (fixedAlignment.set(dirI))
|
||||||
|
{
|
||||||
|
newTriad[dirI] = fixedAlignment[dirI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const triad& oldTriad = alignments[pI];
|
||||||
|
|
||||||
|
for (direction dir = 0; dir < 3; ++dir)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
newTriad.set(dir)
|
||||||
|
&& oldTriad.set(dir)
|
||||||
|
&& !fixedAlignment.set(dir)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
residual += diff(oldTriad, newTriad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (iter == 198 || iter == 199)
|
||||||
|
// {
|
||||||
|
// Info<< "Triad" << nl
|
||||||
|
// << " Fixed (" << nFixed << ") = " << fixedAlignment
|
||||||
|
// << nl
|
||||||
|
// << " Old = " << oldTriad << nl
|
||||||
|
// << " Pre-Align= " << triadAv[pI] << nl
|
||||||
|
// << " New = " << newTriad << nl
|
||||||
|
// << " Residual = " << residual << endl;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(alignments, pI)
|
||||||
|
{
|
||||||
|
alignments[pI] = triadAv[pI].sortxyz();
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(residual, sumOp<scalar>());
|
||||||
|
|
||||||
|
Info<< ", Residual = "
|
||||||
|
<< residual
|
||||||
|
/returnReduce(points.size(), sumOp<label>())
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (iter > 0 && residual <= minResidual)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meshDistributor().distribute(alignments);
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
CellSizeDelaunay::Finite_vertices_iterator vit =
|
||||||
|
mesh_.finite_vertices_begin();
|
||||||
|
vit != mesh_.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vit->real())
|
||||||
|
{
|
||||||
|
vit->alignment() = alignments[vit->index()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList referredPoints;
|
||||||
|
autoPtr<mapDistribute> referredDistributor = buildReferredMap
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
referredPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
alignments.setSize(mesh_.vertexCount());
|
||||||
|
referredDistributor().distribute(alignments);
|
||||||
|
|
||||||
|
label referredI = 0;
|
||||||
|
for
|
||||||
|
(
|
||||||
|
CellSizeDelaunay::Finite_vertices_iterator vit =
|
||||||
|
mesh_.finite_vertices_begin();
|
||||||
|
vit != mesh_.finite_vertices_end();
|
||||||
|
++vit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (vit->referred())
|
||||||
|
{
|
||||||
|
vit->alignment() = alignments[referredPoints[referredI++]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,139 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
||||||
|
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::smoothAlignmentSolver
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
smoothAlignmentSolverI.H
|
||||||
|
smoothAlignmentSolver.C
|
||||||
|
smoothAlignmentSolverIO.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef smoothAlignmentSolver_H
|
||||||
|
#define smoothAlignmentSolver_H
|
||||||
|
|
||||||
|
#include "cellShapeControlMesh.H"
|
||||||
|
#include "triadField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class smoothAlignmentSolver Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class smoothAlignmentSolver
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
cellShapeControlMesh& mesh_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
template <class Triangulation, class Type>
|
||||||
|
tmp<Field<Type> > filterFarPoints
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
const Field<Type>& field
|
||||||
|
);
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
autoPtr<mapDistribute> buildMap
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
labelListList& pointPoints
|
||||||
|
);
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
autoPtr<mapDistribute> buildReferredMap
|
||||||
|
(
|
||||||
|
const Triangulation& mesh,
|
||||||
|
labelList& indices
|
||||||
|
);
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
tmp<triadField> buildAlignmentField(const Triangulation& mesh);
|
||||||
|
|
||||||
|
template <class Triangulation>
|
||||||
|
tmp<pointField> buildPointField(const Triangulation& mesh);
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
smoothAlignmentSolver(const smoothAlignmentSolver&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const smoothAlignmentSolver&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
smoothAlignmentSolver(cellShapeControlMesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~smoothAlignmentSolver();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
// Check
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
//- Smooth the alignments on the mesh
|
||||||
|
void smoothAlignments(const label maxSmoothingIterations);
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
// Friend Functions
|
||||||
|
|
||||||
|
// Friend Operators
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -31,15 +31,15 @@ License
|
|||||||
#include "vectorTools.H"
|
#include "vectorTools.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "indexedCellChecks.H"
|
#include "indexedCellChecks.H"
|
||||||
|
#include "controlMeshRefinement.H"
|
||||||
|
#include "smoothAlignmentSolver.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
defineTypeNameAndDebug(conformalVoronoiMesh, 0);
|
defineTypeNameAndDebug(conformalVoronoiMesh, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Foam::scalar Foam::conformalVoronoiMesh::tolParallel = 1e-3;
|
const Foam::scalar Foam::conformalVoronoiMesh::tolParallel = 1e-3;
|
||||||
@ -634,160 +634,6 @@ void Foam::conformalVoronoiMesh::insertInitialPoints()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::conformalVoronoiMesh::calculateLoadUnbalance() const
|
|
||||||
{
|
|
||||||
label nRealVertices = 0;
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
|
|
||||||
vit != finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Only store real vertices that are not feature vertices
|
|
||||||
if (vit->real() && !vit->featurePoint())
|
|
||||||
{
|
|
||||||
nRealVertices++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar globalNRealVertices = returnReduce
|
|
||||||
(
|
|
||||||
nRealVertices,
|
|
||||||
sumOp<label>()
|
|
||||||
);
|
|
||||||
|
|
||||||
scalar unbalance = returnReduce
|
|
||||||
(
|
|
||||||
mag(1.0 - nRealVertices/(globalNRealVertices/Pstream::nProcs())),
|
|
||||||
maxOp<scalar>()
|
|
||||||
);
|
|
||||||
|
|
||||||
Info<< " Processor unbalance " << unbalance << endl;
|
|
||||||
|
|
||||||
return unbalance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::conformalVoronoiMesh::distributeBackground()
|
|
||||||
{
|
|
||||||
if (!Pstream::parRun())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< nl << "Redistributing points" << endl;
|
|
||||||
|
|
||||||
timeCheck("Before distribute");
|
|
||||||
|
|
||||||
label iteration = 0;
|
|
||||||
|
|
||||||
scalar previousLoadUnbalance = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
scalar maxLoadUnbalance = calculateLoadUnbalance();
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
maxLoadUnbalance <= cvMeshControls().maxLoadUnbalance()
|
|
||||||
|| maxLoadUnbalance <= previousLoadUnbalance
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// If this is the first iteration, return false, if it was a
|
|
||||||
// subsequent one, return true;
|
|
||||||
return iteration != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
previousLoadUnbalance = maxLoadUnbalance;
|
|
||||||
|
|
||||||
Info<< " Total number of vertices before redistribution "
|
|
||||||
<< returnReduce(label(number_of_vertices()), sumOp<label>())
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
const fvMesh& bMesh = decomposition_().mesh();
|
|
||||||
|
|
||||||
volScalarField cellWeights
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"cellWeights",
|
|
||||||
bMesh.time().timeName(),
|
|
||||||
bMesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
bMesh,
|
|
||||||
dimensionedScalar("weight", dimless, 1e-2),
|
|
||||||
zeroGradientFvPatchScalarField::typeName
|
|
||||||
);
|
|
||||||
|
|
||||||
meshSearch cellSearch(bMesh, polyMesh::FACEPLANES);
|
|
||||||
|
|
||||||
labelList cellVertices(bMesh.nCells(), 0);
|
|
||||||
|
|
||||||
for
|
|
||||||
(
|
|
||||||
Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
|
|
||||||
vit != finite_vertices_end();
|
|
||||||
++vit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Only store real vertices that are not feature vertices
|
|
||||||
if (vit->real() && !vit->featurePoint())
|
|
||||||
{
|
|
||||||
pointFromPoint v = topoint(vit->point());
|
|
||||||
|
|
||||||
label cellI = cellSearch.findCell(v);
|
|
||||||
|
|
||||||
if (cellI == -1)
|
|
||||||
{
|
|
||||||
// Pout<< "findCell conformalVoronoiMesh::distribute "
|
|
||||||
// << "findCell "
|
|
||||||
// << vit->type() << " "
|
|
||||||
// << vit->index() << " "
|
|
||||||
// << v << " "
|
|
||||||
// << cellI
|
|
||||||
// << " find nearest cellI ";
|
|
||||||
|
|
||||||
cellI = cellSearch.findNearestCell(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
cellVertices[cellI]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cellVertices, cI)
|
|
||||||
{
|
|
||||||
// Give a small but finite weight for empty cells. Some
|
|
||||||
// decomposition methods have difficulty with integer overflows in
|
|
||||||
// the sum of the normalised weight field.
|
|
||||||
cellWeights.internalField()[cI] = max
|
|
||||||
(
|
|
||||||
cellVertices[cI],
|
|
||||||
1e-2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
autoPtr<mapDistributePolyMesh> mapDist = decomposition_().distribute
|
|
||||||
(
|
|
||||||
cellWeights
|
|
||||||
);
|
|
||||||
|
|
||||||
cellShapeControl_.shapeControlMesh().distribute(decomposition_);
|
|
||||||
|
|
||||||
distribute();
|
|
||||||
|
|
||||||
timeCheck("After distribute");
|
|
||||||
|
|
||||||
iteration++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::conformalVoronoiMesh::distribute()
|
void Foam::conformalVoronoiMesh::distribute()
|
||||||
{
|
{
|
||||||
if (!Pstream::parRun())
|
if (!Pstream::parRun())
|
||||||
@ -871,13 +717,24 @@ void Foam::conformalVoronoiMesh::distribute()
|
|||||||
|
|
||||||
void Foam::conformalVoronoiMesh::buildCellSizeAndAlignmentMesh()
|
void Foam::conformalVoronoiMesh::buildCellSizeAndAlignmentMesh()
|
||||||
{
|
{
|
||||||
cellShapeControl_.initialMeshPopulation(decomposition_);
|
controlMeshRefinement meshRefinement
|
||||||
|
(
|
||||||
|
cellShapeControl_
|
||||||
|
);
|
||||||
|
|
||||||
|
smoothAlignmentSolver meshAlignmentSmoother
|
||||||
|
(
|
||||||
|
cellShapeControl_.shapeControlMesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
meshRefinement.initialMeshPopulation(decomposition_);
|
||||||
|
|
||||||
cellShapeControlMesh& cellSizeMesh = cellShapeControl_.shapeControlMesh();
|
cellShapeControlMesh& cellSizeMesh = cellShapeControl_.shapeControlMesh();
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
cellSizeMesh.distribute(decomposition_);
|
distributeBackground(cellSizeMesh);
|
||||||
|
// cellSizeMesh.distribute(decomposition_);
|
||||||
}
|
}
|
||||||
|
|
||||||
label nMaxIter = readLabel
|
label nMaxIter = readLabel
|
||||||
@ -892,40 +749,48 @@ void Foam::conformalVoronoiMesh::buildCellSizeAndAlignmentMesh()
|
|||||||
|
|
||||||
for (label i = 0; i < nMaxIter; ++i)
|
for (label i = 0; i < nMaxIter; ++i)
|
||||||
{
|
{
|
||||||
// label nRemoved = cellSizeMesh.removePoints();
|
label nAdded = meshRefinement.refineMesh(decomposition_);
|
||||||
label nRemoved = 0;
|
//cellShapeControl_.refineMesh(decomposition_);
|
||||||
reduce(nRemoved, sumOp<label>());
|
|
||||||
|
|
||||||
label nAdded = cellShapeControl_.refineMesh(decomposition_);
|
|
||||||
// label nAdded = 0;
|
|
||||||
reduce(nAdded, sumOp<label>());
|
reduce(nAdded, sumOp<label>());
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
cellSizeMesh.distribute(decomposition_);
|
distributeBackground(cellSizeMesh);
|
||||||
}
|
|
||||||
|
|
||||||
if (nRemoved + nAdded == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< " Iteration " << i
|
Info<< " Iteration " << i
|
||||||
<< " Added = " << nAdded << " points"
|
<< " Added = " << nAdded << " points"
|
||||||
<< ", Removed = " << nRemoved << " points"
|
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
if (nAdded == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cellShapeControl_.smoothMesh();
|
label maxSmoothingIterations = readLabel
|
||||||
|
(
|
||||||
|
cvMeshControls().cvMeshDict().subDict("motionControl").lookup
|
||||||
|
(
|
||||||
|
"maxSmoothingIterations"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
meshAlignmentSmoother.smoothAlignments(maxSmoothingIterations);
|
||||||
|
|
||||||
Info<< "Background cell size and alignment mesh:" << endl;
|
Info<< "Background cell size and alignment mesh:" << endl;
|
||||||
cellSizeMesh.printInfo(Info);
|
cellSizeMesh.printInfo(Info);
|
||||||
|
|
||||||
if (cvMeshControls().objOutput())
|
Info<< "Triangulation is "
|
||||||
|
<< (cellSizeMesh.is_valid() ? "valid" : "not valid!" )
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (!Pstream::parRun())
|
||||||
{
|
{
|
||||||
cellSizeMesh.writeTriangulation();
|
//cellSizeMesh.writeTriangulation();
|
||||||
cellSizeMesh.write();
|
cellSizeMesh.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cellSizeMesh.printVertexInfo(Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1102,11 +967,6 @@ void Foam::conformalVoronoiMesh::setVertexSizeAndAlignment()
|
|||||||
vit->targetCellSize(),
|
vit->targetCellSize(),
|
||||||
vit->alignment()
|
vit->alignment()
|
||||||
);
|
);
|
||||||
|
|
||||||
//vit->alignment() = tensor(1,0,0,0,1,0,0,0,1);
|
|
||||||
//vit->alignment() = requiredAlignment(pt);
|
|
||||||
|
|
||||||
//vit->targetCellSize() = cellShapeControls().cellSize(pt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1424,13 +1284,13 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh
|
|||||||
// Improve the guess that the backgroundMeshDecomposition makes with the
|
// Improve the guess that the backgroundMeshDecomposition makes with the
|
||||||
// initial positions. Use before building the surface conformation to
|
// initial positions. Use before building the surface conformation to
|
||||||
// better balance the surface conformation load.
|
// better balance the surface conformation load.
|
||||||
distributeBackground();
|
distributeBackground(*this);
|
||||||
|
|
||||||
buildSurfaceConformation();
|
buildSurfaceConformation();
|
||||||
|
|
||||||
// The introduction of the surface conformation may have distorted the
|
// The introduction of the surface conformation may have distorted the
|
||||||
// balance of vertices, distribute if necessary.
|
// balance of vertices, distribute if necessary.
|
||||||
distributeBackground();
|
distributeBackground(*this);
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
@ -1701,22 +1561,22 @@ void Foam::conformalVoronoiMesh::move()
|
|||||||
delta
|
delta
|
||||||
);
|
);
|
||||||
|
|
||||||
if (targetFaceArea == 0)
|
// if (targetFaceArea == 0)
|
||||||
{
|
// {
|
||||||
Pout<< vA->info() << vB->info();
|
// Pout<< vA->info() << vB->info();
|
||||||
|
//
|
||||||
Cell_handle ch = locate(vA->point());
|
// Cell_handle ch = locate(vA->point());
|
||||||
if (is_infinite(ch))
|
// if (is_infinite(ch))
|
||||||
{
|
// {
|
||||||
Pout<< "vA " << vA->targetCellSize() << endl;
|
// Pout<< "vA " << vA->targetCellSize() << endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
ch = locate(vB->point());
|
// ch = locate(vB->point());
|
||||||
if (is_infinite(ch))
|
// if (is_infinite(ch))
|
||||||
{
|
// {
|
||||||
Pout<< "vB " << vB->targetCellSize() << endl;
|
// Pout<< "vB " << vB->targetCellSize() << endl;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
delta *= faceAreaWeightModel_->faceAreaWeight
|
delta *= faceAreaWeightModel_->faceAreaWeight
|
||||||
(
|
(
|
||||||
|
|||||||
@ -34,6 +34,7 @@ SourceFiles
|
|||||||
conformalVoronoiMeshFeaturePoints.C
|
conformalVoronoiMeshFeaturePoints.C
|
||||||
conformalVoronoiMeshFeaturePointSpecialisations.C
|
conformalVoronoiMeshFeaturePointSpecialisations.C
|
||||||
conformalVoronoiMeshCalcDualMesh.C
|
conformalVoronoiMeshCalcDualMesh.C
|
||||||
|
conformalVoronoiMeshTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ void Foam::conformalVoronoiMesh::conformToSurface()
|
|||||||
// Rebuild, insert and store new surface conformation
|
// Rebuild, insert and store new surface conformation
|
||||||
buildSurfaceConformation();
|
buildSurfaceConformation();
|
||||||
|
|
||||||
if (distributeBackground())
|
if (distributeBackground(*this))
|
||||||
{
|
{
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -613,17 +613,9 @@ void Foam::conformalVoronoiMesh::insertFeaturePoints()
|
|||||||
}
|
}
|
||||||
|
|
||||||
label nFeatureVertices = number_of_vertices() - preFeaturePointSize;
|
label nFeatureVertices = number_of_vertices() - preFeaturePointSize;
|
||||||
|
reduce(nFeatureVertices, sumOp<label>());
|
||||||
|
|
||||||
if (Pstream::parRun())
|
Info<< " Inserted " << nFeatureVertices << " feature vertices" << endl;
|
||||||
{
|
|
||||||
reduce(nFeatureVertices, sumOp<label>());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nFeatureVertices > 0)
|
|
||||||
{
|
|
||||||
Info<< " Inserted " << nFeatureVertices
|
|
||||||
<< " feature vertices" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
featureVertices_.clear();
|
featureVertices_.clear();
|
||||||
featureVertices_.setSize(pts.size());
|
featureVertices_.setSize(pts.size());
|
||||||
|
|||||||
@ -92,6 +92,7 @@ surface2.nas
|
|||||||
|
|
||||||
// Output the proximity of feature points and edges to each other
|
// Output the proximity of feature points and edges to each other
|
||||||
featureProximity no;
|
featureProximity no;
|
||||||
|
|
||||||
// The maximum search distance to use when looking for other feature
|
// The maximum search distance to use when looking for other feature
|
||||||
// points and edges
|
// points and edges
|
||||||
maxFeatureProximity 1;
|
maxFeatureProximity 1;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# ========= |
|
# ========= |
|
||||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
# \\ / O peration |
|
# \\ / O peration |
|
||||||
# \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
# \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
# \\/ M anipulation |
|
# \\/ M anipulation |
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# License
|
# License
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
|
|||||||
@ -75,8 +75,6 @@ const triad triad::unset
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user