Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : #ifndef LIBMESH_LASPACK_MATRIX_H 21 : #define LIBMESH_LASPACK_MATRIX_H 22 : 23 : #include "libmesh/libmesh_config.h" 24 : 25 : #ifdef LIBMESH_HAVE_LASPACK 26 : 27 : // Local includes 28 : #include "libmesh/sparse_matrix.h" 29 : 30 : // Laspack includes 31 : #include <qmatrix.h> 32 : 33 : // C++ includes 34 : #include <algorithm> 35 : #include <cstddef> 36 : 37 : namespace libMesh 38 : { 39 : 40 : // Forward declarations 41 : template <typename T> class DenseMatrix; 42 : template <typename T> class LaspackVector; 43 : template <typename T> class LaspackLinearSolver; 44 : 45 : /** 46 : * The LaspackMatrix class wraps a QMatrix object from the Laspack 47 : * library. Currently Laspack only supports real datatypes, so this 48 : * class is a full specialization of \p SparseMatrix<T> with \p T = \p 49 : * Real. All overridden virtual functions are documented in 50 : * sparse_matrix.h. 51 : * 52 : * \author Benjamin S. Kirk 53 : * \date 2003 54 : */ 55 : template <typename T> 56 : class LaspackMatrix final : public SparseMatrix<T> 57 : { 58 : 59 : public: 60 : /** 61 : * Constructor; initializes the matrix to be empty, without any 62 : * structure, i.e. the matrix is not usable at all. This 63 : * constructor is therefore only useful for matrices which are 64 : * members of a class. All other matrices should be created at a 65 : * point in the data flow where all necessary information is 66 : * available. 67 : * 68 : * You have to initialize the matrix before usage with \p init(...). 69 : */ 70 : LaspackMatrix (const Parallel::Communicator & comm); 71 : 72 : /** 73 : * This class manages a C-style struct (QMatrix) manually, so we 74 : * don't want to allow any automatic copy/move functions to be 75 : * generated, and we can't default the destructor. 76 : */ 77 : LaspackMatrix (LaspackMatrix &&) = delete; 78 : LaspackMatrix (const LaspackMatrix &) = delete; 79 : LaspackMatrix & operator= (const LaspackMatrix &) = delete; 80 : LaspackMatrix & operator= (LaspackMatrix &&) = delete; 81 : virtual ~LaspackMatrix (); 82 0 : virtual SparseMatrix<T> & operator=(const SparseMatrix<T> &) override 83 : { 84 0 : libmesh_not_implemented(); 85 : return *this; 86 : } 87 : 88 0 : virtual SolverPackage solver_package() override 89 : { 90 0 : return LASPACK_SOLVERS; 91 : } 92 : 93 : /** 94 : * The \p LaspackMatrix needs the full sparsity pattern. 95 : */ 96 0 : virtual bool need_full_sparsity_pattern() const override 97 0 : { return true; } 98 : 99 : /** 100 : * Updates the matrix sparsity pattern. This will tell the 101 : * underlying matrix storage scheme how to map the \f$ (i,j) \f$ 102 : * elements. 103 : */ 104 : virtual void update_sparsity_pattern (const SparsityPattern::Graph &) override; 105 : 106 : virtual void init (const numeric_index_type m, 107 : const numeric_index_type n, 108 : const numeric_index_type m_l, 109 : const numeric_index_type n_l, 110 : const numeric_index_type nnz=30, 111 : const numeric_index_type noz=10, 112 : const numeric_index_type blocksize=1) override; 113 : 114 : virtual void init (ParallelType = PARALLEL) override; 115 : 116 : virtual void clear () override; 117 : 118 : virtual void zero () override; 119 : 120 : virtual std::unique_ptr<SparseMatrix<T>> zero_clone () const override; 121 : 122 : virtual std::unique_ptr<SparseMatrix<T>> clone () const override; 123 : 124 : virtual void close () override; 125 : 126 : virtual numeric_index_type m () const override; 127 : 128 : virtual numeric_index_type n () const override; 129 : 130 : virtual numeric_index_type row_start () const override; 131 : 132 : virtual numeric_index_type row_stop () const override; 133 : 134 : virtual numeric_index_type col_start () const override; 135 : 136 : virtual numeric_index_type col_stop () const override; 137 : 138 : virtual void set (const numeric_index_type i, 139 : const numeric_index_type j, 140 : const T value) override; 141 : 142 : virtual void add (const numeric_index_type i, 143 : const numeric_index_type j, 144 : const T value) override; 145 : 146 : virtual void add_matrix (const DenseMatrix<T> & dm, 147 : const std::vector<numeric_index_type> & rows, 148 : const std::vector<numeric_index_type> & cols) override; 149 : 150 : virtual void add_matrix (const DenseMatrix<T> & dm, 151 : const std::vector<numeric_index_type> & dof_indices) override; 152 : 153 : /** 154 : * Compute A += a*X for scalar \p a, matrix \p X. 155 : * 156 : * \note LASPACK does not provide a true \p axpy for matrices, 157 : * so a hand-coded version with hopefully acceptable performance 158 : * is provided. 159 : */ 160 : virtual void add (const T a, const SparseMatrix<T> & X) override; 161 : 162 : virtual T operator () (const numeric_index_type i, 163 : const numeric_index_type j) const override; 164 : 165 : virtual Real l1_norm () const override; 166 : 167 0 : virtual Real linfty_norm () const override { libmesh_not_implemented(); return 0.; } 168 : 169 2 : virtual bool closed() const override { return _closed; } 170 : 171 0 : virtual void print_personal(std::ostream & os=libMesh::out) const override { this->print(os); } 172 : 173 : virtual void get_diagonal (NumericVector<T> & dest) const override; 174 : 175 : virtual void get_transpose (SparseMatrix<T> & dest) const override; 176 : 177 : virtual void get_row(numeric_index_type i, 178 : std::vector<numeric_index_type> & indices, 179 : std::vector<T> & values) const override; 180 : 181 : private: 182 : 183 : /** 184 : * \returns The position in the compressed row 185 : * storage scheme of the \f$ (i,j) \f$ element. 186 : */ 187 : numeric_index_type pos (const numeric_index_type i, 188 : const numeric_index_type j) const; 189 : 190 : /** 191 : * The Laspack sparse matrix pointer. 192 : */ 193 : QMatrix _QMat; 194 : 195 : /** 196 : * The compressed row indices. 197 : */ 198 : std::vector<numeric_index_type> _csr; 199 : 200 : /** 201 : * The start of each row in the compressed 202 : * row index data structure. 203 : */ 204 : std::vector<std::vector<numeric_index_type>::const_iterator> _row_start; 205 : 206 : /** 207 : * Flag indicating if the matrix has been closed yet. 208 : */ 209 : bool _closed; 210 : 211 : /** 212 : * Make other Laspack datatypes friends 213 : */ 214 : friend class LaspackVector<T>; 215 : friend class LaspackLinearSolver<T>; 216 : }; 217 : 218 : } // namespace libMesh 219 : 220 : #endif // #ifdef LIBMESH_HAVE_LASPACK 221 : #endif // #ifdef LIBMESH_LASPACK_MATRIX_H