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"
31 #include "timpi/parallel_implementation.h"
32 #include "timpi/parallel_sync.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)
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);
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,
132 this->comm().max(local_linfty);
139 template <
typename T>
142 libmesh_assert (this->
closed());
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>
157 libmesh_assert (this->
closed());
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());
176 for (
auto i : index_range(_values))
177 _values[i] *= v_vec.
_values[i];
184 template <
typename T>
187 libmesh_assert_equal_to(size(), v.
size());
191 for (
auto i : index_range(_values))
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.");
263 for (
auto i : index_range(_values))
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() );
310 for (
auto i : index_range(_values))
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())
386 for (
auto i : index_range(*
this))
387 _values[i-first_local_index()] = v[i];
390 libmesh_error_msg(
"Incompatible sizes in DistributedVector::operator=");
397 template <
typename T>
402 libmesh_assert_equal_to (_values.size(), _local_size);
403 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
420 #ifndef LIBMESH_HAVE_MPI
422 libmesh_assert_equal_to (local_size(), size());
429 template <
typename T>
431 const std::vector<numeric_index_type> &)
const
434 libmesh_assert_equal_to (_values.size(), _local_size);
435 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
438 localize (v_local_in);
443 template <
typename T>
445 const std::vector<numeric_index_type> & indices)
const
448 v_local.resize(indices.size());
451 std::vector<numeric_index_type> local_sizes;
452 this->comm().allgather (_local_size, local_sizes);
455 std::vector<numeric_index_type> local_size_sums(this->n_processors());
456 local_size_sums[0] = local_sizes[0];
457 for (
auto i : IntRange<numeric_index_type>(1, local_sizes.size()))
458 local_size_sums[i] = local_size_sums[i-1] + local_sizes[i];
463 std::map<processor_id_type, std::vector<numeric_index_type>>
464 requested_ids, local_requested_ids;
467 typedef typename std::vector<numeric_index_type>::iterator iter_t;
473 for (
auto i : index_range(indices))
475 iter_t ub = std::upper_bound(local_size_sums.begin(),
476 local_size_sums.end(),
480 (std::distance(local_size_sums.begin(), ub));
482 requested_ids[on_proc].push_back(indices[i]);
483 local_requested_ids[on_proc].push_back(i);
486 auto gather_functor =
489 std::vector<T> & values)
493 const std::size_t ids_size = ids.size();
494 values.resize(ids_size);
496 for (std::size_t i=0; i != ids_size; i++)
502 values[i] = _values[requested_index - _first_local_index];
506 auto action_functor =
507 [& v_local, & local_requested_ids]
509 const std::vector<dof_id_type> &,
510 const std::vector<T> & values)
513 for (
auto i : index_range(values))
515 libmesh_assert(local_requested_ids.count(pid));
516 libmesh_assert_less(i, local_requested_ids[pid].size());
520 local_requested_ids[pid][i];
523 v_local[local_requested_index] = values[i];
527 const T * ex =
nullptr;
528 Parallel::pull_parallel_vector_data
529 (this->comm(), requested_ids, gather_functor, action_functor, ex);
534 template <
typename T>
537 const std::vector<numeric_index_type> & send_list)
540 libmesh_assert_equal_to (this->size(), this->local_size());
541 libmesh_assert_greater (last_local_idx, first_local_idx);
542 libmesh_assert_less_equal (send_list.size(), this->size());
543 libmesh_assert_less (last_local_idx, this->size());
549 if ((first_local_idx == 0) &&
550 (my_local_size == my_size))
558 parallel_vec.
init (my_size, my_local_size,
true, PARALLEL);
562 parallel_vec.
_values[i-first_local_idx] = _values[i];
565 parallel_vec.
localize (*
this, send_list);
570 template <
typename T>
574 parallel_object_only();
577 libmesh_assert_equal_to (_values.size(), _local_size);
578 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
580 v_local = this->_values;
582 this->comm().allgather (v_local);
584 #ifndef LIBMESH_HAVE_MPI
585 libmesh_assert_equal_to (local_size(), size());
591 template <
typename T>
596 parallel_object_only();
599 libmesh_assert_equal_to (_values.size(), _local_size);
600 libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
602 v_local = this->_values;
604 this->comm().gather (pid, v_local);
606 #ifndef LIBMESH_HAVE_MPI
607 libmesh_assert_equal_to (local_size(), size());
613 template <
typename T>
619 libmesh_not_implemented();
622 template <
typename T>
626 libmesh_not_implemented();
bool closed()
Checks that the library has been closed.
virtual T dot(const NumericVector< T > &V) const override
计算 ,即 (*this) 与向量 v 的点积。
numeric_index_type _last_local_index
本地存储的最后一个分量(+1)。
virtual void scale(const T factor) override
缩放向量的每个元素。
virtual numeric_index_type last_local_index() const override
获取实际存储在该处理器上的最后一个向量元素的索引+1。
virtual numeric_index_type size() const =0
获取向量的大小。
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
将 v 从 *this 减去, 。等价于 u.add(-1, v)。
DistributedVector & operator=(const DistributedVector &)
复制赋值运算符。我们不能默认实现它(尽管它本质上实现了默认行为), 因为生成的默认版本尝试自动调用基类(NumericVector)的复制赋值运算符, 而选择使其成为纯虚拟函数,出于其他设计原因。 ...
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
计算此向量条目与另一个向量的分量除法, 。
virtual void add(const numeric_index_type i, const T value) override
将 value 添加到由 i 指定的向量条目。 请注意,此方法的库实现是线程安全的, 例如,将在写入向量之前锁定 _numeric_vector_mutex 。
bool _is_initialized
在调用 init() 后设置为 true。
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的平方根。
virtual Real linfty_norm() const override
获取向量的 -范数,即向量的最大绝对值。
numeric_index_type _global_size
全局向量大小。
virtual numeric_index_type local_size() const override
获取向量的本地大小,即 index_stop - index_start。
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
将向量加上 v , 。等价于 u.add(1, v)。
uint8_t processor_id_type
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的绝对值。
virtual void reciprocal() override
计算每个向量条目的分量倒数, 。
virtual Real l1_norm() const override
获取向量的 -范数,即条目的绝对值之和。
该类提供了一个简单的并行分布式向量数据类型, 专门用于 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
计算该向量与另一个向量的逐点除法。
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
比较该向量与另一个向量的全局相对差异。
virtual void conjugate() override
反转向量中每个条目的虚部。
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
在处理器 proc_id 上创建全局向量的本地副本。 默认情况下,数据发送到处理器 0。此方法对于从一个处理器输出数据非常有用。
numeric_index_type _local_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
计算此向量条目与另一个向量的条目之间的分量乘法, 。
virtual void localize(std::vector< T > &v_local) const override
创建全局向量的副本并存储在本地向量 v_local 中。
virtual Real l2_norm() const override
获取向量的 -范数,即条目平方和的平方根。
virtual void abs() override
设置 ,对向量中的每个条目进行绝对值操作。
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
更改向量的维度为 n 。如果可能的话 ,该向量的保留内存保持不变。 如果 n==0 ,所有内存都将被释放。因此,如果要调整向量的大小并释放不需要的内存, 必须首先调用 init(0) ,然后调用 ini...
std::vector< T > _values
实际的向量数据类型,用于保存向量条目。
virtual T sum() const override
获取向量中所有值的总和。
numeric_index_type _first_local_index
本地存储的第一个分量。
bool _is_closed
用于跟踪向量的值在在一些或全部处理器上进行插入或添加值操作后是否在所有处理器上保持一致的标志。