dune-multidomaingrid 2.12-git
Loading...
Searching...
No Matches
subdomainset.hh
Go to the documentation of this file.
1#ifndef DUNE_MULTIDOMAINGRID_SUBDOMAINSET_HH
2#define DUNE_MULTIDOMAINGRID_SUBDOMAINSET_HH
3
4#include <algorithm>
5#include <bit>
6#include <cassert>
7#include <cstddef>
8#include <cstdint>
9#include <limits>
13
15
16namespace Dune {
17
18namespace mdgrid {
19
20// forward declarations
21template<typename SubDomainIndex, std::size_t capacity>
22class IntegralTypeSubDomainSet;
23
24template<typename SubDomainIndex, std::size_t capacity>
27
28template<typename SubDomainIndex, std::size_t capacity>
31
33
34// \internal
35namespace sds_detail {
36
38 template<typename T>
39 struct Candidate;
40
42 template<>
43 struct Candidate<uint8_t> {
44 typedef uint8_t type;
45 typedef Candidate<uint16_t> next_candidate;
46 };
47
49 template<>
50 struct Candidate<uint16_t> {
51 typedef uint16_t type;
52 typedef Candidate<uint32_t> next_candidate;
53 };
54
56 template<>
57 struct Candidate<uint32_t> {
58 typedef uint32_t type;
59 typedef Candidate<uint64_t> next_candidate;
60 };
61
63 template<>
64 struct Candidate<uint64_t> {
65 typedef uint64_t type;
66 typedef void next_candidate;
67 };
68
70 template<std::size_t capacity, typename candidate>
71 struct SetStorageTester {
72
73 static_assert(std::numeric_limits<typename candidate::type>::is_specialized,"numeric_limits<> lacks specialization");
74
76 typename candidate::type,
77 typename SetStorageTester<capacity,
78 typename candidate::next_candidate
79 >::type
80 >::type type;
81
82 static_assert((!std::is_same<type,void>::value),"unsupported maximum number of subdomains");
83
84 };
85
89 template<std::size_t capacity>
90 struct SetStorageTester<capacity,void> {
91
92 typedef void type;
93
94 };
95
97 template<std::size_t capacity>
98 struct SetStorageChooser {
99 typedef typename SetStorageTester<capacity,Candidate<uint8_t> >::type type;
100 };
101
103 template<typename SubDomainIndex, typename SetStorage>
104 class Iterator : public ForwardIteratorFacade<Iterator<SubDomainIndex,SetStorage>,
105 SubDomainIndex,
106 SubDomainIndex,
107 std::ptrdiff_t> {
108
109 template<typename,std::size_t>
110 friend class ::Dune::mdgrid::IntegralTypeSubDomainSet;
111
112 public:
113
114 typedef Iterator<SubDomainIndex,SetStorage> ThisType;
115 static const SetStorage base = 1;
116
117 SubDomainIndex dereference() const {
118 assert(_state != 0);
119 return _value;
120 }
121
122 bool equals(const ThisType& rhs) const {
123 return _state == rhs._state;
124 }
125
126 void increment() {
127 _state &= ~(base << _value); // remove current bit from state
128 if (_state != 0) {
129 findNextValue();
130 }
131 }
132
133 private:
134
135 void findNextValue() {
136 SetStorage lowestBit = _state & ((~_state) + 1); // isolate lowest bit
137 _value = std::countr_zero(lowestBit); // equivalent to log2(lowestBit)
138 }
139
140 explicit Iterator(SetStorage state) :
141 _state(state),
142 _value(0)
143 {
144 if (_state != 0)
145 findNextValue();
146 }
147
148 // optimized constructor for end iterator
149 explicit Iterator() :
150 _state(0),
151 _value(0)
152 {}
153
154 SetStorage _state;
155 SubDomainIndex _value;
156
157 };
158
159}
160
162
163
164template<typename SubDomainIndexT, std::size_t capacity>
166
169
172
173 typedef typename sds_detail::SetStorageChooser<capacity>::type SetStorage;
174 static const SetStorage base = 1;
175
176public:
177 static const std::size_t maxSize = capacity;
179 typedef sds_detail::Iterator<SubDomainIndex,SetStorage> Iterator;
181
183 {
184 typedef SetStorage DataType;
185
186 static bool fixedSize(int dim, int codim)
187 {
188 return true;
189 }
190
192 {
193 return 1;
194 }
195
196 template<typename MessageBufferImp>
198 {
199 buf.write(sds._set);
200 }
201
202 template<typename MessageBufferImp>
204 {
206 buf.read(h._set);
207 sds.addAll(h);
208 }
209
210 };
211
213
214 Iterator begin() const {
215 return Iterator(_set);
216 }
217
218 Iterator end() const {
219 return Iterator();
220 }
221
222 bool contains(SubDomainIndex domain) const {
223 assert(domain < maxSize);
224 return (base << domain) & _set;
225 }
226
227 template<typename Set>
228 bool containsAll(const Set& set) const {
229 return setContains(*this,set);
230 }
231
233 {
234 _set = minuend._set & ~subtrahend._set;
235 }
236
237 bool simple() const {
238 return (!empty()) && ((_set & (_set - 1)) == 0);
239 }
240
241 bool empty() const {
242 return _set == 0;
243 }
244
245 SetState state() const {
246 return (_set == 0 ? emptySet : (_set & (_set - 1)) == 0 ? simpleSet : multipleSet);
247 }
248
250 std::size_t c = 0;
251 for (SetStorage t = _set; t; ++c) {
252 t &= t - 1;
253 }
254 return c;
255 }
256
257 void clear() {
258 _set = 0;
259 }
260
261 void add(SubDomainIndex domain) {
262 assert(domain < maxSize);
263 _set |= base << domain;
264 }
265
266 void remove(SubDomainIndex domain) {
267 assert(domain < maxSize);
268 _set &= ~(base << domain);
269 }
270
271 void set(SubDomainIndex domain) {
272 assert(domain < maxSize);
273 _set = base << domain;
274 }
275
276 template<typename Set>
277 void addAll(const Set& rhs) {
278 setAdd(*this,rhs);
279 }
280
281 int domainOffset(SubDomainIndex domain) const {
282 assert(domain >= 0 && domain < maxSize);
283 return domain;
284 }
285
287 _set(0)
288 {}
289
291 return _set == r._set;
292 }
293
295 return !operator==(r);
296 }
297
298private:
299 SetStorage _set;
300
301};
302
303
304template<typename A, typename B>
305inline bool setContains(const A& a, const B& b) {
306 return std::all_of(b.begin(),b.end(),[&a](decltype(*(b.begin())) i) { return a.contains(i); });
307}
308
309template<typename A, typename B>
310inline void setAdd(A& a, const B& b) {
311 std::for_each(b.begin(),b.end(),[&a](decltype(*(b.begin())) i) { a.add(i); });
312}
313
314
315template<typename SubDomainIndex, std::size_t capacity>
318 return (a._set & b._set) == b._set;
319}
320
321template<typename SubDomainIndex, std::size_t capacity>
326
327} // namespace mdgrid
328
329} // namespace Dune
330
331#endif // DUNE_MULTIDOMAINGRID_SUBDOMAINSET_HH
bool setContains(const ArrayBasedSet< SI, capacity > &a, const ArrayBasedSet< SI, capacity > &b)
void setAdd(ArrayBasedSet< SI, capacity > &a, const ArrayBasedSet< SI, capacity > &b)
T & dereference() const
bool equals(const SLListConstIterator< T, A > &other) const
void increment()
size_type dim() const
LocalIndexState state() const
Definition subdomainset.hh:165
bool operator!=(const IntegralTypeSubDomainSet &r) const
Definition subdomainset.hh:294
friend bool setContains(const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &a, const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &b)
SubDomainIndexT SubDomainIndex
Definition subdomainset.hh:178
bool containsAll(const Set &set) const
Definition subdomainset.hh:228
Iterator begin() const
Definition subdomainset.hh:214
bool empty() const
Definition subdomainset.hh:241
void remove(SubDomainIndex domain)
Definition subdomainset.hh:266
void difference(const IntegralTypeSubDomainSet &minuend, const IntegralTypeSubDomainSet &subtrahend)
Definition subdomainset.hh:232
IntegralTypeSubDomainSet()
Definition subdomainset.hh:286
SetState
Definition subdomainset.hh:212
@ multipleSet
Definition subdomainset.hh:212
@ simpleSet
Definition subdomainset.hh:212
@ emptySet
Definition subdomainset.hh:212
std::size_t size() const
Definition subdomainset.hh:249
sds_detail::Iterator< SubDomainIndex, SetStorage > Iterator
Definition subdomainset.hh:179
void add(SubDomainIndex domain)
Definition subdomainset.hh:261
int domainOffset(SubDomainIndex domain) const
Definition subdomainset.hh:281
friend void setAdd(IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &a, const IntegralTypeSubDomainSet< SubDomainIndexT, capacity > &b)
IntegralTypeSubDomainSet< SubDomainIndex, capacity > This
Definition subdomainset.hh:180
bool simple() const
Definition subdomainset.hh:237
static const std::size_t maxSize
Definition subdomainset.hh:177
Iterator end() const
Definition subdomainset.hh:218
bool operator==(const IntegralTypeSubDomainSet &r) const
Definition subdomainset.hh:290
bool contains(SubDomainIndex domain) const
Definition subdomainset.hh:222
void addAll(const Set &rhs)
Definition subdomainset.hh:277
void set(SubDomainIndex domain)
Definition subdomainset.hh:271
void clear()
Definition subdomainset.hh:257
SetState state() const
Definition subdomainset.hh:245
SetStorage DataType
Definition subdomainset.hh:184
static void scatter(MessageBufferImp &buf, IntegralTypeSubDomainSet &sds, std::size_t n)
Definition subdomainset.hh:203
static bool fixedSize(int dim, int codim)
Definition subdomainset.hh:186
static std::size_t size(const IntegralTypeSubDomainSet &sds)
Definition subdomainset.hh:191
static void gather(MessageBufferImp &buf, const IntegralTypeSubDomainSet &sds)
Definition subdomainset.hh:197
T all_of(T... args)
T countr_zero(T... args)
T for_each(T... args)