Reference documentation for deal.II version 9.0.0
trilinos_vector.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 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 #include <deal.II/lac/trilinos_vector.h>
17 
18 #ifdef DEAL_II_WITH_TRILINOS
19 
20 # include <deal.II/base/mpi.h>
21 # include <deal.II/base/std_cxx14/memory.h>
22 # include <deal.II/lac/trilinos_sparse_matrix.h>
23 # include <deal.II/lac/trilinos_parallel_block_vector.h>
24 # include <deal.II/lac/trilinos_index_access.h>
25 
26 # include <Epetra_Import.h>
27 # include <Epetra_Export.h>
28 # include <Epetra_Vector.h>
29 
30 # include <boost/io/ios_state.hpp>
31 
32 # include <cmath>
33 
34 
35 DEAL_II_NAMESPACE_OPEN
36 
37 namespace TrilinosWrappers
38 {
39  namespace internal
40  {
41  VectorReference::operator TrilinosScalar () const
42  {
43  Assert (index < vector.size(),
44  ExcIndexRange (index, 0, vector.size()));
45 
46  // Trilinos allows for vectors to be referenced by the [] or ()
47  // operators but only () checks index bounds. We check these bounds by
48  // ourselves, so we can use []. Note that we can only get local values.
49 
50  const TrilinosWrappers::types::int_type local_index =
51  vector.vector->Map().LID(static_cast<TrilinosWrappers::types::int_type>(index));
52  Assert (local_index >= 0,
53  MPI::Vector::ExcAccessToNonLocalElement (index, vector.local_size(),
54  vector.vector->Map().MinMyGID(),
55  vector.vector->Map().MaxMyGID()));
56 
57 
58  return (*(vector.vector))[0][local_index];
59  }
60  }
61 
62  namespace MPI
63  {
65  :
66  Subscriptor(),
67  last_action (Zero),
68  compressed (true),
69  has_ghosts (false),
70  vector(new Epetra_FEVector(Epetra_Map(0,0,0,Utilities::Trilinos::comm_self())))
71  {}
72 
73 
74 
75  Vector::Vector (const IndexSet &parallel_partitioning,
76  const MPI_Comm &communicator)
77  : Vector()
78  {
79  reinit (parallel_partitioning, communicator);
80  }
81 
82 
83 
85  :
86  Vector()
87  {
89  vector = std_cxx14::make_unique<Epetra_FEVector>(*v.vector);
91  }
92 
93 
94 
95  Vector::Vector (Vector &&v) noexcept
96 :
97  Vector()
98  {
99  // initialize a minimal, valid object and swap
100  swap(v);
101  }
102 
103 
104 
105  Vector::Vector (const IndexSet &parallel_partitioner,
106  const Vector &v,
107  const MPI_Comm &communicator)
108  : Vector()
109  {
110  AssertThrow (parallel_partitioner.size() ==
111  static_cast<size_type>(TrilinosWrappers::n_global_elements(v.vector->Map())),
112  ExcDimensionMismatch (parallel_partitioner.size(),
114 
115  vector = std_cxx14::make_unique<Epetra_FEVector>
116  (parallel_partitioner.make_trilinos_map(communicator, true));
117  reinit (v, false, true);
118  }
119 
120 
121 
122  Vector::Vector (const IndexSet &local,
123  const IndexSet &ghost,
124  const MPI_Comm &communicator)
125  : Vector()
126  {
127  reinit(local, ghost, communicator, false);
128  }
129 
130 
131 
132  void
134  {
135  // When we clear the vector, reset the pointer and generate an empty
136  // vector.
137 #ifdef DEAL_II_WITH_MPI
138  Epetra_Map map (0, 0, Epetra_MpiComm(MPI_COMM_SELF));
139 #else
140  Epetra_Map map (0, 0, Epetra_SerialComm());
141 #endif
142 
143  has_ghosts = false;
144  vector = std_cxx14::make_unique<Epetra_FEVector>(map);
145  last_action = Zero;
146  }
147 
148 
149 
150  void
151  Vector::reinit (const IndexSet &parallel_partitioner,
152  const MPI_Comm &communicator,
153  const bool /*omit_zeroing_entries*/)
154  {
155  nonlocal_vector.reset();
156 
157  Epetra_Map map = parallel_partitioner.make_trilinos_map (communicator,
158  true);
159 
160  vector = std_cxx14::make_unique<Epetra_FEVector>(map);
161 
162  has_ghosts = vector->Map().UniqueGIDs()==false;
163 
164  // If the IndexSets are overlapping, we don't really know
165  // which process owns what. So we decide that no process
166  // owns anything in that case. In particular asking for
167  // the locally owned elements is not allowed.
168  if (has_ghosts)
169  {
172  }
173  else
174  owned_elements = parallel_partitioner;
175 
176 #ifdef DEBUG
177  const size_type n_elements_global
178  = Utilities::MPI::sum (owned_elements.n_elements(), communicator);
179 
180  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
181 #endif
182 
183  last_action = Zero;
184  }
185 
186 
187 
188  void
190  const bool omit_zeroing_entries,
191  const bool allow_different_maps)
192  {
193  nonlocal_vector.reset();
194 
195  // In case we do not allow to have different maps, this call means that
196  // we have to reset the vector. So clear the vector, initialize our map
197  // with the map in v, and generate the vector.
198  if (allow_different_maps == false)
199  {
200  // check equality for MPI communicators: We can only choose the fast
201  // version in case the underlying Epetra_MpiComm object is the same,
202  // otherwise we might access an MPI_Comm object that has been
203  // deleted
204 #ifdef DEAL_II_WITH_MPI
205  const Epetra_MpiComm *my_comm = dynamic_cast<const Epetra_MpiComm *>(&vector->Comm());
206  const Epetra_MpiComm *v_comm = dynamic_cast<const Epetra_MpiComm *>(&v.vector->Comm());
207  const bool same_communicators = my_comm != nullptr && v_comm != nullptr &&
208  my_comm->DataPtr() == v_comm->DataPtr();
209 #else
210  const bool same_communicators = true;
211 #endif
212  if (!same_communicators || vector->Map().SameAs(v.vector->Map()) == false)
213  {
214  vector = std_cxx14::make_unique<Epetra_FEVector>(v.vector->Map());
216  last_action = Zero;
218  }
219  else if (omit_zeroing_entries == false)
220  {
221  // old and new vectors have exactly the same map, i.e. size and
222  // parallel distribution
223  int ierr;
224  ierr = vector->GlobalAssemble (last_action);
225  (void)ierr;
226  Assert (ierr == 0, ExcTrilinosError(ierr));
227 
228  ierr = vector->PutScalar(0.0);
229  Assert (ierr == 0, ExcTrilinosError(ierr));
230 
231  last_action = Zero;
232  }
233  }
234 
235  // Otherwise, we have to check that the two vectors are already of the
236  // same size, create an object for the data exchange and then insert all
237  // the data. The first assertion is only a check whether the user knows
238  // what she is doing.
239  else
240  {
241  Assert (omit_zeroing_entries == false,
242  ExcMessage ("It is not possible to exchange data with the "
243  "option 'omit_zeroing_entries' set, which would not write "
244  "elements."));
245 
246  AssertThrow (size() == v.size(),
247  ExcDimensionMismatch (size(), v.size()));
248 
249  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
250 
251  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
252  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
253 
254  last_action = Insert;
255  }
256 #if defined(DEBUG) && defined(DEAL_II_WITH_MPI)
257  const Epetra_MpiComm *comm_ptr
258  = dynamic_cast<const Epetra_MpiComm *>(&(v.vector->Comm()));
259  Assert (comm_ptr != nullptr, ExcInternalError());
260  const size_type n_elements_global
261  = Utilities::MPI::sum (owned_elements.n_elements(), comm_ptr->Comm());
262  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
263 #endif
264  }
265 
266 
267 
268  void
270  const bool import_data)
271  {
272  nonlocal_vector.reset();
275 
276  // In case we do not allow to have different maps, this call means that
277  // we have to reset the vector. So clear the vector, initialize our map
278  // with the map in v, and generate the vector.
279  if (v.n_blocks() == 0)
280  return;
281 
282  // create a vector that holds all the elements contained in the block
283  // vector. need to manually create an Epetra_Map.
284  size_type n_elements = 0, added_elements = 0, block_offset = 0;
285  for (size_type block=0; block<v.n_blocks(); ++block)
286  n_elements += v.block(block).local_size();
287  std::vector<TrilinosWrappers::types::int_type> global_ids (n_elements, -1);
288  for (size_type block=0; block<v.n_blocks(); ++block)
289  {
290  TrilinosWrappers::types::int_type *glob_elements =
291  TrilinosWrappers::my_global_elements(v.block(block).vector_partitioner());
292  for (size_type i=0; i<v.block(block).local_size(); ++i)
293  global_ids[added_elements++] = glob_elements[i] + block_offset;
294  owned_elements.add_indices(v.block(block).owned_elements,
295  block_offset);
296  block_offset += v.block(block).size();
297  }
298 
299  Assert (n_elements == added_elements, ExcInternalError());
300  Epetra_Map new_map (v.size(), n_elements, global_ids.data(), 0,
301  v.block(0).vector_partitioner().Comm());
302 
303  auto actual_vec = std_cxx14::make_unique<Epetra_FEVector>(new_map);
304 
305  TrilinosScalar *entries = (*actual_vec)[0];
306  for (size_type block=0; block<v.n_blocks(); ++block)
307  {
308  v.block(block).trilinos_vector().ExtractCopy (entries, 0);
309  entries += v.block(block).local_size();
310  }
311 
312  if (import_data == true)
313  {
314  AssertThrow (static_cast<size_type>(TrilinosWrappers::global_length(*actual_vec))
315  == v.size(),
317  v.size()));
318 
319  Epetra_Import data_exchange (vector->Map(), actual_vec->Map());
320 
321  const int ierr = vector->Import(*actual_vec, data_exchange, Insert);
322  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
323 
324  last_action = Insert;
325  }
326  else
327  vector = std::move(actual_vec);
328 #if defined(DEBUG) && defined(DEAL_II_WITH_MPI)
329  const Epetra_MpiComm *comm_ptr
330  = dynamic_cast<const Epetra_MpiComm *>(&(vector->Comm()));
331  Assert (comm_ptr != nullptr, ExcInternalError());
332  const size_type n_elements_global
333  = Utilities::MPI::sum (owned_elements.n_elements(), comm_ptr->Comm());
334 
335  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
336 #endif
337  }
338 
339 
340 
341  void Vector::reinit(const IndexSet &locally_owned_entries,
342  const IndexSet &ghost_entries,
343  const MPI_Comm &communicator,
344  const bool vector_writable)
345  {
346  nonlocal_vector.reset();
347  owned_elements = locally_owned_entries;
348  if (vector_writable == false)
349  {
350  IndexSet parallel_partitioner = locally_owned_entries;
351  parallel_partitioner.add_indices(ghost_entries);
352  Epetra_Map map = parallel_partitioner.make_trilinos_map (communicator,
353  true);
354  vector = std_cxx14::make_unique<Epetra_FEVector>(map);
355  }
356  else
357  {
358  Epetra_Map map = locally_owned_entries.make_trilinos_map (communicator,
359  true);
360  Assert (map.IsOneToOne(),
361  ExcMessage("A writable vector must not have ghost entries in "
362  "its parallel partitioning"));
363 
364  if (vector->Map().SameAs(map)==false)
365  vector = std_cxx14::make_unique<Epetra_FEVector>(map);
366  else
367  {
368  const int ierr = vector->PutScalar(0.);
369  (void)ierr;
370  Assert (ierr == 0, ExcTrilinosError(ierr));
371  }
372 
373  IndexSet nonlocal_entries(ghost_entries);
374  nonlocal_entries.subtract_set(locally_owned_entries);
375  if (Utilities::MPI::n_mpi_processes(communicator) > 1)
376  {
377  Epetra_Map nonlocal_map =
378  nonlocal_entries.make_trilinos_map(communicator, true);
379  nonlocal_vector = std_cxx14::make_unique<Epetra_MultiVector>(nonlocal_map, 1);
380  }
381  }
382 
383  has_ghosts = vector->Map().UniqueGIDs()==false;
384 
385  last_action = Zero;
386 
387 #ifdef DEBUG
388  const size_type n_elements_global
389  = Utilities::MPI::sum (owned_elements.n_elements(), communicator);
390 
391  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
392 #endif
393  }
394 
395 
396 
397  Vector &
399  {
400  Assert (vector.get() != nullptr,
401  ExcMessage("Vector is not constructed properly."));
402 
403  // check equality for MPI communicators to avoid accessing a possibly
404  // invalid MPI_Comm object
405 #ifdef DEAL_II_WITH_MPI
406  const Epetra_MpiComm *my_comm = dynamic_cast<const Epetra_MpiComm *>(&vector->Comm());
407  const Epetra_MpiComm *v_comm = dynamic_cast<const Epetra_MpiComm *>(&v.vector->Comm());
408  const bool same_communicators = my_comm != nullptr && v_comm != nullptr &&
409  my_comm->DataPtr() == v_comm->DataPtr();
410  // Need to ask MPI whether the communicators are the same. We would like
411  // to use the following checks but currently we cannot make sure the
412  // memory of my_comm is not stale from some MPI_Comm_free
413  // somewhere. This can happen when a vector lives in GrowingVectorMemory
414  // data structures. Thus, the following code is commented out.
415  //
416  //if (my_comm != NULL && v_comm != NULL && my_comm->DataPtr() != v_comm->DataPtr())
417  // {
418  // int communicators_same = 0;
419  // const int ierr = MPI_Comm_compare (my_comm->GetMpiComm(),
420  // v_comm->GetMpiComm(),
421  // &communicators_same);
422  // AssertThrowMPI(ierr);
423  // if (!(communicators_same == MPI_IDENT ||
424  // communicators_same == MPI_CONGRUENT))
425  // same_communicators = false;
426  // else
427  // same_communicators = true;
428  // }
429 #else
430  const bool same_communicators = true;
431 #endif
432 
433  // distinguish three cases. First case: both vectors have the same
434  // layout (just need to copy the local data, not reset the memory and
435  // the underlying Epetra_Map). The third case means that we have to
436  // rebuild the calling vector.
437  if (same_communicators && v.vector->Map().SameAs(vector->Map()))
438  {
439  *vector = *v.vector;
440  if (v.nonlocal_vector.get() != nullptr)
441  nonlocal_vector = std_cxx14::make_unique<Epetra_MultiVector>(v.nonlocal_vector->Map(), 1);
442  last_action = Zero;
443  }
444  // Second case: vectors have the same global
445  // size, but different parallel layouts (and
446  // one of them a one-to-one mapping). Then we
447  // can call the import/export functionality.
448  else if (size() == v.size() &&
449  (v.vector->Map().UniqueGIDs() || vector->Map().UniqueGIDs()))
450  {
451  reinit (v, false, true);
452  }
453  // Third case: Vectors do not have the same
454  // size.
455  else
456  {
457  vector = std_cxx14::make_unique<Epetra_FEVector>(*v.vector);
458  last_action = Zero;
461  }
462 
463  if (v.nonlocal_vector.get() != nullptr)
464  nonlocal_vector = std_cxx14::make_unique<Epetra_MultiVector>(v.nonlocal_vector->Map(), 1);
465 
466  return *this;
467  }
468 
469 
470 
472  {
473  swap(v);
474  return *this;
475  }
476 
477 
478 
479  template <typename number>
480  Vector &
481  Vector::operator = (const ::Vector<number> &v)
482  {
483  Assert (size() == v.size(),
484  ExcDimensionMismatch(size(), v.size()));
485 
486  // this is probably not very efficient but works. in particular, we could
487  // do better if we know that number==TrilinosScalar because then we could
488  // elide the copying of elements
489  //
490  // let's hope this isn't a particularly frequent operation
491  std::pair<size_type, size_type> local_range = this->local_range ();
492  for (size_type i=local_range.first; i<local_range.second; ++i)
493  (*vector)[0][i-local_range.first] = v(i);
494 
495  return *this;
496  }
497 
498 
499 
500  void
502  const Vector &v)
503  {
504  Assert (m.trilinos_matrix().Filled() == true,
505  ExcMessage ("Matrix is not compressed. "
506  "Cannot find exchange information!"));
507  Assert (v.vector->Map().UniqueGIDs() == true,
508  ExcMessage ("The input vector has overlapping data, "
509  "which is not allowed."));
510 
511  if (vector->Map().SameAs(m.trilinos_matrix().ColMap()) == false)
512  vector = std_cxx14::make_unique<Epetra_FEVector>(m.trilinos_matrix().ColMap());
513 
514  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
515  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
516 
517  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
518 
519  last_action = Insert;
520  }
521 
522 
523 
524  void
526  {
527  //Select which mode to send to Trilinos. Note that we use last_action if
528  //available and ignore what the user tells us to detect wrongly mixed
529  //operations. Typically given_last_action is only used on machines that do
530  //not execute an operation (because they have no own cells for example).
531  Epetra_CombineMode mode = last_action;
532  if (last_action == Zero)
533  {
534  if (given_last_action==::VectorOperation::add)
535  mode = Add;
536  else if (given_last_action==::VectorOperation::insert)
537  mode = Insert;
538  }
539  else
540  {
541  Assert(
542  ((last_action == Add) && (given_last_action==::VectorOperation::add))
543  ||
544  ((last_action == Insert) && (given_last_action==::VectorOperation::insert)),
545  ExcMessage("The last operation on the Vector and the given last action in the compress() call do not agree!"));
546  }
547 
548 
549 #ifdef DEBUG
550 # ifdef DEAL_II_WITH_MPI
551  // check that every process has decided to use the same mode. This will
552  // otherwise result in undefined behaviour in the call to
553  // GlobalAssemble().
554  double double_mode = mode;
555  const Epetra_MpiComm *comm_ptr
556  = dynamic_cast<const Epetra_MpiComm *>(&(vector_partitioner().Comm()));
557  Assert (comm_ptr != nullptr, ExcInternalError());
559  = Utilities::MPI::min_max_avg (double_mode, comm_ptr->GetMpiComm());
560  Assert(result.max-result.min<1e-5,
561  ExcMessage ("Not all processors agree whether the last operation on "
562  "this vector was an addition or a set operation. This will "
563  "prevent the compress() operation from succeeding."));
564 
565 # endif
566 #endif
567 
568  // Now pass over the information about what we did last to the vector.
569  int ierr = 0;
570  if (nonlocal_vector.get() == nullptr || mode != Add)
571  ierr = vector->GlobalAssemble(mode);
572  else
573  {
574  Epetra_Export exporter(nonlocal_vector->Map(), vector->Map());
575  ierr = vector->Export(*nonlocal_vector, exporter, mode);
576  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
577  ierr = nonlocal_vector->PutScalar(0.);
578  }
579  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
580  last_action = Zero;
581 
582  compressed = true;
583  }
584 
585 
586 
587  TrilinosScalar
588  Vector::operator () (const size_type index) const
589  {
590  // Extract local indices in the vector.
591  TrilinosWrappers::types::int_type trilinos_i =
592  vector->Map().LID(static_cast<TrilinosWrappers::types::int_type>(index));
593  TrilinosScalar value = 0.;
594 
595  // If the element is not present on the current processor, we can't
596  // continue. This is the main difference to the el() function.
597  if (trilinos_i == -1)
598  {
600  vector->Map().MinMyGID(),
601  vector->Map().MaxMyGID()));
602  }
603  else
604  value = (*vector)[0][trilinos_i];
605 
606  return value;
607  }
608 
609 
610 
611  void
612  Vector::add (const Vector &v,
613  const bool allow_different_maps)
614  {
615  if (allow_different_maps == false)
616  *this += v;
617  else
618  {
620  AssertThrow (size() == v.size(),
621  ExcDimensionMismatch (size(), v.size()));
622 
623 #if DEAL_II_TRILINOS_VERSION_GTE(11,11,0)
624  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
625  int ierr = vector->Import(*v.vector, data_exchange, Epetra_AddLocalAlso);
626  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
627  last_action = Add;
628 #else
629  // In versions older than 11.11 the Import function is broken for adding
630  // Hence, we provide a workaround in this case
631 
632  Epetra_MultiVector dummy(vector->Map(), 1, false);
633  Epetra_Import data_exchange (dummy.Map(), v.vector->Map());
634 
635  int ierr = dummy.Import(*v.vector, data_exchange, Insert);
636  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
637 
638  ierr = vector->Update (1.0, dummy, 1.0);
639  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
640 #endif
641  }
642  }
643 
644 
645 
646  bool
647  Vector::operator == (const Vector &v) const
648  {
649  Assert (size() == v.size(),
650  ExcDimensionMismatch(size(), v.size()));
651  if (local_size() != v.local_size())
652  return false;
653 
654  size_type i;
655  for (i=0; i<local_size(); i++)
656  if ((*(v.vector))[0][i]!=(*vector)[0][i]) return false;
657 
658  return true;
659  }
660 
661 
662 
663  bool
664  Vector::operator != (const Vector &v) const
665  {
666  Assert (size() == v.size(),
667  ExcDimensionMismatch(size(), v.size()));
668 
669  return (!(*this==v));
670  }
671 
672 
673 
674  bool
676  {
677  // get a representation of the vector and
678  // loop over all the elements
679  TrilinosScalar *start_ptr = (*vector)[0];
680  const TrilinosScalar *ptr = start_ptr,
681  *eptr = start_ptr + local_size();
682  unsigned int flag = 0;
683  while (ptr != eptr)
684  {
685  if (*ptr != 0)
686  {
687  flag = 1;
688  break;
689  }
690  ++ptr;
691  }
692 
693 #ifdef DEAL_II_WITH_MPI
694  // in parallel, check that the vector
695  // is zero on _all_ processors.
696  const Epetra_MpiComm *mpi_comm
697  = dynamic_cast<const Epetra_MpiComm *>(&vector->Map().Comm());
698  Assert(mpi_comm != nullptr, ExcInternalError());
699  unsigned int num_nonzero = Utilities::MPI::sum(flag, mpi_comm->Comm());
700  return num_nonzero == 0;
701 #else
702  return flag == 0;
703 #endif
704 
705  }
706 
707 
708 
709  bool
711  {
712 #ifdef DEAL_II_WITH_MPI
713  // if this vector is a parallel one, then
714  // we need to communicate to determine
715  // the answer to the current
716  // function. this still has to be
717  // implemented
719 #endif
720  // get a representation of the vector and
721  // loop over all the elements
722  TrilinosScalar *start_ptr;
723  int leading_dimension;
724  int ierr = vector->ExtractView (&start_ptr, &leading_dimension);
725  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
726 
727  // TODO: This
728  // won't work in parallel like
729  // this. Find out a better way to
730  // this in that case.
731  const TrilinosScalar *ptr = start_ptr,
732  *eptr = start_ptr + size();
733  bool flag = true;
734  while (ptr != eptr)
735  {
736  if (*ptr < 0.0)
737  {
738  flag = false;
739  break;
740  }
741  ++ptr;
742  }
743 
744  return flag;
745  }
746 
747 
748 
749  void
750  Vector::print (std::ostream &out,
751  const unsigned int precision,
752  const bool scientific,
753  const bool across) const
754  {
755  AssertThrow (out, ExcIO());
756  boost::io::ios_flags_saver restore_flags(out);
757 
758 
759  out.precision (precision);
760  if (scientific)
761  out.setf (std::ios::scientific, std::ios::floatfield);
762  else
763  out.setf (std::ios::fixed, std::ios::floatfield);
764 
765  if (size() != local_size())
766  {
767  auto global_id = [&] (const size_type index)
768  {
769  return gid(vector->Map(), static_cast<TrilinosWrappers::types::int_type>(index));
770  };
771  out << "size:" << size() << " local_size:" << local_size() << " :" << std::endl;
772  for (size_type i=0; i<local_size(); ++i)
773  out << "[" << global_id(i) << "]: " << (*(vector))[0][i] << std::endl;
774  }
775  else
776  {
777  TrilinosScalar *val;
778  int leading_dimension;
779  int ierr = vector->ExtractView (&val, &leading_dimension);
780 
781  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
782  if (across)
783  for (size_type i=0; i<size(); ++i)
784  out << static_cast<double>(val[i]) << ' ';
785  else
786  for (size_type i=0; i<size(); ++i)
787  out << static_cast<double>(val[i]) << std::endl;
788  out << std::endl;
789  }
790 
791  AssertThrow (out, ExcIO());
792  }
793 
794 
795 
796  void
798  {
802  std::swap(vector, v.vector);
805  }
806 
807 
808 
809  std::size_t
811  {
812  //TODO[TH]: No accurate memory
813  //consumption for Trilinos vectors
814  //yet. This is a rough approximation with
815  //one index and the value per local
816  //entry.
817  return sizeof(*this)
818  + this->local_size()*( sizeof(double)+
819  sizeof(TrilinosWrappers::types::int_type) );
820  }
821  } /* end of namespace MPI */
822 } /* end of namespace TrilinosWrappers */
823 
824 namespace TrilinosWrappers
825 {
826  namespace MPI
827  {
828 # include "trilinos_vector.inst"
829  }
830 }
831 
832 DEAL_II_NAMESPACE_CLOSE
833 
834 #endif // DEAL_II_WITH_TRILINOS
Vector & operator=(const TrilinosScalar s)
std::unique_ptr< Epetra_MultiVector > nonlocal_vector
static ::ExceptionBase & ExcIO()
TrilinosWrappers::types::int_type global_length(const Epetra_MultiVector &vector)
void reinit(const Vector &v, const bool omit_zeroing_entries=false, const bool allow_different_maps=false)
void add(const std::vector< size_type > &indices, const std::vector< TrilinosScalar > &values)
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Definition: index_set.h:1619
std::pair< size_type, size_type > local_range() const
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
Definition: index_set.cc:549
size_type size() const
Definition: index_set.h:1575
void clear()
Definition: index_set.h:1549
bool operator==(const Vector &v) const
static ::ExceptionBase & ExcMessage(std::string arg1)
std::size_t size() const
reference operator()(const size_type index)
void swap(BlockVector &u, BlockVector &v)
T sum(const T &t, const MPI_Comm &mpi_communicator)
TrilinosWrappers::types::int_type * my_global_elements(const Epetra_BlockMap &map)
void subtract_set(const IndexSet &other)
Definition: index_set.cc:288
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::unique_ptr< Epetra_FEVector > vector
void compress(::VectorOperation::values operation)
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
std::size_t memory_consumption() const
const Epetra_CrsMatrix & trilinos_matrix() const
void import_nonlocal_data_for_fe(const ::TrilinosWrappers::SparseMatrix &matrix, const Vector &vector)
const Epetra_Map & vector_partitioner() const
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:65
static ::ExceptionBase & ExcGhostsPresent()
TrilinosWrappers::types::int_type n_global_elements(const Epetra_BlockMap &map)
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1312
void set_size(const size_type size)
Definition: index_set.h:1562
Definition: cuda.h:31
size_type local_size() const
unsigned int n_blocks() const
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
static ::ExceptionBase & ExcNotImplemented()
bool operator!=(const Vector &v) const
MinMaxAvg min_max_avg(const double my_value, const MPI_Comm &mpi_communicator)
Definition: mpi.cc:275
static ::ExceptionBase & ExcTrilinosError(int arg1)
BlockType & block(const unsigned int i)
size_type n_elements() const
Definition: index_set.h:1717
static ::ExceptionBase & ExcInternalError()