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"
52 libmesh_assert(this->
closed());
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);
71 libmesh_assert(this->
closed());
83 libmesh_assert(this->
closed());
95 libmesh_assert(this->
closed());
99 _vec->NormInf(&value);
104 template <
typename T>
108 libmesh_assert(this->
closed());
117 template <
typename T>
121 libmesh_assert(this->
closed());
129 template <
typename T>
133 libmesh_assert(this->
closed());
134 libmesh_assert_equal_to(size(), v.
size());
138 _vec->Multiply(1.0, *v_vec._vec, *_vec, 0.0);
144 template <
typename T>
148 libmesh_assert(this->
closed());
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 std::scoped_lock lock(this->_numeric_vector_mutex);
170 ReplaceGlobalValues(1, &i, &value);
172 this->_is_closed =
false;
177 template <
typename T>
186 const unsigned int nl = _vec->MyLength();
188 T * values = _vec->Values();
190 for (
unsigned int i=0; i<nl; i++)
193 libmesh_error_msg_if(
std::abs(values[i]) < std::numeric_limits<T>::min(),
194 "Error, divide by zero in DistributedVector<T>::reciprocal()!");
196 values[i] = 1. / values[i];
205 template <
typename T>
213 template <
typename T>
216 int i =
static_cast<int> (i_in);
219 libmesh_assert_less (i_in, this->size());
221 std::scoped_lock lock(this->_numeric_vector_mutex);
222 SumIntoGlobalValues(1, &i, &value);
224 this->_is_closed =
false;
229 template <
typename T>
231 const std::vector<numeric_index_type> & dof_indices)
235 std::scoped_lock lock(this->_numeric_vector_mutex);
236 SumIntoGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
244 template <
typename T>
252 std::unique_ptr<NumericVector<T>> temp = v->
zero_clone();
254 A->mat()->Multiply(
false, *v->
_vec, *temp_v->
_vec);
261 template <
typename T>
265 libmesh_not_implemented();
270 template <
typename T>
273 const unsigned int nl = _vec->MyLength();
275 T * values = _vec->Values();
277 for (
unsigned int i=0; i<nl; i++)
280 this->_is_closed =
false;
284 template <
typename T>
291 template <
typename T>
296 libmesh_assert_equal_to (this->size(), v->
size());
298 _vec->Update(a_in,*v->
_vec, 1.);
303 template <
typename T>
305 const std::vector<numeric_index_type> & dof_indices)
309 std::scoped_lock lock(this->_numeric_vector_mutex);
310 ReplaceGlobalValues (cast_int<numeric_index_type>(dof_indices.size()),
313 this->_is_closed =
false;
318 template <
typename T>
321 _vec->Scale(factor_in);
324 template <
typename T>
331 template <
typename T>
338 _vec->Dot(*v->
_vec, &result);
344 template <
typename T>
351 _vec->Multiply(1.0, *v1->
_vec, *v2->_vec, 0.0);
355 template <
typename T>
359 _vec->PutScalar(s_in);
366 template <
typename T>
375 libmesh_not_implemented();
381 template <
typename T>
385 T * values = _vec->Values();
391 if (this->size() == v.size())
393 const unsigned int nl=this->local_size();
394 const unsigned int fli=this->first_local_index();
396 for (
unsigned int i=0;i<nl;i++)
406 libmesh_assert_equal_to (v.size(), this->local_size());
408 const unsigned int nl=this->local_size();
410 for (
unsigned int i=0;i<nl;i++)
419 template <
typename T>
424 Epetra_Map rootMap = Epetra_Util::Create_Root_Map( *_map, -1);
425 v_local->
_vec->ReplaceMap(rootMap);
427 Epetra_Import importer(v_local->
_vec->Map(), *_map);
428 v_local->
_vec->Import(*_vec, importer, Insert);
433 template <
typename T>
435 const std::vector<numeric_index_type> & )
const
438 this->localize(v_local_in);
455 template <
typename T>
457 const std::vector<numeric_index_type> & indices)
const
462 Epetra_LocalMap import_map(static_cast<int>(indices.size()),
468 int * import_map_global_elements = import_map.MyGlobalElements();
469 for (
auto i : index_range(indices))
470 import_map_global_elements[i] = indices[i];
473 Epetra_Vector import_vector(import_map);
476 Epetra_Import import_object(import_map, *_map);
479 import_vector.Import(*_vec, import_object, Insert);
483 T * values = import_vector.Values();
484 int import_vector_length = import_vector.MyLength();
487 v_local.resize(import_vector_length);
488 for (
int i=0; i<import_vector_length; ++i)
489 v_local[i] = values[i];
494 template <
typename T>
497 const std::vector<numeric_index_type> & send_list)
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());
505 const unsigned int my_size = this->size();
506 const unsigned int my_local_size = (last_local_idx - first_local_idx + 1);
509 if ((first_local_idx == 0) &&
510 (my_local_size == my_size))
517 parallel_vec.
init (my_size, my_local_size,
true, PARALLEL);
521 parallel_vec.
set(i,this->el(i));
524 parallel_vec.
close();
525 parallel_vec.
localize (*
this, send_list);
531 template <
typename T>
535 parallel_object_only();
537 const unsigned int n = this->size();
538 const unsigned int nl = this->local_size();
540 libmesh_assert(this->_vec);
546 for (
unsigned int i=0; i<nl; i++)
547 v_local.push_back((*this->_vec)[i]);
549 this->comm().allgather (v_local);
554 template <
typename T>
559 parallel_object_only();
561 const unsigned int n = this->size();
562 const unsigned int nl = this->local_size();
564 libmesh_assert_less (pid, this->n_processors());
565 libmesh_assert(this->_vec);
572 for (
unsigned int i=0; i<nl; i++)
573 v_local.push_back((*this->_vec)[i]);
575 this->comm().gather (pid, v_local);
580 template <
typename T>
582 const std::vector<numeric_index_type> & )
const
584 libmesh_not_implemented();
596 template <
typename T>
599 const double * values)
601 return( inputValues( numIDs, GIDs, values,
true) );
605 template <
typename T>
607 const Epetra_SerialDenseVector & values)
609 if (GIDs.Length() != values.Length()) {
613 return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(),
true) );
617 template <
typename T>
620 const int * numValuesPerID,
621 const double * values)
623 return( inputValues( numIDs, GIDs, numValuesPerID, values,
true) );
627 template <
typename T>
630 const double * values)
632 return( inputValues( numIDs, GIDs, values,
false) );
636 template <
typename T>
638 const Epetra_SerialDenseVector & values)
640 if (GIDs.Length() != values.Length()) {
644 return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(),
false) );
648 template <
typename T>
651 const int * numValuesPerID,
652 const double * values)
654 return( inputValues( numIDs, GIDs, numValuesPerID, values,
false) );
658 template <
typename T>
661 const double * values,
665 libmesh_assert(last_edit == 0 || last_edit == 2);
668 libmesh_assert(last_edit == 0 || last_edit == 1);
675 for (
int i=0; i<numIDs; ++i) {
676 if (_vec->Map().MyGID(GIDs[i])) {
678 _vec->SumIntoGlobalValue(GIDs[i], 0, 0, values[i]);
681 _vec->ReplaceGlobalValue(GIDs[i], 0, 0, values[i]);
685 if (!ignoreNonLocalEntries_) {
686 EPETRA_CHK_ERR( inputNonlocalValue(GIDs[i], values[i], accumulate) );
695 template <
typename T>
698 const int * numValuesPerID,
699 const double * values,
703 libmesh_assert(last_edit == 0 || last_edit == 2);
706 libmesh_assert(last_edit == 0 || last_edit == 1);
711 for (
int i=0; i<numIDs; ++i) {
712 int numValues = numValuesPerID[i];
713 if (_vec->Map().MyGID(GIDs[i])) {
715 for (
int j=0; j<numValues; ++j) {
716 _vec->SumIntoGlobalValue(GIDs[i], j, 0, values[offset+j]);
720 for (
int j=0; j<numValues; ++j) {
721 _vec->ReplaceGlobalValue(GIDs[i], j, 0, values[offset+j]);
726 if (!ignoreNonLocalEntries_) {
727 EPETRA_CHK_ERR( inputNonlocalValues(GIDs[i], numValues,
728 &(values[offset]), accumulate) );
738 template <
typename T>
741 int insertPoint = -1;
744 int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
751 nonlocalCoefs_[offset][0] += value;
754 nonlocalCoefs_[offset][0] = value;
763 int tmp1 = numNonlocalIDs_;
764 int tmp2 = allocatedNonlocalLength_;
765 int tmp3 = allocatedNonlocalLength_;
766 EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
769 EPETRA_CHK_ERR( Epetra_Util_insert(1, insertPoint, nonlocalElementSize_,
771 double * values =
new double[1];
773 EPETRA_CHK_ERR( Epetra_Util_insert(values, insertPoint, nonlocalCoefs_,
774 numNonlocalIDs_, allocatedNonlocalLength_) );
781 template <
typename T>
784 const double * values,
787 int insertPoint = -1;
790 int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
796 if (numValues != nonlocalElementSize_[offset]) {
797 libMesh::err <<
"Epetra_FEVector ERROR: block-size for GID " << GID <<
" is "
798 << numValues<<
" which doesn't match previously set block-size of "
799 << nonlocalElementSize_[offset] << std::endl;
804 for (
int j=0; j<numValues; ++j) {
805 nonlocalCoefs_[offset][j] += values[j];
809 for (
int j=0; j<numValues; ++j) {
810 nonlocalCoefs_[offset][j] = values[j];
820 int tmp1 = numNonlocalIDs_;
821 int tmp2 = allocatedNonlocalLength_;
822 int tmp3 = allocatedNonlocalLength_;
823 EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
826 EPETRA_CHK_ERR( Epetra_Util_insert(numValues, insertPoint, nonlocalElementSize_,
828 double * newvalues =
new double[numValues];
829 for (
int j=0; j<numValues; ++j) {
830 newvalues[j] = values[j];
832 EPETRA_CHK_ERR( Epetra_Util_insert(newvalues, insertPoint, nonlocalCoefs_,
833 numNonlocalIDs_, allocatedNonlocalLength_) );
840 template <
typename T>
849 if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
858 Epetra_BlockMap sourceMap(-1, numNonlocalIDs_,
859 nonlocalIDs_, nonlocalElementSize_,
860 _vec->Map().IndexBase(), _vec->Map().Comm());
864 Epetra_MultiVector nonlocalVector(sourceMap, 1);
867 for (i=0; i<numNonlocalIDs_; ++i) {
868 for (j=0; j<nonlocalElementSize_[i]; ++j) {
869 nonlocalVector.ReplaceGlobalValue(nonlocalIDs_[i], j, 0,
870 nonlocalCoefs_[i][j]);
874 Epetra_Export exporter(sourceMap, _vec->Map());
876 EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) );
878 destroyNonlocalData();
883 #include <libmesh/ignore_warnings.h>
886 template <
typename T>
889 (*_vec) = *(source.
_vec);
891 destroyNonlocalData();
896 nonlocalIDs_ =
new int[allocatedNonlocalLength_];
897 nonlocalElementSize_ =
new int[allocatedNonlocalLength_];
898 nonlocalCoefs_ =
new double *[allocatedNonlocalLength_];
899 for (
int i=0; i<numNonlocalIDs_; ++i) {
901 nonlocalCoefs_[i] =
new double[elemSize];
903 nonlocalElementSize_[i] = elemSize;
904 for (
int j=0; j<elemSize; ++j) {
911 #include <libmesh/restore_warnings.h>
914 template <
typename T>
917 if (allocatedNonlocalLength_ > 0) {
918 delete [] nonlocalIDs_;
919 delete [] nonlocalElementSize_;
920 nonlocalIDs_ =
nullptr;
921 nonlocalElementSize_ =
nullptr;
922 for (
int i=0; i<numNonlocalIDs_; ++i) {
923 delete [] nonlocalCoefs_[i];
925 delete [] nonlocalCoefs_;
926 nonlocalCoefs_ =
nullptr;
928 allocatedNonlocalLength_ = 0;
940 #endif // LIBMESH_TRILINOS_HAVE_EPETRA
double ** nonlocalCoefs_
非本地系数的指针数组。
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
将矢量与另一个矢量逐元素相除并将结果存储在当前矢量中。
bool closed()
Checks that the library has been closed.
此类提供了对Trilinos Epetra_Vector对象的友好接口。所有重写的虚拟函数在numeric_vector.h中都有文档。
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
计算当前矢量与另一个矢量的逐元素乘积。
int allocatedNonlocalLength_
已分配的非本地长度。
virtual void reciprocal() override
计算当前矢量的逐元素倒数。
virtual void add(const numeric_index_type i, const T value) override
将索引i处的值增加value。
virtual void close() override
关闭矢量,使其无法再次修改。
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
创建零克隆矢量。
virtual numeric_index_type size() const =0
获取向量的大小。
Epetra_Vector * _vec
用于保存向量条目的实际 Epetra 向量数据类型。
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
将所有值本地化到一个本地矢量中,仅保留一个处理器上的值。
virtual void set(const numeric_index_type i, const T value) override
设置索引i处的值为value。
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices) override
使用特定的自由度索引将一个值数组插入到当前矢量中。
int inputNonlocalValues(int GID, int numValues, const double *values, bool accumulate)
输入非本地值到向量中,覆盖或累积到指定 GID 的已存在的任何值。
virtual void conjugate() override
计算当前矢量的逐元素共轭。
int * nonlocalElementSize_
非本地元素大小数组。
virtual T sum() const override
计算矢量中所有元素的总和。
int GlobalAssemble(Epetra_CombineMode mode=Add)
将所有重叠/共享数据收集到由 Map 在构造函数中传递给该向量定义的非重叠分区中。 从其他处理器导入的数据以“sumInto”或累积操作存储在拥有处理器上。这是一种集体方法, 每个处理器在任何处理器完成...
virtual numeric_index_type size() const override
获取矢量的全局大小。
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
使用稀疏矩阵A的转置乘积将另一个矢量v添加到当前矢量中。
uint8_t processor_id_type
int ReplaceGlobalValues(int numIDs, const int *GIDs, const double *values)
将值复制到向量中,覆盖指定索引已存在的任何值。
int inputValues(int numIDs, const int *GIDs, const double *values, bool accumulate)
输入值到向量中,覆盖或累积到指定索引的已存在的任何值。
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的绝对值。
这是一个通用的稀疏矩阵类。该类包含了必须在派生类中覆盖的纯虚拟成员。 使用一个公共的基类允许从不同的求解器包中以不同的格式统一访问稀疏矩阵。
dof_id_type numeric_index_type
virtual NumericVector< T > & operator*=(const NumericVector< T > &v) override
将矢量与另一个矢量逐元素相乘并将结果存储在当前矢量中。
int * nonlocalIDs_
非本地 ID 数组。
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
将矢量与另一个矢量相加并将结果存储在当前矢量中。
virtual Real l1_norm() const override
计算矢量的L1范数。
virtual void abs() override
计算矢量的绝对值。
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
将矢量与另一个矢量相减并将结果存储在当前矢量中。
int inputNonlocalValue(int GID, double value, bool accumulate)
输入非本地值到向量中,覆盖或累积到指定 GID 的已存在的任何值。
virtual Real linfty_norm() const override
计算矢量的L∞范数。
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType type=AUTOMATIC) override
初始化矢量。
void destroyNonlocalData()
销毁非本地数据。
int numNonlocalIDs_
非本地 ID 数量。
virtual void localize(std::vector< T > &v_local) const override
将当前矢量的值本地化到一个本地矢量中。
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)
将值累积到向量中,将它们添加到指定索引已存在的任何值中。
virtual Real l2_norm() const override
计算矢量的L2范数。
virtual void create_subvector(NumericVector< T > &subvector, const std::vector< numeric_index_type > &rows) const override
创建当前矢量的子矢量,包含指定行的值。
void FEoperatorequals(const EpetraVector &source)
从另一个 EpetraVector 对象中复制操作符。
int * numeric_trilinos_cast(const numeric_index_type *p)
virtual void scale(const T factor) override
缩放矢量的所有元素。
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices) override
使用特定的自由度索引添加一个值数组到当前矢量中。
此类提供了对Epetra数据结构的并行、稀疏矩阵的友好接口。所有重写的虚拟函数在sparse_matrix.h中都有文档。
EpetraVector & operator=(const EpetraVector &)=delete