13#ifndef dealii_petsc_vector_base_h
14#define dealii_petsc_vector_base_h
19#ifdef DEAL_II_WITH_PETSC
27# include <boost/serialization/split_member.hpp>
28# include <boost/serialization/utility.hpp>
39#ifdef DEAL_II_WITH_PETSC
42template <
typename number>
95 VectorReference(
const VectorBase &vector,
const size_type index);
101 VectorReference(
const VectorReference &vector) =
default;
114 const VectorReference &
115 operator=(
const VectorReference &r)
const;
123 operator=(
const VectorReference &r);
128 const VectorReference &
129 operator=(
const PetscScalar &s)
const;
134 const VectorReference &
135 operator+=(
const PetscScalar &s)
const;
140 const VectorReference &
141 operator-=(
const PetscScalar &s)
const;
146 const VectorReference &
147 operator*=(
const PetscScalar &s)
const;
152 const VectorReference &
153 operator/=(
const PetscScalar &s)
const;
174 operator PetscScalar()
const;
179 ExcAccessToNonlocalElement,
183 <<
"You tried to access element " << arg1
184 <<
" of a distributed vector, but only elements in range [" << arg2
185 <<
',' << arg3 <<
"] are stored locally and can be accessed."
187 <<
"A common source for this kind of problem is that you "
188 <<
"are passing a 'fully distributed' vector into a function "
189 <<
"that needs read access to vector elements that correspond "
190 <<
"to degrees of freedom on ghost cells (or at least to "
191 <<
"'locally active' degrees of freedom that are not also "
192 <<
"'locally owned'). You need to pass a vector that has these "
193 <<
"elements as ghost entries.");
200 <<
"You tried to do a "
201 << (arg1 == 1 ?
"'set'" : (arg1 == 2 ?
"'add'" :
"???"))
202 <<
" operation but the vector is currently in "
203 << (arg2 == 1 ?
"'set'" : (arg2 == 2 ?
"'add'" :
"???"))
204 <<
" mode. You first have to call 'compress()'.");
210 const VectorBase &vector;
219 friend class ::PETScWrappers::VectorBase;
367 size()
const override;
388 std::pair<size_type, size_type>
470 set(
const std::vector<size_type> &indices,
471 const std::vector<PetscScalar> &values);
490 std::vector<PetscScalar> &values)
const;
527 template <
typename ForwardIterator,
typename OutputIterator>
530 const ForwardIterator indices_end,
531 OutputIterator values_begin)
const;
538 add(
const std::vector<size_type> &indices,
539 const std::vector<PetscScalar> &values);
546 add(
const std::vector<size_type> &indices,
547 const ::Vector<PetscScalar> &values);
557 const PetscScalar *values);
670 add(
const PetscScalar s);
682 add(
const PetscScalar a,
697 sadd(
const PetscScalar s,
const PetscScalar a,
const VectorBase &V);
721 write_ascii(
const PetscViewerFormat format = PETSC_VIEWER_DEFAULT);
731 print(std::ostream &out,
732 const unsigned int precision = 3,
733 const bool scientific =
true,
734 const bool across =
true)
const;
743 template <
class Archive>
745 save(Archive &ar,
const unsigned int version)
const;
752 template <
class Archive>
754 load(Archive &ar,
const unsigned int version);
762 template <
class Archive>
764 serialize(Archive &archive,
const unsigned int version);
768 BOOST_SERIALIZATION_SPLIT_MEMBER()
793 operator const Vec &()
const;
854 const PetscScalar *values,
855 const bool add_values);
908 inline VectorReference::VectorReference(
const VectorBase &vector,
909 const size_type index)
915 inline const VectorReference &
916 VectorReference::operator=(
const VectorReference &r)
const
922 *
this =
static_cast<PetscScalar
>(r);
929 inline VectorReference &
930 VectorReference::operator=(
const VectorReference &r)
936 *
this =
static_cast<PetscScalar
>(r);
943 inline const VectorReference &
944 VectorReference::operator=(
const PetscScalar &value)
const
952 const PetscInt petsc_i =
index;
954 const PetscErrorCode ierr =
955 VecSetValues(vector, 1, &petsc_i, &value, INSERT_VALUES);
965 inline const VectorReference &
966 VectorReference::operator+=(
const PetscScalar &value)
const
983 if (value == PetscScalar())
987 const PetscInt petsc_i =
index;
988 const PetscErrorCode ierr =
989 VecSetValues(vector, 1, &petsc_i, &value, ADD_VALUES);
998 inline const VectorReference &
999 VectorReference::operator-=(
const PetscScalar &value)
const
1016 if (value == PetscScalar())
1021 const PetscInt petsc_i =
index;
1022 const PetscScalar subtractand = -
value;
1023 const PetscErrorCode ierr =
1024 VecSetValues(vector, 1, &petsc_i, &subtractand, ADD_VALUES);
1032 inline const VectorReference &
1033 VectorReference::operator*=(
const PetscScalar &value)
const
1053 const PetscInt petsc_i =
index;
1054 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) *
value;
1056 const PetscErrorCode ierr =
1057 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
1065 inline const VectorReference &
1066 VectorReference::operator/=(
const PetscScalar &value)
const
1086 const PetscInt petsc_i =
index;
1087 const PetscScalar new_value =
static_cast<PetscScalar
>(*this) /
value;
1089 const PetscErrorCode ierr =
1090 VecSetValues(vector, 1, &petsc_i, &new_value, INSERT_VALUES);
1099 VectorReference::real()
const
1101# ifndef PETSC_USE_COMPLEX
1102 return static_cast<PetscScalar
>(*this);
1104 return PetscRealPart(
static_cast<PetscScalar
>(*
this));
1111 VectorReference::imag()
const
1113# ifndef PETSC_USE_COMPLEX
1114 return PetscReal(0);
1116 return PetscImaginaryPart(
static_cast<PetscScalar
>(*
this));
1123 VectorBase::in_local_range(
const size_type index)
const
1126 const PetscErrorCode ierr =
1127 VecGetOwnershipRange(
static_cast<const Vec &
>(vector), &
begin, &
end);
1136 VectorBase::locally_owned_elements()
const
1141 const std::pair<size_type, size_type> x =
local_range();
1142 is.add_range(x.first, x.second);
1149 VectorBase::has_ghost_elements()
const
1156 VectorBase::ghost_elements()
const
1158 return ghost_indices;
1163 VectorBase::update_ghost_values()
const
1167 PetscErrorCode ierr;
1169 ierr = VecGhostUpdateBegin(vector, INSERT_VALUES, SCATTER_FORWARD);
1171 ierr = VecGhostUpdateEnd(vector, INSERT_VALUES, SCATTER_FORWARD);
1178 inline internal::VectorReference
1179 VectorBase::operator()(
const size_type index)
1181 return internal::VectorReference(*
this, index);
1187 VectorBase::operator()(
const size_type index)
const
1189 return static_cast<PetscScalar
>(internal::VectorReference(*
this, index));
1194 inline internal::VectorReference
1195 VectorBase::operator[](
const size_type index)
1203 VectorBase::operator[](
const size_type index)
const
1209 VectorBase::get_mpi_communicator()
const
1211 return PetscObjectComm(
reinterpret_cast<PetscObject
>(vector));
1215 VectorBase::extract_subvector_to(
const std::vector<size_type> &indices,
1216 std::vector<PetscScalar> &values)
const
1220 extract_subvector_to(indices.begin(), indices.end(),
values.begin());
1224 VectorBase::extract_subvector_to(
1229 extract_subvector_to(indices.
begin(), indices.
end(), elements.
begin());
1233 template <
typename ForwardIterator,
typename OutputIterator>
1235 VectorBase::extract_subvector_to(
const ForwardIterator indices_begin,
1236 const ForwardIterator indices_end,
1237 OutputIterator values_begin)
const
1239 if (indices_begin == indices_end)
1264 Assert(ghost_vector !=
nullptr && ghost_vector_array !=
nullptr,
1266 "Ghost elements are not acquired for the vector."));
1269 PetscErrorCode ierr = VecGetOwnershipRange(vector, &
begin, &
end);
1273 ierr = VecGetSize(ghost_vector, &lsize);
1276 auto input = indices_begin;
1277 auto output = values_begin;
1278 while (input != indices_end)
1280 const auto index =
static_cast<PetscInt
>(*input);
1285 *output = *(ghost_vector_array +
index -
begin);
1290 const auto ghost_index = ghost_indices.index_within_set(*input);
1293 *output = *(ghost_vector_array + ghost_index +
end -
begin);
1306 PetscErrorCode ierr = VecGetOwnershipRange(vector, &
begin, &
end);
1309 const PetscScalar *ptr;
1310 ierr = VecGetArrayRead(vector, &ptr);
1313 auto input = indices_begin;
1314 auto output = values_begin;
1315 while (input != indices_end)
1317 const auto index =
static_cast<PetscInt
>(*input);
1321 ExcMessage(
"You are accessing elements of a vector without "
1322 "ghost elements that are not actually owned by "
1323 "this vector. A typical case where this may "
1324 "happen is if you are passing a non-ghosted "
1325 "(completely distributed) vector to a function "
1326 "that expects a vector that stores ghost "
1327 "elements for all locally relevant or locally "
1328 "active vector entries."));
1336 ierr = VecRestoreArrayRead(vector, &ptr);
1341 template <
class Archive>
1343 VectorBase::save(Archive &ar,
const unsigned int)
const
1350 const PetscScalar *array =
nullptr;
1351 int ierr = VecGetArrayRead(*
this, &array);
1354 boost::serialization::array_wrapper<const PetscScalar> wrapper(
1358 ierr = VecRestoreArrayRead(*
this, &array);
1364 template <
class Archive>
1366 VectorBase::load(Archive &ar,
const unsigned int)
1375 ExcMessage(
"The serialized value of size (" + std::to_string(
size) +
1376 ") does not match the current size (" +
1377 std::to_string(this->
size()) +
")"));
1380 ExcMessage(
"The serialized value of local_range (" +
1383 ") does not match the current local_range (" +
1384 std::to_string(this->local_range().first) +
", " +
1385 std::to_string(this->local_range().second) +
")"));
1387 PetscScalar *array =
nullptr;
1388 int ierr = VecGetArray(petsc_vector(), &array);
1391 boost::serialization::array_wrapper<PetscScalar> wrapper(
1395 ierr = VecRestoreArray(petsc_vector(), &array);
* * reference operator*() const
* * Point< dim > operator()(const Point< dim > &p) const *
real_type lp_norm(const real_type p) const
real_type l1_norm() const
VectorBase & operator+=(const VectorBase &V)
PetscScalar mean_value() const
void determine_ghost_indices()
VectorOperation::values last_action
bool operator==(const VectorBase &v) const
VectorBase & operator*=(const PetscScalar factor)
VectorBase & operator-=(const VectorBase &V)
void save(Archive &ar, const unsigned int version) const
bool operator!=(const VectorBase &v) const
IndexSet locally_owned_elements() const
bool in_local_range(const size_type index) const
void load(Archive &ar, const unsigned int version)
std::size_t memory_consumption() const
internal::VectorReference reference
VectorBase & operator/=(const PetscScalar factor)
friend class internal::VectorReference
PetscScalar operator[](const size_type index) const
MPI_Comm get_mpi_communicator() const
void scale(const VectorBase &scaling_factors)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< PetscScalar > &values) const
void update_ghost_values() const
std::pair< size_type, size_type > local_range() const
void sadd(const PetscScalar s, const VectorBase &V)
real_type norm_sqr() const
void compress(const VectorOperation::values operation)
void set(const std::vector< size_type > &indices, const std::vector< PetscScalar > &values)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
PetscScalar add_and_dot(const PetscScalar a, const VectorBase &V, const VectorBase &W)
virtual ~VectorBase() override
const PetscScalar * ghost_vector_array
const IndexSet & ghost_elements() const
real_type linfty_norm() const
void swap(VectorBase &v) noexcept
reference operator()(const size_type index)
void swap(VectorBase &u, VectorBase &v) noexcept
virtual void extract_subvector_to(const ArrayView< const types::global_dof_index > &indices, const ArrayView< PetscScalar > &elements) const override
const internal::VectorReference const_reference
void serialize(Archive &archive, const unsigned int version)
void add(const std::vector< size_type > &indices, const std::vector< PetscScalar > &values)
void write_ascii(const PetscViewerFormat format=PETSC_VIEWER_DEFAULT)
bool has_ghost_elements() const
reference operator[](const size_type index)
void acquire_ghost_form()
size_type locally_owned_size() const
void equ(const PetscScalar a, const VectorBase &V)
void do_set_add_operation(const size_type n_elements, const size_type *indices, const PetscScalar *values, const bool add_values)
VectorBase & operator=(const VectorBase &)
real_type l2_norm() const
void release_ghost_form()
size_type size() const override
PetscScalar operator()(const size_type index) const
void extract_subvector_to(const ForwardIterator indices_begin, const ForwardIterator indices_end, OutputIterator values_begin) const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define AssertIntegerConversion(index1, index2)
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define DeclException2(Exception2, type1, type2, outsequence)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
#define DeclException3(Exception3, type1, type2, type3, outsequence)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::pair< types::global_dof_index, types::global_dof_index > local_range
types::global_dof_index locally_owned_size
types::global_dof_index size_type
unsigned int global_dof_index