libMesh
petsc_vector.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 
21 #ifndef LIBMESH_PETSC_VECTOR_H
22 #define LIBMESH_PETSC_VECTOR_H
23 
24 
25 #include "libmesh/libmesh_config.h"
26 
27 #ifdef LIBMESH_HAVE_PETSC
28 
29 // Local includes
30 #include "libmesh/numeric_vector.h"
31 #include "libmesh/petsc_macro.h"
32 #include "libmesh/int_range.h"
33 #include "libmesh/libmesh_common.h"
34 #include "libmesh/petsc_solver_exception.h"
35 #include "libmesh/parallel_only.h"
36 
37 // PETSc include files.
38 #ifdef I
39 # define LIBMESH_SAW_I
40 #endif
41 #include <petscvec.h>
42 #ifndef LIBMESH_SAW_I
43 # undef I // Avoid complex.h contamination
44 #endif
45 
46 // C++ includes
47 #include <cstddef>
48 #include <cstring>
49 #include <vector>
50 #include <unordered_map>
51 
52 #ifdef LIBMESH_HAVE_CXX11_THREAD
53 #include <atomic>
54 #include <mutex>
55 #endif
56 
57 namespace libMesh
58 {
59 
60 // forward declarations
61 template <typename T> class SparseMatrix;
62 
71 template <typename T>
72 class PetscVector final : public NumericVector<T>
73 {
74 public:
75 
79  explicit
80  PetscVector (const Parallel::Communicator & comm_in,
81  const ParallelType type = AUTOMATIC);
82 
86  explicit
87  PetscVector (const Parallel::Communicator & comm_in,
88  const numeric_index_type n,
89  const ParallelType type = AUTOMATIC);
90 
95  PetscVector (const Parallel::Communicator & comm_in,
96  const numeric_index_type n,
97  const numeric_index_type n_local,
98  const ParallelType type = AUTOMATIC);
99 
105  PetscVector (const Parallel::Communicator & comm_in,
106  const numeric_index_type N,
107  const numeric_index_type n_local,
108  const std::vector<numeric_index_type> & ghost,
109  const ParallelType type = AUTOMATIC);
110 
118  PetscVector(Vec v,
119  const Parallel::Communicator & comm_in);
120 
127 
133  PetscVector (PetscVector &&) = delete;
134  PetscVector (const PetscVector &) = delete;
135  PetscVector & operator= (PetscVector &&) = delete;
136  virtual ~PetscVector ();
137 
138  virtual void close () override;
139 
140  virtual void clear () override;
141 
142  virtual void zero () override;
143 
144  virtual std::unique_ptr<NumericVector<T>> zero_clone () const override;
145 
146  virtual std::unique_ptr<NumericVector<T>> clone () const override;
147 
148  virtual void init (const numeric_index_type N,
149  const numeric_index_type n_local,
150  const bool fast=false,
151  const ParallelType type=AUTOMATIC) override;
152 
153  virtual void init (const numeric_index_type N,
154  const bool fast=false,
155  const ParallelType type=AUTOMATIC) override;
156 
157  virtual void init (const numeric_index_type N,
158  const numeric_index_type n_local,
159  const std::vector<numeric_index_type> & ghost,
160  const bool fast = false,
161  const ParallelType = AUTOMATIC) override;
162 
163  virtual void init (const NumericVector<T> & other,
164  const bool fast = false) override;
165 
166  virtual NumericVector<T> & operator= (const T s) override;
167 
168  virtual NumericVector<T> & operator= (const NumericVector<T> & v) override;
169 
170  virtual NumericVector<T> & operator= (const std::vector<T> & v) override;
171 
172  virtual Real min () const override;
173 
174  virtual Real max () const override;
175 
176  virtual T sum () const override;
177 
178  virtual Real l1_norm () const override;
179 
180  virtual Real l2_norm () const override;
181 
182  virtual Real linfty_norm () const override;
183 
184  virtual numeric_index_type size () const override;
185 
186  virtual numeric_index_type local_size() const override;
187 
188  virtual numeric_index_type first_local_index() const override;
189 
190  virtual numeric_index_type last_local_index() const override;
191 
200 
201  virtual T operator() (const numeric_index_type i) const override;
202 
203  virtual void get(const std::vector<numeric_index_type> & index,
204  T * values) const override;
205 
212  PetscScalar * get_array();
213 
220  const PetscScalar * get_array_read() const;
221 
228  void restore_array();
229 
230  virtual NumericVector<T> & operator += (const NumericVector<T> & v) override;
231 
232  virtual NumericVector<T> & operator -= (const NumericVector<T> & v) override;
233 
234  virtual void reciprocal() override;
235 
236  virtual void conjugate() override;
237 
238  virtual void set (const numeric_index_type i,
239  const T value) override;
240 
241  virtual void add (const numeric_index_type i,
242  const T value) override;
243 
244  virtual void add (const T s) override;
245 
246  virtual void add (const NumericVector<T> & v) override;
247 
248  virtual void add (const T a, const NumericVector<T> & v) override;
249 
255 
256  virtual void add_vector (const T * v,
257  const std::vector<numeric_index_type> & dof_indices) override;
258 
259  virtual void add_vector (const NumericVector<T> & v,
260  const SparseMatrix<T> & A) override;
261 
262  virtual void add_vector_transpose (const NumericVector<T> & v,
263  const SparseMatrix<T> & A) override;
264 
272  const SparseMatrix<T> & A);
273 
279 
280  virtual void insert (const T * v,
281  const std::vector<numeric_index_type> & dof_indices) override;
282 
283  virtual void scale (const T factor) override;
284 
285  virtual NumericVector<T> & operator *= (const NumericVector<T> & v) override;
286 
287  virtual NumericVector<T> & operator /= (const NumericVector<T> & v) override;
288 
289  virtual void abs() override;
290 
291  virtual T dot(const NumericVector<T> & v) const override;
292 
298  T indefinite_dot(const NumericVector<T> & v) const;
299 
300  virtual void localize (std::vector<T> & v_local) const override;
301 
302  virtual void localize (NumericVector<T> & v_local) const override;
303 
304  virtual void localize (NumericVector<T> & v_local,
305  const std::vector<numeric_index_type> & send_list) const override;
306 
307  virtual void localize (std::vector<T> & v_local,
308  const std::vector<numeric_index_type> & indices) const override;
309 
310  virtual void localize (const numeric_index_type first_local_idx,
311  const numeric_index_type last_local_idx,
312  const std::vector<numeric_index_type> & send_list) override;
313 
314  virtual void localize_to_one (std::vector<T> & v_local,
315  const processor_id_type proc_id=0) const override;
316 
317  virtual void pointwise_mult (const NumericVector<T> & vec1,
318  const NumericVector<T> & vec2) override;
319 
320  virtual void print_matlab(const std::string & name = "") const override;
321 
322  virtual void create_subvector(NumericVector<T> & subvector,
323  const std::vector<numeric_index_type> & rows) const override;
324 
325  virtual void swap (NumericVector<T> & v) override;
326 
335  Vec vec () { libmesh_assert (_vec); return _vec; }
336 
337  Vec vec () const { libmesh_assert (_vec); return _vec; }
338 
339 
340 private:
341 
345  Vec _vec;
346 
352 #ifdef LIBMESH_HAVE_CXX11_THREAD
353  // We can't use std::atomic_flag here because we need load and store operations.
354  mutable std::atomic<bool> _array_is_present;
355 #else
356  mutable bool _array_is_present;
357 #endif
358 
365 
372 
377 
383  mutable Vec _local_form;
384 
393  mutable const PetscScalar * _read_only_values;
394 
403  mutable PetscScalar * _values;
404 
410 #ifdef LIBMESH_HAVE_CXX11_THREAD
411  mutable std::mutex _petsc_vector_mutex;
412 #else
414 #endif
415 
422  void _get_array(bool read_only) const;
423 
428  void _restore_array() const;
429 
433  typedef std::unordered_map<numeric_index_type,numeric_index_type> GlobalToLocalMap;
434 
440 
446 
452 
456  mutable bool _values_read_only;
457 };
458 
459 
460 /*----------------------- Inline functions ----------------------------------*/
461 
462 
463 
464 template <typename T>
465 inline
466 PetscVector<T>::PetscVector (const Parallel::Communicator & comm_in, const ParallelType ptype) :
467  NumericVector<T>(comm_in, ptype),
468  _array_is_present(false),
469  _first(0),
470  _last(0),
471  _local_form(nullptr),
472  _values(nullptr),
473  _global_to_local_map(),
474  _destroy_vec_on_exit(true),
475  _values_manually_retrieved(false),
476  _values_read_only(false)
477 {
478  this->_type = ptype;
479 }
480 
481 
482 
483 template <typename T>
484 inline
485 PetscVector<T>::PetscVector (const Parallel::Communicator & comm_in,
486  const numeric_index_type n,
487  const ParallelType ptype) :
488  NumericVector<T>(comm_in, ptype),
489  _array_is_present(false),
490  _local_form(nullptr),
491  _values(nullptr),
492  _global_to_local_map(),
493  _destroy_vec_on_exit(true),
494  _values_manually_retrieved(false),
495  _values_read_only(false)
496 {
497  this->init(n, n, false, ptype);
498 }
499 
500 
501 
502 template <typename T>
503 inline
504 PetscVector<T>::PetscVector (const Parallel::Communicator & comm_in,
505  const numeric_index_type n,
506  const numeric_index_type n_local,
507  const ParallelType ptype) :
508  NumericVector<T>(comm_in, ptype),
509  _array_is_present(false),
510  _local_form(nullptr),
511  _values(nullptr),
512  _global_to_local_map(),
513  _destroy_vec_on_exit(true),
514  _values_manually_retrieved(false),
515  _values_read_only(false)
516 {
517  this->init(n, n_local, false, ptype);
518 }
519 
520 
521 
522 template <typename T>
523 inline
524 PetscVector<T>::PetscVector (const Parallel::Communicator & comm_in,
525  const numeric_index_type n,
526  const numeric_index_type n_local,
527  const std::vector<numeric_index_type> & ghost,
528  const ParallelType ptype) :
529  NumericVector<T>(comm_in, ptype),
530  _array_is_present(false),
531  _local_form(nullptr),
532  _values(nullptr),
533  _global_to_local_map(),
534  _destroy_vec_on_exit(true),
535  _values_manually_retrieved(false),
536  _values_read_only(false)
537 {
538  this->init(n, n_local, ghost, false, ptype);
539 }
540 
541 
542 
543 
544 
545 template <typename T>
546 inline
548  const Parallel::Communicator & comm_in) :
549  NumericVector<T>(comm_in, AUTOMATIC),
550  _array_is_present(false),
551  _local_form(nullptr),
552  _values(nullptr),
553  _global_to_local_map(),
554  _destroy_vec_on_exit(false),
555  _values_manually_retrieved(false),
556  _values_read_only(false)
557 {
558  this->_vec = v;
559  this->_is_closed = true;
560  this->_is_initialized = true;
561 
562  /* We need to ask PETSc about the (local to global) ghost value
563  mapping and create the inverse mapping out of it. */
564  PetscErrorCode ierr=0;
565  PetscInt petsc_local_size=0;
566  ierr = VecGetLocalSize(_vec, &petsc_local_size);
567  LIBMESH_CHKERR(ierr);
568 
569  // Get the vector type from PETSc.
570  // As of PETSc 3.0.0, the VecType #define lost its const-ness, so we
571  // need to have it in the code
572 #if PETSC_VERSION_LESS_THAN(3,0,0) || !PETSC_VERSION_LESS_THAN(3,4,0)
573  // Pre-3.0 and petsc-dev (as of October 2012) use non-const versions
574  VecType ptype;
575 #else
576  const VecType ptype;
577 #endif
578  ierr = VecGetType(_vec, &ptype);
579  LIBMESH_CHKERR(ierr);
580 
581  if ((std::strcmp(ptype,VECSHARED) == 0) || (std::strcmp(ptype,VECMPI) == 0))
582  {
583 #if PETSC_RELEASE_LESS_THAN(3,1,1)
584  ISLocalToGlobalMapping mapping = _vec->mapping;
585 #else
586  ISLocalToGlobalMapping mapping;
587  ierr = VecGetLocalToGlobalMapping(_vec, &mapping);
588  LIBMESH_CHKERR(ierr);
589 #endif
590 
591  // If is a sparsely stored vector, set up our new mapping
592  if (mapping)
593  {
594  const numeric_index_type my_local_size = static_cast<numeric_index_type>(petsc_local_size);
595  const numeric_index_type ghost_begin = static_cast<numeric_index_type>(petsc_local_size);
596 #if PETSC_RELEASE_LESS_THAN(3,4,0)
597  const numeric_index_type ghost_end = static_cast<numeric_index_type>(mapping->n);
598 #else
599  PetscInt n;
600  ierr = ISLocalToGlobalMappingGetSize(mapping, &n);
601  LIBMESH_CHKERR(ierr);
602  const numeric_index_type ghost_end = static_cast<numeric_index_type>(n);
603 #endif
604 #if PETSC_RELEASE_LESS_THAN(3,1,1)
605  const PetscInt * indices = mapping->indices;
606 #else
607  const PetscInt * indices;
608  ierr = ISLocalToGlobalMappingGetIndices(mapping,&indices);
609  LIBMESH_CHKERR(ierr);
610 #endif
611  for (numeric_index_type i=ghost_begin; i<ghost_end; i++)
612  _global_to_local_map[indices[i]] = i-my_local_size;
613  this->_type = GHOSTED;
614 #if !PETSC_RELEASE_LESS_THAN(3,1,1)
615  ierr = ISLocalToGlobalMappingRestoreIndices(mapping, &indices);
616  LIBMESH_CHKERR(ierr);
617 #endif
618  }
619  else
620  this->_type = PARALLEL;
621  }
622  else
623  this->_type = SERIAL;
624 }
625 
626 
627 
628 
629 template <typename T>
630 inline
632 {
633  this->clear ();
634 }
635 
636 
637 
638 template <typename T>
639 inline
641  const numeric_index_type n_local,
642  const bool fast,
643  const ParallelType ptype)
644 {
645  parallel_object_only();
646 
647  PetscErrorCode ierr=0;
648  PetscInt petsc_n=static_cast<PetscInt>(n);
649 
650  // Clear initialized vectors
651  if (this->initialized())
652  this->clear();
653 
654  if (ptype == AUTOMATIC)
655  {
656  if (n == n_local)
657  this->_type = SERIAL;
658  else
659  this->_type = PARALLEL;
660  }
661  else
662  this->_type = ptype;
663 
664  libmesh_assert ((this->_type==SERIAL && n==n_local) ||
665  this->_type==PARALLEL);
666 
667  // create a sequential vector if on only 1 processor
668  if (this->_type == SERIAL)
669  {
670  ierr = VecCreateSeq (PETSC_COMM_SELF, petsc_n, &_vec);
671  CHKERRABORT(PETSC_COMM_SELF,ierr);
672 
673  ierr = VecSetFromOptions (_vec);
674  CHKERRABORT(PETSC_COMM_SELF,ierr);
675  }
676  // otherwise create an MPI-enabled vector
677  else if (this->_type == PARALLEL)
678  {
679 #ifdef LIBMESH_HAVE_MPI
680  PetscInt petsc_n_local=cast_int<PetscInt>(n_local);
681  libmesh_assert_less_equal (n_local, n);
682  ierr = VecCreateMPI (this->comm().get(), petsc_n_local, petsc_n,
683  &_vec);
684  LIBMESH_CHKERR(ierr);
685 #else
686  libmesh_assert_equal_to (n_local, n);
687  ierr = VecCreateSeq (PETSC_COMM_SELF, petsc_n, &_vec);
688  CHKERRABORT(PETSC_COMM_SELF,ierr);
689 #endif
690 
691  ierr = VecSetFromOptions (_vec);
692  LIBMESH_CHKERR(ierr);
693  }
694  else
695  libmesh_error_msg("Unsupported type " << this->_type);
696 
697  this->_is_initialized = true;
698  this->_is_closed = true;
699 
700 
701  if (fast == false)
702  this->zero ();
703 }
704 
705 
706 
707 template <typename T>
708 inline
710  const bool fast,
711  const ParallelType ptype)
712 {
713  this->init(n,n,fast,ptype);
714 }
715 
716 
717 
718 template <typename T>
719 inline
721  const numeric_index_type n_local,
722  const std::vector<numeric_index_type> & ghost,
723  const bool fast,
724  const ParallelType libmesh_dbg_var(ptype))
725 {
726  parallel_object_only();
727 
728  PetscErrorCode ierr=0;
729  PetscInt petsc_n=static_cast<PetscInt>(n);
730  PetscInt petsc_n_local=static_cast<PetscInt>(n_local);
731  PetscInt petsc_n_ghost=static_cast<PetscInt>(ghost.size());
732 
733  // If the mesh is not disjoint, every processor will either have
734  // all the dofs, none of the dofs, or some non-zero dofs at the
735  // boundary between processors.
736  //
737  // However we can't assert this, because someone might want to
738  // construct a GHOSTED vector which doesn't include neighbor element
739  // dofs. Boyce tried to do so in user code, and we're going to want
740  // to do so in System::project_vector().
741  //
742  // libmesh_assert(n_local == 0 || n_local == n || !ghost.empty());
743 
744  libmesh_assert(sizeof(PetscInt) == sizeof(numeric_index_type));
745 
746  PetscInt * petsc_ghost = ghost.empty() ? PETSC_NULL :
747  const_cast<PetscInt *>(reinterpret_cast<const PetscInt *>(ghost.data()));
748 
749  // Clear initialized vectors
750  if (this->initialized())
751  this->clear();
752 
753  libmesh_assert(ptype == AUTOMATIC || ptype == GHOSTED);
754  this->_type = GHOSTED;
755 
756  /* Make the global-to-local ghost cell map. */
757  for (auto i : index_range(ghost))
758  {
759  _global_to_local_map[ghost[i]] = i;
760  }
761 
762  /* Create vector. */
763  ierr = VecCreateGhost (this->comm().get(), petsc_n_local, petsc_n,
764  petsc_n_ghost, petsc_ghost,
765  &_vec);
766  LIBMESH_CHKERR(ierr);
767 
768  ierr = VecSetFromOptions (_vec);
769  LIBMESH_CHKERR(ierr);
770 
771  this->_is_initialized = true;
772  this->_is_closed = true;
773 
774  if (fast == false)
775  this->zero ();
776 }
777 
778 
779 
780 template <typename T>
781 inline
783  const bool fast)
784 {
785  parallel_object_only();
786 
787  // Clear initialized vectors
788  if (this->initialized())
789  this->clear();
790 
791  const PetscVector<T> & v = cast_ref<const PetscVector<T> &>(other);
792 
793  // Other vector should restore array.
794  if (v.initialized())
795  {
796  v._restore_array();
797  }
798 
799  this->_global_to_local_map = v._global_to_local_map;
800 
801  // Even if we're initializing sizes based on an uninitialized or
802  // unclosed vector, *this* vector is being initialized now and is
803  // initially closed.
804  this->_is_closed = true; // v._is_closed;
805  this->_is_initialized = true; // v._is_initialized;
806 
807  this->_type = v._type;
808 
809  // We want to have a valid Vec, even if it's initially of size zero
810  PetscErrorCode ierr = VecDuplicate (v._vec, &this->_vec);
811  LIBMESH_CHKERR(ierr);
812 
813  if (fast == false)
814  this->zero ();
815 }
816 
817 
818 
819 template <typename T>
820 inline
822 {
823  parallel_object_only();
824 
825  this->_restore_array();
826 
827  PetscErrorCode ierr=0;
828 
829  ierr = VecAssemblyBegin(_vec);
830  LIBMESH_CHKERR(ierr);
831  ierr = VecAssemblyEnd(_vec);
832  LIBMESH_CHKERR(ierr);
833 
834  if (this->type() == GHOSTED)
835  {
836  ierr = VecGhostUpdateBegin(_vec,INSERT_VALUES,SCATTER_FORWARD);
837  LIBMESH_CHKERR(ierr);
838  ierr = VecGhostUpdateEnd(_vec,INSERT_VALUES,SCATTER_FORWARD);
839  LIBMESH_CHKERR(ierr);
840  }
841 
842  this->_is_closed = true;
843 }
844 
845 
846 
847 template <typename T>
848 inline
850 {
851  parallel_object_only();
852 
853  if (this->initialized())
854  this->_restore_array();
855 
856  if ((this->initialized()) && (this->_destroy_vec_on_exit))
857  {
858  PetscErrorCode ierr=0;
859 
860  ierr = LibMeshVecDestroy(&_vec);
861  LIBMESH_CHKERR(ierr);
862  }
863 
864  this->_is_closed = this->_is_initialized = false;
865 
866  _global_to_local_map.clear();
867 }
868 
869 
870 
871 template <typename T>
872 inline
874 {
875  parallel_object_only();
876 
877  libmesh_assert(this->closed());
878 
879  this->_restore_array();
880 
881  PetscErrorCode ierr=0;
882 
883  PetscScalar z=0.;
884 
885  if (this->type() != GHOSTED)
886  {
887  ierr = VecSet (_vec, z);
888  LIBMESH_CHKERR(ierr);
889  }
890  else
891  {
892  /* Vectors that include ghost values require a special
893  handling. */
894  Vec loc_vec;
895  ierr = VecGhostGetLocalForm (_vec,&loc_vec);
896  LIBMESH_CHKERR(ierr);
897 
898  ierr = VecSet (loc_vec, z);
899  LIBMESH_CHKERR(ierr);
900 
901  ierr = VecGhostRestoreLocalForm (_vec,&loc_vec);
902  LIBMESH_CHKERR(ierr);
903  }
904 }
905 
906 
907 
908 template <typename T>
909 inline
910 std::unique_ptr<NumericVector<T>> PetscVector<T>::zero_clone () const
911 {
912  NumericVector<T> * cloned_vector = new PetscVector<T>(this->comm(), this->type());
913  cloned_vector->init(*this);
914  return std::unique_ptr<NumericVector<T>>(cloned_vector);
915 }
916 
917 
918 
919 template <typename T>
920 inline
921 std::unique_ptr<NumericVector<T>> PetscVector<T>::clone () const
922 {
923  NumericVector<T> * cloned_vector = new PetscVector<T>(this->comm(), this->type());
924  cloned_vector->init(*this, true);
925  *cloned_vector = *this;
926  return std::unique_ptr<NumericVector<T>>(cloned_vector);
927 }
928 
929 
930 
931 template <typename T>
932 inline
934 {
935  libmesh_assert (this->initialized());
936 
937  PetscErrorCode ierr=0;
938  PetscInt petsc_size=0;
939 
940  if (!this->initialized())
941  return 0;
942 
943  ierr = VecGetSize(_vec, &petsc_size);
944  LIBMESH_CHKERR(ierr);
945 
946  return static_cast<numeric_index_type>(petsc_size);
947 }
948 
949 
950 
951 template <typename T>
952 inline
954 {
955  libmesh_assert (this->initialized());
956 
957  PetscErrorCode ierr=0;
958  PetscInt petsc_size=0;
959 
960  ierr = VecGetLocalSize(_vec, &petsc_size);
961  LIBMESH_CHKERR(ierr);
962 
963  return static_cast<numeric_index_type>(petsc_size);
964 }
965 
966 
967 
968 template <typename T>
969 inline
971 {
972  libmesh_assert (this->initialized());
973 
974  numeric_index_type first = 0;
975 
976  if (_array_is_present) // Can we use cached values?
977  first = _first;
978  else
979  {
980  PetscErrorCode ierr=0;
981  PetscInt petsc_first=0, petsc_last=0;
982  ierr = VecGetOwnershipRange (_vec, &petsc_first, &petsc_last);
983  LIBMESH_CHKERR(ierr);
984  first = static_cast<numeric_index_type>(petsc_first);
985  }
986 
987  return first;
988 }
989 
990 
991 
992 template <typename T>
993 inline
995 {
996  libmesh_assert (this->initialized());
997 
998  numeric_index_type last = 0;
999 
1000  if (_array_is_present) // Can we use cached values?
1001  last = _last;
1002  else
1003  {
1004  PetscErrorCode ierr=0;
1005  PetscInt petsc_first=0, petsc_last=0;
1006  ierr = VecGetOwnershipRange (_vec, &petsc_first, &petsc_last);
1007  LIBMESH_CHKERR(ierr);
1008  last = static_cast<numeric_index_type>(petsc_last);
1009  }
1010 
1011  return last;
1012 }
1013 
1014 
1015 
1016 template <typename T>
1017 inline
1019 {
1020  libmesh_assert (this->initialized());
1021 
1022  numeric_index_type first=0;
1023  numeric_index_type last=0;
1024 
1025  if (_array_is_present) // Can we use cached values?
1026  {
1027  first = _first;
1028  last = _last;
1029  }
1030  else
1031  {
1032  PetscErrorCode ierr=0;
1033  PetscInt petsc_first=0, petsc_last=0;
1034  ierr = VecGetOwnershipRange (_vec, &petsc_first, &petsc_last);
1035  LIBMESH_CHKERR(ierr);
1036  first = static_cast<numeric_index_type>(petsc_first);
1037  last = static_cast<numeric_index_type>(petsc_last);
1038  }
1039 
1040 
1041  if ((i>=first) && (i<last))
1042  {
1043  return i-first;
1044  }
1045 
1046  GlobalToLocalMap::const_iterator it = _global_to_local_map.find(i);
1047 #ifndef NDEBUG
1048  const GlobalToLocalMap::const_iterator end = _global_to_local_map.end();
1049  if (it == end)
1050  {
1051  std::ostringstream error_message;
1052  error_message << "No index " << i << " in ghosted vector.\n"
1053  << "Vector contains [" << first << ',' << last << ")\n";
1054  GlobalToLocalMap::const_iterator b = _global_to_local_map.begin();
1055  if (b == end)
1056  {
1057  error_message << "And empty ghost array.\n";
1058  }
1059  else
1060  {
1061  error_message << "And ghost array {" << b->first;
1062  for (++b; b != end; ++b)
1063  error_message << ',' << b->first;
1064  error_message << "}\n";
1065  }
1066 
1067  libmesh_error_msg(error_message.str());
1068  }
1069  libmesh_assert (it != _global_to_local_map.end());
1070 #endif
1071  return it->second+last-first;
1072 }
1073 
1074 
1075 
1076 template <typename T>
1077 inline
1079 {
1080  this->_get_array(true);
1081 
1082  const numeric_index_type local_index = this->map_global_to_local_index(i);
1083 
1084 #ifndef NDEBUG
1085  if (this->type() == GHOSTED)
1086  {
1087  libmesh_assert_less (local_index, _local_size);
1088  }
1089 #endif
1090 
1091  return static_cast<T>(_read_only_values[local_index]);
1092 }
1093 
1094 
1095 
1096 template <typename T>
1097 inline
1098 void PetscVector<T>::get(const std::vector<numeric_index_type> & index,
1099  T * values) const
1100 {
1101  this->_get_array(true);
1102 
1103  const std::size_t num = index.size();
1104 
1105  for (std::size_t i=0; i<num; i++)
1106  {
1107  const numeric_index_type local_index = this->map_global_to_local_index(index[i]);
1108 #ifndef NDEBUG
1109  if (this->type() == GHOSTED)
1110  {
1111  libmesh_assert_less (local_index, _local_size);
1112  }
1113 #endif
1114  values[i] = static_cast<T>(_read_only_values[local_index]);
1115  }
1116 }
1117 
1118 
1119 template <typename T>
1120 inline
1122 {
1123  _values_manually_retrieved = true;
1124  _get_array(false);
1125 
1126  return _values;
1127 }
1128 
1129 
1130 template <typename T>
1131 inline
1132 const PetscScalar * PetscVector<T>::get_array_read() const
1133 {
1134  _values_manually_retrieved = true;
1135  _get_array(true);
1136 
1137  return _read_only_values;
1138 }
1139 
1140 template <typename T>
1141 inline
1143 {
1144  // \note \p _values_manually_retrieved needs to be set to \p false
1145  // \e before calling \p _restore_array()!
1146  _values_manually_retrieved = false;
1147  _restore_array();
1148 }
1149 
1150 template <typename T>
1151 inline
1153 {
1154  parallel_object_only();
1155 
1156  this->_restore_array();
1157 
1158  PetscErrorCode ierr=0;
1159  PetscInt index=0;
1160  PetscReal returnval=0.;
1161 
1162  ierr = VecMin (_vec, &index, &returnval);
1163  LIBMESH_CHKERR(ierr);
1164 
1165  // this return value is correct: VecMin returns a PetscReal
1166  return static_cast<Real>(returnval);
1167 }
1168 
1169 
1170 
1171 template <typename T>
1172 inline
1174 {
1175  parallel_object_only();
1176 
1177  this->_restore_array();
1178 
1179  PetscErrorCode ierr=0;
1180  PetscInt index=0;
1181  PetscReal returnval=0.;
1182 
1183  ierr = VecMax (_vec, &index, &returnval);
1184  LIBMESH_CHKERR(ierr);
1185 
1186  // this return value is correct: VecMax returns a PetscReal
1187  return static_cast<Real>(returnval);
1188 }
1189 
1190 
1191 
1192 template <typename T>
1193 inline
1195 {
1196  parallel_object_only();
1197 
1198  NumericVector<T>::swap(other);
1199 
1200  PetscVector<T> & v = cast_ref<PetscVector<T> &>(other);
1201 
1202  std::swap(_vec, v._vec);
1203  std::swap(_destroy_vec_on_exit, v._destroy_vec_on_exit);
1204  std::swap(_global_to_local_map, v._global_to_local_map);
1205 
1206 #ifdef LIBMESH_HAVE_CXX11_THREAD
1207  // Only truly atomic for v... but swap() doesn't really need to be thread safe!
1208  _array_is_present = v._array_is_present.exchange(_array_is_present);
1209 #else
1210  std::swap(_array_is_present, v._array_is_present);
1211 #endif
1212 
1213  std::swap(_local_form, v._local_form);
1214  std::swap(_values, v._values);
1215 }
1216 
1217 
1218 
1219 
1220 
1221 #ifdef LIBMESH_HAVE_CXX11
1222 static_assert(sizeof(PetscInt) == sizeof(numeric_index_type),
1223  "PETSc and libMesh integer sizes must match!");
1224 #endif
1225 
1226 
1227 inline
1229 {
1230  return reinterpret_cast<PetscInt *>(const_cast<numeric_index_type *>(p));
1231 }
1232 
1233 } // namespace libMesh
1234 
1235 
1236 #endif // #ifdef LIBMESH_HAVE_PETSC
1237 #endif // LIBMESH_PETSC_VECTOR_H
libMesh::PetscVector::pointwise_mult
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
Definition: petsc_vector.C:1167
libMesh::PetscVector::conjugate
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
Definition: petsc_vector.C:175
libMesh::PetscVector::abs
virtual void abs() override
Sets for each entry in the vector.
Definition: petsc_vector.C:460
libMesh::PetscVector::sum
virtual T sum() const override
Definition: petsc_vector.C:48
libMesh::PetscVector::map_global_to_local_index
numeric_index_type map_global_to_local_index(const numeric_index_type i) const
Definition: petsc_vector.h:1018
libMesh::PetscVector::create_subvector
virtual void create_subvector(NumericVector< T > &subvector, const std::vector< numeric_index_type > &rows) const override
Fills in subvector from this vector using the indices in rows.
Definition: petsc_vector.C:1285
libMesh::PetscVector::operator()
virtual T operator()(const numeric_index_type i) const override
Definition: petsc_vector.h:1078
libMesh::PARALLEL
Definition: enum_parallel_type.h:36
libMesh::PetscVector::last_local_index
virtual numeric_index_type last_local_index() const override
Definition: petsc_vector.h:994
libMesh::PetscVector::GlobalToLocalMap
std::unordered_map< numeric_index_type, numeric_index_type > GlobalToLocalMap
Type for map that maps global to local ghost cells.
Definition: petsc_vector.h:433
libMesh::PetscVector::set
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
Definition: petsc_vector.C:145
libMesh::SERIAL
Definition: enum_parallel_type.h:35
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::PetscVector::restore_array
void restore_array()
Restore the data array.
Definition: petsc_vector.h:1142
libMesh::PetscVector::indefinite_dot
T indefinite_dot(const NumericVector< T > &v) const
Definition: petsc_vector.C:507
libMesh::NumericVector::init
virtual void init(const numeric_index_type n, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC)=0
Change the dimension of the vector to n.
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::PetscVector::init
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType type=AUTOMATIC) override
Change the dimension of the vector to n.
Definition: petsc_vector.h:640
libMesh::PetscVector::_first
numeric_index_type _first
First local index.
Definition: petsc_vector.h:364
libMesh::PetscVector::clone
virtual std::unique_ptr< NumericVector< T > > clone() const override
Definition: petsc_vector.h:921
libMesh::GHOSTED
Definition: enum_parallel_type.h:37
libMesh::PetscVector::add_vector
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
Definition: petsc_vector.C:205
libMesh::PetscVector::reciprocal
virtual void reciprocal() override
Computes the component-wise reciprocal, .
Definition: petsc_vector.C:163
libMesh::PetscVector::_values_manually_retrieved
bool _values_manually_retrieved
Whether or not the data array has been manually retrieved using get_array() or get_array_read()
Definition: petsc_vector.h:451
libMesh::PetscVector::max
virtual Real max() const override
Definition: petsc_vector.h:1173
libMesh::SparseMatrix
Generic sparse matrix.
Definition: vector_fe_ex5.C:45
libMesh::PetscVector::operator*=
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector's entries by another's, .
Definition: petsc_vector.C:434
libMesh::NumericVector
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
Definition: vector_fe_ex5.C:43
libMesh::PetscVector::~PetscVector
virtual ~PetscVector()
Definition: petsc_vector.h:631
libMesh::zero
const Number zero
.
Definition: libmesh.h:243
libMesh::PetscVector::min
virtual Real min() const override
Definition: petsc_vector.h:1152
libMesh::PetscVector::operator=
PetscVector< T > & operator=(const PetscVector< T > &v)
Copy assignment operator.
Definition: petsc_vector.C:580
libMesh::TriangleWrapper::init
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
libMesh::PetscVector::zero_clone
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
Definition: petsc_vector.h:910
libMesh::NumericVector::_type
ParallelType _type
Type of vector.
Definition: numeric_vector.h:737
libMesh::PetscVector::scale
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
Definition: petsc_vector.C:407
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::PetscVector::print_matlab
virtual void print_matlab(const std::string &name="") const override
Print the contents of the vector in Matlab's sparse matrix format.
Definition: petsc_vector.C:1214
libMesh::PetscVector::operator-=
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
Definition: petsc_vector.C:132
libMesh::PetscVector::dot
virtual T dot(const NumericVector< T > &v) const override
Definition: petsc_vector.C:486
libMesh::PetscVector::close
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
Definition: petsc_vector.h:821
libMesh::numeric_petsc_cast
PetscInt * numeric_petsc_cast(const numeric_index_type *p)
Definition: petsc_vector.h:1228
libMesh::PetscVector::localize
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
Definition: petsc_vector.C:946
libMesh::NumericVector::initialized
virtual bool initialized() const
Definition: numeric_vector.h:155
libMesh::PetscVector::add_vector_transpose
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
Definition: petsc_vector.C:256
libMesh::PetscVector::get_array
PetscScalar * get_array()
Get read/write access to the raw PETSc Vector data array.
Definition: petsc_vector.h:1121
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::PetscVector::l2_norm
virtual Real l2_norm() const override
Definition: petsc_vector.C:81
libMesh::PetscVector::operator/=
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector's entries by another's, .
Definition: petsc_vector.C:447
libMesh::PetscVector
This class provides a nice interface to PETSc's Vec object.
Definition: petsc_vector.h:72
A
static PetscErrorCode Mat * A
Definition: petscdmlibmeshimpl.C:1026
libMesh::PetscVector::first_local_index
virtual numeric_index_type first_local_index() const override
Definition: petsc_vector.h:970
libMesh::PetscVector::zero
virtual void zero() override
Set all entries to zero.
Definition: petsc_vector.h:873
libMesh::PetscVector::_destroy_vec_on_exit
bool _destroy_vec_on_exit
This boolean value should only be set to false for the constructor which takes a PETSc Vec object.
Definition: petsc_vector.h:445
libMesh::PetscVector::PetscVector
PetscVector(const Parallel::Communicator &comm_in, const ParallelType type=AUTOMATIC)
Dummy-Constructor.
Definition: petsc_vector.h:466
libMesh::PetscVector::_get_array
void _get_array(bool read_only) const
Queries the array (and the local form if the vector is ghosted) from PETSc.
Definition: petsc_vector.C:1374
libMesh::PetscVector::vec
Vec vec() const
Definition: petsc_vector.h:337
libMesh::PetscVector::size
virtual numeric_index_type size() const override
Definition: petsc_vector.h:933
libMesh::numeric_index_type
dof_id_type numeric_index_type
Definition: id_types.h:99
libMesh::initialized
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:265
libMesh::PetscVector::add_vector_conjugate_transpose
void add_vector_conjugate_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A)
.
Definition: petsc_vector.C:284
libMesh::PetscVector::local_size
virtual numeric_index_type local_size() const override
Definition: petsc_vector.h:953
libMesh::PetscVector::linfty_norm
virtual Real linfty_norm() const override
Definition: petsc_vector.C:99
swap
void swap(Iterator &lhs, Iterator &rhs)
swap, used to implement op=
Definition: variant_filter_iterator.h:478
libMesh::PetscVector::_local_size
numeric_index_type _local_size
Size of the local values from _get_array()
Definition: petsc_vector.h:376
libMesh::ReferenceElem::get
const Elem & get(const ElemType type_in)
Definition: reference_elem.C:237
libMesh::libMeshPrivateData::_is_initialized
bool _is_initialized
Flag that tells if init() has been called.
Definition: libmesh.C:246
libMesh::PetscVector::add
virtual void add(const numeric_index_type i, const T value) override
Adds value to each entry of the vector.
Definition: petsc_vector.C:187
value
static const bool value
Definition: xdr_io.C:56
libMesh::PetscVector::_values_read_only
bool _values_read_only
Whether or not the data array is for read only access.
Definition: petsc_vector.h:456
libMesh::PetscVector::_restore_array
void _restore_array() const
Restores the array (and the local form if the vector is ghosted) to PETSc.
Definition: petsc_vector.C:1478
libMesh::PetscVector::_petsc_vector_mutex
Threads::spin_mutex _petsc_vector_mutex
Definition: petsc_vector.h:413
libMesh::PetscVector::_vec
Vec _vec
Actual PETSc vector datatype to hold vector entries.
Definition: petsc_vector.h:345
libMesh::PetscVector::_values
PetscScalar * _values
Pointer to the actual PETSc array of the values of the vector.
Definition: petsc_vector.h:403
libMesh::PetscVector::_last
numeric_index_type _last
Last local index.
Definition: petsc_vector.h:371
libMesh::AUTOMATIC
Definition: enum_parallel_type.h:34
libMesh::PetscVector::_read_only_values
const PetscScalar * _read_only_values
Pointer to the actual PETSc array of the values of the vector.
Definition: petsc_vector.h:393
libMesh::ParallelType
ParallelType
Defines an enum for parallel data structure types.
Definition: enum_parallel_type.h:33
libMesh::PetscVector::get
virtual void get(const std::vector< numeric_index_type > &index, T *values) const override
Access multiple components at once.
Definition: petsc_vector.h:1098
libMesh::PetscVector::vec
Vec vec()
Definition: petsc_vector.h:335
libMesh::PetscVector::clear
virtual void clear() override
Restores the NumericVector<T> to a pristine state.
Definition: petsc_vector.h:849
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::PetscVector::get_array_read
const PetscScalar * get_array_read() const
Get read only access to the raw PETSc Vector data array.
Definition: petsc_vector.h:1132
libMesh::PetscVector::swap
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
Definition: petsc_vector.h:1194
ierr
PetscErrorCode ierr
Definition: petscdmlibmeshimpl.C:1028
libMesh::PetscVector::l1_norm
virtual Real l1_norm() const override
Definition: petsc_vector.C:64
libMesh::PetscVector::operator+=
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
Definition: petsc_vector.C:118
libMesh::PetscVector::_global_to_local_map
GlobalToLocalMap _global_to_local_map
Map that maps global to local ghost cells (will be empty if not in ghost cell mode).
Definition: petsc_vector.h:439
libMesh::PetscVector::insert
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Inserts the entries of v in *this at the locations specified by v.
Definition: petsc_vector.C:387
libMesh::NumericVector::type
ParallelType type() const
Definition: numeric_vector.h:160
libMesh::PetscVector::_petsc_vector_mutex
std::mutex _petsc_vector_mutex
Mutex for _get_array and _restore_array.
Definition: petsc_vector.h:411
libMesh::PetscVector::_array_is_present
std::atomic< bool > _array_is_present
If true, the actual PETSc array of the values of the vector is currently accessible.
Definition: petsc_vector.h:354
libMesh::Threads::spin_mutex
Spin mutex.
Definition: threads_none.h:127
libMesh::PetscVector::_local_form
Vec _local_form
PETSc vector datatype to hold the local form of a ghosted vector.
Definition: petsc_vector.h:383
libMesh::PetscVector::localize_to_one
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.
libMesh::Quality::name
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
libMesh::PetscVector::_array_is_present
bool _array_is_present
Definition: petsc_vector.h:356
libMesh::closed
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:272