From 98ccc6ed5027ab563eb22aadf65537f0ac0433f2 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Tue, 30 May 2017 13:18:06 +0200
Subject: [PATCH] ENH: add prune option for ListOps reorder, inplaceReorder

- allows simultaneously reordering and truncation of lists

STYLE: add const ref for UnaryPredicate parameter
---
 .../containers/Lists/ListOps/ListOps.H        |  44 +++++--
 .../Lists/ListOps/ListOpsTemplates.C          |  89 +++++++++----
 src/conversion/ccm/misc/ListOps1.H            |  84 -------------
 src/conversion/ccm/misc/ListOps1Templates.C   | 117 ------------------
 src/conversion/ccm/misc/mergePoints1.C        |  59 +++++----
 src/conversion/ccm/reader/ccmReaderMesh.C     |   2 +-
 6 files changed, 131 insertions(+), 264 deletions(-)
 delete mode 100644 src/conversion/ccm/misc/ListOps1.H
 delete mode 100644 src/conversion/ccm/misc/ListOps1Templates.C

diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
index 46f3784a162..d7c93bef023 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
@@ -57,25 +57,41 @@ static const List<Type>& emptyList()
 
 
 //- Renumber the values (not the indices) of a list.
-//  Negative ListType elements are left as is.
+//  Negative ListType elements are left untouched.
 template<class ListType>
 ListType renumber(const labelUList& oldToNew, const ListType& lst);
 
-//- Inplace renumber the values of a list.
-//  Negative ListType elements are left as is.
+//- Inplace renumber the values (not the indices) of a list.
+//  Negative ListType elements are left untouched.
 template<class ListType>
 void inplaceRenumber(const labelUList& oldToNew, ListType& lst);
 
 
-//- Reorder the elements (indices, not values) of a list.
-//  Negative ListType elements are left as is.
+//- Reorder the elements of a list.
+//  Locations with negative oldToNew values are left as is (copy-through).
+//  However, if pruning is activated, these negative oldToNew values are
+//  instead skipped over and the resulting list shrunk to the max index
+//  actually used.
 template<class ListType>
-ListType reorder(const labelUList& oldToNew, const ListType& lst);
+ListType reorder
+(
+    const labelUList& oldToNew,
+    const ListType& lst,
+    const bool prune = false
+);
 
 //- Inplace reorder the elements of a list.
-//  Negative ListType elements are left as is.
+//  Locations with negative oldToNew values are left as is (copy-through).
+//  However, if pruning is activated, these negative oldToNew values are
+//  instead skipped over and the resulting list shrunk to the max index
+//  actually used.
 template<class ListType>
-void inplaceReorder(const labelUList& oldToNew, ListType& lst);
+void inplaceReorder
+(
+    const labelUList& oldToNew,
+    ListType& lst,
+    const bool prune = false
+);
 
 
 // Variants to work with iterators and sparse tables.
@@ -156,12 +172,20 @@ void inplaceSubset(const BoolListType& select, ListType& lst);
 //- Copy a subset of the input list when predicate is true.
 //  Do not use FixedList for the input list, since it doesn't resize.
 template<class ListType, class UnaryPredicate>
-ListType subsetList(const ListType& input, UnaryPredicate pred);
+ListType subsetList
+(
+    const ListType& input,
+    const UnaryPredicate& pred
+);
 
 //- Inplace subset of the list when predicate is true.
 //  Do not use FixedList for the input list, since it doesn't resize.
 template<class ListType, class UnaryPredicate>
