libMesh
trilinos_epetra_vector.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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  std::scoped_lock lock(this->_numeric_vector_mutex);
170  ReplaceGlobalValues(1, &i, &value);
171 
172  this->_is_closed = false;
173 }
174 
175 
176 
177 template <typename T>
179 {
180  // The Epetra::reciprocal() function takes a constant reference to *another* vector,
181  // and fills _vec with its reciprocal. Does that mean we can't pass *_vec as the
182  // argument?
183  // _vec->reciprocal( *_vec );
184 
185  // Alternatively, compute the reciprocal by hand... see also the add(T) member that does this...
186  const unsigned int nl = _vec->MyLength();
187 
188  T * values = _vec->Values();
189 
190  for (unsigned int i=0; i<nl; i++)
191  {
192  // Don't divide by zero (maybe only check this in debug mode?)
193  libmesh_error_msg_if(std::abs(values[i]) < std::numeric_limits<T>::min(),
194  "Error, divide by zero in DistributedVector<T>::reciprocal()!");
195 
196  values[i] = 1. / values[i];
197  }
198 
199  // Leave the vector in a closed state...
200  this->close();
201 }
202 
203 
204 
205 template <typename T>
207 {
208  // EPetra is real, rendering this a no-op.
209 }
210 
211 
212 
213 template <typename T>
214 void EpetraVector<T>::add (const numeric_index_type i_in, const T value_in)
215 {
216  int i = static_cast<int> (i_in);
217  T value = value_in;
218 
219  libmesh_assert_less (i_in, this->size());
220 
221  std::scoped_lock lock(this->_numeric_vector_mutex);
222  SumIntoGlobalValues(1, &i, &value);
223 
224  this->_is_closed = false;
225 }
226 
227 
228 
229 template <typename T>
230 void EpetraVector<T>::add_vector (const T * v,
231  const std::vector<numeric_index_type> & dof_indices)
232 {
233  libmesh_assert_equal_to (sizeof(numeric_index_type), sizeof(int));
234 
235  std::scoped_lock lock(this->_numeric_vector_mutex);
236  SumIntoGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
237  numeric_trilinos_cast(dof_indices.data()),
238  const_cast<T *>(v));
239 }
240 
241 
242 
243 // TODO: fill this in after creating an EpetraMatrix
244 template <typename T>
246  const SparseMatrix<T> & A_in)
247 {
248  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
249  const EpetraMatrix<T> * A = cast_ptr<const EpetraMatrix<T> *>(&A_in);
250 
251  // FIXME - does Trilinos let us do this *without* memory allocation?
252  std::unique_ptr<NumericVector<T>> temp = v->zero_clone();
253  EpetraVector<T> * temp_v = cast_ptr<EpetraVector<T> *>(temp.get());
254  A->mat()->Multiply(false, *v->_vec, *temp_v->_vec);
255  *this += *temp;
256 }
257 
258 
259 
260 // TODO: fill this in after creating an EpetraMatrix
261 template <typename T>
263  const SparseMatrix<T> & /* A_in */)
264 {
265  libmesh_not_implemented();
266 }
267 
268 
269 
270 template <typename T>
271 void EpetraVector<T>::add (const T v_in)
272 {
273  const unsigned int nl = _vec->MyLength();
274 
275  T * values = _vec->Values();
276 
277  for (unsigned int i=0; i<nl; i++)
278  values[i]+=v_in;
279 
280  this->_is_closed = false;
281 }
282 
283 
284 template <typename T>
286 {
287  this->add (1., v);
288 }
289 
290 
291 template <typename T>
292 void EpetraVector<T>::add (const T a_in, const NumericVector<T> & v_in)
293 {
294  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
295 
296  libmesh_assert_equal_to (this->size(), v->size());
297 
298  _vec->Update(a_in,*v->_vec, 1.);
299 }
300 
301 
302 
303 template <typename T>
304 void EpetraVector<T>::insert (const T * v,
305  const std::vector<numeric_index_type> & dof_indices)
306 {
307  libmesh_assert_equal_to (sizeof(numeric_index_type), sizeof(int));
308 
309  std::scoped_lock lock(this->_numeric_vector_mutex);
310  ReplaceGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
311  numeric_trilinos_cast(dof_indices.data()),
312  const_cast<T *>(v));
313  this->_is_closed = false;
314 }
315 
316 
317 
318 template <typename T>
319 void EpetraVector<T>::scale (const T factor_in)
320 {
321  _vec->Scale(factor_in);
322 }
323 
324 template <typename T>
326 {
327  _vec->Abs(*_vec);
328 }
329 
330 
331 template <typename T>
333 {
334  const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
335 
336  T result=0.0;
337 
338  _vec->Dot(*v->_vec, &result);
339 
340  return result;
341 }
342 
343 
344 template <typename T>
346  const NumericVector<T> & vec2)
347 {
348  const EpetraVector<T> * v1 = cast_ptr<const EpetraVector<T> *>(&vec1);
349  const EpetraVector<T> * v2 = cast_ptr<const EpetraVector<T> *>(&vec2);
350 
351  _vec->Multiply(1.0, *v1->_vec, *v2->_vec, 0.0);
352 }
353 
354 
355 template <typename T>
358 {
359  _vec->PutScalar(s_in);
360 
361  return *this;
362 }
363 
364 
365 
366 template <typename T>
369 {
370  // This function could be implemented in terms of the copy
371  // assignment operator (see other NumericVector subclasses) but that
372  // function is currently deleted so calling this function is an error.
373  // const EpetraVector<T> * v = cast_ptr<const EpetraVector<T> *>(&v_in);
374  // *this = *v;
375  libmesh_not_implemented();
376  return *this;
377 }
378 
379 
380 
381 template <typename T>
383 EpetraVector<T>::operator = (const std::vector<T> & v)
384 {
385  T * values = _vec->Values();
386 
391  if (this->size() == v.size())
392  {
393  const unsigned int nl=this->local_size();
394  const unsigned int fli=this->first_local_index();
395 
396  for (unsigned int i=0;i<nl;i++)
397  values[i]=v[fli+i];
398  }
399 
404  else
405  {
406  libmesh_assert_equal_to (v.size(), this->local_size());
407 
408  const unsigned int nl=this->local_size();
409 
410  for (unsigned int i=0;i<nl;i++)
411  values[i]=v[i];
412  }
413 
414  return *this;
415 }
416 
417 
418 
419 template <typename T>
421 {
422  EpetraVector<T> * v_local = cast_ptr<EpetraVector<T> *>(&v_local_in);
423 
424  Epetra_Map rootMap = Epetra_Util::Create_Root_Map( *_map, -1);
425  v_local->_vec->ReplaceMap(rootMap);
426 
427  Epetra_Import importer(v_local->_vec->Map(), *_map);
428  v_local->_vec->Import(*_vec, importer, Insert);
429 }
430 
431 
432 
433 template <typename T>
435  const std::vector<numeric_index_type> & /* send_list */) const
436 {
437  // TODO: optimize to sync only the send list values
438  this->localize(v_local_in);
439 
440  // EpetraVector<T> * v_local =
441  // cast_ptr<EpetraVector<T> *>(&v_local_in);
442 
443  // libmesh_assert(this->_map.get());
444  // libmesh_assert(v_local->_map.get());
445  // libmesh_assert_equal_to (v_local->local_size(), this->size());
446  // libmesh_assert_less_equal (send_list.size(), v_local->size());
447 
448  // Epetra_Import importer (*v_local->_map, *this->_map);
449 
450  // v_local->_vec->Import (*this->_vec, importer, Insert);
451 }
452 
453 
454 
455 template <typename T>
456 void EpetraVector<T>::localize (std::vector<T> & v_local,
457  const std::vector<numeric_index_type> & indices) const
458 {
459  // Create a "replicated" map for importing values. This is
460  // equivalent to creating a general Epetra_Map with
461  // NumGlobalElements == NumMyElements.
462  Epetra_LocalMap import_map(static_cast<int>(indices.size()),
463  /*IndexBase=*/0,
464  _map->Comm());
465 
466  // Get a pointer to the list of global elements for the map, and set
467  // all the values from indices.
468  int * import_map_global_elements = import_map.MyGlobalElements();
469  for (auto i : index_range(indices))
470  import_map_global_elements[i] = indices[i];
471 
472  // Create a new EpetraVector to import values into.
473  Epetra_Vector import_vector(import_map);
474 
475  // Set up an "Import" object which associates the two maps.
476  Epetra_Import import_object(import_map, *_map);
477 
478  // Import the values
479  import_vector.Import(*_vec, import_object, Insert);
480 
481  // Get a pointer to the imported values array and the length of the
482  // array.
483  T * values = import_vector.Values();
484  int import_vector_length = import_vector.MyLength();
485 
486  // Copy the imported values into v_local
487  v_local.resize(import_vector_length);
488  for (int i=0; i<import_vector_length; ++i)
489  v_local[i] = values[i];
490 }
491 
492 
493 
494 template <typename T>
495 void EpetraVector<T>::localize (const numeric_index_type first_local_idx,
496  const numeric_index_type last_local_idx,
497  const std::vector<numeric_index_type> & send_list)
498 {
499  // Only good for serial vectors.
500  libmesh_assert_equal_to (this->size(), this->local_size());
501  libmesh_assert_greater (last_local_idx, first_local_idx);
502  libmesh_assert_less_equal (send_list.size(), this->size());
503  libmesh_assert_less (last_local_idx, this->size());
504 
505  const unsigned int my_size = this->size();
506  const unsigned int my_local_size = (last_local_idx - first_local_idx + 1);
507 
508  // Don't bother for serial cases
509  if ((first_local_idx == 0) &&
510  (my_local_size == my_size))
511  return;
512 
513  // Build a parallel vector, initialize it with the local
514  // parts of (*this)
515  EpetraVector<T> parallel_vec(this->comm(), PARALLEL);
516 
517  parallel_vec.init (my_size, my_local_size, true, PARALLEL);
518 
519  // Copy part of *this into the parallel_vec
520  for (numeric_index_type i=first_local_idx; i<=last_local_idx; i++)
521  parallel_vec.set(i,this->el(i));
522 
523  // localize like normal
524  parallel_vec.close();
525  parallel_vec.localize (*this, send_list);
526  this->close();
527 }
528 
529 
530 
531 template <typename T>
532 void EpetraVector<T>::localize (std::vector<T> & v_local) const
533 {
534  // This function must be run on all processors at once
535  parallel_object_only();
536 
537  const unsigned int n = this->size();
538  const unsigned int nl = this->local_size();
539 
540  libmesh_assert(this->_vec);
541 
542  v_local.clear();
543  v_local.reserve(n);
544 
545  // build up my local part
546  for (unsigned int i=0; i<nl; i++)
547  v_local.push_back((*this->_vec)[i]);
548 
549  this->comm().allgather (v_local);
550 }
551 
552 
553 
554 template <typename T>
555 void EpetraVector<T>::localize_to_one (std::vector<T> & v_local,
556  const processor_id_type pid) const
557 {
558  // This function must be run on all processors at once
559  parallel_object_only();
560 
561  const unsigned int n = this->size();
562  const unsigned int nl = this->local_size();
563 
564  libmesh_assert_less (pid, this->n_processors());
565  libmesh_assert(this->_vec);
566 
567  v_local.clear();
568  v_local.reserve(n);
569 
570 
571  // build up my local part
572  for (unsigned int i=0; i<nl; i++)
573  v_local.push_back((*this->_vec)[i]);
574 
575  this->comm().gather (pid, v_local);
576 }
577 
578 
579 /*********************************************************************
580  * The following were copied (and slightly modified) from
581  * Epetra_FEVector.h in order to allow us to use a standard
582  * Epetra_Vector... which is more compatible with other Trilinos
583  * packages such as NOX. All of this code is originally under LGPL
584  *********************************************************************/
585 
586 //----------------------------------------------------------------------------
587 template <typename T>
589  const int * GIDs,
590  const double * values)
591 {
592  return( inputValues( numIDs, GIDs, values, true) );
593 }
594 
595 //----------------------------------------------------------------------------
596 template <typename T>
597 int EpetraVector<T>::SumIntoGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
598  const Epetra_SerialDenseVector & values)
599 {
600  if (GIDs.Length() != values.Length()) {
601  return(-1);
602  }
603 
604  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), true) );
605 }
606 
607 //----------------------------------------------------------------------------
608 template <typename T>
610  const int * GIDs,
611  const int * numValuesPerID,
612  const double * values)
613 {
614  return( inputValues( numIDs, GIDs, numValuesPerID, values, true) );
615 }
616 
617 //----------------------------------------------------------------------------
618 template <typename T>
620  const int * GIDs,
621  const double * values)
622 {
623  return( inputValues( numIDs, GIDs, values, false) );
624 }
625 
626 //----------------------------------------------------------------------------
627 template <typename T>
628 int EpetraVector<T>::ReplaceGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
629  const Epetra_SerialDenseVector & values)
630 {
631  if (GIDs.Length() != values.Length()) {
632  return(-1);
633  }
634 
635  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), false) );
636 }
637 
638 //----------------------------------------------------------------------------
639 template <typename T>
641  const int * GIDs,
642  const int * numValuesPerID,
643  const double * values)
644 {
645  return( inputValues( numIDs, GIDs, numValuesPerID, values, false) );
646 }
647 
648 //----------------------------------------------------------------------------
649 template <typename T>
651  const int * GIDs,
652  const double * values,
653  bool accumulate)
654 {
655  if (accumulate) {
656  libmesh_assert(last_edit == 0 || last_edit == 2);
657  last_edit = 2;
658  } else {
659  libmesh_assert(last_edit == 0 || last_edit == 1);
660  last_edit = 1;
661  }
662 
663  //Important note!! This method assumes that there is only 1 point
664  //associated with each element.
665 
666  for (int i=0; i<numIDs; ++i) {
667  if (_vec->Map().MyGID(GIDs[i])) {
668  if (accumulate) {
669  _vec->SumIntoGlobalValue(GIDs[i], 0, 0, values[i]);
670  }
671  else {
672  _vec->ReplaceGlobalValue(GIDs[i], 0, 0, values[i]);
673  }
674  }
675  else {
676  if (!ignoreNonLocalEntries_) {
677  EPETRA_CHK_ERR( inputNonlocalValue(GIDs[i], values[i], accumulate) );
678  }
679  }
680  }
681 
682  return(0);
683 }
684 
685 //----------------------------------------------------------------------------
686 template <typename T>
688  const int * GIDs,
689  const int * numValuesPerID,
690  const double * values,
691  bool accumulate)
692 {
693  if (accumulate) {
694  libmesh_assert(last_edit == 0 || last_edit == 2);
695  last_edit = 2;
696  } else {
697  libmesh_assert(last_edit == 0 || last_edit == 1);
698  last_edit = 1;
699  }
700 
701  int offset=0;
702  for (int i=0; i<numIDs; ++i) {
703  int numValues = numValuesPerID[i];
704  if (_vec->Map().MyGID(GIDs[i])) {
705  if (accumulate) {
706  for (int j=0; j<numValues; ++j) {
707  _vec->SumIntoGlobalValue(GIDs[i], j, 0, values[offset+j]);
708  }
709  }
710  else {
711  for (int j=0; j<numValues; ++j) {
712  _vec->ReplaceGlobalValue(GIDs[i], j, 0, values[offset+j]);
713  }
714  }
715  }
716  else {
717  if (!ignoreNonLocalEntries_) {
718  EPETRA_CHK_ERR( inputNonlocalValues(GIDs[i], numValues,
719  &(values[offset]), accumulate) );
720  }
721  }
722  offset += numValues;
723  }
724 
725  return(0);
726 }
727 
728 //----------------------------------------------------------------------------
729 template <typename T>
730 int EpetraVector<T>::inputNonlocalValue(int GID, double value, bool accumulate)
731 {
732  int insertPoint = -1;
733 
734  //find offset of GID in nonlocalIDs_
735  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
736  insertPoint);
737  if (offset >= 0) {
738  //if offset >= 0
739  // put value in nonlocalCoefs_[offset][0]
740 
741  if (accumulate) {
742  nonlocalCoefs_[offset][0] += value;
743  }
744  else {
745  nonlocalCoefs_[offset][0] = value;
746  }
747  }
748  else {
749  //else
750  // insert GID in nonlocalIDs_
751  // insert 1 in nonlocalElementSize_
752  // insert value in nonlocalCoefs_
753 
754  int tmp1 = numNonlocalIDs_;
755  int tmp2 = allocatedNonlocalLength_;
756  int tmp3 = allocatedNonlocalLength_;
757  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
758  tmp1, tmp2) );
759  --tmp1;
760  EPETRA_CHK_ERR( Epetra_Util_insert(1, insertPoint, nonlocalElementSize_,
761  tmp1, tmp3) );
762  double * values = new double[1];
763  values[0] = value;
764  EPETRA_CHK_ERR( Epetra_Util_insert(values, insertPoint, nonlocalCoefs_,
765  numNonlocalIDs_, allocatedNonlocalLength_) );
766  }
767 
768  return(0);
769 }
770 
771 //----------------------------------------------------------------------------
772 template <typename T>
774  int numValues,
775  const double * values,
776  bool accumulate)
777 {
778  int insertPoint = -1;
779 
780  //find offset of GID in nonlocalIDs_
781  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
782  insertPoint);
783  if (offset >= 0) {
784  //if offset >= 0
785  // put value in nonlocalCoefs_[offset][0]
786 
787  if (numValues != nonlocalElementSize_[offset]) {
788  libMesh::err << "Epetra_FEVector ERROR: block-size for GID " << GID << " is "
789  << numValues<<" which doesn't match previously set block-size of "
790  << nonlocalElementSize_[offset] << std::endl;
791  return(-1);
792  }
793 
794  if (accumulate) {
795  for (int j=0; j<numValues; ++j) {
796  nonlocalCoefs_[offset][j] += values[j];
797  }
798  }
799  else {
800  for (int j=0; j<numValues; ++j) {
801  nonlocalCoefs_[offset][j] = values[j];
802  }
803  }
804  }
805  else {
806  //else
807  // insert GID in nonlocalIDs_
808  // insert numValues in nonlocalElementSize_
809  // insert values in nonlocalCoefs_
810 
811  int tmp1 = numNonlocalIDs_;
812  int tmp2 = allocatedNonlocalLength_;
813  int tmp3 = allocatedNonlocalLength_;
814  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
815  tmp1, tmp2) );
816  --tmp1;
817  EPETRA_CHK_ERR( Epetra_Util_insert(numValues, insertPoint, nonlocalElementSize_,
818  tmp1, tmp3) );
819  double * newvalues = new double[numValues];
820  for (int j=0; j<numValues; ++j) {
821  newvalues[j] = values[j];
822  }
823  EPETRA_CHK_ERR( Epetra_Util_insert(newvalues, insertPoint, nonlocalCoefs_,
824  numNonlocalIDs_, allocatedNonlocalLength_) );
825  }
826 
827  return(0);
828 }
829 
830 //----------------------------------------------------------------------------
831 template <typename T>
832 int EpetraVector<T>::GlobalAssemble(Epetra_CombineMode mode)
833 {
834  //In this method we need to gather all the non-local (overlapping) data
835  //that's been input on each processor, into the (probably) non-overlapping
836  //distribution defined by the map that 'this' vector was constructed with.
837 
838  //We don't need to do anything if there's only one processor or if
839  //ignoreNonLocalEntries_ is true.
840  if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
841  return(0);
842  }
843 
844 
845 
846  //First build a map that describes the data in nonlocalIDs_/nonlocalCoefs_.
847  //We'll use the arbitrary distribution constructor of Map.
848 
849  Epetra_BlockMap sourceMap(-1, numNonlocalIDs_,
850  nonlocalIDs_, nonlocalElementSize_,
851  _vec->Map().IndexBase(), _vec->Map().Comm());
852 
853  //Now build a vector to hold our nonlocalCoefs_, and to act as the source-
854  //vector for our import operation.
855  Epetra_MultiVector nonlocalVector(sourceMap, 1);
856 
857  int i,j;
858  for (i=0; i<numNonlocalIDs_; ++i) {
859  for (j=0; j<nonlocalElementSize_[i]; ++j) {
860  nonlocalVector.ReplaceGlobalValue(nonlocalIDs_[i], j, 0,
861  nonlocalCoefs_[i][j]);
862  }
863  }
864 
865  Epetra_Export exporter(sourceMap, _vec->Map());
866 
867  EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) );
868 
869  destroyNonlocalData();
870 
871  return(0);
872 }
873 
874 #include <libmesh/ignore_warnings.h> // deprecated-copy in Epetra_Vector
875 
876 //----------------------------------------------------------------------------
877 template <typename T>
879 {
880  (*_vec) = *(source._vec);
881 
882  destroyNonlocalData();
883 
884  if (source.allocatedNonlocalLength_ > 0) {
885  allocatedNonlocalLength_ = source.allocatedNonlocalLength_;
886  numNonlocalIDs_ = source.numNonlocalIDs_;
887  nonlocalIDs_ = new int[allocatedNonlocalLength_];
888  nonlocalElementSize_ = new int[allocatedNonlocalLength_];
889  nonlocalCoefs_ = new double *[allocatedNonlocalLength_];
890  for (int i=0; i<numNonlocalIDs_; ++i) {
891  int elemSize = source.nonlocalElementSize_[i];
892  nonlocalCoefs_[i] = new double[elemSize];
893  nonlocalIDs_[i] = source.nonlocalIDs_[i];
894  nonlocalElementSize_[i] = elemSize;
895  for (int j=0; j<elemSize; ++j) {
896  nonlocalCoefs_[i][j] = source.nonlocalCoefs_[i][j];
897  }
898  }
899  }
900 }
901 
902 #include <libmesh/restore_warnings.h>
903 
904 //----------------------------------------------------------------------------
905 template <typename T>
907 {
908  if (allocatedNonlocalLength_ > 0) {
909  delete [] nonlocalIDs_;
910  delete [] nonlocalElementSize_;
911  nonlocalIDs_ = nullptr;
912  nonlocalElementSize_ = nullptr;
913  for (int i=0; i<numNonlocalIDs_; ++i) {
914  delete [] nonlocalCoefs_[i];
915  }
916  delete [] nonlocalCoefs_;
917  nonlocalCoefs_ = nullptr;
918  numNonlocalIDs_ = 0;
919  allocatedNonlocalLength_ = 0;
920  }
921  return;
922 }
923 
924 
925 //------------------------------------------------------------------
926 // Explicit instantiations
927 template class LIBMESH_EXPORT EpetraVector<Number>;
928 
929 } // namespace libMesh
930 
931 #endif // LIBMESH_TRILINOS_HAVE_EPETRA
OStreamProxy err
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector&#39;s entries by another&#39;s, .
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:283
This class provides a nice interface to the Trilinos Epetra_Vector object.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual void reciprocal() override
Computes the component-wise reciprocal, .
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
virtual void close() override
Calls the NumericVector&#39;s internal assembly routines, ensuring that the values are consistent across ...
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
virtual numeric_index_type size() const =0
Epetra_Vector * _vec
Actual Epetra vector datatype to hold vector entries.
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.
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
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.
int inputNonlocalValues(int GID, int numValues, const double *values, bool accumulate)
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
The libMesh namespace provides an interface to certain functionality in the library.
virtual T sum() const override
int GlobalAssemble(Epetra_CombineMode mode=Add)
Gather any overlapping/shared data into the non-overlapping partitioning defined by the Map that was ...
virtual numeric_index_type size() const override
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
uint8_t processor_id_type
Definition: id_types.h:104
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...
int inputValues(int numIDs, const int *GIDs, const double *values, bool accumulate)
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
dof_id_type numeric_index_type
Definition: id_types.h:99
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector&#39;s entries by another&#39;s, ...
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
virtual Real l1_norm() const override
libmesh_assert(ctx)
virtual void abs() override
Sets for each entry in the vector.
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
int inputNonlocalValue(int GID, double value, bool accumulate)
virtual Real linfty_norm() const override
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.
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual T dot(const NumericVector< T > &v) const override
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...
virtual Real l2_norm() const override
static const bool value
Definition: xdr_io.C:54
void FEoperatorequals(const EpetraVector &source)
int * numeric_trilinos_cast(const numeric_index_type *p)
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
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]...
This class provides a nice interface to the Epetra data structures for parallel, sparse matrices...
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117
EpetraVector & operator=(const EpetraVector &)=delete