16 #ifndef dealii_petsc_vector_base_h 17 # define dealii_petsc_vector_base_h 20 # include <deal.II/base/config.h> 22 # ifdef DEAL_II_WITH_PETSC 24 # include <deal.II/base/index_set.h> 25 # include <deal.II/base/subscriptor.h> 27 # include <deal.II/lac/exceptions.h> 28 # include <deal.II/lac/vector.h> 29 # include <deal.II/lac/vector_operation.h> 31 # include <petscvec.h> 36 DEAL_II_NAMESPACE_OPEN
39 template <
typename number>
91 VectorReference(
const VectorBase &vector,
const size_type index);
106 const VectorReference &
107 operator=(
const VectorReference &r)
const;
115 operator=(
const VectorReference &r);
120 const VectorReference &
121 operator=(
const PetscScalar &s)
const;
126 const VectorReference &
127 operator+=(
const PetscScalar &s)
const;
132 const VectorReference &
133 operator-=(
const PetscScalar &s)
const;
138 const VectorReference &
139 operator*=(
const PetscScalar &s)
const;
144 const VectorReference &
145 operator/=(
const PetscScalar &s)
const;
166 operator PetscScalar()
const;
174 <<
"You tried to access element " << arg1
175 <<
" of a distributed vector, but only elements " << arg2
176 <<
" through " << arg3
177 <<
" are stored locally and can be accessed.");
184 <<
"You tried to do a " 185 << (arg1 == 1 ?
"'set'" : (arg1 == 2 ?
"'add'" :
"???"))
186 <<
" operation but the vector is currently in " 187 << (arg2 == 1 ?
"'set'" : (arg2 == 2 ?
"'add'" :
"???"))
188 <<
" mode. You first have to call 'compress()'.");
194 const VectorBase &vector;
205 friend class ::PETScWrappers::VectorBase;
248 using real_type = PetscReal;
250 using reference = internal::VectorReference;
251 using const_reference =
const internal::VectorReference;
311 operator=(
const PetscScalar s);
354 std::pair<size_type, size_type>
362 in_local_range(
const size_type index)
const;
378 locally_owned_elements()
const;
387 has_ghost_elements()
const;
396 update_ghost_values()
const;
402 operator()(
const size_type index);
408 operator()(
const size_type index)
const;
415 reference operator[](
const size_type index);
422 PetscScalar operator[](
const size_type index)
const;
431 set(
const std::vector<size_type> & indices,
432 const std::vector<PetscScalar> &values);
450 extract_subvector_to(
const std::vector<size_type> &indices,
451 std::vector<PetscScalar> & values)
const;
480 template <
typename ForwardIterator,
typename OutputIterator>
482 extract_subvector_to(
const ForwardIterator indices_begin,
483 const ForwardIterator indices_end,
484 OutputIterator values_begin)
const;
491 add(
const std::vector<size_type> & indices,
492 const std::vector<PetscScalar> &values);
499 add(
const std::vector<size_type> & indices,
500 const ::Vector<PetscScalar> &values);
508 add(
const size_type n_elements,
509 const size_type * indices,
510 const PetscScalar *values);
554 lp_norm(
const real_type p)
const;
611 is_non_negative()
const;
617 operator*=(
const PetscScalar factor);
623 operator/=(
const PetscScalar factor);
642 add(
const PetscScalar s);
648 add(
const PetscScalar a,
const VectorBase &V);
654 add(
const PetscScalar a,
663 sadd(
const PetscScalar s,
const VectorBase &V);
669 sadd(
const PetscScalar s,
const PetscScalar a,
const VectorBase &V);
683 equ(
const PetscScalar a,
const VectorBase &V);
707 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
717 print(std::ostream & out,
718 const unsigned int precision = 3,
719 const bool scientific =
true,
720 const bool across =
true)
const;
744 operator const Vec &()
const;
750 memory_consumption()
const;
756 virtual const MPI_Comm &
757 get_mpi_communicator()
const;
790 friend class internal::VectorReference;
805 do_set_add_operation(
const size_type n_elements,
806 const size_type * indices,
807 const PetscScalar *values,
808 const bool add_values);
841 inline VectorReference::VectorReference(
const VectorBase &vector,
842 const size_type index)
848 inline const VectorReference &
849 VectorReference::operator=(
const VectorReference &r)
const 855 *
this =
static_cast<PetscScalar
>(r);
862 inline VectorReference &
863 VectorReference::operator=(
const VectorReference &r)
869 *
this =
static_cast<PetscScalar
>(r);
876 inline const VectorReference &
877 VectorReference::operator=(
const PetscScalar &value)
const 885 const PetscInt petsc_i = index;
887 const PetscErrorCode ierr =
888 VecSetValues(vector, 1, &petsc_i, &value, INSERT_VALUES);
898 inline const VectorReference &
899 VectorReference::operator+=(
const PetscScalar &value)
const 916 if (value == PetscScalar())
920 const PetscInt petsc_i = index;
921 const PetscErrorCode ierr =
922 VecSetValues(vector, 1, &petsc_i, &value, ADD_VALUES);
931 inline const VectorReference &
932 VectorReference::operator-=(
const PetscScalar &value)
const 949 if (value == PetscScalar())
954 const PetscInt petsc_i = index;
955 const PetscScalar subtractand = -value;
956 const PetscErrorCode ierr =
957 VecSetValues(vector, 1, &petsc_i, &subtractand, ADD_VALUES);
965 inline const VectorReference &
966 VectorReference::operator*=(
const PetscScalar &value)
const 986 const PetscInt petsc_i = index;
987 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) * value;
989 const PetscErrorCode ierr =
990 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
998 inline const VectorReference &
999 VectorReference::operator/=(
const PetscScalar &value)
const 1019 const PetscInt petsc_i = index;
1020 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) / value;
1022 const PetscErrorCode ierr =
1023 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
1032 VectorReference::real()
const 1034 # ifndef PETSC_USE_COMPLEX 1035 return static_cast<PetscScalar
>(*this);
1037 return PetscRealPart(static_cast<PetscScalar>(*
this));
1044 VectorReference::imag()
const 1046 # ifndef PETSC_USE_COMPLEX 1047 return PetscReal(0);
1049 return PetscImaginaryPart(static_cast<PetscScalar>(*
this));
1058 PetscInt begin, end;
1059 const PetscErrorCode ierr =
1060 VecGetOwnershipRange(static_cast<const Vec &>(vector), &begin, &end);
1063 return ((index >= static_cast<size_type>(begin)) &&
1064 (index < static_cast<size_type>(end)));
1074 const std::pair<size_type, size_type> x = local_range();
1095 inline internal::VectorReference
1098 return internal::VectorReference(*
this, index);
1106 return static_cast<PetscScalar
>(internal::VectorReference(*
this, index));
1113 return operator()(index);
1120 return operator()(index);
1123 inline const MPI_Comm &
1126 static MPI_Comm comm;
1127 PetscObjectGetComm((PetscObject)vector, &comm);
1133 std::vector<PetscScalar> & values)
const 1135 extract_subvector_to(&(indices[0]),
1136 &(indices[0]) + indices.size(),
1140 template <
typename ForwardIterator,
typename OutputIterator>
1143 const ForwardIterator indices_end,
1144 OutputIterator values_begin)
const 1146 const PetscInt n_idx =
static_cast<PetscInt
>(indices_end - indices_begin);
1171 PetscInt begin, end;
1172 PetscErrorCode ierr = VecGetOwnershipRange(vector, &begin, &end);
1175 Vec locally_stored_elements =
nullptr;
1176 ierr = VecGhostGetLocalForm(vector, &locally_stored_elements);
1180 ierr = VecGetSize(locally_stored_elements, &lsize);
1184 ierr = VecGetArray(locally_stored_elements, &ptr);
1187 for (PetscInt i = 0; i < n_idx; ++i)
1189 const unsigned int index = *(indices_begin + i);
1190 if (index >= static_cast<unsigned int>(begin) &&
1191 index < static_cast<unsigned int>(end))
1194 *(values_begin + i) = *(ptr + index - begin);
1199 const unsigned int ghostidx =
1200 ghost_indices.index_within_set(index);
1202 Assert(ghostidx + end - begin < (
unsigned int)lsize,
1204 *(values_begin + i) = *(ptr + ghostidx + end - begin);
1208 ierr = VecRestoreArray(locally_stored_elements, &ptr);
1211 ierr = VecGhostRestoreLocalForm(vector, &locally_stored_elements);
1219 PetscInt begin, end;
1220 PetscErrorCode ierr = VecGetOwnershipRange(vector, &begin, &end);
1224 ierr = VecGetArray(vector, &ptr);
1227 for (PetscInt i = 0; i < n_idx; ++i)
1229 const unsigned int index = *(indices_begin + i);
1231 Assert(index >= static_cast<unsigned int>(begin) &&
1232 index < static_cast<unsigned int>(end),
1235 *(values_begin + i) = *(ptr + index - begin);
1238 ierr = VecRestoreArray(vector, &ptr);
1246 DEAL_II_NAMESPACE_CLOSE
1248 # endif // DEAL_II_WITH_PETSC reference operator[](const size_type index)
#define DeclException2(Exception2, type1, type2, outsequence)
void update_ghost_values() const
void swap(VectorBase &u, VectorBase &v)
bool has_ghost_elements() const
#define AssertThrow(cond, exc)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
unsigned long long int global_dof_index
virtual const MPI_Comm & get_mpi_communicator() const
VectorOperation::values last_action
#define Assert(cond, exc)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< PetscScalar > &values) const
types::global_dof_index size_type
static::ExceptionBase & ExcGhostsPresent()
void add_range(const size_type begin, const size_type end)
reference operator()(const size_type index)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
IndexSet locally_owned_elements() const
static::ExceptionBase & ExcInternalError()
bool in_local_range(const size_type index) const