16 #ifndef dealii_petsc_matrix_base_h 17 # define dealii_petsc_matrix_base_h 20 # include <deal.II/base/config.h> 22 # ifdef DEAL_II_WITH_PETSC 24 # include <deal.II/base/subscriptor.h> 26 # include <deal.II/lac/exceptions.h> 27 # include <deal.II/lac/full_matrix.h> 28 # include <deal.II/lac/petsc_compatibility.h> 29 # include <deal.II/lac/petsc_vector_base.h> 30 # include <deal.II/lac/vector_operation.h> 32 # include <petscmat.h> 38 DEAL_II_NAMESPACE_OPEN
40 template <
typename Matrix>
49 namespace MatrixIterators
122 <<
"You tried to access row " << arg1
123 <<
" of a distributed matrix, but only rows " << arg2
124 <<
" through " << arg3
125 <<
" are stored locally and can be accessed.");
238 <<
"Attempt to access element " << arg2 <<
" of row " 239 << arg1 <<
" which doesn't have that many elements.");
376 set(
const std::vector<size_type> & indices,
378 const bool elide_zero_values =
false);
386 set(
const std::vector<size_type> & row_indices,
387 const std::vector<size_type> & col_indices,
389 const bool elide_zero_values =
false);
407 const std::vector<size_type> & col_indices,
408 const std::vector<PetscScalar> &values,
409 const bool elide_zero_values =
false);
429 const PetscScalar *values,
430 const bool elide_zero_values =
false);
464 add(
const std::vector<size_type> & indices,
466 const bool elide_zero_values =
true);
474 add(
const std::vector<size_type> & row_indices,
475 const std::vector<size_type> & col_indices,
477 const bool elide_zero_values =
true);
495 const std::vector<size_type> & col_indices,
496 const std::vector<PetscScalar> &values,
497 const bool elide_zero_values =
true);
517 const PetscScalar *values,
518 const bool elide_zero_values =
true,
519 const bool col_indices_are_sorted =
false);
549 clear_rows(
const std::vector<size_type> &rows,
550 const PetscScalar new_diag_value = 0);
633 std::pair<size_type, size_type>
647 virtual const MPI_Comm &
882 operator Mat()
const;
920 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
930 print(std::ostream &out,
const bool alternative_output =
false)
const;
942 "You are attempting an operation on two matrices that " 943 "are the same object, but the operation requires that the " 944 "two objects are in fact different.");
952 <<
"You tried to do a " 953 << (arg1 == 1 ?
"'set'" : (arg1 == 2 ?
"'add'" :
"???"))
954 <<
" operation but the matrix is currently in " 955 << (arg2 == 1 ?
"'set'" : (arg2 == 2 ?
"'add'" :
"???"))
956 <<
" mode. You first have to call 'compress()'.");
1075 friend class ::BlockMatrixBase;
1084 namespace MatrixIterators
1087 const size_type row,
1088 const size_type index)
1089 : matrix(const_cast<MatrixBase *>(matrix))
1093 visit_present_row();
1110 return (*colnum_cache)[a_index];
1126 return (*value_cache)[a_index];
1138 inline const_iterator &
1139 const_iterator::operator++()
1147 if (accessor.a_index >= accessor.colnum_cache->size())
1149 accessor.a_index = 0;
1152 while ((accessor.a_row < accessor.matrix->m()) &&
1153 (accessor.a_row < accessor.matrix->local_range().second) &&
1154 (accessor.matrix->row_length(accessor.a_row) == 0))
1157 accessor.visit_present_row();
1163 inline const_iterator
1164 const_iterator::operator++(
int)
1166 const const_iterator old_state = *
this;
1178 inline const const_iterator::Accessor *const_iterator::operator->()
const 1185 const_iterator::operator==(
const const_iterator &other)
const 1187 return (accessor.a_row == other.accessor.a_row &&
1188 accessor.a_index == other.accessor.a_index);
1193 const_iterator::operator!=(
const const_iterator &other)
const 1195 return !(*
this == other);
1200 const_iterator::operator<(
const const_iterator &other)
const 1202 return (accessor.row() < other.accessor.row() ||
1203 (accessor.row() == other.accessor.row() &&
1204 accessor.index() < other.accessor.index()));
1219 MatrixBase::set(
const size_type i,
const size_type j,
const PetscScalar value)
1223 set(i, 1, &j, &value,
false);
1231 const bool elide_zero_values)
1233 Assert(indices.size() == values.
m(),
1237 for (size_type i = 0; i < indices.size(); ++i)
1249 const std::vector<size_type> & col_indices,
1251 const bool elide_zero_values)
1253 Assert(row_indices.size() == values.
m(),
1255 Assert(col_indices.size() == values.
n(),
1258 for (size_type i = 0; i < row_indices.size(); ++i)
1270 const std::vector<size_type> & col_indices,
1271 const std::vector<PetscScalar> &values,
1272 const bool elide_zero_values)
1274 Assert(col_indices.size() == values.size(),
1288 const size_type n_cols,
1289 const size_type * col_indices,
1290 const PetscScalar *values,
1291 const bool elide_zero_values)
1295 const PetscInt petsc_i = row;
1296 PetscInt
const *col_index_ptr;
1298 PetscScalar
const *col_value_ptr;
1302 if (elide_zero_values ==
false)
1304 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1305 col_value_ptr = values;
1312 if (column_indices.size() < n_cols)
1314 column_indices.resize(n_cols);
1315 column_values.resize(n_cols);
1319 for (size_type j = 0; j < n_cols; ++j)
1321 const PetscScalar value = values[j];
1323 if (value != PetscScalar())
1325 column_indices[n_columns] = col_indices[j];
1326 column_values[n_columns] = value;
1332 col_index_ptr = column_indices.data();
1333 col_value_ptr = column_values.data();
1336 const PetscErrorCode ierr = MatSetValues(matrix,
1349 MatrixBase::add(
const size_type i,
const size_type j,
const PetscScalar value)
1353 if (value == PetscScalar())
1364 add(i, 1, &j, &value,
false);
1370 MatrixBase::add(
const std::vector<size_type> & indices,
1372 const bool elide_zero_values)
1374 Assert(indices.size() == values.
m(),
1378 for (size_type i = 0; i < indices.size(); ++i)
1389 MatrixBase::add(
const std::vector<size_type> & row_indices,
1390 const std::vector<size_type> & col_indices,
1392 const bool elide_zero_values)
1394 Assert(row_indices.size() == values.
m(),
1396 Assert(col_indices.size() == values.
n(),
1399 for (size_type i = 0; i < row_indices.size(); ++i)
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)
1415 Assert(col_indices.size() == values.size(),
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,
1435 (void)elide_zero_values;
1439 const PetscInt petsc_i = row;
1440 PetscInt
const *col_index_ptr;
1442 PetscScalar
const *col_value_ptr;
1446 if (elide_zero_values ==
false)
1448 col_index_ptr =
reinterpret_cast<const PetscInt *
>(col_indices);
1449 col_value_ptr = values;
1456 if (column_indices.size() < n_cols)
1458 column_indices.resize(n_cols);
1459 column_values.resize(n_cols);
1463 for (size_type j = 0; j < n_cols; ++j)
1465 const PetscScalar value = values[j];
1467 if (value != PetscScalar())
1469 column_indices[n_columns] = col_indices[j];
1470 column_values[n_columns] = value;
1476 col_index_ptr = column_indices.data();
1477 col_value_ptr = column_values.data();
1480 const PetscErrorCode ierr = MatSetValues(
1481 matrix, 1, &petsc_i, n_columns, col_index_ptr, col_value_ptr, ADD_VALUES);
1488 MatrixBase::operator()(
const size_type i,
const size_type j)
const 1495 inline MatrixBase::const_iterator
1496 MatrixBase::begin()
const 1498 return const_iterator(
this, 0, 0);
1502 inline MatrixBase::const_iterator
1503 MatrixBase::end()
const 1505 return const_iterator(
this, m(), 0);
1509 inline MatrixBase::const_iterator
1510 MatrixBase::begin(
const size_type r)
const 1512 Assert(in_local_range(r),
1513 ExcIndexRange(r, local_range().first, local_range().second));
1515 if (row_length(r) > 0)
1516 return const_iterator(
this, r, 0);
1522 inline MatrixBase::const_iterator
1523 MatrixBase::end(
const size_type r)
const 1525 Assert(in_local_range(r),
1526 ExcIndexRange(r, local_range().first, local_range().second));
1538 for (size_type i = r + 1; i < m(); ++i)
1539 if (i == local_range().second || (row_length(i) > 0))
1540 return const_iterator(
this, i, 0);
1550 MatrixBase::in_local_range(
const size_type index)
const 1552 PetscInt begin, end;
1554 const PetscErrorCode ierr =
1555 MatGetOwnershipRange(static_cast<const Mat &>(matrix), &begin, &end);
1558 return ((index >= static_cast<size_type>(begin)) &&
1559 (index < static_cast<size_type>(end)));
1568 last_action = new_action;
1570 Assert(last_action == new_action, ExcWrongMode(last_action, new_action));
1576 MatrixBase::assert_is_compressed()
1581 ExcMessage(
"Error: missing compress() call."));
1587 MatrixBase::prepare_add()
1595 MatrixBase::prepare_set()
1604 DEAL_II_NAMESPACE_CLOSE
1607 # endif // DEAL_II_WITH_PETSC
#define DeclException2(Exception2, type1, type2, outsequence)
bool operator==(const const_iterator &) const
void Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
Contents is actually a matrix.
PetscScalar matrix_scalar_product(const VectorBase &u, const VectorBase &v) const
static ::ExceptionBase & ExcBeyondEndOfMatrix()
void add(const size_type i, const size_type j, const PetscScalar value)
void vmult(VectorBase &dst, const VectorBase &src) const
const_iterator begin() const
PetscReal frobenius_norm() const
static ::ExceptionBase & ExcInvalidIndexWithinRow(int arg1, int arg2)
std::shared_ptr< const std::vector< PetscScalar > > value_cache
const Accessor & operator*() const
#define AssertIndexRange(index, range)
const Accessor * operator->() const
size_type row_length(const size_type row) const
#define AssertThrow(cond, exc)
types::global_dof_index size_type
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
PetscBool is_symmetric(const double tolerance=1.e-12)
PetscBool is_hermitian(const double tolerance=1.e-12)
void clear_rows(const std::vector< size_type > &rows, const PetscScalar new_diag_value=0)
PetscReal linfty_norm() const
std::vector< PetscInt > column_indices
const_iterator(const MatrixBase *matrix, const size_type row, const size_type index)
void compress(const VectorOperation::values operation)
std::vector< PetscScalar > column_values
size_type n_nonzero_elements() const
MatrixBase & operator=(const MatrixBase &)=delete
static ::ExceptionBase & ExcMessage(std::string arg1)
size_type local_size() const
Accessor(const MatrixBase *matrix, const size_type row, const size_type index)
bool operator<(const const_iterator &) const
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
#define DeclExceptionMsg(Exception, defaulttext)
#define DeclException0(Exception0)
void vmult_add(VectorBase &dst, const VectorBase &src) const
PetscScalar residual(VectorBase &dst, const VectorBase &x, const VectorBase &b) const
void mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
PetscScalar diag_element(const size_type i) const
void Tvmult(VectorBase &dst, const VectorBase &src) const
PetscScalar el(const size_type i, const size_type j) const
void Tvmult_add(VectorBase &dst, const VectorBase &src) const
const_iterator end() const
PetscScalar operator()(const size_type i, const size_type j) const
std::shared_ptr< const std::vector< size_type > > colnum_cache
static ::ExceptionBase & ExcIteratorPastEnd()
void print(std::ostream &out, const bool alternative_output=false) const
static ::ExceptionBase & ExcNotQuadratic()
virtual ~MatrixBase() override
void write_ascii(const PetscViewerFormat format=PETSC_VIEWER_DEFAULT)
VectorOperation::values last_action
void prepare_action(const VectorOperation::values new_action)
unsigned int global_dof_index
__global__ void set(Number *val, const Number s, const size_type N)
const_iterator & operator++()
types::global_dof_index size_type
bool in_local_range(const size_type index) const
MatrixBase & operator*=(const PetscScalar factor)
PetscScalar value() const
std::pair< size_type, size_type > local_range() const
static ::ExceptionBase & ExcAccessToNonlocalRow(int arg1, int arg2, int arg3)
PetscScalar trace() const
PetscScalar matrix_norm_square(const VectorBase &v) const
MatrixBase & operator/=(const PetscScalar factor)
PetscReal l1_norm() const
static ::ExceptionBase & ExcSourceEqualsDestination()
static ::ExceptionBase & ExcWrongMode(int arg1, int arg2)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
bool operator!=(const const_iterator &) const
static ::ExceptionBase & ExcBeyondEndOfMatrix()
virtual const MPI_Comm & get_mpi_communicator() const =0
types::global_dof_index size_type
#define AssertIsFinite(number)
void clear_row(const size_type row, const PetscScalar new_diag_value=0)
std::size_t memory_consumption() const
void assert_is_compressed()