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-2025 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 "CompactListList.H"
31 
32 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
33 
35 (
36  const label len,
37  const labelUList& map
38 )
39 {
40  labelList inverse(len, -1);
41 
42  label i = 0;
43  for (const label newIdx : map)
44  {
45  if (newIdx >= 0)
46  {
47  #ifdef FULLDEBUG
48  if (newIdx >= len)
49  {
51  << "Inverse location " << newIdx
52  << " is out of range. List has size " << len
53  << abort(FatalError);
54  }
55  #endif
56 
57  if (inverse[newIdx] >= 0)
58  {
60  << "Map is not one-to-one. At index " << i
61  << " element " << newIdx << " has already occurred\n"
62  << "Please use invertOneToMany instead"
63  << abort(FatalError);
64  }
65 
66  inverse[newIdx] = i;
67  }
68 
69  ++i;
70  }
71 
72  return inverse;
73 }
74 
75 
77 (
78  const label len,
79  const bitSet& map
80 )
81 {
82  labelList inverse(len, -1);
83 
84  label i = 0;
85  for (const label newIdx : map)
86  {
87  #ifdef FULLDEBUG
88  if (newIdx >= len)
89  {
91  << "Inverse location " << newIdx
92  << " is out of range. List has size " << len
93  << abort(FatalError);
94  }
95  #endif
96 
97  inverse[newIdx] = i;
98 
99  ++i;
100  }
101 
102  return inverse;
103 }
104 
107 {
108  return invert(map.size(), map);
109 }
110 
111 
113 {
114  const label len = values.size();
115 
116  Map<label> inverse;
117  inverse.reserve(len);
118 
119  for (label i = 0 ; i < len; ++i)
120  {
121  // For correct behaviour with duplicates, do NOT use
122  // inverse.insert(values[i], inverse.size());
123 
124  inverse.insert(values[i], i);
125  }
126 
127  return inverse;
128 }
129 
130 
132 (
133  const label len,
134  const labelUList& map
135 )
136 {
137  labelList sizes(len, Foam::zero{});
138 
139  for (const label newIdx : map)
140  {
141  if (newIdx >= 0)
142  {
143  #ifdef FULLDEBUG
144  if (newIdx >= len)
145  {
147  << "Inverse location " << newIdx
148  << " is out of range. List has size " << len
149  << abort(FatalError);
150  }
151  #endif
152 
153  ++sizes[newIdx];
154  }
155  }
156 
157  labelListList inverse(len);
158 
159  for (label i = 0; i < len; ++i)
160  {
161  inverse[i].resize(sizes[i]);
162  sizes[i] = 0; // reset size counter
163  }
164 
165  label i = 0;
166  for (const label newIdx : map)
167  {
168  if (newIdx >= 0)
169  {
170  inverse[newIdx][sizes[newIdx]++] = i;
171  }
172 
173  ++i;
174  }
176  return inverse;
177 }
178 
179 
182 (
183  const label len,
184  const labelUList& map
185 )
186 {
187  labelList sizes(len, Foam::zero{});
188 
189  for (const label newIdx : map)
190  {
191  if (newIdx >= 0)
192  {
193  #ifdef FULLDEBUG
194  if (newIdx >= len)
195  {
197  << "Inverse location " << newIdx
198  << " is out of range. List has size " << len
199  << abort(FatalError);
200  }
201  #endif
202 
203  ++sizes[newIdx];
204  }
205  }
206 
207  CompactListList<label> inverse(sizes);
208 
209  // Reuse sizes as output offset into inverse.values()
210  sizes = labelList::subList(inverse.offsets(), inverse.size());
211  labelList& values = inverse.values();
212 
213  label i = 0;
214  for (const label newIdx : map)
215  {
216  if (newIdx >= 0)
217  {
218  values[sizes[newIdx]++] = i;
219  }
220 
221  ++i;
222  }
223 
224  return inverse;
225 }
226 
227 
229 (
230  const labelUList& oldToNew,
231  const bitSet& input,
232  const bool prune
233 )
234 {
235  const label len = input.size();
236 
237  bitSet output;
238  output.reserve(len);
239 
240  for
241  (
242  label pos = input.find_first();
243  pos >= 0 && pos < len;
244  pos = input.find_next(pos)
245  )
246  {
247  const label newIdx = oldToNew[pos];
248 
249  if (newIdx >= 0)
250  {
251  output.set(newIdx);
252  }
253  else if (!prune)
254  {
255  output.set(pos);
256  }
257  }
258 
259  if (prune)
260  {
261  output.trim();
262  }
263 
264  return output;
265 }
266 
267 
269 (
270  const labelUList& oldToNew,
271  bitSet& input,
272  const bool prune
273 )
274 {
275  input = Foam::reorder(oldToNew, input, prune);
276 }
277 
278 
279 void Foam::ListOps::unionEqOp::operator()
280 (
281  labelList& x,
282  const labelUList& y
283 ) const
284 {
285  if (y.size())
286  {
287  if (x.size())
288  {
289  // Using HashSet will likely change the order of list
290  labelHashSet set(x);
291  set.insert(y);
292  x = set.toc();
293  }
294  else
295  {
296  x = y;
297  }
298  }
299 }
300 
301 
302 // ************************************************************************* //
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:229
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
Various functions to operate on Lists.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
dimensionedScalar pos(const dimensionedScalar &ds)
scalar y
CompactListList< label > invertOneToManyCompact(const label len, const labelUList &map)
Invert one-to-many compact map. Unmapped elements will be size 0.
Definition: ListOps.C:175
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:125
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:139
A packed storage of objects of type <T> using an offset table for access.
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:28
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:44
List< label > labelList
A List of labels.
Definition: List.H:61
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
Map< label > invertToMap(const labelUList &values)
Create inverse mapping, which is a lookup table into the given list.
Definition: ListOps.C:105
label size() const noexcept
Number of entries.
Definition: PackedList.H:393
A HashTable to objects of type <T> with a label key.