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