Reference documentation for deal.II version 8.4.2
petsc_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_vector_h
17 #define dealii__petsc_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/petsc_vector_base.h>
27 # include <deal.II/lac/petsc_parallel_vector.h>
28 # include <deal.II/lac/vector.h>
29 
30 DEAL_II_NAMESPACE_OPEN
31 
32 
33 namespace PETScWrappers
34 {
53  class Vector : public VectorBase
54  {
55  public:
60 
71  static const bool supports_distributed_data = false;
72 
76  Vector ();
77 
88  explicit Vector (const size_type n);
89 
94  template <typename Number>
95  explicit Vector (const ::Vector<Number> &v);
96 
103  explicit Vector (const Vec &v);
104 
108  Vector (const Vector &v);
109 
119  explicit Vector (const MPI::Vector &v);
120 
125  void clear ();
126 
130  Vector &operator = (const Vector &v);
131 
140  Vector &operator = (const MPI::Vector &v);
141 
154  Vector &operator = (const PetscScalar s);
155 
160  template <typename number>
161  Vector &operator = (const ::Vector<number> &v);
162 
173  void reinit (const size_type N,
174  const bool omit_zeroing_entries = false);
175 
183  void reinit (const Vector &v,
184  const bool omit_zeroing_entries = false);
185 
186  protected:
191  void create_vector (const size_type n);
193 
196 // ------------------ template and inline functions -------------
197 
198 
207  inline
208  void swap (Vector &u, Vector &v)
209  {
210  u.swap (v);
211  }
212 
213 
214 #ifndef DOXYGEN
215 
216  template <typename number>
217  Vector::Vector (const ::Vector<number> &v)
218  {
219  Vector::create_vector (v.size());
220 
221  *this = v;
222  }
223 
224 
225 
226  inline
227  Vector::Vector (const Vec &v)
228  :
229  VectorBase(v)
230  {}
231 
232 
233  inline
234  Vector &
235  Vector::operator = (const PetscScalar s)
236  {
238 
239  return *this;
240  }
241 
242 
243  inline
244  Vector &
245  Vector::operator = (const Vector &v)
246  {
247  // if the vectors have different sizes,
248  // then first resize the present one
249  if (size() != v.size())
250  reinit (v.size(), true);
251 
252  const int ierr = VecCopy (v.vector, vector);
253  AssertThrow (ierr == 0, ExcPETScError(ierr));
254 
255  return *this;
256  }
257 
258 
259 
260  inline
261  Vector &
263  {
264  int ierr;
265  if (attained_ownership)
266  {
267  // the petsc function we call wants to
268  // generate the vector itself, so destroy
269  // the old one first
270 #if DEAL_II_PETSC_VERSION_LT(3,2,0)
271  ierr = VecDestroy (vector);
272 #else
273  ierr = VecDestroy (&vector);
274 #endif
275  AssertThrow (ierr == 0, ExcPETScError(ierr));
276  }
277 
278  attained_ownership = true;
279 
280  // then do the gather
281  // operation. <rant>petsc has changed its
282  // interface again, and replaced a single
283  // function call by several calls that
284  // are hard to understand. gets me all
285  // annoyed at their development
286  // model</rant>
287 #if DEAL_II_PETSC_VERSION_LT(2,2,0)
288  ierr = VecConvertMPIToSeqAll (static_cast<const Vec &>(v),
289  &vector);
290  AssertThrow (ierr == 0, ExcPETScError(ierr));
291 
292 #else
293 
294  VecScatter ctx;
295 
296  ierr = VecScatterCreateToAll (static_cast<const Vec &>(v), &ctx, &vector);
297  AssertThrow (ierr == 0, ExcPETScError(ierr));
298 
299 #if ((PETSC_VERSION_MAJOR == 2) && \
300  ((PETSC_VERSION_MINOR < 3) || \
301  ((PETSC_VERSION_MINOR == 3) && \
302  (PETSC_VERSION_SUBMINOR < 3))))
303  ierr = VecScatterBegin (static_cast<const Vec &>(v), vector,
304  INSERT_VALUES, SCATTER_FORWARD, ctx);
305  AssertThrow (ierr == 0, ExcPETScError(ierr));
306 
307  ierr = VecScatterEnd (static_cast<const Vec &>(v), vector,
308  INSERT_VALUES, SCATTER_FORWARD, ctx);
309 
310 #else
311 
312  ierr = VecScatterBegin (ctx,static_cast<const Vec &>(v), vector,
313  INSERT_VALUES, SCATTER_FORWARD);
314  AssertThrow (ierr == 0, ExcPETScError(ierr));
315 
316  ierr = VecScatterEnd (ctx, static_cast<const Vec &>(v), vector,
317  INSERT_VALUES, SCATTER_FORWARD);
318 
319 #endif
320  AssertThrow (ierr == 0, ExcPETScError(ierr));
321 
322 #if DEAL_II_PETSC_VERSION_LT(3,2,0)
323  ierr = VecScatterDestroy (ctx);
324 #else
325  ierr = VecScatterDestroy (&ctx);
326 #endif
327  AssertThrow (ierr == 0, ExcPETScError(ierr));
328 #endif
329 
330  return *this;
331  }
332 
333 
334 
335  template <typename number>
336  inline
337  Vector &
338  Vector::operator = (const ::Vector<number> &v)
339  {
340  reinit (v.size(), true);
341  // the following isn't necessarily fast,
342  // but this is due to the fact that PETSc
343  // doesn't offer an inlined access
344  // operator.
345  //
346  // if someone wants to contribute some
347  // code: to make this code faster, one
348  // could either first convert all values
349  // to PetscScalar, and then set them all
350  // at once using VecSetValues. This has
351  // the drawback that it could take quite
352  // some memory, if the vector is large,
353  // and it would in addition allocate
354  // memory on the heap, which is
355  // expensive. an alternative would be to
356  // split the vector into chunks of, say,
357  // 128 elements, convert a chunk at a
358  // time and set it in the output vector
359  // using VecSetValues. since 128 elements
360  // is small enough, this could easily be
361  // allocated on the stack (as a local
362  // variable) which would make the whole
363  // thing much more efficient.
364  //
365  // a second way to make things faster is
366  // for the special case that
367  // number==PetscScalar. we could then
368  // declare a specialization of this
369  // template, and omit the conversion. the
370  // problem with this is that the best we
371  // can do is to use VecSetValues, but
372  // this isn't very efficient either: it
373  // wants to see an array of indices,
374  // which in this case a) again takes up a
375  // whole lot of memory on the heap, and
376  // b) is totally dumb since its content
377  // would simply be the sequence
378  // 0,1,2,3,...,n. the best of all worlds
379  // would probably be a function in Petsc
380  // that would take a pointer to an array
381  // of PetscScalar values and simply copy
382  // n elements verbatim into the vector...
383  for (size_type i=0; i<v.size(); ++i)
384  (*this)(i) = v(i);
385 
386  compress (::VectorOperation::insert);
387 
388  return *this;
389  }
390 #endif // DOXYGEN
391 
392 }
393 
394 DEAL_II_NAMESPACE_CLOSE
395 
396 #endif // DEAL_II_WITH_PETSC
397 
398 /*---------------------------- petsc_vector.h ---------------------------*/
399 
400 #endif
401 /*---------------------------- petsc_vector.h ---------------------------*/
types::global_dof_index size_type
Definition: petsc_vector.h:59
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
VectorBase & operator=(const PetscScalar s)
Vector & operator=(const Vector &v)
BlockDynamicSparsityPattern BlockCompressedSparsityPattern DEAL_II_DEPRECATED
static const bool supports_distributed_data
Definition: petsc_vector.h:71
void compress(const VectorOperation::values operation)
unsigned int global_dof_index
Definition: types.h:88
void create_vector(const size_type n)
void swap(Vector &u, Vector &v)
Definition: petsc_vector.h:208
void reinit(const size_type N, const bool omit_zeroing_entries=false)
Definition: petsc_vector.cc:74