LCOV - code coverage report
Current view: top level - include/numerics - sparse_matrix.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 16 38 42.1 %
Date: 2025-08-19 19:27:09 Functions: 16 49 32.7 %
Legend: Lines: hit not hit

          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_SPARSE_MATRIX_H
      21             : #define LIBMESH_SPARSE_MATRIX_H
      22             : 
      23             : 
      24             : // Local includes
      25             : #include "libmesh/libmesh.h"
      26             : #include "libmesh/libmesh_common.h"
      27             : #include "libmesh/reference_counted_object.h"
      28             : #include "libmesh/id_types.h"
      29             : #include "libmesh/parallel_object.h"
      30             : #include "libmesh/enum_parallel_type.h" // PARALLEL
      31             : #include "libmesh/enum_matrix_build_type.h" // AUTOMATIC
      32             : #include "libmesh/enum_solver_package.h"
      33             : 
      34             : // C++ includes
      35             : #include <cstddef>
      36             : #include <iomanip>
      37             : #include <vector>
      38             : #include <memory>
      39             : 
      40             : namespace libMesh
      41             : {
      42             : 
      43             : // forward declarations
      44             : template <typename T> class SparseMatrix;
      45             : template <typename T> class DenseMatrix;
      46             : class DofMap;
      47             : namespace SparsityPattern {
      48             :   class Build;
      49             :   class Graph;
      50             : }
      51             : template <typename T> class NumericVector;
      52             : 
      53             : // This template helper function must be declared before it
      54             : // can be defined below.
      55             : template <typename T>
      56             : std::ostream & operator << (std::ostream & os, const SparseMatrix<T> & m);
      57             : 
      58             : 
      59             : /**
      60             :  * Generic sparse matrix. This class contains pure virtual members
      61             :  * that must be overridden in derived classes.  Using a common base
      62             :  * class allows for uniform access to sparse matrices from various
      63             :  * different solver packages in different formats.
      64             :  *
      65             :  * \author Benjamin S. Kirk
      66             :  * \date 2003
      67             :  */
      68             : template <typename T>
      69             : class SparseMatrix : public ReferenceCountedObject<SparseMatrix<T>>,
      70             :                      public ParallelObject
      71             : {
      72             : public:
      73             :   /**
      74             :    * Constructor; initializes the matrix to be empty, without any
      75             :    * structure, i.e.  the matrix is not usable at all. This
      76             :    * constructor is therefore only useful for matrices which are
      77             :    * members of a class. All other matrices should be created at a
      78             :    * point in the data flow where all necessary information is
      79             :    * available.
      80             :    *
      81             :    * You have to initialize the matrix before usage with
      82             :    * \p init(...).
      83             :    */
      84             :   explicit
      85             :   SparseMatrix (const Parallel::Communicator & comm);
      86             : 
      87             :   /**
      88             :    * This _looks_ like a copy assignment operator, but note that,
      89             :    * unlike normal copy assignment operators, it is pure virtual. This
      90             :    * function should be overridden in derived classes so that they can
      91             :    * be copied correctly via references to the base class. This design
      92             :    * usually isn't a good idea in general, but in this context it
      93             :    * works because we usually don't have a mix of different kinds of
      94             :    * SparseMatrix active in the library at a single time.
      95             :    *
      96             :    * \returns A reference to *this as the base type.
      97             :    */
      98           0 :   virtual SparseMatrix<T> & operator= (const SparseMatrix<T> &)
      99             :   {
     100           0 :     libmesh_not_implemented();
     101             :     return *this;
     102             :   }
     103             : 
     104             :   /**
     105             :    * These 3 special functions can be defaulted for this class, as it
     106             :    * does not manage any memory itself.
     107             :    */
     108             :   SparseMatrix (SparseMatrix &&) = default;
     109         284 :   SparseMatrix (const SparseMatrix &) = default;
     110             :   SparseMatrix & operator= (SparseMatrix &&) = default;
     111             : 
     112             :   /**
     113             :    * While this class doesn't manage any memory, the derived class might and
     114             :    * users may be deleting through a pointer to this base class
     115             :    */
     116        2674 :   virtual ~SparseMatrix() = default;
     117             : 
     118             :   /**
     119             :    * Builds a \p SparseMatrix<T> using the linear solver package specified by
     120             :    * \p solver_package
     121             :    */
     122             :   static std::unique_ptr<SparseMatrix<T>>
     123             :   build(const Parallel::Communicator & comm,
     124             :         const SolverPackage solver_package = libMesh::default_solver_package(),
     125             :         const MatrixBuildType matrix_build_type = MatrixBuildType::AUTOMATIC);
     126             : 
     127             :   virtual SolverPackage solver_package() = 0;
     128             : 
     129             :   /**
     130             :    * \returns \p true if the matrix has been initialized,
     131             :    * \p false otherwise.
     132             :    */
     133     3864184 :   virtual bool initialized() const { return _is_initialized; }
     134             : 
     135             :   /**
     136             :    * Set a pointer to the \p DofMap to use.  If a separate sparsity
     137             :    * pattern is not being used, use the one from the DofMap.
     138             :    *
     139             :    * The lifetime of \p dof_map must exceed the lifetime of \p this.
     140             :    */
     141             :   void attach_dof_map (const DofMap & dof_map);
     142             : 
     143             :   /**
     144             :    * Set a pointer to a sparsity pattern to use.  Useful in cases
     145             :    * where a matrix requires a wider (or for efficiency narrower)
     146             :    * pattern than most matrices in the system, or in cases where no
     147             :    * system sparsity pattern is being calculated by the DofMap.
     148             :    *
     149             :    * The lifetime of \p sp must exceed the lifetime of \p this.
     150             :    */
     151             :   void attach_sparsity_pattern (const SparsityPattern::Build & sp);
     152             : 
     153             :   /**
     154             :    * \returns \p true if this sparse matrix format needs to be fed the
     155             :    * graph of the sparse matrix.
     156             :    *
     157             :    * This is true for \p LaspackMatrix, but not \p PetscMatrixBase subclasses.  In
     158             :    * the case where the full graph is not required, we can efficiently
     159             :    * approximate it to provide a good estimate of the required size of
     160             :    * the sparse matrix.
     161             :    */
     162       39891 :   virtual bool need_full_sparsity_pattern() const
     163       39891 :   { return false; }
     164             : 
     165             :   /**
     166             :    * @returns Whether this matrix needs the sparsity pattern computed by the \p DofMap
     167             :    */
     168       14389 :   virtual bool require_sparsity_pattern() const { return !this->use_hash_table(); }
     169             : 
     170             :   /**
     171             :    * Updates the matrix sparsity pattern. When your \p SparseMatrix<T>
     172             :    * implementation does not need this data, simply do not override
     173             :    * this method.
     174             :    */
     175           0 :   virtual void update_sparsity_pattern (const SparsityPattern::Graph &) {}
     176             : 
     177             :   /**
     178             :    * Initialize SparseMatrix with the specified sizes.
     179             :    *
     180             :    * \param m The global number of rows.
     181             :    * \param n The global number of columns.
     182             :    * \param m_l The local number of rows.
     183             :    * \param n_l The local number of columns.
     184             :    * \param nnz The number of on-diagonal nonzeros per row (defaults to 30).
     185             :    * \param noz The number of off-diagonal nonzeros per row (defaults to 10).
     186             :    * \param blocksize Optional value indicating dense coupled blocks
     187             :    * for systems with multiple variables all of the same type.
     188             :    */
     189             :   virtual void init (const numeric_index_type m,
     190             :                      const numeric_index_type n,
     191             :                      const numeric_index_type m_l,
     192             :                      const numeric_index_type n_l,
     193             :                      const numeric_index_type nnz=30,
     194             :                      const numeric_index_type noz=10,
     195             :                      const numeric_index_type blocksize=1) = 0;
     196             : 
     197             :   /**
     198             :    * Initialize this matrix using the sparsity structure computed by \p dof_map.
     199             :    * @param type The serial/parallel/ghosted type of the matrix
     200             :    */
     201             :   virtual void init (ParallelType type = PARALLEL) = 0;
     202             : 
     203             :   /**
     204             :    * Restores the \p SparseMatrix<T> to a pristine state.
     205             :    */
     206             :   virtual void clear () = 0;
     207             : 
     208             :   /**
     209             :    * Set all entries to 0.
     210             :    */
     211             :   virtual void zero () = 0;
     212             : 
     213             :   /**
     214             :    * \returns A smart pointer to a copy of this matrix with the same
     215             :    * type, size, and partitioning, but with all zero entries.
     216             :    *
     217             :    * \note This must be overridden in the derived classes.
     218             :    */
     219             :   virtual std::unique_ptr<SparseMatrix<T>> zero_clone () const = 0;
     220             : 
     221             :   /**
     222             :    * \returns A smart pointer to a copy of this matrix.
     223             :    *
     224             :    * \note This must be overridden in the derived classes.
     225             :    */
     226             :   virtual std::unique_ptr<SparseMatrix<T>> clone () const = 0;
     227             : 
     228             :   /**
     229             :    * Sets all row entries to 0 then puts \p diag_value in the diagonal entry.
     230             :    */
     231             :   virtual void zero_rows (std::vector<numeric_index_type> & rows, T diag_value = 0.0);
     232             : 
     233             :   /**
     234             :    * Calls the SparseMatrix's internal assembly routines, ensuring
     235             :    * that the values are consistent across processors.
     236             :    */
     237             :   virtual void close () = 0;
     238             : 
     239             :   /**
     240             :    *  For PETSc matrix , this function is similar to close but without shrinking memory.
     241             :    *  This is useful when we want to switch between ADD_VALUES and INSERT_VALUES.
     242             :    *  close should be called before using the matrix.
     243             :    */
     244           0 :   virtual void flush () { close(); }
     245             : 
     246             :   /**
     247             :    * \returns The row-dimension of the matrix.
     248             :    */
     249             :   virtual numeric_index_type m () const = 0;
     250             : 
     251             :   /**
     252             :    * Get the number of rows owned by this process
     253             :    */
     254           8 :   virtual numeric_index_type local_m () const { return row_stop() - row_start(); }
     255             : 
     256             :   /**
     257             :    * Get the number of columns owned by this process
     258             :    */
     259          16 :   virtual numeric_index_type local_n () const { return col_stop() - col_start(); }
     260             : 
     261             :   /**
     262             :    * \returns The column-dimension of the matrix.
     263             :    */
     264             :   virtual numeric_index_type n () const = 0;
     265             : 
     266             :   /**
     267             :    * \returns The index of the first matrix row stored on this
     268             :    * processor.
     269             :    */
     270             :   virtual numeric_index_type row_start () const = 0;
     271             : 
     272             :   /**
     273             :    * \returns The index of the last matrix row (+1) stored on this
     274             :    * processor.
     275             :    */
     276             :   virtual numeric_index_type row_stop () const = 0;
     277             : 
     278             :   /**
     279             :    * \returns The index of the first matrix column owned by this
     280             :    * processor.
     281             :    */
     282             :   virtual numeric_index_type col_start () const = 0;
     283             : 
     284             :   /**
     285             :    * \returns The index of the last matrix column (+1) owned by this
     286             :    * processor.
     287             :    */
     288             :   virtual numeric_index_type col_stop () const = 0;
     289             : 
     290             :   /**
     291             :    * Set the element \p (i,j) to \p value.  Throws an error if the
     292             :    * entry does not exist. Zero values can be "stored" in non-existent
     293             :    * fields.
     294             :    */
     295             :   virtual void set (const numeric_index_type i,
     296             :                     const numeric_index_type j,
     297             :                     const T value) = 0;
     298             : 
     299             :   /**
     300             :    * Add \p value to the element \p (i,j).  Throws an error if the
     301             :    * entry does not exist. Zero values can be "added" to non-existent
     302             :    * entries.
     303             :    */
     304             :   virtual void add (const numeric_index_type i,
     305             :                     const numeric_index_type j,
     306             :                     const T value) = 0;
     307             : 
     308             :   /**
     309             :    * Add the full matrix \p dm to the SparseMatrix.  This is useful
     310             :    * for adding an element matrix at assembly time.
     311             :    */
     312             :   virtual void add_matrix (const DenseMatrix<T> & dm,
     313             :                            const std::vector<numeric_index_type> & rows,
     314             :                            const std::vector<numeric_index_type> & cols) = 0;
     315             : 
     316             :   /**
     317             :    * Same as \p add_matrix, but assumes the row and column maps are the same.
     318             :    * Thus the matrix \p dm must be square.
     319             :    */
     320             :   virtual void add_matrix (const DenseMatrix<T> & dm,
     321             :                            const std::vector<numeric_index_type> & dof_indices) = 0;
     322             : 
     323             :   /**
     324             :    * Add the full matrix \p dm to the SparseMatrix.  This is useful
     325             :    * for adding an element matrix at assembly time.  The matrix is
     326             :    * assumed blocked, and \p brow, \p bcol correspond to the *block*
     327             :    * row and column indices.
     328             :    */
     329             :   virtual void add_block_matrix (const DenseMatrix<T> & dm,
     330             :                                  const std::vector<numeric_index_type> & brows,
     331             :                                  const std::vector<numeric_index_type> & bcols);
     332             : 
     333             :   /**
     334             :    * Same as \p add_block_matrix(), but assumes the row and column
     335             :    * maps are the same.  Thus the matrix \p dm must be square.
     336             :    */
     337           0 :   virtual void add_block_matrix (const DenseMatrix<T> & dm,
     338             :                                  const std::vector<numeric_index_type> & dof_indices)
     339           0 :   { this->add_block_matrix (dm, dof_indices, dof_indices); }
     340             : 
     341             :   /**
     342             :    * Compute \f$ A \leftarrow A + a*X \f$ for scalar \p a, matrix \p X.
     343             :    */
     344             :   virtual void add (const T a, const SparseMatrix<T> & X) = 0;
     345             : 
     346             :   /**
     347             :    * Compute Y = A*X for matrix \p X.
     348             :    */
     349           0 :   virtual void matrix_matrix_mult (SparseMatrix<T> & /*X*/, SparseMatrix<T> & /*Y*/, bool /*reuse*/)
     350           0 :   { libmesh_not_implemented(); }
     351             : 
     352             :   /**
     353             :    * Add \p scalar* \p spm to the rows and cols of this matrix (A):
     354             :    * A(rows[i], cols[j]) += scalar * spm(i,j)
     355             :    */
     356           0 :   virtual void add_sparse_matrix (const SparseMatrix<T> & /*spm*/,
     357             :                                   const std::map<numeric_index_type, numeric_index_type> & /*rows*/,
     358             :                                   const std::map<numeric_index_type, numeric_index_type> & /*cols*/,
     359             :                                   const T /*scalar*/)
     360           0 :   { libmesh_not_implemented(); }
     361             : 
     362             :   /**
     363             :    * \returns A copy of matrix entry \p (i,j).
     364             :    *
     365             :    * \note This may be an expensive operation, and you should always
     366             :    * be careful where you call this function.
     367             :    */
     368             :   virtual T operator () (const numeric_index_type i,
     369             :                          const numeric_index_type j) const = 0;
     370             : 
     371             :   /**
     372             :    * \returns The \f$ \ell_1 \f$-norm of the matrix, that is the max column sum:
     373             :    * \f$ |M|_1 = \max_{j} \sum_{i} |M_{ij}| \f$
     374             :    *
     375             :    * This is the natural matrix norm that is compatible with the
     376             :    * \f$ \ell_1 \f$-norm for vectors, i.e. \f$ |Mv|_1 \leq |M|_1 |v|_1 \f$.
     377             :    * (cf. Haemmerlin-Hoffmann : Numerische Mathematik)
     378             :    */
     379             :   virtual Real l1_norm () const = 0;
     380             : 
     381             :   /**
     382             :    * \returns The \f$ \ell_{\infty} \f$-norm of the matrix, that is the max row sum:
     383             :    *
     384             :    * \f$ |M|_{\infty} = \max_{i} \sum_{j} |M_{ij}| \f$
     385             :    *
     386             :    * This is the natural matrix norm that is compatible to the
     387             :    * \f$ \ell_{\infty} \f$-norm of vectors, i.e.
     388             :    * \f$ |Mv|_{\infty} \leq |M|_{\infty} |v|_{\infty} \f$.
     389             :    * (cf. Haemmerlin-Hoffmann : Numerische Mathematik)
     390             :    */
     391             :   virtual Real linfty_norm () const = 0;
     392             : 
     393             :   /**
     394             :    * \returns The l1_norm() of the difference of \p this and \p other_mat
     395             :    */
     396             :   Real l1_norm_diff (const SparseMatrix<T> & other_mat) const;
     397             : 
     398             :   /**
     399             :    * \returns \p true if the matrix has been assembled.
     400             :    */
     401             :   virtual bool closed() const = 0;
     402             : 
     403             :   /**
     404             :    * \returns the global number of non-zero entries in the matrix
     405             :    * sparsity pattern
     406             :    */
     407             :   virtual std::size_t n_nonzeros() const;
     408             : 
     409             :   /**
     410             :    * Print the contents of the matrix to the screen in a uniform
     411             :    * style, regardless of matrix/solver package being used.
     412             :    */
     413             :   void print(std::ostream & os=libMesh::out, const bool sparse=false) const;
     414             : 
     415             :   /**
     416             :    * Same as the print method above, but allows you to print to a
     417             :    * stream in the standard syntax.
     418             :    *
     419             :    * \code
     420             :    * template <typename U>
     421             :    * friend std::ostream & operator << (std::ostream & os, const SparseMatrix<U> & m);
     422             :    * \endcode
     423             :    *
     424             :    * \note The above syntax, which does not require any
     425             :    * prior declaration of operator<<, declares *any* instantiation of
     426             :    * SparseMatrix<X> is friend to *any* instantiation of
     427             :    * operator<<(ostream &, SparseMatrix<Y> &).  It would not happen in
     428             :    * practice, but in principle it means that SparseMatrix<Complex>
     429             :    * would be friend to operator<<(ostream &, SparseMatrix<Real>).
     430             :    *
     431             :    * \note The form below, which requires a previous
     432             :    * declaration of the operator<<(stream &, SparseMatrix<T> &) function
     433             :    * (see top of this file), means that any instantiation of
     434             :    * SparseMatrix<T> is friend to the specialization
     435             :    * operator<<(ostream &, SparseMatrix<T> &), but e.g. SparseMatrix<U>
     436             :    * is *not* friend to the same function.  So this is slightly
     437             :    * different to the form above...
     438             :    *
     439             :    * This method seems to be the "preferred" technique, see
     440             :    * http://www.parashift.com/c++-faq-lite/template-friends.html
     441             :    */
     442             :   friend std::ostream & operator << <>(std::ostream & os, const SparseMatrix<T> & m);
     443             : 
     444             :   /**
     445             :    * Print the contents of the matrix to the screen in a
     446             :    * package-personalized style, if available.
     447             :    */
     448             :   virtual void print_personal(std::ostream & os=libMesh::out) const = 0;
     449             : 
     450             :   /**
     451             :    * Print the contents of the matrix in Matlab's sparse matrix
     452             :    * format. Optionally prints the matrix to the file named \p name.
     453             :    * If \p name is not specified it is dumped to the screen.
     454             :    */
     455             :   virtual void print_matlab(const std::string & /*name*/ = "") const;
     456             : 
     457             :   /**
     458             :    * Write the contents of the matrix to a file in PETSc's binary
     459             :    * sparse matrix format.
     460             :    */
     461             :   virtual void print_petsc_binary(const std::string & filename);
     462             : 
     463             :   /**
     464             :    * Write the contents of the matrix to a file in PETSc's HDF5
     465             :    * sparse matrix format.
     466             :    */
     467             :   virtual void print_petsc_hdf5(const std::string & filename);
     468             : 
     469             : 
     470             :   /**
     471             :    * Read the contents of the matrix from a file, with the file format
     472             :    * inferred from the extension of \p filename.
     473             :    */
     474             :   virtual void read(const std::string & filename);
     475             : 
     476             :   /**
     477             :    * Read the contents of the matrix from the Matlab-script sparse
     478             :    * matrix format used by PETSc.
     479             :    *
     480             :    * If the size and sparsity of the matrix in \p filename appears
     481             :    * consistent with the existing sparsity of \p this then the
     482             :    * existing parallel decomposition and sparsity will be retained.
     483             :    * If not, then \p this will be initialized with the sparsity from
     484             :    * the file, linearly partitioned onto the number of processors
     485             :    * available.
     486             :    */
     487             :   virtual void read_matlab(const std::string & filename);
     488             : 
     489             :   /**
     490             :    * Read the contents of the matrix from a file in PETSc's binary
     491             :    * sparse matrix format.
     492             :    */
     493             :   virtual void read_petsc_binary(const std::string & filename);
     494             : 
     495             :   /**
     496             :    * Read the contents of the matrix from a file in PETSc's HDF5
     497             :    * sparse matrix format.
     498             :    */
     499             :   virtual void read_petsc_hdf5(const std::string & filename);
     500             : 
     501             :   /**
     502             :    * This function creates a matrix called "submatrix" which is defined
     503             :    * by the row and column indices given in the "rows" and "cols" entries.
     504             :    * Currently this operation is only defined for the PetscMatrixBase subclasses.
     505             :    * Note: The \p rows and \p cols vectors need to be sorted;
     506             :    *       Use the nosort version below if \p rows and \p cols vectors are not sorted;
     507             :    *       The \p rows and \p cols only contain indices that are owned by this processor.
     508             :    */
     509         594 :   virtual void create_submatrix(SparseMatrix<T> & submatrix,
     510             :                                 const std::vector<numeric_index_type> & rows,
     511             :                                 const std::vector<numeric_index_type> & cols) const
     512             :   {
     513         594 :     this->_get_submatrix(submatrix,
     514             :                          rows,
     515             :                          cols,
     516             :                          false); // false means DO NOT REUSE submatrix
     517         594 :   }
     518             : 
     519             :   /**
     520             :    * Similar to the above function, this function creates a \p
     521             :    * submatrix which is defined by the indices given in the \p rows
     522             :    * and \p cols vectors.
     523             :    * Note: Both \p rows and \p cols can be unsorted;
     524             :    *       Use the above function for better efficiency if your indices are sorted;
     525             :    *       \p rows and \p cols can contain indices that are owned by other processors.
     526             :    */
     527           0 :   virtual void create_submatrix_nosort(SparseMatrix<T> & /*submatrix*/,
     528             :                                          const std::vector<numeric_index_type> & /*rows*/,
     529             :                                          const std::vector<numeric_index_type> & /*cols*/) const
     530             :   {
     531           0 :     libmesh_not_implemented();
     532             :   }
     533             : 
     534             :   /**
     535             :    * This function is similar to the one above, but it allows you to reuse
     536             :    * the existing sparsity pattern of "submatrix" instead of reallocating
     537             :    * it again.  This should hopefully be more efficient if you are frequently
     538             :    * extracting submatrices of the same size.
     539             :    */
     540           0 :   virtual void reinit_submatrix(SparseMatrix<T> & submatrix,
     541             :                                 const std::vector<numeric_index_type> & rows,
     542             :                                 const std::vector<numeric_index_type> & cols) const
     543             :   {
     544           0 :     this->_get_submatrix(submatrix,
     545             :                          rows,
     546             :                          cols,
     547             :                          true); // true means REUSE submatrix
     548           0 :   }
     549             : 
     550             :   /**
     551             :    * Multiplies the matrix by the NumericVector \p arg and stores the
     552             :    * result in NumericVector \p dest.
     553             :    */
     554             :   void vector_mult (NumericVector<T> & dest,
     555             :                     const NumericVector<T> & arg) const;
     556             : 
     557             :   /**
     558             :    * Multiplies the matrix by the NumericVector \p arg and adds the
     559             :    * result to the NumericVector \p dest.
     560             :    */
     561             :   void vector_mult_add (NumericVector<T> & dest,
     562             :                         const NumericVector<T> & arg) const;
     563             : 
     564             :   /**
     565             :    * Copies the diagonal part of the matrix into \p dest.
     566             :    */
     567             :   virtual void get_diagonal (NumericVector<T> & dest) const = 0;
     568             : 
     569             :   /**
     570             :    * Copies the transpose of the matrix into \p dest, which may be
     571             :    * *this.
     572             :    */
     573             :   virtual void get_transpose (SparseMatrix<T> & dest) const = 0;
     574             : 
     575             :   /**
     576             :    * Get a row from the matrix
     577             :    * @param i The matrix row to get
     578             :    * @param indices A container that will be filled with the column indices
     579             :    *                corresponding to (possibly) non-zero values
     580             :    * @param values A container holding the column values
     581             :    */
     582             :   virtual void get_row(numeric_index_type i,
     583             :                        std::vector<numeric_index_type> & indices,
     584             :                        std::vector<T> & values) const = 0;
     585             : 
     586             :   /**
     587             :    * Scales all elements of this matrix by \p scale
     588             :    */
     589             :   virtual void scale(const T scale);
     590             : 
     591             :   /**
     592             :    * @returns Whether the matrix supports hash table assembly
     593             :    */
     594           0 :   virtual bool supports_hash_table() const { return false; }
     595             : 
     596             :   /**
     597             :    * Sets whether to use hash table assembly. This will error if the passed-in value is true and the
     598             :    * matrix type does not support hash tables. Hash table or hash map assembly means storing maps
     599             :    * from i-j locations in the matrix to values. Because it is a hash map as opposed to a contiguous
     600             :    * array of data, no preallocation is required to use it
     601             :    */
     602             :   void use_hash_table(bool use_hash);
     603             : 
     604             :   /**
     605             :    * @returns Whether this matrix is using hash table assembly. Hash table or hash map assembly
     606             :    * means storing maps from i-j locations in the matrix to values. Because it is a hash map as
     607             :    * opposed to a contiguous array of data, no preallocation is required to use it
     608             :    */
     609       32097 :   bool use_hash_table() const { return _use_hash_table; }
     610             : 
     611             :   /**
     612             :    * Reset the memory storage of the matrix. Unlike \p clear(), this does not destroy the matrix but
     613             :    * rather will reset the matrix to use the original preallocation or when using hash table matrix
     614             :    * assembly (see \p use_hash_table()) will reset (clear) the hash table used for assembly. In the
     615             :    * words of the \p MatResetPreallocation documentation in PETSc, 'current values in the matrix are
     616             :    * lost in this call', so a user can expect to have back their original sparsity pattern in a
     617             :    * zeroed state
     618             :    */
     619           0 :   virtual void restore_original_nonzero_pattern() { libmesh_not_implemented(); }
     620             : 
     621             : protected:
     622             :   /**
     623             :    * Protected implementation of the create_submatrix and reinit_submatrix
     624             :    * routines.
     625             :    *
     626             :    * \note This function must be overridden in derived classes for it
     627             :    * to work properly!
     628             :    */
     629           0 :   virtual void _get_submatrix(SparseMatrix<T> & /*submatrix*/,
     630             :                               const std::vector<numeric_index_type> & /*rows*/,
     631             :                               const std::vector<numeric_index_type> & /*cols*/,
     632             :                               const bool /*reuse_submatrix*/) const
     633             :   {
     634           0 :     libmesh_not_implemented();
     635             :   }
     636             : 
     637             :   /**
     638             :    * The \p DofMap object associated with this object.  May be queried
     639             :    * for degree-of-freedom counts on processors.
     640             :    */
     641             :   DofMap const * _dof_map;
     642             : 
     643             :   /**
     644             :    * The \p sparsity pattern associated with this object.  Should be
     645             :    * queried for entry counts (or with need_full_sparsity_pattern,
     646             :    * patterns) when needed.
     647             :    */
     648             :   SparsityPattern::Build const * _sp;
     649             : 
     650             :   /**
     651             :    * Flag indicating whether or not the matrix has been initialized.
     652             :    */
     653             :   bool _is_initialized;
     654             : 
     655             :   /**
     656             :    * Flag indicating whether the matrix is assembled using a hash table
     657             :    */
     658             :   bool _use_hash_table;
     659             : };
     660             : 
     661             : 
     662             : 
     663             : //-----------------------------------------------------------------------
     664             : // SparseMatrix inline members
     665             : template <typename T>
     666             : void
     667       18877 : SparseMatrix<T>::use_hash_table(const bool use_hash)
     668             : {
     669       18877 :   libmesh_error_msg_if(use_hash && !this->supports_hash_table(),
     670             :                        "This matrix class does not support hash table assembly");
     671       18877 :   this->_use_hash_table = use_hash;
     672       18877 : }
     673             : 
     674             : // For SGI MIPSpro this implementation must occur after
     675             : // the full specialization of the print() member.
     676             : //
     677             : // It's generally easier to define these friend functions in the header
     678             : // file.
     679             : template <typename T>
     680           0 : std::ostream & operator << (std::ostream & os, const SparseMatrix<T> & m)
     681             : {
     682           0 :   m.print(os);
     683           0 :   return os;
     684             : }
     685             : 
     686             : template <typename T>
     687             : auto
     688             : l1_norm(const SparseMatrix<T> & mat)
     689             : {
     690             :   return mat.l1_norm();
     691             : }
     692             : 
     693             : template <typename T>
     694             : auto
     695             : l1_norm_diff(const SparseMatrix<T> & mat1, const SparseMatrix<T> & mat2)
     696             : {
     697             :   return mat1.l1_norm_diff(mat2);
     698             : }
     699             : 
     700             : } // namespace libMesh
     701             : 
     702             : 
     703             : #endif // LIBMESH_SPARSE_MATRIX_H

Generated by: LCOV version 1.14