Dune Core Modules (unstable)

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 
17 namespace 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
const auto & columnIndices(size_type row) const
Return column indices of entries in given row.
Definition: matrixindexset.hh:157
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
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.80.0 (May 6, 22:30, 2024)