mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: globalIndex gather for PatchTools::gatherAndMerge (#2402)
- lower memory overhead, simpler code and eliminates need for ListListOps::combineOffset() - optional handling of local faces/points for re-using in different contexts STYLE: labelUList instead of labelList for globalMesh mergePoints STYLE: adjust verbose information from mergePoints - also report the current new-point location
This commit is contained in:
@ -89,12 +89,12 @@ Foam::label Foam::mergePoints
|
||||
|
||||
|
||||
Field<scalar> sortedTol(nPoints);
|
||||
forAll(order, sortI)
|
||||
forAll(order, sorti)
|
||||
{
|
||||
const point_type& pt = points[order[sortI]];
|
||||
const point_type& pt = points[order[sorti]];
|
||||
|
||||
// Use scalar precision
|
||||
sortedTol[sortI] =
|
||||
sortedTol[sorti] =
|
||||
2*mergeTol*
|
||||
(
|
||||
mag(scalar(pt.x() - compareOrigin.x()))
|
||||
@ -109,11 +109,16 @@ Foam::label Foam::mergePoints
|
||||
label pointi = order[0];
|
||||
pointMap[pointi] = newPointi++;
|
||||
|
||||
for (label sortI = 1; sortI < order.size(); ++sortI)
|
||||
/// if (verbose)
|
||||
/// {
|
||||
/// Pout<< "Foam::mergePoints : [0] Uniq point " << pointi << endl;
|
||||
/// }
|
||||
|
||||
for (label sorti = 1; sorti < order.size(); ++sorti)
|
||||
{
|
||||
// Get original point index
|
||||
const label pointi = order[sortI];
|
||||
const scalar mag2 = magSqrDist[order[sortI]];
|
||||
const label pointi = order[sorti];
|
||||
const scalar mag2 = magSqrDist[order[sorti]];
|
||||
|
||||
// Convert to scalar precision
|
||||
// NOTE: not yet using point_type template parameter
|
||||
@ -130,13 +135,13 @@ Foam::label Foam::mergePoints
|
||||
|
||||
for
|
||||
(
|
||||
label prevSortI = sortI - 1;
|
||||
prevSortI >= 0
|
||||
&& (mag(magSqrDist[order[prevSortI]] - mag2) <= sortedTol[sortI]);
|
||||
--prevSortI
|
||||
label prevSorti = sorti - 1;
|
||||
prevSorti >= 0
|
||||
&& (mag(magSqrDist[order[prevSorti]] - mag2) <= sortedTol[sorti]);
|
||||
--prevSorti
|
||||
)
|
||||
{
|
||||
const label prevPointi = order[prevSortI];
|
||||
const label prevPointi = order[prevSorti];
|
||||
|
||||
// Convert to scalar precision
|
||||
// NOTE: not yet using point_type template parameter
|
||||
@ -164,16 +169,22 @@ Foam::label Foam::mergePoints
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
Pout<< "Foam::mergePoints : Merging points "
|
||||
<< pointi << " and " << equalPointi
|
||||
<< " with coordinates:" << points[pointi]
|
||||
<< " and " << points[equalPointi]
|
||||
<< endl;
|
||||
Pout<< "Foam::mergePoints : [" << pointMap[pointi]
|
||||
<< "] Point " << pointi << " duplicate of " << equalPointi
|
||||
<< " : coordinates:" << points[pointi]
|
||||
<< " and " << points[equalPointi] << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Differs. Store new point.
|
||||
|
||||
/// if (verbose)
|
||||
/// {
|
||||
/// Pout<< "Foam::mergePoints : [" << newPointi
|
||||
/// << "] Uniq point " << pointi << endl;
|
||||
/// }
|
||||
|
||||
pointMap[pointi] = newPointi++;
|
||||
}
|
||||
}
|
||||
@ -200,7 +211,7 @@ bool Foam::mergePoints
|
||||
typename PointList::const_reference origin
|
||||
)
|
||||
{
|
||||
const label nUnique = mergePoints
|
||||
const label nUnique = Foam::mergePoints
|
||||
(
|
||||
points,
|
||||
mergeTol,
|
||||
@ -209,7 +220,7 @@ bool Foam::mergePoints
|
||||
origin
|
||||
);
|
||||
|
||||
newPoints.setSize(nUnique);
|
||||
newPoints.resize_nocopy(nUnique);
|
||||
forAll(pointMap, pointi)
|
||||
{
|
||||
newPoints[pointMap[pointi]] = points[pointi];
|
||||
|
||||
@ -138,7 +138,7 @@ void Foam::globalMeshData::calcSharedPoints() const
|
||||
|
||||
// Calculate all shared points (exclude points that are only
|
||||
// on two coupled patches). This does all the hard work.
|
||||
globalPoints parallelPoints(mesh_, false, true);
|
||||
const globalPoints parallelPoints(mesh_, false, true);
|
||||
|
||||
// Count the number of master points
|
||||
label nMaster = 0;
|
||||
@ -155,7 +155,7 @@ void Foam::globalMeshData::calcSharedPoints() const
|
||||
}
|
||||
|
||||
// Allocate global numbers
|
||||
globalIndex masterNumbering(nMaster);
|
||||
const globalIndex masterNumbering(nMaster);
|
||||
|
||||
nGlobalPoints_ = masterNumbering.totalSize();
|
||||
|
||||
@ -2472,7 +2472,7 @@ Foam::autoPtr<Foam::globalIndex> Foam::globalMeshData::mergePoints
|
||||
|
||||
Foam::autoPtr<Foam::globalIndex> Foam::globalMeshData::mergePoints
|
||||
(
|
||||
const labelList& meshPoints,
|
||||
const labelUList& meshPoints,
|
||||
const Map<label>& /* unused: meshPointMap */,
|
||||
labelList& pointToGlobal,
|
||||
labelList& uniqueMeshPoints
|
||||
@ -2498,7 +2498,7 @@ Foam::autoPtr<Foam::globalIndex> Foam::globalMeshData::mergePoints
|
||||
// - from coupled point to global patch point
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
globalIndex globalPPoints(meshPoints.size());
|
||||
const globalIndex globalPPoints(meshPoints.size());
|
||||
|
||||
labelList patchToCoupled(meshPoints.size(), -1);
|
||||
label nCoupled = 0;
|
||||
|
||||
@ -576,7 +576,7 @@ public:
|
||||
// - the global number for all local points.
|
||||
autoPtr<globalIndex> mergePoints
|
||||
(
|
||||
const labelList& meshPoints,
|
||||
const labelUList& meshPoints,
|
||||
const Map<label>& meshPointMap, //!< currently unused
|
||||
labelList& pointToGlobal,
|
||||
labelList& uniqueMeshPoints
|
||||
|
||||
@ -218,12 +218,20 @@ public:
|
||||
|
||||
|
||||
//- Gather points and faces onto master and merge into single patch.
|
||||
// Note: uses faces/points, not localFaces/localPoints.
|
||||
// Note: Normally uses faces/points (not localFaces/localPoints)
|
||||
//
|
||||
// \param[in] mergeDist Geometric merge tolerance for Foam::mergePoints
|
||||
// \param[in] pp The patch to merge
|
||||
// \param[out] mergedPoints
|
||||
// \param[out] mergedFaces
|
||||
// \param[out] pointMergeMap
|
||||
// \param[in] useLocal gather/merge the localFaces/localPoints
|
||||
// instead of (global) faces/points
|
||||
template<class FaceList, class PointField>
|
||||
static void gatherAndMerge
|
||||
(
|
||||
const scalar mergeDist,
|
||||
const PrimitivePatch<FaceList, PointField>& p,
|
||||
const PrimitivePatch<FaceList, PointField>& pp,
|
||||
Field
|
||||
<
|
||||
typename PrimitivePatch<FaceList, PointField>::point_type
|
||||
@ -232,7 +240,8 @@ public:
|
||||
<
|
||||
typename PrimitivePatch<FaceList, PointField>::face_type
|
||||
>& mergedFaces,
|
||||
labelList& pointMergeMap
|
||||
labelList& pointMergeMap,
|
||||
const bool useLocal = false
|
||||
);
|
||||
|
||||
//- Gather (mesh!) points and faces onto master and merge collocated
|
||||
|
||||
@ -37,7 +37,7 @@ template<class FaceList, class PointField>
|
||||
void Foam::PatchTools::gatherAndMerge
|
||||
(
|
||||
const scalar mergeDist,
|
||||
const PrimitivePatch<FaceList, PointField>& p,
|
||||
const PrimitivePatch<FaceList, PointField>& pp,
|
||||
Field
|
||||
<
|
||||
typename PrimitivePatch<FaceList, PointField>::point_type
|
||||
@ -46,50 +46,54 @@ void Foam::PatchTools::gatherAndMerge
|
||||
<
|
||||
typename PrimitivePatch<FaceList, PointField>::face_type
|
||||
>& mergedFaces,
|
||||
labelList& pointMergeMap
|
||||
labelList& pointMergeMap,
|
||||
const bool useLocal
|
||||
)
|
||||
{
|
||||
typedef typename PrimitivePatch<FaceList,PointField>::face_type FaceType;
|
||||
typedef typename PrimitivePatch<FaceList,PointField>::point_type PointType;
|
||||
|
||||
// Collect points from all processors
|
||||
labelList pointSizes;
|
||||
{
|
||||
const globalIndex gi(p.points().size());
|
||||
// Faces from all ranks
|
||||
const globalIndex faceAddr(pp.size(), globalIndex::gatherOnly{});
|
||||
|
||||
gi.gather(p.points(), mergedPoints);
|
||||
|
||||
pointSizes = gi.sizes();
|
||||
}
|
||||
|
||||
// Collect faces from all processors and renumber using sizes of
|
||||
// gathered points
|
||||
{
|
||||
List<List<FaceType>> gatheredFaces(Pstream::nProcs());
|
||||
gatheredFaces[Pstream::myProcNo()] = p;
|
||||
Pstream::gatherList(gatheredFaces);
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
mergedFaces = static_cast<const List<FaceType>&>
|
||||
// Points from all ranks
|
||||
const globalIndex pointAddr
|
||||
(
|
||||
ListListOps::combineOffset<List<FaceType>>
|
||||
(
|
||||
gatheredFaces,
|
||||
pointSizes,
|
||||
accessOp<List<FaceType>>(),
|
||||
offsetOp<FaceType>()
|
||||
)
|
||||
(useLocal ? pp.localPoints().size() : pp.points().size()),
|
||||
globalIndex::gatherOnly{}
|
||||
);
|
||||
|
||||
if (useLocal)
|
||||
{
|
||||
faceAddr.gather(pp.localFaces(), mergedFaces);
|
||||
pointAddr.gather(pp.localPoints(), mergedPoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
faceAddr.gather(pp, mergedFaces);
|
||||
pointAddr.gather(pp.points(), mergedPoints);
|
||||
}
|
||||
|
||||
// Relabel faces according to global point offsets
|
||||
for (const label proci : faceAddr.subProcs())
|
||||
{
|
||||
SubList<FaceType> slot(mergedFaces, faceAddr.range(proci));
|
||||
|
||||
for (auto& f : slot)
|
||||
{
|
||||
pointAddr.inplaceToGlobal(proci, f);
|
||||
}
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
// Merging points
|
||||
bool hasMerged = false;
|
||||
|
||||
if (Pstream::parRun() && Pstream::master())
|
||||
{
|
||||
Field<PointType> newPoints;
|
||||
labelList oldToNew;
|
||||
|
||||
bool hasMerged = mergePoints
|
||||
hasMerged = Foam::mergePoints
|
||||
(
|
||||
mergedPoints,
|
||||
mergeDist,
|
||||
@ -100,19 +104,28 @@ void Foam::PatchTools::gatherAndMerge
|
||||
|
||||
if (hasMerged)
|
||||
{
|
||||
// Store point mapping
|
||||
pointMergeMap.transfer(oldToNew);
|
||||
|
||||
// Copy points
|
||||
mergedPoints.transfer(newPoints);
|
||||
|
||||
// Relabel faces
|
||||
for (auto& f : mergedFaces)
|
||||
{
|
||||
inplaceRenumber(pointMergeMap, f);
|
||||
inplaceRenumber(oldToNew, f);
|
||||
}
|
||||
|
||||
// Store newly merged points
|
||||
mergedPoints.transfer(newPoints);
|
||||
|
||||
// Store point mapping
|
||||
if (notNull(pointMergeMap))
|
||||
{
|
||||
pointMergeMap.transfer(oldToNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TDB:
|
||||
// if (!hasMerged && notNull(pointMergeMap))
|
||||
// {
|
||||
// pointMergeMap.clear();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -468,9 +468,15 @@ public:
|
||||
bool hasPointNormals() const { return bool(pointNormalsPtr_); }
|
||||
|
||||
bool hasBoundaryPoints() const { return bool(boundaryPointsPtr_); }
|
||||
|
||||
// These ones are currently all calculated together:
|
||||
// - edges(), faceFaces(), edgeFaces(), faceEdges()
|
||||
|
||||
bool hasEdges() const { return bool(edgesPtr_); }
|
||||
bool hasFaceFaces() const { return bool(faceFacesPtr_); }
|
||||
bool hasEdgeFaces() const { return bool(edgeFacesPtr_); }
|
||||
bool hasFaceEdges() const { return bool(faceEdgesPtr_); }
|
||||
|
||||
bool hasPointEdges() const { return bool(pointEdgesPtr_); }
|
||||
bool hasPointFaces() const { return bool(pointFacesPtr_); }
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,7 +32,7 @@ License
|
||||
#include "coupledPolyPatch.H"
|
||||
#include "sampledSurface.H"
|
||||
#include "mergePoints.H"
|
||||
#include "uindirectPrimitivePatch.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
#include "PatchTools.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
@ -353,104 +353,43 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
|
||||
pointField& points
|
||||
) const
|
||||
{
|
||||
List<faceList> allFaces(Pstream::nProcs());
|
||||
List<pointField> allPoints(Pstream::nProcs());
|
||||
labelList whichFaces(faceId_);
|
||||
|
||||
{
|
||||
IndirectList<face> selectedFaces(mesh_.faces(), labelList(faceId_));
|
||||
labelList& meshFaceIds = selectedFaces.addressing();
|
||||
|
||||
forAll(meshFaceIds, i)
|
||||
// Remap patch-face ids to mesh face ids
|
||||
forAll(whichFaces, i)
|
||||
{
|
||||
const label patchi = facePatchId_[i];
|
||||
if (patchi != -1)
|
||||
{
|
||||
meshFaceIds[i] += mesh_.boundaryMesh()[patchi].start();
|
||||
whichFaces[i] += mesh_.boundaryMesh()[patchi].start();
|
||||
}
|
||||
}
|
||||
|
||||
// Add local faces and points to the all* lists
|
||||
uindirectPrimitivePatch pp(selectedFaces, mesh_.points());
|
||||
|
||||
allFaces[Pstream::myProcNo()] = pp.localFaces();
|
||||
allPoints[Pstream::myProcNo()] = pp.localPoints();
|
||||
}
|
||||
|
||||
Pstream::gatherList(allFaces);
|
||||
Pstream::gatherList(allPoints);
|
||||
|
||||
// Renumber and flatten
|
||||
label nFaces = 0;
|
||||
label nPoints = 0;
|
||||
forAll(allFaces, proci)
|
||||
{
|
||||
nFaces += allFaces[proci].size();
|
||||
nPoints += allPoints[proci].size();
|
||||
}
|
||||
|
||||
faces.resize(nFaces);
|
||||
points.resize(nPoints);
|
||||
|
||||
nFaces = 0;
|
||||
nPoints = 0;
|
||||
|
||||
// My data first
|
||||
{
|
||||
for (const face& f : allFaces[Pstream::myProcNo()])
|
||||
{
|
||||
faces[nFaces++] = offsetOp<face>()(f, nPoints);
|
||||
}
|
||||
|
||||
for (const point& p : allPoints[Pstream::myProcNo()])
|
||||
{
|
||||
points[nPoints++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
// Other proc data follows
|
||||
forAll(allFaces, proci)
|
||||
{
|
||||
if (proci == Pstream::myProcNo())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const face& f : allFaces[proci])
|
||||
{
|
||||
faces[nFaces++] = offsetOp<face>()(f, nPoints);
|
||||
}
|
||||
|
||||
for (const point& p : allPoints[proci])
|
||||
{
|
||||
points[nPoints++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge
|
||||
labelList oldToNew;
|
||||
pointField newPoints;
|
||||
bool hasMerged = mergePoints
|
||||
indirectPrimitivePatch pp
|
||||
(
|
||||
points,
|
||||
SMALL,
|
||||
false,
|
||||
oldToNew,
|
||||
newPoints
|
||||
IndirectList<face>(mesh_.faces(), std::move(whichFaces)),
|
||||
mesh_.points()
|
||||
);
|
||||
|
||||
if (hasMerged)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Pout<< "Merged from " << points.size()
|
||||
<< " down to " << newPoints.size() << " points" << endl;
|
||||
}
|
||||
|
||||
points.transfer(newPoints);
|
||||
for (face& f : faces)
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
inplaceRenumber(oldToNew, f);
|
||||
labelList pointsMap;
|
||||
|
||||
PatchTools::gatherAndMerge
|
||||
(
|
||||
SMALL, // mergeDist
|
||||
pp,
|
||||
points,
|
||||
faces,
|
||||
pointsMap,
|
||||
true // useLocal=true
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
faces = pp.localFaces();
|
||||
points = pp.localPoints();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user