Reference documentation for deal.II version 9.0.0
read_write_vector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2015 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_read_write_vector_h
17 #define dealii_read_write_vector_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/index_set.h>
21 #include <deal.II/base/mpi.h>
22 #include <deal.II/base/template_constraints.h>
23 #include <deal.II/base/types.h>
24 #include <deal.II/base/utilities.h>
25 #include <deal.II/base/memory_consumption.h>
26 #include <deal.II/base/thread_management.h>
27 #include <deal.II/lac/vector_operation.h>
28 
29 #include <cstring>
30 #include <cstdlib>
31 #include <iomanip>
32 
33 #ifdef DEAL_II_WITH_TRILINOS
34 # include <deal.II/lac/trilinos_epetra_communication_pattern.h>
35 # include <deal.II/lac/trilinos_epetra_vector.h>
36 
37 # include <Epetra_MultiVector.h>
38 
39 #endif
40 
41 DEAL_II_NAMESPACE_OPEN
42 
43 namespace LinearAlgebra
44 {
45  class CommunicationPatternBase;
46  namespace distributed
47  {
48  template <typename> class Vector;
49  }
50 }
51 
52 #ifdef DEAL_II_WITH_PETSC
53 namespace PETScWrappers
54 {
55  namespace MPI
56  {
57  class Vector;
58  }
59 }
60 #endif
61 
62 #ifdef DEAL_II_WITH_TRILINOS
63 namespace TrilinosWrappers
64 {
65  namespace MPI
66  {
67  class Vector;
68  }
69 }
70 #endif
71 
72 #ifdef DEAL_II_WITH_CUDA
73 namespace LinearAlgebra
74 {
75  namespace CUDAWrappers
76  {
77  template <typename> class Vector;
78  }
79 }
80 #endif
81 
82 namespace LinearAlgebra
83 {
123  template <typename Number>
124  class ReadWriteVector : public Subscriptor
125  {
126  public:
132  typedef Number value_type;
133  typedef value_type *pointer;
134  typedef const value_type *const_pointer;
135  typedef value_type *iterator;
136  typedef const value_type *const_iterator;
137  typedef value_type &reference;
138  typedef const value_type &const_reference;
139  typedef types::global_dof_index size_type;
140  typedef typename numbers::NumberTraits<Number>::real_type real_type;
141 
149  ReadWriteVector ();
150 
154  ReadWriteVector (const ReadWriteVector<Number> &in_vector);
155 
160  explicit ReadWriteVector (const size_type size);
161 
166  explicit ReadWriteVector (const IndexSet &locally_stored_indices);
167 
171  ~ReadWriteVector () = default;
172 
181  virtual void reinit (const size_type size,
182  const bool omit_zeroing_entries = false);
183 
192  template <typename Number2>
193  void reinit(const ReadWriteVector<Number2> &in_vector,
194  const bool omit_zeroing_entries = false);
195 
205  virtual void reinit (const IndexSet &locally_stored_indices,
206  const bool omit_zeroing_entries = false);
207 
208 
209 #ifdef DEAL_II_WITH_TRILINOS
210 #ifdef DEAL_II_WITH_MPI
211 
222  void reinit(const TrilinosWrappers::MPI::Vector &trilinos_vec);
223 #endif
224 #endif
225 
239  template <typename Functor>
240  void apply(const Functor &func);
241 
254  void swap (ReadWriteVector<Number> &v);
255 
260  operator= (const ReadWriteVector<Number> &in_vector);
261 
265  template <typename Number2>
267  operator= (const ReadWriteVector<Number2> &in_vector);
268 
273  ReadWriteVector<Number> &operator = (const Number s);
274 
283  void import(const distributed::Vector<Number> &vec,
284  VectorOperation::values operation,
285  const std::shared_ptr<const CommunicationPatternBase> &communication_pattern =
286  std::shared_ptr<const CommunicationPatternBase> ());
287 
288 #ifdef DEAL_II_WITH_PETSC
289 
297  void import(const PETScWrappers::MPI::Vector &petsc_vec,
298  VectorOperation::values operation,
299  const std::shared_ptr<const CommunicationPatternBase> &communication_pattern =
300  std::shared_ptr<const CommunicationPatternBase> ());
301 #endif
302 
303 #ifdef DEAL_II_WITH_TRILINOS
304 
314  void import(const TrilinosWrappers::MPI::Vector &trilinos_vec,
315  VectorOperation::values operation,
316  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
317  std::shared_ptr<const CommunicationPatternBase> ());
318 
319 #ifdef DEAL_II_WITH_MPI
320 
328  void import(const EpetraWrappers::Vector &epetra_vec,
329  VectorOperation::values operation,
330  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
331  std::shared_ptr<const CommunicationPatternBase> ());
332 #endif
333 #endif
334 
335 #ifdef DEAL_II_WITH_CUDA
336 
342  void import(const CUDAWrappers::Vector<Number> &cuda_vec,
343  VectorOperation::values operation,
344  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
345  std::shared_ptr<const CommunicationPatternBase> ());
346 #endif
347 
356  size_type size() const;
357 
363  size_type n_elements() const;
364 
368  const IndexSet &get_stored_elements () const;
369 
375  iterator begin ();
376 
381  const_iterator begin () const;
382 
387  iterator end ();
388 
393  const_iterator end () const;
395 
396 
401 
407  Number operator () (const size_type global_index) const;
408 
414  Number &operator () (const size_type global_index);
415 
423  Number operator [] (const size_type global_index) const;
424 
432  Number &operator [] (const size_type global_index);
433 
449  template <typename Number2>
450  void extract_subvector_to (const std::vector<size_type> &indices,
451  std::vector<Number2> &values) const;
452 
480  template <typename ForwardIterator, typename OutputIterator>
481  void extract_subvector_to (ForwardIterator indices_begin,
482  const ForwardIterator indices_end,
483  OutputIterator values_begin) const;
484 
495  Number local_element (const size_type local_index) const;
496 
507  Number &local_element (const size_type local_index);
509 
510 
515 
520  template <typename Number2>
521  void add (const std::vector<size_type> &indices,
522  const std::vector<Number2> &values);
523 
528  template <typename Number2>
529  void add (const std::vector<size_type> &indices,
531 
537  template <typename Number2>
538  void add (const size_type n_elements,
539  const size_type *indices,
540  const Number2 *values);
541 
545  void print (std::ostream &out,
546  const unsigned int precision = 3,
547  const bool scientific = true) const;
548 
552  std::size_t memory_consumption () const;
554 
555  protected:
556 #ifdef DEAL_II_WITH_TRILINOS
557 
562  void import(const Epetra_MultiVector &multivector,
563  const IndexSet &locally_owned_elements,
564  VectorOperation::values operation,
565  const MPI_Comm &mpi_comm,
566  const std::shared_ptr<const CommunicationPatternBase> &communication_pattern);
567 #endif
568 
572  unsigned int
573  global_to_local (const types::global_dof_index global_index) const
574  {
575  // the following will throw an exception if the global_index is not
576  // in the remaining_elements
577  return static_cast<unsigned int>(stored_elements.index_within_set(global_index));
578  }
579 
583  void resize_val (const size_type new_allocated_size);
584 
585 #if defined(DEAL_II_WITH_TRILINOS) && defined(DEAL_II_WITH_MPI)
586 
591  create_epetra_comm_pattern(const IndexSet &source_index_set,
592  const MPI_Comm &mpi_comm);
593 #endif
594 
599 
604 
609  std::shared_ptr<CommunicationPatternBase> comm_pattern;
610 
614  std::unique_ptr<Number[], decltype (free) *> values;
615 
620  mutable std::shared_ptr< ::parallel::internal::TBBPartitioner> thread_loop_partitioner;
621 
625  template <typename Number2> friend class ReadWriteVector;
626 
627  private:
633  template <typename Functor>
635  {
636  public:
641  const Functor &functor);
642 
646  virtual void operator() (const size_type begin,
647  const size_type end);
648 
649  private:
654 
658  const Functor &functor;
659  };
660  };
661 
665  /*----------------------- Inline functions ----------------------------------*/
666 
667 #ifndef DOXYGEN
668 
669  template <typename Number>
670  inline
672  :
673  Subscriptor(),
674  values(nullptr, free)
675  {
676  // virtual functions called in constructors and destructors never use the
677  // override in a derived class
678  // for clarity be explicit on which function is called
680  }
681 
682 
683 
684  template <typename Number>
685  inline
686  ReadWriteVector<Number>::ReadWriteVector (const ReadWriteVector<Number> &v)
687  :
688  Subscriptor(),
689  values(nullptr, free)
690  {
691  this->operator=(v);
692  }
693 
694 
695 
696  template <typename Number>
697  inline
699  :
700  Subscriptor(),
701  values(nullptr, free)
702  {
703  // virtual functions called in constructors and destructors never use the
704  // override in a derived class
705  // for clarity be explicit on which function is called
707  }
708 
709 
710 
711  template <typename Number>
712  inline
713  ReadWriteVector<Number>::ReadWriteVector (const IndexSet &locally_stored_indices)
714  :
715  Subscriptor(),
716  values(nullptr, free)
717  {
718  // virtual functions called in constructors and destructors never use the
719  // override in a derived class
720  // for clarity be explicit on which function is called
721  ReadWriteVector<Number>::reinit (locally_stored_indices);
722  }
723 
724 
725 
726  template <typename Number>
727  inline
728  typename ReadWriteVector<Number>::size_type
730  {
731  return stored_elements.size();
732  }
733 
734 
735 
736  template <typename Number>
737  inline
738  typename ReadWriteVector<Number>::size_type
740  {
741  return stored_elements.n_elements();
742  }
743 
744 
745 
746  template <typename Number>
747  inline
748  const IndexSet &
750  {
751  return stored_elements;
752  }
753 
754 
755 
756  template <typename Number>
757  inline
758  typename ReadWriteVector<Number>::iterator
760  {
761  return values.get();
762  }
763 
764 
765 
766  template <typename Number>
767  inline
768  typename ReadWriteVector<Number>::const_iterator
770  {
771  return values.get();
772  }
773 
774 
775 
776  template <typename Number>
777  inline
778  typename ReadWriteVector<Number>::iterator
780  {
781  return values.get() + this->n_elements();
782  }
783 
784 
785 
786  template <typename Number>
787  inline
788  typename ReadWriteVector<Number>::const_iterator
790  {
791  return values.get() + this->n_elements();
792  }
793 
794 
795 
796  template <typename Number>
797  inline
798  Number
799  ReadWriteVector<Number>::operator() (const size_type global_index) const
800  {
801  return values[global_to_local(global_index)];
802  }
803 
804 
805 
806  template <typename Number>
807  inline
808  Number &
809  ReadWriteVector<Number>::operator() (const size_type global_index)
810  {
811  return values[global_to_local (global_index)];
812  }
813 
814 
815 
816  template <typename Number>
817  inline
818  Number
819  ReadWriteVector<Number>::operator[] (const size_type global_index) const
820  {
821  return operator()(global_index);
822  }
823 
824 
825 
826  template <typename Number>
827  inline
828  Number &
829  ReadWriteVector<Number>::operator[] (const size_type global_index)
830  {
831  return operator()(global_index);
832  }
833 
834 
835 
836  template <typename Number>
837  template <typename Number2>
838  inline
839  void ReadWriteVector<Number>::extract_subvector_to (const std::vector<size_type> &indices,
840  std::vector<Number2> &extracted_values) const
841  {
842  for (size_type i = 0; i < indices.size(); ++i)
843  extracted_values[i] = operator()(indices[i]);
844  }
845 
846 
847 
848  template <typename Number>
849  template <typename ForwardIterator, typename OutputIterator>
850  inline
851  void ReadWriteVector<Number>::extract_subvector_to (ForwardIterator indices_begin,
852  const ForwardIterator indices_end,
853  OutputIterator values_begin) const
854  {
855  while (indices_begin != indices_end)
856  {
857  *values_begin = operator()(*indices_begin);
858  indices_begin++;
859  values_begin++;
860  }
861  }
862 
863 
864 
865  template <typename Number>
866  inline
867  Number
868  ReadWriteVector<Number>::local_element (const size_type local_index) const
869  {
870  AssertIndexRange (local_index, this->n_elements());
871 
872  return values[local_index];
873  }
874 
875 
876 
877  template <typename Number>
878  inline
879  Number &
880  ReadWriteVector<Number>::local_element (const size_type local_index)
881  {
882  AssertIndexRange (local_index, this->n_elements());
883 
884  return values[local_index];
885  }
886 
887 
888 
889  template <typename Number>
890  template <typename Number2>
891  inline
892  void
893  ReadWriteVector<Number>::add (const std::vector<size_type> &indices,
894  const std::vector<Number2> &values)
895  {
896  AssertDimension (indices.size(), values.size());
897  add (indices.size(), indices.data(), values.data());
898  }
899 
900 
901 
902  template <typename Number>
903  template <typename Number2>
904  inline
905  void
906  ReadWriteVector<Number>::add (const std::vector<size_type> &indices,
907  const ReadWriteVector<Number2> &values)
908  {
909  const size_type size = indices.size();
910  for (size_type i=0; i<size; ++i)
911  {
913  ExcMessage("The given value is not finite but either infinite or Not A Number (NaN)"));
914  this->operator()(indices[i]) += values[indices[i]];
915  }
916  }
917 
918 
919 
920  template <typename Number>
921  template <typename Number2>
922  inline
923  void
924  ReadWriteVector<Number>::add (const size_type n_indices,
925  const size_type *indices,
926  const Number2 *values_to_add)
927  {
928  for (size_type i=0; i<n_indices; ++i)
929  {
931  ExcMessage("The given value is not finite but either infinite or Not A Number (NaN)"));
932  this->operator()(indices[i]) += values_to_add[i];
933  }
934  }
935 
936 
937 
938  template <typename Number>
939  template <typename Functor>
940  inline
942  ReadWriteVector<Number> &parent,
943  const Functor &functor)
944  :
945  parent(parent),
946  functor(functor)
947  {}
948 
949 
950 
951  template <typename Number>
952  template <typename Functor>
953  void
955  const size_type end)
956  {
957  for (size_type i=begin; i<end; ++i)
958  functor(parent.values[i]);
959  }
960 
961 #endif // ifndef DOXYGEN
962 
963 } // end of namespace LinearAlgebra
964 
965 
966 
967 
975 template <typename Number>
976 inline
979 {
980  u.swap (v);
981 }
982 
983 
984 DEAL_II_NAMESPACE_CLOSE
985 
986 #endif
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1248
Number operator[](const size_type global_index) const
void swap(ReadWriteVector< Number > &v)
Number local_element(const size_type local_index) const
FunctorTemplate(ReadWriteVector< Number > &parent, const Functor &functor)
void resize_val(const size_type new_allocated_size)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
std::size_t memory_consumption() const
void swap(LinearAlgebra::ReadWriteVector< Number > &u, LinearAlgebra::ReadWriteVector< Number > &v)
std::shared_ptr< ::parallel::internal::TBBPartitioner > thread_loop_partitioner
bool is_finite(const double x)
Definition: numbers.h:405
virtual void reinit(const size_type size, const bool omit_zeroing_entries=false)
size_type size() const
Definition: index_set.h:1575
static ::ExceptionBase & ExcMessage(std::string arg1)
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:1142
size_type index_within_set(const size_type global_index) const
Definition: index_set.h:1811
Number operator()(const size_type global_index) const
ReadWriteVector< Number > & operator=(const ReadWriteVector< Number > &in_vector)
EpetraWrappers::CommunicationPattern create_epetra_comm_pattern(const IndexSet &source_index_set, const MPI_Comm &mpi_comm)
void add(const std::vector< size_type > &indices, const std::vector< Number2 > &values)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true) const
virtual void operator()(const size_type begin, const size_type end)
std::shared_ptr< CommunicationPatternBase > comm_pattern
std::unique_ptr< Number[], decltype(free) * > values
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< Number2 > &values) const
void apply(const Functor &func)
void free(T *&pointer)
Definition: cuda.h:84
unsigned int global_to_local(const types::global_dof_index global_index) const
size_type n_elements() const
size_type n_elements() const
Definition: index_set.h:1717
const IndexSet & get_stored_elements() const