$extrastylesheet
eigen_sparse_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 
00019 
00020 
00021 #ifndef LIBMESH_EIGEN_SPARSE_VECTOR_H
00022 #define LIBMESH_EIGEN_SPARSE_VECTOR_H
00023 
00024 
00025 
00026 #include "libmesh/libmesh_common.h"
00027 
00028 #ifdef LIBMESH_HAVE_EIGEN
00029 
00030 // Local includes
00031 #include "libmesh/eigen_core_support.h"
00032 #include "libmesh/numeric_vector.h"
00033 
00034 // C++ includes
00035 
00036 // Eigen includes
00037 
00038 namespace libMesh
00039 {
00040 
00041 
00042 // Forward declarations
00043 template <typename T> class EigenSparseMatrix;
00044 template <typename T> class EigenSparseLinearSolver;
00045 template <typename T> class SparseMatrix;
00046 
00047 
00055 template <typename T>
00056 class EigenSparseVector : public NumericVector<T>
00057 {
00058 public:
00059 
00063   explicit
00064   EigenSparseVector (const Parallel::Communicator &comm_in,
00065                      const ParallelType = AUTOMATIC);
00066 
00070   explicit
00071   EigenSparseVector (const Parallel::Communicator &comm_in,
00072                      const numeric_index_type n,
00073                      const ParallelType = AUTOMATIC);
00074 
00079   EigenSparseVector (const Parallel::Communicator &comm_in,
00080                      const numeric_index_type n,
00081                      const numeric_index_type n_local,
00082                      const ParallelType = AUTOMATIC);
00083 
00089   EigenSparseVector (const Parallel::Communicator &comm_in,
00090                      const numeric_index_type N,
00091                      const numeric_index_type n_local,
00092                      const std::vector<numeric_index_type>& ghost,
00093                      const ParallelType = AUTOMATIC);
00094 
00099   ~EigenSparseVector ();
00100 
00104   typedef EigenSV DataType;
00105 
00109   void close ();
00110 
00114   void clear ();
00115 
00120   void zero ();
00121 
00127   virtual UniquePtr<NumericVector<T> > zero_clone () const;
00128 
00132   UniquePtr<NumericVector<T> > clone () const;
00133 
00147   void init (const numeric_index_type N,
00148              const numeric_index_type n_local,
00149              const bool         fast=false,
00150              const ParallelType ptype=AUTOMATIC);
00151 
00155   void init (const numeric_index_type N,
00156              const bool         fast=false,
00157              const ParallelType ptype=AUTOMATIC);
00158 
00163   void init (const numeric_index_type /*N*/,
00164              const numeric_index_type /*n_local*/,
00165              const std::vector<numeric_index_type>& /*ghost*/,
00166              const bool /*fast*/ = false,
00167              const ParallelType = AUTOMATIC);
00168 
00173   virtual void init (const NumericVector<T>& other,
00174                      const bool fast = false);
00175 
00179   NumericVector<T> & operator= (const T s);
00180 
00184   NumericVector<T> & operator= (const NumericVector<T> &V);
00185 
00189   EigenSparseVector<T> & operator= (const EigenSparseVector<T> &V);
00190 
00194   NumericVector<T> & operator= (const std::vector<T> &v);
00195 
00201   Real min () const;
00202 
00208   Real max () const;
00209 
00213   T sum () const;
00214 
00219   Real l1_norm () const;
00220 
00226   Real l2_norm () const;
00227 
00233   Real linfty_norm () const;
00234 
00242   numeric_index_type size () const;
00243 
00248   numeric_index_type local_size() const;
00249 
00254   numeric_index_type first_local_index() const;
00255 
00260   numeric_index_type last_local_index() const;
00261 
00265   T operator() (const numeric_index_type i) const;
00266 
00271   NumericVector<T> & operator += (const NumericVector<T> &V);
00272 
00277   NumericVector<T> & operator -= (const NumericVector<T> &V);
00278 
00282   virtual NumericVector<T> & operator /= (NumericVector<T> & v_in);
00283 
00287   virtual void reciprocal();
00288 
00293   virtual void conjugate();
00294 
00298   void set (const numeric_index_type i, const T value);
00299 
00303   void add (const numeric_index_type i, const T value);
00304 
00310   void add (const T s);
00311 
00317   void add (const NumericVector<T>& V);
00318 
00324   void add (const T a, const NumericVector<T>& v);
00325 
00330   using NumericVector<T>::add_vector;
00331 
00336   void add_vector (const NumericVector<T> &,
00337                    const SparseMatrix<T> &);
00338 
00343   void add_vector_transpose (const NumericVector<T> &,
00344                              const SparseMatrix<T> &);
00345 
00350   void scale (const T factor);
00351 
00356   virtual void abs();
00357 
00361   virtual T dot(const NumericVector<T>& V) const;
00362 
00367   void localize (std::vector<T>& v_local) const;
00368 
00373   void localize (NumericVector<T>& v_local) const;
00374 
00380   void localize (NumericVector<T>& v_local,
00381                  const std::vector<numeric_index_type>& send_list) const;
00382 
00387   void localize (const numeric_index_type first_local_idx,
00388                  const numeric_index_type last_local_idx,
00389                  const std::vector<numeric_index_type>& send_list);
00390 
00391 
00398   void localize_to_one (std::vector<T>& v_local,
00399                         const processor_id_type proc_id=0) const;
00400 
00405   virtual void pointwise_mult (const NumericVector<T>& vec1,
00406                                const NumericVector<T>& vec2);
00407 
00411   virtual void swap (NumericVector<T> &v);
00412 
00417   DataType &       vec ()        { return _vec; }
00418   const DataType & vec () const  { return _vec; }
00419 
00420 private:
00421 
00425   DataType _vec;
00426 
00430   friend class EigenSparseMatrix<T>;
00431   friend class EigenSparseLinearSolver<T>;
00432 };
00433 
00434 
00435 
00436 //----------------------- ----------------------------------
00437 // EigenSparseVector inline methods
00438 template <typename T>
00439 inline
00440 EigenSparseVector<T>::EigenSparseVector (const Parallel::Communicator &comm_in,
00441                                          const ParallelType ptype)
00442   : NumericVector<T>(comm_in, ptype)
00443 {
00444   this->_type = ptype;
00445 }
00446 
00447 
00448 
00449 template <typename T>
00450 inline
00451 EigenSparseVector<T>::EigenSparseVector (const Parallel::Communicator &comm_in,
00452                                          const numeric_index_type n,
00453                                          const ParallelType ptype)
00454   : NumericVector<T>(comm_in, ptype)
00455 {
00456   this->init(n, n, false, ptype);
00457 }
00458 
00459 
00460 
00461 template <typename T>
00462 inline
00463 EigenSparseVector<T>::EigenSparseVector (const Parallel::Communicator &comm_in,
00464                                          const numeric_index_type n,
00465                                          const numeric_index_type n_local,
00466                                          const ParallelType ptype)
00467   : NumericVector<T>(comm_in, ptype)
00468 {
00469   this->init(n, n_local, false, ptype);
00470 }
00471 
00472 
00473 
00474 template <typename T>
00475 inline
00476 EigenSparseVector<T>::EigenSparseVector (const Parallel::Communicator &comm_in,
00477                                          const numeric_index_type N,
00478                                          const numeric_index_type n_local,
00479                                          const std::vector<numeric_index_type>& ghost,
00480                                          const ParallelType ptype)
00481   : NumericVector<T>(comm_in, ptype)
00482 {
00483   this->init(N, n_local, ghost, false, ptype);
00484 }
00485 
00486 
00487 
00488 template <typename T>
00489 inline
00490 EigenSparseVector<T>::~EigenSparseVector ()
00491 {
00492   this->clear ();
00493 }
00494 
00495 
00496 
00497 template <typename T>
00498 inline
00499 void EigenSparseVector<T>::init (const numeric_index_type n,
00500                                  const numeric_index_type libmesh_dbg_var(n_local),
00501                                  const bool fast,
00502                                  const ParallelType)
00503 {
00504   // Eigen vectors only for serial cases,
00505   // but can provide a "parallel" vector on one processor.
00506   libmesh_assert_equal_to (n, n_local);
00507 
00508   this->_type = SERIAL;
00509 
00510   // Clear initialized vectors
00511   if (this->initialized())
00512     this->clear();
00513 
00514   _vec.resize(n);
00515 
00516   this->_is_initialized = true;
00517 #ifndef NDEBUG
00518   this->_is_closed = true;
00519 #endif
00520 
00521   // Optionally zero out all components
00522   if (fast == false)
00523     this->zero ();
00524 
00525   return;
00526 }
00527 
00528 
00529 
00530 template <typename T>
00531 inline
00532 void EigenSparseVector<T>::init (const numeric_index_type n,
00533                                  const bool fast,
00534                                  const ParallelType ptype)
00535 {
00536   this->init(n,n,fast,ptype);
00537 }
00538 
00539 
00540 template <typename T>
00541 inline
00542 void EigenSparseVector<T>::init (const numeric_index_type n,
00543                                  const numeric_index_type n_local,
00544                                  const std::vector<numeric_index_type>& libmesh_dbg_var(ghost),
00545                                  const bool fast,
00546                                  const ParallelType ptype)
00547 {
00548   libmesh_assert(ghost.empty());
00549   this->init(n,n_local,fast,ptype);
00550 }
00551 
00552 
00553 
00554 /* Default implementation for solver packages for which ghosted
00555    vectors are not yet implemented.  */
00556 template <class T>
00557 void EigenSparseVector<T>::init (const NumericVector<T>& other,
00558                                  const bool fast)
00559 {
00560   this->init(other.size(),other.local_size(),fast,other.type());
00561 }
00562 
00563 
00564 
00565 template <typename T>
00566 inline
00567 void EigenSparseVector<T>::close ()
00568 {
00569   libmesh_assert (this->initialized());
00570 
00571 #ifndef NDEBUG
00572   this->_is_closed = true;
00573 #endif
00574 }
00575 
00576 
00577 
00578 template <typename T>
00579 inline
00580 void EigenSparseVector<T>::clear ()
00581 {
00582   _vec.resize(0);
00583 
00584   this->_is_initialized = false;
00585 #ifndef NDEBUG
00586   this->_is_closed = false;
00587 #endif
00588 }
00589 
00590 
00591 
00592 template <typename T> inline
00593 void EigenSparseVector<T>::zero ()
00594 {
00595   libmesh_assert (this->initialized());
00596   libmesh_assert (this->closed());
00597 
00598   _vec.setZero();
00599 }
00600 
00601 
00602 
00603 template <typename T>
00604 inline
00605 UniquePtr<NumericVector<T> > EigenSparseVector<T>::zero_clone () const
00606 {
00607   NumericVector<T>* cloned_vector = new EigenSparseVector<T>(this->comm());
00608   cloned_vector->init(*this);
00609   return UniquePtr<NumericVector<T> >(cloned_vector);
00610 }
00611 
00612 
00613 
00614 template <typename T>
00615 inline
00616 UniquePtr<NumericVector<T> > EigenSparseVector<T>::clone () const
00617 {
00618   NumericVector<T>* cloned_vector = new EigenSparseVector<T>(this->comm());
00619   cloned_vector->init(*this, true);
00620   *cloned_vector = *this;
00621   return UniquePtr<NumericVector<T> >(cloned_vector);
00622 }
00623 
00624 
00625 
00626 template <typename T>
00627 inline
00628 numeric_index_type EigenSparseVector<T>::size () const
00629 {
00630   libmesh_assert (this->initialized());
00631 
00632   return static_cast<numeric_index_type>(_vec.size());
00633 }
00634 
00635 
00636 
00637 template <typename T>
00638 inline
00639 numeric_index_type EigenSparseVector<T>::local_size () const
00640 {
00641   libmesh_assert (this->initialized());
00642 
00643   return this->size();
00644 }
00645 
00646 
00647 
00648 template <typename T>
00649 inline
00650 numeric_index_type EigenSparseVector<T>::first_local_index () const
00651 {
00652   libmesh_assert (this->initialized());
00653 
00654   return 0;
00655 }
00656 
00657 
00658 
00659 template <typename T>
00660 inline
00661 numeric_index_type EigenSparseVector<T>::last_local_index () const
00662 {
00663   libmesh_assert (this->initialized());
00664 
00665   return this->size();
00666 }
00667 
00668 
00669 
00670 template <typename T>
00671 inline
00672 void EigenSparseVector<T>::set (const numeric_index_type i, const T value)
00673 {
00674   libmesh_assert (this->initialized());
00675   libmesh_assert_less (i, this->size());
00676 
00677   _vec[static_cast<eigen_idx_type>(i)] = value;
00678 
00679 #ifndef NDEBUG
00680   this->_is_closed = false;
00681 #endif
00682 }
00683 
00684 
00685 
00686 template <typename T>
00687 inline
00688 void EigenSparseVector<T>::add (const numeric_index_type i, const T value)
00689 {
00690   libmesh_assert (this->initialized());
00691   libmesh_assert_less (i, this->size());
00692 
00693   _vec[static_cast<eigen_idx_type>(i)] += value;
00694 
00695 #ifndef NDEBUG
00696   this->_is_closed = false;
00697 #endif
00698 }
00699 
00700 
00701 
00702 template <typename T>
00703 inline
00704 T EigenSparseVector<T>::operator() (const numeric_index_type i) const
00705 {
00706   libmesh_assert (this->initialized());
00707   libmesh_assert ( ((i >= this->first_local_index()) &&
00708                     (i <  this->last_local_index())) );
00709 
00710   return _vec[static_cast<eigen_idx_type>(i)];
00711 }
00712 
00713 
00714 
00715 template <typename T>
00716 inline
00717 void EigenSparseVector<T>::swap (NumericVector<T> &other)
00718 {
00719   EigenSparseVector<T>& v = cast_ref<EigenSparseVector<T>&>(other);
00720 
00721   _vec.swap(v._vec);
00722 
00723   std::swap (this->_is_closed,      v._is_closed);
00724   std::swap (this->_is_initialized, v._is_initialized);
00725   std::swap (this->_type,           v._type);
00726 }
00727 
00728 
00729 } // namespace libMesh
00730 
00731 
00732 #endif // #ifdef LIBMESH_HAVE_EIGEN
00733 #endif // LIBMESH_EIGEN_SPARSE_VECTOR_H