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