ListOps.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2015 OpenFOAM Foundation
9 Copyright (C) 2018-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "ListOps.H"
30#include "HashSet.H"
31#include <numeric>
32
33// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
34
36(
37 const label len,
38 const labelUList& map
39)
40{
41 labelList inverse(len, -1);
42
43 label i = 0;
44 for (const label newIdx : map)
45 {
46 if (newIdx >= 0)
47 {
48 #ifdef FULLDEBUG
49 if (newIdx >= len)
50 {
52 << "Inverse location " << newIdx
53 << " is out of range. List has size " << len
54 << abort(FatalError);
55 }
56 #endif
57
58 if (inverse[newIdx] >= 0)
59 {
61 << "Map is not one-to-one. At index " << i
62 << " element " << newIdx << " has already occurred\n"
63 << "Please use invertOneToMany instead"
64 << abort(FatalError);
65 }
66
67 inverse[newIdx] = i;
68 }
69
70 ++i;
71 }
72
73 return inverse;
74}
75
76
78(
79 const label len,
80 const bitSet& map
81)
82{
83 labelList inverse(len, -1);
84
85 label i = 0;
86 for (const label newIdx : map)
87 {
88 #ifdef FULLDEBUG
89 if (newIdx >= len)
90 {
92 << "Inverse location " << newIdx
93 << " is out of range. List has size " << len
94 << abort(FatalError);
95 }
96 #endif
97
98 inverse[newIdx] = i;
99
100 ++i;
101 }
102
103 return inverse;
104}
105
106
108{
109 return invert(map.size(), map);
110}
111
112
114(
115 const label len,
116 const labelUList& map
117)
118{
119 labelList sizes(len, Zero);
120
121 for (const label newIdx : map)
122 {
123 if (newIdx >= 0)
124 {
125 ++sizes[newIdx];
126 }
127 }
128
129 labelListList inverse(len);
130
131 for (label i=0; i < len; ++i)
132 {
133 inverse[i].resize(sizes[i]);
134 sizes[i] = 0; // reset size counter
135 }
136
137 label i = 0;
138 for (const label newIdx : map)
139 {
140 if (newIdx >= 0)
141 {
142 inverse[newIdx][sizes[newIdx]++] = i;
143 }
144
145 ++i;
146 }
147
148 return inverse;
149}
150
151
153(
154 const labelUList& oldToNew,
155 const bitSet& input,
156 const bool prune
157)
158{
159 const label len = input.size();
160
161 bitSet output;
162 output.reserve(len);
163
164 for
165 (
166 label pos = input.find_first();
167 pos >= 0 && pos < len;
168 pos = input.find_next(pos)
169 )
170 {
171 const label newIdx = oldToNew[pos];
172
173 if (newIdx >= 0)
174 {
175 output.set(newIdx);
176 }
177 else if (!prune)
178 {
179 output.set(pos);
180 }
181 }
182
183 if (prune)
184 {
185 output.trim();
186 }
187
188 return output;
189}
190
191
193(
194 const labelUList& oldToNew,
195 bitSet& input,
196 const bool prune
197)
198{
199 input = reorder(oldToNew, input, prune);
200}
201
202
203void Foam::ListOps::identity(labelUList& map, label start)
204{
205 std::iota(map.begin(), map.end(), start);
206}
207
208
210(
211 labelList& x,
212 const labelList& y
213) const
214{
215 if (y.size())
216 {
217 if (x.size())
218 {
219 labelHashSet set(x);
220 set.insert(y);
221 x = set.toc();
222 }
223 else
224 {
225 x = y;
226 }
227 }
228}
229
230
231// ************************************************************************* //
scalar y
Various functions to operate on Lists.
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
bool trim(label minpos=-1)
Definition: PackedListI.H:97
void reserve(const label numElem)
Definition: PackedListI.H:486
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:350
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:590
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:401
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:314
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
void identity(labelUList &map, label start=0)
Set identity map with (map[i] == i)
Definition: ListOps.C:203
dimensionedScalar pos(const dimensionedScalar &ds)
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:36
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:114
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.