Reference documentation for deal.II version 9.1.0-pre
petsc_vector_base.cc
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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/lac/petsc_vector_base.h>
17 
18 #ifdef DEAL_II_WITH_PETSC
19 
20 # include <deal.II/base/memory_consumption.h>
21 # include <deal.II/base/multithread_info.h>
22 
23 # include <deal.II/lac/exceptions.h>
24 # include <deal.II/lac/petsc_compatibility.h>
25 # include <deal.II/lac/petsc_vector.h>
26 
27 # include <cmath>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 namespace PETScWrappers
32 {
33  namespace internal
34  {
35  VectorReference::operator PetscScalar() const
36  {
37  Assert(index < vector.size(), ExcIndexRange(index, 0, vector.size()));
38 
39  // The vector may have ghost entries. In that case, we first need to
40  // figure out which elements we own locally, then get a pointer to the
41  // elements that are stored here (both the ones we own as well as the
42  // ghost elements). In this array, the locally owned elements come first
43  // followed by the ghost elements whose position we can get from an
44  // index set.
45  if (vector.ghosted)
46  {
47  PetscInt begin, end;
48  PetscErrorCode ierr =
49  VecGetOwnershipRange(vector.vector, &begin, &end);
50  AssertThrow(ierr == 0, ExcPETScError(ierr));
51 
52  Vec locally_stored_elements = PETSC_NULL;
53  ierr = VecGhostGetLocalForm(vector.vector, &locally_stored_elements);
54  AssertThrow(ierr == 0, ExcPETScError(ierr));
55 
56  PetscInt lsize;
57  ierr = VecGetSize(locally_stored_elements, &lsize);
58  AssertThrow(ierr == 0, ExcPETScError(ierr));
59 
60  PetscScalar *ptr;
61  ierr = VecGetArray(locally_stored_elements, &ptr);
62  AssertThrow(ierr == 0, ExcPETScError(ierr));
63 
64  PetscScalar value;
65 
66  if (index >= static_cast<size_type>(begin) &&
67  index < static_cast<size_type>(end))
68  {
69  // local entry
70  value = *(ptr + index - begin);
71  }
72  else
73  {
74  // ghost entry
75  const size_type ghostidx =
76  vector.ghost_indices.index_within_set(index);
77 
78  Assert(ghostidx + end - begin < (size_type)lsize,
80  value = *(ptr + ghostidx + end - begin);
81  }
82 
83  ierr = VecRestoreArray(locally_stored_elements, &ptr);
84  AssertThrow(ierr == 0, ExcPETScError(ierr));
85 
86  ierr =
87  VecGhostRestoreLocalForm(vector.vector, &locally_stored_elements);
88  AssertThrow(ierr == 0, ExcPETScError(ierr));
89 
90  return value;
91  }
92 
93 
94  // first verify that the requested
95  // element is actually locally
96  // available
97  PetscInt begin, end;
98 
99  PetscErrorCode ierr = VecGetOwnershipRange(vector.vector, &begin, &end);
100  AssertThrow(ierr == 0, ExcPETScError(ierr));
101 
102  AssertThrow((index >= static_cast<size_type>(begin)) &&
103  (index < static_cast<size_type>(end)),
104  ExcAccessToNonlocalElement(index, begin, end - 1));
105 
106  PetscInt idx = index;
107  PetscScalar value;
108  ierr = VecGetValues(vector.vector, 1, &idx, &value);
109  AssertThrow(ierr == 0, ExcPETScError(ierr));
110 
111  return value;
112  }
113  } // namespace internal
114 
116  : vector(nullptr)
117  , ghosted(false)
118  , last_action(::VectorOperation::unknown)
119  , obtained_ownership(true)
120  {
122  ExcMessage("PETSc does not support multi-threaded access, set "
123  "the thread limit to 1 in MPI_InitFinalize()."));
124  }
125 
126 
127 
129  : Subscriptor()
130  , ghosted(v.ghosted)
132  , last_action(::VectorOperation::unknown)
133  , obtained_ownership(true)
134  {
136  ExcMessage("PETSc does not support multi-threaded access, set "
137  "the thread limit to 1 in MPI_InitFinalize()."));
138 
139  PetscErrorCode ierr = VecDuplicate(v.vector, &vector);
140  AssertThrow(ierr == 0, ExcPETScError(ierr));
141 
142  ierr = VecCopy(v.vector, vector);
143  AssertThrow(ierr == 0, ExcPETScError(ierr));
144  }
145 
146 
147 
149  : Subscriptor()
150  , vector(v)
151  , ghosted(false)
152  , last_action(::VectorOperation::unknown)
153  , obtained_ownership(false)
154  {
156  ExcMessage("PETSc does not support multi-threaded access, set "
157  "the thread limit to 1 in MPI_InitFinalize()."));
158  }
159 
160 
161 
163  {
164  if (obtained_ownership)
165  {
166  const PetscErrorCode ierr = VecDestroy(&vector);
167  AssertNothrow(ierr == 0, ExcPETScError(ierr));
168  (void)ierr;
169  }
170  }
171 
172 
173 
174  void
176  {
177  if (obtained_ownership)
178  {
179  const PetscErrorCode ierr = VecDestroy(&vector);
180  AssertThrow(ierr == 0, ExcPETScError(ierr));
181  }
182 
183  ghosted = false;
186  obtained_ownership = true;
187  }
188 
189 
190 
191  VectorBase &
192  VectorBase::operator=(const PetscScalar s)
193  {
194  AssertIsFinite(s);
195 
196  // TODO[TH]: assert(is_compressed())
197 
198  PetscErrorCode ierr = VecSet(vector, s);
199  AssertThrow(ierr == 0, ExcPETScError(ierr));
200 
201  if (has_ghost_elements())
202  {
203  Vec ghost = PETSC_NULL;
204  ierr = VecGhostGetLocalForm(vector, &ghost);
205  AssertThrow(ierr == 0, ExcPETScError(ierr));
206 
207  ierr = VecSet(ghost, s);
208  AssertThrow(ierr == 0, ExcPETScError(ierr));
209 
210  ierr = VecGhostRestoreLocalForm(vector, &ghost);
211  AssertThrow(ierr == 0, ExcPETScError(ierr));
212  }
213 
214  return *this;
215  }
216 
217 
218 
219  bool
221  {
222  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
223 
224  PetscBool flag;
225  const PetscErrorCode ierr = VecEqual(vector, v.vector, &flag);
226  AssertThrow(ierr == 0, ExcPETScError(ierr));
227 
228  return (flag == PETSC_TRUE);
229  }
230 
231 
232 
233  bool
235  {
236  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
237 
238  PetscBool flag;
239  const PetscErrorCode ierr = VecEqual(vector, v.vector, &flag);
240  AssertThrow(ierr == 0, ExcPETScError(ierr));
241 
242  return (flag == PETSC_FALSE);
243  }
244 
245 
246 
247  VectorBase::size_type
249  {
250  PetscInt sz;
251  const PetscErrorCode ierr = VecGetSize(vector, &sz);
252  AssertThrow(ierr == 0, ExcPETScError(ierr));
253 
254  return sz;
255  }
256 
257 
258 
259  VectorBase::size_type
261  {
262  PetscInt sz;
263  const PetscErrorCode ierr = VecGetLocalSize(vector, &sz);
264  AssertThrow(ierr == 0, ExcPETScError(ierr));
265 
266  return sz;
267  }
268 
269 
270 
271  std::pair<VectorBase::size_type, VectorBase::size_type>
273  {
274  PetscInt begin, end;
275  const PetscErrorCode ierr =
276  VecGetOwnershipRange(static_cast<const Vec &>(vector), &begin, &end);
277  AssertThrow(ierr == 0, ExcPETScError(ierr));
278 
279  return std::make_pair(begin, end);
280  }
281 
282 
283 
284  void
285  VectorBase::set(const std::vector<size_type> & indices,
286  const std::vector<PetscScalar> &values)
287  {
288  Assert(indices.size() == values.size(),
289  ExcMessage("Function called with arguments of different sizes"));
290  do_set_add_operation(indices.size(), indices.data(), values.data(), false);
291  }
292 
293 
294 
295  void
296  VectorBase::add(const std::vector<size_type> & indices,
297  const std::vector<PetscScalar> &values)
298  {
299  Assert(indices.size() == values.size(),
300  ExcMessage("Function called with arguments of different sizes"));
301  do_set_add_operation(indices.size(), indices.data(), values.data(), true);
302  }
303 
304 
305 
306  void
307  VectorBase::add(const std::vector<size_type> & indices,
308  const ::Vector<PetscScalar> &values)
309  {
310  Assert(indices.size() == values.size(),
311  ExcMessage("Function called with arguments of different sizes"));
312  do_set_add_operation(indices.size(), indices.data(), values.begin(), true);
313  }
314 
315 
316 
317  void
318  VectorBase::add(const size_type n_elements,
319  const size_type * indices,
320  const PetscScalar *values)
321  {
322  do_set_add_operation(n_elements, indices, values, true);
323  }
324 
325 
326 
327  PetscScalar VectorBase::operator*(const VectorBase &vec) const
328  {
329  Assert(size() == vec.size(), ExcDimensionMismatch(size(), vec.size()));
330 
331  PetscScalar result;
332 
333  // For complex vectors, VecDot() computes
334  // val = (x,y) = y^H x,
335  // where y^H denotes the conjugate transpose of y.
336  // Note that this corresponds to the usual "mathematicians'"
337  // complex inner product where the SECOND argument gets the
338  // complex conjugate, which is also how we document this
339  // operation.
340  const PetscErrorCode ierr = VecDot(vec.vector, vector, &result);
341  AssertThrow(ierr == 0, ExcPETScError(ierr));
342 
343  return result;
344  }
345 
346 
347 
348  PetscScalar
349  VectorBase::add_and_dot(const PetscScalar a,
350  const VectorBase &V,
351  const VectorBase &W)
352  {
353  this->add(a, V);
354  return *this * W;
355  }
356 
357 
358 
359  void
361  {
362  {
363 # ifdef DEBUG
364 # ifdef DEAL_II_WITH_MPI
365  // Check that all processors agree that last_action is the same (or none!)
366 
367  int my_int_last_action = last_action;
368  int all_int_last_action;
369 
370  const int ierr = MPI_Allreduce(&my_int_last_action,
371  &all_int_last_action,
372  1,
373  MPI_INT,
374  MPI_BOR,
376  AssertThrowMPI(ierr);
377 
378  AssertThrow(all_int_last_action != (::VectorOperation::add |
380  ExcMessage("Error: not all processors agree on the last "
381  "VectorOperation before this compress() call."));
382 # endif
383 # endif
384  }
385 
386  AssertThrow(
388  last_action == operation,
389  ExcMessage(
390  "Missing compress() or calling with wrong VectorOperation argument."));
391 
392  // note that one may think that
393  // we only need to do something
394  // if in fact the state is
395  // anything but
396  // last_action::unknown. but
397  // that's not true: one
398  // frequently gets into
399  // situations where only one
400  // processor (or a subset of
401  // processors) actually writes
402  // something into a vector, but
403  // we still need to call
404  // VecAssemblyBegin/End on all
405  // processors.
406  PetscErrorCode ierr = VecAssemblyBegin(vector);
407  AssertThrow(ierr == 0, ExcPETScError(ierr));
408  ierr = VecAssemblyEnd(vector);
409  AssertThrow(ierr == 0, ExcPETScError(ierr));
410 
411  // reset the last action field to
412  // indicate that we're back to a
413  // pristine state
415  }
416 
417 
418 
419  VectorBase::real_type
421  {
422  const real_type d = l2_norm();
423  return d * d;
424  }
425 
426 
427 
428  PetscScalar
430  {
431  // We can only use our more efficient
432  // routine in the serial case.
433  if (dynamic_cast<const PETScWrappers::MPI::Vector *>(this) != nullptr)
434  {
435  PetscScalar sum;
436  const PetscErrorCode ierr = VecSum(vector, &sum);
437  AssertThrow(ierr == 0, ExcPETScError(ierr));
438  return sum / static_cast<PetscReal>(size());
439  }
440 
441  // get a representation of the vector and
442  // loop over all the elements
443  PetscScalar * start_ptr;
444  PetscErrorCode ierr = VecGetArray(vector, &start_ptr);
445  AssertThrow(ierr == 0, ExcPETScError(ierr));
446 
447  PetscScalar mean = 0;
448  {
449  PetscScalar sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
450 
451  // use modern processors better by
452  // allowing pipelined commands to be
453  // executed in parallel
454  const PetscScalar *ptr = start_ptr;
455  const PetscScalar *eptr = ptr + (size() / 4) * 4;
456  while (ptr != eptr)
457  {
458  sum0 += *ptr++;
459  sum1 += *ptr++;
460  sum2 += *ptr++;
461  sum3 += *ptr++;
462  };
463  // add up remaining elements
464  while (ptr != start_ptr + size())
465  sum0 += *ptr++;
466 
467  mean = (sum0 + sum1 + sum2 + sum3) / static_cast<PetscReal>(size());
468  }
469 
470  // restore the representation of the
471  // vector
472  ierr = VecRestoreArray(vector, &start_ptr);
473  AssertThrow(ierr == 0, ExcPETScError(ierr));
474 
475  return mean;
476  }
477 
478 
479  VectorBase::real_type
481  {
482  real_type d;
483 
484  const PetscErrorCode ierr = VecNorm(vector, NORM_1, &d);
485  AssertThrow(ierr == 0, ExcPETScError(ierr));
486 
487  return d;
488  }
489 
490 
491 
492  VectorBase::real_type
494  {
495  real_type d;
496 
497  const PetscErrorCode ierr = VecNorm(vector, NORM_2, &d);
498  AssertThrow(ierr == 0, ExcPETScError(ierr));
499 
500  return d;
501  }
502 
503 
504 
505  VectorBase::real_type
506  VectorBase::lp_norm(const real_type p) const
507  {
508  // get a representation of the vector and
509  // loop over all the elements
510  PetscScalar * start_ptr;
511  PetscErrorCode ierr = VecGetArray(vector, &start_ptr);
512  AssertThrow(ierr == 0, ExcPETScError(ierr));
513 
514  real_type norm = 0;
515  {
516  real_type sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
517 
518  // use modern processors better by
519  // allowing pipelined commands to be
520  // executed in parallel
521  const PetscScalar *ptr = start_ptr;
522  const PetscScalar *eptr = ptr + (size() / 4) * 4;
523  while (ptr != eptr)
524  {
525  sum0 += std::pow(numbers::NumberTraits<value_type>::abs(*ptr++), p);
526  sum1 += std::pow(numbers::NumberTraits<value_type>::abs(*ptr++), p);
527  sum2 += std::pow(numbers::NumberTraits<value_type>::abs(*ptr++), p);
528  sum3 += std::pow(numbers::NumberTraits<value_type>::abs(*ptr++), p);
529  }
530  // add up remaining elements
531  while (ptr != start_ptr + size())
532  sum0 += std::pow(numbers::NumberTraits<value_type>::abs(*ptr++), p);
533 
534  norm = std::pow(sum0 + sum1 + sum2 + sum3, 1. / p);
535  }
536 
537  // restore the representation of the
538  // vector
539  ierr = VecRestoreArray(vector, &start_ptr);
540  AssertThrow(ierr == 0, ExcPETScError(ierr));
541 
542  return norm;
543  }
544 
545 
546 
547  VectorBase::real_type
549  {
550  real_type d;
551 
552  const PetscErrorCode ierr = VecNorm(vector, NORM_INFINITY, &d);
553  AssertThrow(ierr == 0, ExcPETScError(ierr));
554 
555  return d;
556  }
557 
558 
559 
560  VectorBase::real_type
562  {
563  PetscInt p;
564  real_type d;
565 
566  const PetscErrorCode ierr = VecMin(vector, &p, &d);
567  AssertThrow(ierr == 0, ExcPETScError(ierr));
568 
569  return d;
570  }
571 
572 
573  VectorBase::real_type
575  {
576  PetscInt p;
577  real_type d;
578 
579  const PetscErrorCode ierr = VecMax(vector, &p, &d);
580  AssertThrow(ierr == 0, ExcPETScError(ierr));
581 
582  return d;
583  }
584 
585 
586 
587  bool
589  {
590  // get a representation of the vector and
591  // loop over all the elements
592  PetscScalar * start_ptr;
593  PetscErrorCode ierr = VecGetArray(vector, &start_ptr);
594  AssertThrow(ierr == 0, ExcPETScError(ierr));
595 
596  const PetscScalar *ptr = start_ptr, *eptr = start_ptr + local_size();
597  bool flag = true;
598  while (ptr != eptr)
599  {
600  if (*ptr != value_type())
601  {
602  flag = false;
603  break;
604  }
605  ++ptr;
606  }
607 
608  // restore the representation of the
609  // vector
610  ierr = VecRestoreArray(vector, &start_ptr);
611  AssertThrow(ierr == 0, ExcPETScError(ierr));
612 
613  return flag;
614  }
615 
616 
617  namespace internal
618  {
619  template <typename T>
620  bool
621  is_non_negative(const T &t)
622  {
623  return t >= 0;
624  }
625 
626 
627 
628  template <typename T>
629  bool
630  is_non_negative(const std::complex<T> &)
631  {
632  Assert(false,
633  ExcMessage("You can't ask a complex value "
634  "whether it is non-negative.")) return true;
635  }
636  } // namespace internal
637 
638 
639 
640  bool
642  {
643  // get a representation of the vector and
644  // loop over all the elements
645  PetscScalar * start_ptr;
646  PetscErrorCode ierr = VecGetArray(vector, &start_ptr);
647  AssertThrow(ierr == 0, ExcPETScError(ierr));
648 
649  const PetscScalar *ptr = start_ptr, *eptr = start_ptr + local_size();
650  bool flag = true;
651  while (ptr != eptr)
652  {
653  if (!internal::is_non_negative(*ptr))
654  {
655  flag = false;
656  break;
657  }
658  ++ptr;
659  }
660 
661  // restore the representation of the
662  // vector
663  ierr = VecRestoreArray(vector, &start_ptr);
664  AssertThrow(ierr == 0, ExcPETScError(ierr));
665 
666  return flag;
667  }
668 
669 
670 
671  VectorBase &
672  VectorBase::operator*=(const PetscScalar a)
673  {
675  AssertIsFinite(a);
676 
677  const PetscErrorCode ierr = VecScale(vector, a);
678  AssertThrow(ierr == 0, ExcPETScError(ierr));
679 
680  return *this;
681  }
682 
683 
684 
685  VectorBase &
686  VectorBase::operator/=(const PetscScalar a)
687  {
689  AssertIsFinite(a);
690 
691  const PetscScalar factor = 1. / a;
692  AssertIsFinite(factor);
693 
694  const PetscErrorCode ierr = VecScale(vector, factor);
695  AssertThrow(ierr == 0, ExcPETScError(ierr));
696 
697  return *this;
698  }
699 
700 
701 
702  VectorBase &
704  {
706  const PetscErrorCode ierr = VecAXPY(vector, 1, v);
707  AssertThrow(ierr == 0, ExcPETScError(ierr));
708 
709  return *this;
710  }
711 
712 
713 
714  VectorBase &
716  {
718  const PetscErrorCode ierr = VecAXPY(vector, -1, v);
719  AssertThrow(ierr == 0, ExcPETScError(ierr));
720 
721  return *this;
722  }
723 
724 
725 
726  void
727  VectorBase::add(const PetscScalar s)
728  {
730  AssertIsFinite(s);
731 
732  const PetscErrorCode ierr = VecShift(vector, s);
733  AssertThrow(ierr == 0, ExcPETScError(ierr));
734  }
735 
736 
737 
738  void
739  VectorBase::add(const PetscScalar a, const VectorBase &v)
740  {
742  AssertIsFinite(a);
743 
744  const PetscErrorCode ierr = VecAXPY(vector, a, v);
745  AssertThrow(ierr == 0, ExcPETScError(ierr));
746  }
747 
748 
749 
750  void
751  VectorBase::add(const PetscScalar a,
752  const VectorBase &v,
753  const PetscScalar b,
754  const VectorBase &w)
755  {
757  AssertIsFinite(a);
758  AssertIsFinite(b);
759 
760  const PetscScalar weights[2] = {a, b};
761  Vec addends[2] = {v.vector, w.vector};
762 
763  const PetscErrorCode ierr = VecMAXPY(vector, 2, weights, addends);
764  AssertThrow(ierr == 0, ExcPETScError(ierr));
765  }
766 
767 
768 
769  void
770  VectorBase::sadd(const PetscScalar s, const VectorBase &v)
771  {
773  AssertIsFinite(s);
774 
775  const PetscErrorCode ierr = VecAYPX(vector, s, v);
776  AssertThrow(ierr == 0, ExcPETScError(ierr));
777  }
778 
779 
780 
781  void
782  VectorBase::sadd(const PetscScalar s,
783  const PetscScalar a,
784  const VectorBase &v)
785  {
787  AssertIsFinite(s);
788  AssertIsFinite(a);
789 
790  // there is nothing like a AXPAY
791  // operation in Petsc, so do it in two
792  // steps
793  *this *= s;
794  add(a, v);
795  }
796 
797 
798 
799  void
801  {
803  const PetscErrorCode ierr = VecPointwiseMult(vector, factors, vector);
804  AssertThrow(ierr == 0, ExcPETScError(ierr));
805  }
806 
807 
808 
809  void
810  VectorBase::equ(const PetscScalar a, const VectorBase &v)
811  {
813  AssertIsFinite(a);
814 
815  Assert(size() == v.size(), ExcDimensionMismatch(size(), v.size()));
816 
817  // there is no simple operation for this
818  // in PETSc. there are multiple ways to
819  // emulate it, we choose this one:
820  const PetscErrorCode ierr = VecCopy(v.vector, vector);
821  AssertThrow(ierr == 0, ExcPETScError(ierr));
822 
823  *this *= a;
824  }
825 
826 
827 
828  void
830  {
832  const PetscErrorCode ierr = VecPointwiseDivide(vector, a, b);
833  AssertThrow(ierr == 0, ExcPETScError(ierr));
834  }
835 
836 
837 
838  void
839  VectorBase::write_ascii(const PetscViewerFormat format)
840  {
841  // TODO[TH]:assert(is_compressed())
842 
843  // Set options
844  PetscErrorCode ierr =
845  PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD, format);
846  AssertThrow(ierr == 0, ExcPETScError(ierr));
847 
848  // Write to screen
849  ierr = VecView(vector, PETSC_VIEWER_STDOUT_WORLD);
850  AssertThrow(ierr == 0, ExcPETScError(ierr));
851  }
852 
853 
854 
855  void
856  VectorBase::print(std::ostream & out,
857  const unsigned int precision,
858  const bool scientific,
859  const bool across) const
860  {
861  AssertThrow(out, ExcIO());
862 
863  // get a representation of the vector and
864  // loop over all the elements
865  PetscScalar * val;
866  PetscErrorCode ierr = VecGetArray(vector, &val);
867 
868  AssertThrow(ierr == 0, ExcPETScError(ierr));
869 
870  // save the state of out stream
871  const std::ios::fmtflags old_flags = out.flags();
872  const unsigned int old_precision = out.precision(precision);
873 
874  out.precision(precision);
875  if (scientific)
876  out.setf(std::ios::scientific, std::ios::floatfield);
877  else
878  out.setf(std::ios::fixed, std::ios::floatfield);
879 
880  if (across)
881  for (size_type i = 0; i < local_size(); ++i)
882  out << val[i] << ' ';
883  else
884  for (size_type i = 0; i < local_size(); ++i)
885  out << val[i] << std::endl;
886  out << std::endl;
887 
888  // reset output format
889  out.flags(old_flags);
890  out.precision(old_precision);
891 
892  // restore the representation of the
893  // vector
894  ierr = VecRestoreArray(vector, &val);
895  AssertThrow(ierr == 0, ExcPETScError(ierr));
896 
897  AssertThrow(out, ExcIO());
898  }
899 
900 
901 
902  void
904  {
905  const PetscErrorCode ierr = VecSwap(vector, v.vector);
906  AssertThrow(ierr == 0, ExcPETScError(ierr));
907  }
908 
909 
910 
911  VectorBase::operator const Vec &() const
912  {
913  return vector;
914  }
915 
916 
917  std::size_t
919  {
920  std::size_t mem = sizeof(Vec) + sizeof(last_action) +
923 
924  // TH: I am relatively sure that PETSc is
925  // storing the local data in a contiguous
926  // block without indices:
927  mem += local_size() * sizeof(PetscScalar);
928  // assume that PETSc is storing one index
929  // and one double per ghost element
930  if (ghosted)
931  mem += ghost_indices.n_elements() * (sizeof(PetscScalar) + sizeof(int));
932 
933  // TODO[TH]: size of constant memory for PETSc?
934  return mem;
935  }
936 
937 
938 
939  void
940  VectorBase::do_set_add_operation(const size_type n_elements,
941  const size_type * indices,
942  const PetscScalar *values,
943  const bool add_values)
944  {
946  (add_values ? ::VectorOperation::add :
948  Assert((last_action == action) ||
950  internal::VectorReference::ExcWrongMode(action, last_action));
952  // VecSetValues complains if we
953  // come with an empty
954  // vector. however, it is not a
955  // collective operation, so we
956  // can skip the call if necessary
957  // (unlike the above calls)
958  if (n_elements != 0)
959  {
960  const PetscInt *petsc_indices =
961  reinterpret_cast<const PetscInt *>(indices);
962 
963  const InsertMode mode = (add_values ? ADD_VALUES : INSERT_VALUES);
964  const PetscErrorCode ierr =
965  VecSetValues(vector, n_elements, petsc_indices, values, mode);
966  AssertThrow(ierr == 0, ExcPETScError(ierr));
967  }
968 
969  // set the mode here, independent of whether we have actually
970  // written elements or whether the list was empty
971  last_action = action;
972  }
973 
974 } // namespace PETScWrappers
975 
976 DEAL_II_NAMESPACE_CLOSE
977 
978 #endif // DEAL_II_WITH_PETSC
real_type lp_norm(const real_type p) const
#define AssertNothrow(cond, exc)
Definition: exceptions.h:1278
VectorBase & operator-=(const VectorBase &V)
static::ExceptionBase & ExcIO()
void sadd(const PetscScalar s, const VectorBase &V)
void ratio(const VectorBase &a, const VectorBase &b)
size_type n_elements() const
Definition: index_set.h:1743
bool has_ghost_elements() const
VectorBase & operator/=(const PetscScalar factor)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
VectorBase & operator=(const PetscScalar s)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
void scale(const VectorBase &scaling_factors)
void clear()
Definition: index_set.h:1587
static::ExceptionBase & ExcMessage(std::string arg1)
real_type linfty_norm() const
void compress(const VectorOperation::values operation)
virtual const MPI_Comm & get_mpi_communicator() const
void do_set_add_operation(const size_type n_elements, const size_type *indices, const PetscScalar *values, const bool add_values)
bool operator!=(const VectorBase &v) const
VectorOperation::values last_action
#define Assert(cond, exc)
Definition: exceptions.h:1227
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
PetscScalar mean_value() const
static bool is_running_single_threaded()
bool operator==(const VectorBase &v) const
PetscScalar add_and_dot(const PetscScalar a, const VectorBase &V, const VectorBase &W)
std::pair< size_type, size_type > local_range() const
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
void equ(const PetscScalar a, const VectorBase &V)
PetscScalar operator*(const VectorBase &vec) const
VectorBase & operator*=(const PetscScalar factor)
static::ExceptionBase & ExcGhostsPresent()
size_type local_size() const
VectorBase & operator+=(const VectorBase &V)
#define AssertThrowMPI(error_code)
Definition: exceptions.h:1443
std::size_t memory_consumption() const
void add(const std::vector< size_type > &indices, const std::vector< PetscScalar > &values)
void write_ascii(const PetscViewerFormat format=PETSC_VIEWER_DEFAULT)
virtual ~VectorBase() override
#define AssertIsFinite(number)
Definition: exceptions.h:1428
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static::ExceptionBase & ExcInternalError()
void set(const std::vector< size_type > &indices, const std::vector< PetscScalar > &values)