15#ifdef DEAL_II_WITH_PETSC
23# include <boost/container/small_vector.hpp>
31#ifdef DEAL_II_WITH_PETSC
38 VectorReference::operator PetscScalar()
const
52 VecGetOwnershipRange(vector.vector, &
begin, &
end);
55 Vec locally_stored_elements =
nullptr;
56 ierr = VecGhostGetLocalForm(vector.vector, &locally_stored_elements);
60 ierr = VecGetSize(locally_stored_elements, &lsize);
63 const PetscScalar *ptr;
64 ierr = VecGetArrayRead(locally_stored_elements, &ptr);
69 if (index >=
static_cast<size_type
>(
begin) &&
70 index <
static_cast<size_type
>(
end))
73 value = *(ptr + index -
begin);
78 Assert(vector.ghost_indices.is_element(index),
80 "You are trying to access an element of a vector "
81 "that is neither a locally owned element nor a "
82 "ghost element of the vector."));
83 const size_type ghostidx =
84 vector.ghost_indices.index_within_set(index);
87 value = *(ptr + ghostidx +
end -
begin);
90 ierr = VecRestoreArrayRead(locally_stored_elements, &ptr);
94 VecGhostRestoreLocalForm(vector.vector, &locally_stored_elements);
106 PetscErrorCode ierr = VecGetOwnershipRange(vector.vector, &
begin, &
end);
110 (index <
static_cast<size_type
>(
end)),
111 ExcAccessToNonlocalElement(index,
begin,
end - 1));
113 const PetscScalar *ptr;
115 ierr = VecGetArrayRead(vector.vector, &ptr);
117 value = *(ptr + index -
begin);
118 ierr = VecRestoreArrayRead(vector.vector, &ptr);
130 , ghost_vector(nullptr)
131 , ghost_vector_array(nullptr)
138 , ghost_indices(v.ghost_indices)
140 , ghost_vector(nullptr)
141 , ghost_vector_array(nullptr)
158 , ghost_vector(nullptr)
159 , ghost_vector_array(nullptr)
161 const PetscErrorCode ierr =
162 PetscObjectReference(
reinterpret_cast<PetscObject
>(
vector));
176 const PetscErrorCode ierr = VecDestroy(&
vector);
191 PetscErrorCode ierr =
192 PetscObjectReference(
reinterpret_cast<PetscObject
>(v));
194 ierr = VecDestroy(&
vector);
206 template <
typename Iterator,
typename OutType>
207 class ConvertingIterator
213 typename std::iterator_traits<Iterator>::difference_type;
217 using iterator_category = std::forward_iterator_tag;
219 ConvertingIterator(
const Iterator &iterator)
226 return static_cast<OutType
>(std::real(*m_iterator));
239 ConvertingIterator old = *
this;
245 operator==(
const ConvertingIterator &other)
const
247 return this->m_iterator == other.m_iterator;
251 operator!=(
const ConvertingIterator &other)
const
253 return this->m_iterator != other.m_iterator;
273 ierr = VecGhostGetLocalForm(
vector, &ghosted_vec);
275 if (ghosted_vec && ghosted_vec !=
vector)
279 PetscInt ghost_start_index, end_index, n_elements_stored_locally;
281 ierr = VecGhostRestoreLocalForm(
vector, &ghosted_vec);
284 ierr = VecGetOwnershipRange(
vector, &ghost_start_index, &end_index);
286 ierr = VecDuplicate(
vector, &tvector);
288 ierr = VecGetArray(tvector, &array);
296 for (PetscInt i = 0; i < end_index - ghost_start_index; i++)
298 Assert(
static_cast<PetscInt
>(std::real(
static_cast<PetscScalar
>(
299 ghost_start_index + i))) == (ghost_start_index + i),
301 array[i] = ghost_start_index + i;
304 ierr = VecRestoreArray(tvector, &array);
306 ierr = VecGhostUpdateBegin(tvector, INSERT_VALUES, SCATTER_FORWARD);
308 ierr = VecGhostUpdateEnd(tvector, INSERT_VALUES, SCATTER_FORWARD);
310 ierr = VecGhostGetLocalForm(tvector, &ghosted_vec);
312 ierr = VecGetLocalSize(ghosted_vec, &n_elements_stored_locally);
314 ierr = VecGetArrayRead(ghosted_vec, (
const PetscScalar **)&array);
326 ConvertingIterator<PetscScalar *, types::global_dof_index> begin_ghosts(
327 &array[end_index - ghost_start_index]);
328 ConvertingIterator<PetscScalar *, types::global_dof_index> end_ghosts(
329 &array[n_elements_stored_locally]);
330 if (std::is_sorted(&array[end_index - ghost_start_index],
331 &array[n_elements_stored_locally],
332 [](PetscScalar left, PetscScalar right) {
333 return static_cast<PetscInt
>(std::real(left)) <
334 static_cast<PetscInt
>(std::real(right));
341 std::vector<PetscInt> sorted_indices(begin_ghosts, end_ghosts);
342 std::sort(sorted_indices.begin(), sorted_indices.end());
344 sorted_indices.end());
348 ierr = VecRestoreArrayRead(ghosted_vec, (
const PetscScalar **)&array);
350 ierr = VecGhostRestoreLocalForm(tvector, &ghosted_vec);
352 ierr = VecDestroy(&tvector);
357 ierr = VecGhostRestoreLocalForm(
vector, &ghosted_vec);
371 "Ghost vector is already acquired for the vector."));
387 PetscErrorCode ierr =
405 const PetscErrorCode ierr = VecDestroy(&
vector);
420 PetscErrorCode ierr = VecCopy(v,
vector);
431 if (s != PetscScalar(0))
439 PetscErrorCode ierr = VecSet(
vector, s);
449 ierr = VecGhostGetLocalForm(
vector, &ghost);
452 ierr = VecSet(ghost, s);
455 ierr = VecGhostRestoreLocalForm(
vector, &ghost);
470 const PetscErrorCode ierr = VecEqual(
vector, v.
vector, &flag);
473 return (flag == PETSC_TRUE);
484 const PetscErrorCode ierr = VecEqual(
vector, v.
vector, &flag);
487 return (flag == PETSC_FALSE);
496 const PetscErrorCode ierr = VecGetSize(
vector, &sz);
508 const PetscErrorCode ierr = VecGetLocalSize(
vector, &sz);
516 std::pair<VectorBase::size_type, VectorBase::size_type>
520 const PetscErrorCode ierr =
521 VecGetOwnershipRange(
static_cast<const Vec &
>(
vector), &
begin, &
end);
531 const std::vector<PetscScalar> &values)
533 Assert(indices.size() == values.size(),
534 ExcMessage(
"Function called with arguments of different sizes"));
542 const std::vector<PetscScalar> &values)
544 Assert(indices.size() == values.size(),
545 ExcMessage(
"Function called with arguments of different sizes"));
553 const ::Vector<PetscScalar> &values)
555 Assert(indices.size() == values.size(),
556 ExcMessage(
"Function called with arguments of different sizes"));
565 const PetscScalar *values)
586 const PetscErrorCode ierr = VecDot(vec.
vector,
vector, &result);
609 ExcMessage(
"Calling compress() is only useful if a vector "
610 "has been written into, but this is a vector with ghost "
611 "elements and consequently is read-only. It does "
612 "not make sense to call compress() for such "
622 int all_int_last_action;
624 const int ierr = MPI_Allreduce(&my_int_last_action,
625 &all_int_last_action,
635 "Error: not all processors agree on the last "
636 "VectorOperation before this compress() call."));
643 "Missing compress() or calling with wrong VectorOperation argument."));
659 PetscErrorCode ierr = VecAssemblyBegin(
vector);
661 ierr = VecAssemblyEnd(
vector);
689 const PetscErrorCode ierr = VecSum(
vector, &sum);
691 return sum /
static_cast<PetscReal
>(
size());
696 const PetscScalar *start_ptr;
697 PetscErrorCode ierr = VecGetArrayRead(
vector, &start_ptr);
700 PetscScalar mean = 0;
702 PetscScalar sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
707 const PetscScalar *ptr = start_ptr;
722 static_cast<PetscReal
>(
size());
727 ierr = VecRestoreArrayRead(
vector, &start_ptr);
739 const PetscErrorCode ierr = VecNorm(
vector, NORM_1, &d);
752 const PetscErrorCode ierr = VecNorm(
vector, NORM_2, &d);
765 const PetscScalar *start_ptr;
766 PetscErrorCode ierr = VecGetArrayRead(
vector, &start_ptr);
771 real_type sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
776 const PetscScalar *ptr = start_ptr;
796 ierr = VecRestoreArrayRead(
vector, &start_ptr);
809 const PetscErrorCode ierr = VecNorm(
vector, NORM_INFINITY, &d);
820 const PetscScalar *start_ptr;
821 PetscErrorCode ierr = VecGetArrayRead(
vector, &start_ptr);
824 const bool local_all_zero =
825 std::all_of(start_ptr,
827 numbers::value_is_zero<PetscScalar>);
829 ierr = VecRestoreArrayRead(
vector, &start_ptr);
843 const PetscErrorCode ierr = VecScale(
vector, a);
857 const PetscScalar factor = 1. / a;
860 const PetscErrorCode ierr = VecScale(
vector, factor);
872 const PetscErrorCode ierr = VecAXPY(
vector, 1, v);
884 const PetscErrorCode ierr = VecAXPY(
vector, -1, v);
898 const PetscErrorCode ierr = VecShift(
vector, s);
910 const PetscErrorCode ierr = VecAXPY(
vector, a, v);
926 const PetscScalar weights[2] = {a, b};
927 Vec addends[2] = {v.
vector, w.vector};
929 const PetscErrorCode ierr = VecMAXPY(
vector, 2, weights, addends);
941 const PetscErrorCode ierr = VecAYPX(
vector, s, v);
969 const PetscErrorCode ierr = VecPointwiseMult(
vector, factors,
vector);
983 const PetscErrorCode ierr = VecAXPBY(
vector, a, 0.0, v.
vector);
996 PetscErrorCode ierr =
997 PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(
comm), format);
1001 ierr = VecView(
vector, PETSC_VIEWER_STDOUT_(
comm));
1003 ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(
comm));
1011 const unsigned int precision,
1012 const bool scientific,
1013 const bool across)
const
1019 const PetscScalar *val;
1020 PetscErrorCode ierr = VecGetArrayRead(
vector, &val);
1025 const std::ios::fmtflags old_flags = out.flags();
1026 const unsigned int old_precision = out.precision(precision);
1028 out.precision(precision);
1030 out.setf(std::ios::scientific, std::ios::floatfield);
1032 out.setf(std::ios::fixed, std::ios::floatfield);
1036 out << val[i] <<
' ';
1039 out << val[i] << std::endl;
1043 out.flags(old_flags);
1044 out.precision(old_precision);
1048 ierr = VecRestoreArrayRead(
vector, &val);
1059 std::swap(this->vector, v.vector);
1060 std::swap(this->ghosted, v.ghosted);
1061 std::swap(this->last_action, v.last_action);
1064 this->ghost_indices = v.ghost_indices;
1065 v.ghost_indices = std::move(t);
1066 std::swap(this->ghost_vector, v.ghost_vector);
1067 std::swap(this->ghost_vector_array, v.ghost_vector_array);
1071 VectorBase::operator
const Vec &()
const
1087 std::size_t mem =
sizeof(Vec) +
sizeof(
last_action) +
1109 const PetscScalar *values,
1110 const bool add_values)
1115 internal::VectorReference::ExcWrongMode(action,
last_action));
1118 boost::container::small_vector<PetscInt, 200> petsc_indices(n_elements);
1119 for (
size_type i = 0; i < n_elements; ++i)
1121 const auto petsc_index =
static_cast<PetscInt
>(indices[i]);
1123 petsc_indices[i] = petsc_index;
1126 const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES);
1127 const PetscErrorCode ierr = VecSetValues(
1128 vector, petsc_indices.size(), petsc_indices.data(), values, mode);
* * reference operator*() const
std::ptrdiff_t difference_type
* * iterator & operator++()
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
size_type n_elements() const
void set_size(const size_type size)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
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
PetscScalar operator*(const VectorBase &vec) const
bool operator==(const VectorBase &v) const
VectorBase & operator*=(const PetscScalar factor)
VectorBase & operator-=(const VectorBase &V)
bool operator!=(const VectorBase &v) const
std::size_t memory_consumption() const
VectorBase & operator/=(const PetscScalar factor)
MPI_Comm get_mpi_communicator() const
void scale(const VectorBase &scaling_factors)
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
real_type linfty_norm() const
void swap(VectorBase &v) noexcept
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
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
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define AssertIntegerConversion(index1, index2)
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define AssertIsFinite(number)
#define AssertThrowMPI(error_code)
#define AssertNothrow(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
T sum(const T &t, const MPI_Comm mpi_communicator)
bool logical_and(const bool t, const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)