16#ifndef dealii_block_matrix_base_h
17#define dealii_block_matrix_base_h
62 template <
class BlockMatrixType>
114 template <
class BlockMatrixType,
bool Constness>
121 template <
class BlockMatrixType>
199 friend class Accessor<BlockMatrixType, true>;
206 template <
class BlockMatrixType>
285 friend class ::MatrixIterator;
350template <
typename MatrixType>
404 template <
class BlockMatrixType>
412 block(
const unsigned int row,
const unsigned int column);
420 block(
const unsigned int row,
const unsigned int column)
const;
474 template <
typename number>
476 set(
const std::vector<size_type> &indices,
478 const bool elide_zero_values =
false);
485 template <
typename number>
487 set(
const std::vector<size_type> &row_indices,
488 const std::vector<size_type> &col_indices,
490 const bool elide_zero_values =
false);
502 template <
typename number>
505 const std::vector<size_type> &col_indices,
506 const std::vector<number> & values,
507 const bool elide_zero_values =
false);
518 template <
typename number>
523 const number * values,
524 const bool elide_zero_values =
false);
548 template <
typename number>
550 add(
const std::vector<size_type> &indices,
552 const bool elide_zero_values =
true);
559 template <
typename number>
561 add(
const std::vector<size_type> &row_indices,
562 const std::vector<size_type> &col_indices,
564 const bool elide_zero_values =
true);
575 template <
typename number>
578 const std::vector<size_type> &col_indices,
579 const std::vector<number> & values,
580 const bool elide_zero_values =
true);
591 template <
typename number>
596 const number * values,
597 const bool elide_zero_values =
true,
598 const bool col_indices_are_sorted =
false);
674 template <
class BlockVectorType>
676 vmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
683 template <
class BlockVectorType>
685 Tvmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
699 template <
class BlockVectorType>
713 template <
class BlockVectorType>
716 const BlockVectorType &v)
const;
721 template <
class BlockVectorType>
724 const BlockVectorType &x,
725 const BlockVectorType &b)
const;
734 print(std::ostream &out,
const bool alternative_output =
false)
const;
816 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
817 <<
',' << arg4 <<
"] have differing row numbers.");
826 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
827 <<
',' << arg4 <<
"] have differing column numbers.");
887 template <
class BlockVectorType>
901 template <
class BlockVectorType,
class VectorType>
915 template <
class BlockVectorType,
class VectorType>
929 template <
class VectorType>
944 template <
class BlockVectorType>
958 template <
class BlockVectorType,
class VectorType>
972 template <
class BlockVectorType,
class VectorType>
986 template <
class VectorType>
1070 template <
typename,
bool>
1086 template <
class BlockMatrixType>
1093 template <
class BlockMatrixType>
1095 AccessorBase<BlockMatrixType>::block_row()
const
1103 template <
class BlockMatrixType>
1105 AccessorBase<BlockMatrixType>::block_column()
const
1113 template <
class BlockMatrixType>
1114 inline Accessor<BlockMatrixType, true>::Accessor(
1115 const BlockMatrixType *matrix,
1116 const size_type row,
1117 const size_type col)
1126 if (row < matrix->
m())
1128 const std::pair<unsigned int, size_type> indices =
1129 matrix->row_block_indices.global_to_local(row);
1133 for (
unsigned int bc = 0; bc <
matrix->n_block_cols(); ++bc)
1136 matrix->block(indices.first, bc).begin(indices.second);
1137 if (base_iterator !=
1138 matrix->block(indices.first, bc).end(indices.second))
1140 this->row_block = indices.first;
1141 this->col_block = bc;
1152 *
this =
Accessor(matrix, row + 1, 0);
1177 template <
class BlockMatrixType>
1178 inline Accessor<BlockMatrixType, true>::Accessor(
1179 const Accessor<BlockMatrixType, false> &other)
1181 , base_iterator(other.base_iterator)
1183 this->row_block = other.row_block;
1184 this->col_block = other.col_block;
1188 template <
class BlockMatrixType>
1189 inline typename Accessor<BlockMatrixType, true>::size_type
1190 Accessor<BlockMatrixType, true>::row()
const
1195 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1196 base_iterator->row());
1200 template <
class BlockMatrixType>
1201 inline typename Accessor<BlockMatrixType, true>::size_type
1202 Accessor<BlockMatrixType, true>::column()
const
1207 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1208 base_iterator->column());
1212 template <
class BlockMatrixType>
1213 inline typename Accessor<BlockMatrixType, true>::value_type
1214 Accessor<BlockMatrixType, true>::value()
const
1221 return base_iterator->value();
1226 template <
class BlockMatrixType>
1228 Accessor<BlockMatrixType, true>::advance()
1236 size_type local_row = base_iterator->row();
1247 while (base_iterator ==
1248 matrix->block(this->row_block, this->col_block).end(local_row))
1253 if (this->col_block < matrix->n_block_cols() - 1)
1257 matrix->block(this->row_block, this->col_block).begin(local_row);
1263 this->col_block = 0;
1273 matrix->block(this->row_block, this->col_block).m())
1277 if (this->row_block ==
matrix->n_block_rows())
1286 matrix->block(this->row_block, this->col_block).begin(local_row);
1292 template <
class BlockMatrixType>
1294 Accessor<BlockMatrixType, true>::operator==(
const Accessor &a)
const
1296 if (matrix != a.matrix)
1299 if (this->row_block == a.row_block && this->col_block == a.col_block)
1306 (base_iterator == a.base_iterator));
1314 template <
class BlockMatrixType>
1315 inline Accessor<BlockMatrixType, false>::Accessor(BlockMatrixType *matrix,
1316 const size_type row,
1317 const size_type col)
1325 if (row < matrix->
m())
1327 const std::pair<unsigned int, size_type> indices =
1328 matrix->row_block_indices.global_to_local(row);
1335 matrix->block(indices.first, bc).begin(indices.second);
1336 if (base_iterator !=
1337 matrix->block(indices.first, bc).end(indices.second))
1339 this->row_block = indices.first;
1340 this->col_block = bc;
1351 *
this =
Accessor(matrix, row + 1, 0);
1363 template <
class BlockMatrixType>
1364 inline typename Accessor<BlockMatrixType, false>::size_type
1365 Accessor<BlockMatrixType, false>::row()
const
1369 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1370 base_iterator->row());
1374 template <
class BlockMatrixType>
1375 inline typename Accessor<BlockMatrixType, false>::size_type
1376 Accessor<BlockMatrixType, false>::column()
const
1380 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1381 base_iterator->column());
1385 template <
class BlockMatrixType>
1386 inline typename Accessor<BlockMatrixType, false>::value_type
1387 Accessor<BlockMatrixType, false>::value()
const
1392 return base_iterator->value();
1397 template <
class BlockMatrixType>
1399 Accessor<BlockMatrixType, false>::set_value(
1400 typename Accessor<BlockMatrixType, false>::value_type newval)
const
1405 base_iterator->value() = newval;
1410 template <
class BlockMatrixType>
1412 Accessor<BlockMatrixType, false>::advance()
1418 size_type local_row = base_iterator->row();
1429 while (base_iterator ==
1430 matrix->block(this->row_block, this->col_block).end(local_row))
1435 if (this->col_block < matrix->n_block_cols() - 1)
1439 matrix->block(this->row_block, this->col_block).begin(local_row);
1445 this->col_block = 0;
1455 matrix->block(this->row_block, this->col_block).m())
1459 if (this->row_block ==
matrix->n_block_rows())
1468 matrix->block(this->row_block, this->col_block).begin(local_row);
1475 template <
class BlockMatrixType>
1477 Accessor<BlockMatrixType, false>::operator==(
const Accessor &a)
const
1479 if (matrix != a.matrix)
1482 if (this->row_block == a.row_block && this->col_block == a.col_block)
1489 (base_iterator == a.base_iterator));
1498template <
typename MatrixType>
1510template <
class MatrixType>
1511template <
class BlockMatrixType>
1515 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1516 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1517 block(r, c).
copy_from(source.block(r, c));
1523template <
class MatrixType>
1534 sizeof(temporary_data.mutex);
1536 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1537 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1539 MatrixType *p = this->sub_objects[r][c];
1548template <
class MatrixType>
1552 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1553 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1555 MatrixType *p = this->sub_objects[r][c];
1556 this->sub_objects[r][c] =
nullptr;
1559 sub_objects.reinit(0, 0);
1562 row_block_indices = column_block_indices =
BlockIndices();
1567template <
class MatrixType>
1570 const unsigned int column)
1575 return *sub_objects[row][column];
1580template <
class MatrixType>
1583 const unsigned int column)
const
1588 return *sub_objects[row][column];
1592template <
class MatrixType>
1596 return row_block_indices.total_size();
1601template <
class MatrixType>
1605 return column_block_indices.total_size();
1610template <
class MatrixType>
1614 return column_block_indices.size();
1619template <
class MatrixType>
1623 return row_block_indices.size();
1631template <
class MatrixType>
1635 const value_type value)
1637 prepare_set_operation();
1641 const std::pair<unsigned int, size_type>
1642 row_index = row_block_indices.global_to_local(i),
1643 col_index = column_block_indices.global_to_local(j);
1644 block(row_index.first, col_index.first)
1645 .set(row_index.second, col_index.second, value);
1650template <
class MatrixType>
1651template <
typename number>
1654 const std::vector<size_type> &col_indices,
1656 const bool elide_zero_values)
1663 for (size_type i = 0; i < row_indices.size(); ++i)
1673template <
class MatrixType>
1674template <
typename number>
1678 const bool elide_zero_values)
1684 for (size_type i = 0; i < indices.size(); ++i)
1694template <
class MatrixType>
1695template <
typename number>
1698 const std::vector<size_type> &col_indices,
1699 const std::vector<number> & values,
1700 const bool elide_zero_values)
1717template <
class MatrixType>
1718template <
typename number>
1721 const size_type n_cols,
1722 const size_type *col_indices,
1723 const number * values,
1724 const bool elide_zero_values)
1726 prepare_set_operation();
1730 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1733 if (temporary_data.column_indices.size() < this->n_block_cols())
1735 temporary_data.column_indices.resize(this->n_block_cols());
1736 temporary_data.column_values.resize(this->n_block_cols());
1737 temporary_data.counter_within_block.resize(this->n_block_cols());
1750 if (temporary_data.column_indices[0].size() < n_cols)
1752 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1754 temporary_data.column_indices[i].resize(n_cols);
1755 temporary_data.column_values[i].resize(n_cols);
1761 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1762 temporary_data.counter_within_block[i] = 0;
1773 for (size_type j = 0; j < n_cols; ++j)
1777 if (value == number() && elide_zero_values ==
true)
1780 const std::pair<unsigned int, size_type> col_index =
1781 this->column_block_indices.global_to_local(col_indices[j]);
1784 temporary_data.counter_within_block[col_index.first]++;
1786 temporary_data.column_indices[col_index.first][local_index] =
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> row_index =
1806 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)
1813 .set(row_index.second,
1814 temporary_data.counter_within_block[block_col],
1815 temporary_data.column_indices[block_col].data(),
1816 temporary_data.column_values[block_col].data(),
1823template <
class MatrixType>
1827 const value_type value)
1831 prepare_add_operation();
1836 using MatrixTraits =
typename MatrixType::Traits;
1837 if ((MatrixTraits::zero_addition_can_be_elided ==
true) &&
1838 (value == value_type()))
1841 const std::pair<unsigned int, size_type>
1842 row_index = row_block_indices.global_to_local(i),
1843 col_index = column_block_indices.global_to_local(j);
1844 block(row_index.first, col_index.first)
1845 .add(row_index.second, col_index.second, value);
1850template <
class MatrixType>
1851template <
typename number>
1854 const std::vector<size_type> &col_indices,
1856 const bool elide_zero_values)
1863 for (size_type i = 0; i < row_indices.size(); ++i)
1873template <
class MatrixType>
1874template <
typename number>
1878 const bool elide_zero_values)
1884 for (size_type i = 0; i < indices.size(); ++i)
1894template <
class MatrixType>
1895template <
typename number>
1898 const std::vector<size_type> &col_indices,
1899 const std::vector<number> & values,
1900 const bool elide_zero_values)
1917template <
class MatrixType>
1918template <
typename number>
1921 const size_type n_cols,
1922 const size_type *col_indices,
1923 const number * values,
1924 const bool elide_zero_values,
1925 const bool col_indices_are_sorted)
1927 prepare_add_operation();
1932 if (col_indices_are_sorted ==
true)
1938 for (size_type i = 1; i < n_cols; ++i)
1939 if (col_indices[i] <= before)
1941 ExcMessage(
"Flag col_indices_are_sorted is set, but "
1942 "indices appear to not be sorted.")) else before =
1945 const std::pair<unsigned int, size_type> row_index =
1946 this->row_block_indices.global_to_local(row);
1948 if (this->n_block_cols() > 1)
1952 col_indices + n_cols,
1953 this->column_block_indices.block_start(1));
1955 const size_type n_zero_block_indices = first_block - col_indices;
1956 block(row_index.first, 0)
1957 .add(row_index.second,
1958 n_zero_block_indices,
1962 col_indices_are_sorted);
1964 if (n_zero_block_indices < n_cols)
1966 n_cols - n_zero_block_indices,
1968 values + n_zero_block_indices,
1974 block(row_index.first, 0)
1975 .add(row_index.second,
1980 col_indices_are_sorted);
1987 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1989 if (temporary_data.column_indices.size() < this->n_block_cols())
1991 temporary_data.column_indices.resize(this->n_block_cols());
1992 temporary_data.column_values.resize(this->n_block_cols());
1993 temporary_data.counter_within_block.resize(this->n_block_cols());
2006 if (temporary_data.column_indices[0].size() < n_cols)
2008 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2010 temporary_data.column_indices[i].resize(n_cols);
2011 temporary_data.column_values[i].resize(n_cols);
2017 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2018 temporary_data.counter_within_block[i] = 0;
2029 for (size_type j = 0; j < n_cols; ++j)
2033 if (value == number() && elide_zero_values ==
true)
2036 const std::pair<unsigned int, size_type> col_index =
2037 this->column_block_indices.global_to_local(col_indices[j]);
2040 temporary_data.counter_within_block[col_index.first]++;
2042 temporary_data.column_indices[col_index.first][local_index] =
2044 temporary_data.column_values[col_index.first][local_index] =
value;
2051 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2052 length += temporary_data.counter_within_block[i];
2061 const std::pair<unsigned int, size_type> row_index =
2062 this->row_block_indices.global_to_local(row);
2063 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
2065 if (temporary_data.counter_within_block[block_col] == 0)
2068 block(row_index.first, block_col)
2069 .add(row_index.second,
2070 temporary_data.counter_within_block[block_col],
2071 temporary_data.column_indices[block_col].data(),
2072 temporary_data.column_values[block_col].data(),
2074 col_indices_are_sorted);
2080template <
class MatrixType>
2087 prepare_add_operation();
2092 using MatrixTraits =
typename MatrixType::Traits;
2093 if ((MatrixTraits::zero_addition_can_be_elided ==
true) && (factor == 0))
2096 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2097 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2100 block(row, col).add(factor,
matrix.block(row, col));
2105template <
class MatrixType>
2108 const size_type j)
const
2110 const std::pair<unsigned int, size_type>
2111 row_index = row_block_indices.global_to_local(i),
2112 col_index = column_block_indices.global_to_local(j);
2113 return block(row_index.first, col_index.first)(row_index.second,
2119template <
class MatrixType>
2123 const std::pair<unsigned int, size_type>
2124 row_index = row_block_indices.global_to_local(i),
2125 col_index = column_block_indices.global_to_local(j);
2126 return block(row_index.first, col_index.first)
2127 .el(row_index.second, col_index.second);
2132template <
class MatrixType>
2138 const std::pair<unsigned int, size_type>
index =
2139 row_block_indices.global_to_local(i);
2145template <
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);
2156template <
class MatrixType>
2163 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2164 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2165 block(r, c) *= factor;
2172template <
class MatrixType>
2180 const value_type factor_inv = 1. / factor;
2182 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2183 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2184 block(r, c) *= factor_inv;
2191template <
class MatrixType>
2195 return this->row_block_indices;
2200template <
class MatrixType>
2204 return this->column_block_indices;
2209template <
class MatrixType>
2210template <
class BlockVectorType>
2213 const BlockVectorType &src)
const
2215 Assert(dst.n_blocks() == n_block_rows(),
2217 Assert(src.n_blocks() == n_block_cols(),
2220 for (size_type row = 0; row < n_block_rows(); ++row)
2222 block(row, 0).vmult(dst.block(row), src.block(0));
2223 for (size_type col = 1; col < n_block_cols(); ++col)
2224 block(row, col).vmult_add(dst.block(row), src.block(col));
2230template <
class MatrixType>
2231template <
class BlockVectorType,
class VectorType>
2235 const BlockVectorType &src)
const
2238 Assert(src.n_blocks() == n_block_cols(),
2241 block(0, 0).vmult(dst, src.block(0));
2242 for (size_type col = 1; col < n_block_cols(); ++col)
2243 block(0, col).vmult_add(dst, src.block(col));
2248template <
class MatrixType>
2249template <
class BlockVectorType,
class VectorType>
2252 const VectorType &src)
const
2254 Assert(dst.n_blocks() == n_block_rows(),
2258 for (size_type row = 0; row < n_block_rows(); ++row)
2259 block(row, 0).vmult(dst.block(row), src);
2264template <
class MatrixType>
2265template <
class VectorType>
2269 const VectorType &src)
const
2274 block(0, 0).vmult(dst, src);
2279template <
class MatrixType>
2280template <
class BlockVectorType>
2283 const BlockVectorType &src)
const
2285 Assert(dst.n_blocks() == n_block_rows(),
2287 Assert(src.n_blocks() == n_block_cols(),
2290 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2291 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2292 block(row, col).vmult_add(dst.block(row), src.block(col));
2297template <
class MatrixType>
2298template <
class BlockVectorType>
2301 BlockVectorType & dst,
2302 const BlockVectorType &src)
const
2304 Assert(dst.n_blocks() == n_block_cols(),
2306 Assert(src.n_blocks() == n_block_rows(),
2311 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2313 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2314 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2320template <
class MatrixType>
2321template <
class BlockVectorType,
class VectorType>
2324 const VectorType &src)
const
2326 Assert(dst.n_blocks() == n_block_cols(),
2332 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2333 block(0, col).Tvmult_add(dst.block(col), src);
2338template <
class MatrixType>
2339template <
class BlockVectorType,
class VectorType>
2343 const BlockVectorType &src)
const
2346 Assert(src.n_blocks() == n_block_rows(),
2349 block(0, 0).Tvmult(dst, src.block(0));
2351 for (size_type row = 1; row < n_block_rows(); ++row)
2352 block(row, 0).Tvmult_add(dst, src.block(row));
2357template <
class MatrixType>
2358template <
class VectorType>
2362 const VectorType &src)
const
2367 block(0, 0).Tvmult(dst, src);
2372template <
class MatrixType>
2373template <
class BlockVectorType>
2376 const BlockVectorType &src)
const
2378 Assert(dst.n_blocks() == n_block_cols(),
2380 Assert(src.n_blocks() == n_block_rows(),
2383 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2384 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2385 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2390template <
class MatrixType>
2391template <
class BlockVectorType>
2396 Assert(v.n_blocks() == n_block_rows(),
2399 value_type norm_sqr = 0;
2400 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2401 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2403 norm_sqr += block(row, col).matrix_norm_square(v.block(row));
2406 block(row, col).matrix_scalar_product(v.block(row), v.block(col));
2412template <
class MatrixType>
2416 value_type norm_sqr = 0;
2420 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2422 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2424 const value_type block_norm = block(row, col).frobenius_norm();
2425 norm_sqr += block_norm * block_norm;
2434template <
class MatrixType>
2435template <
class BlockVectorType>
2438 const BlockVectorType &u,
2439 const BlockVectorType &v)
const
2441 Assert(u.n_blocks() == n_block_rows(),
2443 Assert(v.n_blocks() == n_block_cols(),
2446 value_type result = 0;
2447 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2448 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2450 block(row, col).matrix_scalar_product(u.block(row), v.block(col));
2456template <
class MatrixType>
2457template <
class BlockVectorType>
2460 const BlockVectorType &x,
2461 const BlockVectorType &b)
const
2463 Assert(dst.n_blocks() == n_block_rows(),
2465 Assert(
b.n_blocks() == n_block_rows(),
2467 Assert(x.n_blocks() == n_block_cols(),
2483 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2485 block(row, 0).residual(dst.block(row), x.block(0),
b.block(row));
2487 for (size_type i = 0; i < dst.block(row).size(); ++i)
2488 dst.block(row)(i) = -dst.block(row)(i);
2490 for (
unsigned int col = 1; col < n_block_cols(); ++col)
2491 block(row, col).vmult_add(dst.block(row), x.block(col));
2493 for (size_type i = 0; i < dst.block(row).size(); ++i)
2494 dst.block(row)(i) = -dst.block(row)(i);
2498 for (size_type row = 0; row < n_block_rows(); ++row)
2499 res += dst.block(row).norm_sqr();
2505template <
class MatrixType>
2508 const bool alternative_output)
const
2510 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2511 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2513 if (!alternative_output)
2514 out <<
"Block (" << row <<
", " << col <<
')' << std::endl;
2516 block(row, col).print(out, alternative_output);
2522template <
class MatrixType>
2526 return const_iterator(
this, 0);
2531template <
class MatrixType>
2535 return const_iterator(
this, m());
2540template <
class MatrixType>
2545 return const_iterator(
this, r);
2550template <
class MatrixType>
2555 return const_iterator(
this, r + 1);
2560template <
class MatrixType>
2564 return iterator(
this, 0);
2569template <
class MatrixType>
2573 return iterator(
this, m());
2578template <
class MatrixType>
2583 return iterator(
this, r);
2588template <
class MatrixType>
2593 return iterator(
this, r + 1);
2598template <
class MatrixType>
2602 std::vector<size_type> row_sizes(this->n_block_rows());
2603 std::vector<size_type> col_sizes(this->n_block_cols());
2607 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2608 row_sizes[r] = sub_objects[r][0]->m();
2612 for (
unsigned int c = 1; c < this->n_block_cols(); ++c)
2613 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2614 Assert(row_sizes[r] == sub_objects[r][c]->m(),
2615 ExcIncompatibleRowNumbers(r, 0, r, c));
2619 this->row_block_indices.reinit(row_sizes);
2623 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2624 col_sizes[c] = sub_objects[0][c]->n();
2625 for (
unsigned int r = 1; r < this->n_block_rows(); ++r)
2626 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2627 Assert(col_sizes[c] == sub_objects[r][c]->n(),
2628 ExcIncompatibleRowNumbers(0, c, r, c));
2632 this->column_block_indices.reinit(col_sizes);
2637template <
class MatrixType>
2641 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2642 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2643 block(row, col).prepare_add();
2648template <
class MatrixType>
2652 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2653 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2654 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
Table< 2, SmartPointer< BlockType, BlockMatrixBase< MatrixType > > > sub_objects
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
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
#define DEAL_II_NAMESPACE_CLOSE
__global__ void set(Number *val, const Number s, const size_type N)
#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)
@ matrix
Contents is actually a matrix.
types::global_dof_index size_type
std::enable_if_t< std::is_fundamental< T >::value, 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)
static const unsigned int invalid_unsigned_int
const types::global_dof_index invalid_size_type
::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