16 #ifndef dealii_chunk_sparsity_pattern_h 17 #define dealii_chunk_sparsity_pattern_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/subscriptor.h> 24 #include <deal.II/base/vector_slice.h> 26 #include <deal.II/lac/sparsity_pattern.h> 31 DEAL_II_NAMESPACE_OPEN
320 const std::vector<size_type> &row_lengths,
343 const std::vector<size_type> &row_lengths,
390 const std::vector<size_type> &row_lengths,
399 const VectorSlice<
const std::vector<size_type>> &row_lengths,
493 template <
typename ForwardIterator>
497 const ForwardIterator begin,
498 const ForwardIterator end,
506 template <
typename SparsityPatternType>
508 copy_from(
const SparsityPatternType &dsp,
const size_type chunk_size);
517 template <
typename number>
538 template <
typename Sparsity>
540 create_from(
const unsigned int m,
541 const unsigned int n,
542 const Sparsity & sparsity_pattern_for_chunks,
543 const unsigned int chunk_size,
544 const bool optimize_diagonal =
true);
557 get_chunk_size()
const;
565 max_entries_per_row()
const;
630 n_nonzero_elements()
const;
636 is_compressed()
const;
651 stores_only_added_elements()
const;
676 begin(
const unsigned int r)
const;
687 end(
const unsigned int r)
const;
700 block_write(std::ostream &out)
const;
716 block_read(std::istream &in);
724 print(std::ostream &out)
const;
740 print_gnuplot(std::ostream &out)
const;
747 memory_consumption()
const;
758 <<
"The provided number is invalid here: " << arg1);
765 <<
"The given index " << arg1 <<
" should be less than " 773 <<
"Upon entering a new entry to row " << arg1
774 <<
": there was no free entry any more. " << std::endl
775 <<
"(Maximum number of entries for this row: " << arg2
776 <<
"; maybe the matrix is already compressed?)");
783 "The operation you attempted is only allowed after the SparsityPattern " 784 "has been set up and compress() was called.");
790 ExcMatrixIsCompressed,
791 "The operation you attempted changes the structure of the SparsityPattern " 792 "and is not possible after compress() has been called.");
803 <<
"The iterators denote a range of " << arg1
804 <<
" elements, but the given number of rows was " << arg2);
814 <<
"The number of partitions you gave is " << arg1
815 <<
", but must be greater than zero.");
822 <<
"The array has size " << arg1 <<
" but should have size " 868 const unsigned int row)
869 : sparsity_pattern(sparsity_pattern)
871 *sparsity_pattern->sparsity_pattern.end() :
872 *sparsity_pattern->sparsity_pattern.begin(
873 row / sparsity_pattern->get_chunk_size()))
874 ,
chunk_row(row == sparsity_pattern->n_rows() ?
876 row % sparsity_pattern->get_chunk_size())
883 : sparsity_pattern(sparsity_pattern)
884 , reduced_accessor(*sparsity_pattern->sparsity_pattern.
end())
892 Accessor::is_valid_entry()
const 894 return reduced_accessor.is_valid_entry() &&
906 Accessor::row()
const 917 Accessor::column()
const 928 Accessor::reduced_index()
const 932 return reduced_accessor.index_within_sparsity;
938 Accessor::operator==(
const Accessor &other)
const 943 return (reduced_accessor == other.reduced_accessor &&
944 chunk_row == other.chunk_row && chunk_col == other.chunk_col);
950 Accessor::operator<(
const Accessor &other)
const 954 if (chunk_row != other.chunk_row)
956 if (reduced_accessor.index_within_sparsity ==
957 reduced_accessor.sparsity_pattern->n_nonzero_elements())
959 if (other.reduced_accessor.index_within_sparsity ==
960 reduced_accessor.sparsity_pattern->n_nonzero_elements())
964 reduced_accessor.row() +
968 other.reduced_accessor.row() +
970 if (global_row < other_global_row)
972 else if (global_row > other_global_row)
976 return (reduced_accessor.index_within_sparsity <
977 other.reduced_accessor.index_within_sparsity ||
978 (reduced_accessor.index_within_sparsity ==
979 other.reduced_accessor.index_within_sparsity &&
980 chunk_col < other.chunk_col));
988 Assert(chunk_row < chunk_size && chunk_col < chunk_size,
990 Assert(reduced_accessor.row() * chunk_size + chunk_row <
992 reduced_accessor.column() * chunk_size + chunk_col <
997 reduced_accessor.advance();
1004 if (chunk_col == chunk_size ||
1005 reduced_accessor.column() * chunk_size + chunk_col ==
1008 const unsigned int reduced_row = reduced_accessor.row();
1010 if (reduced_accessor.index_within_sparsity + 1 ==
1011 reduced_accessor.sparsity_pattern->rowstart[reduced_row + 1])
1018 if (chunk_row == chunk_size ||
1019 (reduced_row * chunk_size + chunk_row ==
1023 reduced_accessor.advance();
1028 reduced_accessor.index_within_sparsity =
1029 reduced_accessor.sparsity_pattern->rowstart[reduced_row];
1034 reduced_accessor.advance();
1043 const unsigned int row)
1044 : accessor(sparsity_pattern, row)
1050 Iterator::operator++()
1059 Iterator::operator++(
int)
1061 const Iterator iter = *
this;
1075 inline const Accessor *Iterator::operator->()
const 1082 Iterator::operator==(
const Iterator &other)
const 1084 return (accessor == other.accessor);
1090 Iterator::operator!=(
const Iterator &other)
const 1092 return !(accessor == other.accessor);
1097 Iterator::operator<(
const Iterator &other)
const 1099 return accessor < other.accessor;
1170 template <
typename ForwardIterator>
1174 const ForwardIterator
begin,
1175 const ForwardIterator
end,
1178 Assert(static_cast<size_type>(std::distance(begin, end)) == n_rows,
1185 const bool is_square = (n_rows ==
n_cols);
1186 std::vector<size_type> row_lengths;
1187 row_lengths.reserve(n_rows);
1188 for (ForwardIterator i = begin; i !=
end; ++i)
1189 row_lengths.push_back(std::distance(i->begin(), i->end()) +
1190 (is_square ? 1 : 0));
1191 reinit(n_rows, n_cols, row_lengths, chunk_size);
1195 using inner_iterator =
1196 typename std::iterator_traits<ForwardIterator>::value_type::const_iterator;
1197 for (ForwardIterator i = begin; i !=
end; ++i, ++row)
1199 const inner_iterator end_of_row = i->end();
1200 for (inner_iterator j = i->begin(); j != end_of_row; ++j)
1203 internal::SparsityPatternTools::get_column_index_from_iterator(*j);
1217 DEAL_II_NAMESPACE_CLOSE
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end, const size_type chunk_size)
#define DeclException2(Exception2, type1, type2, outsequence)
static::ExceptionBase & ExcInvalidIndex(int arg1, int arg2)
static const size_type invalid_entry
types::global_dof_index size_type
bool is_compressed() const
static::ExceptionBase & ExcMETISNotInstalled()
std::size_t reduced_index() const
bool operator==(const Accessor &) const
const ChunkSparsityPattern * sparsity_pattern
void add(const size_type i, const size_type j)
ChunkSparsityPatternIterators::Iterator iterator
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
SparsityPattern sparsity_pattern
static::ExceptionBase & ExcInvalidIterator()
size_type get_chunk_size() const
static::ExceptionBase & ExcInvalidNumberOfPartitions(int arg1)
#define DeclException1(Exception1, type1, outsequence)
#define Assert(cond, exc)
static::ExceptionBase & ExcInvalidArraySize(int arg1, int arg2)
bool operator<(const Accessor &) const
#define DeclExceptionMsg(Exception, defaulttext)
#define DeclException0(Exception0)
static::ExceptionBase & ExcInvalidNumber(unsigned int arg1)
static::ExceptionBase & ExcIteratorRange(int arg1, int arg2)
SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
static::ExceptionBase & ExcIteratorPastEnd()
Accessor(const ChunkSparsityPattern *matrix, const unsigned int row)
static::ExceptionBase & ExcEmptyObject()
bool is_valid_entry() const
SparsityPatternIterators::Accessor reduced_accessor
void reinit(const size_type m, const size_type n, const size_type max_per_row, const size_type chunk_size)
unsigned int column() const
static::ExceptionBase & ExcInternalError()