16 #ifndef dealii__parallel_vector_h 17 #define dealii__parallel_vector_h 19 #include <deal.II/base/config.h> 20 #include <deal.II/base/index_set.h> 21 #include <deal.II/base/mpi.h> 22 #include <deal.II/base/template_constraints.h> 23 #include <deal.II/base/types.h> 24 #include <deal.II/base/utilities.h> 25 #include <deal.II/base/memory_consumption.h> 26 #include <deal.II/base/partitioner.h> 27 #include <deal.II/base/thread_management.h> 28 #include <deal.II/lac/vector_view.h> 34 DEAL_II_NAMESPACE_OPEN
36 #ifdef DEAL_II_WITH_PETSC 46 #ifdef DEAL_II_WITH_TRILINOS 170 template <
typename Number>
180 typedef value_type *pointer;
181 typedef const value_type *const_pointer;
182 typedef value_type *iterator;
183 typedef const value_type *const_iterator;
184 typedef value_type &reference;
185 typedef const value_type &const_reference;
199 static const bool supports_distributed_data =
true;
219 Vector (
const size_type size);
239 const MPI_Comm communicator);
245 const MPI_Comm communicator);
253 Vector (
const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
264 void reinit (
const size_type size,
265 const bool omit_zeroing_entries =
false);
277 template <
typename Number2>
279 const bool omit_zeroing_entries =
false);
297 void reinit (
const IndexSet &local_range,
299 const MPI_Comm communicator);
304 void reinit (
const IndexSet &local_range,
305 const MPI_Comm communicator);
313 void reinit (
const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
357 template <
typename Number2>
361 #ifdef DEAL_II_WITH_PETSC 373 #ifdef DEAL_II_WITH_TRILINOS 400 Vector<Number> &operator = (const Number s);
447 void update_ghost_values () const;
463 void compress_start (const
unsigned int communication_channel = 0,
497 void update_ghost_values_start (const
unsigned int communication_channel = 0) const;
507 void update_ghost_values_finish () const;
517 void zero_out_ghosts ();
530 bool has_ghost_elements() const;
537 bool all_zero () const;
549 bool is_non_negative () const;
554 template <typename Number2>
555 bool operator == (const
Vector<Number2> &v) const;
560 template <typename Number2>
561 bool operator != (const
Vector<Number2> &v) const;
566 template <typename Number2>
567 Number operator * (const
Vector<Number2> &V) const;
573 real_type norm_sqr () const;
578 Number mean_value () const;
584 real_type l1_norm () const;
590 real_type l2_norm () const;
597 real_type lp_norm (const real_type p) const;
603 real_type linfty_norm () const;
621 Number add_and_dot (const Number a,
629 size_type size () const;
635 size_type local_size() const;
642 std::pair<size_type, size_type> local_range () const;
648 bool in_local_range (const size_type global_index) const;
663 IndexSet locally_owned_elements () const;
679 const
IndexSet &ghost_elements() const DEAL_II_DEPRECATED;
688 bool is_ghost_entry (const
types::global_dof_index global_index) const DEAL_II_DEPRECATED;
703 const_iterator begin () const;
715 const_iterator end () const;
733 Number operator () (const size_type global_index) const;
744 Number &operator () (const size_type global_index);
753 Number operator [] (const size_type global_index) const;
762 Number &operator [] (const size_type global_index);
770 template <typename OtherNumber>
771 void extract_subvector_to (const
std::vector<size_type> &indices,
772 std::vector<OtherNumber> &values) const;
778 template <typename ForwardIterator, typename OutputIterator>
779 void extract_subvector_to (ForwardIterator indices_begin,
780 const ForwardIterator indices_end,
781 OutputIterator values_begin) const;
791 Number local_element (const size_type local_index) const;
801 Number &local_element (const size_type local_index);
824 template <typename OtherNumber>
825 void add (const
std::vector<size_type> &indices,
826 const
std::vector<OtherNumber> &values);
832 template <typename OtherNumber>
833 void add (const
std::vector<size_type> &indices,
834 const ::
Vector<OtherNumber> &values);
841 template <typename OtherNumber>
842 void add (const size_type n_elements,
843 const size_type *indices,
844 const OtherNumber *values);
850 void add (const Number s);
857 void add (const
Vector<Number> &V) DEAL_II_DEPRECATED;
863 void add (const Number a, const
Vector<Number> &V);
868 void add (const Number a, const
Vector<Number> &V,
869 const Number b, const
Vector<Number> &W);
875 void sadd (const Number s,
881 void sadd (const Number s,
890 void sadd (const Number s,
894 const
Vector<Number> &W) DEAL_II_DEPRECATED;
902 void sadd (const Number s,
908 const
Vector<Number> &X) DEAL_II_DEPRECATED;
913 Vector<Number> &operator *= (const Number factor);
918 Vector<Number> &operator /= (const Number factor);
925 void scale (const
Vector<Number> &scaling_factors);
932 template <typename Number2>
933 void scale (const
Vector<Number2> &scaling_factors);
938 void equ (const Number a, const
Vector<Number> &u);
943 template <typename Number2>
944 void equ (const Number a, const
Vector<Number2> &u);
951 void equ (const Number a, const
Vector<Number> &u,
952 const Number b, const
Vector<Number> &v) DEAL_II_DEPRECATED;
959 void equ (const Number a, const
Vector<Number> &u,
960 const Number b, const
Vector<Number> &v,
961 const Number c, const
Vector<Number> &w) DEAL_II_DEPRECATED;
973 void ratio (const
Vector<Number> &a,
974 const
Vector<Number> &b) DEAL_II_DEPRECATED;
986 const MPI_Comm &get_mpi_communicator () const;
995 get_partitioner () const;
1007 partitioners_are_compatible (const
Utilities::MPI::Partitioner &part) const;
1023 partitioners_are_globally_compatible (const
Utilities::MPI::Partitioner &part) const;
1028 void print (
std::ostream &out,
1029 const
unsigned int precision = 3,
1030 const
bool scientific = true,
1031 const
bool across = true) const;
1036 std::
size_t memory_consumption () const;
1043 double,
double,
unsigned int,
1045 << " the element received from a remote processor, value "
1046 <<
std::setprecision(16) << arg1
1047 << ", does not match with the value "
1048 <<
std::setprecision(16) << arg2
1049 << " on the owner processor " << arg3);
1055 size_type, size_type, size_type, size_type,
1056 << "You tried to access element " << arg1
1057 << " of a distributed vector, but this element is not "
1058 << "stored on the current processor. Note: The range of "
1059 << "locally owned elements is " << arg2 << " to "
1060 << arg3 << ", and there are " << arg4 << " ghost elements "
1061 << "that this vector can access.");
1067 bool all_zero_local () const;
1072 bool is_non_negative_local () const;
1077 template <typename Number2>
1078 bool vectors_equal_local (const
Vector<Number2> &v) const;
1083 template <typename Number2>
1084 Number inner_product_local (const
Vector<Number2> &V) const;
1089 real_type norm_sqr_local () const;
1094 Number mean_value_local () const;
1099 real_type l1_norm_local () const;
1104 real_type lp_norm_local (const real_type p) const;
1109 real_type linfty_norm_local () const;
1115 Number add_and_dot_local (const Number a,
1117 const
Vector<Number> &W);
1129 size_type allocated_size;
1141 mutable Number *import_data;
1150 mutable
bool vector_is_ghosted;
1158 #ifdef DEAL_II_WITH_MPI 1187 void clear_mpi_requests ();
1192 void resize_val (
const size_type new_allocated_size);
1197 template <
typename Number2>
friend class Vector;
1212 template <
typename Number>
1216 partitioner (new
Utilities::MPI::Partitioner()),
1220 vector_is_ghosted (false),
1221 vector_view (0, static_cast<Number *>(0))
1226 template <
typename Number>
1234 vector_is_ghosted (false),
1235 vector_view (0, static_cast<Number *>(0))
1244 template <
typename Number>
1248 const MPI_Comm communicator)
1253 vector_is_ghosted (false),
1254 vector_view (0, static_cast<Number *>(0))
1256 reinit (local_range, ghost_indices, communicator);
1261 template <
typename Number>
1264 const MPI_Comm communicator)
1269 vector_is_ghosted (false),
1270 vector_view (0, static_cast<Number *>(0))
1272 reinit (local_range, communicator);
1277 template <
typename Number>
1284 vector_is_ghosted (false),
1285 vector_view (0, static_cast<Number *>(0))
1292 template <
typename Number>
1295 Vector (
const std_cxx11::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
1300 vector_is_ghosted (false),
1301 vector_view (0, static_cast<Number *>(0))
1308 template <
typename Number>
1314 if (import_data != 0)
1315 delete[] import_data;
1318 clear_mpi_requests();
1323 template <
typename Number>
1329 return this->
operator=<Number>(c);
1331 return this->
template operator=<Number>(c);
1337 template <
typename Number>
1338 template <
typename Number2>
1358 if (partitioner.get() == 0)
1360 else if (partitioner.get() != c.
partitioner.get())
1365 int local_ranges_are_identical =
1367 (local_range().second == local_range().first &&
1373 !local_ranges_are_identical)
1376 must_update_ghost_values |= vector_is_ghosted;
1378 must_update_ghost_values |=
1379 (c.
partitioner->ghost_indices_initialized() ==
false &&
1380 partitioner->ghost_indices_initialized() ==
true);
1383 must_update_ghost_values |= vector_is_ghosted;
1390 if (must_update_ghost_values)
1399 template <
typename Number>
1404 compress_start (0, operation);
1405 compress_finish(operation);
1410 template <
typename Number>
1415 update_ghost_values_start ();
1416 update_ghost_values_finish ();
1421 template <
typename Number>
1426 std::fill_n (&
val[partitioner->local_size()],
1427 partitioner->n_ghost_indices(),
1429 vector_is_ghosted =
false;
1434 template <
typename Number>
1439 return vector_is_ghosted;
1444 template <
typename Number>
1449 return partitioner->
local_size()>0 ? vector_view.all_zero () :
true;
1454 template <
typename Number>
1464 int local_result = -
static_cast<int>(all_zero_local());
1465 if (partitioner->n_mpi_processes() > 1)
1467 partitioner->get_communicator());
1469 return -local_result;
1474 template <
typename Number>
1479 return partitioner->
local_size()>0 ? vector_view.is_non_negative () :
true;
1484 template <
typename Number>
1489 int local_result = -
static_cast<int>(is_non_negative_local());
1490 if (partitioner->n_mpi_processes() > 1)
1492 partitioner->get_communicator());
1494 return -local_result;
1499 template <
typename Number>
1500 template <
typename Number2>
1506 vector_view.template
operator == <Number2>(v.
vector_view)
1512 template <
typename Number>
1513 template <
typename Number2>
1520 unsigned int local_result =
static_cast<int>(!vectors_equal_local(v));
1521 unsigned int result =
1522 partitioner->n_mpi_processes() > 1
1532 template <
typename Number>
1533 template <
typename Number2>
1543 template <
typename Number>
1544 template <
typename Number2>
1551 return (partitioner->local_size()>0 ?
1558 template <
typename Number>
1559 template <
typename Number2>
1564 Number local_result = inner_product_local(V);
1565 if (partitioner->n_mpi_processes() > 1)
1567 partitioner->get_communicator());
1569 return local_result;
1574 template <
typename Number>
1576 typename Vector<Number>::real_type
1584 template <
typename Number>
1586 typename Vector<Number>::real_type
1589 real_type local_result = norm_sqr_local();
1590 if (partitioner->n_mpi_processes() > 1)
1592 partitioner->get_communicator());
1594 return local_result;
1599 template <
typename Number>
1604 Assert (partitioner->size()!=0, ExcEmptyObject());
1605 return (partitioner->local_size() ?
1606 vector_view.mean_value()
1612 template <
typename Number>
1617 Number local_result = mean_value_local();
1618 if (partitioner->n_mpi_processes() > 1)
1620 (real_type)partitioner->local_size(),
1621 partitioner->get_communicator())
1622 /(real_type)partitioner->size();
1624 return local_result;
1629 template <
typename Number>
1631 typename Vector<Number>::real_type
1639 template <
typename Number>
1641 typename Vector<Number>::real_type
1644 real_type local_result = l1_norm_local();
1645 if (partitioner->n_mpi_processes() > 1)
1647 partitioner->get_communicator());
1649 return local_result;
1654 template <
typename Number>
1656 typename Vector<Number>::real_type
1664 template <
typename Number>
1666 typename Vector<Number>::real_type
1674 template <
typename Number>
1676 typename Vector<Number>::real_type
1679 const real_type local_result = lp_norm_local(p);
1680 if (partitioner->n_mpi_processes() > 1)
1682 partitioner->get_communicator()),
1683 static_cast<real_type>(1.0/p));
1685 return local_result;
1690 template <
typename Number>
1692 typename Vector<Number>::real_type
1700 template <
typename Number>
1702 typename Vector<Number>::real_type
1705 const real_type local_result = linfty_norm_local();
1706 if (partitioner->n_mpi_processes() > 1)
1708 partitioner->get_communicator());
1710 return local_result;
1715 template <
typename Number>
1724 return (partitioner->local_size()>0 ?
1731 template <
typename Number>
1738 Number local_result = add_and_dot_local(a, V, W);
1739 if (partitioner->n_mpi_processes() > 1)
1741 partitioner->get_communicator());
1743 return local_result;
1748 template <
typename Number>
1750 typename Vector<Number>::size_type
1753 return partitioner->size();
1758 template <
typename Number>
1760 typename Vector<Number>::size_type
1768 template <
typename Number>
1770 std::pair<typename Vector<Number>::size_type,
1771 typename Vector<Number>::size_type>
1779 template <
typename Number>
1783 (
const size_type global_index)
const 1785 return partitioner->in_local_range (global_index);
1790 template <
typename Number>
1797 is.add_range (local_range().first, local_range().second);
1804 template <
typename Number>
1806 typename Vector<Number>::size_type
1809 return partitioner->n_ghost_indices();
1814 template <
typename Number>
1819 return partitioner->ghost_indices();
1824 template <
typename Number>
1834 template <
typename Number>
1836 typename Vector<Number>::iterator
1839 return vector_view.begin();
1844 template <
typename Number>
1846 typename Vector<Number>::const_iterator
1849 return vector_view.begin();
1854 template <
typename Number>
1856 typename Vector<Number>::iterator
1859 return vector_view.end();
1864 template <
typename Number>
1866 typename Vector<Number>::const_iterator
1869 return vector_view.end();
1874 template <
typename Number>
1880 partitioner->ghost_indices().is_element(global_index),
1881 ExcAccessToNonLocalElement(global_index, local_range().first,
1882 local_range().second,
1883 partitioner->ghost_indices().n_elements()));
1886 ExcMessage(
"You tried to read a ghost element of this vector, " 1887 "but it has not imported its ghost values."));
1888 return val[partitioner->global_to_local(global_index)];
1893 template <
typename Number>
1899 partitioner->ghost_indices().is_element(global_index),
1900 ExcAccessToNonLocalElement(global_index, local_range().first,
1901 local_range().second,
1902 partitioner->ghost_indices().n_elements()));
1909 return val[partitioner->global_to_local (global_index)];
1914 template <
typename Number>
1924 template <
typename Number>
1934 template <
typename Number>
1935 template <
typename OtherNumber>
1938 std::vector<OtherNumber> &values)
const 1940 for (size_type i = 0; i < indices.size(); ++i)
1941 values[i] =
operator()(indices[i]);
1946 template <
typename Number>
1947 template <
typename ForwardIterator,
typename OutputIterator>
1950 const ForwardIterator indices_end,
1951 OutputIterator values_begin)
const 1953 while (indices_begin != indices_end)
1963 template <
typename Number>
1969 partitioner->local_size()+
1970 partitioner->n_ghost_indices());
1972 Assert (local_index < local_size() || vector_is_ghosted ==
true,
1973 ExcMessage(
"You tried to read a ghost element of this vector, " 1974 "but it has not imported its ghost values."));
1975 return val[local_index];
1980 template <
typename Number>
1986 partitioner->local_size()+
1987 partitioner->n_ghost_indices());
1988 return val[local_index];
1993 template <
typename Number>
2000 if (partitioner->local_size() > 0)
2010 template <
typename Number>
2022 if (vector_is_ghosted)
2030 template <
typename Number>
2042 if (vector_is_ghosted)
2050 template <
typename Number>
2051 template <
typename OtherNumber>
2055 const std::vector<OtherNumber> &values)
2058 add (indices.size(), &indices[0], &values[0]);
2063 template <
typename Number>
2064 template <
typename OtherNumber>
2068 const ::Vector<OtherNumber> &values)
2071 add (indices.size(), &indices[0], values.begin());
2076 template <
typename Number>
2077 template <
typename OtherNumber>
2081 const size_type *indices,
2082 const OtherNumber *values)
2084 for (size_type i=0; i<n_indices; ++i)
2087 ExcMessage(
"The given value is not finite but either infinite or Not A Number (NaN)"));
2094 template <
typename Number>
2102 vector_view.add (a);
2104 if (vector_is_ghosted)
2110 template <
typename Number>
2120 if (vector_is_ghosted)
2126 template <
typename Number>
2137 if (vector_is_ghosted)
2143 template <
typename Number>
2156 if (vector_is_ghosted)
2162 template <
typename Number>
2173 if (vector_is_ghosted)
2179 template <
typename Number>
2191 if (vector_is_ghosted)
2197 template <
typename Number>
2211 if (vector_is_ghosted)
2217 template <
typename Number>
2234 if (vector_is_ghosted)
2240 template <
typename Number>
2248 vector_view *= factor;
2250 if (vector_is_ghosted)
2258 template <
typename Number>
2269 template <
typename Number>
2279 if (vector_is_ghosted)
2285 template <
typename Number>
2286 template <
typename Number2>
2292 vector_view.template scale<Number2> (scaling_factors.
vector_view);
2294 if (vector_is_ghosted)
2300 template <
typename Number>
2311 if (vector_is_ghosted)
2317 template <
typename Number>
2318 template <
typename Number2>
2329 if (vector_is_ghosted)
2335 template <
typename Number>
2348 if (vector_is_ghosted)
2354 template <
typename Number>
2370 if (vector_is_ghosted)
2376 template <
typename Number>
2387 if (vector_is_ghosted)
2393 template <
typename Number>
2398 return partitioner->get_communicator();
2403 template <
typename Number>
2405 std_cxx11::shared_ptr<const Utilities::MPI::Partitioner>
2411 #endif // ifndef DOXYGEN 2427 template <
typename Number>
2436 DEAL_II_NAMESPACE_CLOSE
std_cxx11::shared_ptr< const Utilities::MPI::Partitioner > partitioner
void update_ghost_values() const
std::vector< MPI_Request > compress_requests
real_type l1_norm() const
Number add_and_dot(const Number a, const Vector< Number > &V, const Vector< Number > &W)
Number operator[](const size_type i) const
bool operator!=(const Vector< Number2 > &v) const
#define AssertDimension(dim1, dim2)
void sadd(const Number s, const Vector< Number > &V)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number operator()(const size_type i) const
std::pair< size_type, size_type > local_range() const
real_type linfty_norm() const
::ExceptionBase & ExcMessage(std::string arg1)
bool is_non_negative() const
void equ(const Number a, const Vector< Number > &u)
#define AssertIndexRange(index, range)
void ratio(const Vector< Number > &a, const Vector< Number > &b) DEAL_II_DEPRECATED
bool is_ghost_entry(const types::global_dof_index global_index) const DEAL_II_DEPRECATED
Vector< Number > & operator=(const Number s)
bool is_finite(const double x)
BlockDynamicSparsityPattern BlockCompressedSparsityPattern DEAL_II_DEPRECATED
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
numbers::NumberTraits< Number >::real_type real_type
VectorView< Number > vector_view
bool in_local_range(const size_type global_index) const
void scale(const Vector< Number > &scaling_factors)
Vector< Number > & operator+=(const Vector< Number > &V)
T sum(const T &t, const MPI_Comm &mpi_communicator)
unsigned int global_dof_index
#define Assert(cond, exc)
real_type lp_norm(const real_type p) const
void swap(Vector< Number > &v)
Vector< Number > & operator-=(const Vector< Number > &V)
Vector< Number > & operator*=(const Number factor)
void swap(parallel::distributed::Vector< Number > &u, parallel::distributed::Vector< Number > &v)
Number operator*(const Vector< Number2 > &V) const
std::vector< MPI_Request > update_ghost_values_requests
Vector< Number > & operator/=(const Number factor)
IndexSet locally_owned_elements() const
T min(const T &t, const MPI_Comm &mpi_communicator)
bool operator==(const Vector< Number2 > &v) const
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
void compress(::VectorOperation::values operation=::VectorOperation::unknown) const
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
real_type norm_sqr() const
#define DeclException3(Exception3, type1, type2, type3, outsequence)
real_type l2_norm() const
size_type local_size() const
Number mean_value() const
T max(const T &t, const MPI_Comm &mpi_communicator)