Reference documentation for deal.II version 9.1.0-pre
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.md at
12 // the top level directory of deal.II.
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 
21 #include <deal.II/base/index_set.h>
22 #include <deal.II/base/memory_consumption.h>
23 #include <deal.II/base/mpi.h>
24 #include <deal.II/base/template_constraints.h>
25 #include <deal.II/base/thread_management.h>
26 #include <deal.II/base/types.h>
27 #include <deal.II/base/utilities.h>
28 
29 #include <deal.II/lac/vector_operation.h>
30 
31 #include <cstdlib>
32 #include <cstring>
33 #include <iomanip>
34 
35 #ifdef DEAL_II_WITH_TRILINOS
36 # include <deal.II/lac/trilinos_epetra_communication_pattern.h>
37 # include <deal.II/lac/trilinos_epetra_vector.h>
38 
39 # include <Epetra_MultiVector.h>
40 
41 #endif
42 
43 DEAL_II_NAMESPACE_OPEN
44 
45 namespace LinearAlgebra
46 {
47  class CommunicationPatternBase;
48  namespace distributed
49  {
50  template <typename>
51  class Vector;
52  }
53 } // namespace LinearAlgebra
54 
55 #ifdef DEAL_II_WITH_PETSC
56 namespace PETScWrappers
57 {
58  namespace MPI
59  {
60  class Vector;
61  }
62 } // namespace PETScWrappers
63 #endif
64 
65 #ifdef DEAL_II_WITH_TRILINOS
66 namespace TrilinosWrappers
67 {
68  namespace MPI
69  {
70  class Vector;
71  }
72 } // namespace TrilinosWrappers
73 #endif
74 
75 #ifdef DEAL_II_WITH_CUDA
76 namespace LinearAlgebra
77 {
78  namespace CUDAWrappers
79  {
80  template <typename>
81  class Vector;
82  }
83 } // namespace LinearAlgebra
84 #endif
85 
86 namespace LinearAlgebra
87 {
127  template <typename Number>
128  class ReadWriteVector : public Subscriptor
129  {
130  public:
136  using value_type = Number;
137  using pointer = value_type *;
138  using const_pointer = const value_type *;
139  using iterator = value_type *;
140  using const_iterator = const value_type *;
141  using reference = value_type &;
142  using const_reference = const value_type &;
143  using size_type = types::global_dof_index;
144  using real_type = typename numbers::NumberTraits<Number>::real_type;
145 
153  ReadWriteVector();
154 
158  ReadWriteVector(const ReadWriteVector<Number> &in_vector);
159 
164  explicit ReadWriteVector(const size_type size);
165 
170  explicit ReadWriteVector(const IndexSet &locally_stored_indices);
171 
175  ~ReadWriteVector() override = default;
176 
185  virtual void
186  reinit(const size_type size, const bool omit_zeroing_entries = false);
187 
196  template <typename Number2>
197  void
198  reinit(const ReadWriteVector<Number2> &in_vector,
199  const bool omit_zeroing_entries = false);
200 
210  virtual void
211  reinit(const IndexSet &locally_stored_indices,
212  const bool omit_zeroing_entries = false);
213 
214 
215 #ifdef DEAL_II_WITH_TRILINOS
216 # ifdef DEAL_II_WITH_MPI
217 
228  void
229  reinit(const TrilinosWrappers::MPI::Vector &trilinos_vec);
230 # endif
231 #endif
232 
246  template <typename Functor>
247  void
248  apply(const Functor &func);
249 
262  void
264 
269  operator=(const ReadWriteVector<Number> &in_vector);
270 
274  template <typename Number2>
276  operator=(const ReadWriteVector<Number2> &in_vector);
277 
283  operator=(const Number s);
284 
293  void
294  import(const distributed::Vector<Number> &vec,
295  VectorOperation::values operation,
296  const std::shared_ptr<const CommunicationPatternBase>
297  &communication_pattern =
298  std::shared_ptr<const CommunicationPatternBase>());
299 
300 #ifdef DEAL_II_WITH_PETSC
301 
309  void
310  import(const PETScWrappers::MPI::Vector &petsc_vec,
311  VectorOperation::values operation,
312  const std::shared_ptr<const CommunicationPatternBase>
313  &communication_pattern =
314  std::shared_ptr<const CommunicationPatternBase>());
315 #endif
316 
317 #ifdef DEAL_II_WITH_TRILINOS
318 
328  void
329  import(
330  const TrilinosWrappers::MPI::Vector & trilinos_vec,
331  VectorOperation::values operation,
332  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
333  std::shared_ptr<const CommunicationPatternBase>());
334 
335 # ifdef DEAL_II_WITH_MPI
336 
344  void
345  import(
346  const EpetraWrappers::Vector & epetra_vec,
347  VectorOperation::values operation,
348  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
349  std::shared_ptr<const CommunicationPatternBase>());
350 # endif
351 #endif
352 
353 #ifdef DEAL_II_WITH_CUDA
354 
360  void
361  import(
362  const CUDAWrappers::Vector<Number> & cuda_vec,
363  VectorOperation::values operation,
364  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
365  std::shared_ptr<const CommunicationPatternBase>());
366 #endif
367 
376  size_type
377  size() const;
378 
384  size_type
385  n_elements() const;
386 
390  const IndexSet &
391  get_stored_elements() const;
392 
398  iterator
399  begin();
400 
405  const_iterator
406  begin() const;
407 
412  iterator
413  end();
414 
419  const_iterator
420  end() const;
422 
423 
428 
434  Number
435  operator()(const size_type global_index) const;
436 
442  Number &
443  operator()(const size_type global_index);
444 
452  Number operator[](const size_type global_index) const;
453 
461  Number &operator[](const size_type global_index);
462 
478  template <typename Number2>
479  void
480  extract_subvector_to(const std::vector<size_type> &indices,
481  std::vector<Number2> & values) const;
482 
510  template <typename ForwardIterator, typename OutputIterator>
511  void
512  extract_subvector_to(ForwardIterator indices_begin,
513  const ForwardIterator indices_end,
514  OutputIterator values_begin) const;
515 
526  Number
527  local_element(const size_type local_index) const;
528 
539  Number &
540  local_element(const size_type local_index);
542 
543 
548 
553  template <typename Number2>
554  void
555  add(const std::vector<size_type> &indices,
556  const std::vector<Number2> & values);
557 
562  template <typename Number2>
563  void
564  add(const std::vector<size_type> & indices,
565  const ReadWriteVector<Number2> &values);
566 
572  template <typename Number2>
573  void
574  add(const size_type n_elements,
575  const size_type *indices,
576  const Number2 * values);
577 
581  void
582  print(std::ostream & out,
583  const unsigned int precision = 3,
584  const bool scientific = true) const;
585 
589  std::size_t
590  memory_consumption() const;
592 
593  protected:
594 #ifdef DEAL_II_WITH_TRILINOS
595 
600  void
601  import(const Epetra_MultiVector &multivector,
602  const IndexSet & locally_owned_elements,
603  VectorOperation::values operation,
604  const MPI_Comm & mpi_comm,
605  const std::shared_ptr<const CommunicationPatternBase>
606  &communication_pattern);
607 #endif
608 
612  unsigned int
613  global_to_local(const types::global_dof_index global_index) const
614  {
615  // the following will throw an exception if the global_index is not
616  // in the remaining_elements
617  return static_cast<unsigned int>(
618  stored_elements.index_within_set(global_index));
619  }
620 
624  void
625  resize_val(const size_type new_allocated_size);
626 
627 #if defined(DEAL_II_WITH_TRILINOS) && defined(DEAL_II_WITH_MPI)
628 
633  create_epetra_comm_pattern(const IndexSet &source_index_set,
634  const MPI_Comm &mpi_comm);
635 #endif
636 
641 
646 
651  std::shared_ptr<CommunicationPatternBase> comm_pattern;
652 
656  std::unique_ptr<Number[], decltype(free) *> values;
657 
662  mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
664 
668  template <typename Number2>
669  friend class ReadWriteVector;
670 
671  private:
677  template <typename Functor>
679  {
680  public:
684  FunctorTemplate(ReadWriteVector<Number> &parent, const Functor &functor);
685 
689  virtual void
690  operator()(const size_type begin, const size_type end);
691 
692  private:
697 
701  const Functor &functor;
702  };
703  };
704 
708  /*---------------------------- Inline functions ---------------------------*/
709 
710 #ifndef DOXYGEN
711 
712  template <typename Number>
714  : Subscriptor()
715  , values(nullptr, free)
716  {
717  // virtual functions called in constructors and destructors never use the
718  // override in a derived class
719  // for clarity be explicit on which function is called
721  }
722 
723 
724 
725  template <typename Number>
727  const ReadWriteVector<Number> &v)
728  : Subscriptor()
729  , values(nullptr, free)
730  {
731  this->operator=(v);
732  }
733 
734 
735 
736  template <typename Number>
737  inline ReadWriteVector<Number>::ReadWriteVector(const size_type size)
738  : Subscriptor()
739  , values(nullptr, free)
740  {
741  // virtual functions called in constructors and destructors never use the
742  // override in a derived class
743  // for clarity be explicit on which function is called
745  }
746 
747 
748 
749  template <typename Number>
751  const IndexSet &locally_stored_indices)
752  : Subscriptor()
753  , values(nullptr, free)
754  {
755  // virtual functions called in constructors and destructors never use the
756  // override in a derived class
757  // for clarity be explicit on which function is called
758  ReadWriteVector<Number>::reinit(locally_stored_indices);
759  }
760 
761 
762 
763  template <typename Number>
764  inline typename ReadWriteVector<Number>::size_type
766  {
767  return stored_elements.size();
768  }
769 
770 
771 
772  template <typename Number>
773  inline typename ReadWriteVector<Number>::size_type
775  {
776  return stored_elements.n_elements();
777  }
778 
779 
780 
781  template <typename Number>
782  inline const IndexSet &
784  {
785  return stored_elements;
786  }
787 
788 
789 
790  template <typename Number>
791  inline typename ReadWriteVector<Number>::iterator
793  {
794  return values.get();
795  }
796 
797 
798 
799  template <typename Number>
800  inline typename ReadWriteVector<Number>::const_iterator
802  {
803  return values.get();
804  }
805 
806 
807 
808  template <typename Number>
809  inline typename ReadWriteVector<Number>::iterator
811  {
812  return values.get() + this->n_elements();
813  }
814 
815 
816 
817  template <typename Number>
818  inline typename ReadWriteVector<Number>::const_iterator
820  {
821  return values.get() + this->n_elements();
822  }
823 
824 
825 
826  template <typename Number>
827  inline Number
828  ReadWriteVector<Number>::operator()(const size_type global_index) const
829  {
830  return values[global_to_local(global_index)];
831  }
832 
833 
834 
835  template <typename Number>
836  inline Number &
837  ReadWriteVector<Number>::operator()(const size_type global_index)
838  {
839  return values[global_to_local(global_index)];
840  }
841 
842 
843 
844  template <typename Number>
845  inline Number ReadWriteVector<Number>::
846  operator[](const size_type global_index) const
847  {
848  return operator()(global_index);
849  }
850 
851 
852 
853  template <typename Number>
854  inline Number &ReadWriteVector<Number>::
855  operator[](const size_type global_index)
856  {
857  return operator()(global_index);
858  }
859 
860 
861 
862  template <typename Number>
863  template <typename Number2>
864  inline void
866  const std::vector<size_type> &indices,
867  std::vector<Number2> & extracted_values) const
868  {
869  for (size_type i = 0; i < indices.size(); ++i)
870  extracted_values[i] = operator()(indices[i]);
871  }
872 
873 
874 
875  template <typename Number>
876  template <typename ForwardIterator, typename OutputIterator>
877  inline void
879  ForwardIterator indices_begin,
880  const ForwardIterator indices_end,
881  OutputIterator values_begin) const
882  {
883  while (indices_begin != indices_end)
884  {
885  *values_begin = operator()(*indices_begin);
886  indices_begin++;
887  values_begin++;
888  }
889  }
890 
891 
892 
893  template <typename Number>
894  inline Number
895  ReadWriteVector<Number>::local_element(const size_type local_index) const
896  {
897  AssertIndexRange(local_index, this->n_elements());
898 
899  return values[local_index];
900  }
901 
902 
903 
904  template <typename Number>
905  inline Number &
906  ReadWriteVector<Number>::local_element(const size_type local_index)
907  {
908  AssertIndexRange(local_index, this->n_elements());
909 
910  return values[local_index];
911  }
912 
913 
914 
915  template <typename Number>
916  template <typename Number2>
917  inline void
918  ReadWriteVector<Number>::add(const std::vector<size_type> &indices,
919  const std::vector<Number2> & values)
920  {
921  AssertDimension(indices.size(), values.size());
922  add(indices.size(), indices.data(), values.data());
923  }
924 
925 
926 
927  template <typename Number>
928  template <typename Number2>
929  inline void
930  ReadWriteVector<Number>::add(const std::vector<size_type> & indices,
931  const ReadWriteVector<Number2> &values)
932  {
933  const size_type size = indices.size();
934  for (size_type i = 0; i < size; ++i)
935  {
936  Assert(
937  numbers::is_finite(values[i]),
938  ExcMessage(
939  "The given value is not finite but either infinite or Not A Number (NaN)"));
940  this->operator()(indices[i]) += values[indices[i]];
941  }
942  }
943 
944 
945 
946  template <typename Number>
947  template <typename Number2>
948  inline void
949  ReadWriteVector<Number>::add(const size_type n_indices,
950  const size_type *indices,
951  const Number2 * values_to_add)
952  {
953  for (size_type i = 0; i < n_indices; ++i)
954  {
955  Assert(
956  numbers::is_finite(values[i]),
957  ExcMessage(
958  "The given value is not finite but either infinite or Not A Number (NaN)"));
959  this->operator()(indices[i]) += values_to_add[i];
960  }
961  }
962 
963 
964 
965  template <typename Number>
966  template <typename Functor>
969  const Functor & functor)
970  : parent(parent)
971  , functor(functor)
972  {}
973 
974 
975 
976  template <typename Number>
977  template <typename Functor>
978  void
980  operator()(const size_type begin, const size_type end)
981  {
982  for (size_type i = begin; i < end; ++i)
983  functor(parent.values[i]);
984  }
985 
986 #endif // ifndef DOXYGEN
987 
988 } // end of namespace LinearAlgebra
989 
990 
991 
999 template <typename Number>
1000 inline void
1003 {
1004  u.swap(v);
1005 }
1006 
1007 
1008 DEAL_II_NAMESPACE_CLOSE
1009 
1010 #endif
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
void swap(ReadWriteVector< Number > &v)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1407
size_type n_elements() const
Definition: index_set.h:1743
void swap(LinearAlgebra::ReadWriteVector< Number > &u, LinearAlgebra::ReadWriteVector< Number > &v)
size_type size() const
Definition: index_set.h:1611
unsigned long long int global_dof_index
Definition: types.h:72
bool is_finite(const double x)
Definition: numbers.h:428
virtual void reinit(const size_type size, const bool omit_zeroing_entries=false)
Number operator[](const size_type global_index) const
std::unique_ptr< Number[], decltype(free)* > values
static::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1227
ReadWriteVector< Number > & operator=(const ReadWriteVector< Number > &in_vector)
unsigned int global_to_local(const types::global_dof_index global_index) const
void add(const std::vector< size_type > &indices, const std::vector< Number2 > &values)
Number operator()(const size_type global_index) const
virtual void operator()(const size_type begin, const size_type end)
std::shared_ptr< CommunicationPatternBase > comm_pattern
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1353
const IndexSet & get_stored_elements() const
size_type n_elements() const
Number local_element(const size_type local_index) const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< Number2 > &values) const
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner