13#ifndef dealii_la_parallel_vector_h
14#define dealii_la_parallel_vector_h
33#if defined(DEAL_II_WITH_MPI)
51 template <
typename,
typename>
56 class ReadWriteVector;
59# ifdef DEAL_II_WITH_PETSC
242 template <
typename Number,
typename MemorySpace = MemorySpace::Host>
258 std::is_same_v<MemorySpace, ::MemorySpace::Host> ||
259 std::is_same_v<MemorySpace, ::MemorySpace::Default>,
260 "MemorySpace should be Host or Default");
263 (!std::is_same_v<MemorySpace, ::MemorySpace::Default>) ||
264 std::is_same_v<Number, float> || std::is_same_v<Number, double>,
265 "Number should be float or double for Default memory space");
331 const std::shared_ptr<const Utilities::MPI::Partitioner> &
partitioner);
355 template <
typename Number2>
358 const bool omit_zeroing_entries =
false);
401 const std::shared_ptr<const Utilities::MPI::Partitioner> &
partitioner,
412 const std::shared_ptr<const Utilities::MPI::Partitioner> &
partitioner,
413 const bool make_ghosted,
507 template <
typename Number2>
638 const unsigned int communication_channel = 0)
const;
690 template <
typename Number2>
704 template <
typename MemorySpace2>
755 const std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
756 &communication_pattern = {});
790 add(
const std::vector<size_type> &indices,
791 const std::vector<Number> &values);
898 const unsigned int precision = 3,
899 const bool scientific =
true,
900 const bool across =
true)
const;
926 template <
typename OtherNumber>
928 add(
const std::vector<size_type> &indices,
929 const ::Vector<OtherNumber> &values);
935 template <
typename OtherNumber>
939 const OtherNumber *values);
1104 template <
typename OtherNumber>
1107 std::vector<OtherNumber> &values)
const;
1144 template <
typename ForwardIterator,
typename OutputIterator>
1147 const ForwardIterator indices_end,
1148 OutputIterator values_begin)
const;
1188 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1231 const std::vector<ArrayView<const Number>> &
1250 <<
"Called compress(VectorOperation::insert), but"
1251 <<
" the element received from a remote processor, value "
1252 << std::setprecision(16) << arg1
1253 <<
", does not match with the value "
1254 << std::setprecision(16) << arg2
1255 <<
" on the owner processor " << arg3);
1266 <<
"You tried to access element " << arg1
1267 <<
" of a distributed vector, but this element is not "
1268 <<
"stored on the current processor. Note: The range of "
1269 <<
"locally owned elements is [" << arg2 <<
',' << arg3
1270 <<
"], and there are " << arg4 <<
" ghost elements "
1271 <<
"that this vector can access."
1273 <<
"A common source for this kind of problem is that you "
1274 <<
"are passing a 'fully distributed' vector into a function "
1275 <<
"that needs read access to vector elements that correspond "
1276 <<
"to degrees of freedom on ghost cells (or at least to "
1277 <<
"'locally active' degrees of freedom that are not also "
1278 <<
"'locally owned'). You need to pass a vector that has these "
1279 <<
"elements as ghost entries.");
1301 template <
typename Number2>
1376 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
data;
1382 mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1389 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1401#ifdef DEAL_II_WITH_MPI
1448 template <
typename Number2,
typename MemorySpace2>
1452 template <
typename Number2,
typename MemorySpace2>
1462 template <
typename Number,
typename MemorySpace>
1466 return vector_is_ghosted;
1471 template <
typename Number,
typename MemorySpace>
1475 return partitioner->size();
1480 template <
typename Number,
typename MemorySpace>
1484 return partitioner->locally_owned_size();
1489 template <
typename Number,
typename MemorySpace>
1492 const size_type global_index)
const
1494 return partitioner->in_local_range(global_index);
1499 template <
typename Number,
typename MemorySpace>
1505 is.add_range(partitioner->local_range().first,
1506 partitioner->local_range().second);
1513 template <
typename Number,
typename MemorySpace>
1517 return data.values.data();
1522 template <
typename Number,
typename MemorySpace>
1526 return data.values.data();
1531 template <
typename Number,
typename MemorySpace>
1535 return data.values.data() + partitioner->locally_owned_size();
1540 template <
typename Number,
typename MemorySpace>
1544 return data.values.data() + partitioner->locally_owned_size();
1549 template <
typename Number,
typename MemorySpace>
1550 const std::vector<ArrayView<const Number>> &
1553 return data.values_sm;
1558 template <
typename Number,
typename MemorySpace>
1562 Assert((std::is_same_v<MemorySpace, ::MemorySpace::Host>),
1564 "This function is only implemented for the Host memory space"));
1566 partitioner->in_local_range(global_index) ||
1567 partitioner->ghost_indices().is_element(global_index),
1568 ExcAccessToNonLocalElement(global_index,
1569 partitioner->local_range().first,
1570 partitioner->local_range().second == 0 ?
1573 partitioner->ghost_indices().n_elements()));
1575 Assert(partitioner->in_local_range(global_index) ||
1576 vector_is_ghosted ==
true,
1577 ExcMessage(
"You tried to read a ghost element of this vector, "
1578 "but it has not imported its ghost values."));
1579 return data.values[partitioner->global_to_local(global_index)];
1584 template <
typename Number,
typename MemorySpace>
1588 Assert((std::is_same_v<MemorySpace, ::MemorySpace::Host>),
1590 "This function is only implemented for the Host memory space"));
1592 partitioner->in_local_range(global_index) ||
1593 partitioner->ghost_indices().is_element(global_index),
1594 ExcAccessToNonLocalElement(global_index,
1595 partitioner->local_range().first,
1596 partitioner->local_range().second == 0 ?
1599 partitioner->ghost_indices().n_elements()));
1606 return data.values[partitioner->global_to_local(global_index)];
1611 template <
typename Number,
typename MemorySpace>
1620 template <
typename Number,
typename MemorySpace>
1629 template <
typename Number,
typename MemorySpace>
1632 const size_type local_index)
const
1634 Assert((std::is_same_v<MemorySpace, ::MemorySpace::Host>),
1636 "This function is only implemented for the Host memory space"));
1638 partitioner->locally_owned_size() +
1639 partitioner->n_ghost_indices());
1642 ExcMessage(
"You tried to read a ghost element of this vector, "
1643 "but it has not imported its ghost values."));
1645 return data.values[local_index];
1650 template <
typename Number,
typename MemorySpace>
1654 Assert((std::is_same_v<MemorySpace, ::MemorySpace::Host>),
1656 "This function is only implemented for the Host memory space"));
1659 partitioner->locally_owned_size() +
1660 partitioner->n_ghost_indices());
1662 return data.values[local_index];
1667 template <
typename Number,
typename MemorySpace>
1671 return data.values.data();
1676 template <
typename Number,
typename MemorySpace>
1677 template <
typename OtherNumber>
1680 const std::vector<size_type> &indices,
1681 std::vector<OtherNumber> &values)
const
1683 for (size_type i = 0; i < indices.size(); ++i)
1684 values[i] =
operator()(indices[i]);
1689 template <
typename Number,
typename MemorySpace>
1690 template <
typename ForwardIterator,
typename OutputIterator>
1693 ForwardIterator indices_begin,
1694 const ForwardIterator indices_end,
1695 OutputIterator values_begin)
const
1697 while (indices_begin != indices_end)
1707 template <
typename Number,
typename MemorySpace>
1708 template <
typename OtherNumber>
1711 const std::vector<size_type> &indices,
1712 const ::Vector<OtherNumber> &values)
1715 for (size_type i = 0; i < indices.size(); ++i)
1720 "The given value is not finite but either infinite or Not A Number (NaN)"));
1727 template <
typename Number,
typename MemorySpace>
1728 template <
typename OtherNumber>
1731 const size_type *indices,
1732 const OtherNumber *values)
1734 for (size_type i = 0; i < n_elements; ++i, ++indices, ++
values)
1739 "The given value is not finite but either infinite or Not A Number (NaN)"));
1746 template <
typename Number,
typename MemorySpace>
1750 return partitioner->get_mpi_communicator();
1755 template <
typename Number,
typename MemorySpace>
1756 inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1764 template <
typename Number,
typename MemorySpace>
1768 vector_is_ghosted = ghosted;
1784template <
typename Number,
typename MemorySpace>
1796template <
typename Number,
typename MemorySpace>
1805 namespace LinearOperatorImplementation
1814 template <
typename Number>
1820 template <
typename T>
1822 decltype(std::declval<T>().get_mpi_communicator());
1824 template <
typename T>
1825 static constexpr bool has_get_mpi_communicator =
1826 is_supported_operation<get_mpi_communicator_t, T>;
1830 template <
typename T>
1832 decltype(std::declval<T>().locally_owned_domain_indices());
1834 template <
typename T>
1835 static constexpr bool has_locally_owned_domain_indices =
1836 is_supported_operation<locally_owned_domain_indices_t, T>;
1840 template <
typename T>
1842 decltype(std::declval<T>().locally_owned_range_indices());
1844 template <
typename T>
1845 static constexpr bool has_locally_owned_range_indices =
1846 is_supported_operation<locally_owned_range_indices_t, T>;
1850 template <
typename T>
1852 decltype(std::declval<T>().initialize_dof_vector(
1855 template <
typename T>
1856 static constexpr bool has_initialize_dof_vector =
1857 is_supported_operation<initialize_dof_vector_t, T>;
1860 template <
typename MatrixType,
1861#if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
1862 std::enable_if_t<has_get_mpi_communicator<MatrixType> &&
1863 has_locally_owned_domain_indices<MatrixType>,
1867 is_supported_operation<get_mpi_communicator_t, MatrixType> &&
1871 MatrixType> * =
nullptr>
1877 vec.
reinit(mat.locally_owned_domain_indices(),
1878 mat.get_mpi_communicator());
1882 template <
typename MatrixType,
1883#if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
1884 std::enable_if_t<has_initialize_dof_vector<MatrixType>,
1888 is_supported_operation<initialize_dof_vector_t, MatrixType>,
1890 MatrixType> * =
nullptr>
1894 bool omit_zeroing_entries)
1896 mat.initialize_dof_vector(vec);
1897 if (!omit_zeroing_entries)
1902 template <
typename MatrixType,
1903#if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
1904 std::enable_if_t<has_get_mpi_communicator<MatrixType> &&
1905 has_locally_owned_range_indices<MatrixType>,
1909 is_supported_operation<get_mpi_communicator_t, MatrixType> &&
1913 MatrixType> * =
nullptr>
1919 vec.
reinit(mat.locally_owned_range_indices(),
1920 mat.get_mpi_communicator());
1924 template <
typename MatrixType,
1925#if !defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1900
1926 std::enable_if_t<has_initialize_dof_vector<MatrixType>,
1930 is_supported_operation<initialize_dof_vector_t, MatrixType>,
1932 MatrixType> * =
nullptr>
1936 bool omit_zeroing_entries)
1938 mat.initialize_dof_vector(vec);
1939 if (!omit_zeroing_entries)
* * Point< dim > operator()(const Point< dim > &p) const *
Number & operator()(const size_type global_index)
void zero_out_ghost_values() const
void assert_no_residual_content_in_ghost_region() const
real_type linfty_norm() const
Number mean_value_local() const
virtual void extract_subvector_to(const ArrayView< const types::global_dof_index > &indices, const ArrayView< Number > &elements) const override
bool partitioners_are_compatible(const Utilities::MPI::Partitioner &part) const
void sadd(const Number s, const Number a, const Vector< Number, MemorySpace > &V)
bool has_ghost_elements() const
const value_type & const_reference
Number local_element(const size_type local_index) const
void reinit(const IndexSet &local_range, const MPI_Comm communicator)
bool all_zero_local() const
Number add_and_dot_local(const Number a, const Vector< Number, MemorySpace > &V, const Vector< Number, MemorySpace > &W)
Number mean_value() const
real_type linfty_norm_local() const
void compress_finish(VectorOperation::values operation)
Number * get_values() const
void update_ghost_values() const
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > import_data
real_type l1_norm_local() const
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > data
void equ(const Number a, const Vector< Number, MemorySpace > &V)
Vector< Number, MemorySpace > & operator=(Vector< Number, MemorySpace > &&in_vector)
void sadd_local(const Number s, const Number a, const Vector< Number, MemorySpace > &V)
typename numbers::NumberTraits< Number >::real_type real_type
const_iterator end() const
Vector(const IndexSet &local_range, const MPI_Comm communicator)
Vector(const size_type size)
Vector(Vector< Number, MemorySpace > &&in_vector)
size_type locally_owned_size() const
void reinit(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner, const MPI_Comm comm_sm=MPI_COMM_SELF)
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
void add(const size_type n_elements, const size_type *indices, const OtherNumber *values)
void sadd(const Number s, const Vector< Number, MemorySpace > &V)
Vector< Number, MemorySpace > & operator=(const Vector< Number, MemorySpace > &in_vector)
real_type norm_sqr_local() const
void reinit(const IndexSet &local_range, const IndexSet &ghost_indices, const MPI_Comm communicator)
void swap(Vector< Number, MemorySpace > &v) noexcept
const value_type * const_iterator
void clear_mpi_requests()
Number operator[](const size_type global_index) const
Vector(const Vector< Number, MemorySpace > &in_vector)
void add(const Number a, const Vector< Number, MemorySpace > &V)
void set_ghost_state(const bool ghosted) const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
::IndexSet locally_owned_elements() const
real_type l2_norm() const
void compress(VectorOperation::values operation)
Vector(const IndexSet &local_range, const IndexSet &ghost_indices, const MPI_Comm communicator)
Vector< Number, MemorySpace > & operator*=(const Number factor)
Vector< Number, MemorySpace > & operator+=(const Vector< Number, MemorySpace > &V)
void add(const std::vector< size_type > &indices, const ::Vector< OtherNumber > &values)
void import_elements(const Vector< Number, MemorySpace2 > &src, VectorOperation::values operation)
Number & operator[](const size_type global_index)
void add(const Number a, const Vector< Number, MemorySpace > &V, const Number b, const Vector< Number, MemorySpace > &W)
const value_type * const_pointer
void reinit(const Vector< Number2, MemorySpace > &in_vector, const bool omit_zeroing_entries=false)
real_type lp_norm(const real_type p) const
bool partitioners_are_globally_compatible(const Utilities::MPI::Partitioner &part) const
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
virtual size_type size() const override
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
Number add_and_dot(const Number a, const Vector< Number, MemorySpace > &V, const Vector< Number, MemorySpace > &W)
std::size_t memory_consumption() const
void update_ghost_values_finish() const
const std::vector< ArrayView< const Number > > & shared_vector_data() const
void update_ghost_values_start(const unsigned int communication_channel=0) const
void import_elements(const LinearAlgebra::ReadWriteVector< Number > &V, const VectorOperation::values operation, const std::shared_ptr< const Utilities::MPI::CommunicationPatternBase > &communication_pattern={})
void copy_locally_owned_data_from(const Vector< Number2, MemorySpace > &src)
Vector< Number, MemorySpace > & operator=(const Vector< Number2, MemorySpace > &in_vector)
Vector< Number, MemorySpace > & operator=(const Number s)
Number operator()(const size_type global_index) const
real_type lp_norm_local(const real_type p) const
Vector< Number, MemorySpace > & operator-=(const Vector< Number, MemorySpace > &V)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
void reinit(const size_type size, const bool omit_zeroing_entries=false)
MPI_Comm get_mpi_communicator() const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
void compress_start(const unsigned int communication_channel=0, VectorOperation::values operation=VectorOperation::add)
std::vector< MPI_Request > update_ghost_values_requests
void scale(const Vector< Number, MemorySpace > &scaling_factors)
const_iterator begin() const
std::vector< MPI_Request > compress_requests
void add_local(const Number a, const Vector< Number, MemorySpace > &V)
Number operator*(const Vector< Number, MemorySpace > &V) const
bool in_local_range(const size_type global_index) const
Vector< Number, MemorySpace > & operator/=(const Number factor)
void extract_subvector_to(ForwardIterator indices_begin, const ForwardIterator indices_end, OutputIterator values_begin) const
Number inner_product_local(const Vector< Number2, MemorySpace > &V) const
Number & local_element(const size_type local_index)
void reinit(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner, const bool make_ghosted, const MPI_Comm &comm_sm=MPI_COMM_SELF)
real_type norm_sqr() const
real_type l1_norm() const
void resize_val(const size_type new_allocated_size, const MPI_Comm comm_sm=MPI_COMM_SELF)
void reinit(const types::global_dof_index local_size, const types::global_dof_index ghost_size, const MPI_Comm comm, const MPI_Comm comm_sm=MPI_COMM_SELF)
Vector(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner)
const value_type * const_iterator
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v) noexcept
decltype(std::declval< T >().initialize_dof_vector(std::declval< LinearAlgebra::distributed::Vector< Number > & >())) initialize_dof_vector_t
decltype(std::declval< T >().get_mpi_communicator()) get_mpi_communicator_t
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
decltype(std::declval< T >().locally_owned_domain_indices()) locally_owned_domain_indices_t
decltype(std::declval< T >().locally_owned_range_indices()) locally_owned_range_indices_t
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
#define DeclException0(Exception0)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcVectorTypeNotCompatible()
static ::ExceptionBase & ExcNonMatchingElements(Number arg1, Number arg2, unsigned int arg3)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< index_type > data
std::pair< types::global_dof_index, types::global_dof_index > local_range
types::global_dof_index locally_owned_size
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
constexpr bool is_supported_operation
bool is_finite(const double x)
unsigned int global_dof_index