deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
psblas_vector.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2019 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_psblas_vector_h
14#define dealii_psblas_vector_h
15
16#include <deal.II/base/config.h>
17
19#include <deal.II/base/types.h>
20
24
25#include <cstddef>
26#include <memory>
27
28#ifdef DEAL_II_WITH_PSBLAS
29
31
32#endif // DEAL_II_WITH_PSBLAS
33
35
36#ifdef DEAL_II_WITH_PSBLAS
37namespace PSCToolkitWrappers
38{
39
69 class Vector : public ReadVector<double>
70 {
71 private:
75 class VectorReference
76 {
77 private:
79
80 using value_type = double;
81
85 VectorReference(Vector &vector, const size_type index)
86 : vector(vector)
87 , index(index)
88 {}
89
90 public:
94 const VectorReference &
95 operator=(const value_type &s) const
96 {
97 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
98 Assert(
99 vector.owned_elements.is_element(index),
101 "You are trying to write to an element of the vector that is not "
102 "locally owned. This is not allowed for the current interface to"
103 " PSBLAS vectors."));
104
105 // Make sure the operation is consistent with the last one
106 Assert(vector.last_action == VectorOperation::insert ||
107 vector.last_action == VectorOperation::unknown,
108 ExcWrongMode(VectorOperation::insert, vector.last_action));
109
110 std::vector<size_type> idx{index};
111 std::vector<value_type> value{s};
112 vector.set(idx, value);
113 vector.last_action = VectorOperation::insert;
114 return *this;
115 }
116
120 const VectorReference &
121 operator+=(const value_type &s) const
122 {
123 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
124 Assert(vector.last_action == VectorOperation::add ||
125 vector.last_action == VectorOperation::unknown,
126 ExcWrongMode(VectorOperation::add, vector.last_action));
127
128 vector.last_action = VectorOperation::add;
129
130 // First check for early return
131 if (s == 0.)
132 return *this;
133
134 std::vector<size_type> idx{index};
135 std::vector<value_type> value{s};
136 vector.add(idx, value);
137 return *this;
138 }
139
143 const VectorReference &
144 operator-=(const value_type &s) const
145 {
146 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
147 Assert(vector.last_action == VectorOperation::add ||
148 vector.last_action == VectorOperation::unknown,
149 ExcWrongMode(VectorOperation::add, vector.last_action));
150
151 vector.last_action = VectorOperation::add;
152
153 // First check for early return
154 if (s == 0.)
155 return *this;
156
157 std::vector<size_type> idx{index};
158 std::vector<value_type> value{-s};
159 vector.add(idx, value);
160 return *this;
161 }
162
166 const VectorReference &
167 operator*=(const value_type &s) const
168 {
169 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
170 Assert((vector.last_action == VectorOperation::insert) ||
171 (vector.last_action == VectorOperation::unknown),
172 ExcWrongMode(VectorOperation::insert, vector.last_action));
173
174 vector.last_action = VectorOperation::insert;
175 if (s == 1.)
176 return *this;
177
178 std::vector<size_type> idx{index};
179 value_type new_value = static_cast<value_type>(*this) * s;
180 std::vector<value_type> value{new_value};
181 vector.set(idx, value);
182
183 return *this;
184 }
185
189 const VectorReference &
190 operator/=(const value_type &s) const
191 {
192 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
193
194 Assert((vector.last_action == VectorOperation::insert) ||
195 (vector.last_action == VectorOperation::unknown),
196 ExcWrongMode(VectorOperation::insert, vector.last_action));
197 std::vector<size_type> idx{index};
198 value_type new_value = static_cast<value_type>(*this) / s;
199 std::vector<value_type> value{new_value};
200 vector.set(idx, value);
201 vector.last_action = VectorOperation::insert;
202 return *this;
203 }
204
205 /*
206 * Convert the reference to an actual value, i.e. return the value of
207 * the referenced element of the vector.
208 */
209 operator value_type() const
210 {
211 AssertIndexRange(index, vector.size());
212 if (vector.ghosted)
213 {
214 AssertThrow(vector.ghost_indices.is_element(index) ||
215 vector.owned_elements.is_element(index),
217 "You are trying to access an element of a vector "
218 "that is neither a locally owned element nor a "
219 "ghost element of the vector."));
220 }
221 else
222 {
224 vector.owned_elements.is_element(index),
225 ExcAccessToNonlocalElement(index,
226 *vector.owned_elements.begin(),
227 (*vector.owned_elements.begin() +
228 vector.locally_owned_size())));
229 }
230 return psb_c_dgetelem(vector.psblas_vector,
231 index,
232 vector.psblas_descriptor.get());
233 };
234
235 private:
236 Vector &vector;
237
238 const size_type index;
239
240 friend class Vector;
241 };
242
243 public:
245
246 using value_type = double;
247
251 Vector();
252
257 Vector(const Vector &);
258
263 explicit Vector(const IndexSet &local_partitioning,
264 const MPI_Comm communicator);
265
275 Vector(const IndexSet &local_partitioning,
276 const IndexSet &ghost_indices,
277 const MPI_Comm communicator);
278
282 ~Vector();
283
292 void
293 reinit(const IndexSet &local_partitioning,
294 const MPI_Comm communicator,
295 const bool omit_zeroing_entries = false);
296
306 void
307 reinit(const Vector &v, const bool omit_zeroing_entries = false);
308
320 void
321 reinit(const IndexSet &local_partitioning,
322 const IndexSet &ghost_indices,
323 const MPI_Comm communicator);
324
325
352 Vector &
353 operator=(const Vector &v);
354
360 size() const override;
361
365 virtual void
366 extract_subvector_to(
368 const ArrayView<value_type> &elements) const override;
369
385 void
386 extract_subvector_to(const std::vector<size_type> &indices,
387 std::vector<value_type> &values) const;
388
416 template <typename ForwardIterator, typename OutputIterator>
417 void
418 extract_subvector_to(ForwardIterator indices_begin,
419 ForwardIterator indices_end,
420 OutputIterator values_begin) const;
421
422
432 locally_owned_size() const;
433
440 void
441 set(const std::vector<size_type> &indices,
442 const std::vector<value_type> &values);
443
448 void
449 add(const std::vector<size_type> &indices,
450 const std::vector<value_type> &values);
451
455 void
456 add(const value_type s, const Vector &V);
457
461 void
462 add(const value_type s);
463
469 void
470 scale(const Vector &v);
471
482 add_and_dot(const value_type a, const Vector &v, const Vector &W);
483
484 /*
485 * Scaling and vector addition, i.e. <tt>*this = s*(*this)+V</tt>.
486 */
487 void
488 sadd(const value_type s, const Vector &V);
489
490 /*
491 * Scaling and vector addition, i.e. <tt>*this = s*(*this)+a*V</tt>.
492 */
493 void
494 sadd(const value_type s, const value_type a, const Vector &V);
495
496 /*
497 * Assignment *this = a*V.
498 */
499 void
500 equ(const value_type a, const Vector &v);
501
506 operator()(const size_type index) const;
507
511 VectorReference
512 operator()(const size_type index);
513
518 operator[](const size_type index) const;
519
523 VectorReference
524 operator[](const size_type index);
525
530 operator*(const Vector &v) const;
531
535 Vector &
536 operator-=(const Vector &v);
537
541 Vector &
542 operator+=(const Vector &v);
543
556 Vector &
557 operator=(const value_type s);
558
572 const IndexSet &
573 locally_owned_elements() const;
574
578 const IndexSet &
579 ghost_elements() const;
580
587 bool
588 has_ghost_elements() const;
589
593 void
594 update_ghost_values() const;
595
604 void
605 swap(Vector &v);
606
614 void
615 compress(const VectorOperation::values operation);
616
621 value_type *
622 begin();
623
628 const value_type *
629 begin() const;
630
635 value_type *
636 end();
637
642 const value_type *
643 end() const;
644
646 get_mpi_communicator() const;
647
652 psb_c_descriptor *
653 get_psblas_descriptor() const;
654
659 psb_c_dvector *
660 get_psblas_vector() const;
661
666 void
667 clear();
668
674 linfty_norm() const;
675
680 l1_norm() const;
681
687 l2_norm() const;
688
693 mean_value() const;
694
700 bool
701 all_zero() const;
702
706 std::size_t
707 memory_consumption() const;
708
709 private:
710 /*
711 * Pointer to the underlying PSBLAS vector.
712 */
713 psb_c_dvector *psblas_vector;
714
715 /*
716 * Pointer to PSBLAS context.
717 */
718 psb_c_ctxt *psblas_context;
719
720 /*
721 * Shared pointer to the PSBLAS descriptor.
722 */
723 std::shared_ptr<psb_c_descriptor> psblas_descriptor;
724
728 MPI_Comm communicator;
729
733 IndexSet owned_elements;
734
738 IndexSet ghost_indices;
739
745 bool ghosted;
746
751 internal::State state;
752
757 VectorOperation::values last_action;
758
763 bool remote_entries_pending;
764
765 friend class SparseMatrix;
766
767 friend class PreconditionAMG;
768 };
769
770
771 /* ----------------------------- Inline functions ---------------- */
772
773
774 inline PSCToolkitWrappers::Vector::value_type *
775 PSCToolkitWrappers::Vector::begin()
776 {
777 return psb_c_dvect_f_get_pnt(psblas_vector);
778 }
779
780
781
782 inline const PSCToolkitWrappers::Vector::value_type *
783 PSCToolkitWrappers::Vector::begin() const
784 {
785 return psb_c_dvect_f_get_pnt(psblas_vector);
786 }
787
788
789
790 inline PSCToolkitWrappers::Vector::value_type *
791 PSCToolkitWrappers::Vector::end()
792 {
793 return psb_c_dvect_f_get_pnt(psblas_vector) + locally_owned_size();
794 }
795
796
797
798 inline const PSCToolkitWrappers::Vector::value_type *
799 PSCToolkitWrappers::Vector::end() const
800 {
801 return psb_c_dvect_f_get_pnt(psblas_vector) + locally_owned_size();
802 }
803
804
805
806 inline Vector::size_type
807 Vector::size() const
808 {
809 return owned_elements.size();
810 }
811
812
813
814 inline const IndexSet &
816 {
817 return owned_elements;
818 }
819
820
821
822 inline const IndexSet &
823 Vector::ghost_elements() const
824 {
825 return ghost_indices;
826 }
827
828
829
830 inline bool
832 {
833 return ghosted;
834 }
835
836
837
838 inline Vector::value_type
839 Vector::operator()(const Vector::size_type index) const
840 {
841 return psb_c_dgetelem(psblas_vector, index, psblas_descriptor.get());
842 }
843
844
845
846 inline Vector::VectorReference
847 Vector::operator()(const size_type index)
848 {
849 return VectorReference(*this, index);
850 }
851
852
853
854 inline Vector::value_type
855 Vector::operator[](const Vector::size_type index) const
856 {
857 return operator()(index);
858 }
859
860
861
862 inline Vector::VectorReference
863 Vector::operator[](const size_type index)
864 {
865 return operator()(index);
866 }
867
868
869
870 inline void
873 const ArrayView<double> &elements) const
874 {
875 AssertDimension(indices.size(), elements.size());
876 extract_subvector_to(indices.begin(), indices.end(), elements.begin());
877 }
878
879
880
881 inline void
882 Vector::extract_subvector_to(const std::vector<size_type> &indices,
883 std::vector<Vector::value_type> &values) const
884 {
885 AssertDimension(indices.size(), values.size());
886 extract_subvector_to(indices.begin(), indices.end(), values.begin());
887 }
888
889
890
891 template <typename ForwardIterator, typename OutputIterator>
892 inline void
893 Vector::extract_subvector_to(ForwardIterator indices_begin,
894 ForwardIterator indices_end,
895 OutputIterator output) const
896 {
897 if (indices_begin == indices_end)
898 return;
899
900 if (ghosted)
901 {
902 types::global_dof_index begin = *owned_elements.begin();
903 types::global_dof_index end = begin + owned_elements.n_elements();
904
905 auto input = indices_begin;
906 while (input != indices_end)
907 {
908 const auto index = static_cast<psb_l_t>(*input);
909 AssertThrow((index >= begin && index < end) ||
910 ghost_indices.is_element(index),
912 "You are trying to access an element of a vector "
913 "that is neither a locally owned element nor a "
914 "ghost element of the vector."));
915 *output =
916 psb_c_dgetelem(psblas_vector, index, psblas_descriptor.get());
917
918
919 ++input;
920 ++output;
921 }
922 }
923 else
924 {
925 // no ghost elements, so we can
926 // just access the local
927 // elements directly
928 while (indices_begin != indices_end)
929 {
930 const size_type index = *indices_begin;
931 Assert(owned_elements.is_element(index),
932 ExcMessage("You are accessing elements of a vector without "
933 "ghost elements that are not actually owned by "
934 "this vector. A typical case where this may "
935 "happen is if you are passing a non-ghosted "
936 "(completely distributed) vector to a function "
937 "that expects a vector that stores ghost "
938 "elements for all locally relevant or locally "
939 "active vector entries."));
940
941 *output =
942 psb_c_dgetelem(psblas_vector, index, psblas_descriptor.get());
943
944 ++indices_begin;
945 ++output;
946 }
947 }
948 }
949
950
951} // namespace PSCToolkitWrappers
952
956template <>
957struct is_serial_vector<PSCToolkitWrappers::Vector> : std::false_type
958{};
959
960#endif // DEAL_II_WITH_PSBLAS
961
963#endif
*  iterator end()
*  *  iterator begin()
*  x_component_mask set(0, true)
*  *  reference operator*() const
*  *  Point< dim > operator()(const Point< dim > &p) const * 
iterator begin() const
Definition array_view.h:755
iterator end() const
Definition array_view.h:764
std::size_t size() const
Definition array_view.h:737
bool has_ghost_elements() const
Number operator[](const size_type i) const
virtual size_type size() const override
IndexSet locally_owned_elements() const
Number operator()(const size_type i) const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number value_type
Definition vector.h:115
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::size_t size
Definition mpi.cc:733
types::global_dof_index locally_owned_size
Definition mpi.cc:821
std::vector< value_type > l2_norm(const typename ::Triangulation< dim, spacedim >::cell_iterator &parent, const value_type parent_value)
void scale(const double scaling_factor, Triangulation< dim, spacedim > &triangulation)
PETScWrappers::PreconditionBoomerAMG PreconditionAMG
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
std::string compress(const std::string &input)
Definition utilities.cc:381
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
unsigned int global_dof_index
Definition types.h:92
void swap(ObserverPointer< T, P > &t1, ObserverPointer< T, Q > &t2)
Number linfty_norm(const Tensor< 2, dim, Number > &t)
Definition tensor.h:3033
Number l1_norm(const Tensor< 2, dim, Number > &t)
Definition tensor.h:3007