Reference documentation for deal.II version 8.5.1
trilinos_vector.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 2017 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/lac/trilinos_sparse_matrix.h>
22 # include <deal.II/lac/trilinos_block_vector.h>
23 
24 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
25 # include <Epetra_Import.h>
26 # include <Epetra_Vector.h>
27 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
28 
29 # include <cmath>
30 
31 
32 DEAL_II_NAMESPACE_OPEN
33 
34 namespace TrilinosWrappers
35 {
36  namespace
37  {
38 #ifndef DEAL_II_WITH_64BIT_INDICES
39  // define a helper function that queries the size of an Epetra_BlockMap object
40  // by calling either the 32- or 64-bit function necessary, and returns the
41  // result in the correct data type so that we can use it in calling other
42  // Epetra member functions that are overloaded by index type
43  int n_global_elements (const Epetra_BlockMap &map)
44  {
45  return map.NumGlobalElements();
46  }
47  // define a helper function that queries the pointer to internal array
48  // containing list of global IDs assigned to the calling processor
49  // by calling either the 32- or 64-bit function necessary, and returns the
50  // result in the correct data type so that we can use it in calling other
51  // Epetra member functions that are overloaded by index type
52  int *my_global_elements(const Epetra_BlockMap &map)
53  {
54  return map.MyGlobalElements();
55  }
56  // define a helper function that queries the global vector length of an
57  // Epetra_FEVector object by calling either the 32- or 64-bit
58  // function necessary.
59  int global_length(const Epetra_FEVector &vector)
60  {
61  return vector.GlobalLength();
62  }
63 #else
64  // define a helper function that queries the size of an Epetra_BlockMap object
65  // by calling either the 32- or 64-bit function necessary, and returns the
66  // result in the correct data type so that we can use it in calling other
67  // Epetra member functions that are overloaded by index type
68  long long int n_global_elements (const Epetra_BlockMap &map)
69  {
70  return map.NumGlobalElements64();
71  }
72  // define a helper function that queries the pointer to internal array
73  // containing list of global IDs assigned to the calling processor
74  // by calling either the 32- or 64-bit function necessary, and returns the
75  // result in the correct data type so that we can use it in calling other
76  // Epetra member functions that are overloaded by index type
77  long long int *my_global_elements(const Epetra_BlockMap &map)
78  {
79  return map.MyGlobalElements64();
80  }
81  // define a helper function that queries the global vector length of an
82  // Epetra_FEVector object by calling either the 32- or 64-bit
83  // function necessary.
84  long long int global_length(const Epetra_FEVector &vector)
85  {
86  return vector.GlobalLength64();
87  }
88 #endif
89  }
90 
91  namespace MPI
92  {
93 
94 
96  {
97  last_action = Zero;
98  vector.reset(new Epetra_FEVector(Epetra_Map(0,0,0,Utilities::Trilinos::comm_self())));
99  }
100 
101 
102 
103  Vector::Vector (const Epetra_Map &parallel_partitioning)
104  {
105  reinit (parallel_partitioning);
106  }
107 
108 
109 
110  Vector::Vector (const IndexSet &parallel_partitioning,
111  const MPI_Comm &communicator)
112  {
113  reinit (parallel_partitioning, communicator);
114  }
115 
116 
117 
119  :
120  VectorBase()
121  {
122  last_action = Zero;
123  vector.reset (new Epetra_FEVector(*v.vector));
124  has_ghosts = v.has_ghosts;
125  owned_elements = v.owned_elements;
126  }
127 
128 
129 
130 #ifdef DEAL_II_WITH_CXX11
132  {
133  // initialize a minimal, valid object and swap
134  last_action = Zero;
135  vector.reset(new Epetra_FEVector(Epetra_Map(0,0,0,Utilities::Trilinos::comm_self())));
137 
138  swap(v);
139  }
140 #endif
141 
142 
143 
144  Vector::Vector (const Epetra_Map &input_map,
145  const VectorBase &v)
146  :
147  VectorBase()
148  {
149  AssertThrow (n_global_elements(input_map) == n_global_elements(v.vector->Map()),
150  ExcDimensionMismatch (n_global_elements(input_map),
151  n_global_elements(v.vector->Map())));
152 
153  last_action = Zero;
154 
155  if (input_map.SameAs(v.vector->Map()) == true)
156  vector.reset (new Epetra_FEVector(*v.vector));
157  else
158  {
159  vector.reset (new Epetra_FEVector(input_map));
160  reinit (v, false, true);
161  }
162  }
163 
164 
165 
166  Vector::Vector (const IndexSet &parallel_partitioner,
167  const VectorBase &v,
168  const MPI_Comm &communicator)
169  :
170  VectorBase()
171  {
172  AssertThrow (parallel_partitioner.size() ==
173  static_cast<size_type>(n_global_elements(v.vector->Map())),
174  ExcDimensionMismatch (parallel_partitioner.size(),
175  n_global_elements(v.vector->Map())));
176 
177  last_action = Zero;
178 
179  vector.reset (new Epetra_FEVector
180  (parallel_partitioner.make_trilinos_map(communicator,
181  true)));
182  reinit (v, false, true);
183  }
184 
185  Vector::Vector (const IndexSet &local,
186  const IndexSet &ghost,
187  const MPI_Comm &communicator)
188  :
189  VectorBase()
190  {
191  reinit(local, ghost, communicator, false);
192  }
193 
194 
195 
197  {}
198 
199 
200 
201  void
202  Vector::reinit (const Epetra_Map &input_map,
203  const bool /*omit_zeroing_entries*/)
204  {
205  nonlocal_vector.reset();
206 
207  vector.reset (new Epetra_FEVector(input_map));
208 
209  has_ghosts = vector->Map().UniqueGIDs()==false;
210 
211  // If the IndexSets are overlapping, we don't really know
212  // which process owns what. So we decide that no process
213  // owns anything in that case. In particular asking for
214  // the locally owned elements is not allowed.
216  if (has_ghosts)
218  else
219  {
221 
222  // easy case: local range is contiguous
223  if (vector->Map().LinearMap())
224  {
225  const std::pair<size_type, size_type> x = local_range();
226  owned_elements.add_range (x.first, x.second);
227  }
228  else if (vector->Map().NumMyElements() > 0)
229  {
230  const size_type n_indices = vector->Map().NumMyElements();
231 #ifndef DEAL_II_WITH_64BIT_INDICES
232  unsigned int *vector_indices = (unsigned int *)vector->Map().MyGlobalElements();
233 #else
234  size_type *vector_indices = (size_type *)vector->Map().MyGlobalElements64();
235 #endif
236  owned_elements.add_indices(vector_indices, vector_indices+n_indices);
238  }
239  }
240 #if defined(DEBUG) && defined(DEAL_II_WITH_MPI)
241  const Epetra_MpiComm *comm_ptr
242  = dynamic_cast<const Epetra_MpiComm *>(&(vector->Comm()));
243  Assert (comm_ptr != 0, ExcInternalError());
244  const size_type n_elements_global
245  = Utilities::MPI::sum (owned_elements.n_elements(), comm_ptr->Comm());
246 
247  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
248 #endif
249 
250  last_action = Zero;
251  }
252 
253 
254 
255  void
256  Vector::reinit (const IndexSet &parallel_partitioner,
257  const MPI_Comm &communicator,
258  const bool /*omit_zeroing_entries*/)
259  {
260  nonlocal_vector.reset();
261 
262  Epetra_Map map = parallel_partitioner.make_trilinos_map (communicator,
263  true);
264 
265  vector.reset (new Epetra_FEVector(map));
266 
267  has_ghosts = vector->Map().UniqueGIDs()==false;
268 
269  // If the IndexSets are overlapping, we don't really know
270  // which process owns what. So we decide that no process
271  // owns anything in that case. In particular asking for
272  // the locally owned elements is not allowed.
273  if (has_ghosts)
274  {
277  }
278  else
279  owned_elements = parallel_partitioner;
280 
281 #ifdef DEBUG
282  const size_type n_elements_global
283  = Utilities::MPI::sum (owned_elements.n_elements(), communicator);
284 
285  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
286 #endif
287 
288  last_action = Zero;
289  }
290 
291 
292 
293  void
295  const bool omit_zeroing_entries,
296  const bool allow_different_maps)
297  {
298  nonlocal_vector.reset();
299 
300  // In case we do not allow to have different maps, this call means that
301  // we have to reset the vector. So clear the vector, initialize our map
302  // with the map in v, and generate the vector.
303  if (allow_different_maps == false)
304  {
305  // check equality for MPI communicators: We can only choose the fast
306  // version in case the underlying Epetra_MpiComm object is the same,
307  // otherwise we might access an MPI_Comm object that has been
308  // deleted
309 #ifdef DEAL_II_WITH_MPI
310  const Epetra_MpiComm *my_comm = dynamic_cast<const Epetra_MpiComm *>(&vector->Comm());
311  const Epetra_MpiComm *v_comm = dynamic_cast<const Epetra_MpiComm *>(&v.vector->Comm());
312  const bool same_communicators = my_comm != NULL && v_comm != NULL &&
313  my_comm->DataPtr() == v_comm->DataPtr();
314 #else
315  const bool same_communicators = true;
316 #endif
317  if (!same_communicators || vector->Map().SameAs(v.vector->Map()) == false)
318  {
319  vector.reset (new Epetra_FEVector(v.vector->Map()));
321  last_action = Zero;
323  }
324  else if (omit_zeroing_entries == false)
325  {
326  // old and new vectors have exactly the same map, i.e. size and
327  // parallel distribution
328  int ierr;
329  ierr = vector->GlobalAssemble (last_action);
330  (void)ierr;
331  Assert (ierr == 0, ExcTrilinosError(ierr));
332 
333  ierr = vector->PutScalar(0.0);
334  Assert (ierr == 0, ExcTrilinosError(ierr));
335 
336  last_action = Zero;
337  }
338  }
339 
340  // Otherwise, we have to check that the two vectors are already of the
341  // same size, create an object for the data exchange and then insert all
342  // the data. The first assertion is only a check whether the user knows
343  // what she is doing.
344  else
345  {
346  Assert (omit_zeroing_entries == false,
347  ExcMessage ("It is not possible to exchange data with the "
348  "option 'omit_zeroing_entries' set, which would not write "
349  "elements."));
350 
351  AssertThrow (size() == v.size(),
352  ExcDimensionMismatch (size(), v.size()));
353 
354  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
355 
356  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
357  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
358 
359  last_action = Insert;
360  }
361 #if defined(DEBUG) && defined(DEAL_II_WITH_MPI)
362  const Epetra_MpiComm *comm_ptr
363  = dynamic_cast<const Epetra_MpiComm *>(&(v.vector->Comm()));
364  Assert (comm_ptr != 0, ExcInternalError());
365  const size_type n_elements_global
366  = Utilities::MPI::sum (owned_elements.n_elements(), comm_ptr->Comm());
367 
368  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
369 #endif
370  }
371 
372 
373 
374  void
376  const bool import_data)
377  {
378  nonlocal_vector.reset();
381 
382  // In case we do not allow to have different maps, this call means that
383  // we have to reset the vector. So clear the vector, initialize our map
384  // with the map in v, and generate the vector.
385  if (v.n_blocks() == 0)
386  return;
387 
388  // create a vector that holds all the elements contained in the block
389  // vector. need to manually create an Epetra_Map.
390  size_type n_elements = 0, added_elements = 0, block_offset = 0;
391  for (size_type block=0; block<v.n_blocks(); ++block)
392  n_elements += v.block(block).local_size();
393  std::vector<TrilinosWrappers::types::int_type> global_ids (n_elements, -1);
394  for (size_type block=0; block<v.n_blocks(); ++block)
395  {
396  TrilinosWrappers::types::int_type *glob_elements =
397  my_global_elements(v.block(block).vector_partitioner());
398  for (size_type i=0; i<v.block(block).local_size(); ++i)
399  global_ids[added_elements++] = glob_elements[i] + block_offset;
400  owned_elements.add_indices(v.block(block).owned_elements,
401  block_offset);
402  block_offset += v.block(block).size();
403  }
404 
405  Assert (n_elements == added_elements, ExcInternalError());
406  Epetra_Map new_map (v.size(), n_elements, &global_ids[0], 0,
407  v.block(0).vector_partitioner().Comm());
408 
409  std_cxx11::shared_ptr<Epetra_FEVector> actual_vec;
410  if ( import_data == true )
411  actual_vec.reset (new Epetra_FEVector (new_map));
412  else
413  {
414  vector.reset (new Epetra_FEVector (new_map));
415  actual_vec = vector;
416  }
417 
418  TrilinosScalar *entries = (*actual_vec)[0];
419  block_offset = 0;
420  for (size_type block=0; block<v.n_blocks(); ++block)
421  {
422  v.block(block).trilinos_vector().ExtractCopy (entries, 0);
423  entries += v.block(block).local_size();
424  }
425 
426  if (import_data == true)
427  {
428  AssertThrow (static_cast<size_type>(global_length(*actual_vec))
429  == v.size(),
430  ExcDimensionMismatch (global_length(*actual_vec),
431  v.size()));
432 
433  Epetra_Import data_exchange (vector->Map(), actual_vec->Map());
434 
435  const int ierr = vector->Import(*actual_vec, data_exchange, Insert);
436  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
437 
438  last_action = Insert;
439  }
440 #if defined(DEBUG) && defined(DEAL_II_WITH_MPI)
441  const Epetra_MpiComm *comm_ptr
442  = dynamic_cast<const Epetra_MpiComm *>(&(vector->Comm()));
443  Assert (comm_ptr != 0, ExcInternalError());
444  const size_type n_elements_global
445  = Utilities::MPI::sum (owned_elements.n_elements(), comm_ptr->Comm());
446 
447  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
448 #endif
449  }
450 
451 
452  void Vector::reinit(const IndexSet &locally_owned_entries,
453  const IndexSet &ghost_entries,
454  const MPI_Comm &communicator,
455  const bool vector_writable)
456  {
457  nonlocal_vector.reset();
458  owned_elements = locally_owned_entries;
459  if (vector_writable == false)
460  {
461  IndexSet parallel_partitioner = locally_owned_entries;
462  parallel_partitioner.add_indices(ghost_entries);
463  Epetra_Map map = parallel_partitioner.make_trilinos_map (communicator,
464  true);
465  vector.reset (new Epetra_FEVector(map));
466  has_ghosts = vector->Map().UniqueGIDs()==false;
467 
468  last_action = Zero;
469  }
470  else
471  {
472  Epetra_Map map = locally_owned_entries.make_trilinos_map (communicator,
473  true);
474  Assert (map.IsOneToOne(),
475  ExcMessage("A writable vector must not have ghost entries in "
476  "its parallel partitioning"));
477  reinit (map);
478 
479  IndexSet nonlocal_entries(ghost_entries);
480  nonlocal_entries.subtract_set(locally_owned_entries);
481  if (Utilities::MPI::n_mpi_processes(communicator) > 1)
482  {
483  Epetra_Map nonlocal_map =
484  nonlocal_entries.make_trilinos_map(communicator, true);
485  nonlocal_vector.reset(new Epetra_MultiVector(nonlocal_map, 1));
486  }
487  }
488 #ifdef DEBUG
489  const size_type n_elements_global
490  = Utilities::MPI::sum (owned_elements.n_elements(), communicator);
491 
492  Assert (has_ghosts || n_elements_global == size(), ExcInternalError());
493 #endif
494  }
495 
496 
497 
498  Vector &
500  {
501  // check equality for MPI communicators to avoid accessing a possibly
502  // invalid MPI_Comm object
503 #ifdef DEAL_II_WITH_MPI
504  const Epetra_MpiComm *my_comm = dynamic_cast<const Epetra_MpiComm *>(&vector->Comm());
505  const Epetra_MpiComm *v_comm = dynamic_cast<const Epetra_MpiComm *>(&v.vector->Comm());
506  const bool same_communicators = my_comm != NULL && v_comm != NULL &&
507  my_comm->DataPtr() == v_comm->DataPtr();
508  // Need to ask MPI whether the communicators are the same. We would like
509  // to use the following checks but currently we cannot make sure the
510  // memory of my_comm is not stale from some MPI_Comm_free
511  // somewhere. This can happen when a vector lives in GrowingVectorMemory
512  // data structures. Thus, the following code is commented out.
513  //
514  //if (my_comm != NULL && v_comm != NULL && my_comm->DataPtr() != v_comm->DataPtr())
515  // {
516  // int communicators_same = 0;
517  // const int ierr = MPI_Comm_compare (my_comm->GetMpiComm(),
518  // v_comm->GetMpiComm(),
519  // &communicators_same);
520  // AssertThrowMPI(ierr);
521  // if (!(communicators_same == MPI_IDENT ||
522  // communicators_same == MPI_CONGRUENT))
523  // same_communicators = false;
524  // else
525  // same_communicators = true;
526  // }
527 #else
528  const bool same_communicators = true;
529 #endif
530 
531  // distinguish three cases. First case: both vectors have the same
532  // layout (just need to copy the local data, not reset the memory and
533  // the underlying Epetra_Map). The third case means that we have to
534  // rebuild the calling vector.
535  if (same_communicators && v.vector->Map().SameAs(vector->Map()))
536  {
537  *vector = *v.vector;
538  if (v.nonlocal_vector.get() != 0)
539  nonlocal_vector.reset(new Epetra_MultiVector(v.nonlocal_vector->Map(), 1));
540  last_action = Zero;
541  }
542  // Second case: vectors have the same global
543  // size, but different parallel layouts (and
544  // one of them a one-to-one mapping). Then we
545  // can call the import/export functionality.
546  else if (size() == v.size() &&
547  (v.vector->Map().UniqueGIDs() || vector->Map().UniqueGIDs()))
548  {
549  reinit (v, false, true);
550  }
551  // Third case: Vectors do not have the same
552  // size.
553  else
554  {
555  vector.reset (new Epetra_FEVector(*v.vector));
556  last_action = Zero;
557  has_ghosts = v.has_ghosts;
558  owned_elements = v.owned_elements;
559  }
560 
561  if (v.nonlocal_vector.get() != 0)
562  nonlocal_vector.reset(new Epetra_MultiVector(v.nonlocal_vector->Map(), 1));
563 
564  return *this;
565  }
566 
567 
568 
569 #ifdef DEAL_II_WITH_CXX11
571  {
572  swap(v);
573  return *this;
574  }
575 #endif
576 
577 
578 
579  Vector &
581  {
582  nonlocal_vector.reset();
583 
584  Assert (size() == v.size(), ExcDimensionMismatch(size(), v.size()));
585 
586  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
587  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
588 
589  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
590 
591  last_action = Insert;
592 
593  return *this;
594  }
595 
596 
597 
598  void
600  const Vector &v)
601  {
602  Assert (m.trilinos_matrix().Filled() == true,
603  ExcMessage ("Matrix is not compressed. "
604  "Cannot find exchange information!"));
605  Assert (v.vector->Map().UniqueGIDs() == true,
606  ExcMessage ("The input vector has overlapping data, "
607  "which is not allowed."));
608 
609  if (vector->Map().SameAs(m.trilinos_matrix().ColMap()) == false)
610  {
611  vector.reset (new Epetra_FEVector(
612  m.trilinos_matrix().ColMap()
613  ));
614  }
615 
616  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
617  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
618 
619  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
620 
621  last_action = Insert;
622  }
623 
624  } /* end of namespace MPI */
625 
626 
627 
628 
630  {
631  last_action = Zero;
632  Epetra_LocalMap map (0, 0, Utilities::Trilinos::comm_self());
633  vector.reset (new Epetra_FEVector(map));
634  }
635 
636 
637 
639  {
640  reinit(n);
641  }
642 
643 
644 
645  Vector::Vector (const Epetra_Map &input_map)
646  {
647  reinit(input_map);
648  }
649 
650 
651 
652  Vector::Vector (const IndexSet &partitioning,
653  const MPI_Comm &communicator)
654  {
655  reinit (partitioning, communicator);
656  }
657 
658 
659 
661  {
662  last_action = Zero;
663  Epetra_LocalMap map (n_global_elements(v.vector->Map()),
664  v.vector->Map().IndexBase(),
665  v.vector->Map().Comm());
666  vector.reset (new Epetra_FEVector(map));
667 
668  if (vector->Map().SameAs(v.vector->Map()) == true)
669  {
670  const int ierr = vector->Update(1.0, *v.vector, 0.0);
671  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
672  }
673  else
674  reinit (v, false, true);
675  }
676 
677 
678 
679  void
681  const bool /*omit_zeroing_entries*/)
682  {
683  owned_elements = complete_index_set(n);
684  Epetra_LocalMap map ((TrilinosWrappers::types::int_type)n, 0,
686  vector.reset (new Epetra_FEVector (map));
687 
688  last_action = Zero;
689  }
690 
691 
692 
693  void
694  Vector::reinit (const Epetra_Map &input_map,
695  const bool /*omit_zeroing_entries*/)
696  {
697  Epetra_LocalMap map (n_global_elements(input_map),
698  input_map.IndexBase(),
699  input_map.Comm());
700  vector.reset (new Epetra_FEVector(map));
701  owned_elements = complete_index_set(n_global_elements(input_map));
702 
703  last_action = Zero;
704  }
705 
706 
707 
708  void
709  Vector::reinit (const IndexSet &partitioning,
710  const MPI_Comm &communicator,
711  const bool /*omit_zeroing_entries*/)
712  {
713  Epetra_LocalMap map (static_cast<TrilinosWrappers::types::int_type>(partitioning.size()),
714  0,
715 #ifdef DEAL_II_WITH_MPI
716  Epetra_MpiComm(communicator));
717 #else
718  Epetra_SerialComm());
719  (void)communicator;
720 #endif
721  vector.reset (new Epetra_FEVector(map));
722 
723  last_action = Zero;
724  owned_elements = partitioning;
725  }
726 
727 
728 
729  void
731  const bool omit_zeroing_entries,
732  const bool allow_different_maps)
733  {
734  // In case we do not allow to
735  // have different maps, this
736  // call means that we have to
737  // reset the vector. So clear
738  // the vector, initialize our
739  // map with the map in v, and
740  // generate the vector.
741  if (allow_different_maps == false)
742  {
743  // check equality for MPI communicators
744 #ifdef DEAL_II_WITH_MPI
745  const Epetra_MpiComm *my_comm = dynamic_cast<const Epetra_MpiComm *>(&vector->Comm());
746  const Epetra_MpiComm *v_comm = dynamic_cast<const Epetra_MpiComm *>(&v.vector->Comm());
747  const bool same_communicators = my_comm != NULL && v_comm != NULL &&
748  my_comm->DataPtr() == v_comm->DataPtr();
749 #else
750  const bool same_communicators = true;
751 #endif
752  if (!same_communicators || local_range() != v.local_range())
753  {
754  Epetra_LocalMap map (global_length(*(v.vector)),
755  v.vector->Map().IndexBase(),
756  v.vector->Comm());
757  vector.reset (new Epetra_FEVector(map));
759  }
760  else if (omit_zeroing_entries)
761  {
762  int ierr;
763  Assert (vector->Map().SameAs(v.vector->Map()) == true,
764  ExcMessage ("The Epetra maps in the assignment operator ="
765  " do not match, even though the local_range "
766  " seems to be the same. Check vector setup!"));
767 
768  ierr = vector->GlobalAssemble(last_action);
769  (void)ierr;
770  Assert (ierr == 0, ExcTrilinosError(ierr));
771 
772  ierr = vector->PutScalar(0.0);
773  Assert (ierr == 0, ExcTrilinosError(ierr));
774  }
775  last_action = Zero;
776  }
777 
778  // Otherwise, we have to check
779  // that the two vectors are
780  // already of the same size,
781  // create an object for the data
782  // exchange and then insert all
783  // the data.
784  else
785  {
786  Assert (omit_zeroing_entries == false,
787  ExcMessage ("It is not possible to exchange data with the "
788  "option 'omit_zeroing_entries' set, which would not write "
789  "elements."));
790 
791  AssertThrow (size() == v.size(),
792  ExcDimensionMismatch (size(), v.size()));
793 
794  Epetra_Import data_exchange (vector->Map(), v.vector->Map());
795 
796  const int ierr = vector->Import(*v.vector, data_exchange, Insert);
797  AssertThrow (ierr == 0, ExcTrilinosError(ierr));
798 
799  last_action = Insert;
800  }
801 
802  }
803 
804 
805 
806  Vector &
808  {
809  if (size() != v.size())
810  {
811  Epetra_LocalMap map (n_global_elements(v.vector->Map()),
812  v.vector->Map().IndexBase(),
813  v.vector->Comm());
814  vector.reset (new Epetra_FEVector(map));
815  }
816 
817  reinit (v, false, true);
818  return *this;
819  }
820 
821 
822 
823  Vector &
825  {
826  if (size() != v.size())
827  {
828  Epetra_LocalMap map (n_global_elements(v.vector->Map()),
829  v.vector->Map().IndexBase(),
830  v.vector->Comm());
831  vector.reset (new Epetra_FEVector(map));
832  owned_elements = v.owned_elements;
833  }
834 
835  const int ierr = vector->Update(1.0, *v.vector, 0.0);
836  Assert (ierr == 0, ExcTrilinosError(ierr));
837  (void)ierr;
838 
839  return *this;
840  }
841 
842 }
843 
844 DEAL_II_NAMESPACE_CLOSE
845 
846 #endif // DEAL_II_WITH_TRILINOS
Vector & operator=(const TrilinosScalar s)
::types::global_dof_index size_type
Vector & operator=(const TrilinosScalar s)
std_cxx11::shared_ptr< Epetra_MultiVector > nonlocal_vector
std::pair< size_type, size_type > local_range() const
void add_indices(const ForwardIterator &begin, const ForwardIterator &end)
Definition: index_set.h:1463
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
const Epetra_Comm & comm_self()
Definition: utilities.cc:736
void reinit(const VectorBase &v, const bool omit_zeroing_entries=false, const bool allow_different_maps=false)
Epetra_Map make_trilinos_map(const MPI_Comm &communicator=MPI_COMM_WORLD, const bool overlapping=false) const
Definition: index_set.cc:535
size_type size() const
Definition: index_set.h:1419
void clear()
Definition: index_set.h:1393
static ::ExceptionBase & ExcMessage(std::string arg1)
std::size_t size() const
T sum(const T &t, const MPI_Comm &mpi_communicator)
std_cxx11::shared_ptr< Epetra_FEVector > vector
void subtract_set(const IndexSet &other)
Definition: index_set.cc:278
#define Assert(cond, exc)
Definition: exceptions.h:313
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
std::size_t size() const
void swap(Vector &u, Vector &v)
const Epetra_CrsMatrix & trilinos_matrix() const
void import_nonlocal_data_for_fe(const ::TrilinosWrappers::SparseMatrix &matrix, const Vector &vector)
static ::ExceptionBase & ExcTrilinosError(int arg1)
unsigned int n_mpi_processes(const MPI_Comm &mpi_communicator)
Definition: mpi.cc:63
void add_range(const size_type begin, const size_type end)
Definition: index_set.cc:88
void set_size(const size_type size)
Definition: index_set.h:1406
void compress() const
Definition: index_set.h:1428
unsigned int n_blocks() const
void reinit(const size_type n, const bool omit_zeroing_entries=false)
::types::global_dof_index size_type
BlockType & block(const unsigned int i)
size_type n_elements() const
Definition: index_set.h:1560
static ::ExceptionBase & ExcInternalError()