16 #ifndef dealii_sparse_matrix_h 17 # define dealii_sparse_matrix_h 20 # include <deal.II/base/config.h> 22 # include <deal.II/base/smartpointer.h> 23 # include <deal.II/base/subscriptor.h> 25 # include <deal.II/lac/exceptions.h> 26 # include <deal.II/lac/identity_matrix.h> 27 # include <deal.II/lac/sparsity_pattern.h> 28 # include <deal.II/lac/vector_operation.h> 29 # ifdef DEAL_II_WITH_MPI 36 DEAL_II_NAMESPACE_OPEN
38 template <
typename number>
40 template <
typename number>
42 template <
typename Matrix>
44 template <
typename number>
46 # ifdef DEAL_II_WITH_MPI 51 template <
typename Number>
58 # ifdef DEAL_II_WITH_TRILINOS 82 template <
typename number,
bool Constness>
95 template <
typename number,
bool Constness>
127 template <
typename number>
179 template <
typename,
bool>
190 template <
typename number>
225 Reference(
const Accessor *accessor,
const bool dummy);
230 operator number()
const;
236 operator=(
const number n)
const;
242 operator+=(
const number n)
const;
248 operator-=(
const number n)
const;
254 operator*=(
const number n)
const;
260 operator/=(
const number n)
const;
314 template <
typename,
bool>
349 template <
typename number,
bool Constness>
497 template <
typename number>
784 template <
typename number2>
786 set(
const std::vector<size_type> &indices,
788 const bool elide_zero_values =
false);
795 template <
typename number2>
797 set(
const std::vector<size_type> &row_indices,
798 const std::vector<size_type> &col_indices,
800 const bool elide_zero_values =
false);
812 template <
typename number2>
815 const std::vector<size_type> &col_indices,
816 const std::vector<number2> & values,
817 const bool elide_zero_values =
false);
828 template <
typename number2>
833 const number2 * values,
834 const bool elide_zero_values =
false);
858 template <
typename number2>
860 add(
const std::vector<size_type> &indices,
862 const bool elide_zero_values =
true);
869 template <
typename number2>
871 add(
const std::vector<size_type> &row_indices,
872 const std::vector<size_type> &col_indices,
874 const bool elide_zero_values =
true);
885 template <
typename number2>
888 const std::vector<size_type> &col_indices,
889 const std::vector<number2> & values,
890 const bool elide_zero_values =
true);
901 template <
typename number2>
906 const number2 * values,
907 const bool elide_zero_values =
true,
908 const bool col_indices_are_sorted =
false);
953 template <
typename somenumber>
973 template <
typename ForwardIterator>
982 template <
typename somenumber>
986 # ifdef DEAL_II_WITH_TRILINOS 1011 template <
typename somenumber>
1098 template <
class OutVector,
class InVector>
1100 vmult(OutVector &dst,
const InVector &src)
const;
1117 template <
class OutVector,
class InVector>
1119 Tvmult(OutVector &dst,
const InVector &src)
const;
1137 template <
class OutVector,
class InVector>
1139 vmult_add(OutVector &dst,
const InVector &src)
const;
1156 template <
class OutVector,
class InVector>
1158 Tvmult_add(OutVector &dst,
const InVector &src)
const;
1177 template <
typename somenumber>
1186 template <
typename somenumber>
1189 const Vector<somenumber> &v)
const;
1200 template <
typename somenumber>
1203 const Vector<somenumber> &x,
1204 const Vector<somenumber> &b)
const;
1241 template <
typename numberB,
typename numberC>
1246 const bool rebuild_sparsity_pattern =
true)
const;
1272 template <
typename numberB,
typename numberC>
1277 const bool rebuild_sparsity_pattern =
true)
const;
1322 template <
typename somenumber>
1325 const Vector<somenumber> &src,
1326 const number omega = 1.)
const;
1334 template <
typename somenumber>
1337 const Vector<somenumber> & src,
1338 const number omega = 1.,
1339 const std::vector<std::size_t> &pos_right_of_diagonal =
1340 std::vector<std::size_t>())
const;
1345 template <
typename somenumber>
1348 const Vector<somenumber> &src,
1349 const number om = 1.)
const;
1354 template <
typename somenumber>
1357 const Vector<somenumber> &src,
1358 const number om = 1.)
const;
1365 template <
typename somenumber>
1367 SSOR(Vector<somenumber> &v,
const number omega = 1.)
const;
1373 template <
typename somenumber>
1375 SOR(Vector<somenumber> &v,
const number om = 1.)
const;
1381 template <
typename somenumber>
1383 TSOR(Vector<somenumber> &v,
const number om = 1.)
const;
1395 template <
typename somenumber>
1397 PSOR(Vector<somenumber> & v,
1398 const std::vector<size_type> &permutation,
1399 const std::vector<size_type> &inverse_permutation,
1400 const number om = 1.)
const;
1412 template <
typename somenumber>
1414 TPSOR(Vector<somenumber> & v,
1415 const std::vector<size_type> &permutation,
1416 const std::vector<size_type> &inverse_permutation,
1417 const number om = 1.)
const;
1424 template <
typename somenumber>
1427 const Vector<somenumber> &b,
1428 const number om = 1.)
const;
1434 template <
typename somenumber>
1437 const Vector<somenumber> &b,
1438 const number om = 1.)
const;
1444 template <
typename somenumber>
1447 const Vector<somenumber> &b,
1448 const number om = 1.)
const;
1454 template <
typename somenumber>
1457 const Vector<somenumber> &b,
1458 const number om = 1.)
const;
1544 template <
class StreamType>
1546 print(StreamType &out,
1547 const bool across =
false,
1548 const bool diagonal_first =
true)
const;
1572 const unsigned int precision = 3,
1573 const bool scientific =
true,
1574 const unsigned int width = 0,
1575 const char * zero_string =
" ",
1576 const double denominator = 1.)
const;
1584 print_pattern(std::ostream &out,
const double threshold = 0.)
const;
1629 <<
"You are trying to access the matrix entry with index <" 1630 << arg1 <<
',' << arg2
1631 <<
">, but this entry does not exist in the sparsity pattern " 1634 "The most common cause for this problem is that you used " 1635 "a method to build the sparsity pattern that did not " 1636 "(completely) take into account all of the entries you " 1637 "will later try to write into. An example would be " 1638 "building a sparsity pattern that does not include " 1639 "the entries you will write into due to constraints " 1640 "on degrees of freedom such as hanging nodes or periodic " 1641 "boundary conditions. In such cases, building the " 1642 "sparsity pattern will succeed, but you will get errors " 1643 "such as the current one at one point or other when " 1644 "trying to write into the entries of the matrix.");
1649 "When copying one sparse matrix into another, " 1650 "or when adding one sparse matrix to another, " 1651 "both matrices need to refer to the same " 1652 "sparsity pattern.");
1659 <<
"The iterators denote a range of " << arg1
1660 <<
" elements, but the given number of rows was " << arg2);
1665 "You are attempting an operation on two matrices that " 1666 "are the same object, but the operation requires that the " 1667 "two objects are in fact different.");
1706 std::unique_ptr<number[]>
val;
1717 template <
typename somenumber>
1719 template <
typename somenumber>
1733 template <
typename,
bool>
1735 template <
typename,
bool>
1738 # ifdef DEAL_II_WITH_MPI 1742 template <
typename Number>
1755 template <
typename number>
1764 template <
typename number>
1774 template <
typename number>
1789 ExcInvalidIndex(i, j));
1798 template <
typename number>
1799 template <
typename number2>
1803 const bool elide_zero_values)
1805 Assert(indices.size() == values.
m(),
1809 for (
size_type i = 0; i < indices.size(); ++i)
1819 template <
typename number>
1820 template <
typename number2>
1823 const std::vector<size_type> &col_indices,
1825 const bool elide_zero_values)
1827 Assert(row_indices.size() == values.
m(),
1829 Assert(col_indices.size() == values.
n(),
1832 for (
size_type i = 0; i < row_indices.size(); ++i)
1842 template <
typename number>
1843 template <
typename number2>
1846 const std::vector<size_type> &col_indices,
1847 const std::vector<number2> & values,
1848 const bool elide_zero_values)
1850 Assert(col_indices.size() == values.size(),
1862 template <
typename number>
1870 if (
value == number())
1880 ExcInvalidIndex(i, j));
1889 template <
typename number>
1890 template <
typename number2>
1894 const bool elide_zero_values)
1896 Assert(indices.size() == values.
m(),
1900 for (
size_type i = 0; i < indices.size(); ++i)
1910 template <
typename number>
1911 template <
typename number2>
1914 const std::vector<size_type> &col_indices,
1916 const bool elide_zero_values)
1918 Assert(row_indices.size() == values.
m(),
1920 Assert(col_indices.size() == values.
n(),
1923 for (
size_type i = 0; i < row_indices.size(); ++i)
1933 template <
typename number>
1934 template <
typename number2>
1937 const std::vector<size_type> &col_indices,
1938 const std::vector<number2> & values,
1939 const bool elide_zero_values)
1941 Assert(col_indices.size() == values.size(),
1953 template <
typename number>
1960 number * val_ptr = val.get();
1961 const number *
const end_ptr = val.get() + cols->n_nonzero_elements();
1963 while (val_ptr != end_ptr)
1964 *val_ptr++ *= factor;
1971 template <
typename number>
1979 const number factor_inv = number(1.) / factor;
1981 number * val_ptr = val.get();
1982 const number *
const end_ptr = val.get() + cols->n_nonzero_elements();
1984 while (val_ptr != end_ptr)
1985 *val_ptr++ *= factor_inv;
1992 template <
typename number>
1993 inline const number &
1998 ExcInvalidIndex(i, j));
1999 return val[cols->operator()(i, j)];
2004 template <
typename number>
2010 ExcInvalidIndex(i, j));
2011 return val[cols->operator()(i, j)];
2016 template <
typename number>
2031 template <
typename number>
2041 return val[cols->rowstart[i]];
2046 template <
typename number>
2056 return val[cols->rowstart[i]];
2061 template <
typename number>
2062 template <
typename ForwardIterator>
2065 const ForwardIterator end)
2067 Assert(static_cast<size_type>(std::distance(begin, end)) == m(),
2068 ExcIteratorRange(std::distance(begin, end), m()));
2072 using inner_iterator =
2073 typename std::iterator_traits<ForwardIterator>::value_type::const_iterator;
2075 for (ForwardIterator i = begin; i != end; ++i, ++
row)
2077 const inner_iterator end_of_row = i->end();
2078 for (inner_iterator j = i->begin(); j != end_of_row; ++j)
2080 set(
row, j->first, j->second);
2090 template <
typename number>
2092 const std::size_t index_within_matrix)
2094 index_within_matrix)
2100 template <
typename number>
2101 inline Accessor<number, true>::Accessor(
const MatrixType *matrix)
2108 template <
typename number>
2109 inline Accessor<number, true>::Accessor(
2112 ,
matrix(&a.get_matrix())
2117 template <
typename number>
2119 Accessor<number, true>::value()
const 2122 return matrix->val[linear_index];
2127 template <
typename number>
2128 inline const typename Accessor<number, true>::MatrixType &
2129 Accessor<number, true>::get_matrix()
const 2136 template <
typename number>
2137 inline Accessor<number, false>::Reference::Reference(
const Accessor *accessor,
2139 : accessor(accessor)
2143 template <
typename number>
2144 inline Accessor<number, false>::Reference::operator number()
const 2147 accessor->matrix->n_nonzero_elements());
2148 return accessor->matrix->val[accessor->linear_index];
2153 template <
typename number>
2154 inline const typename Accessor<number, false>::Reference &
2155 Accessor<number, false>::Reference::operator=(
const number n)
const 2158 accessor->matrix->n_nonzero_elements());
2159 accessor->matrix->val[accessor->linear_index] = n;
2165 template <
typename number>
2166 inline const typename Accessor<number, false>::Reference &
2167 Accessor<number, false>::Reference::operator+=(
const number n)
const 2170 accessor->matrix->n_nonzero_elements());
2171 accessor->matrix->val[accessor->linear_index] += n;
2177 template <
typename number>
2178 inline const typename Accessor<number, false>::Reference &
2179 Accessor<number, false>::Reference::operator-=(
const number n)
const 2182 accessor->matrix->n_nonzero_elements());
2183 accessor->matrix->val[accessor->linear_index] -= n;
2189 template <
typename number>
2190 inline const typename Accessor<number, false>::Reference &
2191 Accessor<number, false>::Reference::operator*=(
const number n)
const 2194 accessor->matrix->n_nonzero_elements());
2195 accessor->matrix->val[accessor->linear_index] *= n;
2201 template <
typename number>
2202 inline const typename Accessor<number, false>::Reference &
2203 Accessor<number, false>::Reference::operator/=(
const number n)
const 2206 accessor->matrix->n_nonzero_elements());
2207 accessor->matrix->val[accessor->linear_index] /= n;
2213 template <
typename number>
2214 inline Accessor<number, false>::Accessor(MatrixType * matrix,
2215 const std::size_t index)
2222 template <
typename number>
2223 inline Accessor<number, false>::Accessor(MatrixType *matrix)
2230 template <
typename number>
2231 inline typename Accessor<number, false>::Reference
2232 Accessor<number, false>::value()
const 2234 return Reference(
this,
true);
2239 template <
typename number>
2240 inline typename Accessor<number, false>::MatrixType &
2241 Accessor<number, false>::get_matrix()
const 2248 template <
typename number,
bool Constness>
2249 inline Iterator<number, Constness>::Iterator(MatrixType * matrix,
2250 const std::size_t index)
2251 : accessor(
matrix, index)
2256 template <
typename number,
bool Constness>
2257 inline Iterator<number, Constness>::Iterator(MatrixType *matrix)
2263 template <
typename number,
bool Constness>
2264 inline Iterator<number, Constness>::Iterator(
2271 template <
typename number,
bool Constness>
2272 inline const Iterator<number, Constness> &
2273 Iterator<number, Constness>::
2282 template <
typename number,
bool Constness>
2283 inline Iterator<number, Constness> &
2284 Iterator<number, Constness>::operator++()
2291 template <
typename number,
bool Constness>
2292 inline Iterator<number, Constness>
2293 Iterator<number, Constness>::operator++(
int)
2301 template <
typename number,
bool Constness>
2309 template <
typename number,
bool Constness>
2310 inline const Accessor<number, Constness> *Iterator<number, Constness>::
2317 template <
typename number,
bool Constness>
2319 Iterator<number, Constness>::operator==(
const Iterator &other)
const 2321 return (accessor == other.accessor);
2325 template <
typename number,
bool Constness>
2327 Iterator<number, Constness>::operator!=(
const Iterator &other)
const 2329 return !(*
this == other);
2333 template <
typename number,
bool Constness>
2335 Iterator<number, Constness>::operator<(
const Iterator &other)
const 2337 Assert(&accessor.get_matrix() == &other.accessor.get_matrix(),
2340 return (accessor < other.accessor);
2344 template <
typename number,
bool Constness>
2346 Iterator<number, Constness>::operator>(
const Iterator &other)
const 2348 return (other < *
this);
2352 template <
typename number,
bool Constness>
2356 Assert(&accessor.get_matrix() == &other.accessor.get_matrix(),
2359 return (*this)->linear_index - other->linear_index;
2364 template <
typename number,
bool Constness>
2365 inline Iterator<number, Constness>
2369 for (size_type i = 0; i < n; ++i)
2379 template <
typename number>
2383 return const_iterator(
this, 0);
2387 template <
typename number>
2391 return const_iterator(
this);
2395 template <
typename number>
2399 return iterator(
this, 0);
2403 template <
typename number>
2407 return iterator(
this, cols->rowstart[cols->rows]);
2411 template <
typename number>
2417 return const_iterator(
this, cols->rowstart[r]);
2422 template <
typename number>
2428 return const_iterator(
this, cols->rowstart[r + 1]);
2433 template <
typename number>
2439 return iterator(
this, cols->rowstart[r]);
2444 template <
typename number>
2450 return iterator(
this, cols->rowstart[r + 1]);
2455 template <
typename number>
2456 template <
class StreamType>
2460 const bool diagonal_first)
const 2465 bool hanging_diagonal =
false;
2468 for (size_type i = 0; i < cols->rows; ++i)
2470 for (size_type j = cols->rowstart[i]; j < cols->rowstart[i + 1]; ++j)
2472 if (!diagonal_first && i == cols->colnums[j])
2475 hanging_diagonal =
true;
2479 if (hanging_diagonal && cols->colnums[j] > i)
2482 out <<
' ' << i <<
',' << i <<
':' <<
diagonal;
2484 out <<
'(' << i <<
',' << i <<
") " <<
diagonal 2486 hanging_diagonal =
false;
2489 out <<
' ' << i <<
',' << cols->colnums[j] <<
':' << val[j];
2491 out <<
"(" << i <<
"," << cols->colnums[j] <<
") " << val[j]
2495 if (hanging_diagonal)
2498 out <<
' ' << i <<
',' << i <<
':' <<
diagonal;
2500 out <<
'(' << i <<
',' << i <<
") " <<
diagonal << std::endl;
2501 hanging_diagonal =
false;
2509 template <
typename number>
2518 template <
typename number>
2530 DEAL_II_NAMESPACE_CLOSE
void PSOR(Vector< somenumber > &v, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const number om=1.) const
void print_formatted(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const unsigned int width=0, const char *zero_string=" ", const double denominator=1.) const
typename Accessor< number, Constness >::MatrixType MatrixType
SparsityPatternIterators::size_type size_type
void Tvmult_add(OutVector &dst, const InVector &src) const
SparseMatrix & operator/=(const number factor)
void precondition_TSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
real_type l1_norm() const
size_type get_row_length(const size_type row) const
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcInvalidIndex(int arg1, int arg2)
types::global_dof_index size_type
typename numbers::NumberTraits< number >::real_type real_type
int operator-(const Iterator &p) const
const_iterator end() const
Contents is actually a matrix.
const Iterator< number, Constness > & operator=(const SparseMatrixIterators::Iterator< number, false > &i)
SparseMatrix< number > & operator=(const SparseMatrix< number > &)
std::size_t n_actually_nonzero_elements(const double threshold=0.) const
std::unique_ptr< number[]> val
const SparseMatrix< number > & get_matrix() const
Iterator(MatrixType *matrix, const std::size_t index_within_matrix)
void set(const size_type i, const size_type j, const number value)
void TSOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
#define AssertIndexRange(index, range)
void block_read(std::istream &in)
somenumber matrix_norm_square(const Vector< somenumber > &v) const
bool operator!=(const Iterator &) const
const Accessor< number, Constness > & operator*() const
void TPSOR(Vector< somenumber > &v, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const number om=1.) const
static ::ExceptionBase & ExcNotInitialized()
void vmult_add(OutVector &dst, const InVector &src) const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator+(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
const Accessor< number, Constness > * operator->() const
static ::ExceptionBase & ExcDifferentSparsityPatterns()
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
virtual void reinit(const SparsityPattern &sparsity)
static ::ExceptionBase & ExcDivideByZero()
LinearAlgebra::distributed::Vector< Number > Vector
void mmult(SparseMatrix< numberC > &C, const SparseMatrix< numberB > &B, const Vector< number > &V=Vector< number >(), const bool rebuild_sparsity_pattern=true) const
void SOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
std::size_t n_nonzero_elements() const
std::size_t memory_consumption() const
void precondition_SOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number om=1.) const
bool operator>(const Iterator &) const
T sum(const T &t, const MPI_Comm &mpi_communicator)
number diag_element(const size_type i) const
Iterator operator+(const size_type n) const
#define Assert(cond, exc)
bool operator<(const Iterator &) const
void vmult(OutVector &dst, const InVector &src) const
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void print(StreamType &out, const bool across=false, const bool diagonal_first=true) const
virtual ~SparseMatrix() override
#define DeclExceptionMsg(Exception, defaulttext)
somenumber matrix_scalar_product(const Vector< somenumber > &u, const Vector< somenumber > &v) const
SmartPointer< const SparsityPattern, SparseMatrix< number > > cols
somenumber residual(Vector< somenumber > &dst, const Vector< somenumber > &x, const Vector< somenumber > &b) const
void Tmmult(SparseMatrix< numberC > &C, const SparseMatrix< numberB > &B, const Vector< number > &V=Vector< number >(), const bool rebuild_sparsity_pattern=true) const
Accessor< number, Constness > accessor
void precondition_SSOR(Vector< somenumber > &dst, const Vector< somenumber > &src, const number omega=1., const std::vector< std::size_t > &pos_right_of_diagonal=std::vector< std::size_t >()) const
static ::ExceptionBase & ExcIteratorRange(int arg1, int arg2)
bool operator==(const Iterator &) const
void SOR(Vector< somenumber > &v, const number om=1.) const
void SSOR(Vector< somenumber > &v, const number omega=1.) const
void add(const size_type i, const size_type j, const number value)
void Jacobi_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
types::global_dof_index size_type
static ::ExceptionBase & ExcNotQuadratic()
unsigned int global_dof_index
const Accessor * accessor
MatrixTableIterators::Iterator< TransposeTable< T >, Constness, MatrixTableIterators::Storage::column_major > Iterator
void SSOR_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
number el(const size_type i, const size_type j) const
void precondition_Jacobi(Vector< somenumber > &dst, const Vector< somenumber > &src, const number omega=1.) const
void TSOR(Vector< somenumber > &v, const number om=1.) const
static const bool zero_addition_can_be_elided
static const size_type invalid_entry
const SparsityPattern & get_sparsity_pattern() const
const_iterator begin() const
SparseMatrix< number > & copy_from(const SparseMatrix< somenumber > &source)
const number & operator()(const size_type i, const size_type j) const
void print_pattern(std::ostream &out, const double threshold=0.) const
real_type frobenius_norm() const
SymmetricTensor< rank_, dim, typename ProductType< Number, OtherNumber >::type > operator-(const SymmetricTensor< rank_, dim, Number > &left, const SymmetricTensor< rank_, dim, OtherNumber > &right)
#define AssertIsFinite(number)
real_type linfty_norm() const
void Tvmult(OutVector &dst, const InVector &src) const
const Accessor< number, Constness > & value_type
void compress(::VectorOperation::values)
static ::ExceptionBase & ExcSourceEqualsDestination()
SparseMatrix & operator*=(const number factor)
static ::ExceptionBase & ExcInternalError()
void block_write(std::ostream &out) const