16 #ifndef dealii_sparse_matrix_h 17 #define dealii_sparse_matrix_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/subscriptor.h> 22 #include <deal.II/base/smartpointer.h> 23 #include <deal.II/lac/sparsity_pattern.h> 24 #include <deal.II/lac/identity_matrix.h> 25 #include <deal.II/lac/exceptions.h> 26 #include <deal.II/lac/vector_operation.h> 27 #ifdef DEAL_II_WITH_MPI 34 DEAL_II_NAMESPACE_OPEN
36 template <
typename number>
class Vector;
39 template <
typename number>
class SparseILU;
40 #ifdef DEAL_II_WITH_MPI 50 #ifdef DEAL_II_WITH_TRILINOS 74 template <
typename number,
bool Constness>
87 template <
typename number,
bool Constness>
116 template <
typename number>
130 const std::size_t index_within_matrix);
145 number
value()
const;
167 template <
typename,
bool>
178 template <
typename number>
213 Reference (
const Accessor *accessor,
219 operator number ()
const;
224 const Reference &operator = (
const number n)
const;
229 const Reference &operator += (
const number n)
const;
234 const Reference &operator -= (
const number n)
const;
239 const Reference &operator *= (
const number n)
const;
244 const Reference &operator /= (
const number n)
const;
265 const std::size_t
index);
275 Reference
value()
const;
297 template <
typename,
bool>
332 template <
typename number,
bool Constness>
355 const std::size_t index_within_matrix);
470 template <
typename number>
653 virtual void clear ();
750 template <
typename number2>
751 void set (
const std::vector<size_type> &indices,
753 const bool elide_zero_values =
false);
760 template <
typename number2>
761 void set (
const std::vector<size_type> &row_indices,
762 const std::vector<size_type> &col_indices,
764 const bool elide_zero_values =
false);
776 template <
typename number2>
778 const std::vector<size_type> &col_indices,
779 const std::vector<number2> &values,
780 const bool elide_zero_values =
false);
791 template <
typename number2>
795 const number2 *values,
796 const bool elide_zero_values =
false);
821 template <
typename number2>
822 void add (
const std::vector<size_type> &indices,
824 const bool elide_zero_values =
true);
831 template <
typename number2>
832 void add (
const std::vector<size_type> &row_indices,
833 const std::vector<size_type> &col_indices,
835 const bool elide_zero_values =
true);
846 template <
typename number2>
848 const std::vector<size_type> &col_indices,
849 const std::vector<number2> &values,
850 const bool elide_zero_values =
true);
861 template <
typename number2>
865 const number2 *values,
866 const bool elide_zero_values =
true,
867 const bool col_indices_are_sorted =
false);
909 template <
typename somenumber>
929 template <
typename ForwardIterator>
931 const ForwardIterator
end);
938 template <
typename somenumber>
941 #ifdef DEAL_II_WITH_TRILINOS 966 template <
typename somenumber>
967 void add (
const number factor,
1051 template <
class OutVector,
class InVector>
1052 void vmult (OutVector &dst,
1053 const InVector &src)
const;
1070 template <
class OutVector,
class InVector>
1071 void Tvmult (OutVector &dst,
1072 const InVector &src)
const;
1090 template <
class OutVector,
class InVector>
1092 const InVector &src)
const;
1109 template <
class OutVector,
class InVector>
1111 const InVector &src)
const;
1130 template <
typename somenumber>
1138 template <
typename somenumber>
1140 const Vector<somenumber> &v)
const;
1151 template <
typename somenumber>
1152 somenumber
residual (Vector<somenumber> &dst,
1153 const Vector<somenumber> &x,
1154 const Vector<somenumber> &b)
const;
1191 template <
typename numberB,
typename numberC>
1195 const bool rebuild_sparsity_pattern =
true)
const;
1221 template <
typename numberB,
typename numberC>
1225 const bool rebuild_sparsity_pattern =
true)
const;
1267 template <
typename somenumber>
1269 const Vector<somenumber> &src,
1270 const number omega = 1.)
const;
1278 template <
typename somenumber>
1280 const Vector<somenumber> &src,
1281 const number omega = 1.,
1282 const std::vector<std::size_t> &pos_right_of_diagonal=std::vector<std::size_t>())
const;
1287 template <
typename somenumber>
1289 const Vector<somenumber> &src,
1290 const number om = 1.)
const;
1295 template <
typename somenumber>
1297 const Vector<somenumber> &src,
1298 const number om = 1.)
const;
1305 template <
typename somenumber>
1306 void SSOR (Vector<somenumber> &v,
1307 const number omega = 1.)
const;
1313 template <
typename somenumber>
1314 void SOR (Vector<somenumber> &v,
1315 const number om = 1.)
const;
1321 template <
typename somenumber>
1322 void TSOR (Vector<somenumber> &v,
1323 const number om = 1.)
const;
1335 template <
typename somenumber>
1336 void PSOR (Vector<somenumber> &v,
1337 const std::vector<size_type> &permutation,
1338 const std::vector<size_type> &inverse_permutation,
1339 const number om = 1.)
const;
1351 template <
typename somenumber>
1352 void TPSOR (Vector<somenumber> &v,
1353 const std::vector<size_type> &permutation,
1354 const std::vector<size_type> &inverse_permutation,
1355 const number om = 1.)
const;
1362 template <
typename somenumber>
1364 const Vector<somenumber> &b,
1365 const number om = 1.)
const;
1371 template <
typename somenumber>
1372 void SOR_step (Vector<somenumber> &v,
1373 const Vector<somenumber> &b,
1374 const number om = 1.)
const;
1380 template <
typename somenumber>
1382 const Vector<somenumber> &b,
1383 const number om = 1.)
const;
1389 template <
typename somenumber>
1391 const Vector<somenumber> &b,
1392 const number om = 1.)
const;
1470 template <
class StreamType>
1471 void print (StreamType &out,
1472 const bool across =
false,
1473 const bool diagonal_first =
true)
const;
1496 const unsigned int precision = 3,
1497 const bool scientific =
true,
1498 const unsigned int width = 0,
1499 const char *zero_string =
" ",
1500 const double denominator = 1.)
const;
1508 const double threshold = 0.)
const;
1550 <<
"You are trying to access the matrix entry with index <" 1551 << arg1 <<
',' << arg2
1552 <<
">, but this entry does not exist in the sparsity pattern " 1555 "The most common cause for this problem is that you used " 1556 "a method to build the sparsity pattern that did not " 1557 "(completely) take into account all of the entries you " 1558 "will later try to write into. An example would be " 1559 "building a sparsity pattern that does not include " 1560 "the entries you will write into due to constraints " 1561 "on degrees of freedom such as hanging nodes or periodic " 1562 "boundary conditions. In such cases, building the " 1563 "sparsity pattern will succeed, but you will get errors " 1564 "such as the current one at one point or other when " 1565 "trying to write into the entries of the matrix.");
1570 "When copying one sparse matrix into another, " 1571 "or when adding one sparse matrix to another, " 1572 "both matrices need to refer to the same " 1573 "sparsity pattern.");
1579 <<
"The iterators denote a range of " << arg1
1580 <<
" elements, but the given number of rows was " << arg2);
1585 "You are attempting an operation on two matrices that " 1586 "are the same object, but the operation requires that the " 1587 "two objects are in fact different.");
1624 std::unique_ptr<number[]>
val;
1637 template <
typename>
friend class SparseILU;
1650 #ifdef DEAL_II_WITH_MPI 1663 template <
typename number>
1672 template <
typename number>
1682 template <
typename number>
1698 (
value == number()),
1699 ExcInvalidIndex(i, j));
1708 template <
typename number>
1709 template <
typename number2>
1714 const bool elide_zero_values)
1716 Assert (indices.size() == values.
m(),
1720 for (
size_type i=0; i<indices.size(); ++i)
1721 set (indices[i], indices.size(), indices.data(), &values(i,0),
1727 template <
typename number>
1728 template <
typename number2>
1732 const std::vector<size_type> &col_indices,
1734 const bool elide_zero_values)
1736 Assert (row_indices.size() == values.
m(),
1738 Assert (col_indices.size() == values.
n(),
1741 for (
size_type i=0; i<row_indices.size(); ++i)
1742 set (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1748 template <
typename number>
1749 template <
typename number2>
1753 const std::vector<size_type> &col_indices,
1754 const std::vector<number2> &values,
1755 const bool elide_zero_values)
1757 Assert (col_indices.size() == values.size(),
1760 set (
row, col_indices.size(), col_indices.data(), values.data(),
1766 template <
typename number>
1775 if (
value == number())
1785 (
value == number()),
1786 ExcInvalidIndex(i, j));
1795 template <
typename number>
1796 template <
typename number2>
1801 const bool elide_zero_values)
1803 Assert (indices.size() == values.
m(),
1807 for (
size_type i=0; i<indices.size(); ++i)
1808 add (indices[i], indices.size(), indices.data(), &values(i,0),
1814 template <
typename number>
1815 template <
typename number2>
1819 const std::vector<size_type> &col_indices,
1821 const bool elide_zero_values)
1823 Assert (row_indices.size() == values.
m(),
1825 Assert (col_indices.size() == values.
n(),
1828 for (
size_type i=0; i<row_indices.size(); ++i)
1829 add (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1835 template <
typename number>
1836 template <
typename number2>
1840 const std::vector<size_type> &col_indices,
1841 const std::vector<number2> &values,
1842 const bool elide_zero_values)
1844 Assert (col_indices.size() == values.size(),
1847 add (
row, col_indices.size(), col_indices.data(), values.data(),
1853 template <
typename number>
1861 number *val_ptr = val.get();
1862 const number *
const end_ptr = val.get() + cols->n_nonzero_elements();
1864 while (val_ptr != end_ptr)
1865 *val_ptr++ *= factor;
1872 template <
typename number>
1881 const number factor_inv = number(1.) / factor;
1883 number *val_ptr = val.get();
1884 const number *
const end_ptr = val.get() + cols->n_nonzero_elements();
1886 while (val_ptr != end_ptr)
1887 *val_ptr++ *= factor_inv;
1894 template <
typename number>
1901 ExcInvalidIndex(i,j));
1902 return val[cols->operator()(i,j)];
1907 template <
typename number>
1914 ExcInvalidIndex(i,j));
1915 return val[cols->operator()(i,j)];
1920 template <
typename number>
1936 template <
typename number>
1946 return val[cols->rowstart[i]];
1951 template <
typename number>
1961 return val[cols->rowstart[i]];
1966 template <
typename number>
1967 template <
typename ForwardIterator>
1970 const ForwardIterator end)
1972 Assert (static_cast<size_type>(std::distance (begin, end)) == m(),
1973 ExcIteratorRange (std::distance (begin, end), m()));
1977 typedef typename std::iterator_traits<ForwardIterator>::value_type::const_iterator inner_iterator;
1979 for (ForwardIterator i=begin; i!=end; ++i, ++
row)
1981 const inner_iterator end_of_row = i->end();
1982 for (inner_iterator j=i->begin(); j!=end_of_row; ++j)
1984 set (
row, j->first, j->second);
1994 template <
typename number>
1997 Accessor (
const MatrixType *matrix,
1998 const std::size_t index_within_matrix)
2001 index_within_matrix),
2007 template <
typename number>
2009 Accessor<number,true>::
2010 Accessor (
const MatrixType *matrix)
2018 template <
typename number>
2020 Accessor<number,true>::
2029 template <
typename number>
2032 Accessor<number, true>::value ()
const 2035 return matrix->val[index_within_sparsity];
2040 template <
typename number>
2042 const typename Accessor<number, true>::MatrixType &
2043 Accessor<number, true>::get_matrix ()
const 2050 template <
typename number>
2052 Accessor<number, false>::Reference::Reference (
2053 const Accessor *accessor,
2060 template <
typename number>
2062 Accessor<number, false>::Reference::operator number()
const 2064 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2065 return accessor->matrix->val[accessor->index_within_sparsity];
2070 template <
typename number>
2072 const typename Accessor<number, false>::Reference &
2073 Accessor<number, false>::Reference::operator = (
const number n)
const 2075 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2076 accessor->matrix->val[accessor->index_within_sparsity] = n;
2082 template <
typename number>
2084 const typename Accessor<number, false>::Reference &
2085 Accessor<number, false>::Reference::operator += (
const number n)
const 2087 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2088 accessor->matrix->val[accessor->index_within_sparsity] += n;
2094 template <
typename number>
2096 const typename Accessor<number, false>::Reference &
2097 Accessor<number, false>::Reference::operator -= (
const number n)
const 2099 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2100 accessor->matrix->val[accessor->index_within_sparsity] -= n;
2106 template <
typename number>
2108 const typename Accessor<number, false>::Reference &
2109 Accessor<number, false>::Reference::operator *= (
const number n)
const 2111 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2112 accessor->matrix->val[accessor->index_within_sparsity] *= n;
2118 template <
typename number>
2120 const typename Accessor<number, false>::Reference &
2121 Accessor<number, false>::Reference::operator /= (
const number n)
const 2123 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2124 accessor->matrix->val[accessor->index_within_sparsity] /= n;
2130 template <
typename number>
2132 Accessor<number,false>::
2133 Accessor (MatrixType *matrix,
2134 const std::size_t index)
2143 template <
typename number>
2145 Accessor<number,false>::
2146 Accessor (MatrixType *matrix)
2154 template <
typename number>
2156 typename Accessor<number, false>::Reference
2157 Accessor<number, false>::value()
const 2159 return Reference(
this,
true);
2165 template <
typename number>
2167 typename Accessor<number, false>::MatrixType &
2168 Accessor<number, false>::get_matrix ()
const 2175 template <
typename number,
bool Constness>
2177 Iterator<number, Constness>::
2178 Iterator (MatrixType *matrix,
2179 const std::size_t index)
2186 template <
typename number,
bool Constness>
2188 Iterator<number, Constness>::
2189 Iterator (MatrixType *matrix)
2196 template <
typename number,
bool Constness>
2198 Iterator<number, Constness>::
2206 template <
typename number,
bool Constness>
2208 Iterator<number, Constness> &
2209 Iterator<number,Constness>::operator++ ()
2211 accessor.advance ();
2216 template <
typename number,
bool Constness>
2218 Iterator<number,Constness>
2219 Iterator<number,Constness>::operator++ (
int)
2221 const Iterator iter = *
this;
2222 accessor.advance ();
2227 template <
typename number,
bool Constness>
2229 const Accessor<number,Constness> &
2236 template <
typename number,
bool Constness>
2238 const Accessor<number,Constness> *
2239 Iterator<number,Constness>::operator-> ()
const 2245 template <
typename number,
bool Constness>
2248 Iterator<number,Constness>::
2249 operator == (
const Iterator &other)
const 2251 return (accessor == other.accessor);
2255 template <
typename number,
bool Constness>
2258 Iterator<number,Constness>::
2259 operator != (
const Iterator &other)
const 2261 return ! (*
this == other);
2265 template <
typename number,
bool Constness>
2268 Iterator<number,Constness>::
2269 operator < (
const Iterator &other)
const 2271 Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2274 return (accessor < other.accessor);
2278 template <
typename number,
bool Constness>
2281 Iterator<number,Constness>::
2282 operator > (
const Iterator &other)
const 2284 return (other < *
this);
2288 template <
typename number,
bool Constness>
2294 Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2297 return (*this)->index_within_sparsity - other->index_within_sparsity;
2302 template <
typename number,
bool Constness>
2304 Iterator<number,Constness>
2309 for (size_type i=0; i<n; ++i)
2319 template <
typename number>
2324 return const_iterator(
this, 0);
2328 template <
typename number>
2333 return const_iterator(
this);
2337 template <
typename number>
2342 return iterator (
this, 0);
2346 template <
typename number>
2351 return iterator(
this, cols->rowstart[cols->rows]);
2355 template <
typename number>
2362 return const_iterator(
this, cols->rowstart[r]);
2367 template <
typename number>
2374 return const_iterator(
this, cols->rowstart[r+1]);
2379 template <
typename number>
2386 return iterator(
this, cols->rowstart[r]);
2391 template <
typename number>
2398 return iterator(
this, cols->rowstart[r+1]);
2403 template <
typename number>
2404 template <
class StreamType>
2408 const bool diagonal_first)
const 2413 bool hanging_diagonal =
false;
2416 for (size_type i=0; i<cols->rows; ++i)
2418 for (size_type j=cols->rowstart[i]; j<cols->rowstart[i+1]; ++j)
2420 if (!diagonal_first && i == cols->colnums[j])
2423 hanging_diagonal =
true;
2427 if (hanging_diagonal && cols->colnums[j]>i)
2430 out <<
' ' << i <<
',' << i <<
':' <<
diagonal;
2432 out <<
'(' << i <<
',' << i <<
") " <<
diagonal << std::endl;
2433 hanging_diagonal =
false;
2436 out <<
' ' << i <<
',' << cols->colnums[j] <<
':' << val[j];
2438 out <<
"(" << i <<
"," << cols->colnums[j] <<
") " << val[j] << std::endl;
2441 if (hanging_diagonal)
2444 out <<
' ' << i <<
',' << i <<
':' <<
diagonal;
2446 out <<
'(' << i <<
',' << i <<
") " <<
diagonal << std::endl;
2447 hanging_diagonal =
false;
2455 template <
typename number>
2466 template <
typename number>
2480 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
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
const Accessor< number, Constness > & operator*() const
#define DeclException2(Exception2, type1, type2, outsequence)
static ::ExceptionBase & ExcInvalidIndex(int arg1, int arg2)
numbers::NumberTraits< number >::real_type real_type
int operator-(const Iterator &p) const
const_iterator end() const
Accessor< number, Constness >::MatrixType MatrixType
Contents is actually a matrix.
SparseMatrix< number > & operator=(const SparseMatrix< number > &)
std::size_t n_actually_nonzero_elements(const double threshold=0.) const
static const size_type invalid_entry
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)
const Accessor< number, Constness > * operator->() const
somenumber matrix_norm_square(const Vector< somenumber > &v) const
bool operator!=(const Iterator &) const
SparseMatrixIterators::Iterator< number, false > iterator
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)
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()
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)
unsigned int global_dof_index
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
types::global_dof_index size_type
#define DeclExceptionMsg(Exception, defaulttext)
somenumber matrix_scalar_product(const Vector< somenumber > &u, const Vector< somenumber > &v) const
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
const SparseMatrix< number > MatrixType
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)
const Accessor< number, Constness > & value_type
Accessor< number, Constness > accessor
void Jacobi_step(Vector< somenumber > &v, const Vector< somenumber > &b, const number om=1.) const
SparseMatrixIterators::Iterator< number, true > const_iterator
static ::ExceptionBase & ExcNotQuadratic()
const Accessor * accessor
types::global_dof_index size_type
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
SparseMatrix< number > MatrixType
SmartPointer< const SparsityPattern, SparseMatrix< number > > cols
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
Accessor(const SparsityPattern *matrix, const std::size_t index_within_sparsity)
static const bool zero_addition_can_be_elided
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
void compress(::VectorOperation::values)
static ::ExceptionBase & ExcSourceEqualsDestination()
SparseMatrix & operator*=(const number factor)
static ::ExceptionBase & ExcInternalError()
void block_write(std::ostream &out) const