16#ifndef dealii_petsc_matrix_base_h
17# define dealii_petsc_matrix_base_h
22# ifdef DEAL_II_WITH_PETSC
42template <
typename Matrix>
52 namespace MatrixIterators
124 <<
"You tried to access row " << arg1
125 <<
" of a distributed matrix, but only rows " << arg2
126 <<
" through " << arg3
127 <<
" are stored locally and can be accessed.");
240 <<
"Attempt to access element " << arg2 <<
" of row "
241 << arg1 <<
" which doesn't have that many elements.");
377 set(
const std::vector<size_type> & indices,
379 const bool elide_zero_values =
false);
387 set(
const std::vector<size_type> & row_indices,
388 const std::vector<size_type> & col_indices,
390 const bool elide_zero_values =
false);
408 const std::vector<size_type> & col_indices,
409 const std::vector<PetscScalar> &values,
410 const bool elide_zero_values =
false);
430 const PetscScalar *values,
431 const bool elide_zero_values =
false);
465 add(
const std::vector<size_type> & indices,
467 const bool elide_zero_values =
true);
475 add(
const std::vector<size_type> & row_indices,
476 const std::vector<size_type> & col_indices,
478 const bool elide_zero_values =
true);
496 const std::vector<size_type> & col_indices,
497 const std::vector<PetscScalar> &values,
498 const bool elide_zero_values =
true);
518 const PetscScalar *values,
519 const bool elide_zero_values =
true,
520 const bool col_indices_are_sorted =
false);
550 clear_rows(
const std::vector<size_type> &rows,
551 const PetscScalar new_diag_value = 0);
634 std::pair<size_type, size_type>
877 operator Mat()
const;
915 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
925 print(std::ostream &out,
const bool alternative_output =
false)
const;
937 "You are attempting an operation on two matrices that "
938 "are the same object, but the operation requires that the "
939 "two objects are in fact different.");
947 <<
"You tried to do a "
948 << (arg1 == 1 ?
"'set'" : (arg1 == 2 ?
"'add'" :
"???"))
949 <<
" operation but the matrix is currently in "
950 << (arg2 == 1 ?
"'set'" : (arg2 == 2 ?
"'add'" :
"???"))
951 <<
" mode. You first have to call 'compress()'.");
1068 friend class ::BlockMatrixBase;
1077 namespace MatrixIterators
1080 const size_type row,
1081 const size_type index)
1086 visit_present_row();
1102 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1103 return (*colnum_cache)[a_index];
1110 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1118 Assert(a_row < matrix->m(), ExcBeyondEndOfMatrix());
1119 return (*value_cache)[a_index];
1131 inline const_iterator &
1132 const_iterator::operator++()
1140 if (accessor.a_index >= accessor.colnum_cache->size())
1142 accessor.a_index = 0;
1145 while ((accessor.a_row < accessor.matrix->m()) &&
1146 (accessor.a_row < accessor.matrix->local_range().second) &&
1147 (accessor.matrix->row_length(accessor.a_row) == 0))
1150 accessor.visit_present_row();
1156 inline const_iterator
1157 const_iterator::operator++(
int)
1159 const const_iterator old_state = *
this;
1165 inline const const_iterator::Accessor &
1166 const_iterator::operator*()
const
1172 inline const const_iterator::Accessor *
1173 const_iterator::operator->()
const
1180 const_iterator::operator==(
const const_iterator &other)
const
1182 return (accessor.a_row == other.accessor.a_row &&
1183 accessor.a_index == other.accessor.a_index);
1188 const_iterator::operator!=(
const const_iterator &other)
const
1190 return !(*
this == other);
1195 const_iterator::operator<(
const const_iterator &other)
const
1197 return (accessor.row() < other.accessor.row() ||
1198 (accessor.row() == other.accessor.row() &&
1199 accessor.index() < other.accessor.index()));
1214 MatrixBase::set(
const size_type i,
const size_type j,
const PetscScalar value)
1218 set(i, 1, &j, &value,
false);
1224 MatrixBase::set(
const std::vector<size_type> & indices,
1226 const bool elide_zero_values)
1232 for (size_type i = 0; i < indices.size(); ++i)
1243 MatrixBase::set(
const std::vector<size_type> & row_indices,
1244 const std::vector<size_type> & col_indices,
1246 const bool elide_zero_values)
1253 for (size_type i = 0; i < row_indices.size(); ++i)
1264 MatrixBase::set(
const size_type row,
1265 const std::vector<size_type> & col_indices,
1266 const std::vector<PetscScalar> &values,
1267 const bool elide_zero_values)
1282 MatrixBase::set(
const size_type row,
1283 const size_type n_cols,
1284 const size_type * col_indices,
1285 const PetscScalar *values,
1286 const bool elide_zero_values)
1290 const PetscInt petsc_i = row;
1291 PetscInt
const *col_index_ptr;
1293 PetscScalar
const *col_value_ptr;
1297 if (elide_zero_values ==
false)
1299 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1307 if (column_indices.size() < n_cols)
1309 column_indices.resize(n_cols);
1310 column_values.resize(n_cols);
1314 for (size_type j = 0; j < n_cols; ++j)
1318 if (value != PetscScalar())
1320 column_indices[n_columns] = col_indices[j];
1321 column_values[n_columns] =
value;
1327 col_index_ptr = column_indices.data();
1328 col_value_ptr = column_values.data();
1331 const PetscErrorCode ierr = MatSetValues(matrix,
1344 MatrixBase::add(
const size_type i,
const size_type j,
const PetscScalar value)
1348 if (value == PetscScalar())
1359 add(i, 1, &j, &value,
false);
1365 MatrixBase::add(
const std::vector<size_type> & indices,
1367 const bool elide_zero_values)
1373 for (size_type i = 0; i < indices.size(); ++i)
1384 MatrixBase::add(
const std::vector<size_type> & row_indices,
1385 const std::vector<size_type> & col_indices,
1387 const bool elide_zero_values)
1394 for (size_type i = 0; i < row_indices.size(); ++i)
1405 MatrixBase::add(
const size_type row,
1406 const std::vector<size_type> & col_indices,
1407 const std::vector<PetscScalar> &values,
1408 const bool elide_zero_values)
1423 MatrixBase::add(
const size_type row,
1424 const size_type n_cols,
1425 const size_type * col_indices,
1426 const PetscScalar *values,
1427 const bool elide_zero_values,
1430 (void)elide_zero_values;
1434 const PetscInt petsc_i = row;
1435 PetscInt
const *col_index_ptr;
1437 PetscScalar
const *col_value_ptr;
1441 if (elide_zero_values ==
false)
1443 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1451 if (column_indices.size() < n_cols)
1453 column_indices.resize(n_cols);
1454 column_values.resize(n_cols);
1458 for (size_type j = 0; j < n_cols; ++j)
1462 if (value != PetscScalar())
1464 column_indices[n_columns] = col_indices[j];
1465 column_values[n_columns] =
value;
1471 col_index_ptr = column_indices.data();
1472 col_value_ptr = column_values.data();
1475 const PetscErrorCode ierr = MatSetValues(
1476 matrix, 1, &petsc_i, n_columns, col_index_ptr, col_value_ptr, ADD_VALUES);
1483 MatrixBase::operator()(
const size_type i,
const size_type j)
const
1490 inline MatrixBase::const_iterator
1491 MatrixBase::begin()
const
1494 (in_local_range(0) && in_local_range(m() - 1)),
1496 "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."));
1501 while ((first_nonempty_row < m()) && (row_length(first_nonempty_row) == 0))
1502 ++first_nonempty_row;
1504 return const_iterator(
this, first_nonempty_row, 0);
1508 inline MatrixBase::const_iterator
1509 MatrixBase::end()
const
1512 (in_local_range(0) && in_local_range(m() - 1)),
1514 "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."));
1516 return const_iterator(
this, m(), 0);
1520 inline MatrixBase::const_iterator
1521 MatrixBase::begin(
const size_type r)
const
1523 Assert(in_local_range(r),
1526 if (row_length(r) > 0)
1527 return const_iterator(
this, r, 0);
1533 inline MatrixBase::const_iterator
1534 MatrixBase::end(
const size_type r)
const
1536 Assert(in_local_range(r),
1549 for (size_type i = r + 1; i < m(); ++i)
1550 if (i == local_range().second || (row_length(i) > 0))
1551 return const_iterator(
this, i, 0);
1557 return {
this, m(), 0};
1563 MatrixBase::in_local_range(
const size_type index)
const
1567 const PetscErrorCode ierr =
1568 MatGetOwnershipRange(
static_cast<const Mat &
>(matrix), &begin, &end);
1571 return ((index >=
static_cast<size_type>(begin)) &&
1581 last_action = new_action;
1583 Assert(last_action == new_action, ExcWrongMode(last_action, new_action));
1589 MatrixBase::assert_is_compressed()
1594 ExcMessage(
"Error: missing compress() call."));
1600 MatrixBase::prepare_add()
1608 MatrixBase::prepare_set()
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
PetscReal l1_norm() const
VectorOperation::values last_action
void vmult(VectorBase &dst, const VectorBase &src) const
void clear_rows(const std::vector< size_type > &rows, const PetscScalar new_diag_value=0)
std::vector< PetscScalar > column_values
PetscScalar diag_element(const size_type i) const
MatrixBase(const MatrixBase &)=delete
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)
PetscReal frobenius_norm() const
virtual ~MatrixBase() override
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(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
size_type local_size() 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)
PetscScalar trace() const
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 assert_is_compressed()
std::vector< PetscInt > column_indices
void Tvmult(VectorBase &dst, const VectorBase &src) const
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)
virtual const MPI_Comm & get_mpi_communicator() const =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)
PetscReal linfty_norm() const
std::shared_ptr< const std::vector< PetscScalar > > value_cache
PetscScalar value() const
types::global_dof_index size_type
std::shared_ptr< const std::vector< size_type > > colnum_cache
Accessor(const MatrixBase *matrix, const size_type row, const size_type index)
const_iterator operator++(int)
bool operator!=(const const_iterator &) const
const_iterator(const MatrixBase *matrix, const size_type row, const size_type index)
types::global_dof_index size_type
bool operator==(const const_iterator &) const
bool operator<(const const_iterator &) const
const_iterator & operator++()
const Accessor * operator->() const
const Accessor & operator*() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
__global__ void set(Number *val, const Number s, const size_type N)
#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)
static ::ExceptionBase & ExcBeyondEndOfMatrix()
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcSourceEqualsDestination()
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)
@ matrix
Contents is actually a matrix.
types::global_dof_index size_type
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
unsigned int global_dof_index