16#ifndef dealii_block_sparsity_pattern_h
17#define dealii_block_sparsity_pattern_h
37template <
typename number>
79template <
typename SparsityPatternType>
157 SparsityPatternType &
164 const SparsityPatternType &
239 template <
typename ForwardIterator>
242 ForwardIterator begin,
244 const bool indices_are_sorted =
false);
254 const bool indices_are_sorted =
false)
override;
304 print(std::ostream &out)
const;
341 "The number of rows and columns (returned by n_rows() and n_cols()) does "
342 "not match their directly computed values. This typically means that a "
343 "call to collect_sizes() is missing.");
353 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
354 <<
',' << arg4 <<
"] have differing row numbers.");
363 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
364 <<
',' << arg4 <<
"] have differing column numbers.");
422 template <
typename number>
475 const std::vector<std::vector<unsigned int>> &row_lengths);
574 const std::vector<size_type> &col_block_sizes);
603 reinit(
const std::vector<size_type> &row_block_sizes,
604 const std::vector<size_type> &col_block_sizes);
611 reinit(
const std::vector<IndexSet> &partitioning);
637#ifdef DEAL_II_WITH_TRILINOS
689 const std::vector<size_type> &col_block_sizes);
699 const MPI_Comm communicator = MPI_COMM_WORLD);
713 const std::vector<IndexSet> &row_parallel_partitioning,
714 const std::vector<IndexSet> &column_parallel_partitioning,
715 const std::vector<IndexSet> &writeable_rows,
716 const MPI_Comm communicator = MPI_COMM_WORLD);
728 reinit(
const std::vector<size_type> &row_block_sizes,
729 const std::vector<size_type> &col_block_sizes);
736 reinit(
const std::vector<IndexSet> ¶llel_partitioning,
737 const MPI_Comm communicator = MPI_COMM_WORLD);
745 reinit(
const std::vector<IndexSet> &row_parallel_partitioning,
746 const std::vector<IndexSet> &column_parallel_partitioning,
747 const MPI_Comm communicator = MPI_COMM_WORLD);
758 reinit(
const std::vector<IndexSet> &row_parallel_partitioning,
759 const std::vector<IndexSet> &column_parallel_partitioning,
760 const std::vector<IndexSet> &writeable_rows,
761 const MPI_Comm communicator = MPI_COMM_WORLD);
779template <
typename SparsityPatternType>
780inline SparsityPatternType &
786 return *sub_objects(row, column);
791template <
typename SparsityPatternType>
792inline const SparsityPatternType &
799 return *sub_objects(row, column);
804template <
typename SparsityPatternType>
813template <
typename SparsityPatternType>
817 return column_indices;
822template <
typename SparsityPatternType>
830 const std::pair<size_type, size_type> row_index =
831 row_indices.global_to_local(i),
833 column_indices.global_to_local(j);
834 sub_objects[row_index.first][col_index.first]->add(row_index.second,
840template <
typename SparsityPatternType>
841template <
typename ForwardIterator>
845 ForwardIterator begin,
847 const bool indices_are_sorted)
851 Assert(n_rows() == compute_n_rows(), ExcNeedsCollectSizes());
852 Assert(n_cols() == compute_n_cols(), ExcNeedsCollectSizes());
856 if (indices_are_sorted && n_cols > 0)
858 block_column_indices[0].resize(0);
860 const std::pair<size_type, size_type> row_index =
861 this->row_indices.global_to_local(row);
862 const auto n_blocks = column_indices.size();
867 size_type current_start_index = column_indices.block_start(current_block);
869 current_block == n_blocks - 1 ?
871 column_indices.block_start(current_block + 1);
873 for (
auto it = begin; it < end; ++it)
878 if (*it >= next_start_index)
882 sub_objects[row_index.first][current_block]->add_entries(
884 block_column_indices[0].begin(),
885 block_column_indices[0].end(),
887 block_column_indices[0].clear();
889 auto block_and_col = column_indices.global_to_local(*it);
890 current_block = block_and_col.first;
891 current_start_index = column_indices.block_start(current_block);
893 current_block == n_blocks - 1 ?
895 column_indices.block_start(current_block + 1);
897 const size_type local_index = *it - current_start_index;
898 block_column_indices[0].push_back(local_index);
903 auto check_block_and_col = column_indices.global_to_local(*it);
904 Assert(current_block == check_block_and_col.first,
906 Assert(local_index == check_block_and_col.second,
912 sub_objects[row_index.first][current_block]->add_entries(
914 block_column_indices[0].begin(),
915 block_column_indices[0].end(),
932 if (block_column_indices[0].size() < n_cols)
933 for (
size_type i = 0; i < this->n_block_cols(); ++i)
934 block_column_indices[i].resize(n_cols);
938 for (
size_type i = 0; i < this->n_block_cols(); ++i)
939 counter_within_block[i] = 0;
950 for (ForwardIterator it = begin; it != end; ++it)
954 const std::pair<size_type, size_type> col_index =
955 this->column_indices.global_to_local(col);
957 const size_type local_index = counter_within_block[col_index.first]++;
959 block_column_indices[col_index.first][local_index] = col_index.second;
967 const std::pair<size_type, size_type> row_index =
968 this->row_indices.global_to_local(row);
969 for (
size_type block_col = 0; block_col < n_block_cols(); ++block_col)
971 if (counter_within_block[block_col] == 0)
973 sub_objects[row_index.first][block_col]->add_entries(
975 block_column_indices[block_col].begin(),
976 block_column_indices[block_col].begin() +
977 counter_within_block[block_col],
985template <
typename SparsityPatternType>
990 const bool indices_are_sorted)
992 add_entries(row, columns.
begin(), columns.
end(), indices_are_sorted);
997template <
typename SparsityPatternType>
1005 const std::pair<size_type, size_type> row_index =
1006 row_indices.global_to_local(i),
1008 column_indices.global_to_local(j);
1009 return sub_objects[row_index.first][col_index.first]->exists(
1010 row_index.second, col_index.second);
1015template <
typename SparsityPatternType>
1020 const std::pair<size_type, size_type> row_index =
1021 row_indices.global_to_local(row);
1025 for (
size_type b = 0; b < n_block_rows(); ++b)
1026 c += sub_objects[row_index.first][b]->row_length(row_index.second);
1033template <
typename SparsityPatternType>
1037 return block_columns;
1042template <
typename SparsityPatternType>
1052 const unsigned int index)
const
1055 const std::pair<size_type, size_type> row_index =
1062 for (
unsigned int b = 0; b < this->
n_block_cols(); ++b)
1064 unsigned int rowlen =
1065 sub_objects[row_index.first][b]->row_length(row_index.second);
1066 if (index < c + rowlen)
1068 sub_objects[row_index.first][b]->column_number(row_index.second,
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
BlockDynamicSparsityPattern()=default
size_type column_number(const size_type row, const unsigned int index) const
std::pair< unsigned int, size_type > global_to_local(const size_type i) const
void print_gnuplot(std::ostream &out) const
static const size_type invalid_entry
const SparsityPatternType & block(const size_type row, const size_type column) const
std::vector< size_type > counter_within_block
size_type n_block_rows() const
BlockSparsityPatternBase()
Table< 2, std::unique_ptr< SparsityPatternType > > sub_objects
SparsityPatternType & block(const size_type row, const size_type column)
types::global_dof_index size_type
std::vector< std::vector< size_type > > block_column_indices
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_sorted=false)
const BlockIndices & get_column_indices() const
size_type n_nonzero_elements() const
void print(std::ostream &out) const
std::size_t memory_consumption() const
void print_svg(std::ostream &out) const
size_type max_entries_per_row() const
size_type compute_n_rows() const
void reinit(const size_type n_block_rows, const size_type n_block_columns)
size_type n_block_cols() const
BlockIndices column_indices
const BlockIndices & get_row_indices() const
unsigned int row_length(const size_type row) const
virtual void add_row_entries(const size_type &row, const ArrayView< const size_type > &columns, const bool indices_are_sorted=false) override
void add(const size_type i, const size_type j)
bool exists(const size_type i, const size_type j) const
BlockSparsityPatternBase & operator=(const BlockSparsityPatternBase &)
size_type compute_n_cols() const
void copy_from(const BlockDynamicSparsityPattern &dsp)
void reinit(const size_type n_block_rows, const size_type n_block_columns)
BlockSparsityPattern()=default
bool is_compressed() const
virtual void add_entries(const ArrayView< const std::pair< size_type, size_type > > &entries)
static constexpr size_type invalid_entry
BlockSparsityPattern()=default
void reinit(const std::vector< size_type > &row_block_sizes, const std::vector< size_type > &col_block_sizes)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNeedsCollectSizes()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcIncompatibleColNumbers(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
const types::global_dof_index invalid_dof_index
unsigned int global_dof_index