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.h> 28 DEAL_II_NAMESPACE_OPEN
30 template <
typename number>
class Vector;
33 template <
typename number>
class SparseILU;
35 #ifdef DEAL_II_WITH_TRILINOS 59 template <
typename number,
bool Constness>
72 template <
typename number,
bool Constness>
101 template <
typename number>
115 const std::size_t index_within_matrix);
130 number
value()
const;
136 const MatrixType &get_matrix ()
const;
152 template <
typename,
bool>
163 template <
typename number>
198 Reference (
const Accessor *accessor,
204 operator number ()
const;
209 const Reference &operator = (
const number n)
const;
214 const Reference &operator += (
const number n)
const;
219 const Reference &operator -= (
const number n)
const;
224 const Reference &operator *= (
const number n)
const;
229 const Reference &operator /= (
const number n)
const;
250 const std::size_t
index);
260 Reference
value()
const;
266 MatrixType &get_matrix ()
const;
282 template <
typename,
bool>
289 template <
typename>
friend class ::SparseMatrix;
323 template <
typename number,
bool Constness>
346 const std::size_t index_within_matrix);
382 bool operator == (
const Iterator &)
const;
387 bool operator != (
const Iterator &)
const;
396 bool operator < (
const Iterator &)
const;
402 bool operator > (
const Iterator &)
const;
410 int operator - (
const Iterator &p)
const;
415 Iterator operator + (
const size_type n)
const;
461 template <
typename number>
517 static const bool zero_addition_can_be_elided =
true;
629 virtual void clear ();
645 size_type m ()
const;
651 size_type n ()
const;
656 size_type get_row_length (
const size_type
row)
const;
663 size_type n_nonzero_elements ()
const;
674 size_type n_actually_nonzero_elements (
const double threshold = 0.)
const;
690 std::size_t memory_consumption ()
const;
695 void compress (::VectorOperation::values);
707 void set (
const size_type i,
726 template <
typename number2>
727 void set (
const std::vector<size_type> &indices,
729 const bool elide_zero_values =
false);
736 template <
typename number2>
737 void set (
const std::vector<size_type> &row_indices,
738 const std::vector<size_type> &col_indices,
740 const bool elide_zero_values =
false);
752 template <
typename number2>
753 void set (
const size_type
row,
754 const std::vector<size_type> &col_indices,
755 const std::vector<number2> &values,
756 const bool elide_zero_values =
false);
767 template <
typename number2>
768 void set (
const size_type
row,
769 const size_type n_cols,
770 const size_type *col_indices,
771 const number2 *values,
772 const bool elide_zero_values =
false);
779 void add (
const size_type i,
797 template <
typename number2>
798 void add (
const std::vector<size_type> &indices,
800 const bool elide_zero_values =
true);
807 template <
typename number2>
808 void add (
const std::vector<size_type> &row_indices,
809 const std::vector<size_type> &col_indices,
811 const bool elide_zero_values =
true);
822 template <
typename number2>
823 void add (
const size_type row,
824 const std::vector<size_type> &col_indices,
825 const std::vector<number2> &values,
826 const bool elide_zero_values =
true);
837 template <
typename number2>
838 void add (
const size_type row,
839 const size_type n_cols,
840 const size_type *col_indices,
841 const number2 *values,
842 const bool elide_zero_values =
true,
843 const bool col_indices_are_sorted =
false);
885 template <
typename somenumber>
905 template <
typename ForwardIterator>
906 void copy_from (
const ForwardIterator begin,
907 const ForwardIterator end);
914 template <
typename somenumber>
917 #ifdef DEAL_II_WITH_TRILINOS 942 template <
typename somenumber>
943 void add (
const number factor,
965 number operator () (
const size_type i,
966 const size_type j)
const;
980 number el (
const size_type i,
981 const size_type j)
const;
993 number diag_element (
const size_type i)
const;
999 number &diag_element (
const size_type i);
1022 template <
class OutVector,
class InVector>
1023 void vmult (OutVector &dst,
1024 const InVector &src)
const;
1041 template <
class OutVector,
class InVector>
1042 void Tvmult (OutVector &dst,
1043 const InVector &src)
const;
1061 template <
class OutVector,
class InVector>
1062 void vmult_add (OutVector &dst,
1063 const InVector &src)
const;
1080 template <
class OutVector,
class InVector>
1081 void Tvmult_add (OutVector &dst,
1082 const InVector &src)
const;
1101 template <
typename somenumber>
1109 template <
typename somenumber>
1122 template <
typename somenumber>
1150 template <
typename numberB,
typename numberC>
1154 const bool rebuild_sparsity_pattern =
true)
const;
1180 template <
typename numberB,
typename numberC>
1184 const bool rebuild_sparsity_pattern =
true)
const;
1199 real_type l1_norm ()
const;
1208 real_type linfty_norm ()
const;
1214 real_type frobenius_norm ()
const;
1226 template <
typename somenumber>
1229 const number omega = 1.)
const;
1237 template <
typename somenumber>
1240 const number omega = 1.,
1241 const std::vector<std::size_t> &pos_right_of_diagonal=std::vector<std::size_t>())
const;
1246 template <
typename somenumber>
1249 const number om = 1.)
const;
1254 template <
typename somenumber>
1257 const number om = 1.)
const;
1264 template <
typename somenumber>
1266 const number omega = 1.)
const;
1272 template <
typename somenumber>
1274 const number om = 1.)
const;
1280 template <
typename somenumber>
1282 const number om = 1.)
const;
1294 template <
typename somenumber>
1296 const std::vector<size_type> &permutation,
1297 const std::vector<size_type> &inverse_permutation,
1298 const number om = 1.)
const;
1310 template <
typename somenumber>
1312 const std::vector<size_type> &permutation,
1313 const std::vector<size_type> &inverse_permutation,
1314 const number om = 1.)
const;
1321 template <
typename somenumber>
1324 const number om = 1.)
const;
1330 template <
typename somenumber>
1333 const number om = 1.)
const;
1339 template <
typename somenumber>
1342 const number om = 1.)
const;
1348 template <
typename somenumber>
1351 const number om = 1.)
const;
1395 iterator begin (
const size_type r);
1429 template <
class StreamType>
1430 void print (StreamType &out,
1431 const bool across =
false,
1432 const bool diagonal_first =
true)
const;
1454 void print_formatted (std::ostream &out,
1455 const unsigned int precision = 3,
1456 const bool scientific =
true,
1457 const unsigned int width = 0,
1458 const char *zero_string =
" ",
1459 const double denominator = 1.)
const;
1466 void print_pattern(std::ostream &out,
1467 const double threshold = 0.)
const;
1479 void block_write (std::ostream &out)
const;
1497 void block_read (std::istream &in);
1509 <<
"You are trying to access the matrix entry with index <" 1510 << arg1 <<
',' << arg2
1511 <<
">, but this entry does not exist in the sparsity pattern " 1514 "The most common cause for this problem is that you used " 1515 "a method to build the sparsity pattern that did not " 1516 "(completely) take into account all of the entries you " 1517 "will later try to write into. An example would be " 1518 "building a sparsity pattern that does not include " 1519 "the entries you will write into due to constraints " 1520 "on degrees of freedom such as hanging nodes or periodic " 1521 "boundary conditions. In such cases, building the " 1522 "sparsity pattern will succeed, but you will get errors " 1523 "such as the current one at one point or other when " 1524 "trying to write into the entries of the matrix.");
1529 "When copying one sparse matrix into another, " 1530 "or when adding one sparse matrix to another, " 1531 "both matrices need to refer to the same " 1532 "sparsity pattern.");
1538 <<
"The iterators denote a range of " << arg1
1539 <<
" elements, but the given number of rows was " << arg2);
1592 template <
typename>
friend class SparseILU;
1605 #ifndef DEAL_II_MSVC 1618 template <typename number>
1622 Assert (cols != 0, ExcNotInitialized());
1627 template <
typename number>
1631 Assert (cols != 0, ExcNotInitialized());
1637 template <
typename number>
1646 const size_type
index = cols->operator()(i, j);
1653 (value == number()),
1654 ExcInvalidIndex(i, j));
1663 template <
typename number>
1664 template <
typename number2>
1669 const bool elide_zero_values)
1671 Assert (indices.size() == values.
m(),
1672 ExcDimensionMismatch(indices.size(), values.
m()));
1673 Assert (values.
m() == values.
n(), ExcNotQuadratic());
1675 for (size_type i=0; i<indices.size(); ++i)
1676 set (indices[i], indices.size(), &indices[0], &values(i,0),
1682 template <
typename number>
1683 template <
typename number2>
1687 const std::vector<size_type> &col_indices,
1689 const bool elide_zero_values)
1691 Assert (row_indices.size() == values.
m(),
1692 ExcDimensionMismatch(row_indices.size(), values.
m()));
1693 Assert (col_indices.size() == values.
n(),
1694 ExcDimensionMismatch(col_indices.size(), values.
n()));
1696 for (size_type i=0; i<row_indices.size(); ++i)
1697 set (row_indices[i], col_indices.size(), &col_indices[0], &values(i,0),
1703 template <
typename number>
1704 template <
typename number2>
1708 const std::vector<size_type> &col_indices,
1709 const std::vector<number2> &values,
1710 const bool elide_zero_values)
1712 Assert (col_indices.size() == values.size(),
1713 ExcDimensionMismatch(col_indices.size(), values.size()));
1715 set (
row, col_indices.size(), &col_indices[0], &values[0],
1721 template <
typename number>
1730 if (value == number())
1733 const size_type index = cols->operator()(i, j);
1740 (value == number()),
1741 ExcInvalidIndex(i, j));
1750 template <
typename number>
1751 template <
typename number2>
1756 const bool elide_zero_values)
1758 Assert (indices.size() == values.
m(),
1759 ExcDimensionMismatch(indices.size(), values.
m()));
1760 Assert (values.
m() == values.
n(), ExcNotQuadratic());
1762 for (size_type i=0; i<indices.size(); ++i)
1763 add (indices[i], indices.size(), &indices[0], &values(i,0),
1769 template <
typename number>
1770 template <
typename number2>
1774 const std::vector<size_type> &col_indices,
1776 const bool elide_zero_values)
1778 Assert (row_indices.size() == values.
m(),
1779 ExcDimensionMismatch(row_indices.size(), values.
m()));
1780 Assert (col_indices.size() == values.
n(),
1781 ExcDimensionMismatch(col_indices.size(), values.
n()));
1783 for (size_type i=0; i<row_indices.size(); ++i)
1784 add (row_indices[i], col_indices.size(), &col_indices[0], &values(i,0),
1790 template <
typename number>
1791 template <
typename number2>
1795 const std::vector<size_type> &col_indices,
1796 const std::vector<number2> &values,
1797 const bool elide_zero_values)
1799 Assert (col_indices.size() == values.size(),
1800 ExcDimensionMismatch(col_indices.size(), values.size()));
1802 add (row, col_indices.size(), &col_indices[0], &values[0],
1808 template <
typename number>
1813 Assert (cols != 0, ExcNotInitialized());
1814 Assert (val != 0, ExcNotInitialized());
1816 number *val_ptr = &val[0];
1819 while (val_ptr != end_ptr)
1820 *val_ptr++ *= factor;
1827 template <
typename number>
1832 Assert (cols != 0, ExcNotInitialized());
1833 Assert (val != 0, ExcNotInitialized());
1834 Assert (factor != number(), ExcDivideByZero());
1836 const number factor_inv = number(1.) / factor;
1838 number *val_ptr = &val[0];
1841 while (val_ptr != end_ptr)
1842 *val_ptr++ *= factor_inv;
1849 template <
typename number>
1852 const size_type j)
const 1854 Assert (cols != 0, ExcNotInitialized());
1856 ExcInvalidIndex(i,j));
1857 return val[cols->operator()(i,j)];
1862 template <
typename number>
1865 const size_type j)
const 1867 Assert (cols != 0, ExcNotInitialized());
1868 const size_type index = cols->operator()(i,j);
1878 template <
typename number>
1882 Assert (cols != 0, ExcNotInitialized());
1883 Assert (m() == n(), ExcNotQuadratic());
1893 template <
typename number>
1897 Assert (cols != 0, ExcNotInitialized());
1898 Assert (m() == n(), ExcNotQuadratic());
1908 template <
typename number>
1909 template <
typename ForwardIterator>
1912 const ForwardIterator end)
1914 Assert (static_cast<size_type>(std::distance (begin, end)) == m(),
1915 ExcIteratorRange (std::distance (begin, end), m()));
1919 typedef typename std::iterator_traits<ForwardIterator>::value_type::const_iterator inner_iterator;
1921 for (ForwardIterator i=begin; i!=end; ++i, ++
row)
1923 const inner_iterator end_of_row = i->end();
1924 for (inner_iterator j=i->begin(); j!=end_of_row; ++j)
1926 set (row, j->first, j->second);
1936 template <
typename number>
1938 Accessor<number,true>::
1939 Accessor (
const MatrixType *
matrix,
1940 const std::size_t index_within_matrix)
1943 index_within_matrix),
1949 template <
typename number>
1951 Accessor<number,true>::
1952 Accessor (
const MatrixType *matrix)
1960 template <
typename number>
1962 Accessor<number,true>::
1966 matrix (&a.get_matrix())
1971 template <
typename number>
1974 Accessor<number, true>::value ()
const 1977 return matrix->val[index_within_sparsity];
1982 template <
typename number>
1984 const typename Accessor<number, true>::MatrixType &
1985 Accessor<number, true>::get_matrix ()
const 1992 template <
typename number>
1994 Accessor<number, false>::Reference::Reference (
1995 const Accessor *accessor,
2002 template <
typename number>
2004 Accessor<number, false>::Reference::operator number()
const 2006 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2007 return accessor->matrix->val[accessor->index_within_sparsity];
2012 template <
typename number>
2014 const typename Accessor<number, false>::Reference &
2015 Accessor<number, false>::Reference::operator = (
const number
n)
const 2017 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2018 accessor->matrix->val[accessor->index_within_sparsity] =
n;
2024 template <
typename number>
2026 const typename Accessor<number, false>::Reference &
2027 Accessor<number, false>::Reference::operator += (
const number n)
const 2029 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2030 accessor->matrix->val[accessor->index_within_sparsity] +=
n;
2036 template <
typename number>
2038 const typename Accessor<number, false>::Reference &
2039 Accessor<number, false>::Reference::operator -= (
const number n)
const 2041 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2042 accessor->matrix->val[accessor->index_within_sparsity] -=
n;
2048 template <
typename number>
2050 const typename Accessor<number, false>::Reference &
2051 Accessor<number, false>::Reference::operator *= (
const number n)
const 2053 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2054 accessor->matrix->val[accessor->index_within_sparsity] *=
n;
2060 template <
typename number>
2062 const typename Accessor<number, false>::Reference &
2063 Accessor<number, false>::Reference::operator /= (
const number n)
const 2065 AssertIndexRange(accessor->index_within_sparsity, accessor->matrix->n_nonzero_elements());
2066 accessor->matrix->val[accessor->index_within_sparsity] /=
n;
2072 template <
typename number>
2074 Accessor<number,false>::
2075 Accessor (MatrixType *matrix,
2076 const std::size_t index)
2085 template <
typename number>
2087 Accessor<number,false>::
2088 Accessor (MatrixType *matrix)
2096 template <
typename number>
2098 typename Accessor<number, false>::Reference
2099 Accessor<number, false>::value()
const 2101 return Reference(
this,
true);
2107 template <
typename number>
2109 typename Accessor<number, false>::MatrixType &
2110 Accessor<number, false>::get_matrix ()
const 2117 template <
typename number,
bool Constness>
2119 Iterator<number, Constness>::
2120 Iterator (MatrixType *matrix,
2121 const std::size_t index)
2123 accessor(matrix, index)
2128 template <
typename number,
bool Constness>
2130 Iterator<number, Constness>::
2131 Iterator (MatrixType *matrix)
2138 template <
typename number,
bool Constness>
2140 Iterator<number, Constness>::
2148 template <
typename number,
bool Constness>
2150 Iterator<number, Constness> &
2151 Iterator<number,Constness>::operator++ ()
2153 accessor.advance ();
2158 template <
typename number,
bool Constness>
2160 Iterator<number,Constness>
2161 Iterator<number,Constness>::operator++ (
int)
2163 const Iterator iter = *
this;
2164 accessor.advance ();
2169 template <
typename number,
bool Constness>
2171 const Accessor<number,Constness> &
2172 Iterator<number,Constness>::operator* ()
const 2178 template <
typename number,
bool Constness>
2180 const Accessor<number,Constness> *
2181 Iterator<number,Constness>::operator-> ()
const 2187 template <
typename number,
bool Constness>
2190 Iterator<number,Constness>::
2191 operator == (
const Iterator &other)
const 2193 return (accessor == other.accessor);
2197 template <
typename number,
bool Constness>
2200 Iterator<number,Constness>::
2201 operator != (
const Iterator &other)
const 2203 return ! (*
this == other);
2207 template <
typename number,
bool Constness>
2210 Iterator<number,Constness>::
2211 operator < (
const Iterator &other)
const 2213 Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2214 ExcInternalError());
2216 return (accessor < other.accessor);
2220 template <
typename number,
bool Constness>
2223 Iterator<number,Constness>::
2224 operator > (
const Iterator &other)
const 2226 return (other < *
this);
2230 template <
typename number,
bool Constness>
2233 Iterator<number,Constness>::
2234 operator - (
const Iterator &other)
const 2236 Assert (&accessor.get_matrix() == &other.accessor.get_matrix(),
2237 ExcInternalError());
2239 return (*this)->index_within_sparsity - other->index_within_sparsity;
2244 template <
typename number,
bool Constness>
2246 Iterator<number,Constness>
2247 Iterator<number,Constness>::
2248 operator + (
const size_type n)
const 2251 for (size_type i=0; i<
n; ++i)
2261 template <
typename number>
2270 template <
typename number>
2279 template <
typename number>
2288 template <
typename number>
2297 template <
typename number>
2302 Assert (r<
m(), ExcIndexRange(r,0,
m()));
2309 template <
typename number>
2314 Assert (r<
m(), ExcIndexRange(r,0,
m()));
2321 template <
typename number>
2326 Assert (r<
m(), ExcIndexRange(r,0,
m()));
2333 template <
typename number>
2338 Assert (r<
m(), ExcIndexRange(r,0,
m()));
2345 template <
typename number>
2346 template <
class StreamType>
2350 const bool diagonal_first)
const 2352 Assert (cols != 0, ExcNotInitialized());
2353 Assert (val != 0, ExcNotInitialized());
2355 bool hanging_diagonal =
false;
2356 number diagonal = number();
2358 for (size_type i=0; i<cols->
rows; ++i)
2360 for (size_type j=cols->
rowstart[i]; j<cols->rowstart[i+1]; ++j)
2362 if (!diagonal_first && i == cols->
colnums[j])
2365 hanging_diagonal =
true;
2369 if (hanging_diagonal && cols->
colnums[j]>i)
2372 out <<
' ' << i <<
',' << i <<
':' << diagonal;
2374 out <<
'(' << i <<
',' << i <<
") " << diagonal << std::endl;
2375 hanging_diagonal =
false;
2378 out <<
' ' << i <<
',' << cols->
colnums[j] <<
':' << val[j];
2380 out <<
"(" << i <<
"," << cols->
colnums[j] <<
") " << val[j] << std::endl;
2383 if (hanging_diagonal)
2386 out <<
' ' << i <<
',' << i <<
':' << diagonal;
2388 out <<
'(' << i <<
',' << i <<
") " << diagonal << std::endl;
2389 hanging_diagonal =
false;
2397 template <
typename number>
2408 template <
typename number>
2422 DEAL_II_NAMESPACE_CLOSE
TrilinosScalar diag_element(const size_type i) const
TrilinosScalar el(const size_type i, const size_type j) const
#define DeclException2(Exception2, type1, type2, outsequence)
numbers::NumberTraits< number >::real_type real_type
const_iterator end() const
Accessor< number, Constness >::MatrixType MatrixType
static const size_type invalid_entry
#define AssertIndexRange(index, range)
SparseMatrixIterators::Iterator< number, false > iterator
TrilinosScalar operator()(const size_type i, const size_type j) const
DeclException0(ExcBeyondEndOfMatrix)
SparseMatrix & operator*=(const TrilinosScalar factor)
unsigned int global_dof_index
void add(const size_type i, const size_type j, const TrilinosScalar value)
#define Assert(cond, exc)
void print(StreamType &out, const bool across=false, const bool diagonal_first=true) const
types::global_dof_index size_type
#define DeclExceptionMsg(Exception, defaulttext)
const SparseMatrix< number > MatrixType
const Accessor< number, Constness > & value_type
Accessor< number, Constness > accessor
size_type n_nonzero_elements() const
SparseMatrixIterators::Iterator< number, true > const_iterator
const Accessor * accessor
types::global_dof_index size_type
SparseMatrix< number > MatrixType
void copy_from(const SparseMatrix &source)
SparseMatrix & operator/=(const TrilinosScalar factor)
SmartPointer< const SparsityPattern, SparseMatrix< number > > cols
TrilinosScalar value() const
const SparsityPattern & get_sparsity_pattern() const
const_iterator begin() const
void set(const size_type i, const size_type j, const TrilinosScalar value)
#define AssertIsFinite(number)