16 #ifndef dealii_block_matrix_base_h 17 #define dealii_block_matrix_base_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/table.h> 22 #include <deal.II/base/thread_management.h> 23 #include <deal.II/base/utilities.h> 24 #include <deal.II/base/smartpointer.h> 25 #include <deal.II/base/memory_consumption.h> 26 #include <deal.II/lac/block_indices.h> 27 #include <deal.II/lac/exceptions.h> 28 #include <deal.II/lac/full_matrix.h> 29 #include <deal.II/lac/matrix_iterator.h> 30 #include <deal.II/lac/vector.h> 31 #include <deal.II/lac/vector_operation.h> 35 DEAL_II_NAMESPACE_OPEN
57 template <
class BlockMatrixType>
109 template <
class BlockMatrixType,
bool Constness>
116 template <
class BlockMatrixType>
188 bool operator == (
const Accessor &a)
const;
191 friend class Accessor<BlockMatrixType, true>;
198 template <
class BlockMatrixType>
269 bool operator == (
const Accessor &a)
const;
275 friend class ::MatrixIterator;
341 template <
typename MatrixType>
396 template <
class BlockMatrixType>
398 copy_from (
const BlockMatrixType &source);
404 block (
const unsigned int row,
405 const unsigned int column);
413 block (
const unsigned int row,
414 const unsigned int column)
const;
420 size_type
m ()
const;
426 size_type
n ()
const;
446 void set (
const size_type i,
465 template <
typename number>
466 void set (
const std::vector<size_type> &indices,
468 const bool elide_zero_values =
false);
475 template <
typename number>
476 void set (
const std::vector<size_type> &row_indices,
477 const std::vector<size_type> &col_indices,
479 const bool elide_zero_values =
false);
491 template <
typename number>
492 void set (
const size_type row,
493 const std::vector<size_type> &col_indices,
494 const std::vector<number> &values,
495 const bool elide_zero_values =
false);
506 template <
typename number>
507 void set (
const size_type row,
508 const size_type n_cols,
509 const size_type *col_indices,
510 const number *values,
511 const bool elide_zero_values =
false);
518 void add (
const size_type i,
536 template <
typename number>
537 void add (
const std::vector<size_type> &indices,
539 const bool elide_zero_values =
true);
546 template <
typename number>
547 void add (
const std::vector<size_type> &row_indices,
548 const std::vector<size_type> &col_indices,
550 const bool elide_zero_values =
true);
561 template <
typename number>
562 void add (
const size_type row,
563 const std::vector<size_type> &col_indices,
564 const std::vector<number> &values,
565 const bool elide_zero_values =
true);
576 template <
typename number>
577 void add (
const size_type row,
578 const size_type n_cols,
579 const size_type *col_indices,
580 const number *values,
581 const bool elide_zero_values =
true,
582 const bool col_indices_are_sorted =
false);
605 const size_type j)
const;
616 const size_type j)
const;
654 template <
class BlockVectorType>
656 const BlockVectorType &src)
const;
663 template <
class BlockVectorType>
665 const BlockVectorType &src)
const;
679 template <
class BlockVectorType>
686 template <
class BlockVectorType>
689 const BlockVectorType &v)
const;
694 template <
class BlockVectorType>
696 const BlockVectorType &x,
697 const BlockVectorType &b)
const;
705 void print (std::ostream &out,
706 const bool alternative_output =
false)
const;
774 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" 775 << arg3 <<
',' << arg4 <<
"] have differing row numbers.");
781 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" 782 << arg3 <<
',' << arg4 <<
"] have differing column numbers.");
840 template <
class BlockVectorType>
842 const BlockVectorType &src)
const;
854 template <
class BlockVectorType,
857 const VectorType &src)
const;
869 template <
class BlockVectorType,
872 const BlockVectorType &src)
const;
884 template <
class VectorType>
886 const VectorType &src)
const;
899 template <
class BlockVectorType>
901 const BlockVectorType &src)
const;
913 template <
class BlockVectorType,
916 const VectorType &src)
const;
928 template <
class BlockVectorType,
931 const BlockVectorType &src)
const;
943 template <
class VectorType>
945 const VectorType &src)
const;
1028 template <
typename,
bool>
1044 template <
class BlockMatrixType>
1053 template <
class BlockMatrixType>
1056 AccessorBase<BlockMatrixType>::block_row()
const 1065 template <
class BlockMatrixType>
1068 AccessorBase<BlockMatrixType>::block_column()
const 1077 template <
class BlockMatrixType>
1079 Accessor<BlockMatrixType, true>::Accessor (
1080 const BlockMatrixType *matrix,
1081 const size_type row,
1082 const size_type col)
1085 base_iterator(
matrix->block(0,0).begin())
1092 if (row < matrix->
m())
1094 const std::pair<unsigned int,size_type> indices
1095 =
matrix->row_block_indices.global_to_local(row);
1099 for (
unsigned int bc=0; bc<
matrix->n_block_cols(); ++bc)
1102 =
matrix->block(indices.first, bc).begin(indices.second);
1103 if (base_iterator !=
1104 matrix->block(indices.first, bc).end(indices.second))
1106 this->row_block = indices.first;
1107 this->col_block = bc;
1118 *
this = Accessor (matrix, row+1, 0);
1142 template <
class BlockMatrixType>
1144 Accessor<BlockMatrixType, true>::Accessor (
const Accessor<BlockMatrixType, false> &other)
1147 base_iterator(other.base_iterator)
1149 this->row_block = other.row_block;
1150 this->col_block = other.col_block;
1154 template <
class BlockMatrixType>
1156 typename Accessor<BlockMatrixType, true>::size_type
1157 Accessor<BlockMatrixType, true>::row()
const 1162 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1163 base_iterator->row());
1167 template <
class BlockMatrixType>
1169 typename Accessor<BlockMatrixType, true>::size_type
1170 Accessor<BlockMatrixType, true>::column()
const 1175 return (
matrix->column_block_indices.local_to_global(this->col_block,0) +
1176 base_iterator->column());
1180 template <
class BlockMatrixType>
1182 typename Accessor<BlockMatrixType, true>::value_type
1183 Accessor<BlockMatrixType, true>::value ()
const 1190 return base_iterator->value();
1195 template <
class BlockMatrixType>
1198 Accessor<BlockMatrixType, true>::advance ()
1206 size_type local_row = base_iterator->row();
1217 while (base_iterator ==
1218 matrix->block(this->row_block, this->col_block).end(local_row))
1223 if (this->col_block < matrix->n_block_cols()-1)
1227 =
matrix->block(this->row_block, this->col_block).begin(local_row);
1233 this->col_block = 0;
1242 if (local_row ==
matrix->block(this->row_block, this->col_block).m())
1246 if (this->row_block ==
matrix->n_block_rows())
1255 =
matrix->block(this->row_block, this->col_block).begin(local_row);
1261 template <
class BlockMatrixType>
1264 Accessor<BlockMatrixType, true>::operator == (
const Accessor &a)
const 1266 if (matrix != a.matrix)
1269 if (this->row_block == a.row_block
1270 && this->col_block == a.col_block)
1279 (base_iterator == a.base_iterator));
1287 template <
class BlockMatrixType>
1289 Accessor<BlockMatrixType, false>::Accessor (
1290 BlockMatrixType *matrix,
1291 const size_type row,
1292 const size_type col)
1295 base_iterator(
matrix->block(0,0).begin())
1301 if (row < matrix->
m())
1303 const std::pair<unsigned int,size_type> indices
1304 =
matrix->row_block_indices.global_to_local(row);
1308 for (size_type bc=0; bc<
matrix->n_block_cols(); ++bc)
1311 =
matrix->block(indices.first, bc).begin(indices.second);
1312 if (base_iterator !=
1313 matrix->block(indices.first, bc).end(indices.second))
1315 this->row_block = indices.first;
1316 this->col_block = bc;
1327 *
this = Accessor (matrix, row+1, 0);
1339 template <
class BlockMatrixType>
1341 typename Accessor<BlockMatrixType, false>::size_type
1342 Accessor<BlockMatrixType, false>::row()
const 1347 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1348 base_iterator->row());
1352 template <
class BlockMatrixType>
1354 typename Accessor<BlockMatrixType, false>::size_type
1355 Accessor<BlockMatrixType, false>::column()
const 1360 return (
matrix->column_block_indices.local_to_global(this->col_block,0) +
1361 base_iterator->column());
1365 template <
class BlockMatrixType>
1367 typename Accessor<BlockMatrixType, false>::value_type
1368 Accessor<BlockMatrixType, false>::value ()
const 1375 return base_iterator->value();
1380 template <
class BlockMatrixType>
1383 Accessor<BlockMatrixType, false>::set_value (
typename Accessor<BlockMatrixType, false>::value_type newval)
const 1390 base_iterator->value() = newval;
1395 template <
class BlockMatrixType>
1398 Accessor<BlockMatrixType, false>::advance ()
1406 size_type local_row = base_iterator->row();
1417 while (base_iterator ==
1418 matrix->block(this->row_block, this->col_block).end(local_row))
1423 if (this->col_block < matrix->n_block_cols()-1)
1427 =
matrix->block(this->row_block, this->col_block).begin(local_row);
1433 this->col_block = 0;
1442 if (local_row ==
matrix->block(this->row_block, this->col_block).m())
1446 if (this->row_block ==
matrix->n_block_rows())
1455 =
matrix->block(this->row_block, this->col_block).begin(local_row);
1462 template <
class BlockMatrixType>
1465 Accessor<BlockMatrixType, false>::operator == (
const Accessor &a)
const 1467 if (matrix != a.matrix)
1470 if (this->row_block == a.row_block
1471 && this->col_block == a.col_block)
1480 (base_iterator == a.base_iterator));
1489 template <
typename MatrixType>
1502 template <
class MatrixType>
1503 template <
class BlockMatrixType>
1507 copy_from (
const BlockMatrixType &source)
1509 for (
unsigned int r=0; r<n_block_rows(); ++r)
1510 for (
unsigned int c=0; c<n_block_cols(); ++c)
1511 block(r,c).
copy_from (source.block(r,c));
1517 template <
class MatrixType>
1528 sizeof(temporary_data.mutex);
1530 for (
unsigned int r=0; r<n_block_rows(); ++r)
1531 for (
unsigned int c=0; c<n_block_cols(); ++c)
1533 MatrixType *p = this->sub_objects[r][c];
1542 template <
class MatrixType>
1547 for (
unsigned int r=0; r<n_block_rows(); ++r)
1548 for (
unsigned int c=0; c<n_block_cols(); ++c)
1550 MatrixType *p = this->sub_objects[r][c];
1551 this->sub_objects[r][c] =
nullptr;
1554 sub_objects.reinit (0,0);
1557 row_block_indices = column_block_indices =
BlockIndices ();
1562 template <
class MatrixType>
1566 const unsigned int column)
1568 Assert (row<n_block_rows(),
1570 Assert (column<n_block_cols(),
1573 return *sub_objects[row][column];
1578 template <
class MatrixType>
1582 const unsigned int column)
const 1584 Assert (row<n_block_rows(),
1586 Assert (column<n_block_cols(),
1589 return *sub_objects[row][column];
1593 template <
class MatrixType>
1595 typename BlockMatrixBase<MatrixType>::size_type
1598 return row_block_indices.total_size();
1603 template <
class MatrixType>
1605 typename BlockMatrixBase<MatrixType>::size_type
1608 return column_block_indices.total_size();
1613 template <
class MatrixType>
1618 return column_block_indices.size();
1623 template <
class MatrixType>
1628 return row_block_indices.size();
1636 template <
class MatrixType>
1641 const value_type value)
1643 prepare_set_operation();
1647 const std::pair<unsigned int,size_type>
1648 row_index = row_block_indices.global_to_local (i),
1649 col_index = column_block_indices.global_to_local (j);
1650 block(row_index.first,col_index.first).set (row_index.second,
1657 template <
class MatrixType>
1658 template <
typename number>
1662 const std::vector<size_type> &col_indices,
1664 const bool elide_zero_values)
1666 Assert (row_indices.size() == values.
m(),
1668 Assert (col_indices.size() == values.
n(),
1671 for (size_type i=0; i<row_indices.size(); ++i)
1672 set (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1678 template <
class MatrixType>
1679 template <
typename number>
1684 const bool elide_zero_values)
1686 Assert (indices.size() == values.
m(),
1690 for (size_type i=0; i<indices.size(); ++i)
1691 set (indices[i], indices.size(), indices.data(), &values(i,0),
1697 template <
class MatrixType>
1698 template <
typename number>
1702 const std::vector<size_type> &col_indices,
1703 const std::vector<number> &values,
1704 const bool elide_zero_values)
1706 Assert (col_indices.size() == values.size(),
1709 set (row, col_indices.size(), col_indices.data(), values.data(),
1718 template <
class MatrixType>
1719 template <
typename number>
1723 const size_type n_cols,
1724 const size_type *col_indices,
1725 const number *values,
1726 const bool elide_zero_values)
1728 prepare_set_operation();
1735 if (temporary_data.column_indices.size() < this->n_block_cols())
1737 temporary_data.column_indices.resize (this->n_block_cols());
1738 temporary_data.column_values.resize (this->n_block_cols());
1739 temporary_data.counter_within_block.resize (this->n_block_cols());
1752 if (temporary_data.column_indices[0].size() < n_cols)
1754 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
1756 temporary_data.column_indices[i].resize(n_cols);
1757 temporary_data.column_values[i].resize(n_cols);
1763 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
1764 temporary_data.counter_within_block[i] = 0;
1775 for (size_type j=0; j<n_cols; ++j)
1777 number value = values[j];
1779 if (value == number() && elide_zero_values ==
true)
1782 const std::pair<unsigned int, size_type>
1783 col_index = this->column_block_indices.global_to_local(col_indices[j]);
1785 const size_type local_index = temporary_data.counter_within_block[col_index.first]++;
1787 temporary_data.column_indices[col_index.first][local_index] = col_index.second;
1788 temporary_data.column_values[col_index.first][local_index] = value;
1795 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
1796 length += temporary_data.counter_within_block[i];
1805 const std::pair<unsigned int,size_type>
1806 row_index = this->row_block_indices.global_to_local (row);
1807 for (
unsigned int block_col=0; block_col<n_block_cols(); ++block_col)
1809 if (temporary_data.counter_within_block[block_col] == 0)
1812 block(row_index.first, block_col).set
1814 temporary_data.counter_within_block[block_col],
1815 &temporary_data.column_indices[block_col][0],
1816 &temporary_data.column_values[block_col][0],
1823 template <
class MatrixType>
1828 const value_type value)
1833 prepare_add_operation();
1838 typedef typename MatrixType::Traits MatrixTraits;
1839 if ((MatrixTraits::zero_addition_can_be_elided ==
true)
1841 (value == value_type()))
1844 const std::pair<unsigned int,size_type>
1845 row_index = row_block_indices.global_to_local (i),
1846 col_index = column_block_indices.global_to_local (j);
1847 block(row_index.first,col_index.first).add (row_index.second,
1854 template <
class MatrixType>
1855 template <
typename number>
1859 const std::vector<size_type> &col_indices,
1861 const bool elide_zero_values)
1863 Assert (row_indices.size() == values.
m(),
1865 Assert (col_indices.size() == values.
n(),
1868 for (size_type i=0; i<row_indices.size(); ++i)
1869 add (row_indices[i], col_indices.size(), col_indices.data(), &values(i,0),
1875 template <
class MatrixType>
1876 template <
typename number>
1881 const bool elide_zero_values)
1883 Assert (indices.size() == values.
m(),
1887 for (size_type i=0; i<indices.size(); ++i)
1888 add (indices[i], indices.size(), indices.data(), &values(i,0),
1894 template <
class MatrixType>
1895 template <
typename number>
1899 const std::vector<size_type> &col_indices,
1900 const std::vector<number> &values,
1901 const bool elide_zero_values)
1903 Assert (col_indices.size() == values.size(),
1906 add (row, col_indices.size(), col_indices.data(), values.data(),
1915 template <
class MatrixType>
1916 template <
typename number>
1920 const size_type n_cols,
1921 const size_type *col_indices,
1922 const number *values,
1923 const bool elide_zero_values,
1924 const bool col_indices_are_sorted)
1926 prepare_add_operation();
1931 if (col_indices_are_sorted ==
true)
1937 for (size_type i=1; i<n_cols; ++i)
1938 if (col_indices[i] <= before)
1940 "indices appear to not be sorted."))
1942 before = col_indices[i];
1944 const std::pair<unsigned int,size_type>
1945 row_index = this->row_block_indices.global_to_local (row);
1947 if (this->n_block_cols() > 1)
1951 this->column_block_indices.block_start(1));
1953 const size_type n_zero_block_indices = first_block - col_indices;
1954 block(row_index.first, 0).add (row_index.second,
1955 n_zero_block_indices,
1959 col_indices_are_sorted);
1961 if (n_zero_block_indices < n_cols)
1962 this->add(row, n_cols - n_zero_block_indices, first_block,
1963 values + n_zero_block_indices, elide_zero_values,
1968 block(row_index.first, 0). add (row_index.second,
1973 col_indices_are_sorted);
1982 if (temporary_data.column_indices.size() < this->n_block_cols())
1984 temporary_data.column_indices.resize (this->n_block_cols());
1985 temporary_data.column_values.resize (this->n_block_cols());
1986 temporary_data.counter_within_block.resize (this->n_block_cols());
1999 if (temporary_data.column_indices[0].size() < n_cols)
2001 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
2003 temporary_data.column_indices[i].resize(n_cols);
2004 temporary_data.column_values[i].resize(n_cols);
2010 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
2011 temporary_data.counter_within_block[i] = 0;
2022 for (size_type j=0; j<n_cols; ++j)
2024 number value = values[j];
2026 if (value == number() && elide_zero_values ==
true)
2029 const std::pair<unsigned int, size_type>
2030 col_index = this->column_block_indices.global_to_local(col_indices[j]);
2032 const size_type local_index = temporary_data.counter_within_block[col_index.first]++;
2034 temporary_data.column_indices[col_index.first][local_index] = col_index.second;
2035 temporary_data.column_values[col_index.first][local_index] = value;
2042 for (
unsigned int i=0; i<this->n_block_cols(); ++i)
2043 length += temporary_data.counter_within_block[i];
2052 const std::pair<unsigned int,size_type>
2053 row_index = this->row_block_indices.global_to_local (row);
2054 for (
unsigned int block_col=0; block_col<n_block_cols(); ++block_col)
2056 if (temporary_data.counter_within_block[block_col] == 0)
2059 block(row_index.first, block_col).add
2061 temporary_data.counter_within_block[block_col],
2062 &temporary_data.column_indices[block_col][0],
2063 &temporary_data.column_values[block_col][0],
2065 col_indices_are_sorted);
2071 template <
class MatrixType>
2079 prepare_add_operation();
2084 typedef typename MatrixType::Traits MatrixTraits;
2085 if ((MatrixTraits::zero_addition_can_be_elided ==
true)
2090 for (
unsigned int row=0; row<n_block_rows(); ++row)
2091 for (
unsigned int col=0; col<n_block_cols(); ++col)
2094 block(row, col).add(factor,
matrix.block(row,col));
2099 template <
class MatrixType>
2103 const size_type j)
const 2105 const std::pair<unsigned int,size_type>
2106 row_index = row_block_indices.global_to_local (i),
2107 col_index = column_block_indices.global_to_local (j);
2108 return block(row_index.first,col_index.first) (row_index.second,
2114 template <
class MatrixType>
2118 const size_type j)
const 2120 const std::pair<unsigned int,size_type>
2121 row_index = row_block_indices.global_to_local (i),
2122 col_index = column_block_indices.global_to_local (j);
2123 return block(row_index.first,col_index.first).el (row_index.second,
2129 template <
class MatrixType>
2134 Assert (n_block_rows() == n_block_cols(),
2137 const std::pair<unsigned int,size_type>
2138 index = row_block_indices.global_to_local (i);
2139 return block(index.first,index.first).diag_element(index.second);
2144 template <
class MatrixType>
2149 for (
unsigned int r=0; r<n_block_rows(); ++r)
2150 for (
unsigned int c=0; c<n_block_cols(); ++c)
2151 block(r,c).compress (operation);
2156 template <
class MatrixType>
2164 for (
unsigned int r=0; r<n_block_rows(); ++r)
2165 for (
unsigned int c=0; c<n_block_cols(); ++c)
2166 block(r,c) *= factor;
2173 template <
class MatrixType>
2182 const value_type factor_inv = 1. / factor;
2184 for (
unsigned int r=0; r<n_block_rows(); ++r)
2185 for (
unsigned int c=0; c<n_block_cols(); ++c)
2186 block(r,c) *= factor_inv;
2193 template <
class MatrixType>
2197 return this->row_block_indices;
2202 template <
class MatrixType>
2206 return this->column_block_indices;
2211 template <
class MatrixType>
2212 template <
class BlockVectorType>
2216 const BlockVectorType &src)
const 2218 Assert (dst.n_blocks() == n_block_rows(),
2220 Assert (src.n_blocks() == n_block_cols(),
2223 for (size_type row=0; row<n_block_rows(); ++row)
2225 block(row,0).vmult (dst.block(row),
2227 for (size_type col=1; col<n_block_cols(); ++col)
2228 block(row,col).vmult_add (dst.block(row),
2235 template <
class MatrixType>
2236 template <
class BlockVectorType,
2241 const BlockVectorType &src)
const 2243 Assert (n_block_rows() == 1,
2245 Assert (src.n_blocks() == n_block_cols(),
2248 block(0,0).vmult (dst, src.block(0));
2249 for (size_type col=1; col<n_block_cols(); ++col)
2250 block(0,col).vmult_add (dst, src.block(col));
2255 template <
class MatrixType>
2256 template <
class BlockVectorType,
2261 const VectorType &src)
const 2263 Assert (dst.n_blocks() == n_block_rows(),
2265 Assert (1 == n_block_cols(),
2268 for (size_type row=0; row<n_block_rows(); ++row)
2269 block(row,0).vmult (dst.block(row),
2275 template <
class MatrixType>
2276 template <
class VectorType>
2280 const VectorType &src)
const 2282 Assert (1 == n_block_rows(),
2284 Assert (1 == n_block_cols(),
2287 block(0,0).vmult (dst, src);
2292 template <
class MatrixType>
2293 template <
class BlockVectorType>
2296 const BlockVectorType &src)
const 2298 Assert (dst.n_blocks() == n_block_rows(),
2300 Assert (src.n_blocks() == n_block_cols(),
2303 for (
unsigned int row=0; row<n_block_rows(); ++row)
2304 for (
unsigned int col=0; col<n_block_cols(); ++col)
2305 block(row,col).vmult_add (dst.block(row),
2312 template <
class MatrixType>
2313 template <
class BlockVectorType>
2317 const BlockVectorType &src)
const 2319 Assert (dst.n_blocks() == n_block_cols(),
2321 Assert (src.n_blocks() == n_block_rows(),
2326 for (
unsigned int row=0; row<n_block_rows(); ++row)
2328 for (
unsigned int col=0; col<n_block_cols(); ++col)
2329 block(row,col).Tvmult_add (dst.block(col),
2336 template <
class MatrixType>
2337 template <
class BlockVectorType,
2342 const VectorType &src)
const 2344 Assert (dst.n_blocks() == n_block_cols(),
2346 Assert (1 == n_block_rows(),
2351 for (
unsigned int col=0; col<n_block_cols(); ++col)
2352 block(0,col).Tvmult_add (dst.block(col), src);
2357 template <
class MatrixType>
2358 template <
class BlockVectorType,
2363 const BlockVectorType &src)
const 2365 Assert (1 == n_block_cols(),
2367 Assert (src.n_blocks() == n_block_rows(),
2370 block(0,0).Tvmult (dst, src.block(0));
2372 for (size_type row=1; row<n_block_rows(); ++row)
2373 block(row,0).Tvmult_add (dst, src.block(row));
2378 template <
class MatrixType>
2379 template <
class VectorType>
2383 const VectorType &src)
const 2385 Assert (1 == n_block_cols(),
2387 Assert (1 == n_block_rows(),
2390 block(0,0).Tvmult (dst, src);
2395 template <
class MatrixType>
2396 template <
class BlockVectorType>
2399 const BlockVectorType &src)
const 2401 Assert (dst.n_blocks() == n_block_cols(),
2403 Assert (src.n_blocks() == n_block_rows(),
2406 for (
unsigned int row=0; row<n_block_rows(); ++row)
2407 for (
unsigned int col=0; col<n_block_cols(); ++col)
2408 block(row,col).Tvmult_add (dst.block(col),
2414 template <
class MatrixType>
2415 template <
class BlockVectorType>
2420 Assert (v.n_blocks() == n_block_rows(),
2423 value_type norm_sqr = 0;
2424 for (
unsigned int row=0; row<n_block_rows(); ++row)
2425 for (
unsigned int col=0; col<n_block_cols(); ++col)
2427 norm_sqr += block(row,col).matrix_norm_square (v.block(row));
2429 norm_sqr += block(row,col).matrix_scalar_product (v.block(row),
2436 template <
class MatrixType>
2437 template <
class BlockVectorType>
2441 const BlockVectorType &v)
const 2443 Assert (u.n_blocks() == n_block_rows(),
2445 Assert (v.n_blocks() == n_block_cols(),
2448 value_type result = 0;
2449 for (
unsigned int row=0; row<n_block_rows(); ++row)
2450 for (
unsigned int col=0; col<n_block_cols(); ++col)
2451 result += block(row,col).matrix_scalar_product (u.block(row),
2458 template <
class MatrixType>
2459 template <
class BlockVectorType>
2463 const BlockVectorType &x,
2464 const BlockVectorType &b)
const 2466 Assert (dst.n_blocks() == n_block_rows(),
2468 Assert (
b.n_blocks() == n_block_rows(),
2470 Assert (x.n_blocks() == n_block_cols(),
2486 for (
unsigned int row=0; row<n_block_rows(); ++row)
2488 block(row,0).residual (dst.block(row),
2492 for (size_type i=0; i<dst.block(row).size(); ++i)
2493 dst.block(row)(i) = -dst.block(row)(i);
2495 for (
unsigned int col=1; col<n_block_cols(); ++col)
2496 block(row,col).vmult_add (dst.block(row),
2499 for (size_type i=0; i<dst.block(row).size(); ++i)
2500 dst.block(row)(i) = -dst.block(row)(i);
2504 for (size_type row=0; row<n_block_rows(); ++row)
2505 res += dst.block(row).norm_sqr ();
2506 return std::sqrt(res);
2511 template <
class MatrixType>
2515 const bool alternative_output)
const 2517 for (
unsigned int row=0; row<n_block_rows(); ++row)
2518 for (
unsigned int col=0; col<n_block_cols(); ++col)
2520 if (!alternative_output)
2521 out <<
"Block (" << row <<
", " << col <<
")" << std::endl;
2523 block(row, col).print(out, alternative_output);
2529 template <
class MatrixType>
2534 return const_iterator(
this, 0);
2539 template <
class MatrixType>
2544 return const_iterator(
this, m());
2549 template <
class MatrixType>
2555 return const_iterator(
this, r);
2560 template <
class MatrixType>
2566 return const_iterator(
this, r+1);
2571 template <
class MatrixType>
2576 return iterator(
this, 0);
2581 template <
class MatrixType>
2586 return iterator(
this, m());
2591 template <
class MatrixType>
2597 return iterator(
this, r);
2602 template <
class MatrixType>
2608 return iterator(
this, r+1);
2613 template <
class MatrixType>
2617 std::vector<size_type> row_sizes (this->n_block_rows());
2618 std::vector<size_type> col_sizes (this->n_block_cols());
2622 for (
unsigned int r=0; r<this->n_block_rows(); ++r)
2623 row_sizes[r] = sub_objects[r][0]->m();
2627 for (
unsigned int c=1; c<this->n_block_cols(); ++c)
2628 for (
unsigned int r=0; r<this->n_block_rows(); ++r)
2629 Assert (row_sizes[r] == sub_objects[r][c]->m(),
2630 ExcIncompatibleRowNumbers (r,0,r,c));
2634 this->row_block_indices.reinit (row_sizes);
2638 for (
unsigned int c=0; c<this->n_block_cols(); ++c)
2639 col_sizes[c] = sub_objects[0][c]->n();
2640 for (
unsigned int r=1; r<this->n_block_rows(); ++r)
2641 for (
unsigned int c=0; c<this->n_block_cols(); ++c)
2642 Assert (col_sizes[c] == sub_objects[r][c]->n(),
2643 ExcIncompatibleRowNumbers (0,c,r,c));
2647 this->column_block_indices.reinit (col_sizes);
2652 template <
class MatrixType>
2656 for (
unsigned int row=0; row<n_block_rows(); ++row)
2657 for (
unsigned int col=0; col<n_block_cols(); ++col)
2658 block(row, col).prepare_add();
2663 template <
class MatrixType>
2667 for (
unsigned int row=0; row<n_block_rows(); ++row)
2668 for (
unsigned int col=0; col<n_block_cols(); ++col)
2669 block(row, col).prepare_set();
2675 DEAL_II_NAMESPACE_CLOSE
2677 #endif // dealii_block_matrix_base_h BlockMatrixType MatrixType
Iterator lower_bound(Iterator first, Iterator last, const T &val)
types::global_dof_index size_type
const types::global_dof_index invalid_size_type
static const unsigned int invalid_unsigned_int
void vmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
BlockMatrixBase & copy_from(const BlockMatrixType &source)
void Tvmult_add(BlockVectorType &dst, const BlockVectorType &src) const
static ::ExceptionBase & ExcIncompatibleColNumbers(int arg1, int arg2, int arg3, int arg4)
TemporaryData & operator=(const TemporaryData &)
Contents is actually a matrix.
std::vector< size_type > counter_within_block
std::vector< std::vector< size_type > > column_indices
void set(const size_type i, const size_type j, const value_type value)
value_type operator()(const size_type i, const size_type j) const
BlockMatrixType::value_type value_type
void vmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
value_type diag_element(const size_type i) const
static ::ExceptionBase & ExcNotInitialized()
void Tvmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
void add(const size_type i, const size_type j, const value_type value)
value_type matrix_norm_square(const BlockVectorType &v) const
void Tvmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void Tvmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
const BlockMatrixType MatrixType
TemporaryData temporary_data
static ::ExceptionBase & ExcDivideByZero()
types::global_dof_index size_type
std::size_t memory_consumption() const
BlockMatrixType::value_type value_type
void vmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
BlockMatrixBase()=default
BlockMatrixBase & operator*=(const value_type factor)
const BlockMatrixType * matrix
void print(std::ostream &out, const bool alternative_output=false) const
void vmult_add(BlockVectorType &dst, const BlockVectorType &src) const
void Tvmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
const BlockIndices & get_row_indices() const
std::vector< std::vector< value_type > > column_values
types::global_dof_index size_type
BlockMatrixBase & operator/=(const value_type factor)
unsigned int n_block_cols() const
static ::ExceptionBase & ExcMessage(std::string arg1)
unsigned int global_dof_index
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
types::global_dof_index size_type
void prepare_add_operation()
value_type el(const size_type i, const size_type j) const
const BlockIndices & get_column_indices() const
BlockType::value_type value_type
BlockMatrixType::BlockType::iterator base_iterator
BlockMatrixType::BlockType::const_iterator base_iterator
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
value_type residual(BlockVectorType &dst, const BlockVectorType &x, const BlockVectorType &b) const
unsigned int block_column() const
static ::ExceptionBase & ExcIteratorPastEnd()
static ::ExceptionBase & ExcNotQuadratic()
unsigned int block_row() const
BlockMatrixType::value_type value_type
void vmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
BlockType & block(const unsigned int row, const unsigned int column)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Table< 2, SmartPointer< BlockType, BlockMatrixBase< MatrixType > > > sub_objects
static ::ExceptionBase & ExcNotImplemented()
BlockIndices row_block_indices
unsigned int n_block_rows() const
value_type matrix_scalar_product(const BlockVectorType &u, const BlockVectorType &v) const
#define AssertIsFinite(number)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void compress(::VectorOperation::values operation)
static ::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
void prepare_set_operation()
static ::ExceptionBase & ExcInternalError()