libmesh解析
本工作只是尝试解析原libmesh的代码,供学习使用
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 
trilinos_epetra_vector.C
浏览该文件的文档.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2023 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 template <typename T>
582  const std::vector<numeric_index_type> & /* rows */) const
583 {
584  libmesh_not_implemented();
585 }
586 
587 
588 /*********************************************************************
589  * The following were copied (and slightly modified) from
590  * Epetra_FEVector.h in order to allow us to use a standard
591  * Epetra_Vector... which is more compatible with other Trilinos
592  * packages such as NOX. All of this code is originally under LGPL
593  *********************************************************************/
594 
595 //----------------------------------------------------------------------------
596 template <typename T>
598  const int * GIDs,
599  const double * values)
600 {
601  return( inputValues( numIDs, GIDs, values, true) );
602 }
603 
604 //----------------------------------------------------------------------------
605 template <typename T>
606 int EpetraVector<T>::SumIntoGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
607  const Epetra_SerialDenseVector & values)
608 {
609  if (GIDs.Length() != values.Length()) {
610  return(-1);
611  }
612 
613  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), true) );
614 }
615 
616 //----------------------------------------------------------------------------
617 template <typename T>
619  const int * GIDs,
620  const int * numValuesPerID,
621  const double * values)
622 {
623  return( inputValues( numIDs, GIDs, numValuesPerID, values, true) );
624 }
625 
626 //----------------------------------------------------------------------------
627 template <typename T>
629  const int * GIDs,
630  const double * values)
631 {
632  return( inputValues( numIDs, GIDs, values, false) );
633 }
634 
635 //----------------------------------------------------------------------------
636 template <typename T>
637 int EpetraVector<T>::ReplaceGlobalValues(const Epetra_IntSerialDenseVector & GIDs,
638  const Epetra_SerialDenseVector & values)
639 {
640  if (GIDs.Length() != values.Length()) {
641  return(-1);
642  }
643 
644  return( inputValues( GIDs.Length(), GIDs.Values(), values.Values(), false) );
645 }
646 
647 //----------------------------------------------------------------------------
648 template <typename T>
650  const int * GIDs,
651  const int * numValuesPerID,
652  const double * values)
653 {
654  return( inputValues( numIDs, GIDs, numValuesPerID, values, false) );
655 }
656 
657 //----------------------------------------------------------------------------
658 template <typename T>
660  const int * GIDs,
661  const double * values,
662  bool accumulate)
663 {
664  if (accumulate) {
665  libmesh_assert(last_edit == 0 || last_edit == 2);
666  last_edit = 2;
667  } else {
668  libmesh_assert(last_edit == 0 || last_edit == 1);
669  last_edit = 1;
670  }
671 
672  //Important note!! This method assumes that there is only 1 point
673  //associated with each element.
674 
675  for (int i=0; i<numIDs; ++i) {
676  if (_vec->Map().MyGID(GIDs[i])) {
677  if (accumulate) {
678  _vec->SumIntoGlobalValue(GIDs[i], 0, 0, values[i]);
679  }
680  else {
681  _vec->ReplaceGlobalValue(GIDs[i], 0, 0, values[i]);
682  }
683  }
684  else {
685  if (!ignoreNonLocalEntries_) {
686  EPETRA_CHK_ERR( inputNonlocalValue(GIDs[i], values[i], accumulate) );
687  }
688  }
689  }
690 
691  return(0);
692 }
693 
694 //----------------------------------------------------------------------------
695 template <typename T>
697  const int * GIDs,
698  const int * numValuesPerID,
699  const double * values,
700  bool accumulate)
701 {
702  if (accumulate) {
703  libmesh_assert(last_edit == 0 || last_edit == 2);
704  last_edit = 2;
705  } else {
706  libmesh_assert(last_edit == 0 || last_edit == 1);
707  last_edit = 1;
708  }
709 
710  int offset=0;
711  for (int i=0; i<numIDs; ++i) {
712  int numValues = numValuesPerID[i];
713  if (_vec->Map().MyGID(GIDs[i])) {
714  if (accumulate) {
715  for (int j=0; j<numValues; ++j) {
716  _vec->SumIntoGlobalValue(GIDs[i], j, 0, values[offset+j]);
717  }
718  }
719  else {
720  for (int j=0; j<numValues; ++j) {
721  _vec->ReplaceGlobalValue(GIDs[i], j, 0, values[offset+j]);
722  }
723  }
724  }
725  else {
726  if (!ignoreNonLocalEntries_) {
727  EPETRA_CHK_ERR( inputNonlocalValues(GIDs[i], numValues,
728  &(values[offset]), accumulate) );
729  }
730  }
731  offset += numValues;
732  }
733 
734  return(0);
735 }
736 
737 //----------------------------------------------------------------------------
738 template <typename T>
739 int EpetraVector<T>::inputNonlocalValue(int GID, double value, bool accumulate)
740 {
741  int insertPoint = -1;
742 
743  //find offset of GID in nonlocalIDs_
744  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
745  insertPoint);
746  if (offset >= 0) {
747  //if offset >= 0
748  // put value in nonlocalCoefs_[offset][0]
749 
750  if (accumulate) {
751  nonlocalCoefs_[offset][0] += value;
752  }
753  else {
754  nonlocalCoefs_[offset][0] = value;
755  }
756  }
757  else {
758  //else
759  // insert GID in nonlocalIDs_
760  // insert 1 in nonlocalElementSize_
761  // insert value in nonlocalCoefs_
762 
763  int tmp1 = numNonlocalIDs_;
764  int tmp2 = allocatedNonlocalLength_;
765  int tmp3 = allocatedNonlocalLength_;
766  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
767  tmp1, tmp2) );
768  --tmp1;
769  EPETRA_CHK_ERR( Epetra_Util_insert(1, insertPoint, nonlocalElementSize_,
770  tmp1, tmp3) );
771  double * values = new double[1];
772  values[0] = value;
773  EPETRA_CHK_ERR( Epetra_Util_insert(values, insertPoint, nonlocalCoefs_,
774  numNonlocalIDs_, allocatedNonlocalLength_) );
775  }
776 
777  return(0);
778 }
779 
780 //----------------------------------------------------------------------------
781 template <typename T>
783  int numValues,
784  const double * values,
785  bool accumulate)
786 {
787  int insertPoint = -1;
788 
789  //find offset of GID in nonlocalIDs_
790  int offset = Epetra_Util_binary_search(GID, nonlocalIDs_, numNonlocalIDs_,
791  insertPoint);
792  if (offset >= 0) {
793  //if offset >= 0
794  // put value in nonlocalCoefs_[offset][0]
795 
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;
800  return(-1);
801  }
802 
803  if (accumulate) {
804  for (int j=0; j<numValues; ++j) {
805  nonlocalCoefs_[offset][j] += values[j];
806  }
807  }
808  else {
809  for (int j=0; j<numValues; ++j) {
810  nonlocalCoefs_[offset][j] = values[j];
811  }
812  }
813  }
814  else {
815  //else
816  // insert GID in nonlocalIDs_
817  // insert numValues in nonlocalElementSize_
818  // insert values in nonlocalCoefs_
819 
820  int tmp1 = numNonlocalIDs_;
821  int tmp2 = allocatedNonlocalLength_;
822  int tmp3 = allocatedNonlocalLength_;
823  EPETRA_CHK_ERR( Epetra_Util_insert(GID, insertPoint, nonlocalIDs_,
824  tmp1, tmp2) );
825  --tmp1;
826  EPETRA_CHK_ERR( Epetra_Util_insert(numValues, insertPoint, nonlocalElementSize_,
827  tmp1, tmp3) );
828  double * newvalues = new double[numValues];
829  for (int j=0; j<numValues; ++j) {
830  newvalues[j] = values[j];
831  }
832  EPETRA_CHK_ERR( Epetra_Util_insert(newvalues, insertPoint, nonlocalCoefs_,
833  numNonlocalIDs_, allocatedNonlocalLength_) );
834  }
835 
836  return(0);
837 }
838 
839 //----------------------------------------------------------------------------
840 template <typename T>
841 int EpetraVector<T>::GlobalAssemble(Epetra_CombineMode mode)
842 {
843  //In this method we need to gather all the non-local (overlapping) data
844  //that's been input on each processor, into the (probably) non-overlapping
845  //distribution defined by the map that 'this' vector was constructed with.
846 
847  //We don't need to do anything if there's only one processor or if
848  //ignoreNonLocalEntries_ is true.
849  if (_vec->Map().Comm().NumProc() < 2 || ignoreNonLocalEntries_) {
850  return(0);
851  }
852 
853 
854 
855  //First build a map that describes the data in nonlocalIDs_/nonlocalCoefs_.
856  //We'll use the arbitrary distribution constructor of Map.
857 
858  Epetra_BlockMap sourceMap(-1, numNonlocalIDs_,
859  nonlocalIDs_, nonlocalElementSize_,
860  _vec->Map().IndexBase(), _vec->Map().Comm());
861 
862  //Now build a vector to hold our nonlocalCoefs_, and to act as the source-
863  //vector for our import operation.
864  Epetra_MultiVector nonlocalVector(sourceMap, 1);
865 
866  int i,j;
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]);
871  }
872  }
873 
874  Epetra_Export exporter(sourceMap, _vec->Map());
875 
876  EPETRA_CHK_ERR( _vec->Export(nonlocalVector, exporter, mode) );
877 
878  destroyNonlocalData();
879 
880  return(0);
881 }
882 
883 #include <libmesh/ignore_warnings.h> // deprecated-copy in Epetra_Vector
884 
885 //----------------------------------------------------------------------------
886 template <typename T>
888 {
889  (*_vec) = *(source._vec);
890 
891  destroyNonlocalData();
892 
893  if (source.allocatedNonlocalLength_ > 0) {
894  allocatedNonlocalLength_ = source.allocatedNonlocalLength_;
895  numNonlocalIDs_ = source.numNonlocalIDs_;
896  nonlocalIDs_ = new int[allocatedNonlocalLength_];
897  nonlocalElementSize_ = new int[allocatedNonlocalLength_];
898  nonlocalCoefs_ = new double *[allocatedNonlocalLength_];
899  for (int i=0; i<numNonlocalIDs_; ++i) {
900  int elemSize = source.nonlocalElementSize_[i];
901  nonlocalCoefs_[i] = new double[elemSize];
902  nonlocalIDs_[i] = source.nonlocalIDs_[i];
903  nonlocalElementSize_[i] = elemSize;
904  for (int j=0; j<elemSize; ++j) {
905  nonlocalCoefs_[i][j] = source.nonlocalCoefs_[i][j];
906  }
907  }
908  }
909 }
910 
911 #include <libmesh/restore_warnings.h>
912 
913 //----------------------------------------------------------------------------
914 template <typename T>
916 {
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];
924  }
925  delete [] nonlocalCoefs_;
926  nonlocalCoefs_ = nullptr;
927  numNonlocalIDs_ = 0;
928  allocatedNonlocalLength_ = 0;
929  }
930  return;
931 }
932 
933 
934 //------------------------------------------------------------------
935 // Explicit instantiations
936 template class LIBMESH_EXPORT EpetraVector<Number>;
937 
938 } // namespace libMesh
939 
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.
Definition: libmesh.C:268
此类提供了对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。
提供了不同线性代数库的向量存储方案的统一接口。
Definition: dof_map.h:67
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
Definition: id_types.h:104
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 > &)
计算自动微分实数向量的绝对值。
Definition: type_vector.h:112
这是一个通用的稀疏矩阵类。该类包含了必须在派生类中覆盖的纯虚拟成员。 使用一个公共的基类允许从不同的求解器包中以不同的格式统一访问稀疏矩阵。
Definition: dof_map.h:66
dof_id_type numeric_index_type
Definition: id_types.h:99
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
将当前矢量的值本地化到一个本地矢量中。
OStreamProxy err
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