13#ifndef dealii_block_matrix_base_h
14#define dealii_block_matrix_base_h
59 template <
typename BlockMatrixType>
107 template <
typename BlockMatrixType,
bool Constness>
114 template <
typename BlockMatrixType>
191 friend class ::MatrixIterator;
193 friend class Accessor<BlockMatrixType, true>;
202 template <
typename BlockMatrixType>
281 friend class ::MatrixIterator;
346template <
typename MatrixType>
400 template <
typename BlockMatrixType>
408 block(
const unsigned int row,
const unsigned int column);
416 block(
const unsigned int row,
const unsigned int column)
const;
470 template <
typename number>
472 set(
const std::vector<size_type> &indices,
474 const bool elide_zero_values =
false);
481 template <
typename number>
483 set(
const std::vector<size_type> &row_indices,
484 const std::vector<size_type> &col_indices,
486 const bool elide_zero_values =
false);
498 template <
typename number>
501 const std::vector<size_type> &col_indices,
502 const std::vector<number> &values,
503 const bool elide_zero_values =
false);
514 template <
typename number>
519 const number *values,
520 const bool elide_zero_values =
false);
544 template <
typename number>
546 add(
const std::vector<size_type> &indices,
548 const bool elide_zero_values =
true);
555 template <
typename number>
557 add(
const std::vector<size_type> &row_indices,
558 const std::vector<size_type> &col_indices,
560 const bool elide_zero_values =
true);
571 template <
typename number>
574 const std::vector<size_type> &col_indices,
575 const std::vector<number> &values,
576 const bool elide_zero_values =
true);
587 template <
typename number>
592 const number *values,
593 const bool elide_zero_values =
true,
594 const bool col_indices_are_sorted =
false);
670 template <
typename BlockVectorType>
672 vmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
679 template <
typename BlockVectorType>
681 Tvmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
695 template <
typename BlockVectorType>
709 template <
typename BlockVectorType>
712 const BlockVectorType &v)
const;
717 template <
typename BlockVectorType>
720 const BlockVectorType &x,
721 const BlockVectorType &b)
const;
730 print(std::ostream &out,
const bool alternative_output =
false)
const;
812 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
813 <<
',' << arg4 <<
"] have differing row numbers.");
822 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
823 <<
',' << arg4 <<
"] have differing column numbers.");
883 template <
typename BlockVectorType>
897 template <
typename BlockVectorType,
typename VectorType>
911 template <
typename BlockVectorType,
typename VectorType>
925 template <
typename VectorType>
940 template <
typename BlockVectorType>
954 template <
typename BlockVectorType,
typename VectorType>
968 template <
typename BlockVectorType,
typename VectorType>
982 template <
typename VectorType>
1066 template <
typename,
bool>
1082 template <
typename BlockMatrixType>
1089 template <
typename BlockMatrixType>
1091 AccessorBase<BlockMatrixType>::block_row()
const
1099 template <
typename BlockMatrixType>
1101 AccessorBase<BlockMatrixType>::block_column()
const
1109 template <
typename BlockMatrixType>
1110 inline Accessor<BlockMatrixType, true>::Accessor(
1111 const BlockMatrixType *matrix,
1112 const size_type row,
1113 const size_type col)
1121 if (row < matrix->
m())
1123 const std::pair<unsigned int, size_type> indices =
1124 matrix->row_block_indices.global_to_local(row);
1128 for (
unsigned int bc = 0; bc <
matrix->n_block_cols(); ++bc)
1131 matrix->block(indices.first, bc).begin(indices.second);
1132 if (base_iterator !=
1133 matrix->block(indices.first, bc).end(indices.second))
1135 this->row_block = indices.first;
1136 this->col_block = bc;
1147 *
this =
Accessor(matrix, row + 1, 0);
1172 template <
typename BlockMatrixType>
1173 inline Accessor<BlockMatrixType, true>::Accessor(
1174 const Accessor<BlockMatrixType, false> &other)
1176 , base_iterator(other.base_iterator)
1178 this->row_block = other.row_block;
1179 this->col_block = other.col_block;
1183 template <
typename BlockMatrixType>
1184 inline typename Accessor<BlockMatrixType, true>::size_type
1185 Accessor<BlockMatrixType, true>::row()
const
1190 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1191 base_iterator->row());
1195 template <
typename BlockMatrixType>
1196 inline typename Accessor<BlockMatrixType, true>::size_type
1197 Accessor<BlockMatrixType, true>::column()
const
1202 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1203 base_iterator->column());
1207 template <
typename BlockMatrixType>
1208 inline typename Accessor<BlockMatrixType, true>::value_type
1209 Accessor<BlockMatrixType, true>::value()
const
1216 return base_iterator->value();
1221 template <
typename BlockMatrixType>
1223 Accessor<BlockMatrixType, true>::advance()
1231 size_type local_row = base_iterator->row();
1242 while (base_iterator ==
1243 matrix->block(this->row_block, this->col_block).end(local_row))
1248 if (this->col_block < matrix->n_block_cols() - 1)
1252 matrix->block(this->row_block, this->col_block).begin(local_row);
1258 this->col_block = 0;
1268 matrix->block(this->row_block, this->col_block).m())
1272 if (this->row_block ==
matrix->n_block_rows())
1281 matrix->block(this->row_block, this->col_block).begin(local_row);
1287 template <
typename BlockMatrixType>
1289 Accessor<BlockMatrixType, true>::operator==(
const Accessor &a)
const
1291 if (matrix != a.matrix)
1294 if (this->row_block == a.row_block && this->col_block == a.col_block)
1301 (base_iterator == a.base_iterator));
1309 template <
typename BlockMatrixType>
1310 inline Accessor<BlockMatrixType, false>::Accessor(BlockMatrixType *matrix,
1311 const size_type row,
1312 const size_type col)
1319 if (row < matrix->
m())
1321 const std::pair<unsigned int, size_type> indices =
1322 matrix->row_block_indices.global_to_local(row);
1329 matrix->block(indices.first, bc).begin(indices.second);
1330 if (base_iterator !=
1331 matrix->block(indices.first, bc).end(indices.second))
1333 this->row_block = indices.first;
1334 this->col_block = bc;
1345 *
this =
Accessor(matrix, row + 1, 0);
1357 template <
typename BlockMatrixType>
1358 inline typename Accessor<BlockMatrixType, false>::size_type
1359 Accessor<BlockMatrixType, false>::row()
const
1364 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1365 base_iterator->row());
1369 template <
typename BlockMatrixType>
1370 inline typename Accessor<BlockMatrixType, false>::size_type
1371 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
1390 return base_iterator->value();
1395 template <
typename BlockMatrixType>
1397 Accessor<BlockMatrixType, false>::set_value(
1398 typename Accessor<BlockMatrixType, false>::value_type newval)
const
1405 base_iterator->value() = newval;
1410 template <
typename BlockMatrixType>
1412 Accessor<BlockMatrixType, false>::advance()
1420 size_type local_row = base_iterator->row();
1431 while (base_iterator ==
1432 matrix->block(this->row_block, this->col_block).end(local_row))
1437 if (this->col_block < matrix->n_block_cols() - 1)
1441 matrix->block(this->row_block, this->col_block).begin(local_row);
1447 this->col_block = 0;
1457 matrix->block(this->row_block, this->col_block).m())
1461 if (this->row_block ==
matrix->n_block_rows())
1470 matrix->block(this->row_block, this->col_block).begin(local_row);
1477 template <
typename BlockMatrixType>
1479 Accessor<BlockMatrixType, false>::operator==(
const Accessor &a)
const
1481 if (matrix != a.matrix)
1484 if (this->row_block == a.row_block && this->col_block == a.col_block)
1491 (base_iterator == a.base_iterator));
1500template <
typename MatrixType>
1512template <
typename MatrixType>
1513template <
typename BlockMatrixType>
1517 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1518 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1519 block(r, c).
copy_from(source.block(r, c));
1525template <
typename MatrixType>
1536 sizeof(temporary_data.mutex);
1538 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1539 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1550template <
typename MatrixType>
1554 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1555 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1558 this->sub_objects[r][c] =
nullptr;
1561 sub_objects.reinit(0, 0);
1564 row_block_indices = column_block_indices =
BlockIndices();
1569template <
typename MatrixType>
1572 const unsigned int column)
1577 return *sub_objects[row][column];
1582template <
typename MatrixType>
1585 const unsigned int column)
const
1590 return *sub_objects[row][column];
1594template <
typename MatrixType>
1598 return row_block_indices.total_size();
1603template <
typename MatrixType>
1607 return column_block_indices.total_size();
1612template <
typename MatrixType>
1616 return column_block_indices.size();
1621template <
typename MatrixType>
1625 return row_block_indices.size();
1633template <
typename MatrixType>
1639 prepare_set_operation();
1643 const std::pair<unsigned int, size_type>
1644 row_index = row_block_indices.global_to_local(i),
1645 col_index = column_block_indices.global_to_local(j);
1646 block(row_index.first, col_index.first)
1647 .set(row_index.second, col_index.second, value);
1652template <
typename MatrixType>
1653template <
typename number>
1656 const std::vector<size_type> &col_indices,
1658 const bool elide_zero_values)
1665 for (size_type i = 0; i < row_indices.size(); ++i)
1675template <
typename MatrixType>
1676template <
typename number>
1680 const bool elide_zero_values)
1686 for (size_type i = 0; i < indices.size(); ++i)
1696template <
typename MatrixType>
1697template <
typename number>
1700 const std::vector<size_type> &col_indices,
1701 const std::vector<number> &values,
1702 const bool elide_zero_values)
1719template <
typename MatrixType>
1720template <
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();
1732 std::scoped_lock lock(temporary_data.mutex);
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)
1779 if (value == number() && elide_zero_values ==
true)
1782 const std::pair<unsigned int, size_type> col_index =
1783 this->column_block_indices.global_to_local(col_indices[j]);
1786 temporary_data.counter_within_block[col_index.first]++;
1788 temporary_data.column_indices[col_index.first][local_index] =
1790 temporary_data.column_values[col_index.first][local_index] =
value;
1798 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1799 length += temporary_data.counter_within_block[i];
1808 const std::pair<unsigned int, size_type> row_index =
1809 this->row_block_indices.global_to_local(row);
1810 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
1812 if (temporary_data.counter_within_block[block_col] == 0)
1815 block(row_index.first, block_col)
1816 .set(row_index.second,
1817 temporary_data.counter_within_block[block_col],
1818 temporary_data.column_indices[block_col].data(),
1819 temporary_data.column_values[block_col].data(),
1826template <
typename MatrixType>
1834 prepare_add_operation();
1839 using MatrixTraits =
typename MatrixType::Traits;
1840 if ((MatrixTraits::zero_addition_can_be_elided ==
true) &&
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)
1848 .add(row_index.second, col_index.second, value);
1853template <
typename MatrixType>
1854template <
typename number>
1857 const std::vector<size_type> &col_indices,
1859 const bool elide_zero_values)
1866 for (size_type i = 0; i < row_indices.size(); ++i)
1876template <
typename MatrixType>
1877template <
typename number>
1881 const bool elide_zero_values)
1887 for (size_type i = 0; i < indices.size(); ++i)
1897template <
typename MatrixType>
1898template <
typename number>
1901 const std::vector<size_type> &col_indices,
1902 const std::vector<number> &values,
1903 const bool elide_zero_values)
1920template <
typename MatrixType>
1921template <
typename number>
1924 const size_type n_cols,
1925 const size_type *col_indices,
1926 const number *values,
1927 const bool elide_zero_values,
1928 const bool col_indices_are_sorted)
1930 prepare_add_operation();
1935 if (col_indices_are_sorted ==
true)
1942 for (size_type i = 1; i < n_cols; ++i)
1943 if (col_indices[i] <= before)
1946 ExcMessage(
"Flag col_indices_are_sorted is set, but "
1947 "indices appear to not be sorted."));
1950 before = col_indices[i];
1952 const std::pair<unsigned int, size_type> row_index =
1953 this->row_block_indices.global_to_local(row);
1955 if (this->n_block_cols() > 1)
1959 col_indices + n_cols,
1960 this->column_block_indices.block_start(1));
1962 const size_type n_zero_block_indices = first_block - col_indices;
1963 block(row_index.first, 0)
1964 .add(row_index.second,
1965 n_zero_block_indices,
1969 col_indices_are_sorted);
1971 if (n_zero_block_indices < n_cols)
1973 n_cols - n_zero_block_indices,
1975 values + n_zero_block_indices,
1981 block(row_index.first, 0)
1982 .add(row_index.second,
1987 col_indices_are_sorted);
1994 std::scoped_lock lock(temporary_data.mutex);
1996 if (temporary_data.column_indices.size() < this->n_block_cols())
1998 temporary_data.column_indices.resize(this->n_block_cols());
1999 temporary_data.column_values.resize(this->n_block_cols());
2000 temporary_data.counter_within_block.resize(this->n_block_cols());
2013 if (temporary_data.column_indices[0].size() < n_cols)
2015 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2017 temporary_data.column_indices[i].resize(n_cols);
2018 temporary_data.column_values[i].resize(n_cols);
2024 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2025 temporary_data.counter_within_block[i] = 0;
2036 for (size_type j = 0; j < n_cols; ++j)
2040 if (value == number() && elide_zero_values ==
true)
2043 const std::pair<unsigned int, size_type> col_index =
2044 this->column_block_indices.global_to_local(col_indices[j]);
2047 temporary_data.counter_within_block[col_index.first]++;
2049 temporary_data.column_indices[col_index.first][local_index] =
2051 temporary_data.column_values[col_index.first][local_index] =
value;
2059 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2060 length += temporary_data.counter_within_block[i];
2069 const std::pair<unsigned int, size_type> row_index =
2070 this->row_block_indices.global_to_local(row);
2071 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
2073 if (temporary_data.counter_within_block[block_col] == 0)
2076 block(row_index.first, block_col)
2077 .add(row_index.second,
2078 temporary_data.counter_within_block[block_col],
2079 temporary_data.column_indices[block_col].data(),
2080 temporary_data.column_values[block_col].data(),
2082 col_indices_are_sorted);
2088template <
typename MatrixType>
2095 prepare_add_operation();
2100 using MatrixTraits =
typename MatrixType::Traits;
2101 if ((MatrixTraits::zero_addition_can_be_elided ==
true) && (factor == 0))
2104 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2105 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2108 block(row, col).add(factor,
matrix.block(row, col));
2113template <
typename MatrixType>
2116 const size_type j)
const
2118 const std::pair<unsigned int, size_type>
2119 row_index = row_block_indices.global_to_local(i),
2120 col_index = column_block_indices.global_to_local(j);
2121 return block(row_index.first, col_index.first)(row_index.second,
2127template <
typename MatrixType>
2131 const std::pair<unsigned int, size_type>
2132 row_index = row_block_indices.global_to_local(i),
2133 col_index = column_block_indices.global_to_local(j);
2134 return block(row_index.first, col_index.first)
2135 .el(row_index.second, col_index.second);
2140template <
typename MatrixType>
2146 const std::pair<unsigned int, size_type>
index =
2147 row_block_indices.global_to_local(i);
2153template <
typename MatrixType>
2157 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2158 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2159 block(r, c).compress(operation);
2164template <
typename MatrixType>
2171 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2172 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2173 block(r, c) *= factor;
2180template <
typename MatrixType>
2190 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2191 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2192 block(r, c) *= factor_inv;
2199template <
typename MatrixType>
2203 return this->row_block_indices;
2208template <
typename MatrixType>
2212 return this->column_block_indices;
2217template <
typename MatrixType>
2218template <
typename BlockVectorType>
2221 const BlockVectorType &src)
const
2223 Assert(dst.n_blocks() == n_block_rows(),
2225 Assert(src.n_blocks() == n_block_cols(),
2228 for (size_type row = 0; row < n_block_rows(); ++row)
2230 block(row, 0).vmult(dst.block(row), src.block(0));
2231 for (size_type col = 1; col < n_block_cols(); ++col)
2232 block(row, col).vmult_add(dst.block(row), src.block(col));
2238template <
typename MatrixType>
2239template <
typename BlockVectorType,
typename VectorType>
2243 const BlockVectorType &src)
const
2246 Assert(src.n_blocks() == n_block_cols(),
2249 block(0, 0).vmult(dst, src.block(0));
2250 for (size_type col = 1; col < n_block_cols(); ++col)
2251 block(0, col).vmult_add(dst, src.block(col));
2256template <
typename MatrixType>
2257template <
typename BlockVectorType,
typename VectorType>
2260 const VectorType &src)
const
2262 Assert(dst.n_blocks() == n_block_rows(),
2266 for (size_type row = 0; row < n_block_rows(); ++row)
2267 block(row, 0).vmult(dst.block(row), src);
2272template <
typename MatrixType>
2273template <
typename VectorType>
2277 const VectorType &src)
const
2282 block(0, 0).vmult(dst, src);
2287template <
typename MatrixType>
2288template <
typename BlockVectorType>
2291 const BlockVectorType &src)
const
2293 Assert(dst.n_blocks() == n_block_rows(),
2295 Assert(src.n_blocks() == n_block_cols(),
2298 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2299 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2300 block(row, col).vmult_add(dst.block(row), src.block(col));
2305template <
typename MatrixType>
2306template <
typename BlockVectorType>
2309 BlockVectorType &dst,
2310 const BlockVectorType &src)
const
2312 Assert(dst.n_blocks() == n_block_cols(),
2314 Assert(src.n_blocks() == n_block_rows(),
2319 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2321 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2322 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2328template <
typename MatrixType>
2329template <
typename BlockVectorType,
typename VectorType>
2332 const VectorType &src)
const
2334 Assert(dst.n_blocks() == n_block_cols(),
2340 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2341 block(0, col).Tvmult_add(dst.block(col), src);
2346template <
typename MatrixType>
2347template <
typename BlockVectorType,
typename VectorType>
2351 const BlockVectorType &src)
const
2354 Assert(src.n_blocks() == n_block_rows(),
2357 block(0, 0).Tvmult(dst, src.block(0));
2359 for (size_type row = 1; row < n_block_rows(); ++row)
2360 block(row, 0).Tvmult_add(dst, src.block(row));
2365template <
typename MatrixType>
2366template <
typename VectorType>
2370 const VectorType &src)
const
2375 block(0, 0).Tvmult(dst, src);
2380template <
typename MatrixType>
2381template <
typename BlockVectorType>
2384 const BlockVectorType &src)
const
2386 Assert(dst.n_blocks() == n_block_cols(),
2388 Assert(src.n_blocks() == n_block_rows(),
2391 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2392 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2393 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2398template <
typename MatrixType>
2399template <
typename BlockVectorType>
2404 Assert(v.n_blocks() == n_block_rows(),
2408 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2409 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2411 norm_sqr += block(row, col).matrix_norm_square(v.block(row));
2414 block(row, col).matrix_scalar_product(v.block(row), v.block(col));
2420template <
typename MatrixType>
2428 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2430 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2432 const value_type block_norm = block(row, col).frobenius_norm();
2433 norm_sqr += block_norm * block_norm;
2442template <
typename MatrixType>
2443template <
typename BlockVectorType>
2446 const BlockVectorType &u,
2447 const BlockVectorType &v)
const
2449 Assert(u.n_blocks() == n_block_rows(),
2451 Assert(v.n_blocks() == n_block_cols(),
2455 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2456 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2458 block(row, col).matrix_scalar_product(u.block(row), v.block(col));
2464template <
typename MatrixType>
2465template <
typename BlockVectorType>
2468 const BlockVectorType &x,
2469 const BlockVectorType &b)
const
2471 Assert(dst.n_blocks() == n_block_rows(),
2473 Assert(
b.n_blocks() == n_block_rows(),
2475 Assert(x.n_blocks() == n_block_cols(),
2491 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2493 block(row, 0).residual(dst.block(row), x.block(0),
b.block(row));
2495 for (size_type i = 0; i < dst.block(row).
size(); ++i)
2496 dst.block(row)(i) = -dst.block(row)(i);
2498 for (
unsigned int col = 1; col < n_block_cols(); ++col)
2499 block(row, col).vmult_add(dst.block(row), x.block(col));
2501 for (size_type i = 0; i < dst.block(row).size(); ++i)
2502 dst.block(row)(i) = -dst.block(row)(i);
2506 for (size_type row = 0; row < n_block_rows(); ++row)
2507 res += dst.block(row).norm_sqr();
2513template <
typename MatrixType>
2516 const bool alternative_output)
const
2518 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2519 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2521 if (!alternative_output)
2522 out <<
"Block (" << row <<
", " << col <<
')' << std::endl;
2524 block(row, col).print(out, alternative_output);
2530template <
typename MatrixType>
2539template <
typename MatrixType>
2548template <
typename MatrixType>
2558template <
typename MatrixType>
2568template <
typename MatrixType>
2577template <
typename MatrixType>
2586template <
typename MatrixType>
2596template <
typename MatrixType>
2606template <
typename MatrixType>
2610 std::vector<size_type> row_sizes(this->n_block_rows());
2611 std::vector<size_type> col_sizes(this->n_block_cols());
2615 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2616 row_sizes[r] = sub_objects[r][0]->m();
2620 for (
unsigned int c = 1; c < this->n_block_cols(); ++c)
2621 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2622 Assert(row_sizes[r] == sub_objects[r][c]->m(),
2623 ExcIncompatibleRowNumbers(r, 0, r, c));
2627 this->row_block_indices.reinit(row_sizes);
2631 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2632 col_sizes[c] = sub_objects[0][c]->n();
2633 for (
unsigned int r = 1; r < this->n_block_rows(); ++r)
2634 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2635 Assert(col_sizes[c] == sub_objects[r][c]->n(),
2636 ExcIncompatibleRowNumbers(0, c, r, c));
2640 this->column_block_indices.reinit(col_sizes);
2645template <
typename MatrixType>
2649 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2650 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2651 block(row, col).prepare_add();
2656template <
typename MatrixType>
2660 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2661 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2662 block(row, col).prepare_set();
* x_component_mask set(0, true)
* * const_iterator()=default
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
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)
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
Table< 2, ObserverPointer< BlockType, BlockMatrixBase< MatrixType > > > 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
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
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)
#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)
types::global_dof_index size_type
@ matrix
Contents is actually a matrix.
Tpetra::CrsMatrix< Number, LO, GO, NodeType< MemorySpace > > MatrixType
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)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
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