16 #ifndef dealii_chunk_sparse_matrix_h 17 # define dealii_chunk_sparse_matrix_h 36 template <
typename number>
38 template <
typename number>
53 template <
typename number,
bool Constness>
66 template <
typename number,
bool Constness>
98 template <
typename number>
148 template <
typename,
bool>
159 template <
typename number>
197 operator number()
const;
203 operator=(
const number n)
const;
209 operator+=(
const number n)
const;
215 operator-=(
const number n)
const;
221 operator*=(
const number n)
const;
227 operator/=(
const number n)
const;
279 template <
typename,
bool>
295 template <
typename number,
bool Constness>
422 template <
typename number>
474 static const bool zero_addition_can_be_elided =
true;
564 operator=(
const double d);
621 n_nonzero_elements()
const;
631 n_actually_nonzero_elements()
const;
642 get_sparsity_pattern()
const;
681 template <
typename number2>
686 const number2 * values,
687 const bool elide_zero_values =
true,
688 const bool col_indices_are_sorted =
false);
694 operator*=(
const number factor);
700 operator/=(
const number factor);
733 template <
typename somenumber>
754 template <
typename ForwardIterator>
756 copy_from(
const ForwardIterator
begin,
const ForwardIterator
end);
763 template <
typename somenumber>
778 template <
typename somenumber>
845 number * values)
const;
866 template <
class OutVector,
class InVector>
868 vmult(OutVector &dst,
const InVector &src)
const;
885 template <
class OutVector,
class InVector>
887 Tvmult(OutVector &dst,
const InVector &src)
const;
903 template <
class OutVector,
class InVector>
905 vmult_add(OutVector &dst,
const InVector &src)
const;
922 template <
class OutVector,
class InVector>
924 Tvmult_add(OutVector &dst,
const InVector &src)
const;
941 template <
typename somenumber>
943 matrix_norm_square(
const Vector<somenumber> &v)
const;
948 template <
typename somenumber>
950 matrix_scalar_product(
const Vector<somenumber> &u,
951 const Vector<somenumber> &v)
const;
959 template <
typename somenumber>
961 residual(Vector<somenumber> & dst,
962 const Vector<somenumber> &x,
963 const Vector<somenumber> &
b)
const;
996 frobenius_norm()
const;
1008 template <
typename somenumber>
1010 precondition_Jacobi(Vector<somenumber> & dst,
1011 const Vector<somenumber> &src,
1012 const number omega = 1.)
const;
1017 template <
typename somenumber>
1019 precondition_SSOR(Vector<somenumber> & dst,
1020 const Vector<somenumber> &src,
1021 const number om = 1.)
const;
1026 template <
typename somenumber>
1028 precondition_SOR(Vector<somenumber> & dst,
1029 const Vector<somenumber> &src,
1030 const number om = 1.)
const;
1035 template <
typename somenumber>
1037 precondition_TSOR(Vector<somenumber> & dst,
1038 const Vector<somenumber> &src,
1039 const number om = 1.)
const;
1046 template <
typename somenumber>
1048 SSOR(Vector<somenumber> &v,
const number omega = 1.)
const;
1054 template <
typename somenumber>
1056 SOR(Vector<somenumber> &v,
const number om = 1.)
const;
1062 template <
typename somenumber>
1064 TSOR(Vector<somenumber> &v,
const number om = 1.)
const;
1076 template <
typename somenumber>
1078 PSOR(Vector<somenumber> & v,
1079 const std::vector<size_type> &permutation,
1080 const std::vector<size_type> &inverse_permutation,
1081 const number om = 1.)
const;
1093 template <
typename somenumber>
1095 TPSOR(Vector<somenumber> & v,
1096 const std::vector<size_type> &permutation,
1097 const std::vector<size_type> &inverse_permutation,
1098 const number om = 1.)
const;
1104 template <
typename somenumber>
1106 SOR_step(Vector<somenumber> & v,
1107 const Vector<somenumber> &
b,
1108 const number om = 1.)
const;
1114 template <
typename somenumber>
1116 TSOR_step(Vector<somenumber> & v,
1117 const Vector<somenumber> &
b,
1118 const number om = 1.)
const;
1124 template <
typename somenumber>
1126 SSOR_step(Vector<somenumber> & v,
1127 const Vector<somenumber> &
b,
1128 const number om = 1.)
const;
1196 begin(
const unsigned int r)
const;
1213 end(
const unsigned int r)
const;
1230 begin(
const unsigned int r);
1247 end(
const unsigned int r);
1259 print(std::ostream &out)
const;
1282 print_formatted(std::ostream & out,
1283 const unsigned int precision = 3,
1284 const bool scientific =
true,
1285 const unsigned int width = 0,
1286 const char * zero_string =
" ",
1287 const double denominator = 1.)
const;
1295 print_pattern(std::ostream &out,
const double threshold = 0.)
const;
1308 block_write(std::ostream &out)
const;
1327 block_read(std::istream &in);
1340 <<
"You are trying to access the matrix entry with index <" 1341 << arg1 <<
',' << arg2
1342 <<
">, but this entry does not exist in the sparsity pattern " 1345 "The most common cause for this problem is that you used " 1346 "a method to build the sparsity pattern that did not " 1347 "(completely) take into account all of the entries you " 1348 "will later try to write into. An example would be " 1349 "building a sparsity pattern that does not include " 1350 "the entries you will write into due to constraints " 1351 "on degrees of freedom such as hanging nodes or periodic " 1352 "boundary conditions. In such cases, building the " 1353 "sparsity pattern will succeed, but you will get errors " 1354 "such as the current one at one point or other when " 1355 "trying to write into the entries of the matrix.");
1366 <<
"The iterators denote a range of " << arg1
1367 <<
" elements, but the given number of rows was " << arg2);
1372 "You are attempting an operation on two matrices that " 1373 "are the same object, but the operation requires that the " 1374 "two objects are in fact different.");
1391 std::unique_ptr<number[]>
val;
1408 template <
typename somenumber>
1412 template <
typename,
bool>
1414 template <
typename,
bool>
1425 template <
typename number>
1434 template <
typename number>
1444 template <
typename number>
1454 template <
typename number>
1461 cols->sparsity_pattern(i / chunk_size, j / chunk_size);
1467 return (chunk_index * chunk_size * chunk_size +
1468 (i % chunk_size) * chunk_size + (j % chunk_size));
1473 template <
typename number>
1484 const size_type index = compute_location(i, j);
1486 ExcInvalidIndex(i, j));
1494 template <
typename number>
1504 if (std::abs(value) != 0.)
1506 const size_type index = compute_location(i, j);
1508 ExcInvalidIndex(i, j));
1510 val[index] +=
value;
1516 template <
typename number>
1517 template <
typename number2>
1522 const number2 * values,
1527 for (
size_type col = 0; col < n_cols; ++col)
1528 add(row, col_indices[col], static_cast<number>(values[col]));
1533 template <
typename number>
1540 const size_type chunk_size = cols->get_chunk_size();
1546 number * val_ptr = val.get();
1547 const number *
const end_ptr =
1549 cols->sparsity_pattern.n_nonzero_elements() * chunk_size *
chunk_size;
1550 while (val_ptr != end_ptr)
1551 *val_ptr++ *= factor;
1558 template <
typename number>
1566 const number factor_inv = 1. / factor;
1568 const size_type chunk_size = cols->get_chunk_size();
1574 number * val_ptr = val.get();
1575 const number *
const end_ptr =
1577 cols->sparsity_pattern.n_nonzero_elements() * chunk_size *
chunk_size;
1579 while (val_ptr != end_ptr)
1580 *val_ptr++ *= factor_inv;
1587 template <
typename number>
1594 ExcInvalidIndex(i, j));
1595 return val[compute_location(i, j)];
1600 template <
typename number>
1605 const size_type index = compute_location(i, j);
1615 template <
typename number>
1625 const size_type chunk_size = cols->get_chunk_size();
1626 return val[cols->sparsity_pattern.rowstart[i /
chunk_size] * chunk_size *
1628 (i %
chunk_size) * chunk_size + (i % chunk_size)];
1633 template <
typename number>
1634 template <
typename ForwardIterator>
1637 const ForwardIterator
end)
1639 Assert(static_cast<size_type>(std::distance(begin, end)) == m(),
1640 ExcIteratorRange(std::distance(begin, end), m()));
1644 using inner_iterator =
1645 typename std::iterator_traits<ForwardIterator>::value_type::const_iterator;
1647 for (ForwardIterator i = begin; i !=
end; ++i, ++
row)
1649 const inner_iterator end_of_row = i->end();
1650 for (inner_iterator j = i->begin(); j != end_of_row; ++j)
1652 set(row, j->first, j->second);
1663 template <
typename number>
1665 const unsigned int row)
1673 template <
typename number>
1681 template <
typename number>
1685 ,
matrix(&a.get_matrix())
1690 template <
typename number>
1694 const unsigned int chunk_size =
1695 matrix->get_sparsity_pattern().get_chunk_size();
1696 return matrix->val[reduced_index() * chunk_size * chunk_size +
1697 chunk_row * chunk_size + chunk_col];
1702 template <
typename number>
1703 inline const typename Accessor<number, true>::MatrixType &
1704 Accessor<number, true>::get_matrix()
const 1711 template <
typename number>
1712 inline Accessor<number, false>::Reference::Reference(
const Accessor *accessor,
1714 : accessor(accessor)
1718 template <
typename number>
1719 inline Accessor<number, false>::Reference::operator number()
const 1721 const unsigned int chunk_size =
1722 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1723 return accessor->matrix
1724 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1725 accessor->chunk_row * chunk_size + accessor->chunk_col];
1730 template <
typename number>
1731 inline const typename Accessor<number, false>::Reference &
1732 Accessor<number, false>::Reference::operator=(
const number
n)
const 1734 const unsigned int chunk_size =
1735 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1737 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1738 accessor->chunk_row * chunk_size + accessor->chunk_col] =
n;
1744 template <
typename number>
1745 inline const typename Accessor<number, false>::Reference &
1746 Accessor<number, false>::Reference::operator+=(
const number n)
const 1748 const unsigned int chunk_size =
1749 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1751 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1752 accessor->chunk_row * chunk_size + accessor->chunk_col] +=
n;
1758 template <
typename number>
1759 inline const typename Accessor<number, false>::Reference &
1760 Accessor<number, false>::Reference::operator-=(
const number n)
const 1762 const unsigned int chunk_size =
1763 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1765 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1766 accessor->chunk_row * chunk_size + accessor->chunk_col] -=
n;
1772 template <
typename number>
1773 inline const typename Accessor<number, false>::Reference &
1774 Accessor<number, false>::Reference::operator*=(
const number n)
const 1776 const unsigned int chunk_size =
1777 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1779 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1780 accessor->chunk_row * chunk_size + accessor->chunk_col] *=
n;
1786 template <
typename number>
1787 inline const typename Accessor<number, false>::Reference &
1788 Accessor<number, false>::Reference::operator/=(
const number n)
const 1790 const unsigned int chunk_size =
1791 accessor->matrix->get_sparsity_pattern().get_chunk_size();
1793 ->val[accessor->reduced_index() * chunk_size * chunk_size +
1794 accessor->chunk_row * chunk_size + accessor->chunk_col] /=
n;
1800 template <
typename number>
1802 const unsigned int row)
1810 template <
typename number>
1818 template <
typename number>
1819 inline typename Accessor<number, false>::Reference
1822 return Reference(
this,
true);
1827 template <
typename number>
1828 inline typename Accessor<number, false>::MatrixType &
1829 Accessor<number, false>::get_matrix()
const 1836 template <
typename number,
bool Constness>
1838 const unsigned int row)
1839 : accessor(matrix, row)
1844 template <
typename number,
bool Constness>
1851 template <
typename number,
bool Constness>
1859 template <
typename number,
bool Constness>
1860 inline Iterator<number, Constness> &
1868 template <
typename number,
bool Constness>
1869 inline Iterator<number, Constness>
1878 template <
typename number,
bool Constness>
1886 template <
typename number,
bool Constness>
1887 inline const Accessor<number, Constness> *Iterator<number, Constness>::
1894 template <
typename number,
bool Constness>
1898 return (accessor == other.accessor);
1902 template <
typename number,
bool Constness>
1906 return !(*
this == other);
1910 template <
typename number,
bool Constness>
1914 Assert(&accessor.get_matrix() == &other.accessor.get_matrix(),
1917 return (accessor < other.accessor);
1921 template <
typename number,
bool Constness>
1925 return (other < *
this);
1929 template <
typename number,
bool Constness>
1933 Assert(&accessor.get_matrix() == &other.accessor.get_matrix(),
1941 while (copy != other)
1950 while (copy != *
this)
1961 template <
typename number,
bool Constness>
1962 inline Iterator<number, Constness>
1966 for (
unsigned int i = 0; i <
n; ++i)
1976 template <
typename number>
1984 template <
typename number>
1992 template <
typename number>
2000 template <
typename number>
2008 template <
typename number>
2018 template <
typename number>
2028 template <
typename number>
2038 template <
typename number>
typename numbers::NumberTraits< number >::real_type real_type
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
#define DeclException2(Exception2, type1, type2, outsequence)
Contents is actually a matrix.
constexpr SymmetricTensor< 2, dim, Number > symmetrize(const Tensor< 2, dim, Number > &t)
ChunkSparseMatrix< number > & copy_from(const ChunkSparseMatrix< somenumber > &source)
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
#define AssertIndexRange(index, range)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)
static ::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
std::unique_ptr< number[]> val
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
static ::ExceptionBase & ExcDivideByZero()
const ChunkSparseMatrix< number > & get_matrix() const
ChunkSparseMatrixIterators::Iterator< number, false > iterator
Accessor< number, Constness > accessor
const Accessor * accessor
Accessor(const ChunkSparsityPattern *matrix, const size_type row)
const_iterator begin() const
number operator()(const size_type i, const size_type j) const
#define Assert(cond, exc)
constexpr SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
ChunkSparseMatrix & operator*=(const number factor)
size_type compute_location(const size_type i, const size_type j) const
#define DeclExceptionMsg(Exception, defaulttext)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
#define DeclException0(Exception0)
#define DEAL_II_NAMESPACE_CLOSE
VectorType::value_type * end(VectorType &V)
SynchronousIterators< Iterators > operator++(SynchronousIterators< Iterators > &a)
ChunkSparseMatrixIterators::Iterator< number, true > const_iterator
Expression operator>(const Expression &lhs, const Expression &rhs)
number el(const size_type i, const size_type j) const
const types::global_dof_index * dummy()
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SmartPointer< const ChunkSparsityPattern, ChunkSparseMatrix< number > > cols
MatrixTableIterators::Accessor< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Accessor
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
static ::ExceptionBase & ExcNotQuadratic()
number diag_element(const size_type i) const
unsigned int global_dof_index
MatrixTableIterators::Iterator< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Iterator
const_iterator end() const
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
const ChunkSparsityPattern & get_sparsity_pattern() const
Number l1_norm(const Tensor< 2, dim, Number > &t)
ChunkSparseMatrix & operator/=(const number factor)
const Accessor< number, Constness > & value_type
void set(const size_type i, const size_type j, const number value)
static const size_type invalid_entry
static const size_type invalid_entry
bool operator<(const Accessor &) const
std::enable_if< std::is_floating_point< T >::value &&std::is_floating_point< U >::value, typename ProductType< std::complex< T >, std::complex< U > >::type >::type operator*(const std::complex< T > &left, const std::complex< U > &right)
void add(const size_type i, const size_type j, const number value)
typename Accessor< number, Constness >::MatrixType MatrixType
void copy(const T *begin, const T *end, U *dest)
#define AssertIsFinite(number)
bool operator==(const Accessor &) const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()