$extrastylesheet
trilinos_epetra_vector.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 #ifndef LIBMESH_TRILINOS_EPETRA_VECTOR_H
00019 #define LIBMESH_TRILINOS_EPETRA_VECTOR_H
00020 
00021 
00022 #include "libmesh/libmesh_common.h"
00023 
00024 
00025 #ifdef LIBMESH_HAVE_TRILINOS
00026 
00027 // Local includes
00028 #include "libmesh/numeric_vector.h"
00029 #include "libmesh/parallel.h"
00030 
00031 // Trilinos includes
00032 #include <Epetra_CombineMode.h>
00033 #include <Epetra_Map.h>
00034 #include <Epetra_MultiVector.h>
00035 #include <Epetra_Vector.h>
00036 #include <Epetra_MpiComm.h>
00037 
00038 // C++ includes
00039 #include <cstddef>
00040 #include <vector>
00041 
00042 // Forward declarations
00043 class Epetra_IntSerialDenseVector;
00044 class Epetra_SerialDenseVector;
00045 
00046 namespace libMesh
00047 {
00048 
00049 // forward declarations
00050 template <typename T> class SparseMatrix;
00051 
00059 template <typename T>
00060 class EpetraVector : public NumericVector<T>
00061 {
00062 public:
00063 
00067   explicit
00068   EpetraVector (const Parallel::Communicator &comm,
00069                 const ParallelType type = AUTOMATIC);
00070 
00074   explicit
00075   EpetraVector (const Parallel::Communicator &comm,
00076                 const numeric_index_type n,
00077                 const ParallelType type = AUTOMATIC);
00078 
00083   EpetraVector (const Parallel::Communicator &comm,
00084                 const numeric_index_type n,
00085                 const numeric_index_type n_local,
00086                 const ParallelType type = AUTOMATIC);
00087 
00093   EpetraVector (const Parallel::Communicator &comm,
00094                 const numeric_index_type N,
00095                 const numeric_index_type n_local,
00096                 const std::vector<numeric_index_type>& ghost,
00097                 const ParallelType type = AUTOMATIC);
00098 
00106   EpetraVector(Epetra_Vector & v,
00107                const Parallel::Communicator &comm
00108                LIBMESH_CAN_DEFAULT_TO_COMMWORLD);
00109 
00114   ~EpetraVector ();
00115 
00119   void close ();
00120 
00124   void clear ();
00125 
00130   void zero ();
00131 
00137   virtual UniquePtr<NumericVector<T> > zero_clone () const;
00138 
00142   UniquePtr<NumericVector<T> > clone () const;
00143 
00157   void init (const numeric_index_type N,
00158              const numeric_index_type n_local,
00159              const bool         fast=false,
00160              const ParallelType type=AUTOMATIC);
00161 
00165   void init (const numeric_index_type N,
00166              const bool         fast=false,
00167              const ParallelType type=AUTOMATIC);
00168 
00173   void init (const numeric_index_type /*N*/,
00174              const numeric_index_type /*n_local*/,
00175              const std::vector<numeric_index_type>& /*ghost*/,
00176              const bool /*fast*/ = false,
00177              const ParallelType = AUTOMATIC);
00178 
00183   virtual void init (const NumericVector<T>& other,
00184                      const bool fast = false);
00185 
00186   //   /**
00187   //    * Change the dimension to that of the
00188   //    * vector \p V. The same applies as for
00189   //    * the other \p init function.
00190   //    *
00191   //    * The elements of \p V are not copied, i.e.
00192   //    * this function is the same as calling
00193   //    * \p init(V.size(),fast).
00194   //    */
00195   //   void init (const NumericVector<T>& V,
00196   //      const bool fast=false);
00197 
00201   NumericVector<T> & operator= (const T s);
00202 
00206   NumericVector<T> & operator= (const NumericVector<T> &V);
00207 
00211   EpetraVector<T> & operator= (const EpetraVector<T> &V);
00212 
00216   NumericVector<T> & operator= (const std::vector<T> &v);
00217 
00223   Real min () const;
00224 
00230   Real max () const;
00231 
00235   T sum () const;
00236 
00241   Real l1_norm () const;
00242 
00248   Real l2_norm () const;
00249 
00255   Real linfty_norm () const;
00256 
00264   numeric_index_type size () const;
00265 
00270   numeric_index_type local_size() const;
00271 
00276   numeric_index_type first_local_index() const;
00277 
00282   numeric_index_type last_local_index() const;
00283 
00287   T operator() (const numeric_index_type i) const;
00288 
00293   NumericVector<T> & operator += (const NumericVector<T> &V);
00294 
00299   NumericVector<T> & operator -= (const NumericVector<T> &V);
00300 
00304   virtual NumericVector<T> & operator /= (NumericVector<T> & v);
00305 
00309   virtual void reciprocal();
00310 
00316   virtual void conjugate();
00317 
00321   void set (const numeric_index_type i, const T value);
00322 
00326   void add (const numeric_index_type i, const T value);
00327 
00333   void add (const T s);
00334 
00340   void add (const NumericVector<T>& V);
00341 
00347   void add (const T a, const NumericVector<T>& v);
00348 
00353   using NumericVector<T>::add_vector;
00354 
00359   void add_vector (const T* v,
00360                    const std::vector<numeric_index_type>& dof_indices);
00361 
00366   void add_vector (const NumericVector<T> &V,
00367                    const SparseMatrix<T> &A);
00368 
00373   void add_vector_transpose (const NumericVector<T> &V,
00374                              const SparseMatrix<T> &A_trans);
00375 
00380   using NumericVector<T>::insert;
00381 
00386   virtual void insert (const T* v,
00387                        const std::vector<numeric_index_type>& dof_indices);
00388 
00393   void scale (const T factor);
00394 
00399   virtual void abs();
00400 
00401 
00405   virtual T dot(const NumericVector<T>& V) const;
00406 
00411   void localize (std::vector<T>& v_local) const;
00412 
00417   void localize (NumericVector<T>& v_local) const;
00418 
00424   void localize (NumericVector<T>& v_local,
00425                  const std::vector<numeric_index_type>& send_list) const;
00426 
00431   void localize (const numeric_index_type first_local_idx,
00432                  const numeric_index_type last_local_idx,
00433                  const std::vector<numeric_index_type>& send_list);
00434 
00441   void localize_to_one (std::vector<T>& v_local,
00442                         const processor_id_type proc_id=0) const;
00443 
00448   virtual void pointwise_mult (const NumericVector<T>& vec1,
00449                                const NumericVector<T>& vec2);
00450 
00455   virtual void create_subvector (NumericVector<T>& subvector,
00456                                  const std::vector<numeric_index_type>& rows) const;
00457 
00461   virtual void swap (NumericVector<T> &v);
00462 
00468   Epetra_Vector * vec () { libmesh_assert(_vec); return _vec; }
00469 
00470 private:
00471 
00476   Epetra_Vector * _vec;
00477 
00481   Epetra_Map * _map;
00482 
00487   bool _destroy_vec_on_exit;
00488 
00489 
00490 
00491   /*********************************************************************
00492    * The following were copied (and slightly modified) from
00493    * Epetra_FEVector.h in order to allow us to use a standard
00494    * Epetra_Vector... which is more compatible with other Trilinos
00495    * packages such as NOX.  All of this code is originally under LGPL
00496    *********************************************************************/
00497 
00501   int SumIntoGlobalValues(int numIDs, const int* GIDs, const double* values);
00502 
00512   int SumIntoGlobalValues(const Epetra_IntSerialDenseVector& GIDs,
00513                           const Epetra_SerialDenseVector& values);
00514 
00518   int ReplaceGlobalValues(int numIDs, const int* GIDs, const double* values);
00519 
00529   int ReplaceGlobalValues(const Epetra_IntSerialDenseVector& GIDs,
00530                           const Epetra_SerialDenseVector& values);
00531 
00532   int SumIntoGlobalValues(int numIDs, const int* GIDs,
00533                           const int* numValuesPerID,
00534                           const double* values);
00535 
00536   int ReplaceGlobalValues(int numIDs, const int* GIDs,
00537                           const int* numValuesPerID,
00538                           const double* values);
00539 
00547   int GlobalAssemble(Epetra_CombineMode mode = Add);
00548 
00551   void setIgnoreNonLocalEntries(bool flag) {
00552     ignoreNonLocalEntries_ = flag;
00553   }
00554 
00555   void FEoperatorequals(const EpetraVector& source);
00556 
00557   int inputValues(int numIDs,
00558                   const int* GIDs, const double* values,
00559                   bool accumulate);
00560 
00561   int inputValues(int numIDs,
00562                   const int* GIDs, const int* numValuesPerID,
00563                   const double* values,
00564                   bool accumulate);
00565 
00566   int inputNonlocalValue(int GID, double value, bool accumulate);
00567 
00568   int inputNonlocalValues(int GID, int numValues, const double* values,
00569                           bool accumulate);
00570 
00571   void destroyNonlocalData();
00572 
00573   int myFirstID_;
00574   int myNumIDs_;
00575   double* myCoefs_;
00576 
00577   int* nonlocalIDs_;
00578   int* nonlocalElementSize_;
00579   int numNonlocalIDs_;
00580   int allocatedNonlocalLength_;
00581   double** nonlocalCoefs_;
00582 
00588   unsigned char last_edit;
00589 
00590   bool ignoreNonLocalEntries_;
00591 };
00592 
00593 
00594 /*----------------------- Inline functions ----------------------------------*/
00595 
00596 
00597 
00598 template <typename T>
00599 inline
00600 EpetraVector<T>::EpetraVector (const Parallel::Communicator &comm,
00601                                const ParallelType type)
00602   : NumericVector<T>(comm, type),
00603     _destroy_vec_on_exit(true),
00604     myFirstID_(0),
00605     myNumIDs_(0),
00606     myCoefs_(NULL),
00607     nonlocalIDs_(NULL),
00608     nonlocalElementSize_(NULL),
00609     numNonlocalIDs_(0),
00610     allocatedNonlocalLength_(0),
00611     nonlocalCoefs_(NULL),
00612     last_edit(0),
00613     ignoreNonLocalEntries_(false)
00614 {
00615   this->_type = type;
00616 }
00617 
00618 
00619 
00620 template <typename T>
00621 inline
00622 EpetraVector<T>::EpetraVector (const Parallel::Communicator &comm,
00623                                const numeric_index_type n,
00624                                const ParallelType type)
00625   : NumericVector<T>(comm, type),
00626     _destroy_vec_on_exit(true),
00627     myFirstID_(0),
00628     myNumIDs_(0),
00629     myCoefs_(NULL),
00630     nonlocalIDs_(NULL),
00631     nonlocalElementSize_(NULL),
00632     numNonlocalIDs_(0),
00633     allocatedNonlocalLength_(0),
00634     nonlocalCoefs_(NULL),
00635     last_edit(0),
00636     ignoreNonLocalEntries_(false)
00637 
00638 {
00639   this->init(n, n, false, type);
00640 }
00641 
00642 
00643 
00644 template <typename T>
00645 inline
00646 EpetraVector<T>::EpetraVector (const Parallel::Communicator &comm,
00647                                const numeric_index_type n,
00648                                const numeric_index_type n_local,
00649                                const ParallelType type)
00650   : NumericVector<T>(comm, type),
00651     _destroy_vec_on_exit(true),
00652     myFirstID_(0),
00653     myNumIDs_(0),
00654     myCoefs_(NULL),
00655     nonlocalIDs_(NULL),
00656     nonlocalElementSize_(NULL),
00657     numNonlocalIDs_(0),
00658     allocatedNonlocalLength_(0),
00659     nonlocalCoefs_(NULL),
00660     last_edit(0),
00661     ignoreNonLocalEntries_(false)
00662 {
00663   this->init(n, n_local, false, type);
00664 }
00665 
00666 
00667 
00668 
00669 template <typename T>
00670 inline
00671 EpetraVector<T>::EpetraVector(Epetra_Vector & v,
00672                               const Parallel::Communicator &comm)
00673   : NumericVector<T>(comm, AUTOMATIC),
00674     _destroy_vec_on_exit(false),
00675     myFirstID_(0),
00676     myNumIDs_(0),
00677     myCoefs_(NULL),
00678     nonlocalIDs_(NULL),
00679     nonlocalElementSize_(NULL),
00680     numNonlocalIDs_(0),
00681     allocatedNonlocalLength_(0),
00682     nonlocalCoefs_(NULL),
00683     last_edit(0),
00684     ignoreNonLocalEntries_(false)
00685 {
00686   _vec = &v;
00687 
00688   this->_type = PARALLEL; // FIXME - need to determine this from v!
00689 
00690   myFirstID_ = _vec->Map().MinMyGID();
00691   myNumIDs_ = _vec->Map().NumMyElements();
00692 
00693   _map = new Epetra_Map(_vec->GlobalLength(),
00694                         _vec->MyLength(),
00695                         0,
00696                         Epetra_MpiComm (this->comm().get()));
00697 
00698   //Currently we impose the restriction that NumVectors==1, so we won't
00699   //need the LDA argument when calling ExtractView. Hence the "dummy" arg.
00700   int dummy;
00701   _vec->ExtractView(&myCoefs_, &dummy);
00702 
00703   this->_is_closed = true;
00704   this->_is_initialized = true;
00705 }
00706 
00707 
00708 
00709 template <typename T>
00710 inline
00711 EpetraVector<T>::EpetraVector (const Parallel::Communicator &comm,
00712                                const numeric_index_type n,
00713                                const numeric_index_type n_local,
00714                                const std::vector<numeric_index_type>& ghost,
00715                                const ParallelType type)
00716   : NumericVector<T>(comm, AUTOMATIC),
00717     _destroy_vec_on_exit(true),
00718     myFirstID_(0),
00719     myNumIDs_(0),
00720     myCoefs_(NULL),
00721     nonlocalIDs_(NULL),
00722     nonlocalElementSize_(NULL),
00723     numNonlocalIDs_(0),
00724     allocatedNonlocalLength_(0),
00725     nonlocalCoefs_(NULL),
00726     last_edit(0),
00727     ignoreNonLocalEntries_(false)
00728 {
00729   this->init(n, n_local, ghost, false, type);
00730 }
00731 
00732 
00733 
00734 /* Default implementation for solver packages for which ghosted
00735    vectors are not yet implemented.  */
00736 template <class T>
00737 void EpetraVector<T>::init (const NumericVector<T>& other,
00738                             const bool fast)
00739 {
00740   this->init(other.size(),other.local_size(),fast,other.type());
00741 }
00742 
00743 
00744 
00745 template <typename T>
00746 inline
00747 EpetraVector<T>::~EpetraVector ()
00748 {
00749   this->clear ();
00750 }
00751 
00752 
00753 
00754 template <typename T>
00755 inline
00756 void EpetraVector<T>::init (const numeric_index_type n,
00757                             const numeric_index_type n_local,
00758                             const bool fast,
00759                             const ParallelType type)
00760 {
00761   // We default to allocating n_local local storage
00762   numeric_index_type my_n_local = n_local;
00763 
00764   if (type == AUTOMATIC)
00765     {
00766       if (n == n_local)
00767         this->_type = SERIAL;
00768       else
00769         this->_type = PARALLEL;
00770     }
00771   else if (type == GHOSTED)
00772     {
00773       // We don't yet support GHOSTED Epetra vectors, so to get the
00774       // same functionality we need a SERIAL vector with local
00775       // storage allocated for every entry.
00776       this->_type = SERIAL;
00777       my_n_local = n;
00778     }
00779   else
00780     this->_type = type;
00781 
00782   libmesh_assert ((this->_type==SERIAL && n==my_n_local) ||
00783                   this->_type==PARALLEL);
00784 
00785   _map = new Epetra_Map(static_cast<int>(n),
00786                         my_n_local,
00787                         0,
00788                         Epetra_MpiComm (this->comm().get()));
00789 
00790   _vec = new Epetra_Vector(*_map);
00791 
00792   myFirstID_ = _vec->Map().MinMyGID();
00793   myNumIDs_ = _vec->Map().NumMyElements();
00794 
00795   //Currently we impose the restriction that NumVectors==1, so we won't
00796   //need the LDA argument when calling ExtractView. Hence the "dummy" arg.
00797   int dummy;
00798   _vec->ExtractView(&myCoefs_, &dummy);
00799 
00800   this->_is_initialized = true;
00801   this->_is_closed = true;
00802   this->last_edit = 0;
00803 
00804   if (fast == false)
00805     this->zero ();
00806 }
00807 
00808 
00809 template <typename T>
00810 inline
00811 void EpetraVector<T>::init (const numeric_index_type n,
00812                             const numeric_index_type n_local,
00813                             const std::vector<numeric_index_type>& /*ghost*/,
00814                             const bool fast,
00815                             const ParallelType type)
00816 {
00817   // TODO: we shouldn't ignore the ghost sparsity pattern
00818   this->init(n, n_local, fast, type);
00819 }
00820 
00821 
00822 
00823 template <typename T>
00824 inline
00825 void EpetraVector<T>::init (const numeric_index_type n,
00826                             const bool fast,
00827                             const ParallelType type)
00828 {
00829   this->init(n,n,fast,type);
00830 }
00831 
00832 
00833 
00834 template <typename T>
00835 inline
00836 void EpetraVector<T>::close ()
00837 {
00838   libmesh_assert (this->initialized());
00839 
00840   // Are we adding or inserting?
00841   unsigned char global_last_edit = last_edit;
00842   this->comm().max(global_last_edit);
00843   libmesh_assert(!last_edit || last_edit == global_last_edit);
00844 
00845   if (global_last_edit == 1)
00846     this->GlobalAssemble(Insert);
00847   else if (global_last_edit == 2)
00848     this->GlobalAssemble(Add);
00849   else
00850     libmesh_assert(!global_last_edit);
00851 
00852   this->_is_closed = true;
00853   this->last_edit = 0;
00854 }
00855 
00856 
00857 
00858 template <typename T>
00859 inline
00860 void EpetraVector<T>::clear ()
00861 {
00862   if (this->initialized())
00863     {
00864       // We might just be an interface to a user-provided _vec
00865       if (this->_destroy_vec_on_exit)
00866         {
00867           delete _vec;
00868           _vec = NULL;
00869         }
00870 
00871       // But we currently always own our own _map
00872       delete _map;
00873       _map = NULL;
00874     }
00875 
00876   this->_is_closed = this->_is_initialized = false;
00877 }
00878 
00879 
00880 
00881 template <typename T>
00882 inline
00883 void EpetraVector<T>::zero ()
00884 {
00885   libmesh_assert (this->initialized());
00886   libmesh_assert (this->closed());
00887 
00888   _vec->PutScalar(0.0);
00889 }
00890 
00891 
00892 
00893 template <typename T>
00894 inline
00895 UniquePtr<NumericVector<T> > EpetraVector<T>::zero_clone () const
00896 {
00897   UniquePtr<NumericVector<T> > cloned_vector
00898     (new EpetraVector<T>(this->comm(), AUTOMATIC));
00899 
00900   cloned_vector->init(*this);
00901 
00902   return cloned_vector;
00903 }
00904 
00905 
00906 
00907 template <typename T>
00908 inline
00909 UniquePtr<NumericVector<T> > EpetraVector<T>::clone () const
00910 {
00911   UniquePtr<NumericVector<T> > cloned_vector
00912     (new EpetraVector<T>(this->comm(), AUTOMATIC));
00913 
00914   cloned_vector->init(*this, true);
00915 
00916   *cloned_vector = *this;
00917 
00918   return cloned_vector;
00919 }
00920 
00921 
00922 
00923 template <typename T>
00924 inline
00925 numeric_index_type EpetraVector<T>::size () const
00926 {
00927   libmesh_assert (this->initialized());
00928 
00929   return _vec->GlobalLength();
00930 }
00931 
00932 
00933 
00934 template <typename T>
00935 inline
00936 numeric_index_type EpetraVector<T>::local_size () const
00937 {
00938   libmesh_assert (this->initialized());
00939 
00940   return _vec->MyLength();
00941 }
00942 
00943 template <typename T>
00944 inline
00945 numeric_index_type EpetraVector<T>::first_local_index () const
00946 {
00947   libmesh_assert (this->initialized());
00948 
00949   return _vec->Map().MinMyGID();
00950 }
00951 
00952 
00953 
00954 template <typename T>
00955 inline
00956 numeric_index_type EpetraVector<T>::last_local_index () const
00957 {
00958   libmesh_assert (this->initialized());
00959 
00960   return _vec->Map().MaxMyGID()+1;
00961 }
00962 
00963 
00964 template <typename T>
00965 inline
00966 T EpetraVector<T>::operator() (const numeric_index_type i) const
00967 {
00968   libmesh_assert (this->initialized());
00969   libmesh_assert ( ((i >= this->first_local_index()) &&
00970                     (i <  this->last_local_index())) );
00971 
00972   return (*_vec)[i-this->first_local_index()];
00973 }
00974 
00975 
00976 
00977 template <typename T>
00978 inline
00979 Real EpetraVector<T>::min () const
00980 {
00981   libmesh_assert (this->initialized());
00982 
00983   T value;
00984 
00985   _vec->MinValue(&value);
00986 
00987   return value;
00988 }
00989 
00990 
00991 
00992 template <typename T>
00993 inline
00994 Real EpetraVector<T>::max() const
00995 {
00996   libmesh_assert (this->initialized());
00997 
00998   T value;
00999 
01000   _vec->MaxValue(&value);
01001 
01002   return value;
01003 }
01004 
01005 
01006 
01007 template <typename T>
01008 inline
01009 void EpetraVector<T>::swap (NumericVector<T> &other)
01010 {
01011   NumericVector<T>::swap(other);
01012 
01013   EpetraVector<T>& v = cast_ref<EpetraVector<T>&>(other);
01014 
01015   std::swap(_vec, v._vec);
01016   std::swap(_map, v._map);
01017   std::swap(_destroy_vec_on_exit, v._destroy_vec_on_exit);
01018   std::swap(myFirstID_, v.myFirstID_);
01019   std::swap(myNumIDs_, v.myNumIDs_);
01020   std::swap(myCoefs_, v.myCoefs_);
01021   std::swap(nonlocalIDs_, v.nonlocalIDs_);
01022   std::swap(nonlocalElementSize_, v.nonlocalElementSize_);
01023   std::swap(numNonlocalIDs_, v.numNonlocalIDs_);
01024   std::swap(allocatedNonlocalLength_, v.allocatedNonlocalLength_);
01025   std::swap(nonlocalCoefs_, v.nonlocalCoefs_);
01026   std::swap(last_edit, v.last_edit);
01027   std::swap(ignoreNonLocalEntries_, v.ignoreNonLocalEntries_);
01028 }
01029 
01030 } // namespace libMesh
01031 
01032 
01033 #endif // #ifdef HAVE_EPETRA
01034 #endif // LIBMESH_TRILINOS_EPETRA_VECTOR_H