Reference documentation for deal.II version 9.0.0
petsc_parallel_block_vector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 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_petsc_parallel_block_vector_h
17 #define dealii_petsc_parallel_block_vector_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #ifdef DEAL_II_WITH_PETSC
23 
24 # include <deal.II/lac/petsc_parallel_vector.h>
25 # include <deal.II/lac/block_indices.h>
26 # include <deal.II/lac/block_vector_base.h>
27 # include <deal.II/lac/exceptions.h>
28 # include <deal.II/lac/vector_type_traits.h>
29 
30 DEAL_II_NAMESPACE_OPEN
31 
32 
33 namespace PETScWrappers
34 {
35  // forward declaration
36  class BlockVector;
37 
38  namespace MPI
39  {
40 
62  class BlockVector : public BlockVectorBase<Vector>
63  {
64  public:
69 
74 
78  typedef BaseClass::value_type value_type;
79  typedef BaseClass::pointer pointer;
80  typedef BaseClass::const_pointer const_pointer;
81  typedef BaseClass::reference reference;
82  typedef BaseClass::const_reference const_reference;
83  typedef BaseClass::size_type size_type;
86 
90  BlockVector () = default;
91 
98  explicit BlockVector (const unsigned int n_blocks,
99  const MPI_Comm &communicator,
100  const size_type block_size,
101  const size_type local_size);
102 
107  BlockVector (const BlockVector &V);
108 
116  BlockVector (const std::vector<size_type> &block_sizes,
117  const MPI_Comm &communicator,
118  const std::vector<size_type> &local_elements);
119 
124  explicit BlockVector (const std::vector<IndexSet> &parallel_partitioning,
125  const MPI_Comm &communicator = MPI_COMM_WORLD);
126 
130  BlockVector (const std::vector<IndexSet> &parallel_partitioning,
131  const std::vector<IndexSet> &ghost_indices,
132  const MPI_Comm &communicator);
133 
134 
135 
139  ~BlockVector () = default;
140 
146 
150  BlockVector &
151  operator= (const BlockVector &V);
152 
162  void reinit (const unsigned int n_blocks,
163  const MPI_Comm &communicator,
164  const size_type block_size,
165  const size_type local_size,
166  const bool omit_zeroing_entries = false);
167 
188  void reinit (const std::vector<size_type> &block_sizes,
189  const MPI_Comm &communicator,
190  const std::vector<size_type> &local_sizes,
191  const bool omit_zeroing_entries=false);
192 
207  void reinit (const BlockVector &V,
208  const bool omit_zeroing_entries=false);
209 
214  void reinit (const std::vector<IndexSet> &parallel_partitioning,
215  const MPI_Comm &communicator);
216 
220  void reinit (const std::vector<IndexSet> &parallel_partitioning,
221  const std::vector<IndexSet> &ghost_entries,
222  const MPI_Comm &communicator);
223 
230  void reinit (const unsigned int num_blocks);
231 
235  bool has_ghost_elements() const;
236 
241  const MPI_Comm &get_mpi_communicator () const;
242 
260  void swap (BlockVector &v);
261 
265  void print (std::ostream &out,
266  const unsigned int precision = 3,
267  const bool scientific = true,
268  const bool across = true) const;
269 
278  };
279 
282  /*----------------------- Inline functions ----------------------------------*/
283 
284  inline
285  BlockVector::BlockVector (const unsigned int n_blocks,
286  const MPI_Comm &communicator,
287  const size_type block_size,
288  const size_type local_size)
289  {
290  reinit (n_blocks, communicator, block_size, local_size);
291  }
292 
293 
294 
295  inline
296  BlockVector::BlockVector (const std::vector<size_type> &block_sizes,
297  const MPI_Comm &communicator,
298  const std::vector<size_type> &local_elements)
299  {
300  reinit (block_sizes, communicator, local_elements, false);
301  }
302 
303 
304  inline
306  :
308  {
309  this->components.resize (v.n_blocks());
310  this->block_indices = v.block_indices;
311 
312  for (unsigned int i=0; i<this->n_blocks(); ++i)
313  this->components[i] = v.components[i];
314  }
315 
316  inline
317  BlockVector::BlockVector (const std::vector<IndexSet> &parallel_partitioning,
318  const MPI_Comm &communicator)
319  {
320  reinit(parallel_partitioning, communicator);
321  }
322 
323  inline
324  BlockVector::BlockVector (const std::vector<IndexSet> &parallel_partitioning,
325  const std::vector<IndexSet> &ghost_indices,
326  const MPI_Comm &communicator)
327  {
328  reinit(parallel_partitioning, ghost_indices, communicator);
329  }
330 
331  inline
332  BlockVector &
334  {
336  return *this;
337  }
338 
339  inline
340  BlockVector &
342  {
343  // we only allow assignment to vectors with the same number of blocks
344  // or to an empty BlockVector
345  Assert (n_blocks() == 0 || n_blocks() == v.n_blocks(),
347 
348  if (this->n_blocks() != v.n_blocks())
349  reinit(v.n_blocks());
350 
351  for (size_type i=0; i<this->n_blocks(); ++i)
352  this->components[i] = v.block(i);
353 
354  collect_sizes();
355 
356  return *this;
357  }
358 
359 
360 
361  inline
362  void
363  BlockVector::reinit (const unsigned int n_blocks,
364  const MPI_Comm &communicator,
365  const size_type block_size,
366  const size_type local_size,
367  const bool omit_zeroing_entries)
368  {
369  reinit(std::vector<size_type>(n_blocks, block_size),
370  communicator,
371  std::vector<size_type>(n_blocks, local_size),
372  omit_zeroing_entries);
373  }
374 
375 
376 
377  inline
378  void
379  BlockVector::reinit (const std::vector<size_type> &block_sizes,
380  const MPI_Comm &communicator,
381  const std::vector<size_type> &local_sizes,
382  const bool omit_zeroing_entries)
383  {
384  this->block_indices.reinit (block_sizes);
385  if (this->components.size() != this->n_blocks())
386  this->components.resize(this->n_blocks());
387 
388  for (unsigned int i=0; i<this->n_blocks(); ++i)
389  this->components[i].reinit(communicator, block_sizes[i],
390  local_sizes[i], omit_zeroing_entries);
391  }
392 
393 
394  inline
395  void
397  const bool omit_zeroing_entries)
398  {
399  this->block_indices = v.get_block_indices();
400  if (this->components.size() != this->n_blocks())
401  this->components.resize(this->n_blocks());
402 
403  for (unsigned int i=0; i<this->n_blocks(); ++i)
404  block(i).reinit(v.block(i), omit_zeroing_entries);
405  }
406 
407  inline
408  void
409  BlockVector::reinit (const std::vector<IndexSet> &parallel_partitioning,
410  const MPI_Comm &communicator)
411  {
412  std::vector<size_type> sizes(parallel_partitioning.size());
413  for (unsigned int i=0; i<parallel_partitioning.size(); ++i)
414  sizes[i] = parallel_partitioning[i].size();
415 
416  this->block_indices.reinit(sizes);
417  if (this->components.size() != this->n_blocks())
418  this->components.resize(this->n_blocks());
419 
420  for (unsigned int i=0; i<this->n_blocks(); ++i)
421  block(i).reinit(parallel_partitioning[i], communicator);
422  }
423 
424  inline
425  void
426  BlockVector::reinit (const std::vector<IndexSet> &parallel_partitioning,
427  const std::vector<IndexSet> &ghost_entries,
428  const MPI_Comm &communicator)
429  {
430  std::vector<types::global_dof_index> sizes(parallel_partitioning.size());
431  for (unsigned int i=0; i<parallel_partitioning.size(); ++i)
432  sizes[i] = parallel_partitioning[i].size();
433 
434  this->block_indices.reinit(sizes);
435  if (this->components.size() != this->n_blocks())
436  this->components.resize(this->n_blocks());
437 
438  for (unsigned int i=0; i<this->n_blocks(); ++i)
439  block(i).reinit(parallel_partitioning[i], ghost_entries[i], communicator);
440  }
441 
442 
443 
444  inline
445  const MPI_Comm &
447  {
448  return block(0).get_mpi_communicator();
449  }
450 
451  inline
452  bool
454  {
455  bool ghosted=block(0).has_ghost_elements();
456 #ifdef DEBUG
457  for (unsigned int i=0; i<this->n_blocks(); ++i)
458  Assert(block(i).has_ghost_elements()==ghosted, ExcInternalError());
459 #endif
460  return ghosted;
461  }
462 
463 
464  inline
465  void
467  {
468  std::swap(this->components, v.components);
469 
471  }
472 
473 
474 
475  inline
476  void
477  BlockVector::print (std::ostream &out,
478  const unsigned int precision,
479  const bool scientific,
480  const bool across) const
481  {
482  for (unsigned int i=0; i<this->n_blocks(); ++i)
483  {
484  if (across)
485  out << 'C' << i << ':';
486  else
487  out << "Component " << i << std::endl;
488  this->components[i].print(out, precision, scientific, across);
489  }
490  }
491 
492 
493 
502  inline
503  void swap (BlockVector &u,
504  BlockVector &v)
505  {
506  u.swap (v);
507  }
508 
509  }
510 
511 }
512 
513 namespace internal
514 {
515  namespace LinearOperatorImplementation
516  {
517  template <typename> class ReinitHelper;
518 
523  template <>
524  class ReinitHelper<PETScWrappers::MPI::BlockVector>
525  {
526  public:
527  template <typename Matrix>
528  static
529  void reinit_range_vector (const Matrix &matrix,
531  bool /*omit_zeroing_entries*/)
532  {
533  v.reinit(matrix.locally_owned_range_indices(), matrix.get_mpi_communicator());
534  }
535 
536  template <typename Matrix>
537  static
538  void reinit_domain_vector(const Matrix &matrix,
540  bool /*omit_zeroing_entries*/)
541  {
542  v.reinit(matrix.locally_owned_domain_indices(), matrix.get_mpi_communicator());
543  }
544  };
545 
546  } /* namespace LinearOperator */
547 } /* namespace internal */
548 
549 
555 template <>
556 struct is_serial_vector< PETScWrappers::MPI::BlockVector > : std::false_type
557 {
558 };
559 
560 
561 DEAL_II_NAMESPACE_CLOSE
562 
563 #endif // DEAL_II_WITH_PETSC
564 
565 #endif
void reinit(const unsigned int n_blocks, const MPI_Comm &communicator, const size_type block_size, const size_type local_size, const bool omit_zeroing_entries=false)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
static ::ExceptionBase & ExcIteratorRangeDoesNotMatchVectorSize()
static void reinit_range_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
static ::ExceptionBase & ExcNonMatchingBlockVectors()
static void reinit_domain_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
void swap(BlockVector &u, BlockVector &v)
std::size_t size() const
const BlockIndices & get_block_indices() const
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const unsigned int n_blocks, const size_type n_elements_per_block)
#define DeclException0(Exception0)
Definition: exceptions.h:323
std::vector< Vector > components
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1312
unsigned int n_blocks() const
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
BlockVector & operator=(const value_type s)
BlockType & block(const unsigned int i)
BlockVectorBase & operator=(const value_type s)
static ::ExceptionBase & ExcInternalError()