-void inplaceSubsetList(ListType& input, UnaryPredicate pred);
+void inplaceSubsetList
+(
+    ListType& input,
+    const UnaryPredicate& pred
+);
 
 
 //- Invert one-to-one map. Unmapped elements will be -1.
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
index 48e8b73897e..bf5af3080db 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
@@ -70,23 +70,42 @@ template<class ListType>
 ListType Foam::reorder
 (
     const labelUList& oldToNew,
-    const ListType& lst
+    const ListType& lst,
+    const bool prune
 )
 {
-    ListType newLst(lst.size());
-    newLst.setSize(lst.size()); // Consistent sizes (eg, DynamicList)
+    const label sz = lst.size();
 
-    forAll(lst, elemI)
+    ListType newLst(sz);
+    newLst.setSize(sz);     // Consistent sizing (eg, DynamicList)
+
+    label maxIdx = -1;      // For pruning: newSize = maxIdx+1
+    forAll(lst, i)
     {
-        if (oldToNew[elemI] >= 0)
+        const label newIdx = oldToNew[i];
+        if (newIdx >= 0)
         {
-            newLst[oldToNew[elemI]] = lst[elemI];
+            // Could additionally enforce (newIdx < lst.size())
+            // ... or just rely on FULLDEBUG from UList
+
+            newLst[newIdx] = lst[i];
+
+            if (maxIdx < newIdx)
+            {
+                maxIdx = newIdx;
+            }
         }
-        else
+        else if (!prune)
         {
-            newLst[elemI] = lst[elemI];
+            newLst[i] = lst[i];
         }
     }
+
+    if (prune)
+    {
+        newLst.setSize(maxIdx+1);
+    }
+
     return newLst;
 }
 
@@ -95,24 +114,42 @@ template<class ListType>
 void Foam::inplaceReorder
 (
     const labelUList& oldToNew,
-    ListType& lst
+    ListType& lst,
+    const bool prune
 )
 {
-    ListType newLst(lst.size());
-    newLst.setSize(lst.size()); // Consistent sizing (eg, DynamicList)
+    const label sz = lst.size();
 
-    forAll(lst, elemI)
+    ListType newLst(sz);
+    newLst.setSize(sz);     // Consistent sizing (eg, DynamicList)
+
+    label maxIdx = -1;      // For pruning: newSize = maxIdx+1
+    forAll(lst, i)
     {
-        if (oldToNew[elemI] >= 0)
+        const label newIdx = oldToNew[i];
+        if (newIdx >= 0)
         {
-            newLst[oldToNew[elemI]] = lst[elemI];
+            // Could additionally enforce (newIdx < lst.size())
+            // ... or just rely on FULLDEBUG from UList
+
+            newLst[newIdx] = lst[i];
+
+            if (maxIdx < newIdx)
+            {
+                maxIdx = newIdx;
+            }
         }
-        else
+        else if (!prune)
         {
-            newLst[elemI] = lst[elemI];
+            newLst[i] = lst[i];
         }
     }
 
+    if (prune)
+    {
+        newLst.setSize(maxIdx+1);
+    }
+
     lst.transfer(newLst);
 }
 
@@ -126,9 +163,13 @@ void Foam::inplaceMapValue
 {
     for (auto iter = lst.begin(); iter != lst.end(); ++iter)
     {
-        if (iter.object() >= 0)
+        const label oldIdx = iter.object();
+        if (oldIdx >= 0)
         {
-            iter.object() = oldToNew[iter.object()];
+            // Could additionally enforce (oldIdx < oldToNew.size())
+            // ... or just rely on FULLDEBUG from UList
+
+            iter.object() = oldToNew[oldIdx];
         }
     }
 }
@@ -145,9 +186,13 @@ void Foam::inplaceMapKey
 
     for (auto iter = lst.begin(); iter != lst.end(); ++iter)
     {
-        if (iter.key() >= 0)
+        const label oldIdx = iter.key();
+        if (oldIdx >= 0)
         {
-            newLst.insert(oldToNew[iter.key()], iter.object());
+            // Could additionally enforce (oldIdx < oldToNew.size())
+            // ... or just rely on FULLDEBUG from UList
+
+            newLst.insert(oldToNew[oldIdx], iter.object());
         }
     }
 
