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-2019 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 <numeric>
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 
105 
107 {
108  return invert(map.size(), map);
109 }
110 
111 
113 (
114  const label len,
115  const labelUList& map
116 )
117 {
118  labelList sizes(len, Zero);
119 
120  for (const label newIdx : map)
121  {
122  if (newIdx >= 0)
123  {
124  ++sizes[newIdx];
125  }
126  }
127 
128  labelListList inverse(len);
129 
130  for (label i=0; i < len; ++i)
131  {
132  inverse[i].resize(sizes[i]);
133  sizes[i] = 0; // reset size counter
134  }
135 
136  label i = 0;
137  for (const label newIdx : map)
138  {
139  if (newIdx >= 0)
140  {
141  inverse[newIdx][sizes[newIdx]++] = i;
142  }
143 
144  ++i;
145  }
146 
147  return inverse;
148 }
149 
150 
152 (
153  const labelUList& oldToNew,
154  const bitSet& input,
155  const bool prune
156 )
157 {
158  const label len = input.size();
159 
160  bitSet output;
161  output.reserve(len);
162 
163  for
164  (
165  label pos = input.find_first();
166  pos >= 0 && pos < len;
167  pos = input.find_next(pos)
168  )
169  {
170  const label newIdx = oldToNew[pos];
171 
172  if (newIdx >= 0)
173  {
174  output.set(newIdx);
175  }
176  else if (!prune)
177  {
178  output.set(pos);
179  }
180  }
181 
182  if (prune)
183  {
184  output.trim();
185  }
186 
187  return output;
188 }
189 
190 
192 (
193  const labelUList& oldToNew,
194  bitSet& input,
195  const bool prune
196 )
197 {
198  input = reorder(oldToNew, input, prune);
199 }
200 
201 
203 {
204  std::iota(map.begin(), map.end(), start);
205 }
206 
207 
208 // ************************************************************************* //
Foam::bitSet::find_first
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:314
Foam::bitSet
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:64
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::bitSet::set
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:563
Foam::UList::begin
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:276
Foam::invert
labelList invert(const label len, const labelUList &map)
Create an inverse one-to-one mapping.
Definition: ListOps.C:35
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::reorder
ListType reorder(const labelUList &oldToNew, const ListType &input, const bool prune=false)
Reorder the elements of a list.
Definition: ListOpsTemplates.C:80
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::FatalError
error FatalError
Foam::bitSet::find_next
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:400
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::List< label >
Foam::ListOps::identity
void identity(labelUList &map, label start=0)
Set identity map with (map[i] == i)
Definition: ListOps.C:202
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::PackedList::size
label size() const noexcept
Number of entries.
Definition: PackedListI.H:366
Foam::UList< label >
Foam::PackedList::reserve
void reserve(const label nElem)
Reserve allocation space for at least this size.
Definition: PackedListI.H:476
Foam::PackedList::trim
bool trim(label minpos=-1)
Definition: PackedListI.H:97
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
ListOps.H
Various functions to operate on Lists.
Foam::UList::end
iterator end()
Return an iterator to end traversing the UList.
Definition: UListI.H:297
Foam::invertOneToMany
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:113
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177