16#ifndef dealii_block_matrix_base_h
17#define dealii_block_matrix_base_h
60 template <
class BlockMatrixType>
112 template <
class BlockMatrixType,
bool Constness>
119 template <
class BlockMatrixType>
197 friend class Accessor<BlockMatrixType, true>;
204 template <
class BlockMatrixType>
283 friend class ::MatrixIterator;
348template <
typename MatrixType>
402 template <
class 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>
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>
595 const bool elide_zero_values =
true,
596 const bool col_indices_are_sorted =
false);
672 template <
class BlockVectorType>
674 vmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
681 template <
class BlockVectorType>
683 Tvmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
697 template <
class BlockVectorType>
711 template <
class BlockVectorType>
714 const BlockVectorType &v)
const;
719 template <
class 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 <
class BlockVectorType>
899 template <
class BlockVectorType,
class VectorType>
913 template <
class BlockVectorType,
class VectorType>
927 template <
class VectorType>
942 template <
class BlockVectorType>
956 template <
class BlockVectorType,
class VectorType>
970 template <
class BlockVectorType,
class VectorType>
984 template <
class VectorType>
1068 template <
typename,
bool>
1084 template <
class BlockMatrixType>
1091 template <
class BlockMatrixType>
1093 AccessorBase<BlockMatrixType>::block_row()
const
1101 template <
class BlockMatrixType>
1103 AccessorBase<BlockMatrixType>::block_column()
const
1111 template <
class BlockMatrixType>
1112 inline Accessor<BlockMatrixType, true>::Accessor(
1113 const BlockMatrixType *
matrix,
1124 if (row < matrix->
m())
1126 const std::pair<unsigned int, size_type> indices =
1127 matrix->row_block_indices.global_to_local(row);
1131 for (
unsigned int bc = 0; bc <
matrix->n_block_cols(); ++bc)
1134 matrix->block(indices.first, bc).begin(indices.second);
1135 if (base_iterator !=
1136 matrix->block(indices.first, bc).end(indices.second))
1138 this->row_block = indices.first;
1139 this->col_block = bc;
1150 *
this = Accessor(
matrix, row + 1, 0);
1175 template <
class BlockMatrixType>
1176 inline Accessor<BlockMatrixType, true>::Accessor(
1177 const Accessor<BlockMatrixType, false> &other)
1179 , base_iterator(other.base_iterator)
1181 this->row_block = other.row_block;
1182 this->col_block = other.col_block;
1186 template <
class BlockMatrixType>
1188 Accessor<BlockMatrixType, true>::row()
const
1193 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1194 base_iterator->row());
1198 template <
class BlockMatrixType>
1200 Accessor<BlockMatrixType, true>::column()
const
1205 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1206 base_iterator->column());
1210 template <
class BlockMatrixType>
1211 inline typename Accessor<BlockMatrixType, true>::value_type
1212 Accessor<BlockMatrixType, true>::value()
const
1219 return base_iterator->value();
1224 template <
class BlockMatrixType>
1234 size_type local_row = base_iterator->row();
1245 while (base_iterator ==
1246 matrix->block(this->row_block, this->col_block).end(local_row))
1251 if (this->col_block < matrix->n_block_cols() - 1)
1255 matrix->block(this->row_block, this->col_block).begin(local_row);
1261 this->col_block = 0;
1271 matrix->block(this->row_block, this->col_block).m())
1275 if (this->row_block ==
matrix->n_block_rows())
1284 matrix->block(this->row_block, this->col_block).begin(local_row);
1290 template <
class BlockMatrixType>
1297 if (this->row_block == a.row_block && this->col_block == a.col_block)
1304 (base_iterator == a.base_iterator));
1312 template <
class BlockMatrixType>
1313 inline Accessor<BlockMatrixType, false>::Accessor(BlockMatrixType *
matrix,
1323 if (row < matrix->
m())
1325 const std::pair<unsigned int, size_type> indices =
1326 matrix->row_block_indices.global_to_local(row);
1333 matrix->block(indices.first, bc).begin(indices.second);
1334 if (base_iterator !=
1335 matrix->block(indices.first, bc).end(indices.second))
1337 this->row_block = indices.first;
1338 this->col_block = bc;
1349 *
this = Accessor(
matrix, row + 1, 0);
1361 template <
class BlockMatrixType>
1363 Accessor<BlockMatrixType, false>::row()
const
1367 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1368 base_iterator->row());
1372 template <
class BlockMatrixType>
1374 Accessor<BlockMatrixType, false>::column()
const
1378 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1379 base_iterator->column());
1383 template <
class BlockMatrixType>
1384 inline typename Accessor<BlockMatrixType, false>::value_type
1385 Accessor<BlockMatrixType, false>::value()
const
1390 return base_iterator->value();
1395 template <
class BlockMatrixType>
1397 Accessor<BlockMatrixType, false>::set_value(
1398 typename Accessor<BlockMatrixType, false>::value_type newval)
const
1403 base_iterator->value() = newval;
1408 template <
class BlockMatrixType>
1416 size_type local_row = base_iterator->row();
1427 while (base_iterator ==
1428 matrix->block(this->row_block, this->col_block).end(local_row))
1433 if (this->col_block < matrix->n_block_cols() - 1)
1437 matrix->block(this->row_block, this->col_block).begin(local_row);
1443 this->col_block = 0;
1453 matrix->block(this->row_block, this->col_block).m())
1457 if (this->row_block ==
matrix->n_block_rows())
1466 matrix->block(this->row_block, this->col_block).begin(local_row);
1473 template <
class BlockMatrixType>
1480 if (this->row_block == a.row_block && this->col_block == a.col_block)
1487 (base_iterator == a.base_iterator));
1496template <
typename MatrixType>
1508template <
class MatrixType>
1509template <
class BlockMatrixType>
1513 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1514 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1515 block(r, c).
copy_from(source.block(r, c));
1521template <
class MatrixType>
1532 sizeof(temporary_data.mutex);
1534 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1535 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1537 MatrixType *p = this->sub_objects[r][c];
1546template <
class MatrixType>
1550 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1551 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1553 MatrixType *p = this->sub_objects[r][c];
1554 this->sub_objects[r][c] =
nullptr;
1557 sub_objects.reinit(0, 0);
1560 row_block_indices = column_block_indices =
BlockIndices();
1565template <
class MatrixType>
1568 const unsigned int column)
1573 return *sub_objects[row][column];
1578template <
class MatrixType>
1581 const unsigned int column)
const
1586 return *sub_objects[row][column];
1590template <
class MatrixType>
1594 return row_block_indices.total_size();
1599template <
class MatrixType>
1603 return column_block_indices.total_size();
1608template <
class MatrixType>
1612 return column_block_indices.size();
1617template <
class MatrixType>
1621 return row_block_indices.size();
1629template <
class MatrixType>
1633 const value_type value)
1635 prepare_set_operation();
1639 const std::pair<unsigned int, size_type>
1640 row_index = row_block_indices.global_to_local(i),
1641 col_index = column_block_indices.global_to_local(j);
1642 block(row_index.first, col_index.first)
1643 .set(row_index.second, col_index.second, value);
1648template <
class MatrixType>
1649template <
typename number>
1652 const std::vector<size_type> &col_indices,
1654 const bool elide_zero_values)
1661 for (
size_type i = 0; i < row_indices.size(); ++i)
1671template <
class MatrixType>
1672template <
typename number>
1676 const bool elide_zero_values)
1682 for (
size_type i = 0; i < indices.size(); ++i)
1692template <
class MatrixType>
1693template <
typename number>
1696 const std::vector<size_type> &col_indices,
1697 const std::vector<number> &
values,
1698 const bool elide_zero_values)
1715template <
class MatrixType>
1716template <
typename number>
1722 const bool elide_zero_values)
1724 prepare_set_operation();
1728 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1731 if (temporary_data.column_indices.size() < this->n_block_cols())
1733 temporary_data.column_indices.resize(this->n_block_cols());
1734 temporary_data.column_values.resize(this->n_block_cols());
1735 temporary_data.counter_within_block.resize(this->n_block_cols());
1748 if (temporary_data.column_indices[0].size() < n_cols)
1750 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1752 temporary_data.column_indices[i].resize(n_cols);
1753 temporary_data.column_values[i].resize(n_cols);
1759 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1760 temporary_data.counter_within_block[i] = 0;
1775 if (value == number() && elide_zero_values ==
true)
1778 const std::pair<unsigned int, size_type> col_index =
1779 this->column_block_indices.global_to_local(col_indices[j]);
1782 temporary_data.counter_within_block[col_index.first]++;
1784 temporary_data.column_indices[col_index.first][local_index] =
1786 temporary_data.column_values[col_index.first][local_index] =
value;
1793 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1794 length += temporary_data.counter_within_block[i];
1803 const std::pair<unsigned int, size_type> row_index =
1804 this->row_block_indices.global_to_local(row);
1805 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
1807 if (temporary_data.counter_within_block[block_col] == 0)
1810 block(row_index.first, block_col)
1811 .set(row_index.second,
1812 temporary_data.counter_within_block[block_col],
1813 temporary_data.column_indices[block_col].data(),
1814 temporary_data.column_values[block_col].data(),
1821template <
class MatrixType>
1825 const value_type value)
1829 prepare_add_operation();
1834 using MatrixTraits =
typename MatrixType::Traits;
1835 if ((MatrixTraits::zero_addition_can_be_elided ==
true) &&
1836 (value == value_type()))
1839 const std::pair<unsigned int, size_type>
1840 row_index = row_block_indices.global_to_local(i),
1841 col_index = column_block_indices.global_to_local(j);
1842 block(row_index.first, col_index.first)
1843 .add(row_index.second, col_index.second, value);
1848template <
class MatrixType>
1849template <
typename number>
1852 const std::vector<size_type> &col_indices,
1854 const bool elide_zero_values)
1861 for (
size_type i = 0; i < row_indices.size(); ++i)
1871template <
class MatrixType>
1872template <
typename number>
1876 const bool elide_zero_values)
1882 for (
size_type i = 0; i < indices.size(); ++i)
1892template <
class MatrixType>
1893template <
typename number>
1896 const std::vector<size_type> &col_indices,
1897 const std::vector<number> &
values,
1898 const bool elide_zero_values)
1915template <
class MatrixType>
1916template <
typename number>
1922 const bool elide_zero_values,
1923 const bool col_indices_are_sorted)
1925 prepare_add_operation();
1930 if (col_indices_are_sorted ==
true)
1937 if (col_indices[i] <= before)
1939 ExcMessage(
"Flag col_indices_are_sorted is set, but "
1940 "indices appear to not be sorted.")) else before =
1943 const std::pair<unsigned int, size_type> row_index =
1944 this->row_block_indices.global_to_local(row);
1946 if (this->n_block_cols() > 1)
1950 col_indices + n_cols,
1951 this->column_block_indices.block_start(1));
1953 const size_type n_zero_block_indices = first_block - col_indices;
1954 block(row_index.first, 0)
1955 .add(row_index.second,
1956 n_zero_block_indices,
1960 col_indices_are_sorted);
1962 if (n_zero_block_indices < n_cols)
1964 n_cols - n_zero_block_indices,
1966 values + n_zero_block_indices,
1972 block(row_index.first, 0)
1973 .add(row_index.second,
1978 col_indices_are_sorted);
1985 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1987 if (temporary_data.column_indices.size() < this->n_block_cols())
1989 temporary_data.column_indices.resize(this->n_block_cols());
1990 temporary_data.column_values.resize(this->n_block_cols());
1991 temporary_data.counter_within_block.resize(this->n_block_cols());
2004 if (temporary_data.column_indices[0].size() < n_cols)
2006 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2008 temporary_data.column_indices[i].resize(n_cols);
2009 temporary_data.column_values[i].resize(n_cols);
2015 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2016 temporary_data.counter_within_block[i] = 0;
2031 if (value == number() && elide_zero_values ==
true)
2034 const std::pair<unsigned int, size_type> col_index =
2035 this->column_block_indices.global_to_local(col_indices[j]);
2038 temporary_data.counter_within_block[col_index.first]++;
2040 temporary_data.column_indices[col_index.first][local_index] =
2042 temporary_data.column_values[col_index.first][local_index] =
value;
2049 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2050 length += temporary_data.counter_within_block[i];
2059 const std::pair<unsigned int, size_type> row_index =
2060 this->row_block_indices.global_to_local(row);
2061 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
2063 if (temporary_data.counter_within_block[block_col] == 0)
2066 block(row_index.first, block_col)
2067 .add(row_index.second,
2068 temporary_data.counter_within_block[block_col],
2069 temporary_data.column_indices[block_col].data(),
2070 temporary_data.column_values[block_col].data(),
2072 col_indices_are_sorted);
2078template <
class MatrixType>
2085 prepare_add_operation();
2090 using MatrixTraits =
typename MatrixType::Traits;
2091 if ((MatrixTraits::zero_addition_can_be_elided ==
true) && (factor == 0))
2094 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2095 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2098 block(row, col).add(factor,
matrix.block(row, col));
2103template <
class MatrixType>
2108 const std::pair<unsigned int, size_type>
2109 row_index = row_block_indices.global_to_local(i),
2110 col_index = column_block_indices.global_to_local(j);
2111 return block(row_index.first, col_index.first)(row_index.second,
2117template <
class MatrixType>
2121 const std::pair<unsigned int, size_type>
2122 row_index = row_block_indices.global_to_local(i),
2123 col_index = column_block_indices.global_to_local(j);
2124 return block(row_index.first, col_index.first)
2125 .el(row_index.second, col_index.second);
2130template <
class MatrixType>
2136 const std::pair<unsigned int, size_type> index =
2137 row_block_indices.global_to_local(i);
2138 return block(index.first, index.first).diag_element(index.second);
2143template <
class MatrixType>
2148 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2149 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2150 block(r, c).compress(operation);
2155template <
class MatrixType>
2162 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2163 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2164 block(r, c) *= factor;
2171template <
class MatrixType>
2179 const value_type factor_inv = 1. / factor;
2181 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2182 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2183 block(r, c) *= factor_inv;
2190template <
class MatrixType>
2194 return this->row_block_indices;
2199template <
class MatrixType>
2203 return this->column_block_indices;
2208template <
class MatrixType>
2209template <
class BlockVectorType>
2212 const BlockVectorType &src)
const
2214 Assert(dst.n_blocks() == n_block_rows(),
2216 Assert(src.n_blocks() == n_block_cols(),
2219 for (
size_type row = 0; row < n_block_rows(); ++row)
2221 block(row, 0).vmult(dst.block(row), src.block(0));
2222 for (
size_type col = 1; col < n_block_cols(); ++col)
2223 block(row, col).vmult_add(dst.block(row), src.block(col));
2229template <
class MatrixType>
2230template <
class BlockVectorType,
class VectorType>
2234 const BlockVectorType &src)
const
2237 Assert(src.n_blocks() == n_block_cols(),
2240 block(0, 0).vmult(dst, src.block(0));
2241 for (
size_type col = 1; col < n_block_cols(); ++col)
2242 block(0, col).vmult_add(dst, src.block(col));
2247template <
class MatrixType>
2248template <
class BlockVectorType,
class VectorType>
2251 const VectorType &src)
const
2253 Assert(dst.n_blocks() == n_block_rows(),
2257 for (
size_type row = 0; row < n_block_rows(); ++row)
2258 block(row, 0).vmult(dst.block(row), src);
2263template <
class MatrixType>
2264template <
class VectorType>
2268 const VectorType &src)
const
2273 block(0, 0).vmult(dst, src);
2278template <
class MatrixType>
2279template <
class BlockVectorType>
2282 const BlockVectorType &src)
const
2284 Assert(dst.n_blocks() == n_block_rows(),
2286 Assert(src.n_blocks() == n_block_cols(),
2289 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2290 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2291 block(row, col).vmult_add(dst.block(row), src.block(col));
2296template <
class MatrixType>
2297template <
class BlockVectorType>
2300 BlockVectorType & dst,
2301 const BlockVectorType &src)
const
2303 Assert(dst.n_blocks() == n_block_cols(),
2305 Assert(src.n_blocks() == n_block_rows(),
2310 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2312 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2313 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2319template <
class MatrixType>
2320template <
class BlockVectorType,
class VectorType>
2323 const VectorType &src)
const
2325 Assert(dst.n_blocks() == n_block_cols(),
2331 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2332 block(0, col).Tvmult_add(dst.block(col), src);
2337template <
class MatrixType>
2338template <
class BlockVectorType,
class VectorType>
2342 const BlockVectorType &src)
const
2345 Assert(src.n_blocks() == n_block_rows(),
2348 block(0, 0).Tvmult(dst, src.block(0));
2350 for (
size_type row = 1; row < n_block_rows(); ++row)
2351 block(row, 0).Tvmult_add(dst, src.block(row));
2356template <
class MatrixType>
2357template <
class VectorType>
2361 const VectorType &src)
const
2366 block(0, 0).Tvmult(dst, src);
2371template <
class MatrixType>
2372template <
class BlockVectorType>
2375 const BlockVectorType &src)
const
2377 Assert(dst.n_blocks() == n_block_cols(),
2379 Assert(src.n_blocks() == n_block_rows(),
2382 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2383 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2384 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2389template <
class MatrixType>
2390template <
class BlockVectorType>
2395 Assert(v.n_blocks() == n_block_rows(),
2398 value_type norm_sqr = 0;
2399 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2400 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2402 norm_sqr += block(row, col).matrix_norm_square(v.block(row));
2405 block(row, col).matrix_scalar_product(v.block(row), v.block(col));
2411template <
class MatrixType>
2415 value_type norm_sqr = 0;
2419 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2421 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2423 const value_type block_norm = block(row, col).frobenius_norm();
2424 norm_sqr += block_norm * block_norm;
2433template <
class MatrixType>
2434template <
class BlockVectorType>
2437 const BlockVectorType &u,
2438 const BlockVectorType &v)
const
2440 Assert(u.n_blocks() == n_block_rows(),
2442 Assert(v.n_blocks() == n_block_cols(),
2445 value_type result = 0;
2446 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2447 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2449 block(row, col).matrix_scalar_product(u.block(row), v.block(col));
2455template <
class MatrixType>
2456template <
class BlockVectorType>
2459 const BlockVectorType &x,
2460 const BlockVectorType &
b)
const
2462 Assert(dst.n_blocks() == n_block_rows(),
2464 Assert(
b.n_blocks() == n_block_rows(),
2466 Assert(x.n_blocks() == n_block_cols(),
2482 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2484 block(row, 0).residual(dst.block(row), x.block(0),
b.block(row));
2486 for (
size_type i = 0; i < dst.block(row).size(); ++i)
2487 dst.block(row)(i) = -dst.block(row)(i);
2489 for (
unsigned int col = 1; col < n_block_cols(); ++col)
2490 block(row, col).vmult_add(dst.block(row), x.block(col));
2492 for (
size_type i = 0; i < dst.block(row).size(); ++i)
2493 dst.block(row)(i) = -dst.block(row)(i);
2497 for (
size_type row = 0; row < n_block_rows(); ++row)
2498 res += dst.block(row).norm_sqr();
2504template <
class MatrixType>
2507 const bool alternative_output)
const
2509 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2510 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2512 if (!alternative_output)
2513 out <<
"Block (" << row <<
", " << col <<
")" << std::endl;
2515 block(row, col).print(out, alternative_output);
2521template <
class MatrixType>
2525 return const_iterator(
this, 0);
2530template <
class MatrixType>
2534 return const_iterator(
this, m());
2539template <
class MatrixType>
2544 return const_iterator(
this, r);
2549template <
class MatrixType>
2554 return const_iterator(
this, r + 1);
2559template <
class MatrixType>
2563 return iterator(
this, 0);
2568template <
class MatrixType>
2572 return iterator(
this, m());
2577template <
class MatrixType>
2582 return iterator(
this, r);
2587template <
class MatrixType>
2592 return iterator(
this, r + 1);
2597template <
class MatrixType>
2601 std::vector<size_type> row_sizes(this->n_block_rows());
2602 std::vector<size_type> col_sizes(this->n_block_cols());
2606 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2607 row_sizes[r] = sub_objects[r][0]->m();
2611 for (
unsigned int c = 1; c < this->n_block_cols(); ++c)
2612 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2613 Assert(row_sizes[r] == sub_objects[r][c]->m(),
2614 ExcIncompatibleRowNumbers(r, 0, r, c));
2618 this->row_block_indices.reinit(row_sizes);
2622 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2623 col_sizes[c] = sub_objects[0][c]->n();
2624 for (
unsigned int r = 1; r < this->n_block_rows(); ++r)
2625 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2626 Assert(col_sizes[c] == sub_objects[r][c]->n(),
2627 ExcIncompatibleRowNumbers(0, c, r, c));
2631 this->column_block_indices.reinit(col_sizes);
2636template <
class MatrixType>
2640 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2641 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2642 block(row, col).prepare_add();
2647template <
class MatrixType>
2651 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2652 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2653 block(row, col).prepare_set();
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
__global__ void set(Number *val, const Number s, const size_type N)
void Tvmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
void vmult_nonblock_nonblock(VectorType &dst, const VectorType &src) const
std::vector< std::vector< size_type > > column_indices
BlockIndices column_block_indices
std::vector< std::vector< value_type > > column_values
void Tvmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
void Tvmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
TemporaryData & operator=(const TemporaryData &)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
void vmult_block_block(BlockVectorType &dst, const BlockVectorType &src) const
static ::ExceptionBase & ExcIncompatibleColNumbers(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcNotImplemented()
Table< 2, SmartPointer< BlockType, BlockMatrixBase< MatrixType > > > sub_objects
void prepare_add_operation()
void vmult_nonblock_block(VectorType &dst, const BlockVectorType &src) const
#define Assert(cond, exc)
static ::ExceptionBase & ExcIncompatibleRowNumbers(int arg1, int arg2, int arg3, int arg4)
static ::ExceptionBase & ExcIteratorPastEnd()
void prepare_set_operation()
#define AssertIsFinite(number)
TemporaryData temporary_data
BlockIndices row_block_indices
#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()
void vmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
static ::ExceptionBase & ExcMessage(std::string arg1)
void Tvmult_block_nonblock(BlockVectorType &dst, const VectorType &src) const
std::vector< size_type > counter_within_block
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)
const BlockMatrixType MatrixType
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
const_iterator end() const
BlockMatrixBase & operator*=(const value_type factor)
value_type matrix_norm_square(const BlockVectorType &v) const
const value_type & const_reference
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
bool operator==(const Accessor &a) const
unsigned int block_row() const
Accessor(BlockMatrixType *m, const size_type row, const size_type col)
void vmult_add(BlockVectorType &dst, const BlockVectorType &src) const
types::global_dof_index size_type
BlockMatrixType MatrixType
void Tvmult_add(BlockVectorType &dst, const BlockVectorType &src) const
typename BlockType::value_type value_type
void compress(::VectorOperation::values operation)
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)
unsigned int n_block_cols() const
const value_type * const_pointer
const BlockIndices & get_row_indices() const
BlockMatrixType::BlockType::iterator base_iterator
Accessor(const Accessor< BlockMatrixType, false > &)
const BlockMatrixType * matrix
void set(const size_type i, const size_type j, const value_type value)
bool operator==(const Accessor &a) const
BlockMatrixBase & copy_from(const BlockMatrixType &source)
BlockMatrixType::BlockType::const_iterator base_iterator
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
~BlockMatrixBase() override
BlockType & block(const unsigned int row, const unsigned int column)
void set_value(value_type newval) const
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)
unsigned int block_column() const
typename BlockMatrixType::value_type value_type
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
Accessor(const BlockMatrixType *m, const size_type row, const size_type col)
iterator begin(const size_type r)
const_iterator begin(const size_type r) const
BlockMatrixBase & operator/=(const value_type factor)
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)
@ matrix
Contents is actually a matrix.
types::global_dof_index size_type
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type 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
void advance(std::tuple< I1, I2 > &t, const unsigned int n)