@@ -423,7 +468,7 @@ template<class ListType, class UnaryPredicate>
 ListType Foam::subsetList
 (
     const ListType& lst,
-    UnaryPredicate pred
+    const UnaryPredicate& pred
 )
 {
     ListType newLst(lst.size());
@@ -447,7 +492,7 @@ template<class ListType, class UnaryPredicate>
 void Foam::inplaceSubsetList
 (
     ListType& lst,
-    UnaryPredicate pred
+    const UnaryPredicate& pred
 )
 {
     label nElem = 0;
diff --git a/src/conversion/ccm/misc/ListOps1.H b/src/conversion/ccm/misc/ListOps1.H
deleted file mode 100644
index 7e8490240c7..00000000000
--- a/src/conversion/ccm/misc/ListOps1.H
+++ /dev/null
@@ -1,84 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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/>.
-
-InNamspace
-    Foam
-
-Description
-    Various functions to operate on Lists.
-
-SourceFiles
-    ListOps.C
-    ListOpsTemplates.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef ListOps1_H
-#define ListOps1_H
-
-#include "ListOps.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-//- Reorder the elements (indices, not values) of a list.
-//  Negative ListType elements are untouched, unless pruning has been selected.
-//  With pruning, these elements are skipped and the list shrinks accordingly.
-template<class ListType>
-ListType reorder
-(
-    const labelUList& oldToNew,
-    const ListType&,
-    const bool prune
-);
-
-//- Inplace reorder the elements of a list.
-//  Negative ListType elements are untouched, unless pruning has been selected.
-//  With pruning, these elements are skipped and the list shrinks accordingly.
-template<class ListType>
-void inplaceReorder
-(
-    const labelUList& oldToNew,
-    ListType&,
-    const bool prune
-);
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-    #include "ListOps1Templates.C"
-#endif
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
-
diff --git a/src/conversion/ccm/misc/ListOps1Templates.C b/src/conversion/ccm/misc/ListOps1Templates.C
deleted file mode 100644
index 14a9ac38c92..00000000000
--- a/src/conversion/ccm/misc/ListOps1Templates.C
+++ /dev/null
@@ -1,117 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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 "ListOps1.H"
-
-// * * * * * * * * * * * * * * * Global Functions  * * * * * * * * * * * * * //
-
-template<class ListType>
-ListType Foam::reorder
-(
-    const labelUList& oldToNew,
-    const ListType& lst,
-    const bool prune
-)
-{
-    const label sz = lst.size();
-
-    // Create copy
-    ListType newLst(sz);
-
-    // Ensure consistent addressable size (eg, DynamicList)
-    newLst.setSize(sz);
-
-
-    label maxIdx = 0;
-    forAll(lst, elemI)
-    {
-        const label newIdx = oldToNew[elemI];
-        if (newIdx >= 0) // could also require newIdx < sz
-        {
-            newLst[newIdx] = lst[elemI];
-            if (prune && maxIdx < newIdx)
-            {
-                maxIdx = newIdx;
-            }
-        }
-        else if (!prune)
-        {
-            newLst[elemI] = lst[elemI];
-        }
-    }
-
-    if (prune && maxIdx < sz)
-    {
-        newLst.setSize(maxIdx);
-    }
-
-    return newLst;
-}
-
-
-template<class ListType>
-void Foam::inplaceReorder
-(
-    const labelUList& oldToNew,
-    ListType& lst,
-    const bool prune
-)
-{
-    const label sz = lst.size();
-
-    // Create copy
-    ListType newLst(sz);
-
-    // Ensure consistent addressable size (eg, DynamicList)
-    newLst.setSize(sz);
-
-    label maxIdx = 0;
-    forAll(lst, elemI)
-    {
-        const label newIdx = oldToNew[elemI];
-        if (newIdx >= 0) // could also require newIdx < sz
-        {
-            newLst[newIdx] = lst[elemI];
-            if (prune && maxIdx < newIdx)
-            {
-                maxIdx = newIdx;
-            }
-        }
-        else if (!prune)
-        {
-            newLst[elemI] = lst[elemI];
-        }
-    }
-
-    if (prune && maxIdx < sz)
-    {
-        newLst.setSize(maxIdx);
-    }
-
-    lst.transfer(newLst);
-}
-
-
-// ************************************************************************* //
diff --git a/src/conversion/ccm/misc/mergePoints1.C b/src/conversion/ccm/misc/mergePoints1.C
index c1114df3ca0..487ffffdb88 100644
--- a/src/conversion/ccm/misc/mergePoints1.C
+++ b/src/conversion/ccm/misc/mergePoints1.C
@@ -51,9 +51,8 @@ Foam::label Foam::mergePoints
         return 0;
     }
 
-    // No normal field operations on UIndirectList.
-    // Use a tmp pointField instead.
-    tmp<Field<Type>> tPoints(new pointField(points));
+    // Explicitly convert to Field to support various list types
+    tmp<Field<Type>> tPoints(new Field<Type>(points));
 
     Type compareOrigin = origin;
     if (origin == Type::max)
@@ -76,9 +75,9 @@ Foam::label Foam::mergePoints
     const Field<Type> d(tPoints - compareOrigin);
 
     List<scalar> magSqrD(d.size());
-    forAll(d, pointI)
+    forAll(d, pointi)
     {
-        magSqrD[pointI] = magSqr(d[pointI]);
+        magSqrD[pointi] = magSqr(d[pointi]);
     }
     labelList order;
     sortedOrder(magSqrD, order);
@@ -87,41 +86,41 @@ Foam::label Foam::mergePoints
     Field<scalar> sortedTol(points.size());
     forAll(order, sortI)
     {
-        label pointI = order[sortI];
+        label pointi = order[sortI];
 
         // Convert to scalar precision
         const point pt
         (
-            scalar(d[pointI].x()),
-            scalar(d[pointI].y()),
-            scalar(d[pointI].z())
+            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()));
     }
 
