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>
206 template <
class BlockMatrixType>
285 friend class ::MatrixIterator;
351 template <
typename MatrixType>
405 template <
class BlockMatrixType>
407 copy_from(
const BlockMatrixType &source);
413 block(
const unsigned int row,
const unsigned int column);
421 block(
const unsigned int row,
const unsigned int column)
const;
475 template <
typename number>
477 set(
const std::vector<size_type> &indices,
479 const bool elide_zero_values =
false);
486 template <
typename number>
488 set(
const std::vector<size_type> &row_indices,
489 const std::vector<size_type> &col_indices,
491 const bool elide_zero_values =
false);
503 template <
typename number>
506 const std::vector<size_type> &col_indices,
507 const std::vector<number> & values,
508 const bool elide_zero_values =
false);
519 template <
typename number>
524 const number * values,
525 const bool elide_zero_values =
false);
549 template <
typename number>
551 add(
const std::vector<size_type> &indices,
553 const bool elide_zero_values =
true);
560 template <
typename number>
562 add(
const std::vector<size_type> &row_indices,
563 const std::vector<size_type> &col_indices,
565 const bool elide_zero_values =
true);
576 template <
typename number>
579 const std::vector<size_type> &col_indices,
580 const std::vector<number> & values,
581 const bool elide_zero_values =
true);
592 template <
typename number>
597 const number * values,
598 const bool elide_zero_values =
true,
599 const bool col_indices_are_sorted =
false);
675 template <
class BlockVectorType>
677 vmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
684 template <
class BlockVectorType>
686 Tvmult_add(BlockVectorType &dst,
const BlockVectorType &src)
const;
700 template <
class BlockVectorType>
714 template <
class BlockVectorType>
717 const BlockVectorType &v)
const;
722 template <
class BlockVectorType>
725 const BlockVectorType &x,
726 const BlockVectorType &
b)
const;
735 print(std::ostream &out,
const bool alternative_output =
false)
const;
817 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
818 <<
',' << arg4 <<
"] have differing row numbers.");
827 <<
"The blocks [" << arg1 <<
',' << arg2 <<
"] and [" << arg3
828 <<
',' << arg4 <<
"] have differing column numbers.");
888 template <
class BlockVectorType>
902 template <
class BlockVectorType,
class VectorType>
916 template <
class BlockVectorType,
class VectorType>
930 template <
class VectorType>
945 template <
class BlockVectorType>
959 template <
class BlockVectorType,
class VectorType>
973 template <
class BlockVectorType,
class VectorType>
987 template <
class VectorType>
1071 template <
typename,
bool>
1087 template <
class BlockMatrixType>
1094 template <
class BlockMatrixType>
1096 AccessorBase<BlockMatrixType>::block_row()
const
1104 template <
class BlockMatrixType>
1106 AccessorBase<BlockMatrixType>::block_column()
const
1114 template <
class BlockMatrixType>
1116 const BlockMatrixType *
matrix,
1127 if (row < matrix->
m())
1129 const std::pair<unsigned int, size_type> indices =
1130 matrix->row_block_indices.global_to_local(row);
1134 for (
unsigned int bc = 0; bc <
matrix->n_block_cols(); ++bc)
1137 matrix->block(indices.first, bc).begin(indices.second);
1138 if (base_iterator !=
1139 matrix->block(indices.first, bc).end(indices.second))
1141 this->row_block = indices.first;
1142 this->col_block = bc;
1178 template <
class BlockMatrixType>
1180 const Accessor<BlockMatrixType, false> &other)
1182 , base_iterator(other.base_iterator)
1184 this->row_block = other.row_block;
1185 this->col_block = other.col_block;
1189 template <
class BlockMatrixType>
1191 Accessor<BlockMatrixType, true>::row()
const
1196 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1197 base_iterator->row());
1201 template <
class BlockMatrixType>
1203 Accessor<BlockMatrixType, true>::column()
const
1208 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1209 base_iterator->column());
1213 template <
class BlockMatrixType>
1214 inline typename Accessor<BlockMatrixType, true>::value_type
1222 return base_iterator->value();
1227 template <
class BlockMatrixType>
1237 size_type local_row = base_iterator->row();
1248 while (base_iterator ==
1249 matrix->block(this->row_block, this->col_block).end(local_row))
1254 if (this->col_block < matrix->n_block_cols() - 1)
1258 matrix->block(this->row_block, this->col_block).begin(local_row);
1264 this->col_block = 0;
1274 matrix->block(this->row_block, this->col_block).m())
1278 if (this->row_block ==
matrix->n_block_rows())
1287 matrix->block(this->row_block, this->col_block).begin(local_row);
1293 template <
class BlockMatrixType>
1300 if (this->row_block == a.row_block && this->col_block == a.col_block)
1307 (base_iterator == a.base_iterator));
1315 template <
class BlockMatrixType>
1326 if (row < matrix->
m())
1328 const std::pair<unsigned int, size_type> indices =
1329 matrix->row_block_indices.global_to_local(row);
1336 matrix->block(indices.first, bc).begin(indices.second);
1337 if (base_iterator !=
1338 matrix->block(indices.first, bc).end(indices.second))
1340 this->row_block = indices.first;
1341 this->col_block = bc;
1364 template <
class BlockMatrixType>
1366 Accessor<BlockMatrixType, false>::row()
const
1370 return (
matrix->row_block_indices.local_to_global(this->row_block, 0) +
1371 base_iterator->row());
1375 template <
class BlockMatrixType>
1377 Accessor<BlockMatrixType, false>::column()
const
1381 return (
matrix->column_block_indices.local_to_global(this->col_block, 0) +
1382 base_iterator->column());
1386 template <
class BlockMatrixType>
1387 inline typename Accessor<BlockMatrixType, false>::value_type
1393 return base_iterator->value();
1398 template <
class BlockMatrixType>
1400 Accessor<BlockMatrixType, false>::set_value(
1401 typename Accessor<BlockMatrixType, false>::value_type newval)
const
1406 base_iterator->value() = newval;
1411 template <
class BlockMatrixType>
1419 size_type local_row = base_iterator->row();
1430 while (base_iterator ==
1431 matrix->block(this->row_block, this->col_block).end(local_row))
1436 if (this->col_block < matrix->n_block_cols() - 1)
1440 matrix->block(this->row_block, this->col_block).begin(local_row);
1446 this->col_block = 0;
1456 matrix->block(this->row_block, this->col_block).m())
1460 if (this->row_block ==
matrix->n_block_rows())
1469 matrix->block(this->row_block, this->col_block).begin(local_row);
1476 template <
class BlockMatrixType>
1483 if (this->row_block == a.row_block && this->col_block == a.col_block)
1490 (base_iterator == a.base_iterator));
1499 template <
typename MatrixType>
1511 template <
class MatrixType>
1512 template <
class BlockMatrixType>
1516 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1517 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1518 block(r, c).
copy_from(source.block(r, c));
1524 template <
class MatrixType>
1535 sizeof(temporary_data.mutex);
1537 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1538 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1540 MatrixType *p = this->sub_objects[r][c];
1549 template <
class MatrixType>
1553 for (
unsigned int r = 0; r < n_block_rows(); ++r)
1554 for (
unsigned int c = 0; c < n_block_cols(); ++c)
1556 MatrixType *p = this->sub_objects[r][c];
1557 this->sub_objects[r][c] =
nullptr;
1560 sub_objects.reinit(0, 0);
1563 row_block_indices = column_block_indices =
BlockIndices();
1568 template <
class MatrixType>
1571 const unsigned int column)
1576 return *sub_objects[row][column];
1581 template <
class MatrixType>
1584 const unsigned int column)
const
1589 return *sub_objects[row][column];
1593 template <
class MatrixType>
1597 return row_block_indices.total_size();
1602 template <
class MatrixType>
1606 return column_block_indices.total_size();
1611 template <
class MatrixType>
1615 return column_block_indices.size();
1620 template <
class MatrixType>
1624 return row_block_indices.size();
1632 template <
class MatrixType>
1638 prepare_set_operation();
1642 const std::pair<unsigned int, size_type>
1643 row_index = row_block_indices.global_to_local(i),
1644 col_index = column_block_indices.global_to_local(j);
1645 block(row_index.first, col_index.first)
1646 .set(row_index.second, col_index.second,
value);
1651 template <
class MatrixType>
1652 template <
typename number>
1655 const std::vector<size_type> &col_indices,
1657 const bool elide_zero_values)
1659 Assert(row_indices.size() == values.
m(),
1661 Assert(col_indices.size() == values.
n(),
1664 for (
size_type i = 0; i < row_indices.size(); ++i)
1674 template <
class MatrixType>
1675 template <
typename number>
1679 const bool elide_zero_values)
1681 Assert(indices.size() == values.
m(),
1685 for (
size_type i = 0; i < indices.size(); ++i)
1695 template <
class MatrixType>
1696 template <
typename number>
1699 const std::vector<size_type> &col_indices,
1700 const std::vector<number> & values,
1701 const bool elide_zero_values)
1703 Assert(col_indices.size() == values.size(),
1718 template <
class MatrixType>
1719 template <
typename number>
1724 const number * values,
1725 const bool elide_zero_values)
1727 prepare_set_operation();
1731 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1734 if (temporary_data.column_indices.size() < this->n_block_cols())
1736 temporary_data.column_indices.resize(this->n_block_cols());
1737 temporary_data.column_values.resize(this->n_block_cols());
1738 temporary_data.counter_within_block.resize(this->n_block_cols());
1751 if (temporary_data.column_indices[0].size() < n_cols)
1753 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1755 temporary_data.column_indices[i].resize(n_cols);
1756 temporary_data.column_values[i].resize(n_cols);
1762 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1763 temporary_data.counter_within_block[i] = 0;
1776 number
value = values[j];
1778 if (
value == number() && elide_zero_values ==
true)
1781 const std::pair<unsigned int, size_type> col_index =
1782 this->column_block_indices.global_to_local(col_indices[j]);
1785 temporary_data.counter_within_block[col_index.first]++;
1787 temporary_data.column_indices[col_index.first][local_index] =
1789 temporary_data.column_values[col_index.first][local_index] =
value;
1796 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
1797 length += temporary_data.counter_within_block[i];
1806 const std::pair<unsigned int, size_type> row_index =
1807 this->row_block_indices.global_to_local(row);
1808 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
1810 if (temporary_data.counter_within_block[block_col] == 0)
1813 block(row_index.first, block_col)
1814 .set(row_index.second,
1815 temporary_data.counter_within_block[block_col],
1816 temporary_data.column_indices[block_col].data(),
1817 temporary_data.column_values[block_col].data(),
1824 template <
class MatrixType>
1832 prepare_add_operation();
1837 using MatrixTraits =
typename MatrixType::Traits;
1838 if ((MatrixTraits::zero_addition_can_be_elided ==
true) &&
1842 const std::pair<unsigned int, size_type>
1843 row_index = row_block_indices.global_to_local(i),
1844 col_index = column_block_indices.global_to_local(j);
1845 block(row_index.first, col_index.first)
1846 .add(row_index.second, col_index.second,
value);
1851 template <
class MatrixType>
1852 template <
typename number>
1855 const std::vector<size_type> &col_indices,
1857 const bool elide_zero_values)
1859 Assert(row_indices.size() == values.
m(),
1861 Assert(col_indices.size() == values.
n(),
1864 for (
size_type i = 0; i < row_indices.size(); ++i)
1874 template <
class MatrixType>
1875 template <
typename number>
1879 const bool elide_zero_values)
1881 Assert(indices.size() == values.
m(),
1885 for (
size_type i = 0; i < indices.size(); ++i)
1895 template <
class MatrixType>
1896 template <
typename number>
1899 const std::vector<size_type> &col_indices,
1900 const std::vector<number> & values,
1901 const bool elide_zero_values)
1903 Assert(col_indices.size() == values.size(),
1918 template <
class MatrixType>
1919 template <
typename number>
1924 const number * values,
1925 const bool elide_zero_values,
1926 const bool col_indices_are_sorted)
1928 prepare_add_operation();
1933 if (col_indices_are_sorted ==
true)
1940 if (col_indices[i] <= before)
1942 ExcMessage(
"Flag col_indices_are_sorted is set, but "
1943 "indices appear to not be sorted.")) else before =
1946 const std::pair<unsigned int, size_type> row_index =
1947 this->row_block_indices.global_to_local(row);
1949 if (this->n_block_cols() > 1)
1953 col_indices + n_cols,
1954 this->column_block_indices.block_start(1));
1956 const size_type n_zero_block_indices = first_block - col_indices;
1957 block(row_index.first, 0)
1958 .add(row_index.second,
1959 n_zero_block_indices,
1963 col_indices_are_sorted);
1965 if (n_zero_block_indices < n_cols)
1967 n_cols - n_zero_block_indices,
1969 values + n_zero_block_indices,
1975 block(row_index.first, 0)
1976 .add(row_index.second,
1981 col_indices_are_sorted);
1988 std::lock_guard<std::mutex> lock(temporary_data.mutex);
1990 if (temporary_data.column_indices.size() < this->n_block_cols())
1992 temporary_data.column_indices.resize(this->n_block_cols());
1993 temporary_data.column_values.resize(this->n_block_cols());
1994 temporary_data.counter_within_block.resize(this->n_block_cols());
2007 if (temporary_data.column_indices[0].size() < n_cols)
2009 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2011 temporary_data.column_indices[i].resize(n_cols);
2012 temporary_data.column_values[i].resize(n_cols);
2018 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2019 temporary_data.counter_within_block[i] = 0;
2032 number
value = values[j];
2034 if (
value == number() && elide_zero_values ==
true)
2037 const std::pair<unsigned int, size_type> col_index =
2038 this->column_block_indices.global_to_local(col_indices[j]);
2041 temporary_data.counter_within_block[col_index.first]++;
2043 temporary_data.column_indices[col_index.first][local_index] =
2045 temporary_data.column_values[col_index.first][local_index] =
value;
2052 for (
unsigned int i = 0; i < this->n_block_cols(); ++i)
2053 length += temporary_data.counter_within_block[i];
2062 const std::pair<unsigned int, size_type> row_index =
2063 this->row_block_indices.global_to_local(row);
2064 for (
unsigned int block_col = 0; block_col < n_block_cols(); ++block_col)
2066 if (temporary_data.counter_within_block[block_col] == 0)
2069 block(row_index.first, block_col)
2070 .add(row_index.second,
2071 temporary_data.counter_within_block[block_col],
2072 temporary_data.column_indices[block_col].data(),
2073 temporary_data.column_values[block_col].data(),
2075 col_indices_are_sorted);
2081 template <
class MatrixType>
2088 prepare_add_operation();
2093 using MatrixTraits =
typename MatrixType::Traits;
2094 if ((MatrixTraits::zero_addition_can_be_elided ==
true) && (factor == 0))
2097 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2098 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2101 block(row, col).add(factor,
matrix.block(row, col));
2106 template <
class MatrixType>
2111 const std::pair<unsigned int, size_type>
2112 row_index = row_block_indices.global_to_local(i),
2113 col_index = column_block_indices.global_to_local(j);
2114 return block(row_index.first, col_index.first)(row_index.second,
2120 template <
class MatrixType>
2124 const std::pair<unsigned int, size_type>
2125 row_index = row_block_indices.global_to_local(i),
2126 col_index = column_block_indices.global_to_local(j);
2127 return block(row_index.first, col_index.first)
2128 .el(row_index.second, col_index.second);
2133 template <
class MatrixType>
2139 const std::pair<unsigned int, size_type> index =
2140 row_block_indices.global_to_local(i);
2141 return block(index.first, index.first).diag_element(index.second);
2146 template <
class MatrixType>
2151 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2152 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2153 block(r, c).compress(operation);
2158 template <
class MatrixType>
2165 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2166 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2167 block(r, c) *= factor;
2174 template <
class MatrixType>
2184 for (
unsigned int r = 0; r < n_block_rows(); ++r)
2185 for (
unsigned int c = 0; c < n_block_cols(); ++c)
2186 block(r, c) *= factor_inv;
2193 template <
class MatrixType>
2197 return this->row_block_indices;
2202 template <
class MatrixType>
2206 return this->column_block_indices;
2211 template <
class MatrixType>
2212 template <
class BlockVectorType>
2215 const BlockVectorType &src)
const
2217 Assert(dst.n_blocks() == n_block_rows(),
2219 Assert(src.n_blocks() == n_block_cols(),
2222 for (
size_type row = 0; row < n_block_rows(); ++row)
2224 block(row, 0).vmult(dst.block(row), src.block(0));
2225 for (
size_type col = 1; col < n_block_cols(); ++col)
2226 block(row, col).vmult_add(dst.block(row), src.block(col));
2232 template <
class MatrixType>
2233 template <
class BlockVectorType,
class VectorType>
2237 const BlockVectorType &src)
const
2240 Assert(src.n_blocks() == n_block_cols(),
2243 block(0, 0).vmult(dst, src.block(0));
2244 for (
size_type col = 1; col < n_block_cols(); ++col)
2245 block(0, col).vmult_add(dst, src.block(col));
2250 template <
class MatrixType>
2251 template <
class BlockVectorType,
class VectorType>
2256 Assert(dst.n_blocks() == n_block_rows(),
2260 for (
size_type row = 0; row < n_block_rows(); ++row)
2261 block(row, 0).vmult(dst.block(row), src);
2266 template <
class MatrixType>
2267 template <
class VectorType>
2276 block(0, 0).vmult(dst, src);
2281 template <
class MatrixType>
2282 template <
class BlockVectorType>
2285 const BlockVectorType &src)
const
2287 Assert(dst.n_blocks() == n_block_rows(),
2289 Assert(src.n_blocks() == n_block_cols(),
2292 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2293 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2294 block(row, col).vmult_add(dst.block(row), src.block(col));
2299 template <
class MatrixType>
2300 template <
class BlockVectorType>
2303 BlockVectorType & dst,
2304 const BlockVectorType &src)
const
2306 Assert(dst.n_blocks() == n_block_cols(),
2308 Assert(src.n_blocks() == n_block_rows(),
2313 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2315 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2316 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2322 template <
class MatrixType>
2323 template <
class BlockVectorType,
class VectorType>
2328 Assert(dst.n_blocks() == n_block_cols(),
2334 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2335 block(0, col).Tvmult_add(dst.block(col), src);
2340 template <
class MatrixType>
2341 template <
class BlockVectorType,
class VectorType>
2345 const BlockVectorType &src)
const
2348 Assert(src.n_blocks() == n_block_rows(),
2351 block(0, 0).Tvmult(dst, src.block(0));
2353 for (
size_type row = 1; row < n_block_rows(); ++row)
2354 block(row, 0).Tvmult_add(dst, src.block(row));
2359 template <
class MatrixType>
2360 template <
class VectorType>
2369 block(0, 0).Tvmult(dst, src);
2374 template <
class MatrixType>
2375 template <
class BlockVectorType>
2378 const BlockVectorType &src)
const
2380 Assert(dst.n_blocks() == n_block_cols(),
2382 Assert(src.n_blocks() == n_block_rows(),
2385 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2386 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2387 block(row, col).Tvmult_add(dst.block(col), src.block(row));
2392 template <
class MatrixType>
2393 template <
class BlockVectorType>
2398 Assert(v.n_blocks() == n_block_rows(),
2402 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2403 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2405 norm_sqr += block(row, col).matrix_norm_square(v.block(row));
2408 block(row, col).matrix_scalar_product(v.block(row), v.block(col));
2414 template <
class MatrixType>
2422 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2424 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2426 const value_type block_norm = block(row, col).frobenius_norm();
2427 norm_sqr += block_norm * block_norm;
2436 template <
class MatrixType>
2437 template <
class BlockVectorType>
2440 const BlockVectorType &u,
2441 const BlockVectorType &v)
const
2443 Assert(u.n_blocks() == n_block_rows(),
2445 Assert(v.n_blocks() == n_block_cols(),
2449 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2450 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2452 block(row, col).matrix_scalar_product(u.block(row), v.block(col));
2458 template <
class MatrixType>
2459 template <
class BlockVectorType>
2462 const BlockVectorType &x,
2463 const BlockVectorType &
b)
const
2465 Assert(dst.n_blocks() == n_block_rows(),
2467 Assert(
b.n_blocks() == n_block_rows(),
2469 Assert(x.n_blocks() == n_block_cols(),
2485 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2487 block(row, 0).residual(dst.block(row), x.block(0),
b.block(row));
2489 for (
size_type i = 0; i < dst.block(row).size(); ++i)
2490 dst.block(row)(i) = -dst.block(row)(i);
2492 for (
unsigned int col = 1; col < n_block_cols(); ++col)
2493 block(row, col).vmult_add(dst.block(row), x.block(col));
2495 for (
size_type i = 0; i < dst.block(row).size(); ++i)
2496 dst.block(row)(i) = -dst.block(row)(i);
2500 for (
size_type row = 0; row < n_block_rows(); ++row)
2501 res += dst.block(row).norm_sqr();
2507 template <
class MatrixType>
2510 const bool alternative_output)
const
2512 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2513 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2515 if (!alternative_output)
2516 out <<
"Block (" << row <<
", " << col <<
")" << std::endl;
2518 block(row, col).print(out, alternative_output);
2524 template <
class MatrixType>
2528 return const_iterator(
this, 0);
2533 template <
class MatrixType>
2537 return const_iterator(
this, m());
2542 template <
class MatrixType>
2547 return const_iterator(
this, r);
2552 template <
class MatrixType>
2557 return const_iterator(
this, r + 1);
2562 template <
class MatrixType>
2566 return iterator(
this, 0);
2571 template <
class MatrixType>
2575 return iterator(
this, m());
2580 template <
class MatrixType>
2585 return iterator(
this, r);
2590 template <
class MatrixType>
2595 return iterator(
this, r + 1);
2600 template <
class MatrixType>
2604 std::vector<size_type> row_sizes(this->n_block_rows());
2605 std::vector<size_type> col_sizes(this->n_block_cols());
2609 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2610 row_sizes[r] = sub_objects[r][0]->m();
2614 for (
unsigned int c = 1; c < this->n_block_cols(); ++c)
2615 for (
unsigned int r = 0; r < this->n_block_rows(); ++r)
2616 Assert(row_sizes[r] == sub_objects[r][c]->m(),
2617 ExcIncompatibleRowNumbers(r, 0, r, c));
2621 this->row_block_indices.reinit(row_sizes);
2625 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2626 col_sizes[c] = sub_objects[0][c]->n();
2627 for (
unsigned int r = 1; r < this->n_block_rows(); ++r)
2628 for (
unsigned int c = 0; c < this->n_block_cols(); ++c)
2629 Assert(col_sizes[c] == sub_objects[r][c]->n(),
2630 ExcIncompatibleRowNumbers(0, c, r, c));
2634 this->column_block_indices.reinit(col_sizes);
2639 template <
class MatrixType>
2643 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2644 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2645 block(row, col).prepare_add();
2650 template <
class MatrixType>
2654 for (
unsigned int row = 0; row < n_block_rows(); ++row)
2655 for (
unsigned int col = 0; col < n_block_cols(); ++col)
2656 block(row, col).prepare_set();
2664 #endif // dealii_block_matrix_base_h