DUNE PDELab (git)

matrixindexset.hh
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_MATRIXINDEXSET_HH
6#define DUNE_ISTL_MATRIXINDEXSET_HH
7
8#include <algorithm>
9#include <cstddef>
10#include <cstdint>
11#include <set>
12#include <variant>
13#include <vector>
14
15#include <dune/common/overloadset.hh>
16
17namespace Dune {
18
19
37 {
38 using Index = std::uint_least32_t;
39
40 // A vector that partly mimics a std::set by staying
41 // sorted on insert() and having unique values.
42 class FlatSet : public std::vector<Index>
43 {
44 using Base = std::vector<Index>;
45 public:
46 using Base::Base;
47 using Base::begin;
48 using Base::end;
49 void insert(const Index& value) {
50 auto it = std::lower_bound(begin(), end(), value);
51 if ((it == end() or (*it != value)))
52 Base::insert(it, value);
53 }
54 bool contains(const Index& value) const {
55 return std::binary_search(begin(), end(), value);
56 }
57 };
58
59 using RowIndexSet = std::variant<FlatSet, std::set<Index>>;
60
61 public:
62
63 using size_type = Index;
64
76 static constexpr size_type defaultMaxVectorSize = 2048;
77
83 MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept : rows_(0), cols_(0), maxVectorSize_(maxVectorSize)
84 {}
85
93 MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize) : rows_(rows), cols_(cols), maxVectorSize_(maxVectorSize)
94 {
95 indices_.resize(rows_, FlatSet());
96 }
97
99 void resize(size_type rows, size_type cols) {
100 rows_ = rows;
101 cols_ = cols;
102 indices_.resize(rows_, FlatSet());
103 }
104
112 void add(size_type row, size_type col) {
113 return std::visit(Dune::overload(
114 // If row is stored as set, call insert directly
115 [&](std::set<size_type>& set) {
116 set.insert(col);
117 },
118 // If row is stored as vector only insert directly
119 // if maxVectorSize_ is not reached. Otherwise switch
120 // to set storage first.
121 [&](FlatSet& sortedVector) {
122 if (sortedVector.size() < maxVectorSize_)
123 sortedVector.insert(col);
124 else if (not sortedVector.contains(col))
125 {
126 std::set<size_type> set(sortedVector.begin(), sortedVector.end());
127 set.insert(col);
128 indices_[row] = std::move(set);
129 }
130 }
131 ), indices_[row]);
132 }
133
135 size_type size() const {
136 size_type entries = 0;
137 for (size_type i=0; i<rows_; i++)
138 entries += rowsize(i);
139 return entries;
140 }
141
143 size_type rows() const {return rows_;}
144
146 size_type cols() const {return cols_;}
147
157 const auto& columnIndices(size_type row) const {
158 return indices_[row];
159 }
160
162 size_type rowsize(size_type row) const {
163 return std::visit([&](const auto& rowIndices) {
164 return rowIndices.size();
165 }, indices_[row]);
166 }
167
174 template <class MatrixType>
175 void import(const MatrixType& m, size_type rowOffset=0, size_type colOffset=0) {
176
177 typedef typename MatrixType::row_type RowType;
178 typedef typename RowType::ConstIterator ColumnIterator;
179
180 for (size_type rowIdx=0; rowIdx<m.N(); rowIdx++) {
181
182 const RowType& row = m[rowIdx];
183
184 ColumnIterator cIt = row.begin();
185 ColumnIterator cEndIt = row.end();
186
187 for(; cIt!=cEndIt; ++cIt)
188 add(rowIdx+rowOffset, cIt.index()+colOffset);
189
190 }
191
192 }
193
199 template <class MatrixType>
200 void exportIdx(MatrixType& matrix) const {
201
202 matrix.setSize(rows_, cols_);
203 matrix.setBuildMode(MatrixType::random);
204
205 for (size_type row=0; row<rows_; row++)
206 matrix.setrowsize(row, rowsize(row));
207
208 matrix.endrowsizes();
209
210 for (size_type row=0; row<rows_; row++) {
211 std::visit([&](const auto& rowIndices) {
212 matrix.setIndicesNoSort(row, rowIndices.begin(), rowIndices.end());
213 }, indices_[row]);
214 }
215
216 matrix.endindices();
217
218 }
219
220 private:
221
222 std::vector<RowIndexSet> indices_;
223
224 size_type rows_, cols_;
225 size_type maxVectorSize_;
226
227 };
228
229
230} // end namespace Dune
231
232#endif
Stores the nonzero entries for creating a sparse matrix.
Definition: matrixindexset.hh:37
void resize(size_type rows, size_type cols)
Reset the size of an index set.
Definition: matrixindexset.hh:99
static constexpr size_type defaultMaxVectorSize
Default value for maxVectorSize.
Definition: matrixindexset.hh:76
size_type rows() const
Return the number of rows.
Definition: matrixindexset.hh:143
void exportIdx(MatrixType &matrix) const
Initializes a BCRSMatrix with the indices contained in this MatrixIndexSet.
Definition: matrixindexset.hh:200
void add(size_type row, size_type col)
Add an index to the index set.
Definition: matrixindexset.hh:112
MatrixIndexSet(size_type rows, size_type cols, size_type maxVectorSize=defaultMaxVectorSize)
Constructor setting the matrix size.
Definition: matrixindexset.hh:93
MatrixIndexSet(size_type maxVectorSize=defaultMaxVectorSize) noexcept
Constructor with custom maxVectorSize.
Definition: matrixindexset.hh:83
const auto & columnIndices(size_type row) const
Return column indices of entries in given row.
Definition: matrixindexset.hh:157
size_type rowsize(size_type row) const
Return the number of entries in a given row.
Definition: matrixindexset.hh:162
size_type size() const
Return the number of entries.
Definition: matrixindexset.hh:135
size_type cols() const
Return the number of columns.
Definition: matrixindexset.hh:146
auto overload(F &&... f)
Create an overload set.
Definition: overloadset.hh:61
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)