libMesh
trilinos_epetra_vector.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // C++ includes
19 #include <limits>
20 
21 // Local Includes
22 #include "libmesh/trilinos_epetra_vector.h"
23 
24 #ifdef LIBMESH_TRILINOS_HAVE_EPETRA
25 
26 #include "libmesh/dense_subvector.h"
27 #include "libmesh/dense_vector.h"
28 #include "libmesh/parallel.h"
29 #include "libmesh/trilinos_epetra_matrix.h"
30 #include "libmesh/utility.h"
31 
32 // Trilinos Includes
33 #include "libmesh/ignore_warnings.h"
34 #include <Epetra_LocalMap.h>
35 #include <Epetra_Comm.h>
36 #include <Epetra_Map.h>
37 #include <Epetra_BlockMap.h>
38 #include <Epetra_Import.h>
39 #include <Epetra_Export.h>
40 #include <Epetra_Util.h>
41 #include <Epetra_IntSerialDenseVector.h>
42 #include <Epetra_SerialDenseVector.h>
43 #include <Epetra_Vector.h>
44 #include "libmesh/restore_warnings.h"
45 
46 namespace libMesh
47 {
48 
49 template <typename T>
51 {
52  libmesh_assert(this->closed());
53 
54  const unsigned int nl = _vec->MyLength();
55 
56  T sum=0.0;
57 
58  T * values = _vec->Values();
59 
60  for (unsigned int i=0; i<nl; i++)
61  sum += values[i];
62 
63  this->comm().sum(sum);
64 
65  return sum;
66 }
67 
68 template <typename T>
70 {
71  libmesh_assert(this->closed());
72 
73  Real value;
74 
75  _vec->Norm1(&value);
76 
77  return value;
78 }
79 
80 template <typename T>
82 {
83  libmesh_assert(this->closed());
84 
85  Real value;
86 
87  _vec->Norm2(&value);
88 
89  return value;
90 }
91 
92 template <typename T>
94 {
95  libmesh_assert(this->closed());
96 
97  Real value;
98 
99  _vec->NormInf(&value);
100 
101  return value;
102 }
103 
104 template <typename T>
107 {
108  libmesh_assert(this->closed());
109 
110  this->add(1., v);
111 
112  return *this;
113 }
114 
115 
116 
117 template <typename T>
120 {
121  libmesh_assert(this->closed());
122 
123  this->add(-1., v);
124 
125  return *this;
126 }
127 
128 
129 template <typename T>
132 {
133  libmesh_assert(this->closed());
134  libmesh_assert_equal_to(size(), v.size());
135 
136  const EpetraVector<T> & v_vec = cast_ref<const EpetraVector<T> &>(v);
137 
138  _vec->Multiply(1.0, *v_vec._vec, *_vec, 0.0);
139 
140  return *this;
141 }
142 
143 
144 template <typename T>
147 {
148  libmesh_assert(this->closed());
149  libmesh_assert_equal_to(size(), v.size());
150 
151  const EpetraVector<T> & v_vec = cast_ref<const EpetraVector<T> &>(v);
152 
153  _vec->ReciprocalMultiply(1.0, *v_vec._vec, *_vec, 0.0);
154 
155  return *this;
156 }
157 
158 
159 
160 
161 template <typename T>
162 void EpetraVector<T>::set (const numeric_index_type i_in, const T value_in)
163 {
164  int i = static_cast<int> (i_in);
165  T value = value_in;
166 
167  libmesh_assert_less (i_in, this->size());
168 
169  ReplaceGlobalValues(1, &i, &value);
170 
171  this->_is_closed = false;
172 }
173 
174 
175 
176 template <typename T>
178 {
179  // The Epetra::reciprocal() function takes a constant reference to *another* vector,
180  // and fills _vec with its reciprocal. Does that mean we can't pass *_vec as the
181  // argument?
182  // _vec->reciprocal( *_vec );
183 
184  // Alternatively, compute the reciprocal by hand... see also the add(T) member that does this...
185  const unsigned int nl = _vec->MyLength();
186 
187  T * values = _vec->Values();
188 
189  for (unsigned int i=0; i<nl; i++)
190  {
191  // Don't divide by zero (maybe only check this in debug mode?)
192  if (std::abs(values[i]) < std::numeric_limits<T>::min())
193  libmesh_error_msg("Error, divide by zero in DistributedVector<T>::reciprocal()!");
194 
195  values[i] = 1. / values[i];
196  }
197 
198  // Leave the vector in a closed state...
199  this->close();
200 }
201 
202 
203 
204 template <typename T>
206 {
207  // EPetra is real, rendering this a no-op.
208 }
209 
210 
211 
212 template <typename T>
213 void EpetraVector<T>::add (const numeric_index_type i_in, const T value_in)
214 {
215  int i = static_cast<int> (i_in);
216  T value = value_in;
217 
218  libmesh_assert_less (i_in, this->size());
219 
220  SumIntoGlobalValues(1, &i, &value);
221 
222  this->_is_closed = false;
223 }
224 
225 
226 
227 template <typename T>
228 void EpetraVector<T>::add_vector (const T * v,
229  const std::vector<numeric_index_type> & dof_indices)
230 {
231  libmesh_assert_equal_to (sizeof(numeric_index_type), sizeof(int));
232 
233  SumIntoGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
234  numeric_trilinos_cast(dof_indices.data()),
235  const_cast<T *>(v));
236 }
237 
238 
239 
240 // TODO: fill this in after creating an EpetraMatrix
241 template <typename T>
243  const SparseMatrix<T> & A_in)
244 {
245  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
246  const EpetraMatrix<T> * A = cast_ptr<const EpetraMatrix<T> *>(&A_in);
247 
248  // FIXME - does Trilinos let us do this *without* memory allocation?
249  std::unique_ptr<NumericVector<T>> temp = v->zero_clone();
250  EpetraVector<T> * temp_v = cast_ptr<EpetraVector<T> *>(temp.get());
251  A->mat()->Multiply(false, *v->_vec, *temp_v->_vec);
252  *this += *temp;
253 }
254 
255 
256 
257 // TODO: fill this in after creating an EpetraMatrix
258 template <typename T>
260  const SparseMatrix<T> & /* A_in */)
261 {
262  libmesh_not_implemented();
263 }
264 
265 
266 
267 template <typename T>
268 void EpetraVector<T>::add (const T v_in)
269 {
270  const unsigned int nl = _vec->MyLength();
271 
272  T * values = _vec->Values();
273 
274  for (unsigned int i=0; i<nl; i++)
275  values[i]+=v_in;
276 
277  this->_is_closed = false;
278 }
279 
280 
281 template <typename T>
283 {
284  this->add (1., v);
285 }
286 
287 
288 template <typename T>
289 void EpetraVector<T>::add (const T a_in, const NumericVector<T> & v_in)
290 {
291  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
292 
293  libmesh_assert_equal_to (this->size(), v->size());
294 
295  _vec->Update(a_in,*v->_vec, 1.);
296 }
297 
298 
299 
300 template <typename T>
301 void EpetraVector<T>::insert (const T * v,
302  const std::vector<numeric_index_type> & dof_indices)
303 {
304  libmesh_assert_equal_to (sizeof(numeric_index_type), sizeof(int));
305 
306  ReplaceGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
307  numeric_trilinos_cast(dof_indices.data()),
308  const_cast<T *>(v));
309 }
310 
311 
312 
313 template <typename T>
314 void EpetraVector<T>::scale (const T factor_in)
315 {
316  _vec->Scale(factor_in);
317 }
318 
319 template <typename T>
321 {
322  _vec->Abs(*_vec);
323 }
324 
325 
326 template <typename T>
328 {
329  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
330 
331  T result=0.0;
332 
333  _vec->Dot(*v->_vec, &result);
334 
335  return result;
336 }
337 
338 
339 template <typename T>
341  const NumericVector<T> & vec2)
342 {
343  const EpetraVector<T> * v1 = cast_ptr<const EpetraVector<T> *>(&vec1);
344  const EpetraVector<T> * v2 = cast_ptr<const EpetraVector<T> *>(&vec2);
345 
346  _vec->Multiply(1.0, *v1->_vec, *v2->_vec, 0.0);
347 }
348 
349 
350 template <typename T>
353 {
354  _vec->PutScalar(s_in);
355 
356  return *this;
357 }
358 
359 
360 
361 template <typename T>
364 {
365  // This function could be implemented in terms of the copy
366  // assignment operator (see other NumericVector subclasses) but that
367  // function is currently deleted so calling this function is an error.
368  // const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
369  // *this = *v;
370  libmesh_not_implemented();
371  return *this;
372 }
373 
374 
375 
376 template <typename T>
378 EpetraVector<T>::operator = (const std::vector<T> & v)
379 {
380  T * values = _vec->Values();
381 
386  if (this->size() == v.size())
387  {
388  const unsigned int nl=this->local_size();
389  const unsigned int fli=this->first_local_index();
390 
391  for (unsigned int i=0;i<nl;i++)
392  values[i]=v[fli+i];
393  }
394 
399  else
400  {
401  libmesh_assert_equal_to (v.size(), this->local_size());
402 
403  const unsigned int nl=this->local_size();
404 
405  for (unsigned int i=0;i<nl;i++)
406  values[i]=v[i];
407  }
408 
409  return *this;
410 }
411 
412 
413 
414 template <typename T>
416 {
417  EpetraVector<T> * v_local = cast_ptr<EpetraVector<T> *>(&v_local_in);
418 
419  Epetra_Map rootMap = Epetra_Util::Create_Root_Map( *_map, -1);
420  v_local->_vec->ReplaceMap(rootMap);
421 
422  Epetra_Import importer(v_local->_vec->Map(), *_map);
423  v_local->_vec->Import(*_vec, importer, Insert);
424 }
425 
426 
427 
428 template <typename T>
430  const std::vector<numeric_index_type> & /* send_list */) const
431 {
432  // TODO: optimize to sync only the send list values
433  this->localize(v_local_in);
434 
435  // EpetraVector<T> * v_local =
436  // cast_ptr<EpetraVector<T> *>(&v_local_in);
437 
438  // libmesh_assert(this->_map.get());
439  // libmesh_assert(v_local->_map.get());
440  // libmesh_assert_equal_to (v_local->local_size(), this->size());
441  // libmesh_assert_less_equal (send_list.size(), v_local->size());
442 
443  // Epetra_Import importer (*v_local->_map, *this->_map);
444 
445  // v_local->_vec->Import (*this->_vec, importer, Insert);
446 }
447 
448 
449 
450 template <typename T>
451 void EpetraVector<T>::localize (std::vector<T> & v_local,
452  const std::vector<numeric_index_type> & indices) const
453 {
454  // Create a "replicated" map for importing values. This is
455  // equivalent to creating a general Epetra_Map with
456  // NumGlobalElements == NumMyElements.
457  Epetra_LocalMap import_map(static_cast<int>(indices.size()),
458  /*IndexBase=*/0,
459  _map->Comm());
460 
461  // Get a pointer to the list of global elements for the map, and set
462  // all the values from indices.
463  int * import_map_global_elements = import_map.MyGlobalElements();
464  for (auto i : index_range(indices))
465  import_map_global_elements[i] = indices[i];
466 
467  // Create a new EpetraVector to import values into.
468  Epetra_Vector import_vector(import_map);
469 
470  // Set up an "Import" object which associates the two maps.
471  Epetra_Import import_object(import_map, *_map);
472 
473  // Import the values
474  import_vector.Import(*_vec, import_object, Insert);
475 
476  // Get a pointer to the imported values array and the length of the
477  // array.
478  T * values = import_vector.Values();
479  int import_vector_length = import_vector.MyLength();
480 
481  // Copy the imported values into v_local
482  v_local.resize(import_vector_length);
483  for (int i=0; i<import_vector_length; ++i)
484  v_local[i] = values[i];
485 }
486 
487 
488 
489 template <typename T>
490 void EpetraVector<T>::localize (const numeric_index_type first_local_idx,
491  const numeric_index_type last_local_idx,
492  const std::vector<numeric_index_type> & send_list)
493 {
494  // Only good for serial vectors.
495  libmesh_assert_equal_to (this->size(), this->local_size());
496  libmesh_assert_greater (last_local_idx, first_local_idx);
497  libmesh_assert_less_equal (send_list.size(), this->size());
498  libmesh_assert_less (last_local_idx, this->size());
499 
500  const unsigned int my_size = this->size();
501  const unsigned int my_local_size = (last_local_idx - first_local_idx + 1);
502 
503  // Don't bother for serial cases
504  if ((first_local_idx == 0) &&
505  (my_local_size == my_size))
506  return;
507 
508  // Build a parallel vector, initialize it with the local
509  // parts of (*this)
510  EpetraVector<T> parallel_vec(this->comm(), PARALLEL);
511 
512  parallel_vec.init (my_size, my_local_size, true, PARALLEL);
513 
514  // Copy part of *this into the parallel_vec
515  for (numeric_index_type i=first_local_idx; i<=last_local_idx; i++)
516  parallel_vec.set(i,this->el(i));
517 
518  // localize like normal
519  parallel_vec.close();
520  parallel_vec.localize (*this, send_list);
521  this->close();
522 }
523 
524 
525 
526 template <typename T>
527 void EpetraVector<T>::localize (std::vector<T> & v_local) const
528 {
529  // This function must be run on all processors at once
530  parallel_object_only();
531 
532  const unsigned int n = this->size();
533  const unsigned int nl = this->local_size();
534 
535  libmesh_assert(this->_vec);
536 
537  v_local.clear();
538  v_local.reserve(n);
539 
540  // build up my local part
541  for (unsigned int i=0; i<nl; i++)
542  v_local.push_back((*this->_vec)[i]);
543 
544  this->comm().allgather (v_local);
545 }
546 
547 
548 
549 template <typename T>
550 void EpetraVector<T>::localize_to_one (std::vector<T> & v_local,
551  const processor_id_type pid) const
552 {
553  // This function must be run on all processors at once
554  parallel_object_only();
555 
556  const unsigned int n = this->size();
557  const unsigned int nl = this->local_size();
558 
559  libmesh_assert_less (pid, this->n_processors());
560  libmesh_assert(this->_vec);
561 
562  v_local.clear();
563  v_local.reserve(n);
564 
565 
566  // build up my local part
567  for (unsigned int i=0; i<nl; i++)
568  v_local.push_back((*this->_vec)[i]);
569 
570  this->comm().gather (pid, v_local);
571 }
572 
573 
574 
575 template <typename T>
577  const std::vector<numeric_index_type> & /* rows */) const
578 {
579  libmesh_not_implemented();
580 }
581 
582 
583 /*********************************************************************
584  * The following were copied (and slightly modified) from
585  * Epetra_FEVector.h in order to allow us to use a standard
586  * Epetra_Vector... which is more compatible with other Trilinos
587  * packages such as NOX. All of this code is originally under LGPL
588  *********************************************************************/
589 
590 //----------------------------------------------------------------------------
591 template <typename T>
593  const int * GIDs,
594  const double * values)
595 {
596  return( inputValues( numIDs, GIDs, values, true) );
597 }
598 
599 //----------------------------------------------------------------------------
600 template <typename T>
601 int EpetraVector<T>::SumIntoGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
602  const Epetra_SerialDenseVector & values)
603 {
604  if (GIDs.Length() != values.Length()) {
605  return(-1);
606  }
607 
608  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), true) );
609 }
610 
611 //----------------------------------------------------------------------------
612 template <typename T>
614  const int * GIDs,
615  const int * numValuesPerID,
616  const double * values)
617 {
618  return( inputValues( numIDs, GIDs, numValuesPerID, values, true) );
619 }
620 
621 //----------------------------------------------------------------------------
622 template <typename T>
624  const int * GIDs,
625  const double * values)
626 {
627  return( inputValues( numIDs, GIDs, values, false) );
628 }
629 
630 //----------------------------------------------------------------------------
631 template <typename T>
632 int EpetraVector<T>::ReplaceGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
633  const Epetra_SerialDenseVector & values)
634 {
635  if (GIDs.Length() != values.Length()) {
636  return(-1);
637  }
638 
639  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), false) );
640 }
641 
642 //----------------------------------------------------------------------------
643 template <typename T>
645  const int * GIDs,
646  const int * numValuesPerID,
647  const double * values)
648 {
649  return( inputValues( numIDs, GIDs, numValuesPerID, values, false) );
650 }
651 
652 //----------------------------------------------------------------------------
653 template <typename T>
654 int EpetraVector<T>::inputValues(int numIDs,
655  const int * GIDs,
656  const double * values,
657  bool accumulate)
658 {
659  if (accumulate) {
660  libmesh_assert(last_edit == 0 || last_edit == 2);
661  last_edit = 2;
662  } else {
663  libmesh_assert(last_edit == 0 || last_edit == 1);
664  last_edit = 1;
665  }
666 
667  //Important note!! This method assumes that there is only 1 point
668  //associated with each element.
669 
670  for (int i=0; i<numIDs; ++i) {
671  if (_vec->Map().MyGID(GIDs[i])) {
672  if (accumulate) {
673  _vec->SumIntoGlobalValue(GIDs[i], 0, 0, values[i]);
674  }
675  else {
676  _vec->ReplaceGlobalValue(GIDs[i], 0, 0, values[i]);
677  }
678  }
679  else {
680  if (!ignoreNonLocalEntries_) {
681  EPETRA_CHK_ERR( inputNonlocalValue(GIDs[i], values[i], accumulate) );
682  }
683  }
684  }
685 
686  return(0);
687 }
688 
689 //----------------------------------------------------------------------------
690 template <typename T>
691 int EpetraVector<T>::inputValues(int numIDs,
692  const int * GIDs,
693  const int * numValuesPerID,
694  const double * values,
695  bool accumulate)
696 {
697  if (accumulate) {
698  libmesh_assert(last_edit == 0 || last_edit == 2);
699  last_edit = 2;
700  } else {
701  libmesh_assert(last_edit == 0 || last_edit == 1);
702  last_edit = 1;
703  }
704 
705  int offset=0;
706  for (int i=0; i<numIDs; ++i) {
707  int numValues = numValuesPerID[i];
708  if (_vec->Map().MyGID(GIDs[i])) {
709  if (accumulate) {
710  for (int j=0; j<numValues; ++j) {
711  _vec->SumIntoGlobalValue(GIDs[i], j, 0, values[offset+j]);
712  }
713  }
714  else {
715  for (int j=0; j<numValues; ++j) {
716  _vec->ReplaceGlobalValue(GIDs[i], j, 0, values[offset+j]);
717  }
718  }
719  }
720  else {
721  if (!ignoreNonLocalEntries_) {
722  EPETRA_CHK_ERR( inputNonlocalValues(GIDs[i], numValues,
723  &(values[offset]), accumulate) );
724  }
725  }
726  offset += numValues;
727  }
728 
729  return(0);
730 }
731 
732 //----------------------------------------------------------------------------
733 template <typename T>
734 int EpetraVector<T>::inputNonlocalValue(int GID, double value, bool accumulate)
735 {
736  int insertPoint = -1;
737 
738  //find offset of GID in nonlocalIDs_
739  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
740  insertPoint);
741  if (offset >= 0) {
742  //if offset >= 0
743  // put value in nonlocalCoefs_[offset][0]
744 
745  if (accumulate) {
746  nonlocalCoefs_[offset][0] += value;
747  }
748  else {
749  nonlocalCoefs_[offset][0] = value;
750  }
751  }
752  else {
753  //else
754  // insert GID in nonlocalIDs_
755  // insert 1 in nonlocalElementSize_
756  // insert value in nonlocalCoefs_
757 
758  int tmp1 = numNonlocalIDs_;
759  int tmp2 = allocatedNonlocalLength_;
760  int tmp3 = allocatedNonlocalLength_;
761  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
762  tmp1, tmp2) );
763  --tmp1;
764  EPETRA_CHK_ERR( Epetra_Util_insert(1, insertPoint, nonlocalElementSize_,
765  tmp1, tmp3) );
766  double * values = new double[1];
767  values[0] = value;
768  EPETRA_CHK_ERR( Epetra_Util_insert(values, insertPoint, nonlocalCoefs_,
769  numNonlocalIDs_, allocatedNonlocalLength_) );
770  }
771 
772  return(0);
773 }
774 
775 //----------------------------------------------------------------------------
776 template <typename T>
778  int numValues,
779  const double * values,
780  bool accumulate)
781 {
782  int insertPoint = -1;
783 
784  //find offset of GID in nonlocalIDs_
785  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
786  insertPoint);
787  if (offset >= 0) {
788  //if offset >= 0
789  // put value in nonlocalCoefs_[offset][0]
790 
791  if (numValues != nonlocalElementSize_[offset]) {
792  libMesh::err << "Epetra_FEVector ERROR: block-size for GID " << GID << " is "
793  << numValues<<" which doesn't match previously set block-size of "
794  << nonlocalElementSize_[offset] << std::endl;
795  return(-1);
796  }
797 
798  if (accumulate) {
799  for (int j=0; j<numValues; ++j) {
800  nonlocalCoefs_[offset][j] += values[j];
801  }
802  }
803  else {
804  for (int j=0; j<numValues; ++j) {
805  nonlocalCoefs_[offset][j] = values[j];
806  }
807  }
808  }
809  else {
810  //else
811  // insert GID in nonlocalIDs_
812  // insert numValues in nonlocalElementSize_
813  // insert values in nonlocalCoefs_
814 
815  int tmp1 = numNonlocalIDs_;
816  int tmp2 = allocatedNonlocalLength_;
817  int tmp3 = allocatedNonlocalLength_;
818  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
819  tmp1, tmp2) );
820  --tmp1;
821  EPETRA_CHK_ERR( Epetra_Util_insert(numValues, insertPoint, nonlocalElementSize_,
822  tmp1, tmp3) );
823  double * newvalues = new double[numValues];
824  for (int j=0; j<numValues; ++j) {
825  newvalues[j] = values[j];
826  }
827  EPETRA_CHK_ERR( Epetra_Util_insert(newvalues, insertPoint, nonlocalCoefs_,
828  numNonlocalIDs_, allocatedNonlocalLength_) );
829  }
830 
831  return(0);
832 }
833 
834 //----------------------------------------------------------------------------
835 template <typename T>
836 int EpetraVector<T>::GlobalAssemble(Epetra_CombineMode mode)
837 {
838  //In this method we need to gather all the non-local (overlapping) data
839  //that's been input on each processor, into the (probably) non-overlapping
840  //distribution defined by the map that 'this' vector was constructed with.
841 
842  //We don't need to do anything if there's only one processor or if
843  //ignoreNonLocalEntries_ is true.
844  if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
845  return(0);
846  }
847 
848 
849 
850  //First build a map that describes the data in nonlocalIDs_/nonlocalCoefs_.
851  //We'll use the arbitrary distribution constructor of Map.
852 
853  Epetra_BlockMap sourceMap(-1, numNonlocalIDs_,
854  nonlocalIDs_, nonlocalElementSize_,
855  _vec->Map().IndexBase(), _vec->Map().Comm());
856 
857  //Now build a vector to hold our nonlocalCoefs_, and to act as the source-
858  //vector for our import operation.
859  Epetra_MultiVector nonlocalVector(sourceMap, 1);
860 
861  int i,j;
862  for (i=0; i<numNonlocalIDs_; ++i) {
863  for (j=0; j<nonlocalElementSize_[i]; ++j) {
864  nonlocalVector.ReplaceGlobalValue(nonlocalIDs_[i], j, 0,
865  nonlocalCoefs_[i][j]);
866  }
867  }
868 
869  Epetra_Export exporter(sourceMap, _vec->Map());
870 
871  EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) );
872 
873  destroyNonlocalData();
874 
875  return(0);
876 }
877 
878 #include <libmesh/ignore_warnings.h> // deprecated-copy in Epetra_Vector
879 
880 //----------------------------------------------------------------------------
881 template <typename T>
883 {
884  (*_vec) = *(source._vec);
885 
886  destroyNonlocalData();
887 
888  if (source.allocatedNonlocalLength_ > 0) {
889  allocatedNonlocalLength_ = source.allocatedNonlocalLength_;
890  numNonlocalIDs_ = source.numNonlocalIDs_;
891  nonlocalIDs_ = new int[allocatedNonlocalLength_];
892  nonlocalElementSize_ = new int[allocatedNonlocalLength_];
893  nonlocalCoefs_ = new double *[allocatedNonlocalLength_];
894  for (int i=0; i<numNonlocalIDs_; ++i) {
895  int elemSize = source.nonlocalElementSize_[i];
896  nonlocalCoefs_[i] = new double[elemSize];
897  nonlocalIDs_[i] = source.nonlocalIDs_[i];
898  nonlocalElementSize_[i] = elemSize;
899  for (int j=0; j<elemSize; ++j) {
900  nonlocalCoefs_[i][j] = source.nonlocalCoefs_[i][j];
901  }
902  }
903  }
904 }
905 
906 #include <libmesh/restore_warnings.h>
907 
908 //----------------------------------------------------------------------------
909 template <typename T>
911 {
912  if (allocatedNonlocalLength_ > 0) {
913  delete [] nonlocalIDs_;
914  delete [] nonlocalElementSize_;
915  nonlocalIDs_ = nullptr;
916  nonlocalElementSize_ = nullptr;
917  for (int i=0; i<numNonlocalIDs_; ++i) {
918  delete [] nonlocalCoefs_[i];
919  }
920  delete [] nonlocalCoefs_;
921  nonlocalCoefs_ = nullptr;
922  numNonlocalIDs_ = 0;
923  allocatedNonlocalLength_ = 0;
924  }
925  return;
926 }
927 
928 
929 //------------------------------------------------------------------
930 // Explicit instantiations
931 template class EpetraVector<Number>;
932 
933 } // namespace libMesh
934 
935 #endif // LIBMESH_TRILINOS_HAVE_EPETRA
libMesh::EpetraVector::operator*=
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector's entries by another's, .
Definition: trilinos_epetra_vector.C:131
libMesh::EpetraVector::zero_clone
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
Definition: trilinos_epetra_vector.h:705
libMesh::EpetraVector::allocatedNonlocalLength_
int allocatedNonlocalLength_
Definition: trilinos_epetra_vector.h:389
libMesh::EpetraVector::operator-=
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
Definition: trilinos_epetra_vector.C:119
libMesh::EpetraVector::nonlocalElementSize_
int * nonlocalElementSize_
Definition: trilinos_epetra_vector.h:387
libMesh::EpetraVector::destroyNonlocalData
void destroyNonlocalData()
Definition: trilinos_epetra_vector.C:909
libMesh::EpetraVector::inputValues
int inputValues(int numIDs, const int *GIDs, const double *values, bool accumulate)
Definition: trilinos_epetra_vector.C:653
libMesh::EpetraVector::FEoperatorequals
void FEoperatorequals(const EpetraVector &source)
Definition: trilinos_epetra_vector.C:881
libMesh::PARALLEL
Definition: enum_parallel_type.h:36
libMesh::EpetraVector::SumIntoGlobalValues
int SumIntoGlobalValues(int numIDs, const int *GIDs, const double *values)
Accumulate values into the vector, adding them to any values that already exist for the specified ind...
Definition: trilinos_epetra_vector.C:591
libMesh::EpetraVector::create_subvector
virtual void create_subvector(NumericVector< T > &subvector, const std::vector< numeric_index_type > &rows) const override
Fills in subvector from this vector using the indices in rows.
Definition: trilinos_epetra_vector.C:576
libMesh::EpetraVector::conjugate
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
Definition: trilinos_epetra_vector.C:205
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::EpetraVector::scale
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
Definition: trilinos_epetra_vector.C:314
libMesh::EpetraVector::ReplaceGlobalValues
int ReplaceGlobalValues(int numIDs, const int *GIDs, const double *values)
Copy values into the vector overwriting any values that already exist for the specified indices.
Definition: trilinos_epetra_vector.C:622
libMesh::EpetraVector::localize
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
Definition: trilinos_epetra_vector.C:527
libMesh::EpetraVector::GlobalAssemble
int GlobalAssemble(Epetra_CombineMode mode=Add)
Gather any overlapping/shared data into the non-overlapping partitioning defined by the Map that was ...
Definition: trilinos_epetra_vector.C:835
libMesh::EpetraVector::insert
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Inserts the entries of v in *this at the locations specified by v.
Definition: trilinos_epetra_vector.C:301
libMesh::EpetraVector::linfty_norm
virtual Real linfty_norm() const override
Definition: trilinos_epetra_vector.C:93
libMesh::SparseMatrix
Generic sparse matrix.
Definition: vector_fe_ex5.C:45
libMesh::EpetraVector::reciprocal
virtual void reciprocal() override
Computes the component-wise reciprocal, .
Definition: trilinos_epetra_vector.C:177
libMesh::NumericVector::size
virtual numeric_index_type size() const =0
libMesh::NumericVector
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
Definition: vector_fe_ex5.C:43
libMesh::EpetraVector
This class provides a nice interface to the Trilinos Epetra_Vector object.
Definition: trilinos_epetra_vector.h:63
libMesh::EpetraVector::init
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType type=AUTOMATIC) override
Change the dimension of the vector to n.
Definition: trilinos_epetra_vector.h:566
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::EpetraVector::inputNonlocalValues
int inputNonlocalValues(int GID, int numValues, const double *values, bool accumulate)
Definition: trilinos_epetra_vector.C:776
libMesh::EpetraVector::operator/=
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector's entries by another's, .
Definition: trilinos_epetra_vector.C:146
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::EpetraVector::set
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
Definition: trilinos_epetra_vector.C:162
libMesh::EpetraVector::close
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
Definition: trilinos_epetra_vector.h:647
libMesh::EpetraMatrix
This class provides a nice interface to the Epetra data structures for parallel, sparse matrices.
Definition: trilinos_epetra_matrix.h:63
libMesh::EpetraVector::inputNonlocalValue
int inputNonlocalValue(int GID, double value, bool accumulate)
Definition: trilinos_epetra_vector.C:733
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::EpetraVector::dot
virtual T dot(const NumericVector< T > &v) const override
Definition: trilinos_epetra_vector.C:327
libMesh::EpetraVector::operator=
EpetraVector & operator=(const EpetraVector &)=delete
libMesh::EpetraVector::_vec
Epetra_Vector * _vec
Actual Epetra vector datatype to hold vector entries.
Definition: trilinos_epetra_vector.h:271
libMesh::EpetraVector::l1_norm
virtual Real l1_norm() const override
Definition: trilinos_epetra_vector.C:69
A
static PetscErrorCode Mat * A
Definition: petscdmlibmeshimpl.C:1026
libMesh::EpetraVector::size
virtual numeric_index_type size() const override
Definition: trilinos_epetra_vector.h:728
libMesh::numeric_index_type
dof_id_type numeric_index_type
Definition: id_types.h:99
libMesh::EpetraVector::l2_norm
virtual Real l2_norm() const override
Definition: trilinos_epetra_vector.C:81
libMesh::EpetraVector::pointwise_mult
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
Definition: trilinos_epetra_vector.C:340
value
static const bool value
Definition: xdr_io.C:56
libMesh::EpetraVector::add_vector_transpose
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
Definition: trilinos_epetra_vector.C:259
libMesh::EpetraVector::abs
virtual void abs() override
Sets for each entry in the vector.
Definition: trilinos_epetra_vector.C:320
libMesh::EpetraVector::nonlocalIDs_
int * nonlocalIDs_
Definition: trilinos_epetra_vector.h:386
libMesh::numeric_trilinos_cast
int * numeric_trilinos_cast(const numeric_index_type *p)
Definition: trilinos_epetra_vector.h:836
libMesh::EpetraVector::operator+=
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
Definition: trilinos_epetra_vector.C:106
libMesh::EpetraVector::localize_to_one
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
Creates a local copy of the global vector in v_local only on processor proc_id.
Definition: trilinos_epetra_vector.C:550
libMesh::EpetraVector::nonlocalCoefs_
double ** nonlocalCoefs_
Definition: trilinos_epetra_vector.h:390
libMesh::err
OStreamProxy err
libMesh::EpetraVector::add
virtual void add(const numeric_index_type i, const T value) override
Adds value to each entry of the vector.
Definition: trilinos_epetra_vector.C:213
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::EpetraVector::add_vector
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
Definition: trilinos_epetra_vector.C:228
libMesh::EpetraVector::sum
virtual T sum() const override
Definition: trilinos_epetra_vector.C:50
libMesh::EpetraVector::numNonlocalIDs_
int numNonlocalIDs_
Definition: trilinos_epetra_vector.h:388
libMesh::closed
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:272