mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Creating a buildDualFace function, using everywhere a dual face is
required. Separating dual face creation into two loops - first one to loop over the dual faces and collapse the points of those that are to be removed, second one to create the faces that remain.
This commit is contained in:
@ -1766,7 +1766,8 @@ void Foam::conformalVoronoiMesh::calcDualMesh
|
|||||||
|
|
||||||
timeCheck();
|
timeCheck();
|
||||||
|
|
||||||
// Indexing cells, which are Dual vertices
|
// Indexing Delaunay cells, which are Dual vertices
|
||||||
|
|
||||||
label dualVertI = 0;
|
label dualVertI = 0;
|
||||||
|
|
||||||
points.setSize(number_of_cells());
|
points.setSize(number_of_cells());
|
||||||
@ -2042,6 +2043,38 @@ void Foam::conformalVoronoiMesh::calcDualMesh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~ dual face filtering ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Loop over all dual faces and merge points to remove faces that
|
||||||
|
// are not wanted.
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
Triangulation::Finite_edges_iterator eit = finite_edges_begin();
|
||||||
|
eit != finite_edges_end();
|
||||||
|
++eit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Cell_handle c = eit->first;
|
||||||
|
Vertex_handle vA = c->vertex(eit->second);
|
||||||
|
Vertex_handle vB = c->vertex(eit->third);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
vA->internalOrBoundaryPoint()
|
||||||
|
|| vB->internalOrBoundaryPoint()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
face newDualFace = buildDualFace(eit);
|
||||||
|
|
||||||
|
bool keepFace = assessFace(newDualFace, vA, vB, points);
|
||||||
|
|
||||||
|
if (!keepFace)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~ dual face and owner neighbour construction ~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~ dual face and owner neighbour construction ~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
patchNames = geometryToConformTo_.patchNames();
|
patchNames = geometryToConformTo_.patchNames();
|
||||||
@ -2081,55 +2114,9 @@ void Foam::conformalVoronoiMesh::calcDualMesh
|
|||||||
|| vB->internalOrBoundaryPoint()
|
|| vB->internalOrBoundaryPoint()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Cell_circulator ccStart = incident_cells(*eit);
|
face newDualFace = buildDualFace(eit);
|
||||||
Cell_circulator cc1 = ccStart;
|
|
||||||
Cell_circulator cc2 = cc1;
|
|
||||||
|
|
||||||
// Advance the second circulator so that it always stays on the next
|
if (newDualFace.size() >= 3)
|
||||||
// cell around the edge;
|
|
||||||
cc2++;
|
|
||||||
|
|
||||||
DynamicList<label> verticesOnFace;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
label cc1I = cc1->cellIndex();
|
|
||||||
|
|
||||||
label cc2I = cc2->cellIndex();
|
|
||||||
|
|
||||||
|
|
||||||
if (cc1I < 0 || cc2I < 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn("Foam::conformalVoronoiMesh::calcDualMesh")
|
|
||||||
<< "Dual face uses circumcenter defined by a "
|
|
||||||
<< "Delaunay tetrahedron with no internal "
|
|
||||||
<< "or boundary points. Defining Delaunay edge ends: "
|
|
||||||
<< topoint(vA->point()) << " "
|
|
||||||
<< topoint(vB->point()) << nl
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cc1I != cc2I)
|
|
||||||
{
|
|
||||||
verticesOnFace.append(cc1I);
|
|
||||||
}
|
|
||||||
|
|
||||||
cc1++;
|
|
||||||
|
|
||||||
cc2++;
|
|
||||||
|
|
||||||
} while (cc1 != ccStart);
|
|
||||||
|
|
||||||
face newDualFace(verticesOnFace);
|
|
||||||
|
|
||||||
bool keepFace = assessFace
|
|
||||||
(
|
|
||||||
newDualFace,
|
|
||||||
averageAnyCellSize(vA, vB),
|
|
||||||
points
|
|
||||||
);
|
|
||||||
|
|
||||||
if (verticesOnFace.size() >= 3 && keepFace)
|
|
||||||
{
|
{
|
||||||
label dcA = vA->index();
|
label dcA = vA->index();
|
||||||
|
|
||||||
@ -2450,16 +2437,85 @@ void Foam::conformalVoronoiMesh::calcTetMesh
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::face Foam::conformalVoronoiMesh::buildDualFace
|
||||||
|
(
|
||||||
|
const Triangulation::Finite_edges_iterator& eit
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
Cell_circulator ccStart = incident_cells(*eit);
|
||||||
|
Cell_circulator cc1 = ccStart;
|
||||||
|
Cell_circulator cc2 = cc1;
|
||||||
|
|
||||||
|
// Advance the second circulator so that it always stays on the next
|
||||||
|
// cell around the edge;
|
||||||
|
cc2++;
|
||||||
|
|
||||||
|
DynamicList<label> verticesOnFace;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
label cc1I = cc1->cellIndex();
|
||||||
|
|
||||||
|
label cc2I = cc2->cellIndex();
|
||||||
|
|
||||||
|
if (cc1I < 0 || cc2I < 0)
|
||||||
|
{
|
||||||
|
Cell_handle c = eit->first;
|
||||||
|
Vertex_handle vA = c->vertex(eit->second);
|
||||||
|
Vertex_handle vB = c->vertex(eit->third);
|
||||||
|
|
||||||
|
FatalErrorIn("Foam::conformalVoronoiMesh::buildDualFace")
|
||||||
|
<< "Dual face uses circumcenter defined by a "
|
||||||
|
<< "Delaunay tetrahedron with no internal "
|
||||||
|
<< "or boundary points. Defining Delaunay edge ends: "
|
||||||
|
<< topoint(vA->point()) << " "
|
||||||
|
<< topoint(vB->point()) << nl
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cc1I != cc2I)
|
||||||
|
{
|
||||||
|
verticesOnFace.append(cc1I);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc1++;
|
||||||
|
|
||||||
|
cc2++;
|
||||||
|
|
||||||
|
} while (cc1 != ccStart);
|
||||||
|
|
||||||
|
return face(verticesOnFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::conformalVoronoiMesh::assessFace
|
bool Foam::conformalVoronoiMesh::assessFace
|
||||||
(
|
(
|
||||||
const face& f,
|
const face& f,
|
||||||
scalar averageCellSize,
|
const Vertex_handle& vA,
|
||||||
|
const Vertex_handle& vB,
|
||||||
const pointField& pts
|
const pointField& pts
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
scalar smallFaceAreaCoeff = 0.1;
|
if (f.size() < 3)
|
||||||
scalar highAspectRatioFaceAreaCoeff = 0.2;
|
{
|
||||||
scalar aspectRatioLimit = 1.2;
|
// Invalid face, fewer than three points
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (f.size() == 3)
|
||||||
|
{
|
||||||
|
// Triangle face, handle specially
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Polygonal face
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar averageCellSize = averageAnyCellSize(vA, vB);
|
||||||
|
|
||||||
|
scalar smallFaceAreaCoeff = 0.01;
|
||||||
|
scalar highAspectRatioFaceAreaCoeff = 0.1;
|
||||||
|
scalar aspectRatioLimit = 2.0;
|
||||||
scalar targetArea = sqr(averageCellSize);
|
scalar targetArea = sqr(averageCellSize);
|
||||||
|
|
||||||
const edgeList& eds = f.edges();
|
const edgeList& eds = f.edges();
|
||||||
@ -2777,31 +2833,7 @@ void Foam::conformalVoronoiMesh::move()
|
|||||||
&& eit->first->vertex(eit->third)->internalOrBoundaryPoint()
|
&& eit->first->vertex(eit->third)->internalOrBoundaryPoint()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Cell_circulator ccStart = incident_cells(*eit);
|
face dualFace = buildDualFace(eit);
|
||||||
Cell_circulator cc = ccStart;
|
|
||||||
|
|
||||||
DynamicList<label> verticesOnFace;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!is_infinite(cc))
|
|
||||||
{
|
|
||||||
if (cc->cellIndex() < 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn("conformalVoronoiMesh::move")
|
|
||||||
<< "Dual face uses circumcenter defined by a "
|
|
||||||
<< " Delaunay tetrahedron with no internal "
|
|
||||||
<< "or boundary points."
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
verticesOnFace.append(cc->cellIndex());
|
|
||||||
}
|
|
||||||
} while (++cc != ccStart);
|
|
||||||
|
|
||||||
verticesOnFace.shrink();
|
|
||||||
|
|
||||||
face dualFace(verticesOnFace);
|
|
||||||
|
|
||||||
Cell_handle c = eit->first;
|
Cell_handle c = eit->first;
|
||||||
Vertex_handle vA = c->vertex(eit->second);
|
Vertex_handle vA = c->vertex(eit->second);
|
||||||
|
|||||||
@ -443,14 +443,31 @@ private:
|
|||||||
labelList& patchStarts
|
labelList& patchStarts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Builds a dual face by circulating around the supplied edge
|
||||||
|
face buildDualFace
|
||||||
|
(
|
||||||
|
const Triangulation::Finite_edges_iterator& eit
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Assess face to see if it is a candidate for removal
|
//- Assess face to see if it is a candidate for removal
|
||||||
bool assessFace
|
bool assessFace
|
||||||
(
|
(
|
||||||
const face& f,
|
const face& f,
|
||||||
scalar averageCellSize,
|
const Vertex_handle& vA,
|
||||||
|
const Vertex_handle& vB,
|
||||||
const pointField& pts
|
const pointField& pts
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Collapse a face to a point or an edge, modifying and
|
||||||
|
// mapping the points
|
||||||
|
// void collapseFace
|
||||||
|
// (
|
||||||
|
// const face& f,
|
||||||
|
// const Vertex_handle& vA,
|
||||||
|
// const Vertex_handle& vB
|
||||||
|
// pointField& pts,
|
||||||
|
// ) const;
|
||||||
|
|
||||||
//- Sort the faces, owner and neighbour lists into
|
//- Sort the faces, owner and neighbour lists into
|
||||||
// upper-triangular order. For internal faces only, use
|
// upper-triangular order. For internal faces only, use
|
||||||
// before adding patch faces.
|
// before adding patch faces.
|
||||||
|
|||||||
Reference in New Issue
Block a user