-    label newPointI = 0;
+    label newPointi = 0;
 
     // Handle 0th point separately (is always unique)
-    label pointI = order[0];
-    pointMap[pointI] = newPointI++;
+    label pointi = order[0];
+    pointMap[pointi] = newPointi++;
 
 
     for (label sortI = 1; sortI < order.size(); sortI++)
     {
         // Get original point index
-        label pointI = order[sortI];
+        label pointi = order[sortI];
         const scalar mag2 = magSqrD[order[sortI]];
         // Convert to scalar precision
         const point pt
         (
-            scalar(points[pointI].x()),
-            scalar(points[pointI].y()),
-            scalar(points[pointI].z())
+            scalar(points[pointi].x()),
+            scalar(points[pointi].y()),
+            scalar(points[pointi].z())
         );
 
 
         // Compare to previous points to find equal one.
-        label equalPointI = -1;
+        label equalPointi = -1;
 
         for
         (
@@ -131,46 +130,46 @@ Foam::label Foam::mergePoints
             prevSortI--
         )
         {
-            label prevPointI = order[prevSortI];
+            label prevPointi = order[prevSortI];
             const point prevPt
             (
-                scalar(points[prevPointI].x()),
-                scalar(points[prevPointI].y()),
-                scalar(points[prevPointI].z())
+                scalar(points[prevPointi].x()),
+                scalar(points[prevPointi].y()),
+                scalar(points[prevPointi].z())
             );
 
             if (magSqr(pt - prevPt) <= mergeTolSqr)
             {
                 // Found match.
-                equalPointI = prevPointI;
+                equalPointi = prevPointi;
 
                 break;
             }
         }
 
 
-        if (equalPointI != -1)
+        if (equalPointi != -1)
         {
-            // Same coordinate as equalPointI. Map to same new point.
-            pointMap[pointI] = pointMap[equalPointI];
+            // Same coordinate as equalPointi. Map to same new point.
+            pointMap[pointi] = pointMap[equalPointi];
 
             if (verbose)
             {
                 Pout<< "Foam::mergePoints : Merging points "
-                    << pointI << " and " << equalPointI
-                    << " with coordinates:" << points[pointI]
-                    << " and " << points[equalPointI]
+                    << pointi << " and " << equalPointi
+                    << " with coordinates:" << points[pointi]
+                    << " and " << points[equalPointi]
                     << endl;
             }
         }
         else
         {
             // Differs. Store new point.
-            pointMap[pointI] = newPointI++;
+            pointMap[pointi] = newPointi++;
         }
     }
 
-    return newPointI;
+    return newPointi;
 }
 
 
diff --git a/src/conversion/ccm/reader/ccmReaderMesh.C b/src/conversion/ccm/reader/ccmReaderMesh.C
index 0eaee2ef47c..346e9b557e1 100644
--- a/src/conversion/ccm/reader/ccmReaderMesh.C
+++ b/src/conversion/ccm/reader/ccmReaderMesh.C
@@ -38,7 +38,7 @@ License
 #include "uindirectPrimitivePatch.H"
 #include "SortableList.H"
 #include "mergePoints1.H"
-#include "ListOps1.H"
+#include "ListOps.H"
 
 #include "ccmInternal.H" // include last to avoid any strange interactions
 
-- 
GitLab