deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
petsc_matrix_base.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2004 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_petsc_matrix_base_h
14#define dealii_petsc_matrix_base_h
15
16
17#include <deal.II/base/config.h>
18
19#ifdef DEAL_II_WITH_PETSC
20
22
28
29# include <boost/container/small_vector.hpp>
30
31# include <petscmat.h>
32
33# include <cmath>
34# include <memory>
35# include <optional>
36# include <vector>
37
38#endif // DEAL_II_WITH_PETSC
39
41
42#ifdef DEAL_II_WITH_PETSC
43// Forward declarations
44# ifndef DOXYGEN
45template <typename Matrix>
46class BlockMatrixBase;
47# endif
48
49
50namespace PETScWrappers
51{
52 // forward declarations
53 class MatrixBase;
54
55 namespace MatrixIterators
56 {
71 {
72# ifdef __CUDACC__
73 // NVCC, at least until 12.8, fails to compile the
74 // implementations of the nested Accessor class if it is
75 // declared as private. Work around this by making it public.
76 public:
77# else
78 private:
79# endif
84 {
85 public:
90
96 const size_type row,
97 const size_type index);
98
103 row() const;
104
109 index() const;
110
115 column() const;
116
120 PetscScalar
121 value() const;
122
131 int,
132 int,
133 int,
134 << "You tried to access row " << arg1
135 << " of a distributed matrix, but only rows " << arg2
136 << " through " << arg3
137 << " are stored locally and can be accessed.");
138
139 private:
144
149
154
167 std::shared_ptr<const std::vector<size_type>> colnum_cache;
168
172 std::shared_ptr<const std::vector<PetscScalar>> value_cache;
173
179 void
181
182 // Make enclosing class a friend.
183 friend class const_iterator;
184 };
185
186 public:
191
197 const size_type row,
198 const size_type index);
199
205
211
215 const Accessor &
216 operator*() const;
217
221 const Accessor *
222 operator->() const;
223
228 bool
233 bool
235
241 bool
242 operator<(const const_iterator &) const;
243
248 int,
249 int,
250 << "Attempt to access element " << arg2 << " of row "
251 << arg1 << " which doesn't have that many elements.");
252
253 private:
258 };
259
260 } // namespace MatrixIterators
261
262
295 {
296 public:
301
306
310 using value_type = PetscScalar;
311
315 MatrixBase();
316
335 explicit MatrixBase(const Mat &);
336
342 MatrixBase(const MatrixBase &) = delete;
343
349 MatrixBase &
350 operator=(const MatrixBase &) = delete;
351
355 virtual ~MatrixBase() override;
356
363 void
364 reinit(Mat A);
365
376 MatrixBase &
377 operator=(const value_type d);
378
383 void
384 clear();
385
395 void
396 set(const size_type i, const size_type j, const PetscScalar value);
397
417 void
418 set(const std::vector<size_type> &indices,
419 const FullMatrix<PetscScalar> &full_matrix,
420 const bool elide_zero_values = false);
421
427 void
428 set(const std::vector<size_type> &row_indices,
429 const std::vector<size_type> &col_indices,
430 const FullMatrix<PetscScalar> &full_matrix,
431 const bool elide_zero_values = false);
432
447 void
448 set(const size_type row,
449 const std::vector<size_type> &col_indices,
450 const std::vector<PetscScalar> &values,
451 const bool elide_zero_values = false);
452
467 void
468 set(const size_type row,
469 const size_type n_cols,
470 const size_type *col_indices,
471 const PetscScalar *values,
472 const bool elide_zero_values = false);
473
483 void
484 add(const size_type i, const size_type j, const PetscScalar value);
485
505 void
506 add(const std::vector<size_type> &indices,
507 const FullMatrix<PetscScalar> &full_matrix,
508 const bool elide_zero_values = true);
509
515 void
516 add(const std::vector<size_type> &row_indices,
517 const std::vector<size_type> &col_indices,
518 const FullMatrix<PetscScalar> &full_matrix,
519 const bool elide_zero_values = true);
520
535 void
536 add(const size_type row,
537 const std::vector<size_type> &col_indices,
538 const std::vector<PetscScalar> &values,
539 const bool elide_zero_values = true);
540
555 void
556 add(const size_type row,
557 const size_type n_cols,
558 const size_type *col_indices,
559 const PetscScalar *values,
560 const bool elide_zero_values = true,
561 const bool col_indices_are_sorted = false);
562
579 void
580 clear_row(const size_type row, const PetscScalar new_diag_value = 0);
581
590 void
592 const PetscScalar new_diag_value = 0);
593
597 void
598 clear_rows_columns(const std::vector<size_type> &row_and_column_indices,
599 const PetscScalar new_diag_value = 0);
600
612 void
613 compress(const VectorOperation::values operation);
614
626 PetscScalar
627 operator()(const size_type i, const size_type j) const;
628
636 PetscScalar
637 el(const size_type i, const size_type j) const;
638
648 PetscScalar
649 diag_element(const size_type i) const;
650
655 m() const;
656
661 n() const;
662
672 local_size() const;
673
682 std::pair<size_type, size_type>
683 local_range() const;
684
689 bool
690 in_local_range(const size_type index) const;
691
699 local_domain_size() const;
700
707 std::pair<size_type, size_type>
708 local_domain() const;
709
715
721 std::uint64_t
722 n_nonzero_elements() const;
723
728 row_length(const size_type row) const;
729
737 PetscReal
738 l1_norm() const;
739
747 PetscReal
748 linfty_norm() const;
749
754 PetscReal
755 frobenius_norm() const;
756
757
777 PetscScalar
778 matrix_norm_square(const VectorBase &v) const;
779
780
794 PetscScalar
795 matrix_scalar_product(const VectorBase &u, const VectorBase &v) const;
796
801 PetscScalar
802 trace() const;
803
807 MatrixBase &
808 operator*=(const PetscScalar factor);
809
813 MatrixBase &
814 operator/=(const PetscScalar factor);
815
816
821 MatrixBase &
822 add(const PetscScalar factor, const MatrixBase &other);
823
835 void
836 vmult(VectorBase &dst, const VectorBase &src) const;
837
850 void
851 Tvmult(VectorBase &dst, const VectorBase &src) const;
852
864 void
865 vmult_add(VectorBase &dst, const VectorBase &src) const;
866
879 void
880 Tvmult_add(VectorBase &dst, const VectorBase &src) const;
881
894 PetscScalar
895 residual(VectorBase &dst, const VectorBase &x, const VectorBase &b) const;
896
903 begin() const;
904
911 end() const;
912
922 begin(const size_type r) const;
923
933 end(const size_type r) const;
934
942 operator Mat() const;
943
949 Mat &
950 petsc_matrix();
951
955 void
956 transpose();
957
962 PetscBool
963 is_symmetric(const double tolerance = 1.e-12);
964
970 PetscBool
971 is_hermitian(const double tolerance = 1.e-12);
972
979 void
980 write_ascii(const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
981
989 void
990 print(std::ostream &out, const bool alternative_output = false) const;
991
995 std::size_t
996 memory_consumption() const;
997
1002 "You are attempting an operation on two vectors that "
1003 "are the same object, but the operation requires that the "
1004 "two objects are in fact different.");
1005
1010 int,
1011 int,
1012 << "You tried to do a "
1013 << (arg1 == 1 ? "'set'" : (arg1 == 2 ? "'add'" : "???"))
1014 << " operation but the matrix is currently in "
1015 << (arg2 == 1 ? "'set'" : (arg2 == 2 ? "'add'" : "???"))
1016 << " mode. You first have to call 'compress()'.");
1017
1018 protected:
1024
1029
1035 void
1037
1043 void
1045
1056 void
1063 void
1065
1081 void
1082 mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const;
1083
1100 void
1101 Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const;
1102
1103 private:
1104 // To allow calling protected prepare_add() and prepare_set().
1105 template <class>
1106 friend class ::BlockMatrixBase;
1107
1108
1112 void
1114 const size_type row,
1115 const size_type n_cols,
1116 const size_type *col_indices,
1117 const PetscScalar *values,
1118 const bool elide_zero_values);
1119 };
1120
1121
1122
1123# ifndef DOXYGEN
1124 // ---------------------- inline and template functions ---------------------
1125
1126
1127 namespace MatrixIterators
1128 {
1130 const size_type row,
1131 const size_type index)
1132 : matrix(const_cast<MatrixBase *>(matrix))
1133 , a_row(row)
1134 , a_index(index)
1135 {
1136 visit_present_row();
1137 }
1138
1139
1140
1141 inline const_iterator::Accessor::size_type
1142 const_iterator::Accessor::row() const
1143 {
1144 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1145 return a_row;
1146 }
1147
1148
1149 inline const_iterator::Accessor::size_type
1150 const_iterator::Accessor::column() const
1151 {
1152 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1153 return (*colnum_cache)[a_index];
1154 }
1155
1156
1157 inline const_iterator::Accessor::size_type
1158 const_iterator::Accessor::index() const
1159 {
1160 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1161 return a_index;
1162 }
1163
1164
1165 inline PetscScalar
1166 const_iterator::Accessor::value() const
1167 {
1168 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1169 return (*value_cache)[a_index];
1170 }
1171
1172
1173 inline const_iterator::const_iterator(const MatrixBase *matrix,
1174 const size_type row,
1175 const size_type index)
1176 : accessor(matrix, row, index)
1177 {}
1178
1179
1180
1181 inline const_iterator &
1182 const_iterator::operator++()
1183 {
1184 Assert(accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
1185
1186 ++accessor.a_index;
1187
1188 // if at end of line: do one step, then cycle until we find a
1189 // row with a nonzero number of entries
1190 if (accessor.a_index >= accessor.colnum_cache->size())
1191 {
1192 accessor.a_index = 0;
1193 ++accessor.a_row;
1194
1195 while ((accessor.a_row < accessor.matrix->m()) &&
1196 (accessor.a_row < accessor.matrix->local_range().second) &&
1197 (accessor.matrix->row_length(accessor.a_row) == 0))
1198 ++accessor.a_row;
1199
1200 accessor.visit_present_row();
1201 }
1202 return *this;
1203 }
1204
1205
1206 inline const_iterator
1207 const_iterator::operator++(int)
1208 {
1209 const const_iterator old_state = *this;
1210 ++(*this);
1211 return old_state;
1212 }
1213
1214
1215 inline const const_iterator::Accessor &
1216 const_iterator::operator*() const
1217 {
1218 return accessor;
1219 }
1220
1221
1222 inline const const_iterator::Accessor *
1223 const_iterator::operator->() const
1224 {
1225 return &accessor;
1226 }
1227
1228
1229 inline bool
1230 const_iterator::operator==(const const_iterator &other) const
1231 {
1232 return (accessor.a_row == other.accessor.a_row &&
1233 accessor.a_index == other.accessor.a_index);
1234 }
1235
1236
1237 inline bool
1238 const_iterator::operator!=(const const_iterator &other) const
1239 {
1240 return !(*this == other);
1241 }
1242
1243
1244 inline bool
1245 const_iterator::operator<(const const_iterator &other) const
1246 {
1247 return (accessor.row() < other.accessor.row() ||
1248 (accessor.row() == other.accessor.row() &&
1249 accessor.index() < other.accessor.index()));
1250 }
1251
1252 } // namespace MatrixIterators
1253
1254
1255
1256 // Inline the set() and add()
1257 // functions, since they will be
1258 // called frequently, and the
1259 // compiler can optimize away
1260 // some unnecessary loops when
1261 // the sizes are given at
1262 // compile time.
1263 inline void
1264 MatrixBase::set(const size_type i, const size_type j, const PetscScalar value)
1265 {
1266 AssertIsFinite(value);
1267
1268 set(i, 1, &j, &value, false);
1269 }
1270
1271
1272
1273 inline void
1274 MatrixBase::set(const std::vector<size_type> &indices,
1275 const FullMatrix<PetscScalar> &values,
1276 const bool elide_zero_values)
1277 {
1278 Assert(indices.size() == values.m(),
1279 ExcDimensionMismatch(indices.size(), values.m()));
1280 Assert(values.m() == values.n(), ExcNotQuadratic());
1281
1282 for (size_type i = 0; i < indices.size(); ++i)
1283 set(indices[i],
1284 indices.size(),
1285 indices.data(),
1286 &values(i, 0),
1287 elide_zero_values);
1288 }
1289
1290
1291
1292 inline void
1293 MatrixBase::set(const std::vector<size_type> &row_indices,
1294 const std::vector<size_type> &col_indices,
1295 const FullMatrix<PetscScalar> &values,
1296 const bool elide_zero_values)
1297 {
1298 Assert(row_indices.size() == values.m(),
1299 ExcDimensionMismatch(row_indices.size(), values.m()));
1300 Assert(col_indices.size() == values.n(),
1301 ExcDimensionMismatch(col_indices.size(), values.n()));
1302
1303 for (size_type i = 0; i < row_indices.size(); ++i)
1304 set(row_indices[i],
1305 col_indices.size(),
1306 col_indices.data(),
1307 &values(i, 0),
1308 elide_zero_values);
1309 }
1310
1311
1312
1313 inline void
1314 MatrixBase::set(const size_type row,
1315 const std::vector<size_type> &col_indices,
1316 const std::vector<PetscScalar> &values,
1317 const bool elide_zero_values)
1318 {
1319 Assert(col_indices.size() == values.size(),
1320 ExcDimensionMismatch(col_indices.size(), values.size()));
1321
1322 set(row,
1323 col_indices.size(),
1324 col_indices.data(),
1325 values.data(),
1326 elide_zero_values);
1327 }
1328
1329
1330
1331 inline void
1332 MatrixBase::set(const size_type row,
1333 const size_type n_cols,
1334 const size_type *col_indices,
1335 const PetscScalar *values,
1336 const bool elide_zero_values)
1337 {
1338 add_or_set(VectorOperation::insert,
1339 row,
1340 n_cols,
1341 col_indices,
1342 values,
1343 elide_zero_values);
1344 }
1345
1346
1347
1348 inline void
1349 MatrixBase::add(const size_type i, const size_type j, const PetscScalar value)
1350 {
1351 AssertIsFinite(value);
1352
1353 if (value == PetscScalar())
1354 {
1355 // we have to check after using Insert/Add in any case to be
1356 // consistent with the MPI communication model, but we can save
1357 // some work if the addend is zero. However, these actions are done
1358 // in case we pass on to the other function.
1359 prepare_action(VectorOperation::add);
1360
1361 return;
1362 }
1363 else
1364 add(i, 1, &j, &value, false);
1365 }
1366
1367
1368
1369 inline void
1370 MatrixBase::add(const std::vector<size_type> &indices,
1371 const FullMatrix<PetscScalar> &values,
1372 const bool elide_zero_values)
1373 {
1374 Assert(indices.size() == values.m(),
1375 ExcDimensionMismatch(indices.size(), values.m()));
1376 Assert(values.m() == values.n(), ExcNotQuadratic());
1377
1378 for (size_type i = 0; i < indices.size(); ++i)
1379 add(indices[i],
1380 indices.size(),
1381 indices.data(),
1382 &values(i, 0),
1383 elide_zero_values);
1384 }
1385
1386
1387
1388 inline void
1389 MatrixBase::add(const std::vector<size_type> &row_indices,
1390 const std::vector<size_type> &col_indices,
1391 const FullMatrix<PetscScalar> &values,
1392 const bool elide_zero_values)
1393 {
1394 Assert(row_indices.size() == values.m(),
1395 ExcDimensionMismatch(row_indices.size(), values.m()));
1396 Assert(col_indices.size() == values.n(),
1397 ExcDimensionMismatch(col_indices.size(), values.n()));
1398
1399 for (size_type i = 0; i < row_indices.size(); ++i)
1400 add(row_indices[i],
1401 col_indices.size(),
1402 col_indices.data(),
1403 &values(i, 0),
1404 elide_zero_values);
1405 }
1406
1407
1408
1409 inline void
1410 MatrixBase::add(const size_type row,
1411 const std::vector<size_type> &col_indices,
1412 const std::vector<PetscScalar> &values,
1413 const bool elide_zero_values)
1414 {
1415 Assert(col_indices.size() == values.size(),
1416 ExcDimensionMismatch(col_indices.size(), values.size()));
1417
1418 add(row,
1419 col_indices.size(),
1420 col_indices.data(),
1421 values.data(),
1422 elide_zero_values);
1423 }
1424
1425
1426
1427 inline void
1428 MatrixBase::add(const size_type row,
1429 const size_type n_cols,
1430 const size_type *col_indices,
1431 const PetscScalar *values,
1432 const bool elide_zero_values,
1433 const bool /*col_indices_are_sorted*/)
1434 {
1435 add_or_set(VectorOperation::add,
1436 row,
1437 n_cols,
1438 col_indices,
1439 values,
1440 elide_zero_values);
1441 }
1442
1443
1444
1445 inline void
1446 MatrixBase::add_or_set(const VectorOperation::values &operation,
1447 const size_type row,
1448 const size_type n_cols,
1449 const size_type *col_indices,
1450 const PetscScalar *values,
1451 const bool elide_zero_values)
1452 {
1453 prepare_action(operation);
1454
1455 const auto petsc_row = static_cast<PetscInt>(row);
1456 AssertIntegerConversion(petsc_row, row);
1457
1458 // Use 100 entries so that we can store a row of a matrix constructed with
1459 // FESystem<3>(FE_Q<3>(2), 3, FE_Q<3>(1), 1) (i.e., a common Stokes FE,
1460 // which has 89 DoFs) with room to spare without allocating memory in the
1461 // free store.
1462 //
1463 // Setting up small_vectors isn't free so only set up column_values if we
1464 // actually use it.
1465 boost::container::small_vector<PetscInt, 100> column_indices;
1466 std::optional<boost::container::small_vector<PetscScalar, 100>>
1467 column_values;
1468
1469 const PetscScalar *values_ptr = nullptr;
1470 if (elide_zero_values == false)
1471 {
1472 column_indices.resize(n_cols);
1473
1474 for (size_type j = 0; j < n_cols; ++j)
1475 {
1476 AssertIsFinite(values[j]);
1477 column_indices[j] = static_cast<PetscInt>(col_indices[j]);
1478 AssertIntegerConversion(column_indices[j], col_indices[j]);
1479 }
1480
1481 values_ptr = values;
1482 }
1483 else
1484 {
1485 // Otherwise, extract nonzero values in each row and get the
1486 // respective index.
1487 column_values.emplace();
1488 for (size_type j = 0; j < n_cols; ++j)
1489 {
1490 const PetscScalar value = values[j];
1491 AssertIsFinite(value);
1492 if (value != PetscScalar())
1493 {
1494 column_indices.push_back(static_cast<PetscInt>(col_indices[j]));
1495 AssertIntegerConversion(column_indices.back(), col_indices[j]);
1496 column_values->push_back(value);
1497 }
1498 }
1499 values_ptr = column_values->data();
1500 }
1501
1502 const auto petsc_n_columns = static_cast<PetscInt>(column_indices.size());
1503 AssertIntegerConversion(petsc_n_columns, column_indices.size());
1504
1505 Assert(operation == VectorOperation::insert ||
1506 operation == VectorOperation::add,
1508 const PetscErrorCode ierr =
1509 MatSetValues(matrix,
1510 1,
1511 &petsc_row,
1512 petsc_n_columns,
1513 column_indices.data(),
1514 values_ptr,
1515 operation == VectorOperation::insert ? INSERT_VALUES :
1516 ADD_VALUES);
1517 AssertThrow(ierr == 0, ExcPETScError(ierr));
1518 }
1519
1520
1521
1522 inline PetscScalar
1523 MatrixBase::operator()(const size_type i, const size_type j) const
1524 {
1525 return el(i, j);
1526 }
1527
1528
1529
1530 inline MatrixBase::const_iterator
1531 MatrixBase::begin() const
1532 {
1533 Assert(
1534 (in_local_range(0) && in_local_range(m() - 1)),
1535 ExcMessage(
1536 "begin() and end() can only be called on a processor owning the entire matrix. If this is a distributed matrix, use begin(row) and end(row) instead."));
1537
1538 // find the first non-empty row in order to make sure that the returned
1539 // iterator points to something useful
1540 size_type first_nonempty_row = 0;
1541 while ((first_nonempty_row < m()) && (row_length(first_nonempty_row) == 0))
1542 ++first_nonempty_row;
1543
1544 return const_iterator(this, first_nonempty_row, 0);
1545 }
1546
1547
1548 inline MatrixBase::const_iterator
1549 MatrixBase::end() const
1550 {
1551 Assert(
1552 (in_local_range(0) && in_local_range(m() - 1)),
1553 ExcMessage(
1554 "begin() and end() can only be called on a processor owning the entire matrix. If this is a distributed matrix, use begin(row) and end(row) instead."));
1555
1556 return const_iterator(this, m(), 0);
1557 }
1558
1559
1560 inline MatrixBase::const_iterator
1561 MatrixBase::begin(const size_type r) const
1562 {
1563 Assert(in_local_range(r),
1565
1566 if (row_length(r) > 0)
1567 return const_iterator(this, r, 0);
1568 else
1569 return end(r);
1570 }
1571
1572
1573 inline MatrixBase::const_iterator
1574 MatrixBase::end(const size_type r) const
1575 {
1576 Assert(in_local_range(r),
1578
1579 // place the iterator on the first entry past this line, or at the
1580 // end of the matrix
1581 //
1582 // in the parallel case, we need to put it on the first entry of
1583 // the first row after the locally owned range. this of course
1584 // doesn't exist, but we can nevertheless create such an
1585 // iterator. we need to check whether 'i' is past the locally
1586 // owned range of rows first, before we ask for the length of the
1587 // row since the latter query leads to an exception in case we ask
1588 // for a row that is not locally owned
1589 for (size_type i = r + 1; i < m(); ++i)
1590 if (i == local_range().second || (row_length(i) > 0))
1591 return const_iterator(this, i, 0);
1592
1593 // if there is no such line, then take the
1594 // end iterator of the matrix
1595 // we don't allow calling end() directly for distributed matrices so we need
1596 // to copy the code without the assertion.
1597 return {this, m(), 0};
1598 }
1599
1600
1601
1602 inline bool
1603 MatrixBase::in_local_range(const size_type index) const
1604 {
1605 PetscInt petsc_begin, petsc_end;
1606
1607 const PetscErrorCode ierr =
1608 MatGetOwnershipRange(static_cast<const Mat &>(matrix),
1609 &petsc_begin,
1610 &petsc_end);
1611 AssertThrow(ierr == 0, ExcPETScError(ierr));
1612
1613 const auto begin = static_cast<size_type>(petsc_begin);
1614 AssertIntegerConversion(begin, petsc_begin);
1615 const auto end = static_cast<size_type>(petsc_end);
1616 AssertIntegerConversion(end, petsc_end);
1617
1618 return ((index >= begin) && (index < end));
1619 }
1620
1621
1622
1623 inline void
1624 MatrixBase::prepare_action(const VectorOperation::values new_action)
1625 {
1626 if (last_action == VectorOperation::unknown)
1627 last_action = new_action;
1628
1629 Assert(last_action == new_action, ExcWrongMode(last_action, new_action));
1630 }
1631
1632
1633
1634 inline void
1635 MatrixBase::assert_is_compressed()
1636 {
1637 // compress() sets the last action to none, which allows us to check if
1638 // there are pending add/insert operations:
1640 ExcMessage("Error: missing compress() call."));
1641 }
1642
1643
1644
1645 inline void
1646 MatrixBase::prepare_add()
1647 {
1648 prepare_action(VectorOperation::add);
1649 }
1650
1651
1652
1653 inline void
1654 MatrixBase::prepare_set()
1655 {
1656 prepare_action(VectorOperation::insert);
1657 }
1658
1659 inline MPI_Comm
1660 MatrixBase::get_mpi_communicator() const
1661 {
1662 return PetscObjectComm(reinterpret_cast<PetscObject>(matrix));
1663 }
1664
1665# endif // DOXYGEN
1666} // namespace PETScWrappers
1667
1668#endif // DEAL_II_WITH_PETSC
1669
1671
1672#endif
*  iterator end()
*  *  iterator begin()
*  x_component_mask set(0, true)
*  *  const_iterator()=default
void add(const size_type i, const size_type j, const PetscScalar value)
void add(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, const FullMatrix< PetscScalar > &full_matrix, const bool elide_zero_values=true)
const_iterator end(const size_type r) const
size_type row_length(const size_type row) const
std::size_t memory_consumption() const
VectorOperation::values last_action
void vmult(VectorBase &dst, const VectorBase &src) const
MPI_Comm get_mpi_communicator() const
PetscScalar diag_element(const size_type i) const
MatrixBase(const MatrixBase &)=delete
size_type local_domain_size() const
const_iterator begin() const
MatrixBase & operator/=(const PetscScalar factor)
void mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
PetscBool is_symmetric(const double tolerance=1.e-12)
std::pair< size_type, size_type > local_domain() const
const_iterator end() const
void Tvmult_add(VectorBase &dst, const VectorBase &src) const
void print(std::ostream &out, const bool alternative_output=false) const
const_iterator begin(const size_type r) const
void add_or_set(const VectorOperation::values &operation, const size_type row, const size_type n_cols, const size_type *col_indices, const PetscScalar *values, const bool elide_zero_values)
void add(const size_type row, const std::vector< size_type > &col_indices, const std::vector< PetscScalar > &values, const bool elide_zero_values=true)
PetscScalar el(const size_type i, const size_type j) const
PetscScalar operator()(const size_type i, const size_type j) const
MatrixBase & operator=(const MatrixBase &)=delete
void set(const std::vector< size_type > &row_indices, const std::vector< size_type > &col_indices, const FullMatrix< PetscScalar > &full_matrix, const bool elide_zero_values=false)
void prepare_action(const VectorOperation::values new_action)
void add(const std::vector< size_type > &indices, const FullMatrix< PetscScalar > &full_matrix, const bool elide_zero_values=true)
bool in_local_range(const size_type index) const
PetscBool is_hermitian(const double tolerance=1.e-12)
PetscScalar matrix_scalar_product(const VectorBase &u, const VectorBase &v) const
void Tvmult(VectorBase &dst, const VectorBase &src) const
void clear_rows_columns(const std::vector< size_type > &row_and_column_indices, const PetscScalar new_diag_value=0)
MatrixBase & operator*=(const PetscScalar factor)
PetscScalar residual(VectorBase &dst, const VectorBase &x, const VectorBase &b) const
void Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
void set(const size_type row, const std::vector< size_type > &col_indices, const std::vector< PetscScalar > &values, const bool elide_zero_values=false)
void add(const size_type row, const size_type n_cols, const size_type *col_indices, const PetscScalar *values, const bool elide_zero_values=true, const bool col_indices_are_sorted=false)
void write_ascii(const PetscViewerFormat format=PETSC_VIEWER_DEFAULT)
void vmult_add(VectorBase &dst, const VectorBase &src) const
std::pair< size_type, size_type > local_range() const
void compress(const VectorOperation::values operation)
PetscScalar matrix_norm_square(const VectorBase &v) const
void set(const size_type row, const size_type n_cols, const size_type *col_indices, const PetscScalar *values, const bool elide_zero_values=false)
void clear_rows(const ArrayView< const size_type > &rows, const PetscScalar new_diag_value=0)
void set(const std::vector< size_type > &indices, const FullMatrix< PetscScalar > &full_matrix, const bool elide_zero_values=false)
void set(const size_type i, const size_type j, const PetscScalar value)
std::uint64_t n_nonzero_elements() const
void clear_row(const size_type row, const PetscScalar new_diag_value=0)
std::shared_ptr< const std::vector< PetscScalar > > value_cache
std::shared_ptr< const std::vector< size_type > > colnum_cache
Accessor(const MatrixBase *matrix, const size_type row, const size_type index)
bool operator!=(const const_iterator &) const
const_iterator(const MatrixBase *matrix, const size_type row, const size_type index)
bool operator==(const const_iterator &) const
bool operator<(const const_iterator &) const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define AssertIntegerConversion(index1, index2)
Point< 2 > second
Definition grid_out.cc:4640
Point< 2 > first
Definition grid_out.cc:4639
#define DeclException0(Exception0)
static ::ExceptionBase & ExcAccessToNonlocalRow(int arg1, int arg2, int arg3)
#define Assert(cond, exc)
static ::ExceptionBase & ExcIteratorPastEnd()
static ::ExceptionBase & ExcInvalidIndexWithinRow(int arg1, int arg2)
#define AssertIsFinite(number)
#define DeclException2(Exception2, type1, type2, outsequence)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcSourceEqualsDestination()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcWrongMode(int arg1, int arg2)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::pair< types::global_dof_index, types::global_dof_index > local_range
Definition mpi.cc:814
@ matrix
Contents is actually a matrix.
unsigned int global_dof_index
Definition types.h:92