Reference documentation for deal.II version 8.4.2
petsc_parallel_vector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2016 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__petsc_parallel_vector_h
17 #define dealii__petsc_parallel_vector_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #ifdef DEAL_II_WITH_PETSC
23 
24 # include <deal.II/base/subscriptor.h>
25 # include <deal.II/lac/exceptions.h>
26 # include <deal.II/lac/vector.h>
27 # include <deal.II/lac/petsc_vector_base.h>
28 # include <deal.II/base/index_set.h>
29 
30 DEAL_II_NAMESPACE_OPEN
31 
32 
33 
34 // forward declaration
35 template <typename> class Vector;
36 class IndexSet;
37 
38 
42 namespace PETScWrappers
43 {
51  namespace MPI
52  {
53 
163  class Vector : public VectorBase
164  {
165  public:
170 
181  static const bool supports_distributed_data = true;
182 
186  Vector ();
187 
204  explicit Vector (const MPI_Comm &communicator,
205  const size_type n,
206  const size_type local_size);
207 
208 
219  template <typename Number>
220  explicit Vector (const MPI_Comm &communicator,
221  const ::Vector<Number> &v,
222  const size_type local_size);
223 
224 
234  explicit Vector (const MPI_Comm &communicator,
235  const VectorBase &v,
236  const size_type local_size);
237 
254  Vector (const IndexSet &local,
255  const IndexSet &ghost,
256  const MPI_Comm &communicator);
257 
262  explicit Vector (const IndexSet &local,
263  const MPI_Comm &communicator);
264 
269  void clear ();
270 
275  Vector &operator= (const Vector &v);
276 
293 
300  Vector &operator= (const PetscScalar s);
301 
311  template <typename number>
312  Vector &operator= (const ::Vector<number> &v);
313 
330  void reinit (const MPI_Comm &communicator,
331  const size_type N,
332  const size_type local_size,
333  const bool omit_zeroing_entries = false);
334 
344  void reinit (const Vector &v,
345  const bool omit_zeroing_entries = false);
346 
354  void reinit (const IndexSet &local,
355  const IndexSet &ghost,
356  const MPI_Comm &communicator);
357 
365  void reinit (const IndexSet &local,
366  const MPI_Comm &communicator);
367 
372  const MPI_Comm &get_mpi_communicator () const;
373 
385  void print (std::ostream &out,
386  const unsigned int precision = 3,
387  const bool scientific = true,
388  const bool across = true) const;
389 
396  bool all_zero () const;
397 
398  protected:
405  virtual void create_vector (const size_type n,
406  const size_type local_size);
407 
408 
409 
415  virtual void create_vector (const size_type n,
416  const size_type local_size,
417  const IndexSet &ghostnodes);
418 
419 
420  private:
424  MPI_Comm communicator;
425  };
426 
427 
428 // ------------------ template and inline functions -------------
429 
430 
439  inline
440  void swap (Vector &u, Vector &v)
441  {
442  u.swap (v);
443  }
444 
445 
446 #ifndef DOXYGEN
447 
448  template <typename number>
449  Vector::Vector (const MPI_Comm &communicator,
450  const ::Vector<number> &v,
451  const size_type local_size)
452  :
453  communicator (communicator)
454  {
455  Vector::create_vector (v.size(), local_size);
456 
457  *this = v;
458  }
459 
460 
461 
462  inline
463  Vector &
464  Vector::operator= (const PetscScalar s)
465  {
467 
468  return *this;
469  }
470 
471 
472 
473  inline
474  Vector &
475  Vector::operator= (const Vector &v)
476  {
477  // make sure left- and right-hand side of the assignment are compress()'ed:
478  Assert(v.last_action == VectorOperation::unknown,
479  internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
480  v.last_action));
481  Assert(last_action == VectorOperation::unknown,
482  internal::VectorReference::ExcWrongMode (VectorOperation::unknown,
483  last_action));
484 
485 
486  if (v.size()==0)
487  {
488  // this happens if v has not been initialized to something useful:
489  // Vector x,v;x=v;
490  // we skip the code below and create a simple serial vector of
491  // length 0
492 
493  int ierr;
494 #if DEAL_II_PETSC_VERSION_LT(3,2,0)
495  ierr = VecDestroy (vector);
496 #else
497  ierr = VecDestroy (&vector);
498 #endif
499  AssertThrow (ierr == 0, ExcPETScError(ierr));
500 
501  const int n = 0;
502  ierr = VecCreateSeq (PETSC_COMM_SELF, n, &vector);
503  AssertThrow (ierr == 0, ExcPETScError(ierr));
504  ghosted = false;
506  return *this;
507  }
508 
509  // if the vectors have different sizes,
510  // then first resize the present one
511  if (size() != v.size())
512  {
513  if (v.has_ghost_elements())
515  else
516  reinit (v.communicator, v.size(), v.local_size(), true);
517  }
518 
519  const int ierr = VecCopy (v.vector, vector);
520  AssertThrow (ierr == 0, ExcPETScError(ierr));
521 
522  if (has_ghost_elements())
523  {
524  int ierr;
525 
526  ierr = VecGhostUpdateBegin(vector, INSERT_VALUES, SCATTER_FORWARD);
527  AssertThrow (ierr == 0, ExcPETScError(ierr));
528  ierr = VecGhostUpdateEnd(vector, INSERT_VALUES, SCATTER_FORWARD);
529  AssertThrow (ierr == 0, ExcPETScError(ierr));
530  }
531  return *this;
532  }
533 
534 
535 
536  template <typename number>
537  inline
538  Vector &
539  Vector::operator= (const ::Vector<number> &v)
540  {
541  Assert (size() == v.size(),
542  ExcDimensionMismatch (size(), v.size()));
543 
544  // FIXME: the following isn't necessarily fast, but this is due to
545  // the fact that PETSc doesn't offer an inlined access operator.
546  //
547  // if someone wants to contribute some code: to make this code
548  // faster, one could either first convert all values to PetscScalar,
549  // and then set them all at once using VecSetValues. This has the
550  // drawback that it could take quite some memory, if the vector is
551  // large, and it would in addition allocate memory on the heap, which
552  // is expensive. an alternative would be to split the vector into
553  // chunks of, say, 128 elements, convert a chunk at a time and set it
554  // in the output vector using VecSetValues. since 128 elements is
555  // small enough, this could easily be allocated on the stack (as a
556  // local variable) which would make the whole thing much more
557  // efficient.
558  //
559  // a second way to make things faster is for the special case that
560  // number==PetscScalar. we could then declare a specialization of
561  // this template, and omit the conversion. the problem with this is
562  // that the best we can do is to use VecSetValues, but this isn't
563  // very efficient either: it wants to see an array of indices, which
564  // in this case a) again takes up a whole lot of memory on the heap,
565  // and b) is totally dumb since its content would simply be the
566  // sequence 0,1,2,3,...,n. the best of all worlds would probably be a
567  // function in Petsc that would take a pointer to an array of
568  // PetscScalar values and simply copy n elements verbatim into the
569  // vector...
570  for (size_type i=0; i<v.size(); ++i)
571  (*this)(i) = v(i);
572 
573  compress (::VectorOperation::insert);
574 
575  return *this;
576  }
577 
578 
579 
580  inline
581  const MPI_Comm &
583  {
584  return communicator;
585  }
586 
587 #endif // DOXYGEN
588  }
589 }
590 
593 DEAL_II_NAMESPACE_CLOSE
594 
595 #endif // DEAL_II_WITH_PETSC
596 
597 /*---------------------------- petsc_parallel_vector.h ---------------------------*/
598 
599 #endif
600 /*---------------------------- petsc_parallel_vector.h ---------------------------*/
types::global_dof_index size_type
Vector & operator=(const Vector &v)
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
VectorBase & operator=(const PetscScalar s)
void clear()
Definition: index_set.h:1223
void compress(const VectorOperation::values operation)
unsigned int global_dof_index
Definition: types.h:88
VectorOperation::values last_action
#define Assert(cond, exc)
Definition: exceptions.h:294
static const bool supports_distributed_data
const MPI_Comm & get_mpi_communicator() const
bool has_ghost_elements() const
void reinit(const MPI_Comm &communicator, const size_type N, const size_type local_size, const bool omit_zeroing_entries=false)
IndexSet locally_owned_elements() const
virtual void create_vector(const size_type n, const size_type local_size)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
void swap(Vector &u, Vector &v)