$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 #ifndef LIBMESH_NUMERIC_VECTOR_H 00021 #define LIBMESH_NUMERIC_VECTOR_H 00022 00023 // Local includes 00024 #include "libmesh/libmesh_common.h" 00025 #include "libmesh/auto_ptr.h" 00026 #include "libmesh/enum_parallel_type.h" 00027 #include "libmesh/enum_solver_package.h" 00028 #include "libmesh/id_types.h" 00029 #include "libmesh/reference_counted_object.h" 00030 #include "libmesh/libmesh.h" 00031 #include "libmesh/parallel_object.h" 00032 #include "libmesh/dense_subvector.h" 00033 #include "libmesh/dense_vector.h" 00034 00035 // C++ includes 00036 #include <cstddef> 00037 #include <set> 00038 #include <vector> 00039 00040 namespace libMesh 00041 { 00042 00043 00044 // forward declarations 00045 template <typename T> class NumericVector; 00046 template <typename T> class DenseVector; 00047 template <typename T> class DenseSubVector; 00048 template <typename T> class SparseMatrix; 00049 template <typename T> class ShellMatrix; 00050 00051 00059 template <typename T> 00060 class NumericVector : public ReferenceCountedObject<NumericVector<T> >, 00061 public ParallelObject 00062 { 00063 public: 00064 00068 explicit 00069 NumericVector (const Parallel::Communicator &comm_in, 00070 const ParallelType ptype = AUTOMATIC); 00071 00075 explicit 00076 NumericVector (const Parallel::Communicator &comm_in, 00077 const numeric_index_type n, 00078 const ParallelType ptype = AUTOMATIC); 00079 00084 NumericVector (const Parallel::Communicator &comm_in, 00085 const numeric_index_type n, 00086 const numeric_index_type n_local, 00087 const ParallelType ptype = AUTOMATIC); 00088 00094 NumericVector (const Parallel::Communicator &comm_in, 00095 const numeric_index_type N, 00096 const numeric_index_type n_local, 00097 const std::vector<numeric_index_type>& ghost, 00098 const ParallelType ptype = AUTOMATIC); 00099 00100 public: 00101 00106 virtual ~NumericVector (); 00107 00113 static UniquePtr<NumericVector<T> > 00114 build(const Parallel::Communicator &comm, 00115 const SolverPackage solver_package = libMesh::default_solver_package()); 00116 00117 #ifndef LIBMESH_DISABLE_COMMWORLD 00118 00123 static UniquePtr<NumericVector<T> > 00124 build(const SolverPackage solver_package = libMesh::default_solver_package()); 00125 #endif 00126 00131 virtual bool initialized() const { return _is_initialized; } 00132 00136 ParallelType type() const { return _type; } 00137 00141 ParallelType & type() { return _type; } 00142 00147 virtual bool closed() const { return _is_closed; } 00148 00152 virtual void close () = 0; 00153 00157 virtual void clear (); 00158 00163 virtual void zero () = 0; 00164 00171 virtual UniquePtr<NumericVector<T> > zero_clone () const = 0; 00172 00177 virtual UniquePtr<NumericVector<T> > clone () const = 0; 00178 00192 virtual void init (const numeric_index_type, 00193 const numeric_index_type, 00194 const bool = false, 00195 const ParallelType = AUTOMATIC) = 0; 00196 00200 virtual void init (const numeric_index_type, 00201 const bool = false, 00202 const ParallelType = AUTOMATIC) = 0; 00203 00208 virtual void init (const numeric_index_type /*N*/, 00209 const numeric_index_type /*n_local*/, 00210 const std::vector<numeric_index_type>& /*ghost*/, 00211 const bool /*fast*/ = false, 00212 const ParallelType = AUTOMATIC) = 0; 00213 00218 virtual void init (const NumericVector<T>& other, 00219 const bool fast = false) = 0; 00220 00224 virtual NumericVector<T> & operator= (const T s) = 0; 00225 00229 virtual NumericVector<T> & operator= (const NumericVector<T> &V) = 0; 00230 00234 virtual NumericVector<T> & operator= (const std::vector<T> &v) = 0; 00235 00241 virtual Real min () const = 0; 00242 00248 virtual Real max () const = 0; 00249 00253 virtual T sum() const = 0; 00254 00259 virtual Real l1_norm () const = 0; 00260 00266 virtual Real l2_norm () const = 0; 00267 00273 virtual Real linfty_norm () const = 0; 00274 00283 virtual Real subset_l1_norm (const std::set<numeric_index_type> & indices) const; 00284 00294 virtual Real subset_l2_norm (const std::set<numeric_index_type> & indices) const; 00295 00304 virtual Real subset_linfty_norm (const std::set<numeric_index_type> & indices) const; 00305 00313 virtual numeric_index_type size () const = 0; 00314 00320 virtual numeric_index_type local_size() const = 0; 00321 00327 virtual numeric_index_type first_local_index() const = 0; 00328 00334 virtual numeric_index_type last_local_index() const = 0; 00335 00339 virtual T operator() (const numeric_index_type i) const = 0; 00340 00344 virtual T el(const numeric_index_type i) const { return (*this)(i); } 00345 00352 virtual void get(const std::vector<numeric_index_type>& index, T* values) const; 00353 00360 void get(const std::vector<numeric_index_type>& index, std::vector<T>& values) const; 00361 00366 virtual NumericVector<T> & operator += (const NumericVector<T> &V) = 0; 00367 00372 virtual NumericVector<T> & operator -= (const NumericVector<T> &V) = 0; 00373 00378 NumericVector<T> & operator *= (const T a) { this->scale(a); return *this; } 00379 00384 NumericVector<T> & operator /= (const T a) { this->scale(1./a); return *this; } 00385 00389 virtual NumericVector<T> & operator /= (NumericVector<T> & /*v*/) = 0; 00390 00394 virtual void reciprocal() = 0; 00395 00400 virtual void conjugate() = 0; 00401 00405 virtual void set (const numeric_index_type i, const T value) = 0; 00406 00410 virtual void add (const numeric_index_type i, const T value) = 0; 00411 00417 virtual void add (const T s) = 0; 00418 00424 virtual void add (const NumericVector<T>& V) = 0; 00425 00431 virtual void add (const T a, const NumericVector<T>& v) = 0; 00432 00439 virtual void add_vector (const T* v, 00440 const std::vector<numeric_index_type>& dof_indices); 00441 00446 void add_vector (const std::vector<T>& v, 00447 const std::vector<numeric_index_type>& dof_indices); 00448 00453 virtual void add_vector (const NumericVector<T>& V, 00454 const std::vector<numeric_index_type>& dof_indices); 00455 00460 void add_vector (const DenseVector<T>& V, 00461 const std::vector<numeric_index_type>& dof_indices); 00462 00467 virtual void add_vector (const NumericVector<T>&, 00468 const SparseMatrix<T>&) = 0; 00469 00474 void add_vector (const NumericVector<T>& v, 00475 const ShellMatrix<T>& a); 00476 00481 virtual void add_vector_transpose (const NumericVector<T>&, 00482 const SparseMatrix<T>&) = 0; 00483 00488 virtual void insert (const T* v, 00489 const std::vector<numeric_index_type>& dof_indices); 00490 00495 void insert (const std::vector<T>& v, 00496 const std::vector<numeric_index_type>& dof_indices); 00497 00504 virtual void insert (const NumericVector<T>& V, 00505 const std::vector<numeric_index_type>& dof_indices); 00506 00513 void insert (const DenseVector<T>& V, 00514 const std::vector<numeric_index_type>& dof_indices); 00515 00521 void insert (const DenseSubVector<T>& V, 00522 const std::vector<numeric_index_type>& dof_indices); 00523 00528 virtual void scale (const T factor) = 0; 00529 00534 virtual void abs() = 0; 00535 00539 virtual T dot(const NumericVector<T>&) const = 0; 00540 00545 virtual void localize (std::vector<T>& v_local) const = 0; 00546 00551 virtual void localize (NumericVector<T>& v_local) const = 0; 00552 00558 virtual void localize (NumericVector<T>& v_local, 00559 const std::vector<numeric_index_type>& send_list) const = 0; 00560 00565 virtual void localize (const numeric_index_type first_local_idx, 00566 const numeric_index_type last_local_idx, 00567 const std::vector<numeric_index_type>& send_list) = 0; 00568 00575 virtual void localize_to_one (std::vector<T>& v_local, 00576 const processor_id_type proc_id=0) const = 0; 00577 00586 virtual int compare (const NumericVector<T> &other_vector, 00587 const Real threshold = TOLERANCE) const; 00588 00597 virtual int local_relative_compare (const NumericVector<T> &other_vector, 00598 const Real threshold = TOLERANCE) const; 00599 00608 virtual int global_relative_compare (const NumericVector<T> &other_vector, 00609 const Real threshold = TOLERANCE) const; 00610 00615 virtual void pointwise_mult (const NumericVector<T>& vec1, 00616 const NumericVector<T>& vec2) = 0; 00617 00622 virtual void print(std::ostream& os=libMesh::out) const; 00623 00628 virtual void print_global(std::ostream& os=libMesh::out) const; 00629 00633 friend std::ostream& operator << (std::ostream& os, const NumericVector<T>& v) 00634 { 00635 v.print_global(os); 00636 return os; 00637 } 00638 00645 virtual void print_matlab(const std::string& /*name*/ = "") const 00646 { 00647 libmesh_not_implemented(); 00648 } 00649 00656 virtual void create_subvector(NumericVector<T>& , 00657 const std::vector<numeric_index_type>& ) const 00658 { 00659 libmesh_not_implemented(); 00660 } 00661 00667 virtual void swap (NumericVector<T> &v); 00668 00669 protected: 00670 00675 bool _is_closed; 00676 00681 bool _is_initialized; 00682 00686 ParallelType _type; 00687 }; 00688 00689 00690 /*----------------------- Inline functions ----------------------------------*/ 00691 00692 00693 00694 template <typename T> 00695 inline 00696 NumericVector<T>::NumericVector (const Parallel::Communicator &comm_in, 00697 const ParallelType ptype) : 00698 ParallelObject(comm_in), 00699 _is_closed(false), 00700 _is_initialized(false), 00701 _type(ptype) 00702 { 00703 } 00704 00705 00706 00707 template <typename T> 00708 inline 00709 NumericVector<T>::NumericVector (const Parallel::Communicator &comm_in, 00710 const numeric_index_type /*n*/, 00711 const ParallelType ptype) : 00712 ParallelObject(comm_in), 00713 _is_closed(false), 00714 _is_initialized(false), 00715 _type(ptype) 00716 { 00717 libmesh_not_implemented(); // Abstract base class! 00718 // init(n, n, false, ptype); 00719 } 00720 00721 00722 00723 template <typename T> 00724 inline 00725 NumericVector<T>::NumericVector (const Parallel::Communicator &comm_in, 00726 const numeric_index_type /*n*/, 00727 const numeric_index_type /*n_local*/, 00728 const ParallelType ptype) : 00729 ParallelObject(comm_in), 00730 _is_closed(false), 00731 _is_initialized(false), 00732 _type(ptype) 00733 { 00734 libmesh_not_implemented(); // Abstract base class! 00735 // init(n, n_local, false, ptype); 00736 } 00737 00738 00739 00740 template <typename T> 00741 inline 00742 NumericVector<T>::NumericVector (const Parallel::Communicator &comm_in, 00743 const numeric_index_type /*n*/, 00744 const numeric_index_type /*n_local*/, 00745 const std::vector<numeric_index_type>& /*ghost*/, 00746 const ParallelType ptype) : 00747 ParallelObject(comm_in), 00748 _is_closed(false), 00749 _is_initialized(false), 00750 _type(ptype) 00751 { 00752 libmesh_not_implemented(); // Abstract base class! 00753 // init(n, n_local, ghost, false, ptype); 00754 } 00755 00756 00757 00758 template <typename T> 00759 inline 00760 NumericVector<T>::~NumericVector () 00761 { 00762 clear (); 00763 } 00764 00765 00766 00767 template <typename T> 00768 inline 00769 void NumericVector<T>::clear () 00770 { 00771 _is_closed = false; 00772 _is_initialized = false; 00773 } 00774 00775 00776 00777 template <typename T> 00778 inline 00779 void NumericVector<T>::get(const std::vector<numeric_index_type>& index, T* values) const 00780 { 00781 const std::size_t num = index.size(); 00782 for(std::size_t i=0; i<num; i++) 00783 { 00784 values[i] = (*this)(index[i]); 00785 } 00786 } 00787 00788 00789 00790 template <typename T> 00791 inline 00792 void NumericVector<T>::get(const std::vector<numeric_index_type>& index, std::vector<T>& values) const 00793 { 00794 const std::size_t num = index.size(); 00795 values.resize(num); 00796 if (!num) 00797 return; 00798 00799 this->get(index, &values[0]); 00800 } 00801 00802 00803 00804 template <typename T> 00805 inline 00806 void NumericVector<T>::add_vector(const std::vector<T>& v, 00807 const std::vector<numeric_index_type>& dof_indices) 00808 { 00809 libmesh_assert(v.size() == dof_indices.size()); 00810 if (!v.empty()) 00811 this->add_vector(&v[0], dof_indices); 00812 } 00813 00814 00815 00816 template <typename T> 00817 inline 00818 void NumericVector<T>::add_vector(const DenseVector<T>& v, 00819 const std::vector<numeric_index_type>& dof_indices) 00820 { 00821 libmesh_assert(v.size() == dof_indices.size()); 00822 if (!v.empty()) 00823 this->add_vector(&v(0), dof_indices); 00824 } 00825 00826 00827 00828 template <typename T> 00829 inline 00830 void NumericVector<T>::insert(const std::vector<T>& v, 00831 const std::vector<numeric_index_type>& dof_indices) 00832 { 00833 libmesh_assert(v.size() == dof_indices.size()); 00834 if (!v.empty()) 00835 this->insert(&v[0], dof_indices); 00836 } 00837 00838 00839 00840 template <typename T> 00841 inline 00842 void NumericVector<T>::insert(const DenseVector<T>& v, 00843 const std::vector<numeric_index_type>& dof_indices) 00844 { 00845 libmesh_assert(v.size() == dof_indices.size()); 00846 if (!v.empty()) 00847 this->insert(&v(0), dof_indices); 00848 } 00849 00850 00851 00852 template <typename T> 00853 inline 00854 void NumericVector<T>::insert(const DenseSubVector<T>& v, 00855 const std::vector<numeric_index_type>& dof_indices) 00856 { 00857 libmesh_assert(v.size() == dof_indices.size()); 00858 if (!v.empty()) 00859 this->insert(&v(0), dof_indices); 00860 } 00861 00862 00863 00864 // Full specialization of the print() member for complex 00865 // variables. This must precede the non-specialized 00866 // version, at least according to icc v7.1 00867 template <> 00868 inline 00869 void NumericVector<Complex>::print(std::ostream& os) const 00870 { 00871 libmesh_assert (this->initialized()); 00872 os << "Size\tglobal = " << this->size() 00873 << "\t\tlocal = " << this->local_size() << std::endl; 00874 00875 // std::complex<>::operator<<() is defined, but use this form 00876 os << "#\tReal part\t\tImaginary part" << std::endl; 00877 for (numeric_index_type i=this->first_local_index(); i<this->last_local_index(); i++) 00878 os << i << "\t" 00879 << (*this)(i).real() << "\t\t" 00880 << (*this)(i).imag() << std::endl; 00881 } 00882 00883 00884 00885 template <typename T> 00886 inline 00887 void NumericVector<T>::print(std::ostream& os) const 00888 { 00889 libmesh_assert (this->initialized()); 00890 os << "Size\tglobal = " << this->size() 00891 << "\t\tlocal = " << this->local_size() << std::endl; 00892 00893 os << "#\tValue" << std::endl; 00894 for (numeric_index_type i=this->first_local_index(); i<this->last_local_index(); i++) 00895 os << i << "\t" << (*this)(i) << std::endl; 00896 } 00897 00898 00899 00900 template <> 00901 inline 00902 void NumericVector<Complex>::print_global(std::ostream& os) const 00903 { 00904 libmesh_assert (this->initialized()); 00905 00906 std::vector<Complex> v(this->size()); 00907 this->localize(v); 00908 00909 // Right now we only want one copy of the output 00910 if (this->processor_id()) 00911 return; 00912 00913 os << "Size\tglobal = " << this->size() << std::endl; 00914 os << "#\tReal part\t\tImaginary part" << std::endl; 00915 for (numeric_index_type i=0; i!=v.size(); i++) 00916 os << i << "\t" 00917 << v[i].real() << "\t\t" 00918 << v[i].imag() << std::endl; 00919 } 00920 00921 00922 template <typename T> 00923 inline 00924 void NumericVector<T>::print_global(std::ostream& os) const 00925 { 00926 libmesh_assert (this->initialized()); 00927 00928 std::vector<T> v(this->size()); 00929 this->localize(v); 00930 00931 // Right now we only want one copy of the output 00932 if (this->processor_id()) 00933 return; 00934 00935 os << "Size\tglobal = " << this->size() << std::endl; 00936 os << "#\tValue" << std::endl; 00937 for (numeric_index_type i=0; i!=v.size(); i++) 00938 os << i << "\t" << v[i] << std::endl; 00939 } 00940 00941 00942 00943 template <typename T> 00944 inline 00945 void NumericVector<T>::swap (NumericVector<T> &v) 00946 { 00947 std::swap(_is_closed, v._is_closed); 00948 std::swap(_is_initialized, v._is_initialized); 00949 std::swap(_type, v._type); 00950 } 00951 00952 00953 } // namespace libMesh 00954 00955 00956 #endif // LIBMESH_NUMERIC_VECTOR_H