ENH: mergePoints and patch gatherAndMerge improvements (#2402)

- when writing surface formats (eg, vtk, ensight etc) the sampled
  surfaces merge the faces/points originating from different
  processors into a single surface (ie, patch gatherAndMerge).

  Previous versions of mergePoints simply merged all points possible,
  which proves to be rather slow for larger meshes. This has now been
  modified to only consider boundary points, which reduces the number
  of points to consider. As part of this change, the reference point
  is now always equivalent to the min of the bounding box, which
  reduces the number of search loops. The merged points retain their
  original order.

- inplaceMergePoints version to simplify use and improve code
  robustness and efficiency.

ENH: make PrimitivePatch::boundaryPoints() less costly

- if edge addressing does not already exist, it will now simply walk
  the local face edges directly to define the boundary points.

  This avoids a rather large overhead of the full faceFaces,
  edgeFaces, faceEdges addressing.

  This operation is now more important since it is used in the revised
  patch gatherAndMerge.

ENH: topological merge for mesh-based surfaces in surfaceFieldValue
This commit is contained in:
Mark Olesen
2022-03-15 21:38:49 +01:00
parent bf46b589cf
commit 24c0b30d48
26 changed files with 833 additions and 296 deletions

View File

@ -862,25 +862,22 @@ void Foam::meshToMesh::distributeAndMergeCells
// only merging points in debug mode
labelList oldToNew;
pointField newTgtPoints;
bool hasMerged = mergePoints
label nChanged = Foam::inplaceMergePoints
(
tgtPoints,
SMALL,
false,
oldToNew,
newTgtPoints
oldToNew
);
if (hasMerged)
if (nChanged)
{
Pout<< "Merged from " << tgtPoints.size()
<< " down to " << newTgtPoints.size() << " points" << endl;
Pout<< "Merged from " << oldToNew.size()
<< " down to " << tgtPoints.size() << " points" << endl;
tgtPoints.transfer(newTgtPoints);
forAll(tgtFaces, i)
for (auto& f : tgtFaces)
{
inplaceRenumber(oldToNew, tgtFaces[i]);
inplaceRenumber(oldToNew, f);
}
}
}

View File

@ -131,13 +131,12 @@ void Foam::patchEdgeSet::genSamples()
labelList pointMap;
const label nMerged = mergePoints
const label nMerged = Foam::mergePoints
(
samplingPts,
SMALL, //const scalar mergeTol,
false, //const bool verbose,
pointMap,
origin_
SMALL, // mergeTol
false, // verbose = false
pointMap
);
if (nMerged == samplingPts.size())

View File

@ -767,7 +767,7 @@ Foam::triSurface Foam::isoSurfaceCell::stitchTriPoints
}
pointField newPoints;
mergePoints
Foam::mergePoints
(
triPoints,
mergeDistance_,
@ -779,27 +779,25 @@ Foam::triSurface Foam::isoSurfaceCell::stitchTriPoints
// Check that enough merged.
if (debug)
{
Pout<< "isoSurfaceCell : merged from " << triPoints.size()
Pout<< "isoSurfaceCell : merged from " << triPointReverseMap.size()
<< " points down to " << newPoints.size() << endl;
pointField newNewPoints;
labelList oldToNew;
bool hasMerged = mergePoints
const label nUnique = Foam::mergePoints
(
newPoints,
mergeDistance_,
true,
oldToNew,
newNewPoints
oldToNew
);
if (hasMerged)
if (nUnique != newPoints.size())
{
FatalErrorInFunction
<< "Merged points contain duplicates"
<< " when merging with distance " << mergeDistance_ << endl
<< "merged:" << newPoints.size() << " re-merged:"
<< newNewPoints.size()
<< nUnique
<< abort(FatalError);
}
}
@ -852,30 +850,28 @@ Foam::triSurface Foam::isoSurfaceCell::stitchTriPoints
centres[triI] = tris[triI].centre(newPoints);
}
pointField mergedCentres;
labelList oldToMerged;
bool hasMerged = mergePoints
label nUnique = Foam::mergePoints
(
centres,
mergeDistance_,
false,
oldToMerged,
mergedCentres
oldToMerged
);
if (debug)
{
Pout<< "isoSurfaceCell : detected "
<< centres.size()-mergedCentres.size()
<< (oldToMerged.size() - nUnique)
<< " duplicate triangles." << endl;
}
if (hasMerged)
if (oldToMerged.size() != nUnique)
{
// Filter out duplicates.
label newTriI = 0;
DynamicList<label> newToOldTri(tris.size());
labelList newToMaster(mergedCentres.size(), -1);
labelList newToMaster(nUnique, -1);
forAll(tris, triI)
{
label mergedI = oldToMerged[triI];
@ -918,26 +914,25 @@ void Foam::isoSurfaceCell::calcAddressing
edgeCentres[edgeI++] = 0.5*(points[tri[2]]+points[tri[0]]);
}
pointField mergedCentres;
labelList oldToMerged;
bool hasMerged = mergePoints
const label nUnique = Foam::mergePoints
(
edgeCentres,
mergeDistance_,
false,
oldToMerged,
mergedCentres
oldToMerged
);
if (debug)
{
Pout<< "isoSurfaceCell : detected "
<< mergedCentres.size()
<< nUnique
<< " edges on " << surf.size() << " triangles." << endl;
}
if (!hasMerged)
if (nUnique == edgeCentres.size())
{
// Nothing to do
return;
}
@ -954,9 +949,9 @@ void Foam::isoSurfaceCell::calcAddressing
// Determine edgeFaces
edgeFace0.setSize(mergedCentres.size());
edgeFace0.resize(nUnique);
edgeFace0 = -1;
edgeFace1.setSize(mergedCentres.size());
edgeFace1.resize(nUnique);
edgeFace1 = -1;
edgeFacesRest.clear();
@ -976,7 +971,7 @@ void Foam::isoSurfaceCell::calcAddressing
else
{
//WarningInFunction
// << "Edge " << edgeI << " with centre " << mergedCentres[edgeI]
// << "Edge " << edgeI << " with centre "
// << " used by more than two triangles: " << edgeFace0[edgeI]
// << ", "
// << edgeFace1[edgeI] << " and " << triI << endl;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -906,7 +906,7 @@ Foam::triSurface Foam::isoSurfacePoint::stitchTriPoints
// Check that enough merged.
if (debug)
{
Pout<< "isoSurfacePoint : merged from " << triPoints.size()
Pout<< "isoSurfacePoint : merged from " << triPointReverseMap.size()
<< " down to " << newPoints.size() << " unique points." << endl;
pointField newNewPoints;
@ -925,7 +925,7 @@ Foam::triSurface Foam::isoSurfacePoint::stitchTriPoints
FatalErrorInFunction
<< "Merged points contain duplicates"
<< " when merging with distance " << mergeDistance_ << endl
<< "merged:" << newPoints.size() << " re-merged:"
<< "merged:" << oldToNew.size() << " re-merged:"
<< newNewPoints.size()
<< abort(FatalError);
}