From 4094e2c58f38c614e3072dad6209e353647cb821 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Mon, 12 Jun 2017 14:36:45 +0200 Subject: [PATCH] ENH: reduce memory overhead in mergePoints (issue #495) - can avoid the intermediate point distance field in exchange for calculating a point subtraction twice. --- src/OpenFOAM/meshes/meshTools/mergePoints.C | 61 +++++++++++---------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/OpenFOAM/meshes/meshTools/mergePoints.C b/src/OpenFOAM/meshes/meshTools/mergePoints.C index 2b99235b72b..041a6f81944 100644 --- a/src/OpenFOAM/meshes/meshTools/mergePoints.C +++ b/src/OpenFOAM/meshes/meshTools/mergePoints.C @@ -41,22 +41,28 @@ Foam::label Foam::mergePoints { typedef typename PointList::value_type point_type; - // Create a old to new point mapping array - pointMap.setSize(points.size()); + const label nPoints = points.size(); + + // Create an old to new point mapping array + pointMap.setSize(nPoints); pointMap = -1; - if (points.empty()) + if (!nPoints) { return 0; } - // Explicitly convert to Field to support various list types - tmp<Field<point_type>> tPoints(new Field<point_type>(points)); - point_type compareOrigin = origin; if (origin == point_type::max) { - compareOrigin = sum(tPoints())/points.size(); + // Use average of input points to define a comparison origin. + // Same as sum(points)/nPoints, but handles different list types + compareOrigin = points[0]; + for (label pointi=1; pointi < nPoints; ++pointi) + { + compareOrigin += points[pointi]; + } + compareOrigin /= nPoints; } // We're comparing distance squared to origin first. @@ -68,34 +74,31 @@ Foam::label Foam::mergePoints // x^2+y^2+z^2 + 2*mergeTol*(x+z+y) + mergeTol^2*... // so the difference will be 2*mergeTol*(x+y+z) - const scalar mergeTolSqr = Foam::sqr(scalar(mergeTol)); + const scalar mergeTolSqr = Foam::sqr(mergeTol); // Sort points by magSqr - const Field<point_type> d(tPoints - compareOrigin); - - List<scalar> magSqrD(d.size()); - forAll(d, pointi) + List<scalar> magSqrDist(nPoints); + forAll(points, pointi) { - magSqrD[pointi] = magSqr(d[pointi]); + magSqrDist[pointi] = magSqr(points[pointi] - compareOrigin); } labelList order; - Foam::sortedOrder(magSqrD, order); + Foam::sortedOrder(magSqrDist, order); - Field<scalar> sortedTol(points.size()); + Field<scalar> sortedTol(nPoints); forAll(order, sortI) { - const label pointi = order[sortI]; + const point_type& pt = points[order[sortI]]; - // Convert to scalar precision - // NOTE: not yet using point_type template parameter - const point pt - ( - scalar(d[pointi].x()), - scalar(d[pointi].y()), - scalar(d[pointi].z()) - ); - sortedTol[sortI] = 2*mergeTol*(mag(pt.x())+mag(pt.y())+mag(pt.z())); + // Use scalar precision + sortedTol[sortI] = + 2*mergeTol* + ( + mag(scalar(pt.x() - compareOrigin.x())), + + mag(scalar(pt.y() - compareOrigin.y())), + + mag(scalar(pt.z() - compareOrigin.z())) + ); } label newPointi = 0; @@ -104,11 +107,11 @@ Foam::label Foam::mergePoints label pointi = order[0]; pointMap[pointi] = newPointi++; - for (label sortI = 1; sortI < order.size(); sortI++) + for (label sortI = 1; sortI < order.size(); ++sortI) { // Get original point index const label pointi = order[sortI]; - const scalar mag2 = magSqrD[order[sortI]]; + const scalar mag2 = magSqrDist[order[sortI]]; // Convert to scalar precision // NOTE: not yet using point_type template parameter @@ -127,8 +130,8 @@ Foam::label Foam::mergePoints ( label prevSortI = sortI - 1; prevSortI >= 0 - && (mag(magSqrD[order[prevSortI]] - mag2) <= sortedTol[sortI]); - prevSortI-- + && (mag(magSqrDist[order[prevSortI]] - mag2) <= sortedTol[sortI]); + --prevSortI ) { const label prevPointi = order[prevSortI]; -- GitLab