diff --git a/applications/test/ListOps/Test-ListOps.C b/applications/test/ListOps/Test-ListOps.C index e722ced197b38ec8757abf8b0e37977c345ca0af..c4fb44a0f55ffe3ac6a59c8ee315b3fc7b1b8271 100644 --- a/applications/test/ListOps/Test-ListOps.C +++ b/applications/test/ListOps/Test-ListOps.C @@ -125,7 +125,6 @@ int main(int argc, char *argv[]) ) << nl << endl; - test6.append(identity(13)); // Randomize the list @@ -135,6 +134,45 @@ int main(int argc, char *argv[]) inplaceUniqueSort(test6); Info<< "Unique : " << flatOutput(test6) << endl; + + // List reorder + labelList oldToNew(identity(40)); + std::random_shuffle(oldToNew.begin(), oldToNew.end()); + + // Force a few -1: + oldToNew[4] = oldToNew[8] = -1; + + Info<<"Test reorder - oldToNew:" << nl + << flatOutput(oldToNew) << nl << nl; + + PackedBoolList bitset + ( + ListOps::createWithValue<bool> + ( + 25, + labelList({8, 12, 15, 22, 4}), + true + ) + ); + + Info<<"bitset input: " << flatOutput(bitset) << nl; + inplaceReorder(oldToNew, bitset); + Info<<" reorder: " << flatOutput(bitset) << nl << nl; + + PackedList<2> packed + ( + ListOps::createWithValue<label> + ( + 25, + labelList({8, 12, 15, 22, 4}), + 2 + ) + ); + + Info<<"packed input: " << flatOutput(packed) << nl; + inplaceReorder(oldToNew, packed); + Info<<" reorder: " << flatOutput(packed) << nl << nl; + Info<< "\nEnd\n" << endl; return 0; diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C index 96e2afe42cd29538f361033d9dbea1f5bcf89665..72b34de0ca81e15ae7b1560d54a2330d8481d2e8 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C @@ -105,6 +105,7 @@ Foam::labelList Foam::identity(const label len, const label start) { labelList map(len); + // Same as std::iota(map.begin(), map.end(), start); for (label i = 0; i < len; ++i) { map[i] = i + start; @@ -114,4 +115,60 @@ Foam::labelList Foam::identity(const label len, const label start) } +Foam::PackedBoolList Foam::reorder +( + const labelUList& oldToNew, + const PackedBoolList& input, + const bool prune +) +{ + const label len = input.size(); + + PackedBoolList output(len); + output.reserve(len); + + for (label i=0; i < len; ++i) + { + if (input.test(i)) + { + const label newIdx = oldToNew[i]; + + if (newIdx >= 0) + { + output.set(newIdx); + } + else if (!prune) + { + output.set(i); + } + } + } + + if (prune) + { + output.trim(); + } + + // Verify addresses (for movable refs) + // Info<< "reordered in " << long(input.storage().cdata()) << nl + // << "reordered out " << long(output.storage().cdata()) << nl; + + return output; +} + + +void Foam::inplaceReorder +( + const labelUList& oldToNew, + PackedBoolList& input, + const bool prune +) +{ + input = reorder(oldToNew, input, prune); + + // Verify address (for movable refs) + // Info<< "now have " << long(input.storage().cdata()) << nl; +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H index 54033086d208626ed5191cbfe7d16588000680d7..9f9511601d0fa2a516bf5f3f459509bd0d2f5232 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H @@ -65,14 +65,14 @@ static const List<Type>& emptyList() //- Renumber the values (not the indices) of a list. -// Negative ListType elements are left untouched. -template<class ListType> -ListType renumber(const labelUList& oldToNew, const ListType& input); +// Negative IntListType elements are left untouched. +template<class IntListType> +IntListType renumber(const labelUList& oldToNew, const IntListType& input); //- 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& input); +// Negative IntListType elements are left untouched. +template<class IntListType> +void inplaceRenumber(const labelUList& oldToNew, IntListType& input); //- Reorder the elements of a list. @@ -102,6 +102,50 @@ void inplaceReorder ); +//- Reorder the elements of a packed list. +// Similar to the general templated form, but with auto-vivify +// for PackedList. +template<unsigned Width> +PackedList<Width> reorder +( + const labelUList& oldToNew, + const PackedList<Width>& input, + const bool prune = false +); + +//- Inplace reorder the elements of a packed list. +// Similar to the general templated form, but with auto-vivify +// for PackedList. +template<unsigned Width> +void inplaceReorder +( + const labelUList& oldToNew, + PackedList<Width>& input, + const bool prune = false +); + + +//- Reorder the elements of a list. +// Similar to the general templated form, but with auto-vivify +// for PackedBoolList. +PackedBoolList reorder +( + const labelUList& oldToNew, + const PackedBoolList& input, + const bool prune = false +); + +//- Inplace reorder the elements of a list. +// Similar to the general templated form, but with auto-vivify +// for PackedBoolList. +void inplaceReorder +( + const labelUList& oldToNew, + PackedBoolList& input, + const bool prune = false +); + + // Variants to work with iterators and sparse tables. // Need to have iterators and insert() diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index 0ac119e1b288d9d118c791d166c9104b6a7dae61..068d4187bdc6801180a5565c19d8e4e60e030651 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -29,16 +29,16 @@ License // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // -template<class ListType> -ListType Foam::renumber +template<class IntListType> +IntListType Foam::renumber ( const labelUList& oldToNew, - const ListType& input + const IntListType& input ) { const label len = input.size(); - ListType output(len); + IntListType output(len); output.resize(len); // Consistent sizing (eg, DynamicList) for (label i=0; i < len; ++i) @@ -53,11 +53,11 @@ ListType Foam::renumber } -template<class ListType> +template<class IntListType> void Foam::inplaceRenumber ( const labelUList& oldToNew, - ListType& input + IntListType& input ) { const label len = input.size(); @@ -120,13 +120,17 @@ template<class ListType> void Foam::inplaceReorder ( const labelUList& oldToNew, - ListType& input, + ListType& inputOutput, const bool prune ) { // NOTE: cannot use std::move() since we have no guarantee that // the oldToNew map is unique (ie, shuffle) + // Use const reference to ensure we obtain the proper operator[] + // on lazy lists (eg, List<bool>, PackedBoolList) + + const ListType& input = inputOutput; const label len = input.size(); ListType output(len); @@ -159,7 +163,72 @@ void Foam::inplaceReorder output.resize(maxIdx+1); } - input.transfer(output); + inputOutput.transfer(output); +} + + +template<unsigned Width> +Foam::PackedList<Width> Foam::reorder +( + const labelUList& oldToNew, + const PackedList<Width>& input, + const bool prune +) +{ + const label len = input.size(); + + PackedList<Width> output(len); + + label maxIdx = -1; // For pruning: newSize = maxIdx+1 + for (label i=0; i < len; ++i) + { + const auto& val = input.get(i); + + const label newIdx = oldToNew[i]; + + if (newIdx >= 0) + { + // Could enforce (newIdx < len) + // ... or just rely on FULLDEBUG from UList + + output.set(newIdx, val); + + if (maxIdx < newIdx) + { + maxIdx = newIdx; + } + } + else if (!prune) + { + output.set(i, val); + } + } + + if (prune) + { + output.resize(maxIdx+1); + } + + // Verify addresses (for movable refs) + // Info<< "reordered in " << long(input.storage().cdata()) << nl + // << "reordered out " << long(output.storage().cdata()) << nl; + + return output; +} + + +template<unsigned Width> +void Foam::inplaceReorder +( + const labelUList& oldToNew, + PackedList<Width>& input, + const bool prune +) +{ + input = reorder(oldToNew, input, prune); + + // Verify address (for movable refs) + // Info<< "now have " << long(input.storage().cdata()) << nl; } diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C index 6170cd2fce59dfbe113f24273a539859a6abb968..38b7f23091a27b3971e3dcdfcb5e3cfb44814812 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C @@ -1222,18 +1222,8 @@ void Foam::polyTopoChange::compact { faces_[facei].flip(); Swap(faceOwner_[facei], faceNeighbour_[facei]); - flipFaceFlux_[facei] = - ( - flipFaceFlux_[facei] - ? 0 - : 1 - ); - faceZoneFlip_[facei] = - ( - faceZoneFlip_[facei] - ? 0 - : 1 - ); + flipFaceFlux_.set(facei, !flipFaceFlux_.test(facei)); + faceZoneFlip_.set(facei, !faceZoneFlip_.test(facei)); } } } @@ -2809,7 +2799,7 @@ Foam::label Foam::polyTopoChange::addFace } reverseFaceMap_.append(facei); - flipFaceFlux_[facei] = (flipFaceFlux ? 1 : 0); + flipFaceFlux_.set(facei, flipFaceFlux); if (zoneID >= 0) {