15#ifndef dealii_block_matrix_base_h
16#define dealii_block_matrix_base_h
61 template <
typename BlockMatrixType>
109 template <
typename BlockMatrixType,
bool Constness>
116 template <
typename BlockMatrixType>
193 friend class ::MatrixIterator;
195 friend class Accessor<BlockMatrixType, true>;
204 template <
typename BlockMatrixType>
283 friend class ::MatrixIterator;
348template <
typename MatrixType>
402 template <
typename BlockMatrixType>
410 block(
const unsigned int row,
const unsigned int column);
418 block(
const unsigned int row,
const unsigned int column)
const;
472 template <
typename number>
474 set(
const std::vector<size_type> &indices,
476 const bool elide_zero_values =
false);
483 template <
typename number>
485 set(
const std::vector<size_type> &row_indices,
486 const std::vector<size_type> &col_indices,
488 const bool elide_zero_values =
false);
500 template <
typename number>
503 const std::vector<size_type> &col_indices,
504 const std::vector<number> &values,
505 const bool elide_zero_values =
false);
516 template <
typename number>
521 const number *values,
522 const bool elide_zero_values =
false);
546 template <
typename number>
548 add(
const std::vector<size_type> &indices,
550 const bool elide_zero_values =
true);
557 template <
typename number>
559 add(
const std::vector<size_type> &row_indices,
560 const std::vector<size_type> &col_indices,
562 const bool elide_zero_values =
true);
573 template <
typename number>
576 const std::vector<size_type> &col_indices,
577 const std::vector<number> &values,
578 const bool elide_zero_values =
true);
589 template <
typename number>
594 const number *values,
595 const bool elide_zero_values =
true,
596 const bool col_indices_are_sorted =
false);
672 template <
typename BlockVectorType>
674 vmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
681 template <
typename BlockVectorType>
683 Tvmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
697 template <
typename BlockVectorType>
711 template <
typename BlockVectorType>
714 const BlockVectorType &v)
const;
719 template <
typename BlockVectorType>
722 const BlockVectorType &x,
723 const BlockVectorType &b)
const;
732 print(std::ostream &out,
const bool alternative_output =
false)
const;
814 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
815 <<
',' << arg4 <<
"] have differing row numbers.");
824 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
825 <<
',' << arg4 <<
"] have differing column numbers.");
885 template <
typename BlockVectorType>
899 template <
typename BlockVectorType,
typename VectorType>
913 template <
typename BlockVectorType,
typename VectorType>
927 template <
typename VectorType>
942 template <
typename BlockVectorType>
956 template <
typename BlockVectorType,
typename VectorType>
970 template <
typename BlockVectorType,
typename VectorType>
984 template <
typename VectorType>
1068 template <
typename,
bool>
1084 template <
typename BlockMatrixType>
1091 template <
typename BlockMatrixType>
1093 AccessorBase<BlockMatrixType>::block_row()
const
1101 template <
typename BlockMatrixType>
1103 AccessorBase<BlockMatrixType>::block_column()
const
1111 template <
typename BlockMatrixType>
1112 inline Accessor<BlockMatrixType, true>::Accessor(
1113 const BlockMatrixType *matrix,
1114 const size_type row,
1115 const size_type col)
1123 if (row < matrix->
m())
1125 const std::pair<unsigned int, size_type> indices =
1126 matrix->row_block_indices.global_to_local(row);
1130 for (
unsigned int bc = 0; bc <
matrix->n_block_cols(); ++bc)
1133 matrix->block(indices.first, bc).begin(indices.second);
1134 if (base_iterator !=
1135 matrix->block(indices.first, bc).end(indices.second))
1137 this->row_block = indices.first;
1138 this->col_block = bc;
1149 *
this =
Accessor(matrix, row + 1, 0);
1174 template <
typename BlockMatrixType>
1175 inline Accessor<BlockMatrixType, true>::Accessor(
1176 const Accessor<BlockMatrixType, false> &other)
1178 , base_iterator(other.base_iterator)
1180 this->row_block = other.row_block;
1181 this->col_block = other.col_block;
1185 template <
typename BlockMatrixType>
1186 inline typename Accessor<BlockMatrixType, true>::size_type
1187 Accessor<BlockMatrixType, true>::row()
const
1192 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1193 base_iterator->row());
1197 template <
typename BlockMatrixType>
1198 inline typename Accessor<BlockMatrixType, true>::size_type
1199 Accessor<BlockMatrixType, true>::column()
const
1204 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1205 base_iterator->column());
1209 template <
typename BlockMatrixType>
1210 inline typename Accessor<BlockMatrixType, true>::value_type
1211 Accessor<BlockMatrixType, true>::value()
const
1218 return base_iterator->value();
1223 template <
typename BlockMatrixType>
1225 Accessor<BlockMatrixType, true>::advance()
1233 size_type local_row = base_iterator->row();
1244 while (base_iterator ==
1245 matrix->block(this->row_block, this->col_block).end(local_row))
1250 if (this->col_block < matrix->n_block_cols() - 1)
1254 matrix->block(this->row_block, this->col_block).begin(local_row);
1260 this->col_block = 0;
1270 matrix->block(this->row_block, this->col_block).m())
1274 if (this->row_block ==
matrix->n_block_rows())
1283 matrix->block(this->row_block, this->col_block).begin(local_row);
1289 template <
typename BlockMatrixType>
1291 Accessor<BlockMatrixType, true>::operator==(
const Accessor &a)
const
1293 if (matrix != a.matrix)
1296 if (this->row_block == a.row_block && this->col_block == a.col_block)
1303 (base_iterator == a.base_iterator));
1311 template <
typename BlockMatrixType>
1312 inline Accessor<BlockMatrixType, false>::Accessor(BlockMatrixType *matrix,
1313 const size_type row,
1314 const size_type col)
1321 if (row < matrix->
m())
1323 const std::pair<unsigned int, size_type> indices =
1324 matrix->row_block_indices.global_to_local(row);
1331 matrix->block(indices.first, bc).begin(indices.second);
1332 if (base_iterator !=
1333 matrix->block(indices.first, bc).end(indices.second))
1335 this->row_block = indices.first;
1336 this->col_block = bc;
1347 *
this =
Accessor(matrix, row + 1, 0);
1359 template <
typename BlockMatrixType>
1360 inline typename Accessor<BlockMatrixType, false>::size_type
1361 Accessor<BlockMatrixType, false>::row()
const
1365 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1366 base_iterator->row());
1370 template <
typename BlockMatrixType>
1371 inline typename Accessor<BlockMatrixType, false>::size_type
1372 Accessor<BlockMatrixType, false>::column()
const
1376 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1377 base_iterator->column());
1381 template <
typename BlockMatrixType>
1382 inline typename Accessor<BlockMatrixType, false>::value_type
1383 Accessor<BlockMatrixType, false>::value()
const
1388 return base_iterator->value();
1393 template <
typename BlockMatrixType>
1395 Accessor<BlockMatrixType, false>::set_value(
1396 typename Accessor<BlockMatrixType, false>::value_type newval)
const
1401 base_iterator->value() = newval;
1406 template <
typename BlockMatrixType>
1408 Accessor<BlockMatrixType, false>::advance()
1414 size_type local_row = base_iterator->row();
1425 while (base_iterator ==
1426 matrix->block(this->row_block, this->col_block).end(local_row))
1431 if (this->col_block < matrix->n_block_cols() - 1)
1435 matrix->block(this->row_block, this->col_block).begin(local_row);
1441 this->col_block = 0;
1451 matrix->block(this->row_block, this->col_block).m())
1455 if (this->row_block ==
matrix->n_block_rows())
1464 matrix->block(this->row_block, this->col_block).begin(local_row);
1471 template <
typename BlockMatrixType>
1473 Accessor<BlockMatrixType, false>::operator==(
const Accessor &a)
const
1475 if (matrix != a.matrix)
1478 if (this->row_block == a.row_block && this->col_block == a.col_block)
1485 (base_iterator == a.base_iterator));
1494template <
typename MatrixType>
1506template <
typename MatrixType>
1507template <
typename BlockMatrixType>
1511 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1512 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1513 block(r, c).
copy_from(source.block(r, c));
1519template <
typename MatrixType>
1530 sizeof(temporary_data.mutex);
1532 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1533 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1535 MatrixType *p = this->sub_objects[r][c];
1544template <
typename MatrixType>
1548 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1549 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1551 MatrixType *p = this->sub_objects[r][c];
1552 this->sub_objects[r][c] =
nullptr;
1555 sub_objects.reinit(0, 0);
1558 row_block_indices = column_block_indices =
BlockIndices();
1563template <
typename MatrixType>
1566 const unsigned int column)
1571 return *sub_objects[row][column];
1576template <
typename MatrixType>
1579 const unsigned int column)
const
1584 return *sub_objects[row][column];
1588template <
typename MatrixType>
1592 return row_block_indices.total_size();
1597template <
typename MatrixType>
1601 return column_block_indices.total_size();
1606template <
typename MatrixType>
1610 return column_block_indices.size();
1615template <
typename MatrixType>
1619 return row_block_indices.size();
1627template <
typename MatrixType>
1631 const value_type
value)
1633 prepare_set_operation();
1637 const std::pair<unsigned int, size_type>
1638 row_index = row_block_indices.global_to_local(i),
1639 col_index = column_block_indices.global_to_local(j);
1640 block(row_index.first, col_index.first)
1641 .set(row_index.second, col_index.second,
value);
1646template <
typename MatrixType>
1647template <
typename number>
1650 const std::vector<size_type> &col_indices,
1652 const bool elide_zero_values)
1654 Assert(row_indices.size() == values.m(),
1656 Assert(col_indices.size() == values.n(),
1659 for (size_type i = 0; i < row_indices.size(); ++i)
1669template <
typename MatrixType>
1670template <
typename number>
1674 const bool elide_zero_values)
1676 Assert(indices.size() == values.m(),
1680 for (size_type i = 0; i < indices.size(); ++i)
1690template <
typename MatrixType>
1691template <
typename number>
1694 const std::vector<size_type> &col_indices,
1695 const std::vector<number> &values,
1696 const bool elide_zero_values)
1698 Assert(col_indices.size() == values.size(),
1713template <
typename MatrixType>
1714template <
typename number>
1717 const size_type n_cols,
1718 const size_type *col_indices,
1719 const number *values,
1720 const bool elide_zero_values)
1722 prepare_set_operation();
1726 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1729 if (temporary_data.column_indices.size() < this->n_block_cols())
1731 temporary_data.column_indices.resize(this->n_block_cols());
1732 temporary_data.column_values.resize(this->n_block_cols());
1733 temporary_data.counter_within_block.resize(this->n_block_cols());
1746 if (temporary_data.column_indices[0].size() < n_cols)
1748 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1750 temporary_data.column_indices[i].resize(n_cols);
1751 temporary_data.column_values[i].resize(n_cols);
1757 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1758 temporary_data.counter_within_block[i] = 0;
1769 for (size_type j = 0; j < n_cols; ++j)
1771 number
value = values[j];
1773 if (
value == number() && elide_zero_values ==
true)
1776 const std::pair<unsigned int, size_type> col_index =
1777 this->column_block_indices.global_to_local(col_indices[j]);
1780 temporary_data.counter_within_block[col_index.first]++;
1782 temporary_data.column_indices[col_index.first][local_index] =
1784 temporary_data.column_values[col_index.first][local_index] =
value;
1792 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1793 length += temporary_data.counter_within_block[i];
1802 const std::pair<unsigned int, size_type> row_index =
1803 this->row_block_indices.global_to_local(row);
1804 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
1806 if (temporary_data.counter_within_block[block_col] == 0)
1809 block(row_index.first, block_col)
1810 .set(row_index.second,
1811 temporary_data.counter_within_block[block_col],
1812 temporary_data.column_indices[block_col].data(),
1813 temporary_data.column_values[block_col].data(),
1820template <
typename MatrixType>
1824 const value_type
value)
1828 prepare_add_operation();
1833 using MatrixTraits =
typename MatrixType::Traits;
1834 if ((MatrixTraits::zero_addition_can_be_elided ==
true) &&
1835 (
value == value_type()))
1838 const std::pair<unsigned int, size_type>
1839 row_index = row_block_indices.global_to_local(i),
1840 col_index = column_block_indices.global_to_local(j);
1841 block(row_index.first, col_index.first)
1842 .add(row_index.second, col_index.second,
value);
1847template <
typename MatrixType>
1848template <
typename number>
1851 const std::vector<size_type> &col_indices,
1853 const bool elide_zero_values)
1855 Assert(row_indices.size() == values.m(),
1857 Assert(col_indices.size() == values.n(),
1860 for (size_type i = 0; i < row_indices.size(); ++i)
1870template <
typename MatrixType>
1871template <
typename number>
1875 const bool elide_zero_values)
1877 Assert(indices.size() == values.m(),
1881 for (size_type i = 0; i < indices.size(); ++i)
1891template <
typename MatrixType>
1892template <
typename number>
1895 const std::vector<size_type> &col_indices,
1896 const std::vector<number> &values,
1897 const bool elide_zero_values)
1899 Assert(col_indices.size() == values.size(),
1914template <
typename MatrixType>
1915template <
typename number>
1918 const size_type n_cols,
1919 const size_type *col_indices,
1920 const number *values,
1921 const bool elide_zero_values,
1922 const bool col_indices_are_sorted)
1924 prepare_add_operation();
1929 if (col_indices_are_sorted ==
true)
1936 for (size_type i = 1; i < n_cols; ++i)
1937 if (col_indices[i] <= before)
1940 ExcMessage(
"Flag col_indices_are_sorted is set, but "
1941 "indices appear to not be sorted."));
1944 before = col_indices[i];
1946 const std::pair<unsigned int, size_type> row_index =
1947 this->row_block_indices.global_to_local(row);
1949 if (this->n_block_cols() > 1)
1953 col_indices + n_cols,
1954 this->column_block_indices.block_start(1));
1956 const size_type n_zero_block_indices = first_block - col_indices;
1957 block(row_index.first, 0)
1958 .add(row_index.second,
1959 n_zero_block_indices,
1963 col_indices_are_sorted);
1965 if (n_zero_block_indices < n_cols)
1967 n_cols - n_zero_block_indices,
1969 values + n_zero_block_indices,
1975 block(row_index.first, 0)
1976 .add(row_index.second,
1981 col_indices_are_sorted);
1988 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1990 if (temporary_data.column_indices.size() < this->n_block_cols())
1992 temporary_data.column_indices.resize(this->n_block_cols());
1993 temporary_data.column_values.resize(this->n_block_cols());
1994 temporary_data.counter_within_block.resize(this->n_block_cols());
2007 if (temporary_data.column_indices[0].size() < n_cols)
2009 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2011 temporary_data.column_indices[i].resize(n_cols);
2012 temporary_data.column_values[i].resize(n_cols);
2018 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2019 temporary_data.counter_within_block[i] = 0;
2030 for (size_type j = 0; j < n_cols; ++j)
2032 number
value = values[j];
2034 if (
value == number() && elide_zero_values ==
true)
2037 const std::pair<unsigned int, size_type> col_index =
2038 this->column_block_indices.global_to_local(col_indices[j]);
2041 temporary_data.counter_within_block[col_index.first]++;
2043 temporary_data.column_indices[col_index.first][local_index] =
2045 temporary_data.column_values[col_index.first][local_index] =
value;
2053 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2054 length += temporary_data.counter_within_block[i];
2063 const std::pair<unsigned int, size_type> row_index =
2064 this->row_block_indices.global_to_local(row);
2065 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
2067 if (temporary_data.counter_within_block[block_col] == 0)
2070 block(row_index.first, block_col)
2071 .add(row_index.second,
2072 temporary_data.counter_within_block[block_col],
2073 temporary_data.column_indices[block_col].data(),
2074 temporary_data.column_values[block_col].data(),
2076 col_indices_are_sorted);
2082template <
typename MatrixType>
2089 prepare_add_operation();
2094 using MatrixTraits =
typename MatrixType::Traits;
2095 if ((MatrixTraits::zero_addition_can_be_elided ==
true) && (factor == 0))
2098 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2099 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2102 block(row, col).add(factor,
matrix.block(row, col));
2107template <
typename MatrixType>
2110 const size_type j)
const
2112 const std::pair<unsigned int, size_type>
2113 row_index = row_block_indices.global_to_local(i),
2114 col_index = column_block_indices.global_to_local(j);
2115 return block(row_index.first, col_index.first)(row_index.second,
2121template <
typename MatrixType>
2125 const std::pair<unsigned int, size_type>
2126 row_index = row_block_indices.global_to_local(i),
2127 col_index = column_block_indices.global_to_local(j);
2128 return block(row_index.first, col_index.first)
2129 .el(row_index.second, col_index.second);
2134template <
typename MatrixType>
2140 const std::pair<unsigned int, size_type>
index =
2141 row_block_indices.global_to_local(i);
2147template <
typename MatrixType>
2151 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2152 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2153 block(r, c).compress(operation);
2158template <
typename MatrixType>
2165 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2166 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2167 block(r, c) *= factor;
2174template <
typename 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;
2193template <
typename MatrixType>
2197 return this->row_block_indices;
2202template <
typename MatrixType>
2206 return this->column_block_indices;
2211template <
typename MatrixType>
2212template <
typename BlockVectorType>
2215 const BlockVectorType &src)
const
2217 Assert(dst.n_blocks() == n_block_rows(),
2219 Assert(src.n_blocks() == n_block_cols(),
2222 for (size_type row = 0; row < n_block_rows(); ++row)
2224 block(row, 0).vmult(dst.block(row), src.block(0));
2225 for (size_type col = 1; col < n_block_cols(); ++col)
2226 block(row, col).vmult_add(dst.block(row), src.block(col));
2232template <
typename MatrixType>
2233template <
typename BlockVectorType,
typename VectorType>
2237 const BlockVectorType &src)
const
2240 Assert(src.n_blocks() == n_block_cols(),
2243 block(0, 0).vmult(dst, src.block(0));
2244 for (size_type col = 1; col < n_block_cols(); ++col)
2245 block(0, col).vmult_add(dst, src.block(col));
2250template <
typename MatrixType>
2251template <
typename BlockVectorType,
typename VectorType>
2254 const VectorType &src)
const
2256 Assert(dst.n_blocks() == n_block_rows(),
2260 for (size_type row = 0; row < n_block_rows(); ++row)
2261 block(row, 0).vmult(dst.block(row), src);
2266template <
typename MatrixType>
2267template <
typename VectorType>
2271 const VectorType &src)
const
2276 block(0, 0).vmult(dst, src);
2281template <
typename MatrixType>
2282template <
typename BlockVectorType>
2285 const BlockVectorType &src)
const
2287 Assert(dst.n_blocks() == n_block_rows(),
2289 Assert(src.n_blocks() == n_block_cols(),
2292 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2293 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2294 block(row, col).vmult_add(dst.block(row), src.block(col));
2299template <
typename MatrixType>
2300template <
typename BlockVectorType>
2303 BlockVectorType &dst,
2304 const BlockVectorType &src)
const
2306 Assert(dst.n_blocks() == n_block_cols(),
2308 Assert(src.n_blocks() == n_block_rows(),
2313 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2315 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2316 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2322template <
typename MatrixType>
2323template <
typename BlockVectorType,
typename VectorType>
2326 const VectorType &src)
const
2328 Assert(dst.n_blocks() == n_block_cols(),
2334 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2335 block(0, col).Tvmult_add(dst.block(col), src);
2340template <
typename MatrixType>
2341template <
typename BlockVectorType,
typename VectorType>
2345 const BlockVectorType &src)
const
2348 Assert(src.n_blocks() == n_block_rows(),
2351 block(0, 0).Tvmult(dst, src.block(0));
2353 for (size_type row = 1; row < n_block_rows(); ++row)
2354 block(row, 0).Tvmult_add(dst, src.block(row));
2359template <
typename MatrixType>
2360template <
typename VectorType>
2364 const VectorType &src)
const
2369 block(0, 0).Tvmult(dst, src);
2374template <
typename MatrixType>
2375template <
typename BlockVectorType>
2378 const BlockVectorType &src)
const
2380 Assert(dst.n_blocks() == n_block_cols(),
2382 Assert(src.n_blocks() == n_block_rows(),
2385 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2386 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2387 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2392template <
typename MatrixType>
2393template <
typename BlockVectorType>
2398 Assert(v.n_blocks() == n_block_rows(),
2401 value_type norm_sqr = 0;
2402 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2403 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2405 norm_sqr += block(row, col).matrix_norm_square(v.block(row));
2408 block(row, col).matrix_scalar_product(v.block(row), v.block(col));
2414template <
typename MatrixType>
2418 value_type norm_sqr = 0;
2422 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2424 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2426 const value_type block_norm = block(row, col).frobenius_norm();
2427 norm_sqr += block_norm * block_norm;
2436template <
typename MatrixType>
2437template <
typename BlockVectorType>
2440 const BlockVectorType &u,
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)
2452 block(row, col).matrix_scalar_product(u.block(row), v.block(col));
2458template <
typename MatrixType>
2459template <
typename BlockVectorType>
2462 const BlockVectorType &x,
2463 const BlockVectorType &b)
const
2465 Assert(dst.n_blocks() == n_block_rows(),
2467 Assert(
b.n_blocks() == n_block_rows(),
2469 Assert(x.n_blocks() == n_block_cols(),
2485 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2487 block(row, 0).residual(dst.block(row), x.block(0),
b.block(row));
2489 for (size_type i = 0; i < dst.block(row).size(); ++i)
2490 dst.block(row)(i) = -dst.block(row)(i);
2492 for (
unsigned int col = 1; col < n_block_cols(); ++col)
2493 block(row, col).vmult_add(dst.block(row), x.block(col));
2495 for (size_type i = 0; i < dst.block(row).size(); ++i)
2496 dst.block(row)(i) = -dst.block(row)(i);
2500 for (size_type row = 0; row < n_block_rows(); ++row)
2501 res += dst.block(row).norm_sqr();
2507template <
typename MatrixType>
2510 const bool alternative_output)
const
2512 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2513 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2515 if (!alternative_output)
2516 out <<
"Block (" << row <<
", " << col <<
')' << std::endl;
2518 block(row, col).print(out, alternative_output);
2524template <
typename MatrixType>
2528 return const_iterator(
this, 0);
2533template <
typename MatrixType>
2537 return const_iterator(
this, m());
2542template <
typename MatrixType>
2547 return const_iterator(
this, r);
2552template <
typename MatrixType>
2557 return const_iterator(
this, r + 1);
2562template <
typename MatrixType>
2566 return iterator(
this, 0);
2571template <
typename MatrixType>
2575 return iterator(
this, m());
2580template <
typename MatrixType>
2585 return iterator(
this, r);
2590template <
typename MatrixType>
2595 return iterator(
this, r + 1);
2600template <
typename MatrixType>
2604 std::vector<size_type> row_sizes(this->n_block_rows());
2605 std::vector<size_type> col_sizes(this->n_block_cols());
2609 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2610 row_sizes[r] = sub_objects[r][0]->m();
2614 for (
unsigned int c = 1; c < this->n_block_cols(); ++c)
2615 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2616 Assert(row_sizes[r] == sub_objects[r][c]->m(),
2617 ExcIncompatibleRowNumbers(r, 0, r, c));
2621 this->row_block_indices.reinit(row_sizes);
2625 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2626 col_sizes[c] = sub_objects[0][c]->n();
2627 for (
unsigned int r = 1; r < this->n_block_rows(); ++r)
2628 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2629 Assert(col_sizes[c] == sub_objects[r][c]->n(),
2630 ExcIncompatibleRowNumbers(0, c, r, c));
2634 this->column_block_indices.reinit(col_sizes);
2639template <
typename MatrixType>
2643 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2644 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2645 block(row, col).prepare_add();
2650template <
typename MatrixType>
2654 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2655 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2656 block(row, col).prepare_set();
void Tvmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
void vmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
void add(const size_type row, const std::vector< size_type > &col_indices, const std::vector< number > &values, const bool elide_zero_values=true)
void add(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=true)
void add(const size_type row, const size_type n_cols, const size_type *col_indices, const number *values, const bool elide_zero_values=true, const bool col_indices_are_sorted=false)
void print(std::ostream &out, const bool alternative_output=false) const
friend class BlockMatrixIterators::Accessor
const_iterator end() const
BlockIndices column_block_indices
BlockMatrixBase & operator*=(const value_type factor)
value_type matrix_norm_square(const BlockVectorType &v) const
void Tvmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
const value_type & const_reference
void Tvmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
unsigned int n_block_rows() const
value_type operator()(const size_type i, const size_type j) const
value_type el(const size_type i, const size_type j) const
const_iterator begin() const
real_type frobenius_norm() const
void vmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
void compress(VectorOperation::values operation)
void vmult_add(BlockVectorType &dst, const BlockVectorType &src) const
types::global_dof_index size_type
void Tvmult_add(BlockVectorType &dst, const BlockVectorType &src) const
typename BlockType::value_type value_type
void prepare_add_operation()
void vmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
value_type residual(BlockVectorType &dst, const BlockVectorType &x, const BlockVectorType &b) const
BlockMatrixBase()=default
MatrixIterator< BlockMatrixIterators::Accessor< BlockMatrixBase, true > > const_iterator
void set(const size_type row, const size_type n_cols, const size_type *col_indices, const number *values, const bool elide_zero_values=false)
void prepare_set_operation()
unsigned int n_block_cols() const
const value_type * const_pointer
TemporaryData temporary_data
const BlockIndices & get_row_indices() const
void set(const size_type i, const size_type j, const value_type value)
friend class MatrixIterator
BlockMatrixBase & copy_from(const BlockMatrixType &source)
std::size_t memory_consumption() const
void add(const value_type factor, const BlockMatrixBase< MatrixType > &matrix)
const BlockType & block(const unsigned int row, const unsigned int column) const
typename numbers::NumberTraits< value_type >::real_type real_type
BlockIndices row_block_indices
~BlockMatrixBase() override
BlockType & block(const unsigned int row, const unsigned int column)
value_type matrix_scalar_product(const BlockVectorType &u, const BlockVectorType &v) const
const BlockIndices & get_column_indices() const
void set(const std::vector< size_type > &indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=false)
void add(const std::vector< size_type > &indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=true)
void add(const size_type i, const size_type j, const value_type value)
void set(const size_type row, const std::vector< size_type > &col_indices, const std::vector< number > &values, const bool elide_zero_values=false)
value_type diag_element(const size_type i) const
void vmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
MatrixIterator< BlockMatrixIterators::Accessor< BlockMatrixBase, false > > iterator
Table< 2, ObserverPointer< BlockType, BlockMatrixBase< SparseMatrix< number > > > > sub_objects
iterator begin(const size_type r)
const_iterator begin(const size_type r) const
BlockMatrixBase & operator/=(const value_type factor)
void Tvmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
iterator end(const size_type r)
const_iterator end(const size_type r) const
void set(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, const FullMatrix< number > &full_matrix, const bool elide_zero_values=false)
unsigned int block_row() const
types::global_dof_index size_type
unsigned int block_column() const
typename BlockMatrixType::value_type value_type
Accessor(BlockMatrixType *m, const size_type row, const size_type col)
BlockMatrixType MatrixType
BlockMatrixType::BlockType::iterator base_iterator
bool operator==(const Accessor &a) const
void set_value(value_type newval) const
types::global_dof_index size_type
typename BlockMatrixType::value_type value_type
const BlockMatrixType MatrixType
typename BlockMatrixType::value_type value_type
bool operator==(const Accessor &a) const
Accessor(const Accessor< BlockMatrixType, false > &)
const BlockMatrixType * matrix
BlockMatrixType::BlockType::const_iterator base_iterator
Accessor(const BlockMatrixType *m, const size_type row, const size_type col)
types::global_dof_index size_type
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcIncompatibleColNumbers(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcIteratorPastEnd()
#define AssertIsFinite(number)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDivideByZero()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcMessage(std::string arg1)
const bool IsBlockVector< VectorType >::value
types::global_dof_index size_type
@ matrix
Contents is actually a matrix.
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
VectorType::value_type * begin(VectorType &V)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
constexpr types::global_dof_index invalid_size_type
constexpr unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
std::vector< std::vector< size_type > > column_indices
std::vector< std::vector< value_type > > column_values
TemporaryData & operator=(const TemporaryData &)
std::vector< size_type > counter_within_block