$extrastylesheet
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