libMesh
Loading...
Searching...
No Matches
trilinos_epetra_vector.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
46namespace libMesh
47{
48
49template <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
68template <typename T>
70{
71 libmesh_assert(this->closed());
72
73 Real value;
74
75 _vec->Norm1(&value);
76
77 return value;
78}
79
80template <typename T>
82{
83 libmesh_assert(this->closed());
84
85 Real value;
86
87 _vec->Norm2(&value);
88
89 return value;
90}
91
92template <typename T>
94{
95 libmesh_assert(this->closed());
96
97 Real value;
98
99 _vec->NormInf(&value);
100
101 return value;
102}
103
104template <typename T>
107{
108 libmesh_assert(this->closed());
109
110 this->add(1., v);
111
112 return *this;
113}
114
115
116
117template <typename T>
120{
121 libmesh_assert(this->closed());
122
123 this->add(-1., v);
124
125 return *this;
126}
127
128
129template <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
144template <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
161template <typename T>
162void 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
177template <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
205template <typename T>
207{
208 // EPetra is real, rendering this a no-op.
209}
210
211
212
213template <typename T>
214void 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
229template <typename T>
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
244template <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
261template <typename T>
263 const SparseMatrix<T> & /* A_in */)
264{
265 libmesh_not_implemented();
266}
267
268
269
270template <typename T>
271void 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
284template <typename T>
286{
287 this->add (1., v);
288}
289
290
291template <typename T>
292void 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
303template <typename T>
304void 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
318template <typename T>
319void EpetraVector<T>::scale (const T factor_in)
320{
321 _vec->Scale(factor_in);
322}
323
324template <typename T>
326{
327 _vec->Abs(*_vec);
328}
329
330
331template <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
344template <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
355template <typename T>
358{
359 _vec->PutScalar(s_in);
360
361 return *this;
362}
363
364
365
366template <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
381template <typename T>
383EpetraVector<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
419template <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
433template <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
455template <typename T>
456void 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
494template <typename T>
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
531template <typename T>
532void 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
554template <typename T>
555void 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//----------------------------------------------------------------------------
587template <typename T>
589 const int * GIDs,
590 const double * values)
591{
592 return( inputValues( numIDs, GIDs, values, true) );
593}
594
595//----------------------------------------------------------------------------
596template <typename T>
597int 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//----------------------------------------------------------------------------
608template <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//----------------------------------------------------------------------------
618template <typename T>
620 const int * GIDs,
621 const double * values)
622{
623 return( inputValues( numIDs, GIDs, values, false) );
624}
625
626//----------------------------------------------------------------------------
627template <typename T>
628int 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//----------------------------------------------------------------------------
639template <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//----------------------------------------------------------------------------
649template <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//----------------------------------------------------------------------------
686template <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//----------------------------------------------------------------------------
729template <typename T>
730int 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//----------------------------------------------------------------------------
772template <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//----------------------------------------------------------------------------
831template <typename T>
832int 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//----------------------------------------------------------------------------
877template <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//----------------------------------------------------------------------------
905template <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
927template class LIBMESH_EXPORT EpetraVector<Number>;
928
929} // namespace libMesh
930
931#endif // LIBMESH_TRILINOS_HAVE_EPETRA
This class provides a nice interface to the Epetra data structures for parallel, sparse matrices.
This class provides a nice interface to the Trilinos Epetra_Vector object.
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
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 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 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].
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
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.
virtual void abs() override
Sets for each entry in the vector.
void FEoperatorequals(const EpetraVector &source)
int inputNonlocalValue(int GID, double value, bool accumulate)
int inputNonlocalValues(int GID, int numValues, const double *values, bool accumulate)
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
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.
virtual numeric_index_type size() const override
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
EpetraVector & operator=(const EpetraVector &)=delete
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual T sum() const override
int inputValues(int numIDs, const int *GIDs, const double *values, bool accumulate)
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 Real l1_norm() const override
virtual void reciprocal() override
Computes the component-wise reciprocal, .
virtual T dot(const NumericVector< T > &v) const override
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector's entries by another's, .
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector's entries by another's, .
virtual Real linfty_norm() const override
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
int GlobalAssemble(Epetra_CombineMode mode=Add)
Gather any overlapping/shared data into the non-overlapping partitioning defined by the Map that was ...
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
virtual Real l2_norm() const override
Epetra_Vector * _vec
Actual Epetra vector datatype to hold vector entries.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual numeric_index_type size() const =0
Generic sparse matrix.
The libMesh namespace provides an interface to certain functionality in the library.
OStreamProxy err
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:153
bool closed()
Checks that the library has been closed.
Definition libmesh.C:331
libmesh_assert(ctx)
dof_id_type numeric_index_type
Definition id_types.h:99
int * numeric_trilinos_cast(const numeric_index_type *p)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
Definition id_types.h:104
static const bool value
Definition xdr_io.C:55