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