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;
199 const size_type index;
205 friend class ::PETScWrappers::VectorBase;
248 using real_type = PetscReal;
250 using reference = internal::VectorReference;
251 using const_reference =
const internal::VectorReference;
318 operator=(
const PetscScalar s);
361 std::pair<size_type, size_type>
369 in_local_range(
const size_type index)
const;
385 locally_owned_elements()
const;
394 has_ghost_elements()
const;
403 update_ghost_values()
const;
409 operator()(
const size_type index);
415 operator()(
const size_type index)
const;
422 reference operator[](
const size_type index);
429 PetscScalar operator[](
const size_type index)
const;
438 set(
const std::vector<size_type> & indices,
439 const std::vector<PetscScalar> &values);
457 extract_subvector_to(
const std::vector<size_type> &indices,
458 std::vector<PetscScalar> & values)
const;
487 template <
typename ForwardIterator,
typename OutputIterator>
489 extract_subvector_to(
const ForwardIterator indices_begin,
490 const ForwardIterator indices_end,
491 OutputIterator values_begin)
const;
498 add(
const std::vector<size_type> & indices,
499 const std::vector<PetscScalar> &values);
506 add(
const std::vector<size_type> & indices,
507 const ::Vector<PetscScalar> &values);
515 add(
const size_type n_elements,
516 const size_type * indices,
517 const PetscScalar *values);
561 lp_norm(
const real_type p)
const;
618 is_non_negative()
const;
624 operator*=(
const PetscScalar factor);
630 operator/=(
const PetscScalar factor);
649 add(
const PetscScalar s);
655 add(
const PetscScalar a,
const VectorBase &V);
661 add(
const PetscScalar a,
676 sadd(
const PetscScalar s,
const PetscScalar a,
const VectorBase &V);
714 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
724 print(std::ostream & out,
725 const unsigned int precision = 3,
726 const bool scientific =
true,
727 const bool across =
true)
const;
751 operator const Vec &()
const;
757 memory_consumption()
const;
763 virtual const MPI_Comm &
764 get_mpi_communicator()
const;
797 friend class internal::VectorReference;
812 do_set_add_operation(
const size_type n_elements,
813 const size_type * indices,
814 const PetscScalar *values,
815 const bool add_values);
839 inline VectorReference::VectorReference(
const VectorBase &vector,
840 const size_type index)
846 inline const VectorReference &
847 VectorReference::operator=(
const VectorReference &r)
const 853 *
this =
static_cast<PetscScalar
>(r);
860 inline VectorReference &
861 VectorReference::operator=(
const VectorReference &r)
867 *
this =
static_cast<PetscScalar
>(r);
874 inline const VectorReference &
875 VectorReference::operator=(
const PetscScalar &value)
const 883 const PetscInt petsc_i = index;
885 const PetscErrorCode ierr =
886 VecSetValues(vector, 1, &petsc_i, &value, INSERT_VALUES);
896 inline const VectorReference &
897 VectorReference::operator+=(
const PetscScalar &value)
const 914 if (value == PetscScalar())
918 const PetscInt petsc_i = index;
919 const PetscErrorCode ierr =
920 VecSetValues(vector, 1, &petsc_i, &value, ADD_VALUES);
929 inline const VectorReference &
930 VectorReference::operator-=(
const PetscScalar &value)
const 947 if (value == PetscScalar())
952 const PetscInt petsc_i = index;
953 const PetscScalar subtractand = -value;
954 const PetscErrorCode ierr =
955 VecSetValues(vector, 1, &petsc_i, &subtractand, ADD_VALUES);
963 inline const VectorReference &
964 VectorReference::operator*=(
const PetscScalar &value)
const 984 const PetscInt petsc_i = index;
985 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) * value;
987 const PetscErrorCode ierr =
988 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
996 inline const VectorReference &
997 VectorReference::operator/=(
const PetscScalar &value)
const 1017 const PetscInt petsc_i = index;
1018 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) / value;
1020 const PetscErrorCode ierr =
1021 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
1030 VectorReference::real()
const 1032 # ifndef PETSC_USE_COMPLEX 1033 return static_cast<PetscScalar
>(*this);
1035 return PetscRealPart(static_cast<PetscScalar>(*
this));
1042 VectorReference::imag()
const 1044 # ifndef PETSC_USE_COMPLEX 1045 return PetscReal(0);
1047 return PetscImaginaryPart(static_cast<PetscScalar>(*
this));
1056 PetscInt begin, end;
1057 const PetscErrorCode ierr =
1058 VecGetOwnershipRange(static_cast<const Vec &>(vector), &begin, &end);
1061 return ((index >= static_cast<size_type>(begin)) &&
1062 (index < static_cast<size_type>(end)));
1072 const std::pair<size_type, size_type> x = local_range();
1093 inline internal::VectorReference
1096 return internal::VectorReference(*
this, index);
1104 return static_cast<PetscScalar
>(internal::VectorReference(*
this, index));
1111 return operator()(index);
1118 return operator()(index);
1121 inline const MPI_Comm &
1124 static MPI_Comm comm;
1125 PetscObjectGetComm(reinterpret_cast<PetscObject>(vector), &comm);
1131 std::vector<PetscScalar> & values)
const 1133 Assert(indices.size() <= values.size(),
1135 extract_subvector_to(indices.begin(), indices.end(), values.begin());
1138 template <
typename ForwardIterator,
typename OutputIterator>
1141 const ForwardIterator indices_end,
1142 OutputIterator values_begin)
const 1144 const PetscInt n_idx =
static_cast<PetscInt
>(indices_end - indices_begin);
1169 PetscInt begin, end;
1170 PetscErrorCode ierr = VecGetOwnershipRange(vector, &begin, &end);
1173 Vec locally_stored_elements =
nullptr;
1174 ierr = VecGhostGetLocalForm(vector, &locally_stored_elements);
1178 ierr = VecGetSize(locally_stored_elements, &lsize);
1182 ierr = VecGetArray(locally_stored_elements, &ptr);
1185 for (PetscInt i = 0; i < n_idx; ++i)
1187 const unsigned int index = *(indices_begin + i);
1188 if (index >= static_cast<unsigned int>(begin) &&
1189 index < static_cast<unsigned int>(end))
1192 *(values_begin + i) = *(ptr + index - begin);
1197 const unsigned int ghostidx =
1198 ghost_indices.index_within_set(index);
1201 *(values_begin + i) = *(ptr + ghostidx + end - begin);
1205 ierr = VecRestoreArray(locally_stored_elements, &ptr);
1208 ierr = VecGhostRestoreLocalForm(vector, &locally_stored_elements);
1216 PetscInt begin, end;
1217 PetscErrorCode ierr = VecGetOwnershipRange(vector, &begin, &end);
1221 ierr = VecGetArray(vector, &ptr);
1224 for (PetscInt i = 0; i < n_idx; ++i)
1226 const unsigned int index = *(indices_begin + i);
1228 Assert(index >= static_cast<unsigned int>(begin) &&
1229 index < static_cast<unsigned int>(end),
1232 *(values_begin + i) = *(ptr + index - begin);
1235 ierr = VecRestoreArray(vector, &ptr);
1243 DEAL_II_NAMESPACE_CLOSE
1245 # endif // DEAL_II_WITH_PETSC reference operator[](const size_type index)
#define DeclException2(Exception2, type1, type2, outsequence)
void update_ghost_values() const
#define AssertIndexRange(index, range)
void swap(VectorBase &u, VectorBase &v)
__global__ void add_and_dot(Number *res, Number *v1, const Number *v2, const Number *v3, const Number a, const size_type N)
#define AssertThrow(cond, exc)
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
bool in_local_range(const size_type index) const
LinearAlgebra::distributed::Vector< Number > Vector
__global__ void scale(Number *val, const Number *V_val, const size_type N)
VectorOperation::values last_action
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
__global__ void equ(Number *val, const Number a, const Number *V_val, const size_type N)
__global__ void sadd(const Number s, Number *val, const Number a, const Number *V_val, const size_type N)
static ::ExceptionBase & ExcGhostsPresent()
void add_range(const size_type begin, const size_type end)
unsigned int global_dof_index
bool has_ghost_elements() const
reference operator()(const size_type index)
IndexSet locally_owned_elements() const
#define DeclException3(Exception3, type1, type2, type3, outsequence)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< PetscScalar > &values) const
virtual const MPI_Comm & get_mpi_communicator() const
static ::ExceptionBase & ExcInternalError()