22 #include "libmesh/trilinos_epetra_vector.h"
24 #ifdef LIBMESH_TRILINOS_HAVE_EPETRA
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"
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"
54 const unsigned int nl = _vec->MyLength();
58 T * values = _vec->Values();
60 for (
unsigned int i=0; i<nl; i++)
63 this->comm().sum(sum);
99 _vec->NormInf(&
value);
104 template <
typename T>
117 template <
typename T>
129 template <
typename T>
134 libmesh_assert_equal_to(size(), v.
size());
138 _vec->Multiply(1.0, *v_vec._vec, *_vec, 0.0);
144 template <
typename T>
149 libmesh_assert_equal_to(size(), v.
size());
153 _vec->ReciprocalMultiply(1.0, *v_vec._vec, *_vec, 0.0);
161 template <
typename T>
164 int i = static_cast<int> (i_in);
167 libmesh_assert_less (i_in, this->size());
169 ReplaceGlobalValues(1, &i, &
value);
171 this->_is_closed =
false;
176 template <
typename T>
185 const unsigned int nl = _vec->MyLength();
187 T * values = _vec->Values();
189 for (
unsigned int i=0; i<nl; i++)
192 if (
std::abs(values[i]) < std::numeric_limits<T>::min())
193 libmesh_error_msg(
"Error, divide by zero in DistributedVector<T>::reciprocal()!");
195 values[i] = 1. / values[i];
204 template <
typename T>
212 template <
typename T>
215 int i = static_cast<int> (i_in);
218 libmesh_assert_less (i_in, this->size());
220 SumIntoGlobalValues(1, &i, &
value);
222 this->_is_closed =
false;
227 template <
typename T>
229 const std::vector<numeric_index_type> & dof_indices)
233 SumIntoGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
241 template <
typename T>
249 std::unique_ptr<NumericVector<T>> temp = v->
zero_clone();
251 A->mat()->Multiply(
false, *v->
_vec, *temp_v->
_vec);
258 template <
typename T>
262 libmesh_not_implemented();
267 template <
typename T>
270 const unsigned int nl = _vec->MyLength();
272 T * values = _vec->Values();
274 for (
unsigned int i=0; i<nl; i++)
277 this->_is_closed =
false;
281 template <
typename T>
288 template <
typename T>
293 libmesh_assert_equal_to (this->size(), v->
size());
295 _vec->Update(a_in,*v->
_vec, 1.);
300 template <
typename T>
302 const std::vector<numeric_index_type> & dof_indices)
306 ReplaceGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
313 template <
typename T>
316 _vec->Scale(factor_in);
319 template <
typename T>
326 template <
typename T>
333 _vec->Dot(*v->
_vec, &result);
339 template <
typename T>
346 _vec->Multiply(1.0, *v1->
_vec, *v2->_vec, 0.0);
350 template <
typename T>
354 _vec->PutScalar(s_in);
361 template <
typename T>
370 libmesh_not_implemented();
376 template <
typename T>
380 T * values = _vec->Values();
386 if (this->size() == v.size())
388 const unsigned int nl=this->local_size();
389 const unsigned int fli=this->first_local_index();
391 for (
unsigned int i=0;i<nl;i++)
401 libmesh_assert_equal_to (v.size(), this->local_size());
403 const unsigned int nl=this->local_size();
405 for (
unsigned int i=0;i<nl;i++)
414 template <
typename T>
419 Epetra_Map rootMap = Epetra_Util::Create_Root_Map( *_map, -1);
420 v_local->
_vec->ReplaceMap(rootMap);
422 Epetra_Import importer(v_local->
_vec->Map(), *_map);
423 v_local->
_vec->Import(*_vec, importer, Insert);
428 template <
typename T>
430 const std::vector<numeric_index_type> & )
const
433 this->localize(v_local_in);
450 template <
typename T>
452 const std::vector<numeric_index_type> & indices)
const
457 Epetra_LocalMap import_map(static_cast<int>(indices.size()),
463 int * import_map_global_elements = import_map.MyGlobalElements();
465 import_map_global_elements[i] = indices[i];
468 Epetra_Vector import_vector(import_map);
471 Epetra_Import import_object(import_map, *_map);
474 import_vector.Import(*_vec, import_object, Insert);
478 T * values = import_vector.Values();
479 int import_vector_length = import_vector.MyLength();
482 v_local.resize(import_vector_length);
483 for (
int i=0; i<import_vector_length; ++i)
484 v_local[i] = values[i];
489 template <
typename T>
492 const std::vector<numeric_index_type> & send_list)
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());
500 const unsigned int my_size = this->size();
501 const unsigned int my_local_size = (last_local_idx - first_local_idx + 1);
504 if ((first_local_idx == 0) &&
505 (my_local_size == my_size))
512 parallel_vec.
init (my_size, my_local_size,
true,
PARALLEL);
516 parallel_vec.
set(i,this->el(i));
519 parallel_vec.
close();
520 parallel_vec.
localize (*
this, send_list);
526 template <
typename T>
530 parallel_object_only();
532 const unsigned int n = this->size();
533 const unsigned int nl = this->local_size();
541 for (
unsigned int i=0; i<nl; i++)
542 v_local.push_back((*this->_vec)[i]);
544 this->comm().allgather (v_local);
549 template <
typename T>
554 parallel_object_only();
556 const unsigned int n = this->size();
557 const unsigned int nl = this->local_size();
559 libmesh_assert_less (pid, this->n_processors());
567 for (
unsigned int i=0; i<nl; i++)
568 v_local.push_back((*this->_vec)[i]);
570 this->comm().gather (pid, v_local);
575 template <
typename T>
577 const std::vector<numeric_index_type> & )
const
579 libmesh_not_implemented();
591 template <
typename T>
594 const double * values)
596 return( inputValues( numIDs, GIDs, values,
true) );
600 template <
typename T>
602 const Epetra_SerialDenseVector & values)
604 if (GIDs.Length() != values.Length()) {
608 return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(),
true) );
612 template <
typename T>
615 const int * numValuesPerID,
616 const double * values)
618 return( inputValues( numIDs, GIDs, numValuesPerID, values,
true) );
622 template <
typename T>
625 const double * values)
627 return( inputValues( numIDs, GIDs, values,
false) );
631 template <
typename T>
633 const Epetra_SerialDenseVector & values)
635 if (GIDs.Length() != values.Length()) {
639 return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(),
false) );
643 template <
typename T>
646 const int * numValuesPerID,
647 const double * values)
649 return( inputValues( numIDs, GIDs, numValuesPerID, values,
false) );
653 template <
typename T>
656 const double * values,
670 for (
int i=0; i<numIDs; ++i) {
671 if (_vec->Map().MyGID(GIDs[i])) {
673 _vec->SumIntoGlobalValue(GIDs[i], 0, 0, values[i]);
676 _vec->ReplaceGlobalValue(GIDs[i], 0, 0, values[i]);
680 if (!ignoreNonLocalEntries_) {
681 EPETRA_CHK_ERR( inputNonlocalValue(GIDs[i], values[i], accumulate) );
690 template <
typename T>
693 const int * numValuesPerID,
694 const double * values,
706 for (
int i=0; i<numIDs; ++i) {
707 int numValues = numValuesPerID[i];
708 if (_vec->Map().MyGID(GIDs[i])) {
710 for (
int j=0; j<numValues; ++j) {
711 _vec->SumIntoGlobalValue(GIDs[i], j, 0, values[offset+j]);
715 for (
int j=0; j<numValues; ++j) {
716 _vec->ReplaceGlobalValue(GIDs[i], j, 0, values[offset+j]);
721 if (!ignoreNonLocalEntries_) {
722 EPETRA_CHK_ERR( inputNonlocalValues(GIDs[i], numValues,
723 &(values[offset]), accumulate) );
733 template <
typename T>
736 int insertPoint = -1;
739 int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
746 nonlocalCoefs_[offset][0] +=
value;
749 nonlocalCoefs_[offset][0] =
value;
758 int tmp1 = numNonlocalIDs_;
759 int tmp2 = allocatedNonlocalLength_;
760 int tmp3 = allocatedNonlocalLength_;
761 EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
764 EPETRA_CHK_ERR( Epetra_Util_insert(1, insertPoint, nonlocalElementSize_,
766 double * values =
new double[1];
768 EPETRA_CHK_ERR( Epetra_Util_insert(values, insertPoint, nonlocalCoefs_,
769 numNonlocalIDs_, allocatedNonlocalLength_) );
776 template <
typename T>
779 const double * values,
782 int insertPoint = -1;
785 int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
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;
799 for (
int j=0; j<numValues; ++j) {
800 nonlocalCoefs_[offset][j] += values[j];
804 for (
int j=0; j<numValues; ++j) {
805 nonlocalCoefs_[offset][j] = values[j];
815 int tmp1 = numNonlocalIDs_;
816 int tmp2 = allocatedNonlocalLength_;
817 int tmp3 = allocatedNonlocalLength_;
818 EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
821 EPETRA_CHK_ERR( Epetra_Util_insert(numValues, insertPoint, nonlocalElementSize_,
823 double * newvalues =
new double[numValues];
824 for (
int j=0; j<numValues; ++j) {
825 newvalues[j] = values[j];
827 EPETRA_CHK_ERR( Epetra_Util_insert(newvalues, insertPoint, nonlocalCoefs_,
828 numNonlocalIDs_, allocatedNonlocalLength_) );
835 template <
typename T>
844 if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
853 Epetra_BlockMap sourceMap(-1, numNonlocalIDs_,
854 nonlocalIDs_, nonlocalElementSize_,
855 _vec->Map().IndexBase(), _vec->Map().Comm());
859 Epetra_MultiVector nonlocalVector(sourceMap, 1);
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]);
869 Epetra_Export exporter(sourceMap, _vec->Map());
871 EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) );
873 destroyNonlocalData();
878 #include <libmesh/ignore_warnings.h>
881 template <
typename T>
884 (*_vec) = *(source.
_vec);
886 destroyNonlocalData();
891 nonlocalIDs_ =
new int[allocatedNonlocalLength_];
892 nonlocalElementSize_ =
new int[allocatedNonlocalLength_];
893 nonlocalCoefs_ =
new double *[allocatedNonlocalLength_];
894 for (
int i=0; i<numNonlocalIDs_; ++i) {
896 nonlocalCoefs_[i] =
new double[elemSize];
898 nonlocalElementSize_[i] = elemSize;
899 for (
int j=0; j<elemSize; ++j) {
906 #include <libmesh/restore_warnings.h>
909 template <
typename T>
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];
920 delete [] nonlocalCoefs_;
921 nonlocalCoefs_ =
nullptr;
923 allocatedNonlocalLength_ = 0;
935 #endif // LIBMESH_TRILINOS_HAVE_EPETRA