distributed_vector.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 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/numeric_vector.h"
29 #include "libmesh/parallel.h"
30 
31 // C++ includes
32 #include <vector>
33 #include <algorithm>
34 #include <limits>
35 
36 namespace libMesh
37 {
38 
39 
40 
51 template <typename T>
53 {
54 public:
55 
59  explicit
61  const ParallelType = AUTOMATIC);
62 
66  explicit
68  const numeric_index_type n,
69  const ParallelType ptype = AUTOMATIC);
70 
76  const numeric_index_type n,
78  const ParallelType ptype = AUTOMATIC);
79 
86  const numeric_index_type N,
87  const numeric_index_type n_local,
88  const std::vector<numeric_index_type>& ghost,
89  const ParallelType ptype = AUTOMATIC);
90 
96 
100  void close ();
101 
105  void clear ();
106 
111  void zero ();
112 
118  virtual AutoPtr<NumericVector<T> > zero_clone () const;
119 
123  AutoPtr<NumericVector<T> > clone () const;
124 
137  void init (const numeric_index_type N,
138  const numeric_index_type n_local,
139  const bool fast=false,
140  const ParallelType ptype=AUTOMATIC);
141 
145  void init (const numeric_index_type N,
146  const bool fast=false,
147  const ParallelType ptype=AUTOMATIC);
148 
153  virtual void init (const numeric_index_type /*N*/,
154  const numeric_index_type /*n_local*/,
155  const std::vector<numeric_index_type>& /*ghost*/,
156  const bool /*fast*/ = false,
157  const ParallelType = AUTOMATIC);
158 
163  virtual void init (const NumericVector<T>& other,
164  const bool fast = false);
165 
169  NumericVector<T> & operator= (const T s);
170 
175 
180 
184  NumericVector<T> & operator= (const std::vector<T> &v);
185 
191  Real min () const;
192 
198  Real max () const;
199 
203  T sum() const;
204 
209  Real l1_norm () const;
210 
216  Real l2_norm () const;
217 
223  Real linfty_norm () const;
224 
232  numeric_index_type size () const;
233 
239 
245 
251 
255  T operator() (const numeric_index_type i) const;
256 
262 
268 
273 
277  virtual void reciprocal();
278 
283  virtual void conjugate();
284 
288  void set (const numeric_index_type i, const T value);
289 
293  void add (const numeric_index_type i, const T value);
294 
300  void add (const T s);
301 
307  void add (const NumericVector<T>& V);
308 
314  void add (const T a, const NumericVector<T>& v);
315 
321  void add_vector (const std::vector<T>& v,
322  const std::vector<numeric_index_type>& dof_indices);
323 
330  void add_vector (const NumericVector<T>& V,
331  const std::vector<numeric_index_type>& dof_indices);
332 
340  const SparseMatrix<T>&)
341  { libmesh_error(); }
342 
349  void add_vector (const DenseVector<T>& V,
350  const std::vector<numeric_index_type>& dof_indices);
351 
359  const SparseMatrix<T>&)
360  { libmesh_error(); }
361 
366  virtual void insert (const std::vector<T>& v,
367  const std::vector<numeric_index_type>& dof_indices);
368 
375  virtual void insert (const NumericVector<T>& V,
376  const std::vector<numeric_index_type>& dof_indices);
377 
383  virtual void insert (const DenseVector<T>& V,
384  const std::vector<numeric_index_type>& dof_indices);
385 
391  virtual void insert (const DenseSubVector<T>& V,
392  const std::vector<numeric_index_type>& dof_indices);
393 
398  void scale (const T factor);
399 
404  virtual void abs();
405 
409  virtual T dot(const NumericVector<T>& V) const;
410 
415  void localize (std::vector<T>& v_local) const;
416 
421  void localize (NumericVector<T>& v_local) const;
422 
428  void localize (NumericVector<T>& v_local,
429  const std::vector<numeric_index_type>& send_list) const;
430 
435  void localize (const numeric_index_type first_local_idx,
436  const numeric_index_type last_local_idx,
437  const std::vector<numeric_index_type>& send_list);
438 
445  void localize_to_one (std::vector<T>& v_local,
446  const processor_id_type proc_id=0) const;
447 
452  virtual void pointwise_mult (const NumericVector<T>& vec1,
453  const NumericVector<T>& vec2);
454 
458  virtual void swap (NumericVector<T> &v);
459 
460 private:
461 
466  std::vector<T> _values;
467 
472 
477 
482 
487 };
488 
489 
490 //--------------------------------------------------------------------------
491 // DistributedVector inline methods
492 template <typename T>
493 inline
495  const ParallelType ptype)
496  : NumericVector<T>(comm, ptype),
497  _global_size (0),
498  _local_size (0),
499  _first_local_index(0),
500  _last_local_index (0)
501 {
502  this->_type = ptype;
503 }
504 
505 
506 
507 template <typename T>
508 inline
510  const numeric_index_type n,
511  const ParallelType ptype)
512  : NumericVector<T>(comm, ptype)
513 {
514  this->init(n, n, false, ptype);
515 }
516 
517 
518 
519 template <typename T>
520 inline
522  const numeric_index_type n,
524  const ParallelType ptype)
525  : NumericVector<T>(comm, ptype)
526 {
527  this->init(n, n_local, false, ptype);
528 }
529 
530 
531 
532 template <typename T>
533 inline
535  const numeric_index_type n,
537  const std::vector<numeric_index_type>& ghost,
538  const ParallelType ptype)
539  : NumericVector<T>(comm, ptype)
540 {
541  this->init(n, n_local, ghost, false, ptype);
542 }
543 
544 
545 
546 template <typename T>
547 inline
549 {
550  this->clear ();
551 }
552 
553 
554 
555 template <typename T>
556 inline
559  const bool fast,
560  const ParallelType ptype)
561 {
562  // This function must be run on all processors at once
563  parallel_object_only();
564 
565  libmesh_assert_less_equal (n_local, n);
566 
567  if (ptype == AUTOMATIC)
568  {
569  if (n == n_local)
570  this->_type = SERIAL;
571  else
572  this->_type = PARALLEL;
573  }
574  else
575  this->_type = ptype;
576 
577  libmesh_assert ((this->_type==SERIAL && n==n_local) ||
578  this->_type==PARALLEL);
579 
580  // Clear the data structures if already initialized
581  if (this->initialized())
582  this->clear();
583 
584  // Initialize data structures
585  _values.resize(n_local);
586  _local_size = n_local;
587  _global_size = n;
588 
589  _first_local_index = 0;
590 
591 #ifdef LIBMESH_HAVE_MPI
592 
593  std::vector<numeric_index_type> local_sizes (this->n_processors(), 0);
594 
595  local_sizes[this->processor_id()] = n_local;
596 
597  this->comm().sum(local_sizes);
598 
599  // _first_local_index is the sum of _local_size
600  // for all processor ids less than ours
601  for (processor_id_type p=0; p!=this->processor_id(); p++)
602  _first_local_index += local_sizes[p];
603 
604 
605 # ifdef DEBUG
606  // Make sure all the local sizes sum up to the global
607  // size, otherwise there is big trouble!
608  numeric_index_type dbg_sum=0;
609 
610  for (processor_id_type p=0; p!=this->n_processors(); p++)
611  dbg_sum += local_sizes[p];
612 
613  libmesh_assert_equal_to (dbg_sum, n);
614 
615 # endif
616 
617 #else
618 
619  // No other options without MPI!
620  if (n != n_local)
621  {
622  libMesh::err << "ERROR: MPI is required for n != n_local!"
623  << std::endl;
624  libmesh_error();
625  }
626 
627 #endif
628 
629  _last_local_index = _first_local_index + n_local;
630 
631  // Set the initialized flag
632  this->_is_initialized = true;
633 
634  // Zero the components unless directed otherwise
635  if (!fast)
636  this->zero();
637 }
638 
639 
640 template <typename T>
641 inline
644  const std::vector<numeric_index_type>& /*ghost*/,
645  const bool fast,
646  const ParallelType ptype)
647 {
648  // TODO: we shouldn't ignore the ghost sparsity pattern
649  this->init(n, n_local, fast, ptype);
650 }
651 
652 
653 
654 /* Default implementation for solver packages for which ghosted
655  vectors are not yet implemented. */
656 template <class T>
658  const bool fast)
659 {
660  this->init(other.size(),other.local_size(),fast,other.type());
661 }
662 
663 
664 
665 template <typename T>
666 inline
668  const bool fast,
669  const ParallelType ptype)
670 {
671  this->init(n,n,fast,ptype);
672 }
673 
674 
675 
676 template <typename T>
677 inline
679 {
680  libmesh_assert (this->initialized());
681 
682  this->_is_closed = true;
683 }
684 
685 
686 
687 template <typename T>
688 inline
690 {
691  _values.clear();
692 
693  _global_size =
694  _local_size =
695  _first_local_index =
696  _last_local_index = 0;
697 
698 
699  this->_is_closed = this->_is_initialized = false;
700 }
701 
702 
703 
704 template <typename T>
705 inline
707 {
708  libmesh_assert (this->initialized());
709  libmesh_assert_equal_to (_values.size(), _local_size);
710  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
711 
712  std::fill (_values.begin(),
713  _values.end(),
714  0.);
715 }
716 
717 
718 
719 template <typename T>
720 inline
722 {
723  AutoPtr<NumericVector<T> > cloned_vector
724  (new DistributedVector<T>(this->comm()));
725 
726  cloned_vector->init(*this);
727 
728  return cloned_vector;
729 }
730 
731 
732 
733 template <typename T>
734 inline
736 {
737  AutoPtr<NumericVector<T> > cloned_vector
738  (new DistributedVector<T>(this->comm()));
739 
740  cloned_vector->init(*this, true);
741 
742  *cloned_vector = *this;
743 
744  return cloned_vector;
745 }
746 
747 
748 
749 template <typename T>
750 inline
752 {
753  libmesh_assert (this->initialized());
754  libmesh_assert_equal_to (_values.size(), _local_size);
755  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
756 
757  return _global_size;
758 }
759 
760 
761 
762 template <typename T>
763 inline
765 {
766  libmesh_assert (this->initialized());
767  libmesh_assert_equal_to (_values.size(), _local_size);
768  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
769 
770  return _local_size;
771 }
772 
773 
774 
775 template <typename T>
776 inline
778 {
779  libmesh_assert (this->initialized());
780  libmesh_assert_equal_to (_values.size(), _local_size);
781  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
782 
783  return _first_local_index;
784 }
785 
786 
787 
788 template <typename T>
789 inline
791 {
792  libmesh_assert (this->initialized());
793  libmesh_assert_equal_to (_values.size(), _local_size);
794  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
795 
796  return _last_local_index;
797 }
798 
799 
800 
801 template <typename T>
802 inline
804 {
805  libmesh_assert (this->initialized());
806  libmesh_assert_equal_to (_values.size(), _local_size);
807  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
808  libmesh_assert ( ((i >= first_local_index()) &&
809  (i < last_local_index())) );
810 
811  return _values[i - _first_local_index];
812 }
813 
814 
815 
816 template <typename T>
817 inline
818 void DistributedVector<T>::set (const numeric_index_type i, const T value)
819 {
820  libmesh_assert (this->initialized());
821  libmesh_assert_equal_to (_values.size(), _local_size);
822  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
823  libmesh_assert_less (i, size());
824  libmesh_assert_less (i-first_local_index(), local_size());
825 
826  _values[i - _first_local_index] = value;
827 }
828 
829 
830 
831 template <typename T>
832 inline
833 void DistributedVector<T>::add (const numeric_index_type i, const T value)
834 {
835  libmesh_assert (this->initialized());
836  libmesh_assert_equal_to (_values.size(), _local_size);
837  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
838  libmesh_assert_less (i, size());
839  libmesh_assert_less (i-first_local_index(), local_size());
840 
841  _values[i - _first_local_index] += value;
842 }
843 
844 
845 
846 template <typename T>
847 inline
849 {
850  // This function must be run on all processors at once
851  parallel_object_only();
852 
853  libmesh_assert (this->initialized());
854  libmesh_assert_equal_to (_values.size(), _local_size);
855  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
856 
857  Real local_min = _values.size() ?
859  for (numeric_index_type i = 1; i < _values.size(); ++i)
860  local_min = std::min(libmesh_real(_values[i]), local_min);
861 
862  this->comm().min(local_min);
863 
864  return local_min;
865 }
866 
867 
868 
869 template <typename T>
870 inline
872 {
873  // This function must be run on all processors at once
874  parallel_object_only();
875 
876  libmesh_assert (this->initialized());
877  libmesh_assert_equal_to (_values.size(), _local_size);
878  libmesh_assert_equal_to ((_last_local_index - _first_local_index), _local_size);
879 
880  Real local_max = _values.size() ?
882  for (numeric_index_type i = 1; i < _values.size(); ++i)
883  local_max = std::max(libmesh_real(_values[i]), local_max);
884 
885  this->comm().max(local_max);
886 
887  return local_max;
888 }
889 
890 
891 template <typename T>
892 inline
894 {
895  DistributedVector<T>& v = libmesh_cast_ref<DistributedVector<T>&>(other);
896 
897  std::swap(_global_size, v._global_size);
898  std::swap(_local_size, v._local_size);
899  std::swap(_first_local_index, v._first_local_index);
900  std::swap(_last_local_index, v._last_local_index);
901 
902  // This should be O(1) with any reasonable STL implementation
903  std::swap(_values, v._values);
904 }
905 
906 } // namespace libMesh
907 
908 
909 #endif // LIBMESH_DISTRIBUTED_VECTOR_H

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:04 UTC

Hosted By:
SourceForge.net Logo