DUNE PDELab (git)

bcrspattern.hh
1// -*- tab-width: 4; indent-tabs-mode: nil -*-
2#ifndef DUNE_PDELAB_BACKEND_ISTL_BCRSPATTERN_HH
3#define DUNE_PDELAB_BACKEND_ISTL_BCRSPATTERN_HH
4
5#include <utility>
6#include <vector>
7#include <algorithm>
8#include <set>
9
11
13#include <dune/pdelab/backend/common/uncachedmatrixview.hh>
14#include <dune/pdelab/backend/istl/matrixhelpers.hh>
15#include <dune/pdelab/backend/istl/descriptors.hh>
16
17namespace Dune {
18 namespace PDELab {
19 namespace ISTL {
20
22
42 template<typename RowOrdering, typename ColOrdering>
44 {
45
46 public:
47
49 typedef typename RowOrdering::Traits::size_type size_type;
50
52 typedef void SubPattern;
53
54 private:
55
57 static const size_type empty = ~static_cast<size_type>(0);
58
60
69 struct PaddedColumnCriterion
70 {
71
72 bool operator()(size_type k) const
73 {
74 return k == _j || k == empty;
75 }
76
77 PaddedColumnCriterion(size_type j)
78 : _j(j)
79 {}
80
81 const size_type _j;
82
83 };
84
85
86 typedef typename std::vector<size_type>::iterator IndicesIterator;
87 typedef typename std::set<std::pair<size_type,size_type> >::iterator OverflowIterator;
88
89 typedef typename std::vector<size_type>::const_iterator ConstIndicesIterator;
90 typedef typename std::set<std::pair<size_type,size_type> >::const_iterator ConstOverflowIterator;
91
92 public:
93
95 template<typename RI, typename CI>
96 void add_link(const RI& ri, const CI& ci)
97 {
98 // extract block indices for current level
99 size_type i = ri.back();
100 size_type j = ci.back();
101
102 IndicesIterator start = _indices.begin();
103 IndicesIterator begin = start + _entries_per_row*i;
104 IndicesIterator end = start + _entries_per_row*(i+1);
105
106 // Does the entry (i,j) already exist?
107 IndicesIterator it = std::find_if(begin,end,PaddedColumnCriterion(j));
108 if (it != end)
109 {
110 // Yes, just write out j. This does the right thing regardless of whether
111 // it points at the correct column value or at an empty entry.
112 *it = j;
113 }
114 else
115 {
116 // The row is already full -> spill into map
117 _overflow.insert(std::make_pair(i,j));
118 }
119 }
120
121#ifndef DOXYGEN
122
123 // implementation detail for nested patterns
124 template<typename RI, typename CI>
125 void recursive_add_entry(const RI& ri, const CI& ci)
126 {
127 add_link(ri,ci);
128 }
129
130#endif //DOXYGEN
131
133 template<typename I>
134 void sizes(I rit) const
135 {
136 ConstIndicesIterator it = _indices.begin();
137 ConstIndicesIterator end = _indices.begin() + _entries_per_row;
138 ConstOverflowIterator oit = _overflow.begin();
139 ConstOverflowIterator oend = _overflow.end();
140 for (size_type i = 0; i < _row_ordering.blockCount(); ++i, ++rit, end+=_entries_per_row)
141 {
142 size_type s = 0;
143 // count non-empty column entries, break when first empty one is found.
144 for (; it != end; ++it)
145 {
146 if (*it == empty)
147 break;
148 ++s;
149 }
150 it = end;
151 // add overflow entries
152 for (; oit != oend && oit->first == i; ++oit)
153 ++s;
154 *rit = s;
155 }
156 }
157
159 std::vector<size_type> sizes() const
160 {
161 std::vector<size_type> r(_row_ordering.blockCount());
162 sizes(r.begin());
163 return r;
164 }
165
167 struct iterator
168 : public ForwardIteratorFacade<iterator, const size_type>
169 {
170
171#ifndef DOXYGEN
172
173 const size_type& dereference() const
174 {
175 if (_in_overflow)
176 return _oit->second;
177 else
178 return *_it;
179 }
180
181 void increment()
182 {
183 if (_in_overflow)
184 {
185 if (++_oit == _oend or _oit->first != _row)
186 {
187 // we have exhausted the row, invalidate iterator
188 _at_end = true;
189 }
190 }
191 else
192 {
193 if (_it != _end)
194 ++_it;
195 if (_it == _end || *_it == empty)
196 {
197 _in_overflow = true;
198 // we have exhausted the row, invalidate iterator
199 if (_oit == _oend || _oit->first > _row)
200 _at_end = true;
201 }
202 }
203 }
204
205 bool equals(const iterator& other) const
206 {
207 if (_row != other._row)
208 return false;
209 if (_at_end || other._at_end)
210 return _at_end && other._at_end;
211 if (_in_overflow)
212 return _oit == other._oit;
213 else
214 return _it == other._it;
215 }
216
217 iterator(const BCRSPattern& p, size_type row, bool at_end)
218 : _row(row)
219 , _in_overflow(false)
220 , _at_end(at_end)
221 , _it(p._indices.begin() + row * p._entries_per_row)
222 , _end(p._indices.begin() + (row+1) * p._entries_per_row)
223 , _oit(p._overflow.lower_bound(std::make_pair(row,0)))
224 , _oend(p._overflow.end())
225 {
226 // catch corner case with completely empty row
227 if ((!_at_end) && (_it == _end || *_it == empty))
228 {
229 _in_overflow = true;
230 _at_end = _oit == _oend || _oit->first != _row;
231 }
232 }
233
234 size_type _row;
235 bool _in_overflow;
236 bool _at_end;
237 typename std::vector<size_type>::const_iterator _it;
238 typename std::vector<size_type>::const_iterator _end;
239 typename std::set<std::pair<size_type,size_type> >::const_iterator _oit;
240 const typename std::set<std::pair<size_type,size_type> >::const_iterator _oend;
241
242#endif // DOXYGEN
243
244 };
245
248 {
249 return iterator(*this,i,false);
250 }
251
254 {
255 return iterator(*this,i,true);
256 }
257
259
264 BCRSPattern(const RowOrdering& row_ordering, const ColOrdering& col_ordering, size_type entries_per_row)
265 : _row_ordering(row_ordering)
266 , _col_ordering(col_ordering)
267 , _entries_per_row(entries_per_row)
268 , _indices(row_ordering.blockCount()*entries_per_row,size_type(empty))
269 {}
270
271 const RowOrdering& rowOrdering() const
272 {
273 return _row_ordering;
274 }
275
276 const ColOrdering& colOrdering() const
277 {
278 return _row_ordering;
279 }
280
282
288 void clear()
289 {
290 _indices = std::vector<size_type>();
291 _overflow = std::set<std::pair<size_type,size_type> >();
292 }
293
294 size_type entriesPerRow() const
295 {
296 return _entries_per_row;
297 }
298
299 size_type overflowCount() const
300 {
301 return _overflow.size();
302 }
303
304 private:
305
306 const RowOrdering& _row_ordering;
307 const ColOrdering& _col_ordering;
308 const size_type _entries_per_row;
309
310 std::vector<size_type> _indices;
311 std::set<std::pair<size_type,size_type> > _overflow;
312
313 };
314
315
317
322 template<typename RowOrdering, typename ColOrdering, typename SubPattern_>
324 {
325
326 public:
327
329 typedef SubPattern_ SubPattern;
330
332 typedef typename SubPattern::size_type size_type;
333
335
339 template<typename RI, typename CI>
340 void add_link(const RI& ri, const CI& ci)
341 {
342 recursive_add_entry(ri.view(),ci.view());
343 }
344
345#ifndef DOXYGEN
346
347 template<typename RI, typename CI>
348 void recursive_add_entry(const RI& ri, const CI& ci)
349 {
350 _sub_patterns[ri.back() * _col_ordering.blockCount() + ci.back()].recursive_add_entry(ri.back_popped(),ci.back_popped());
351 }
352
353#endif // DOXYGEN
354
355 template<typename EntriesPerRow>
356 NestedPattern(const RowOrdering& row_ordering, const ColOrdering& col_ordering, const EntriesPerRow& entries_per_row)
357 : _row_ordering(row_ordering)
358 , _col_ordering(col_ordering)
359 {
360 size_type rows = row_ordering.blockCount();
361 size_type cols = col_ordering.blockCount();
362 for (size_type i = 0; i < rows; ++i)
363 for (size_type j = 0; j < cols; ++j)
364 _sub_patterns.push_back(
366 _row_ordering.childOrdering(i),
367 _col_ordering.childOrdering(j),
368 entries_per_row[i][j]
369 )
370 );
371 }
372
373 NestedPattern(const RowOrdering& row_ordering, const ColOrdering& col_ordering, size_type entries_per_row)
374 : _row_ordering(row_ordering)
375 , _col_ordering(col_ordering)
376 {
377 size_type rows = row_ordering.blockCount();
378 size_type cols = col_ordering.blockCount();
379 for (size_type i = 0; i < rows; ++i)
380 for (size_type j = 0; j < cols; ++j)
381 _sub_patterns.push_back(
383 _row_ordering.childOrdering(i),
384 _col_ordering.childOrdering(j),
385 entries_per_row
386 )
387 );
388 }
389
392 {
393 return _sub_patterns[i * _col_ordering.blockCount() + j];
394 }
395
396 private:
397
398 const RowOrdering& _row_ordering;
399 const ColOrdering& _col_ordering;
400 std::vector<SubPattern> _sub_patterns;
401
402 };
403
404
405 } // namespace ISTL
406 } // namespace PDELab
407} // namespace Dune
408
409#endif // DUNE_PDELAB_BACKEND_ISTL_BCRSPATTERN_HH
Various tags for influencing backend behavior.
Base class for stl conformant forward iterators.
Definition: iteratorfacades.hh:142
Pattern builder for generic BCRS-like sparse matrices.
Definition: bcrspattern.hh:44
void SubPattern
BCRSPattern cannot contain nested subpatterns. This entry is only required for TMP purposes.
Definition: bcrspattern.hh:52
iterator begin(size_type i) const
Returns an iterator to the first column index of row i.
Definition: bcrspattern.hh:247
BCRSPattern(const RowOrdering &row_ordering, const ColOrdering &col_ordering, size_type entries_per_row)
Constructs a BCRSPattern for the given pair of orderings and reserves space for the provided average ...
Definition: bcrspattern.hh:264
RowOrdering::Traits::size_type size_type
size type used by BCRSPattern.
Definition: bcrspattern.hh:49
void sizes(I rit) const
Stream the sizes of all rows into the output iterator rit.
Definition: bcrspattern.hh:134
void clear()
Discard all internal data.
Definition: bcrspattern.hh:288
iterator end(size_type i) const
Returns an iterator past the last column index of row i.
Definition: bcrspattern.hh:253
void add_link(const RI &ri, const CI &ci)
Add a link between the row indicated by ri and the column indicated by ci.
Definition: bcrspattern.hh:96
std::vector< size_type > sizes() const
Returns a vector with the size of all rows in the pattern.
Definition: bcrspattern.hh:159
Pattern builder for nested hierarchies of generic BCRS-like sparse matrices.
Definition: bcrspattern.hh:324
void add_link(const RI &ri, const CI &ci)
Add a link between the row indicated by ri and the column indicated by ci.
Definition: bcrspattern.hh:340
SubPattern_ SubPattern
The pattern type used for each block.
Definition: bcrspattern.hh:329
SubPattern::size_type size_type
size type used by NestedPattern.
Definition: bcrspattern.hh:332
SubPattern & subPattern(size_type i, size_type j)
Returns the subpattern associated with block (i,j).
Definition: bcrspattern.hh:391
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:587
This file implements iterator facade classes for writing stl conformant iterators.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::bool_constant<(sizeof...(II)==0)> empty(std::integer_sequence< T, II... >)
Checks whether the sequence is empty.
Definition: integersequence.hh:80
Iterator over all column indices for a given row, unique but in arbitrary order.
Definition: bcrspattern.hh:169
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)