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