$extrastylesheet
eigen_sparse_matrix.C
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 // C++ includes
00021 
00022 // Local includes
00023 #include "libmesh/libmesh_config.h"
00024 
00025 #ifdef LIBMESH_HAVE_EIGEN
00026 
00027 #include "libmesh/eigen_sparse_vector.h"
00028 #include "libmesh/eigen_sparse_matrix.h"
00029 #include "libmesh/dense_matrix.h"
00030 #include "libmesh/dof_map.h"
00031 #include "libmesh/sparsity_pattern.h"
00032 
00033 namespace libMesh
00034 {
00035 
00036 
00037 //-----------------------------------------------------------------------
00038 // EigenSparseMatrix members
00039 template <typename T>
00040 void EigenSparseMatrix<T>::init (const numeric_index_type m_in,
00041                                  const numeric_index_type n_in,
00042                                  const numeric_index_type libmesh_dbg_var(m_l),
00043                                  const numeric_index_type libmesh_dbg_var(n_l),
00044                                  const numeric_index_type nnz,
00045                                  const numeric_index_type,
00046                                  const numeric_index_type)
00047 {
00048   // noz ignored...  only used for multiple processors!
00049   libmesh_assert_equal_to (m_in, m_l);
00050   libmesh_assert_equal_to (n_in, n_l);
00051   libmesh_assert_equal_to (m_in, n_in);
00052   libmesh_assert_greater  (nnz, 0);
00053 
00054   _mat.resize(m_in, n_in);
00055   _mat.reserve(Eigen::Matrix<numeric_index_type, Eigen::Dynamic, 1>::Constant(m_in,nnz));
00056 
00057   this->_is_initialized = true;
00058 }
00059 
00060 
00061 
00062 template <typename T>
00063 void EigenSparseMatrix<T>::init ()
00064 {
00065   // Ignore calls on initialized objects
00066   if (this->initialized())
00067     return;
00068 
00069   // We need the DofMap for this!
00070   libmesh_assert(this->_dof_map);
00071 
00072   // Clear intialized matrices
00073   if (this->initialized())
00074     this->clear();
00075 
00076   const numeric_index_type n_rows   = this->_dof_map->n_dofs();
00077   const numeric_index_type n_cols   = n_rows;
00078 
00079 #ifndef NDEBUG
00080   // The following variables are only used for assertions,
00081   // so avoid declaring them when asserts are inactive.
00082   const numeric_index_type n_l = this->_dof_map->n_dofs_on_processor(0);
00083   const numeric_index_type m_l = n_l;
00084 #endif
00085 
00086   // Laspack Matrices only work for uniprocessor cases
00087   libmesh_assert_equal_to (n_rows, n_cols);
00088   libmesh_assert_equal_to (m_l, n_rows);
00089   libmesh_assert_equal_to (n_l, n_cols);
00090 
00091   const std::vector<numeric_index_type>& n_nz = this->_dof_map->get_n_nz();
00092 
00093 #ifndef NDEBUG
00094   // The following variables are only used for assertions,
00095   // so avoid declaring them when asserts are inactive.
00096   const std::vector<numeric_index_type>& n_oz = this->_dof_map->get_n_oz();
00097 #endif
00098 
00099   // Make sure the sparsity pattern isn't empty
00100   libmesh_assert_equal_to (n_nz.size(), n_l);
00101   libmesh_assert_equal_to (n_oz.size(), n_l);
00102 
00103   if (n_rows==0)
00104     {
00105       _mat.resize(0,0);
00106       return;
00107     }
00108 
00109   _mat.resize(n_rows,n_cols);
00110   _mat.reserve(n_nz);
00111 
00112   this->_is_initialized = true;
00113 
00114   libmesh_assert_equal_to (n_rows, this->m());
00115   libmesh_assert_equal_to (n_cols, this->n());
00116 }
00117 
00118 
00119 
00120 template <typename T>
00121 void EigenSparseMatrix<T>::add_matrix(const DenseMatrix<T>& dm,
00122                                       const std::vector<numeric_index_type>& rows,
00123                                       const std::vector<numeric_index_type>& cols)
00124 
00125 {
00126   libmesh_assert (this->initialized());
00127   unsigned int n_rows = cast_int<unsigned int>(rows.size());
00128   unsigned int n_cols = cast_int<unsigned int>(cols.size());
00129   libmesh_assert_equal_to (dm.m(), n_rows);
00130   libmesh_assert_equal_to (dm.n(), n_cols);
00131 
00132 
00133   for (unsigned int i=0; i<n_rows; i++)
00134     for (unsigned int j=0; j<n_cols; j++)
00135       this->add(rows[i],cols[j],dm(i,j));
00136 }
00137 
00138 
00139 
00140 template <typename T>
00141 void EigenSparseMatrix<T>::get_diagonal (NumericVector<T>& dest_in) const
00142 {
00143   EigenSparseVector<T>& dest = cast_ref<EigenSparseVector<T>&>(dest_in);
00144 
00145   dest._vec = _mat.diagonal();
00146 }
00147 
00148 
00149 
00150 template <typename T>
00151 void EigenSparseMatrix<T>::get_transpose (SparseMatrix<T>& dest_in) const
00152 {
00153   EigenSparseMatrix<T>& dest = cast_ref<EigenSparseMatrix<T>&>(dest_in);
00154 
00155   dest._mat = _mat.transpose();
00156 }
00157 
00158 
00159 
00160 template <typename T>
00161 EigenSparseMatrix<T>::EigenSparseMatrix (const Parallel::Communicator &comm_in) :
00162   SparseMatrix<T>(comm_in),
00163   _closed (false)
00164 {
00165 }
00166 
00167 
00168 
00169 template <typename T>
00170 EigenSparseMatrix<T>::~EigenSparseMatrix ()
00171 {
00172   this->clear ();
00173 }
00174 
00175 
00176 
00177 template <typename T>
00178 void EigenSparseMatrix<T>::clear ()
00179 {
00180   _mat.resize(0,0);
00181 
00182   _closed = false;
00183   this->_is_initialized = false;
00184 }
00185 
00186 
00187 
00188 template <typename T>
00189 void EigenSparseMatrix<T>::zero ()
00190 {
00191   _mat.setZero();
00192 }
00193 
00194 
00195 
00196 template <typename T>
00197 numeric_index_type EigenSparseMatrix<T>::m () const
00198 {
00199   libmesh_assert (this->initialized());
00200 
00201   return _mat.rows();
00202 }
00203 
00204 
00205 
00206 template <typename T>
00207 numeric_index_type EigenSparseMatrix<T>::n () const
00208 {
00209   libmesh_assert (this->initialized());
00210 
00211   return _mat.cols();
00212 }
00213 
00214 
00215 
00216 template <typename T>
00217 numeric_index_type EigenSparseMatrix<T>::row_start () const
00218 {
00219   return 0;
00220 }
00221 
00222 
00223 
00224 template <typename T>
00225 numeric_index_type EigenSparseMatrix<T>::row_stop () const
00226 {
00227   return this->m();
00228 }
00229 
00230 
00231 
00232 template <typename T>
00233 void EigenSparseMatrix<T>::set (const numeric_index_type i,
00234                                 const numeric_index_type j,
00235                                 const T value)
00236 {
00237   libmesh_assert (this->initialized());
00238   libmesh_assert_less (i, this->m());
00239   libmesh_assert_less (j, this->n());
00240 
00241   _mat.coeffRef(i,j) = value;
00242 }
00243 
00244 
00245 
00246 template <typename T>
00247 void EigenSparseMatrix<T>::add (const numeric_index_type i,
00248                                 const numeric_index_type j,
00249                                 const T value)
00250 {
00251   libmesh_assert (this->initialized());
00252   libmesh_assert_less (i, this->m());
00253   libmesh_assert_less (j, this->n());
00254 
00255   _mat.coeffRef(i,j) += value;
00256 }
00257 
00258 
00259 
00260 template <typename T>
00261 void EigenSparseMatrix<T>::add_matrix(const DenseMatrix<T>& dm,
00262                                       const std::vector<numeric_index_type>& dof_indices)
00263 {
00264   this->add_matrix (dm, dof_indices, dof_indices);
00265 }
00266 
00267 
00268 
00269 template <typename T>
00270 void EigenSparseMatrix<T>::add (const T a_in, SparseMatrix<T> &X_in)
00271 {
00272   libmesh_assert (this->initialized());
00273   libmesh_assert_equal_to (this->m(), X_in.m());
00274   libmesh_assert_equal_to (this->n(), X_in.n());
00275 
00276   EigenSparseMatrix<T> &X = cast_ref<EigenSparseMatrix<T>&> (X_in);
00277 
00278   _mat += X._mat*a_in;
00279 }
00280 
00281 
00282 
00283 
00284 template <typename T>
00285 T EigenSparseMatrix<T>::operator () (const numeric_index_type i,
00286                                      const numeric_index_type j) const
00287 {
00288   libmesh_assert (this->initialized());
00289   libmesh_assert_less (i, this->m());
00290   libmesh_assert_less (j, this->n());
00291 
00292   return _mat.coeff(i,j);
00293 }
00294 
00295 
00296 
00297 //------------------------------------------------------------------
00298 // Explicit instantiations
00299 template class EigenSparseMatrix<Number>;
00300 
00301 } // namespace libMesh
00302 
00303 
00304 #endif // #ifdef LIBMESH_HAVE_EIGEN