Reference documentation for deal.II version 9.2.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
sparsity_pattern.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_sparsity_pattern_h
17 #define dealii_sparsity_pattern_h
18 
19 
20 #include <deal.II/base/config.h>
21 
27 
28 // boost::serialization::make_array used to be in array.hpp, but was
29 // moved to a different file in BOOST 1.64
30 #include <boost/version.hpp>
31 #if BOOST_VERSION >= 106400
32 # include <boost/serialization/array_wrapper.hpp>
33 #else
34 # include <boost/serialization/array.hpp>
35 #endif
36 #include <boost/serialization/split_member.hpp>
37 
38 #include <algorithm>
39 #include <iostream>
40 #include <vector>
41 
43 
44 // Forward declarations
45 #ifndef DOXYGEN
46 class SparsityPattern;
50 template <typename number>
51 class FullMatrix;
52 template <typename number>
53 class SparseMatrix;
54 template <typename number>
56 template <typename number>
57 class SparseILU;
58 
60 {
61  class Accessor;
62 }
63 #endif
64 
69 namespace internals
70 {
71  namespace SparsityPatternTools
72  {
77 
83  size_type
85 
91  template <typename value>
92  size_type
93  get_column_index_from_iterator(const std::pair<size_type, value> &i);
94 
100  template <typename value>
101  size_type
102  get_column_index_from_iterator(const std::pair<const size_type, value> &i);
103 
104  } // namespace SparsityPatternTools
105 } // namespace internals
106 
107 
112 {
113  // forward declaration
114  class Iterator;
115 
120 
134  class Accessor
135  {
136  public:
141 
145  Accessor(const SparsityPatternBase *matrix, const std::size_t linear_index);
146 
151 
157  Accessor();
158 
163  size_type
164  row() const;
165 
171  size_type
172  index() const;
173 
183  size_type
184  global_index() const;
185 
190  size_type
191  column() const;
192 
202  bool
203  is_valid_entry() const;
204 
208  bool
209  operator==(const Accessor &) const;
210 
218  bool
219  operator<(const Accessor &) const;
220 
221  protected:
222  DeclExceptionMsg(DummyAccessor,
223  "The instance of this class was initialized"
224  " without SparsityPattern object, which"
225  " means that it is a dummy accessor that can"
226  " not do any operations.");
227 
232 
240  std::size_t linear_index;
241 
245  void
246  advance();
247 
248  // Grant access to iterator class.
250 
251  // Grant access to accessor class of ChunkSparsityPattern.
253  };
254 
255 
256 
281  class Iterator : public LinearIndexIterator<Iterator, Accessor>
282  {
283  public:
288 
293 
299  Iterator(const SparsityPatternBase *sp, const std::size_t linear_index);
300 
305  Iterator(const Accessor &accessor);
306  };
307 } // namespace SparsityPatternIterators
308 
309 
310 
330 {
331 public:
336 
342 
351 
366  static const size_type invalid_entry = numbers::invalid_size_type;
367 
374  // @{
381 
385  ~SparsityPatternBase() override = default;
386 
395  void
396  reinit(const size_type m, const size_type n, const unsigned int max_per_row);
397 
408  void
409  reinit(const size_type m,
410  const size_type n,
411  const std::vector<unsigned int> &row_lengths);
412 
418  virtual void
419  reinit(const size_type m,
420  const size_type n,
421  const ArrayView<const unsigned int> &row_lengths) = 0;
422 
430  void
431  symmetrize();
432 
439  void
440  add(const size_type i, const size_type j);
441 
442  // @}
443 
447  // @{
448 
457  iterator
458  begin() const;
459 
463  iterator
464  end() const;
465 
477  iterator
478  begin(const size_type r) const;
479 
488  iterator
489  end(const size_type r) const;
490 
491 
492  // @}
493 
497  // @{
498 
502  bool
503  operator==(const SparsityPatternBase &) const;
504 
509  bool
510  empty() const;
511 
515  bool
516  exists(const size_type i, const size_type j) const;
517 
523  size_type
524  max_entries_per_row() const;
525 
535  size_type
536  bandwidth() const;
537 
546  std::size_t
547  n_nonzero_elements() const;
548 
552  bool
553  is_compressed() const;
554 
559  size_type
560  n_rows() const;
561 
566  size_type
567  n_cols() const;
568 
572  unsigned int
573  row_length(const size_type row) const;
574 
579  std::size_t
580  memory_consumption() const;
581 
582  // @}
583 
587  // @{
588 
599  size_type
600  column_number(const size_type row, const unsigned int index) const;
601 
609  size_type
610  row_position(const size_type i, const size_type j) const;
611 
623  std::pair<size_type, size_type>
624  matrix_position(const std::size_t global_index) const;
625 
626  // @}
627 
631  // @{
632 
638  void
639  print(std::ostream &out) const;
640 
654  void
655  print_gnuplot(std::ostream &out) const;
656 
664  void
665  print_svg(std::ostream &out) const;
666 
671  template <class Archive>
672  void
673  save(Archive &ar, const unsigned int version) const;
674 
679  template <class Archive>
680  void
681  load(Archive &ar, const unsigned int version);
682 
683 #ifdef DOXYGEN
684 
688  template <class Archive>
689  void
690  serialize(Archive &archive, const unsigned int version);
691 #else
692  // This macro defines the serialize() method that is compatible with
693  // the templated save() and load() method that have been implemented.
694  BOOST_SERIALIZATION_SPLIT_MEMBER()
695 #endif
696 
697  // @}
698 
709  ExcNotCompressed,
710  "The operation you attempted is only allowed after the SparsityPattern "
711  "has been set up and compress() was called.");
712 
716  DeclException2(ExcNotEnoughSpace,
717  int,
718  int,
719  << "Upon entering a new entry to row " << arg1
720  << ": there was no free entry any more. " << std::endl
721  << "(Maximum number of entries for this row: " << arg2
722  << "; maybe the matrix is already compressed?)");
723 
729  ExcMatrixIsCompressed,
730  "The operation you attempted changes the structure of the SparsityPattern "
731  "and is not possible after compress() has been called.");
732 
733  // @}
734 
735 
736 protected:
745 
750 
755 
761  std::size_t max_vec_len;
762 
770  unsigned int max_row_length;
771 
785  std::unique_ptr<std::size_t[]> rowstart;
786 
809  std::unique_ptr<size_type[]> colnums;
810 
815 
816  // Make all sparse matrices friends of this class.
817  template <typename number>
818  friend class SparseMatrix;
819  template <typename number>
820  friend class SparseLUDecomposition;
821  template <typename number>
822  friend class SparseILU;
823  template <typename number>
824  friend class ChunkSparseMatrix;
825 
826  friend class ChunkSparsityPattern;
828 
829  // Also give access to internal details to the iterator/accessor classes.
833 };
834 
866 {
867 public:
872 
878 
887 
894 
901  // @{
907  SparsityPattern();
908 
925 
933  SparsityPattern(const size_type m,
934  const size_type n,
935  const unsigned int max_per_row);
936 
937 
946  SparsityPattern(const size_type m,
947  const size_type n,
948  const std::vector<unsigned int> &row_lengths);
949 
958  SparsityPattern(const size_type m, const unsigned int max_per_row);
959 
967  SparsityPattern(const size_type m,
968  const std::vector<unsigned int> &row_lengths);
969 
992  SparsityPattern(const SparsityPattern &original,
993  const unsigned int max_per_row,
994  const size_type extra_off_diagonals);
995 
999  ~SparsityPattern() override = default;
1000 
1006  SparsityPattern &
1007  operator=(const SparsityPattern &);
1008 
1014  virtual void
1015  reinit(const size_type m,
1016  const size_type n,
1017  const ArrayView<const unsigned int> &row_lengths) override;
1018 
1031  void
1032  compress();
1033 
1034 
1111  template <typename ForwardIterator>
1112  void
1113  copy_from(const size_type n_rows,
1114  const size_type n_cols,
1115  const ForwardIterator begin,
1116  const ForwardIterator end);
1117 
1122  void
1123  copy_from(const DynamicSparsityPattern &dsp);
1124 
1129  void
1130  copy_from(const SparsityPattern &sp);
1131 
1139  template <typename number>
1140  void
1141  copy_from(const FullMatrix<number> &matrix);
1142 
1149  template <typename ForwardIterator>
1150  void
1151  add_entries(const size_type row,
1152  ForwardIterator begin,
1153  ForwardIterator end,
1154  const bool indices_are_sorted = false);
1155 
1156  // @}
1157 
1158 
1162  // @{
1166  bool
1167  operator==(const SparsityPattern &) const;
1168 
1181  bool
1182  stores_only_added_elements() const;
1183 
1188  std::size_t
1189  memory_consumption() const;
1190 
1191  // @}
1195  // @{
1218  size_type
1219  operator()(const size_type i, const size_type j) const;
1220 
1221  // @}
1225  // @{
1226 
1237  void
1238  block_write(std::ostream &out) const;
1239 
1253  void
1254  block_read(std::istream &in);
1255 
1260  template <class Archive>
1261  void
1262  save(Archive &ar, const unsigned int version) const;
1263 
1268  template <class Archive>
1269  void
1270  load(Archive &ar, const unsigned int version);
1271 
1272 #ifdef DOXYGEN
1273 
1277  template <class Archive>
1278  void
1279  serialize(Archive &archive, const unsigned int version);
1280 #else
1281  // This macro defines the serialize() method that is compatible with
1282  // the templated save() and load() method that have been implemented.
1283  BOOST_SERIALIZATION_SPLIT_MEMBER()
1284 #endif
1285 
1286  // @}
1287 
1295  DeclException2(ExcIteratorRange,
1296  int,
1297  int,
1298  << "The iterators denote a range of " << arg1
1299  << " elements, but the given number of rows was " << arg2);
1304  int,
1305  << "The number of partitions you gave is " << arg1
1306  << ", but must be greater than zero.");
1308 private:
1313 
1314  // Make all sparse matrices friends of this class.
1315  template <typename number>
1316  friend class SparseMatrix;
1317  template <typename number>
1319  template <typename number>
1320  friend class SparseILU;
1321  template <typename number>
1322  friend class ChunkSparseMatrix;
1323 
1324  friend class ChunkSparsityPattern;
1326 
1327  // Also give access to internal details to the iterator/accessor classes.
1331 };
1332 
1333 
1335 /*---------------------- Inline functions -----------------------------------*/
1336 
1337 #ifndef DOXYGEN
1338 
1339 
1340 namespace SparsityPatternIterators
1341 {
1342  inline Accessor::Accessor(const SparsityPatternBase *sparsity_pattern,
1343  const std::size_t i)
1344  : container(sparsity_pattern)
1345  , linear_index(i)
1346  {}
1347 
1348 
1349 
1350  inline Accessor::Accessor(const SparsityPatternBase *sparsity_pattern)
1351  : container(sparsity_pattern)
1352  , linear_index(container->rowstart[container->rows])
1353  {}
1354 
1355 
1356 
1357  inline Accessor::Accessor()
1358  : container(nullptr)
1359  , linear_index(numbers::invalid_size_type)
1360  {}
1361 
1362 
1363 
1364  inline bool
1365  Accessor::is_valid_entry() const
1366  {
1367  Assert(container != nullptr, DummyAccessor());
1368  return (linear_index < container->rowstart[container->rows] &&
1369  container->colnums[linear_index] != SparsityPattern::invalid_entry);
1370  }
1371 
1372 
1373 
1374  inline size_type
1375  Accessor::row() const
1376  {
1377  Assert(is_valid_entry() == true, ExcInvalidIterator());
1378 
1379  const std::size_t *insert_point =
1380  std::upper_bound(container->rowstart.get(),
1381  container->rowstart.get() + container->rows + 1,
1382  linear_index);
1383  return insert_point - container->rowstart.get() - 1;
1384  }
1385 
1386 
1387 
1388  inline size_type
1389  Accessor::column() const
1390  {
1391  Assert(is_valid_entry() == true, ExcInvalidIterator());
1392 
1393  return (container->colnums[linear_index]);
1394  }
1395 
1396 
1397 
1398  inline size_type
1399  Accessor::index() const
1400  {
1401  Assert(is_valid_entry() == true, ExcInvalidIterator());
1402 
1403  return linear_index - container->rowstart[row()];
1404  }
1405 
1406 
1407 
1408  inline size_type
1409  Accessor::global_index() const
1410  {
1411  Assert(is_valid_entry() == true, ExcInvalidIterator());
1412 
1413  return linear_index;
1414  }
1415 
1416 
1417 
1418  inline bool
1419  Accessor::operator==(const Accessor &other) const
1420  {
1421  Assert(container != nullptr, DummyAccessor());
1422  Assert(other.container != nullptr, DummyAccessor());
1423  return (container == other.container && linear_index == other.linear_index);
1424  }
1425 
1426 
1427 
1428  inline bool
1429  Accessor::operator<(const Accessor &other) const
1430  {
1431  Assert(container != nullptr, DummyAccessor());
1432  Assert(other.container != nullptr, DummyAccessor());
1433  Assert(container == other.container, ExcInternalError());
1434 
1435  return linear_index < other.linear_index;
1436  }
1437 
1438 
1439 
1440  inline void
1442  {
1443  Assert(container != nullptr, DummyAccessor());
1444  Assert(linear_index < container->rowstart[container->rows],
1445  ExcIteratorPastEnd());
1446  ++linear_index;
1447  }
1448 
1449 
1450  inline Iterator::Iterator(const SparsityPatternBase *sp,
1451  const std::size_t linear_index)
1452  : LinearIndexIterator<Iterator, Accessor>(Accessor(sp, linear_index))
1453  {}
1454 
1455 
1456  inline Iterator::Iterator(const Accessor &accessor)
1457  : LinearIndexIterator<Iterator, Accessor>(accessor)
1458  {}
1459 
1460 
1461 } // namespace SparsityPatternIterators
1462 
1463 
1464 
1467 {
1468  if (n_rows() > 0)
1469  return {this, rowstart[0]};
1470  else
1471  return end();
1472 }
1473 
1474 
1475 
1478 {
1479  if (n_rows() > 0)
1480  return {this, rowstart[rows]};
1481  else
1482  return {nullptr, 0};
1483 }
1484 
1485 
1486 
1489 {
1490  AssertIndexRange(r, n_rows());
1491 
1492  return {this, rowstart[r]};
1493 }
1494 
1495 
1496 
1498 SparsityPatternBase::end(const size_type r) const
1499 {
1500  AssertIndexRange(r, n_rows());
1501 
1502  return {this, rowstart[r + 1]};
1503 }
1504 
1505 
1506 
1509 {
1510  return rows;
1511 }
1512 
1513 
1514 
1517 {
1518  return cols;
1519 }
1520 
1521 
1522 
1523 inline bool
1525 {
1526  return compressed;
1527 }
1528 
1529 
1530 
1531 inline bool
1533 {
1534  return (store_diagonal_first_in_row == false);
1535 }
1536 
1537 
1538 
1539 inline unsigned int
1541 {
1542  AssertIndexRange(row, rows);
1543  return rowstart[row + 1] - rowstart[row];
1544 }
1545 
1546 
1547 
1550  const unsigned int index) const
1551 {
1552  AssertIndexRange(row, rows);
1553  AssertIndexRange(index, row_length(row));
1554 
1555  return colnums[rowstart[row] + index];
1556 }
1557 
1558 
1559 
1560 inline std::size_t
1562 {
1564 
1565  if ((rowstart != nullptr) && (colnums != nullptr))
1566  return rowstart[rows] - rowstart[0];
1567  else
1568  // the object is empty or has zero size
1569  return 0;
1570 }
1571 
1572 
1573 
1574 template <class Archive>
1575 inline void
1576 SparsityPatternBase::save(Archive &ar, const unsigned int) const
1577 {
1578  // forward to serialization function in the base class.
1579  ar &boost::serialization::base_object<const Subscriptor>(*this);
1580 
1582 
1583  ar &boost::serialization::make_array(rowstart.get(), max_dim + 1);
1584  ar &boost::serialization::make_array(colnums.get(), max_vec_len);
1585 }
1586 
1587 
1588 
1589 template <class Archive>
1590 inline void
1591 SparsityPatternBase::load(Archive &ar, const unsigned int)
1592 {
1593  // forward to serialization function in the base class.
1594  ar &boost::serialization::base_object<Subscriptor>(*this);
1595 
1597 
1598  rowstart = std_cxx14::make_unique<std::size_t[]>(max_dim + 1);
1599  colnums = std_cxx14::make_unique<size_type[]>(max_vec_len);
1600 
1601  ar &boost::serialization::make_array(rowstart.get(), max_dim + 1);
1602  ar &boost::serialization::make_array(colnums.get(), max_vec_len);
1603 }
1604 
1605 
1606 
1607 template <class Archive>
1608 inline void
1609 SparsityPattern::save(Archive &ar, const unsigned int) const
1610 {
1611  // forward to serialization function in the base class.
1612  ar &boost::serialization::base_object<const SparsityPatternBase>(*this);
1614 }
1615 
1616 
1617 
1618 template <class Archive>
1619 inline void
1620 SparsityPattern::load(Archive &ar, const unsigned int)
1621 {
1622  // forward to serialization function in the base class.
1623  ar &boost::serialization::base_object<SparsityPatternBase>(*this);
1625 }
1626 
1627 
1628 
1629 inline bool
1631 {
1632  // it isn't quite necessary to compare *all* member variables. by only
1633  // comparing the essential ones, we can say that two sparsity patterns are
1634  // equal even if one is compressed and the other is not (in which case some
1635  // of the member variables are not yet set correctly)
1636  if (rows != sp2.rows || cols != sp2.cols || compressed != sp2.compressed)
1637  return false;
1638 
1639  for (size_type i = 0; i < rows + 1; ++i)
1640  if (rowstart[i] != sp2.rowstart[i])
1641  return false;
1642 
1643  for (size_type i = 0; i < rowstart[rows]; ++i)
1644  if (colnums[i] != sp2.colnums[i])
1645  return false;
1646 
1647  return true;
1648 }
1649 
1650 
1651 
1652 inline bool
1654 {
1655  return (static_cast<const SparsityPatternBase &>(*this) == sp2) &&
1657 }
1658 
1659 
1660 
1661 namespace internal
1662 {
1663  namespace SparsityPatternTools
1664  {
1669 
1670  inline size_type
1672  {
1673  return i;
1674  }
1675 
1676 
1677 
1678  template <typename value>
1679  inline size_type
1680  get_column_index_from_iterator(const std::pair<size_type, value> &i)
1681  {
1682  return i.first;
1683  }
1684 
1685 
1686 
1687  template <typename value>
1688  inline size_type
1689  get_column_index_from_iterator(const std::pair<const size_type, value> &i)
1690  {
1691  return i.first;
1692  }
1693  } // namespace SparsityPatternTools
1694 } // namespace internal
1695 
1696 
1697 
1698 template <typename ForwardIterator>
1699 void
1701  const size_type n_cols,
1702  const ForwardIterator begin,
1703  const ForwardIterator end)
1704 {
1705  Assert(static_cast<size_type>(std::distance(begin, end)) == n_rows,
1706  ExcIteratorRange(std::distance(begin, end), n_rows));
1707 
1708  // first determine row lengths for each row. if the matrix is quadratic,
1709  // then we might have to add an additional entry for the diagonal, if that
1710  // is not yet present. as we have to call compress anyway later on, don't
1711  // bother to check whether that diagonal entry is in a certain row or not
1712  const bool is_square = (n_rows == n_cols);
1713  std::vector<unsigned int> row_lengths;
1714  row_lengths.reserve(n_rows);
1715  for (ForwardIterator i = begin; i != end; ++i)
1716  row_lengths.push_back(std::distance(i->begin(), i->end()) +
1717  (is_square ? 1 : 0));
1718  reinit(n_rows, n_cols, row_lengths);
1719 
1720  // now enter all the elements into the matrix. note that if the matrix is
1721  // quadratic, then we already have the diagonal element preallocated
1722  //
1723  // for use in the inner loop, we define an alias to the type of the inner
1724  // iterators
1725  size_type row = 0;
1726  using inner_iterator =
1727  typename std::iterator_traits<ForwardIterator>::value_type::const_iterator;
1728  for (ForwardIterator i = begin; i != end; ++i, ++row)
1729  {
1730  size_type * cols = &colnums[rowstart[row]] + (is_square ? 1 : 0);
1731  const inner_iterator end_of_row = i->end();
1732  for (inner_iterator j = i->begin(); j != end_of_row; ++j)
1733  {
1734  const size_type col =
1736  AssertIndexRange(col, n_cols);
1737 
1738  if ((col != row) || !is_square)
1739  *cols++ = col;
1740  }
1741  }
1742 
1743  // finally compress everything. this also sorts the entries within each row
1744  compress();
1745 }
1746 
1747 
1748 #endif // DOXYGEN
1749 
1751 
1752 #endif
const types::global_dof_index invalid_size_type
Definition: types.h:200
iterator end() const
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
Definition: matrix_block.h:621
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:541
unsigned int max_row_length
iterator begin() const
Contents is actually a matrix.
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
void load(Archive &ar, const unsigned int version)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1649
types::global_dof_index size_type
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)
bool operator==(const SparsityPatternBase &) const
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
types::global_dof_index size_type
std::unique_ptr< std::size_t[]> rowstart
static ::ExceptionBase & ExcNotCompressed()
static ::ExceptionBase & ExcInvalidIterator()
static ::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
virtual void reinit(const size_type m, const size_type n, const ArrayView< const unsigned int > &row_lengths) override
std::string compress(const std::string &input)
Definition: utilities.cc:392
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:518
Accessor(const ChunkSparsityPattern *matrix, const size_type row)
#define Assert(cond, exc)
Definition: exceptions.h:1419
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:496
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:359
VectorType::value_type * end(VectorType &V)
SparsityPatternIterators::Iterator const_iterator
void load(Archive &ar, const unsigned int version)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
std::size_t n_nonzero_elements() const
MatrixTableIterators::Accessor< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Accessor
Definition: table.h:1907
static ::ExceptionBase & ExcIteratorPastEnd()
std::unique_ptr< size_type[]> colnums
unsigned int global_dof_index
Definition: types.h:76
MatrixTableIterators::Iterator< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Iterator
Definition: table.h:1913
void advance(std::tuple< I1, I2 > &t, const unsigned int n)
bool is_compressed() const
bool operator==(const SparsityPattern &) const
bool stores_only_added_elements() const
void save(Archive &ar, const unsigned int version) const
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:358
VectorType::value_type * begin(VectorType &V)
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
static const size_type invalid_entry
types::global_dof_index size_type
static ::ExceptionBase & ExcIteratorRange(int arg1, int arg2)
size_type column_number(const size_type row, const unsigned int index) const
void save(Archive &ar, const unsigned int version) const
size_type get_column_index_from_iterator(const std::pair< const size_type, value > &i)
unsigned int row_length(const size_type row) const
size_type n_rows() const
const SparsityPatternBase * container
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()
SparsityPatternIterators::Iterator iterator
size_type n_cols() const