libMesh
sparse_matrix.h
Go to the documentation of this file.
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 
68 template <typename T>
69 class SparseMatrix : public ReferenceCountedObject<SparseMatrix<T>>,
70  public ParallelObject
71 {
72 public:
84  explicit
85  SparseMatrix (const Parallel::Communicator & comm);
86 
99  {
100  libmesh_not_implemented();
101  return *this;
102  }
103 
108  SparseMatrix (SparseMatrix &&) = default;
109  SparseMatrix (const SparseMatrix &) = default;
110  SparseMatrix & operator= (SparseMatrix &&) = default;
111 
116  virtual ~SparseMatrix() = default;
117 
122  static std::unique_ptr<SparseMatrix<T>>
125  const MatrixBuildType matrix_build_type = MatrixBuildType::AUTOMATIC);
126 
127  virtual SolverPackage solver_package() = 0;
128 
133  virtual bool initialized() const { return _is_initialized; }
134 
141  void attach_dof_map (const DofMap & dof_map);
142 
152 
162  virtual bool need_full_sparsity_pattern() const
163  { return false; }
164 
168  virtual bool require_sparsity_pattern() const { return !this->use_hash_table(); }
169 
176 
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 
201  virtual void init (ParallelType type = PARALLEL) = 0;
202 
206  virtual void clear () = 0;
207 
211  virtual void zero () = 0;
212 
219  virtual std::unique_ptr<SparseMatrix<T>> zero_clone () const = 0;
220 
226  virtual std::unique_ptr<SparseMatrix<T>> clone () const = 0;
227 
231  virtual void zero_rows (std::vector<numeric_index_type> & rows, T diag_value = 0.0);
232 
237  virtual void close () = 0;
238 
244  virtual void flush () { close(); }
245 
249  virtual numeric_index_type m () const = 0;
250 
254  virtual numeric_index_type local_m () const { return row_stop() - row_start(); }
255 
259  virtual numeric_index_type local_n () const { return col_stop() - col_start(); }
260 
264  virtual numeric_index_type n () const = 0;
265 
270  virtual numeric_index_type row_start () const = 0;
271 
276  virtual numeric_index_type row_stop () const = 0;
277 
282  virtual numeric_index_type col_start () const = 0;
283 
288  virtual numeric_index_type col_stop () const = 0;
289 
295  virtual void set (const numeric_index_type i,
296  const numeric_index_type j,
297  const T value) = 0;
298 
304  virtual void add (const numeric_index_type i,
305  const numeric_index_type j,
306  const T value) = 0;
307 
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 
320  virtual void add_matrix (const DenseMatrix<T> & dm,
321  const std::vector<numeric_index_type> & dof_indices) = 0;
322 
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 
337  virtual void add_block_matrix (const DenseMatrix<T> & dm,
338  const std::vector<numeric_index_type> & dof_indices)
339  { this->add_block_matrix (dm, dof_indices, dof_indices); }
340 
344  virtual void add (const T a, const SparseMatrix<T> & X) = 0;
345 
349  virtual void matrix_matrix_mult (SparseMatrix<T> & /*X*/, SparseMatrix<T> & /*Y*/, bool /*reuse*/)
350  { libmesh_not_implemented(); }
351 
356  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  { libmesh_not_implemented(); }
361 
368  virtual T operator () (const numeric_index_type i,
369  const numeric_index_type j) const = 0;
370 
379  virtual Real l1_norm () const = 0;
380 
391  virtual Real linfty_norm () const = 0;
392 
396  Real l1_norm_diff (const SparseMatrix<T> & other_mat) const;
397 
401  virtual bool closed() const = 0;
402 
407  virtual std::size_t n_nonzeros() const;
408 
413  void print(std::ostream & os=libMesh::out, const bool sparse=false) const;
414 
442  friend std::ostream & operator << <>(std::ostream & os, const SparseMatrix<T> & m);
443 
448  virtual void print_personal(std::ostream & os=libMesh::out) const = 0;
449 
455  virtual void print_matlab(const std::string & /*name*/ = "") const;
456 
461  virtual void print_petsc_binary(const std::string & filename);
462 
467  virtual void print_petsc_hdf5(const std::string & filename);
468 
469 
474  virtual void read(const std::string & filename);
475 
487  virtual void read_matlab(const std::string & filename);
488 
493  virtual void read_petsc_binary(const std::string & filename);
494 
499  virtual void read_petsc_hdf5(const std::string & filename);
500 
509  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  this->_get_submatrix(submatrix,
514  rows,
515  cols,
516  false); // false means DO NOT REUSE submatrix
517  }
518 
527  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  libmesh_not_implemented();
532  }
533 
540  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  this->_get_submatrix(submatrix,
545  rows,
546  cols,
547  true); // true means REUSE submatrix
548  }
549 
554  void vector_mult (NumericVector<T> & dest,
555  const NumericVector<T> & arg) const;
556 
561  void vector_mult_add (NumericVector<T> & dest,
562  const NumericVector<T> & arg) const;
563 
567  virtual void get_diagonal (NumericVector<T> & dest) const = 0;
568 
573  virtual void get_transpose (SparseMatrix<T> & dest) const = 0;
574 
582  virtual void get_row(numeric_index_type i,
583  std::vector<numeric_index_type> & indices,
584  std::vector<T> & values) const = 0;
585 
589  virtual void scale(const T scale);
590 
594  virtual bool supports_hash_table() const { return false; }
595 
602  void use_hash_table(bool use_hash);
603 
609  bool use_hash_table() const { return _use_hash_table; }
610 
619  virtual void restore_original_nonzero_pattern() { libmesh_not_implemented(); }
620 
621 protected:
629  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  libmesh_not_implemented();
635  }
636 
641  DofMap const * _dof_map;
642 
649 
654 
659 };
660 
661 
662 
663 //-----------------------------------------------------------------------
664 // SparseMatrix inline members
665 template <typename T>
666 void
668 {
669  libmesh_error_msg_if(use_hash && !this->supports_hash_table(),
670  "This matrix class does not support hash table assembly");
671  this->_use_hash_table = use_hash;
672 }
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 std::ostream & operator << (std::ostream & os, const SparseMatrix<T> & m)
681 {
682  m.print(os);
683  return os;
684 }
685 
686 template <typename T>
687 auto
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
virtual void add_block_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &brows, const std::vector< numeric_index_type > &bcols)
Add the full matrix dm to the SparseMatrix.
Definition: sparse_matrix.C:91
virtual bool initialized() const
virtual void restore_original_nonzero_pattern()
Reset the memory storage of the matrix.
virtual void create_submatrix(SparseMatrix< T > &submatrix, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols) const
This function creates a matrix called "submatrix" which is defined by the row and column indices give...
virtual std::size_t n_nonzeros() const
virtual void print_petsc_binary(const std::string &filename)
Write the contents of the matrix to a file in PETSc&#39;s binary sparse matrix format.
virtual void print_personal(std::ostream &os=libMesh::out) const =0
Print the contents of the matrix to the screen in a package-personalized style, if available...
virtual void read_petsc_hdf5(const std::string &filename)
Read the contents of the matrix from a file in PETSc&#39;s HDF5 sparse matrix format. ...
SparseMatrix(const Parallel::Communicator &comm)
Constructor; initializes the matrix to be empty, without any structure, i.e.
Definition: sparse_matrix.C:61
This helper class can be called on multiple threads to compute the sparsity pattern (or graph) of the...
void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const
Multiplies the matrix by the NumericVector arg and stores the result in NumericVector dest...
virtual ~SparseMatrix()=default
While this class doesn&#39;t manage any memory, the derived class might and users may be deleting through...
virtual numeric_index_type local_m() const
Get the number of rows owned by this process.
SparsityPattern::Build const * _sp
The sparsity pattern associated with this object.
bool use_hash_table() const
void attach_sparsity_pattern(const SparsityPattern::Build &sp)
Set a pointer to a sparsity pattern to use.
Definition: sparse_matrix.C:82
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
Definition: vector_fe_ex5.C:44
const Parallel::Communicator & comm() const
virtual void matrix_matrix_mult(SparseMatrix< T > &, SparseMatrix< T > &, bool)
Compute Y = A*X for matrix X.
The libMesh namespace provides an interface to certain functionality in the library.
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package(), const MatrixBuildType matrix_build_type=MatrixBuildType::AUTOMATIC)
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
virtual numeric_index_type local_n() const
Get the number of columns owned by this process.
virtual numeric_index_type row_stop() const =0
virtual void clear()=0
Restores the SparseMatrix<T> to a pristine state.
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value)=0
Add value to the element (i,j).
virtual void add_sparse_matrix(const SparseMatrix< T > &, const std::map< numeric_index_type, numeric_index_type > &, const std::map< numeric_index_type, numeric_index_type > &, const T)
Add scalar* spm to the rows and cols of this matrix (A): A(rows[i], cols[j]) += scalar * spm(i...
Generic sparse matrix.
Definition: vector_fe_ex5.C:46
SolverPackage default_solver_package()
Definition: libmesh.C:1117
virtual void read_matlab(const std::string &filename)
Read the contents of the matrix from the Matlab-script sparse matrix format used by PETSc...
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:179
virtual void flush()
For PETSc matrix , this function is similar to close but without shrinking memory.
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
virtual SolverPackage solver_package()=0
virtual void zero()=0
Set all entries to 0.
auto l1_norm(const NumericVector< T > &vec)
dof_id_type numeric_index_type
Definition: id_types.h:99
virtual SparseMatrix< T > & operator=(const SparseMatrix< T > &)
This looks like a copy assignment operator, but note that, unlike normal copy assignment operators...
Definition: sparse_matrix.h:98
bool _is_initialized
Flag indicating whether or not the matrix has been initialized.
auto l1_norm_diff(const NumericVector< T > &vec1, const NumericVector< T > &vec2)
virtual std::unique_ptr< SparseMatrix< T > > zero_clone() const =0
virtual numeric_index_type m() const =0
virtual void read_petsc_binary(const std::string &filename)
Read the contents of the matrix from a file in PETSc&#39;s binary sparse matrix format.
virtual void zero_rows(std::vector< numeric_index_type > &rows, T diag_value=0.0)
Sets all row entries to 0 then puts diag_value in the diagonal entry.
virtual numeric_index_type col_stop() const =0
virtual void get_diagonal(NumericVector< T > &dest) const =0
Copies the diagonal part of the matrix into dest.
virtual numeric_index_type col_start() const =0
virtual void read(const std::string &filename)
Read the contents of the matrix from a file, with the file format inferred from the extension of file...
virtual void reinit_submatrix(SparseMatrix< T > &submatrix, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols) const
This function is similar to the one above, but it allows you to reuse the existing sparsity pattern o...
virtual void create_submatrix_nosort(SparseMatrix< T > &, const std::vector< numeric_index_type > &, const std::vector< numeric_index_type > &) const
Similar to the above function, this function creates a submatrix which is defined by the indices give...
Real l1_norm_diff(const SparseMatrix< T > &other_mat) const
virtual bool closed() const =0
void attach_dof_map(const DofMap &dof_map)
Set a pointer to the DofMap to use.
Definition: sparse_matrix.C:72
DofMap const * _dof_map
The DofMap object associated with this object.
virtual void get_row(numeric_index_type i, std::vector< numeric_index_type > &indices, std::vector< T > &values) const =0
Get a row from the matrix.
virtual bool need_full_sparsity_pattern() const
virtual void close()=0
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
virtual void update_sparsity_pattern(const SparsityPattern::Graph &)
Updates the matrix sparsity pattern.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const
Multiplies the matrix by the NumericVector arg and adds the result to the NumericVector dest...
virtual numeric_index_type row_start() const =0
OStreamProxy out
virtual void print_matlab(const std::string &="") const
Print the contents of the matrix in Matlab&#39;s sparse matrix format.
virtual void get_transpose(SparseMatrix< T > &dest) const =0
Copies the transpose of the matrix into dest, which may be *this.
static const bool value
Definition: xdr_io.C:54
virtual void _get_submatrix(SparseMatrix< T > &, const std::vector< numeric_index_type > &, const std::vector< numeric_index_type > &, const bool) const
Protected implementation of the create_submatrix and reinit_submatrix routines.
virtual void scale(const T scale)
Scales all elements of this matrix by scale.
bool _use_hash_table
Flag indicating whether the matrix is assembled using a hash table.
virtual Real linfty_norm() const =0
virtual bool supports_hash_table() const
SolverPackage
Defines an enum for various linear solver packages.
virtual Real l1_norm() const =0
MatrixBuildType
Defines an enum for matrix build types.
virtual std::unique_ptr< SparseMatrix< T > > clone() const =0
Defines a dense matrix for use in Finite Element-type computations.
Definition: dof_map.h:75
virtual T operator()(const numeric_index_type i, const numeric_index_type j) const =0
virtual bool require_sparsity_pattern() const
void print(std::ostream &os=libMesh::out, const bool sparse=false) const
Print the contents of the matrix to the screen in a uniform style, regardless of matrix/solver packag...
virtual numeric_index_type n() const =0
virtual void add_block_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &dof_indices)
Same as add_block_matrix(), but assumes the row and column maps are the same.
virtual void print_petsc_hdf5(const std::string &filename)
Write the contents of the matrix to a file in PETSc&#39;s HDF5 sparse matrix format.
virtual void init(const numeric_index_type m, const numeric_index_type n, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz=30, const numeric_index_type noz=10, const numeric_index_type blocksize=1)=0
Initialize SparseMatrix with the specified sizes.
ParallelType
Defines an enum for parallel data structure types.