16 #ifndef dealii_sparsity_pattern_h 17 #define dealii_sparsity_pattern_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/std_cxx14/memory.h> 24 #include <deal.II/base/subscriptor.h> 28 #include <boost/version.hpp> 29 #if BOOST_VERSION >= 106400 30 # include <boost/serialization/array_wrapper.hpp> 32 # include <boost/serialization/array.hpp> 34 #include <boost/serialization/split_member.hpp> 40 DEAL_II_NAMESPACE_OPEN
45 template <
typename number>
47 template <
typename number>
49 template <
typename number>
51 template <
typename number>
53 template <
typename VectorType>
68 namespace SparsityPatternTools
81 get_column_index_from_iterator(
const size_type i);
88 template <
typename value>
90 get_column_index_from_iterator(
const std::pair<size_type, value> &i);
97 template <
typename value>
99 get_column_index_from_iterator(
const std::pair<const size_type, value> &i);
138 const std::size_t index_within_sparsity);
170 global_index()
const;
189 is_valid_entry()
const;
274 const std::size_t index_within_sparsity);
451 const unsigned int max_per_row);
464 const std::vector<unsigned int> &row_lengths);
484 const std::vector<unsigned int> &row_lengths);
509 const unsigned int max_per_row,
554 const std::vector<unsigned int> &row_lengths);
563 const VectorSlice<
const std::vector<unsigned int>> &row_lengths);
657 template <
typename ForwardIterator>
661 const ForwardIterator begin,
662 const ForwardIterator end);
685 template <
typename number>
714 template <
typename ForwardIterator>
717 ForwardIterator begin,
719 const bool indices_are_sorted =
false);
797 max_entries_per_row()
const;
820 n_nonzero_elements()
const;
826 is_compressed()
const;
861 stores_only_added_elements()
const;
868 memory_consumption()
const;
911 std::pair<size_type, size_type>
912 matrix_position(
const std::size_t global_index)
const;
941 column_number(
const size_type row,
const unsigned int index)
const;
960 block_write(std::ostream &out)
const;
976 block_read(std::istream &in);
984 print(std::ostream &out)
const;
1000 print_gnuplot(std::ostream &out)
const;
1010 print_svg(std::ostream &out)
const;
1017 template <
class Archive>
1019 save(Archive &ar,
const unsigned int version)
const;
1025 template <
class Archive>
1027 load(Archive &ar,
const unsigned int version);
1029 BOOST_SERIALIZATION_SPLIT_MEMBER()
1043 << "Upon entering a new entry to row " << arg1
1044 << ": there was no free entry any more. " <<
std::endl
1045 << "(Maximum number of entries for this row: " << arg2
1046 << "; maybe the matrix is already compressed?)");
1053 "The operation you attempted is only allowed after the
SparsityPattern "
1054 "has been set up and compress() was called.");
1060 ExcMatrixIsCompressed,
1061 "The operation you attempted changes the structure of the
SparsityPattern "
1062 "and is not possible after compress() has been called.");
1069 << "The iterators denote a range of " << arg1
1070 << " elements, but the given number of rows was " << arg2);
1076 << "The number of partitions you gave is " << arg1
1077 << ", but must be greater than zero.");
1113 unsigned int max_row_length;
1162 bool store_diagonal_first_in_row;
1167 template <typename number>
1169 template <typename number>
1171 template <typename number>
1173 template <typename number>
1196 const std::size_t i)
1197 : sparsity_pattern(sparsity_pattern)
1198 , index_within_sparsity(i)
1204 : sparsity_pattern(sparsity_pattern)
1205 , index_within_sparsity(sparsity_pattern->
rowstart[sparsity_pattern->
rows])
1213 return (index_within_sparsity <
1215 sparsity_pattern->
colnums[index_within_sparsity] !=
1226 const std::size_t *insert_point =
1227 std::upper_bound(sparsity_pattern->
rowstart.get(),
1229 sparsity_pattern->
rows + 1,
1230 index_within_sparsity);
1231 return insert_point - sparsity_pattern->
rowstart.get() - 1;
1241 return (sparsity_pattern->
colnums[index_within_sparsity]);
1247 Accessor::index()
const 1251 return index_within_sparsity - sparsity_pattern->
rowstart[row()];
1257 Accessor::global_index()
const 1261 return index_within_sparsity;
1269 return (sparsity_pattern == other.sparsity_pattern &&
1270 index_within_sparsity == other.index_within_sparsity);
1280 return index_within_sparsity < other.index_within_sparsity;
1287 Assert(index_within_sparsity <
1290 ++index_within_sparsity;
1296 const std::size_t i)
1297 : accessor(sparsity_pattern, i)
1314 const Iterator iter = *
this;
1337 return (accessor == other.accessor);
1345 return !(*
this == other);
1353 return accessor < other.accessor;
1361 Assert(accessor.sparsity_pattern == other.accessor.sparsity_pattern,
1364 return (*this)->index_within_sparsity - other->index_within_sparsity;
1373 return iterator(
this, rowstart[0]);
1381 return iterator(
this, rowstart[rows]);
1389 Assert(r < n_rows(), ExcIndexRangeType<size_type>(r, 0, n_rows()));
1391 return iterator(
this, rowstart[r]);
1399 Assert(r < n_rows(), ExcIndexRangeType<size_type>(r, 0, n_rows()));
1401 return iterator(
this, rowstart[r + 1]);
1433 return (store_diagonal_first_in_row ==
false);
1441 Assert(row < rows, ExcIndexRangeType<size_type>(row, 0, rows));
1442 return rowstart[row + 1] - rowstart[row];
1449 const unsigned int index)
const 1451 Assert(row < rows, ExcIndexRangeType<size_type>(row, 0, rows));
1454 return colnums[rowstart[row] + index];
1462 Assert(compressed, ExcNotCompressed());
1464 if ((rowstart !=
nullptr) && (colnums !=
nullptr))
1465 return rowstart[rows] - rowstart[0];
1473 template <
class Archive>
1480 ar &max_dim &rows &cols &max_vec_len &max_row_length &compressed
1481 &store_diagonal_first_in_row;
1483 ar &boost::serialization::make_array(rowstart.get(), max_dim + 1);
1484 ar &boost::serialization::make_array(colnums.get(), max_vec_len);
1489 template <
class Archive>
1496 ar &max_dim &rows &cols &max_vec_len &max_row_length &compressed
1497 &store_diagonal_first_in_row;
1499 rowstart = std_cxx14::make_unique<std::size_t[]>(max_dim + 1);
1500 colnums = std_cxx14::make_unique<size_type[]>(max_vec_len);
1502 ar &boost::serialization::make_array(rowstart.get(), max_dim + 1);
1503 ar &boost::serialization::make_array(colnums.get(), max_vec_len);
1519 for (
size_type i = 0; i < rows + 1; ++i)
1520 if (rowstart[i] != sp2.
rowstart[i])
1523 for (
size_type i = 0; i < rowstart[rows]; ++i)
1524 if (colnums[i] != sp2.
colnums[i])
1534 namespace SparsityPatternTools
1542 get_column_index_from_iterator(
const size_type i)
1549 template <
typename value>
1551 get_column_index_from_iterator(
const std::pair<size_type, value> &i)
1558 template <
typename value>
1560 get_column_index_from_iterator(
const std::pair<const size_type, value> &i)
1569 template <
typename ForwardIterator>
1573 const ForwardIterator begin,
1574 const ForwardIterator end)
1576 Assert(static_cast<size_type>(std::distance(begin, end)) == n_rows,
1577 ExcIteratorRange(std::distance(begin, end), n_rows));
1583 const bool is_square = (n_rows == n_cols);
1584 std::vector<unsigned int> row_lengths;
1585 row_lengths.reserve(n_rows);
1586 for (ForwardIterator i = begin; i != end; ++i)
1587 row_lengths.push_back(std::distance(i->begin(), i->end()) +
1588 (is_square ? 1 : 0));
1589 reinit(n_rows, n_cols, row_lengths);
1597 using inner_iterator =
1598 typename std::iterator_traits<ForwardIterator>::value_type::const_iterator;
1599 for (ForwardIterator i = begin; i != end; ++i, ++row)
1601 size_type * cols = &colnums[rowstart[row]] + (is_square ? 1 : 0);
1602 const inner_iterator end_of_row = i->end();
1603 for (inner_iterator j = i->begin(); j != end_of_row; ++j)
1606 internal::SparsityPatternTools::get_column_index_from_iterator(*j);
1609 if ((col != row) || !is_square)
1621 DEAL_II_NAMESPACE_CLOSE
const types::global_dof_index invalid_size_type
std::size_t index_within_sparsity
#define DeclException2(Exception2, type1, type2, outsequence)
Iterator(const ChunkSparsityPattern *sp, const unsigned int row)
static const size_type invalid_entry
void save(Archive &ar, const unsigned int version) const
types::global_dof_index size_type
bool operator==(const Accessor &) const
const Accessor * operator->() const
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
unsigned long long int global_dof_index
std::unique_ptr< size_type[]> colnums
static::ExceptionBase & ExcInvalidIterator()
static::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
#define DeclException1(Exception1, type1, outsequence)
#define Assert(cond, exc)
bool operator<(const Accessor &) const
#define DeclExceptionMsg(Exception, defaulttext)
unsigned int row_length(const size_type row) const
size_type column_number(const size_type row, const unsigned int index) const
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
bool stores_only_added_elements() const
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)
bool operator<(const Iterator &) const
types::global_dof_index size_type
types::global_dof_index size_type
static::ExceptionBase & ExcIteratorPastEnd()
Accessor(const ChunkSparsityPattern *matrix, const unsigned int row)
bool operator==(const Iterator &) const
bool store_diagonal_first_in_row
const SparsityPattern * sparsity_pattern
std::unique_ptr< std::size_t[]> rowstart
bool operator==(const SparsityPattern &) const
bool is_valid_entry() const
bool operator!=(const Iterator &) const
bool is_compressed() const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
std::size_t n_nonzero_elements() const
const Accessor & operator*() const
unsigned int column() const
static::ExceptionBase & ExcInternalError()