libmesh解析
本工作只是尝试解析原libmesh的代码,供学习使用
全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 
distributed_vector.h
浏览该文件的文档.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2023 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #include "libmesh/libmesh_common.h"
21 
22 
23 
24 #ifndef LIBMESH_DISTRIBUTED_VECTOR_H
25 #define LIBMESH_DISTRIBUTED_VECTOR_H
26 
27 // Local includes
28 #include "libmesh/int_range.h"
29 #include "libmesh/numeric_vector.h"
30 #include "libmesh/parallel.h"
31 
32 // C++ includes
33 #include <vector>
34 #include <algorithm>
35 #include <limits>
36 #include <mutex>
37 
38 namespace libMesh
39 {
40 
51 template <typename T>
52 class DistributedVector final : public NumericVector<T>
53 {
54 public:
55 
59  explicit
60  DistributedVector (const Parallel::Communicator & comm,
61  const ParallelType = AUTOMATIC);
62 
66  explicit
67  DistributedVector (const Parallel::Communicator & comm,
68  const numeric_index_type n,
69  const ParallelType ptype = AUTOMATIC);
70 
74  DistributedVector (const Parallel::Communicator & comm,
75  const numeric_index_type n,
76  const numeric_index_type n_local,
77  const ParallelType ptype = AUTOMATIC);
78 
83  DistributedVector (const Parallel::Communicator & comm,
84  const numeric_index_type N,
85  const numeric_index_type n_local,
86  const std::vector<numeric_index_type> & ghost,
87  const ParallelType ptype = AUTOMATIC);
88 
95 
99  DistributedVector (DistributedVector &&) = default;
100  DistributedVector (const DistributedVector &) = default;
102  virtual ~DistributedVector () = default;
103 
104  virtual void close () override;
105 
106  virtual void clear () override;
107 
108  virtual void zero () override;
109 
110  virtual std::unique_ptr<NumericVector<T>> zero_clone () const override;
111 
112  virtual std::unique_ptr<NumericVector<T>> clone () const override;
113 
114  virtual void init (const numeric_index_type N,
115  const numeric_index_type n_local,
116  const bool fast=false,
117  const ParallelType ptype=AUTOMATIC) override;
118 
119  virtual void init (const numeric_index_type N,
120  const bool fast=false,
121  const ParallelType ptype=AUTOMATIC) override;
122 
123  virtual void init (const numeric_index_type N,
124  const numeric_index_type n_local,
125  const std::vector<numeric_index_type> & ghost,
126  const bool fast = false,
127  const ParallelType = AUTOMATIC) override;
128 
129  virtual void init (const NumericVector<T> & other,
130  const bool fast = false) override;
131 
132  virtual NumericVector<T> & operator= (const T s) override;
133 
134  virtual NumericVector<T> & operator= (const NumericVector<T> & v) override;
135 
136  virtual NumericVector<T> & operator= (const std::vector<T> & v) override;
137 
138  virtual Real min () const override;
139 
140  virtual Real max () const override;
141 
142  virtual T sum() const override;
143 
144  virtual Real l1_norm () const override;
145 
146  virtual Real l2_norm () const override;
147 
148  virtual Real linfty_norm () const override;
149 
150  virtual numeric_index_type size () const override;
151 
152  virtual numeric_index_type local_size() const override;
153 
154  virtual numeric_index_type first_local_index() const override;
155 
156  virtual numeric_index_type last_local_index() const override;
157 
158  virtual T operator() (const numeric_index_type i) const override;
159 
160  virtual NumericVector<T> & operator += (const NumericVector<T> & v) override;
161 
162  virtual NumericVector<T> & operator -= (const NumericVector<T> & v) override;
163 
164  virtual NumericVector<T> & operator *= (const NumericVector<T> & v) override;
165 
166  virtual NumericVector<T> & operator /= (const NumericVector<T> & v) override;
167 
168  virtual void reciprocal() override;
169 
170  virtual void conjugate() override;
171 
172  virtual void set (const numeric_index_type i, const T value) override;
173 
174  virtual void add (const numeric_index_type i, const T value) override;
175 
176  virtual void add (const T s) override;
177 
178  virtual void add (const NumericVector<T> & V) override;
179 
180  virtual void add (const T a, const NumericVector<T> & v) override;
181 
187 
188  virtual void add_vector (const NumericVector<T> &,
189  const SparseMatrix<T> &) override
190  { libmesh_not_implemented(); }
191 
192  virtual void add_vector_transpose (const NumericVector<T> &,
193  const SparseMatrix<T> &) override
194  { libmesh_not_implemented(); }
195 
196  virtual void scale (const T factor) override;
197 
198  virtual void abs() override;
199 
200  virtual T dot(const NumericVector<T> & V) const override;
201 
202  virtual void localize (std::vector<T> & v_local) const override;
203 
204  virtual void localize (NumericVector<T> & v_local) const override;
205 
206  virtual void localize (NumericVector<T> & v_local,
207  const std::vector<numeric_index_type> & send_list) const override;
208 
209  virtual void localize (std::vector<T> & v_local,
210  const std::vector<numeric_index_type> & indices) const override;
211 
212  virtual void localize (const numeric_index_type first_local_idx,
213  const numeric_index_type last_local_idx,
214  const std::vector<numeric_index_type> & send_list) override;
215 
216  virtual void localize_to_one (std::vector<T> & v_local,
217  const processor_id_type proc_id=0) const override;
218 
219  virtual void pointwise_mult (const NumericVector<T> & vec1,
220  const NumericVector<T> & vec2) override;
221 
222  virtual void pointwise_divide (const NumericVector<T> & vec1,
223  const NumericVector<T> & vec2) override;
224 
225  virtual void swap (NumericVector<T> & v) override;
226 
227  virtual std::size_t max_allowed_id() const override;
228 
229 private:
230 
234  std::vector<T> _values;
235 
240 
245 
250 
255 };
256 
257 
258 //--------------------------------------------------------------------------
259 // DistributedVector inline methods
260 template <typename T>
261 inline
262 DistributedVector<T>::DistributedVector (const Parallel::Communicator & comm_in,
263  const ParallelType ptype) :
264  NumericVector<T>(comm_in, ptype),
265  _global_size (0),
266  _local_size (0),
267  _first_local_index(0),
268  _last_local_index (0)
269 {
270  this->_type = ptype;
271 }
272 
273 
274 
275 template <typename T>
276 inline
277 DistributedVector<T>::DistributedVector (const Parallel::Communicator & comm_in,
278  const numeric_index_type n,
279  const ParallelType ptype)
280  : NumericVector<T>(comm_in, ptype)
281 {
282  this->init(n, n, false, ptype);
283 }
284 
285 
286 
287 template <typename T>
288 inline
289 DistributedVector<T>::DistributedVector (const Parallel::Communicator & comm_in,
290  const numeric_index_type n,
291  const numeric_index_type n_local,
292  const ParallelType ptype)
293  : NumericVector<T>(comm_in, ptype)
294 {
295  this->init(n, n_local, false, ptype);
296 }
297 
298 
299 
300 template <typename T>
301 inline
302 DistributedVector<T>::DistributedVector (const Parallel::Communicator & comm_in,
303  const numeric_index_type n,
304  const numeric_index_type n_local,
305  const std::vector<numeric_index_type> & ghost,
306  const ParallelType ptype)
307  : NumericVector<T>(comm_in, ptype)
308 {
309  this->init(n, n_local, ghost, false, ptype);
310 }
311 
312 
313 
314 template <typename T>
315 inline
317  const numeric_index_type n_local,
318  const bool fast,
319  const ParallelType ptype)
320 {
321  // This function must be run on all processors at once
322  parallel_object_only();
323 
324  libmesh_assert_less_equal (n_local, n);
325 
326  if (ptype == AUTOMATIC)
327  {
328  if (n == n_local)
329  this->_type = SERIAL;
330  else
331  this->_type = PARALLEL;
332  }
333  else if (ptype == GHOSTED &&
334  n == n_local) // We can support GHOSTED with no ghosts...
335  this->_type = SERIAL;
336  else
337  this->_type = ptype;
338 
339  libmesh_assert ((this->_type==SERIAL && n==n_local) ||
340  this->_type==PARALLEL);
341 
342  // Clear the data structures if already initialized
343  if (this->initialized())
344  this->clear();
345 
346  // Initialize data structures
347  _values.resize(n_local);
348  _local_size = n_local;
349  _global_size = n;
350 
351  _first_local_index = 0;
352 
353 #ifdef LIBMESH_HAVE_MPI
354 
355  std::vector<numeric_index_type> local_sizes (this->n_processors(), 0);
356 
357  local_sizes[this->processor_id()] = n_local;
358 
359  this->comm().sum(local_sizes);
360 
361  // _first_local_index is the sum of _local_size
362  // for all processor ids less than ours
363  for (auto p : make_range(this->processor_id()))
364  _first_local_index += local_sizes[p];
365 
366 
367 # ifdef DEBUG
368  // Make sure all the local sizes sum up to the global
369  // size, otherwise there is big trouble!
370  numeric_index_type dbg_sum=0;
371 
372  for (auto p : make_range(this->n_processors()))
373  dbg_sum += local_sizes[p];
374 
375  libmesh_assert_equal_to (dbg_sum, n);
376 
377 # endif
378 
379 #else
380 
381  // No other options without MPI!
382  libmesh_error_msg_if(n != n_local, "ERROR: MPI is required for n != n_local!");
383 
384 #endif
385 
386  _last_local_index = _first_local_index + n_local;
387 
388  // Set the initialized flag
389  this->_is_initialized = true;
390 
391  // Zero the components unless directed otherwise
392  if (!fast)
393  this->zero();
394 }
395 
396 
397 template <typename T>
398 inline
400  const numeric_index_type n_local,
401  const std::vector<numeric_index_type> & /*ghost*/,
402  const bool fast,
403  const ParallelType ptype)
404 {
405  // TODO: we shouldn't ignore the ghost sparsity pattern
406  this->init(n, n_local, fast, ptype);
407 }
408 
409 
410 
411 /* Default implementation for solver packages for which ghosted
412  vectors are not yet implemented. */
413 template <class T>
415  const bool fast)
416 {
417  this->init(other.size(),other.local_size(),fast,other.type());
418 }
419 
420 
421 
422 template <typename T>
423 inline
425  const bool fast,
426  const ParallelType ptype)
427 {
428  this->init(n,n,fast,ptype);
429 }
430 
431 
432 
433 template <typename T>
434 inline
436 {
437  libmesh_assert (this->initialized());
438 
439  this->_is_closed = true;
440 }
441 
442 
443 
444 template <typename T>
445 inline
447 {
448  _values.clear();
449 
450  _global_size =
451  _local_size =
452  _first_local_index =
453  _last_local_index = 0;
454 
455 
456  this->_is_closed = this->_is_initialized = false;
457 }
458 
459 
460 
461 template <typename T>
462 inline
464 {
465  libmesh_assert (this->initialized());
466  libmesh_assert_equal_to (_values.size(), _local_size);
467  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
468 
469  std::fill (_values.begin(),
470  _values.end(),
471  0.);
472 }
473 
474 
475 
476 template <typename T>
477 inline
478 std::unique_ptr<NumericVector<T>> DistributedVector<T>::zero_clone () const
479 {
480  NumericVector<T> * cloned_vector = new DistributedVector<T>(this->comm());
481  cloned_vector->init(*this);
482  return std::unique_ptr<NumericVector<T>>(cloned_vector);
483 }
484 
485 
486 
487 template <typename T>
488 inline
489 std::unique_ptr<NumericVector<T>> DistributedVector<T>::clone () const
490 {
491  NumericVector<T> * cloned_vector = new DistributedVector<T>(this->comm());
492  cloned_vector->init(*this, true);
493  *cloned_vector = *this;
494  return std::unique_ptr<NumericVector<T>>(cloned_vector);
495 }
496 
497 
498 
499 template <typename T>
500 inline
502 {
503  libmesh_assert (this->initialized());
504  libmesh_assert_equal_to (_values.size(), _local_size);
505  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
506 
507  return _global_size;
508 }
509 
510 
511 
512 template <typename T>
513 inline
515 {
516  libmesh_assert (this->initialized());
517  libmesh_assert_equal_to (_values.size(), _local_size);
518  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
519 
520  return _local_size;
521 }
522 
523 
524 
525 template <typename T>
526 inline
528 {
529  libmesh_assert (this->initialized());
530  libmesh_assert_equal_to (_values.size(), _local_size);
531  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
532 
533  return _first_local_index;
534 }
535 
536 
537 
538 template <typename T>
539 inline
541 {
542  libmesh_assert (this->initialized());
543  libmesh_assert_equal_to (_values.size(), _local_size);
544  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
545 
546  return _last_local_index;
547 }
548 
549 
550 
551 template <typename T>
552 inline
554 {
555  libmesh_assert (this->initialized());
556  libmesh_assert_equal_to (_values.size(), _local_size);
557  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
558  libmesh_assert ( ((i >= first_local_index()) &&
559  (i < last_local_index())) );
560 
561  return _values[i - _first_local_index];
562 }
563 
564 
565 
566 template <typename T>
567 inline
568 void DistributedVector<T>::set (const numeric_index_type i, const T value)
569 {
570  libmesh_assert (this->initialized());
571  libmesh_assert_equal_to (_values.size(), _local_size);
572  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
573  libmesh_assert_less (i, size());
574  libmesh_assert_less (i-first_local_index(), local_size());
575 
576  std::scoped_lock lock(this->_numeric_vector_mutex);
577  _values[i - _first_local_index] = value;
578 
579 
580  this->_is_closed = false;
581 }
582 
583 
584 
585 
586 template <typename T>
587 inline
588 void DistributedVector<T>::add (const numeric_index_type i, const T value)
589 {
590  libmesh_assert (this->initialized());
591  libmesh_assert_equal_to (_values.size(), _local_size);
592  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
593  libmesh_assert_less (i, size());
594  libmesh_assert_less (i-first_local_index(), local_size());
595 
596  std::scoped_lock lock(this->_numeric_vector_mutex);
597  _values[i - _first_local_index] += value;
598 
599 
600  this->_is_closed = false;
601 }
602 
603 
604 
605 template <typename T>
606 inline
608 {
609  // This function must be run on all processors at once
610  parallel_object_only();
611 
612  libmesh_assert (this->initialized());
613  libmesh_assert_equal_to (_values.size(), _local_size);
614  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
615 
616  Real local_min = std::numeric_limits<Real>::max();
617  for (auto v : _values)
618  local_min = std::min(libmesh_real(v), local_min);
619 
620  this->comm().min(local_min);
621 
622  return local_min;
623 }
624 
625 
626 
627 template <typename T>
628 inline
630 {
631  // This function must be run on all processors at once
632  parallel_object_only();
633 
634  libmesh_assert (this->initialized());
635  libmesh_assert_equal_to (_values.size(), _local_size);
636  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
637 
638  Real local_max = -std::numeric_limits<Real>::max();
639  for (auto v : _values)
640  local_max = std::max(libmesh_real(v), local_max);
641 
642  this->comm().max(local_max);
643 
644  return local_max;
645 }
646 
647 
648 template <typename T>
649 inline
651 {
652  DistributedVector<T> & v = cast_ref<DistributedVector<T> &>(other);
653 
654  std::swap(_global_size, v._global_size);
655  std::swap(_local_size, v._local_size);
656  std::swap(_first_local_index, v._first_local_index);
657  std::swap(_last_local_index, v._last_local_index);
658 
659  // This should be O(1) with any reasonable STL implementation
660  std::swap(_values, v._values);
661 }
662 
663 template <typename T>
664 inline
666 {
667  // Uses a std:vector<T>, so our indexing matches that
668  return std::numeric_limits<typename std::vector<T>::size_type>::max();
669 }
670 
671 } // namespace libMesh
672 
673 
674 #endif // LIBMESH_DISTRIBUTED_VECTOR_H
T libmesh_real(T a)
virtual Real max() const override
获取向量中的最大值,或者在复数情况下获取最大的实部。
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 void add_vector(const NumericVector< T > &, const SparseMatrix< T > &) override
计算 , 即将 SparseMatrix A 和 NumericVector v 的乘积添加到 this。
virtual numeric_index_type last_local_index() const override
获取实际存储在该处理器上的最后一个向量元素的索引+1。
virtual void close() override
调用 NumericVector 的内部组装函数,确保值在处理器之间一致。
virtual numeric_index_type size() const =0
获取向量的大小。
virtual void set(const numeric_index_type i, const T value) override
设置 v(i) = value 。 请注意,此方法的库实现是线程安全的, 例如,将在写入向量之前锁定 _numeric_vector_mutex 。
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
将 v 从 *this 减去, 。等价于 u.add(-1, v)。
DistributedVector & operator=(const DistributedVector &)
复制赋值运算符。我们不能默认实现它(尽管它本质上实现了默认行为), 因为生成的默认版本尝试自动调用基类(NumericVector)的复制赋值运算符, 而选择使其成为纯虚拟函数,出于其他设计原因。 ...
提供了不同线性代数库的向量存储方案的统一接口。
Definition: dof_map.h:67
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 。
virtual Real linfty_norm() const override
获取向量的 -范数,即向量的最大绝对值。
numeric_index_type _global_size
全局向量大小。
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
返回一个智能指针,指向具有相同类型、大小和分区的此向量的副本,但所有条目都为零。
const Number zero
.
Definition: libmesh.h:248
virtual numeric_index_type local_size() const override
获取向量的本地大小,即 index_stop - index_start。
virtual void init(const numeric_index_type n, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC)=0
更改向量的维度为 n 。如果可能的话 ,该向量的保留内存保持不变。 如果 n==0 ,所有内存都将被释放。因此,如果要调整向量的大小并释放不需要的内存, 必须首先调用 init(0) ,然后调用 ini...
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
将向量加上 v , 。等价于 u.add(1, v)。
uint8_t processor_id_type
Definition: id_types.h:104
这是一个通用的稀疏矩阵类。该类包含了必须在派生类中覆盖的纯虚拟成员。 使用一个公共的基类允许从不同的求解器包中以不同的格式统一访问稀疏矩阵。
Definition: dof_map.h:66
virtual void reciprocal() override
计算每个向量条目的分量倒数, 。
virtual void zero() override
将所有条目设置为零。等同于 v = 0,但更明显且更快。
virtual Real l1_norm() const override
获取向量的 -范数,即条目的绝对值之和。
该类提供了一个简单的并行分布式向量数据类型, 专门用于 libmesh。提供了一些集体通信功能。
dof_id_type numeric_index_type
Definition: id_types.h:99
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:242
virtual ~DistributedVector()=default
virtual numeric_index_type size() const override
获取向量的大小。
virtual std::size_t max_allowed_id() const override
返回 NumericVector 可以包含的最大条目数(在所有处理器上)。
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
计算该向量与另一个向量的逐点除法。
ParallelType _type
向量的类型。
virtual std::unique_ptr< NumericVector< T > > clone() const 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 numeric_index_type local_size() const =0
获取向量的本地大小,即 index_stop - index_start。
virtual void abs() override
设置 ,对向量中的每个条目进行绝对值操作。
ParallelType type() const
获取向量的类型。
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:261
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...
virtual void clear() override
将 NumericVector&lt;T&gt; 恢复到原始状态。
std::vector< T > _values
实际的向量数据类型,用于保存向量条目。
virtual Real min() const override
获取向量中的最小值,或者在复数情况下获取最小的实部。
virtual T sum() const override
获取向量中所有值的总和。
virtual void swap(NumericVector< T > &v) override
交换该向量的内容与向量 v 的内容。子类应提供足够的间接性以使此操作成为 O(1) 的头部交换操作。
virtual void add_vector_transpose(const NumericVector< T > &, const SparseMatrix< T > &) override
计算 , 即将矩阵 A 的转置与 NumericVector v 的乘积添加到 this。
DistributedVector(const Parallel::Communicator &comm, const ParallelType=AUTOMATIC)
虚构造函数。维度为 0。
numeric_index_type _first_local_index
本地存储的第一个分量。
virtual T operator()(const numeric_index_type i) const override
获取向量的第 i 个条目的副本。