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.cc
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
14
15#ifdef DEAL_II_WITH_PETSC
16
22
23
24#endif // DEAL_II_WITH_PETSC
25
27
28#ifdef DEAL_II_WITH_PETSC
29
30namespace PETScWrappers
31{
32 namespace MatrixIterators
33 {
34# ifndef DOXYGEN
35 void
36 MatrixBase::const_iterator::Accessor::visit_present_row()
37 {
38 // if we are asked to visit the past-the-end line (or a line that is not
39 // stored on the current processor), then simply release all our caches
40 // and go on with life
41 if (matrix->in_local_range(this->a_row) == false)
42 {
43 colnum_cache.reset();
44 value_cache.reset();
45
46 return;
47 }
48
49 // get a representation of the present row
50 PetscInt ncols;
51 const PetscInt *colnums;
52 const PetscScalar *values;
53
54 PetscErrorCode ierr =
55 MatGetRow(*matrix, this->a_row, &ncols, &colnums, &values);
56 AssertThrow(ierr == 0, ExcPETScError(ierr));
57
58 // copy it into our caches if the line
59 // isn't empty. if it is, then we've
60 // done something wrong, since we
61 // shouldn't have initialized an
62 // iterator for an empty line (what
63 // would it point to?)
64 Assert(ncols != 0, ExcInternalError());
65 if constexpr (running_in_debug_mode())
66 {
67 for (PetscInt j = 0; j < ncols; ++j)
68 {
69 const auto column = static_cast<PetscInt>(colnums[j]);
70 AssertIntegerConversion(column, colnums[j]);
71 }
72 }
73 colnum_cache =
74 std::make_shared<std::vector<size_type>>(colnums, colnums + ncols);
75 value_cache =
76 std::make_shared<std::vector<PetscScalar>>(values, values + ncols);
77
78 // and finally restore the matrix
79 ierr = MatRestoreRow(*matrix, this->a_row, &ncols, &colnums, &values);
80 AssertThrow(ierr == 0, ExcPETScError(ierr));
81 }
82# endif
83 } // namespace MatrixIterators
84
85
86
88 : matrix(nullptr)
89 , last_action(VectorOperation::unknown)
90 {}
91
92
94 : matrix(A)
95 , last_action(VectorOperation::unknown)
96 {
97 const PetscErrorCode ierr =
98 PetscObjectReference(reinterpret_cast<PetscObject>(matrix));
99 AssertThrow(ierr == 0, ExcPETScError(ierr));
100 }
101
102 void
104 {
106 ExcMessage("Cannot assign a new Mat."));
107 PetscErrorCode ierr =
108 PetscObjectReference(reinterpret_cast<PetscObject>(A));
109 AssertThrow(ierr == 0, ExcPETScError(ierr));
110 ierr = MatDestroy(&matrix);
111 AssertThrow(ierr == 0, ExcPETScError(ierr));
112 matrix = A;
113 }
114
116 {
117 PetscErrorCode ierr = MatDestroy(&matrix);
118 AssertNothrow(ierr == 0, ExcPETScError(ierr));
119 }
120
121 void
123 {
124 // destroy the matrix...
125 {
126 const PetscErrorCode ierr = MatDestroy(&matrix);
127 AssertThrow(ierr == 0, ExcPETScError(ierr));
128 }
129
130 // ...and replace it by an empty
131 // sequential matrix
132 const int m = 0, n = 0, n_nonzero_per_row = 0;
133 const PetscErrorCode ierr = MatCreateSeqAIJ(
134 PETSC_COMM_SELF, m, n, n_nonzero_per_row, nullptr, &matrix);
135 AssertThrow(ierr == 0, ExcPETScError(ierr));
136 }
137
138
139
140 MatrixBase &
142 {
144
146
147 const PetscErrorCode ierr = MatZeroEntries(matrix);
148 AssertThrow(ierr == 0, ExcPETScError(ierr));
149
150 return *this;
151 }
152
153
154
155 void
156 MatrixBase::clear_row(const size_type row, const PetscScalar new_diag_value)
157 {
158 clear_rows(ArrayView<const size_type>(row), new_diag_value);
159 }
160
161
162
163 void
165 const PetscScalar new_diag_value)
166 {
168
169 // now set all the entries of these rows to zero
170 if constexpr (running_in_debug_mode())
171 {
172 for (const auto &row : rows)
173 AssertIntegerConversion(static_cast<PetscInt>(row), row);
174 }
175 const std::vector<PetscInt> petsc_rows(rows.begin(), rows.end());
176
177 // call the functions. note that we have
178 // to call them even if #rows is empty,
179 // since this is a collective operation
180 IS index_set;
181
182 PetscErrorCode ierr;
183 ierr = ISCreateGeneral(get_mpi_communicator(),
184 rows.size(),
185 petsc_rows.data(),
186 PETSC_COPY_VALUES,
187 &index_set);
188 AssertThrow(ierr == 0, ExcPETScError(ierr));
189
190 ierr = MatZeroRowsIS(matrix, index_set, new_diag_value, nullptr, nullptr);
191 AssertThrow(ierr == 0, ExcPETScError(ierr));
192 ierr = ISDestroy(&index_set);
193 AssertThrow(ierr == 0, ExcPETScError(ierr));
194 }
195
196 void
197 MatrixBase::clear_rows_columns(const std::vector<size_type> &rows,
198 const PetscScalar new_diag_value)
199 {
201
202 // now set all the entries of these rows to zero
203 if constexpr (running_in_debug_mode())
204 {
205 for (const auto &row : rows)
206 AssertIntegerConversion(static_cast<PetscInt>(row), row);
207 }
208 const std::vector<PetscInt> petsc_rows(rows.begin(), rows.end());
209
210 // call the functions. note that we have
211 // to call them even if #rows is empty,
212 // since this is a collective operation
213 IS index_set;
214
215 PetscErrorCode ierr;
216 ierr = ISCreateGeneral(get_mpi_communicator(),
217 rows.size(),
218 petsc_rows.data(),
219 PETSC_COPY_VALUES,
220 &index_set);
221 AssertThrow(ierr == 0, ExcPETScError(ierr));
222
223 ierr =
224 MatZeroRowsColumnsIS(matrix, index_set, new_diag_value, nullptr, nullptr);
225 AssertThrow(ierr == 0, ExcPETScError(ierr));
226 ierr = ISDestroy(&index_set);
227 AssertThrow(ierr == 0, ExcPETScError(ierr));
228 }
229
230
231
232 PetscScalar
233 MatrixBase::el(const size_type i, const size_type j) const
234 {
235 const auto petsc_i = static_cast<PetscInt>(i);
236 AssertIntegerConversion(petsc_i, i);
237 const auto petsc_j = static_cast<PetscInt>(j);
238 AssertIntegerConversion(petsc_j, j);
239
240 PetscScalar value;
241
242 const PetscErrorCode ierr =
243 MatGetValues(matrix, 1, &petsc_i, 1, &petsc_j, &value);
244 AssertThrow(ierr == 0, ExcPETScError(ierr));
245
246 return value;
247 }
248
249
250
251 PetscScalar
253 {
254 Assert(m() == n(), ExcNotQuadratic());
255
256 // this doesn't seem to work any
257 // different than any other element
258 return el(i, i);
259 }
260
261
262
263 void
265 {
266 {
267 if constexpr (running_in_debug_mode())
268 {
269 // Check that all processors agree that last_action is the same (or
270 // none!)
271
272 int my_int_last_action = last_action;
273 int all_int_last_action;
274
275 const int ierr = MPI_Allreduce(&my_int_last_action,
276 &all_int_last_action,
277 1,
278 MPI_INT,
279 MPI_BOR,
281 AssertThrowMPI(ierr);
282
283 AssertThrow(all_int_last_action !=
286 "Error: not all processors agree on the last "
287 "VectorOperation before this compress() call."));
288 }
289 }
290
294 "Missing compress() or calling with wrong VectorOperation argument."));
295
296 // flush buffers
297 PetscErrorCode ierr = MatAssemblyBegin(matrix, MAT_FINAL_ASSEMBLY);
298 AssertThrow(ierr == 0, ExcPETScError(ierr));
299
300 ierr = MatAssemblyEnd(matrix, MAT_FINAL_ASSEMBLY);
301 AssertThrow(ierr == 0, ExcPETScError(ierr));
302
304 }
305
306
307
310 {
311 PetscInt n_rows, n_cols;
312
313 const PetscErrorCode ierr = MatGetSize(matrix, &n_rows, &n_cols);
314 AssertThrow(ierr == 0, ExcPETScError(ierr));
315
316 return n_rows;
317 }
318
319
320
323 {
324 PetscInt n_rows, n_cols;
325
326 const PetscErrorCode ierr = MatGetSize(matrix, &n_rows, &n_cols);
327 AssertThrow(ierr == 0, ExcPETScError(ierr));
328
329 return n_cols;
330 }
331
332
333
336 {
337 PetscInt n_rows;
338
339 const PetscErrorCode ierr = MatGetLocalSize(matrix, &n_rows, nullptr);
340 AssertThrow(ierr == 0, ExcPETScError(ierr));
341
342 return n_rows;
343 }
344
345
346
347 std::pair<MatrixBase::size_type, MatrixBase::size_type>
349 {
350 PetscInt begin, end;
351
352 const PetscErrorCode ierr =
353 MatGetOwnershipRange(static_cast<const Mat &>(matrix), &begin, &end);
354 AssertThrow(ierr == 0, ExcPETScError(ierr));
355
356 return {begin, end};
357 }
358
359
360
363 {
364 PetscInt n_cols;
365
366 const PetscErrorCode ierr = MatGetLocalSize(matrix, nullptr, &n_cols);
367 AssertThrow(ierr == 0, ExcPETScError(ierr));
368
369 return n_cols;
370 }
371
372
373
374 std::pair<MatrixBase::size_type, MatrixBase::size_type>
376 {
377 PetscInt begin, end;
378
379 const PetscErrorCode ierr =
380 MatGetOwnershipRangeColumn(static_cast<const Mat &>(matrix),
381 &begin,
382 &end);
383 AssertThrow(ierr == 0, ExcPETScError(ierr));
384
385 return {begin, end};
386 }
387
388
389
390 std::uint64_t
392 {
393 MatInfo mat_info;
394 const PetscErrorCode ierr = MatGetInfo(matrix, MAT_GLOBAL_SUM, &mat_info);
395 AssertThrow(ierr == 0, ExcPETScError(ierr));
396
397 // MatInfo logs quantities as PetscLogDouble. So we need to cast it to match
398 // our interface.
399 return static_cast<std::uint64_t>(mat_info.nz_used);
400 }
401
402
403
406 {
407 // TODO: this function will probably only work if compress() was called on
408 // the matrix previously. however, we can't do this here, since it would
409 // impose global communication and one would have to make sure that this
410 // function is called the same number of times from all processors,
411 // something that is unreasonable. there should simply be a way in PETSc to
412 // query the number of entries in a row bypassing the call to compress(),
413 // but I can't find one
414 AssertIndexRange(row, m());
415
416 // get a representation of the present
417 // row
418 PetscInt ncols;
419 const PetscInt *colnums;
420 const PetscScalar *values;
421
422 // TODO: this is probably horribly inefficient; we should lobby for a way to
423 // query this information from PETSc
424 PetscErrorCode ierr = MatGetRow(*this, row, &ncols, &colnums, &values);
425 AssertThrow(ierr == 0, ExcPETScError(ierr));
426
427 // then restore the matrix and return the number of columns in this row as
428 // queried previously. Starting with PETSc 3.4, MatRestoreRow actually
429 // resets the last three arguments to nullptr, to avoid abuse of pointers
430 // now dangling. as a consequence, we need to save the size of the array
431 // and return the saved value.
432 const PetscInt ncols_saved = ncols;
433 ierr = MatRestoreRow(*this, row, &ncols, &colnums, &values);
434 AssertThrow(ierr == 0, ExcPETScError(ierr));
435
436 return ncols_saved;
437 }
438
439
440 PetscReal
442 {
443 PetscReal result;
444
445 const PetscErrorCode ierr = MatNorm(matrix, NORM_1, &result);
446 AssertThrow(ierr == 0, ExcPETScError(ierr));
447
448 return result;
449 }
450
451
452
453 PetscReal
455 {
456 PetscReal result;
457
458 const PetscErrorCode ierr = MatNorm(matrix, NORM_INFINITY, &result);
459 AssertThrow(ierr == 0, ExcPETScError(ierr));
460
461 return result;
462 }
463
464
465
466 PetscReal
468 {
469 PetscReal result;
470
471 const PetscErrorCode ierr = MatNorm(matrix, NORM_FROBENIUS, &result);
472 AssertThrow(ierr == 0, ExcPETScError(ierr));
473
474 return result;
475 }
476
477
478 PetscScalar
480 {
481 AssertDimension(m(), v.size());
482
483 VectorBase tmp(v);
484 vmult(tmp, v);
485 return tmp * v;
486 }
487
488
489 PetscScalar
491 const VectorBase &v) const
492 {
493 AssertDimension(m(), u.size());
494 AssertDimension(m(), v.size());
495
496 VectorBase tmp(u);
497 vmult(tmp, v);
498 return u * tmp;
499 }
500
501
502 PetscScalar
504 {
505 PetscScalar result;
506
507 const PetscErrorCode ierr = MatGetTrace(matrix, &result);
508 AssertThrow(ierr == 0, ExcPETScError(ierr));
509
510 return result;
511 }
512
513
514
515 MatrixBase &
516 MatrixBase::operator*=(const PetscScalar a)
517 {
518 const PetscErrorCode ierr = MatScale(matrix, a);
519 AssertThrow(ierr == 0, ExcPETScError(ierr));
520
521 return *this;
522 }
523
524
525
526 MatrixBase &
527 MatrixBase::operator/=(const PetscScalar a)
528 {
529 const PetscScalar factor = 1. / a;
530 const PetscErrorCode ierr = MatScale(matrix, factor);
531 AssertThrow(ierr == 0, ExcPETScError(ierr));
532
533 return *this;
534 }
535
536
537
538 MatrixBase &
539 MatrixBase::add(const PetscScalar factor, const MatrixBase &other)
540 {
541 const PetscErrorCode ierr =
542 MatAXPY(matrix, factor, other, DIFFERENT_NONZERO_PATTERN);
543 AssertThrow(ierr == 0, ExcPETScError(ierr));
544
545 return *this;
546 }
547
548
549 void
551 {
552 Assert(&src != &dst, ExcSourceEqualsDestination());
553
554 const PetscErrorCode ierr = MatMult(matrix, src, dst);
555 AssertThrow(ierr == 0, ExcPETScError(ierr));
556 }
557
558
559
560 void
562 {
563 Assert(&src != &dst, ExcSourceEqualsDestination());
564
565 const PetscErrorCode ierr = MatMultTranspose(matrix, src, dst);
566 AssertThrow(ierr == 0, ExcPETScError(ierr));
567 }
568
569
570
571 void
573 {
574 Assert(&src != &dst, ExcSourceEqualsDestination());
575
576 const PetscErrorCode ierr = MatMultAdd(matrix, src, dst, dst);
577 AssertThrow(ierr == 0, ExcPETScError(ierr));
578 }
579
580
581
582 void
584 {
585 Assert(&src != &dst, ExcSourceEqualsDestination());
586
587 const PetscErrorCode ierr = MatMultTransposeAdd(matrix, src, dst, dst);
588 AssertThrow(ierr == 0, ExcPETScError(ierr));
589 }
590
591
592 namespace internals
593 {
594 void
595 perform_mmult(const MatrixBase &inputleft,
596 const MatrixBase &inputright,
597 MatrixBase &result,
598 const VectorBase &V,
599 const bool transpose_left)
600 {
601 const bool use_vector = (V.size() == inputright.m() ? true : false);
602 if (transpose_left == false)
603 {
604 Assert(inputleft.n() == inputright.m(),
605 ExcDimensionMismatch(inputleft.n(), inputright.m()));
606 }
607 else
608 {
609 Assert(inputleft.m() == inputright.m(),
610 ExcDimensionMismatch(inputleft.m(), inputright.m()));
611 }
612
613 result.clear();
614
615 PetscErrorCode ierr;
616
617 if (use_vector == false)
618 {
619 if (transpose_left)
620 {
621 ierr = MatTransposeMatMult(inputleft,
622 inputright,
623 MAT_INITIAL_MATRIX,
624 PETSC_DEFAULT,
625 &result.petsc_matrix());
626 AssertThrow(ierr == 0, ExcPETScError(ierr));
627 }
628 else
629 {
630 ierr = MatMatMult(inputleft,
631 inputright,
632 MAT_INITIAL_MATRIX,
633 PETSC_DEFAULT,
634 &result.petsc_matrix());
635 AssertThrow(ierr == 0, ExcPETScError(ierr));
636 }
637 }
638 else
639 {
640 Mat tmp;
641 ierr = MatDuplicate(inputleft, MAT_COPY_VALUES, &tmp);
642 AssertThrow(ierr == 0, ExcPETScError(ierr));
643 if (transpose_left)
644 {
645# if DEAL_II_PETSC_VERSION_LT(3, 8, 0)
646 ierr = MatTranspose(tmp, MAT_REUSE_MATRIX, &tmp);
647# else
648 ierr = MatTranspose(tmp, MAT_INPLACE_MATRIX, &tmp);
649# endif
650 AssertThrow(ierr == 0, ExcPETScError(ierr));
651 }
652 ierr = MatDiagonalScale(tmp, nullptr, V);
653 AssertThrow(ierr == 0, ExcPETScError(ierr));
654 ierr = MatMatMult(tmp,
655 inputright,
656 MAT_INITIAL_MATRIX,
657 PETSC_DEFAULT,
658 &result.petsc_matrix());
659 AssertThrow(ierr == 0, ExcPETScError(ierr));
660 ierr = MatDestroy(&tmp);
661 AssertThrow(ierr == 0, ExcPETScError(ierr));
662 }
663 }
664 } // namespace internals
665
666 void
668 const MatrixBase &B,
669 const VectorBase &V) const
670 {
671 internals::perform_mmult(*this, B, C, V, false);
672 }
673
674 void
676 const MatrixBase &B,
677 const VectorBase &V) const
678 {
679 internals::perform_mmult(*this, B, C, V, true);
680 }
681
682 PetscScalar
684 const VectorBase &x,
685 const VectorBase &b) const
686 {
687 // avoid the use of a temporary, and
688 // rather do one negation pass more than
689 // necessary
690 vmult(dst, x);
691 dst -= b;
692 dst *= -1;
693
694 return dst.l2_norm();
695 }
696
697
698
699 MatrixBase::operator Mat() const
700 {
701 return matrix;
702 }
703
704 Mat &
706 {
707 return matrix;
708 }
709
710 void
712 {
713# if DEAL_II_PETSC_VERSION_LT(3, 8, 0)
714 const PetscErrorCode ierr = MatTranspose(matrix, MAT_REUSE_MATRIX, &matrix);
715# else
716 const PetscErrorCode ierr =
717 MatTranspose(matrix, MAT_INPLACE_MATRIX, &matrix);
718# endif
719 AssertThrow(ierr == 0, ExcPETScError(ierr));
720 }
721
722 PetscBool
723 MatrixBase::is_symmetric(const double tolerance)
724 {
725 PetscBool truth;
727 const PetscErrorCode ierr = MatIsSymmetric(matrix, tolerance, &truth);
728 AssertThrow(ierr == 0, ExcPETScError(ierr));
729 return truth;
730 }
731
732 PetscBool
733 MatrixBase::is_hermitian(const double tolerance)
734 {
735 PetscBool truth;
736
738 const PetscErrorCode ierr = MatIsHermitian(matrix, tolerance, &truth);
739 AssertThrow(ierr == 0, ExcPETScError(ierr));
740
741 return truth;
742 }
743
744 void
745 MatrixBase::write_ascii(const PetscViewerFormat format)
746 {
748 MPI_Comm comm = PetscObjectComm(reinterpret_cast<PetscObject>(matrix));
749
750 // Set options
751 PetscErrorCode ierr =
752 PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(comm), format);
753 AssertThrow(ierr == 0, ExcPETScError(ierr));
754
755 // Write to screen
756 ierr = MatView(matrix, PETSC_VIEWER_STDOUT_(comm));
757 AssertThrow(ierr == 0, ExcPETScError(ierr));
758 ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(comm));
759 AssertThrow(ierr == 0, ExcPETScError(ierr));
760 }
761
762 void
763 MatrixBase::print(std::ostream &out, const bool /*alternative_output*/) const
764 {
765 PetscBool has;
766
767 PetscErrorCode ierr = MatHasOperation(matrix, MATOP_GET_ROW, &has);
768 AssertThrow(ierr == 0, ExcPETScError(ierr));
769
770 Mat vmatrix = matrix;
771 if (!has)
772 {
773 ierr = MatConvert(matrix, MATAIJ, MAT_INITIAL_MATRIX, &vmatrix);
774 AssertThrow(ierr == 0, ExcPETScError(ierr));
775 }
776
777 std::pair<MatrixBase::size_type, MatrixBase::size_type> loc_range =
778 local_range();
779
780 PetscInt ncols;
781 const PetscInt *colnums;
782 const PetscScalar *values;
783
785 for (row = loc_range.first; row < loc_range.second; ++row)
786 {
787 ierr = MatGetRow(vmatrix, row, &ncols, &colnums, &values);
788 AssertThrow(ierr == 0, ExcPETScError(ierr));
789
790 for (PetscInt col = 0; col < ncols; ++col)
791 {
792 out << "(" << row << "," << colnums[col] << ") " << values[col]
793 << std::endl;
794 }
795
796 ierr = MatRestoreRow(vmatrix, row, &ncols, &colnums, &values);
797 AssertThrow(ierr == 0, ExcPETScError(ierr));
798 }
799 if (vmatrix != matrix)
800 {
801 ierr = MatDestroy(&vmatrix);
802 AssertThrow(ierr == 0, ExcPETScError(ierr));
803 }
804 AssertThrow(out.fail() == false, ExcIO());
805 }
806
807
808
809 std::size_t
811 {
812 MatInfo info;
813 const PetscErrorCode ierr = MatGetInfo(matrix, MAT_LOCAL, &info);
814 AssertThrow(ierr == 0, ExcPETScError(ierr));
815
816 return (sizeof(*this) +
817 static_cast<size_type>(
818 // In a typical CSR format, one needs one scalar and one int to
819 // represent each nonzero in the matrix:
820 ((info.nz_allocated * (sizeof(PetscScalar) + sizeof(PetscInt))) +
821 // Plus one integer to store the row-start index for each
822 // (locally stored) row:
823 local_size() * sizeof(PetscInt))));
824 }
825
826} // namespace PETScWrappers
827
828
829#endif // DEAL_II_WITH_PETSC
iterator begin() const
Definition array_view.h:755
iterator end() const
Definition array_view.h:764
std::size_t size() const
Definition array_view.h:737
void add(const size_type i, const size_type j, const PetscScalar value)
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
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
PetscScalar el(const size_type i, const size_type j) const
MatrixBase & operator=(const MatrixBase &)=delete
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 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 clear_rows(const ArrayView< const size_type > &rows, const PetscScalar new_diag_value=0)
std::uint64_t n_nonzero_elements() const
void clear_row(const size_type row, const PetscScalar new_diag_value=0)
size_type size() const override
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
constexpr bool running_in_debug_mode()
Definition config.h:76
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define AssertIntegerConversion(index1, index2)
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcScalarAssignmentOnlyForZeroValue()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertNothrow(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcSourceEqualsDestination()
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcNotQuadratic()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
bool use_vector
Definition mpi.cc:732
const MPI_Comm comm
Definition mpi.cc:912
@ matrix
Contents is actually a matrix.
void perform_mmult(const MatrixBase &inputleft, const MatrixBase &inputright, MatrixBase &result, const VectorBase &V, const bool transpose_left)