21 #include "libmesh/distributed_vector.h" 24 #include "libmesh/dense_vector.h" 25 #include "libmesh/dense_subvector.h" 26 #include "libmesh/int_range.h" 27 #include "libmesh/libmesh_common.h" 28 #include "libmesh/tensor_tools.h" 51 parallel_object_only();
54 libmesh_assert_equal_to (_values.size(), _local_size);
55 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
59 for (
auto & val : _values)
62 this->comm().sum(local_sum);
73 parallel_object_only();
76 libmesh_assert_equal_to (_values.size(), _local_size);
77 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
81 for (
auto & val : _values)
82 local_l1 += std::abs(val);
84 this->comm().sum(local_l1);
95 parallel_object_only();
98 libmesh_assert_equal_to (_values.size(), _local_size);
99 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
103 for (
auto & val : _values)
106 this->comm().sum(local_l2);
108 return std::sqrt(local_l2);
113 template <
typename T>
117 parallel_object_only();
120 libmesh_assert_equal_to (_values.size(), _local_size);
121 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
123 Real local_linfty = 0.;
125 for (
auto & val : _values)
126 local_linfty = std::max(local_linfty,
127 static_cast<Real>(std::abs(val))
132 this->comm().max(local_linfty);
139 template <
typename T>
144 libmesh_assert_equal_to (_values.size(), _local_size);
145 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
154 template <
typename T>
159 libmesh_assert_equal_to (_values.size(), _local_size);
160 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
169 template <
typename T>
172 libmesh_assert_equal_to(size(), v.
size());
177 _values[i] *= v_vec.
_values[i];
184 template <
typename T>
187 libmesh_assert_equal_to(size(), v.
size());
192 _values[i] /= v_vec.
_values[i];
200 template <
typename T>
203 for (
auto & val : _values)
206 libmesh_assert_not_equal_to (val, T(0));
215 template <
typename T>
219 for (
auto & val : _values)
227 template <
typename T>
231 libmesh_assert_equal_to (_values.size(), _local_size);
232 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
234 for (
auto & val : _values)
240 template <
typename T>
244 libmesh_assert_equal_to (_values.size(), _local_size);
245 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
252 template <
typename T>
256 libmesh_assert_equal_to (_values.size(), _local_size);
257 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
261 libmesh_error_msg_if(!v,
"Cannot add different types of NumericVectors.");
264 _values[i] += a * v->
_values[i];
269 template <
typename T>
273 libmesh_assert_equal_to (_values.size(), _local_size);
274 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
276 for (
auto & val : _values)
280 template <
typename T>
284 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
286 for (
auto & val : _values)
294 template <
typename T>
298 parallel_object_only();
305 libmesh_assert_equal_to ( this->last_local_index(), v->
last_local_index() );
311 local_dot += this->_values[i] * v->
_values[i];
314 this->comm().sum(local_dot);
321 template <
typename T>
326 libmesh_assert_equal_to (_values.size(), _local_size);
327 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
329 for (
auto & val : _values)
337 template <
typename T>
351 template <
typename T>
367 libmesh_error_msg(
"v.local_size() = " << v.
local_size() <<
" must be equal to this->local_size() = " << this->local_size());
374 template <
typename T>
379 libmesh_assert_equal_to (_values.size(), _local_size);
380 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
382 if (v.size() == local_size())
385 else if (v.size() == size())
387 _values[i-first_local_index()] = v[i];
390 libmesh_error_msg(
"Incompatible sizes in DistributedVector::operator=");
397 template <
typename T>
403 parallel_object_only();
405 bool have_remote_values = !_remote_values.empty();
406 this->comm().max(have_remote_values);
408 if (have_remote_values)
410 bool someone_is_setting = (_unclosed_state == SET_VALUES);
411 this->comm().max(someone_is_setting);
415 if (!_remote_values.empty())
417 _unclosed_state == ADD_VALUES);
421 bool someone_is_adding = (_unclosed_state == ADD_VALUES);
422 this->comm().max(someone_is_adding);
424 libmesh_assert_not_equal_to(someone_is_setting, someone_is_adding);
429 std::sort(_remote_values.begin(), _remote_values.end(),
431 {
return a.first < b.first; });
433 std::vector<numeric_index_type> last_local_indices;
434 this->comm().allgather(_last_local_index, last_local_indices);
436 std::map<processor_id_type, std::vector<std::pair<numeric_index_type,T>>>
440 for (
auto [i, v] : _remote_values)
442 while (i >= last_local_indices[p])
444 libmesh_assert_less(p, this->n_processors());
447 updates_to_send[p].emplace_back(i, v);
449 _remote_values.clear();
451 auto action_functor =
452 [
this, someone_is_setting]
454 const std::vector<std::pair<numeric_index_type,T>> & incoming_values)
456 for (
auto [i, v] : incoming_values)
458 libmesh_assert_greater_equal(i, _first_local_index);
459 libmesh_assert_less(i, _last_local_index);
460 if (someone_is_setting)
461 _values[i-_first_local_index] = v;
463 _values[i-_first_local_index] += v;
467 Parallel::push_parallel_vector_data
468 (this->comm(), updates_to_send, action_functor);
470 _unclosed_state = DO_NOTHING;
473 this->_is_closed =
true;
478 template <
typename T>
483 libmesh_assert_equal_to (_values.size(), _local_size);
484 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
501 #ifndef LIBMESH_HAVE_MPI 503 libmesh_assert_equal_to (local_size(), size());
510 template <
typename T>
512 const std::vector<numeric_index_type> &)
const 515 libmesh_assert_equal_to (_values.size(), _local_size);
516 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
519 localize (v_local_in);
524 template <
typename T>
526 const std::vector<numeric_index_type> & indices)
const 529 v_local.resize(indices.size());
532 std::vector<numeric_index_type> local_sizes;
533 this->comm().allgather (_local_size, local_sizes);
536 std::vector<numeric_index_type> local_size_sums(this->n_processors());
537 local_size_sums[0] = local_sizes[0];
539 local_size_sums[i] = local_size_sums[i-1] + local_sizes[i];
544 std::map<processor_id_type, std::vector<numeric_index_type>>
545 requested_ids, local_requested_ids;
548 typedef typename std::vector<numeric_index_type>::iterator iter_t;
556 iter_t ub = std::upper_bound(local_size_sums.begin(),
557 local_size_sums.end(),
563 requested_ids[on_proc].push_back(indices[i]);
564 local_requested_ids[on_proc].push_back(i);
567 auto gather_functor =
570 std::vector<T> & values)
574 const std::size_t ids_size = ids.size();
575 values.resize(ids_size);
577 for (std::size_t i=0; i != ids_size; i++)
583 values[i] = _values[requested_index - _first_local_index];
587 auto action_functor =
588 [& v_local, & local_requested_ids]
590 const std::vector<dof_id_type> &,
591 const std::vector<T> & values)
597 libmesh_assert_less(i, local_requested_ids[pid].size());
601 local_requested_ids[pid][i];
604 v_local[local_requested_index] = values[i];
608 const T * ex =
nullptr;
609 Parallel::pull_parallel_vector_data
610 (this->comm(), requested_ids, gather_functor, action_functor, ex);
615 template <
typename T>
618 const std::vector<numeric_index_type> & send_list)
621 libmesh_assert_equal_to (this->size(), this->local_size());
622 libmesh_assert_greater (last_local_idx, first_local_idx);
623 libmesh_assert_less_equal (send_list.size(), this->size());
624 libmesh_assert_less (last_local_idx, this->size());
630 if ((first_local_idx == 0) &&
631 (my_local_size == my_size))
639 parallel_vec.
init (my_size, my_local_size,
true,
PARALLEL);
643 parallel_vec.
_values[i-first_local_idx] = _values[i];
646 parallel_vec.
localize (*
this, send_list);
651 template <
typename T>
655 parallel_object_only();
658 libmesh_assert_equal_to (_values.size(), _local_size);
659 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
661 v_local = this->_values;
663 this->comm().allgather (v_local);
665 #ifndef LIBMESH_HAVE_MPI 666 libmesh_assert_equal_to (local_size(), size());
672 template <
typename T>
677 parallel_object_only();
680 libmesh_assert_equal_to (_values.size(), _local_size);
681 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
683 v_local = this->_values;
685 this->comm().gather (pid, v_local);
687 #ifndef LIBMESH_HAVE_MPI 688 libmesh_assert_equal_to (local_size(), size());
694 template <
typename T>
700 libmesh_not_implemented();
703 template <
typename T>
707 libmesh_not_implemented();
bool closed()
Checks that the library has been closed.
virtual T dot(const NumericVector< T > &V) const override
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
numeric_index_type _last_local_index
The last component (+1) stored locally.
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
virtual numeric_index_type last_local_index() const override
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual numeric_index_type size() const =0
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
DistributedVector & operator=(const DistributedVector &)
Copy assignment operator.
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector's entries by another's, .
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
bool _is_initialized
true once init() has been called.
virtual Real linfty_norm() const override
The libMesh namespace provides an interface to certain functionality in the library.
numeric_index_type _global_size
The global vector size.
virtual numeric_index_type local_size() const override
Real distance(const Point &p)
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
uint8_t processor_id_type
virtual void reciprocal() override
Computes the component-wise reciprocal, .
virtual Real l1_norm() const override
This class provides a simple parallel, distributed vector datatype which is specific to libmesh...
dof_id_type numeric_index_type
bool _is_initialized
Flag that tells if init() has been called.
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
Creates a local copy of the global vector in v_local only on processor proc_id.
numeric_index_type _local_size
The local vector size.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual numeric_index_type first_local_index() const override
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector's entries by another's, ...
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
virtual Real l2_norm() const override
virtual void abs() override
Sets for each entry in the vector.
bool initialized()
Checks that library initialization has been done.
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC) override
Change the dimension of the vector to n.
std::vector< T > _values
Actual vector datatype to hold vector entries.
virtual T sum() const override
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
numeric_index_type _first_local_index
The first component stored locally.
bool _is_closed
Flag which tracks whether the vector's values are consistent on all processors after insertion or add...