MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
sparsemat.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_SPARSEMAT_HPP
13#define MFEM_SPARSEMAT_HPP
14
15// Data types for sparse matrix
16
20#include "../general/device.hpp"
21#include "../general/table.hpp"
23#include "densemat.hpp"
24
25#if defined(MFEM_USE_HIP)
26#if (HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR) < 502
27#include <hipsparse.h>
28#else
29#include <hipsparse/hipsparse.h>
30#endif
31#endif
32
33
34namespace mfem
35{
36
37class
38#if defined(__alignas_is_defined)
39 alignas(real_t)
40#endif
42{
43public:
46 int Column;
47};
48
49/// Data type sparse matrix
51{
52protected:
53 /// @name Arrays used by the CSR storage format.
54 /** */
55 ///@{
56 /// @brief %Array with size (#height+1) containing the row offsets.
57 /** The data for row r, 0 <= r < height, is at offsets j, I[r] <= j < I[r+1].
58 The offsets, j, are indices in the #J and #A arrays. The first entry in
59 this array is always zero, I[0] = 0, and the last entry, I[height], gives
60 the total number of entries stored (at a minimum, all nonzeros must be
61 represented) in the sparse matrix. */
63 /** @brief %Array with size #I[#height], containing the column indices for
64 all matrix entries, as indexed by the #I array. */
66 /** @brief %Array with size #I[#height], containing the actual entries of the
67 sparse matrix, as indexed by the #I array. */
69 ///@}
70
71 /** @brief %Array of linked lists, one for every row. This array represents
72 the linked list (LIL) storage format. */
74
75 mutable int current_row;
76 mutable int* ColPtrJ;
77 mutable RowNode ** ColPtrNode;
78
79 /// Transpose of A. Owned. Used to perform MultTranspose() on devices.
80 mutable SparseMatrix *At;
81
82#ifdef MFEM_USE_MEMALLOC
83 typedef MemAlloc <RowNode, 1024> RowNodeAlloc;
85#endif
86
87 /// Are the columns sorted already.
89
90 void Destroy(); // Delete all owned data
91 void SetEmpty(); // Init all entries with empty values
92
93 bool useGPUSparse = true; // Use cuSPARSE or hipSPARSE if available
94
95 // Initialize cuSPARSE/hipSPARSE
96 void InitGPUSparse();
97
98#ifdef MFEM_USE_CUDA_OR_HIP
99 // common for hipSPARSE and cuSPARSE
101 mutable bool initBuffers = false;
102
103#if defined(MFEM_USE_CUDA) && CUDA_VERSION >= 12300 && CUDA_VERSION < 12602
104 // Workaround for bug CUSPARSE-1897
105#define MFEM_CUDA_1897_WORKAROUND
106 mutable size_t bufferSize = 0;
107 mutable void *dBuffer = nullptr;
108#else
109 static size_t bufferSize;
110 static void *dBuffer;
111#endif
112
113#if defined(MFEM_USE_CUDA)
114 cusparseStatus_t status;
115 static cusparseHandle_t handle;
116 cusparseMatDescr_t descr = 0;
117
118#if CUDA_VERSION >= 10010
119 mutable cusparseSpMatDescr_t matA_descr;
120 mutable cusparseDnVecDescr_t vecX_descr;
121 mutable cusparseDnVecDescr_t vecY_descr;
122#else // CUDA_VERSION >= 10010
123 mutable cusparseMatDescr_t matA_descr;
124#endif // CUDA_VERSION >= 10010
125
126#else // defined(MFEM_USE_CUDA)
127 hipsparseStatus_t status;
128 static hipsparseHandle_t handle;
129 hipsparseMatDescr_t descr = 0;
130
131 mutable hipsparseSpMatDescr_t matA_descr;
132 mutable hipsparseDnVecDescr_t vecX_descr;
133 mutable hipsparseDnVecDescr_t vecY_descr;
134#endif // defined(MFEM_USE_CUDA)
135#endif // MFEM_USE_CUDA_OR_HIP
136
137public:
138 /// Create an empty SparseMatrix.
140 {
141 SetEmpty();
142
144 }
145
146 /** @brief Create a sparse matrix with flexible sparsity structure using a
147 row-wise linked list (LIL) format. */
148 /** New entries are added as needed by methods like AddSubMatrix(),
149 SetSubMatrix(), etc. Calling Finalize() will convert the SparseMatrix to
150 the more compact compressed sparse row (CSR) format. */
151 explicit SparseMatrix(int nrows, int ncols = -1);
152
153 /** @brief Create a sparse matrix in CSR format. Ownership of @a i, @a j, and
154 @a data is transferred to the SparseMatrix. */
155 SparseMatrix(int *i, int *j, real_t *data, int m, int n);
156
157 /** @brief Create a sparse matrix in CSR format. Ownership of @a i, @a j, and
158 @a data is optionally transferred to the SparseMatrix. */
159 /** If the parameter @a data is NULL, then the internal #A array is allocated
160 by this constructor (initializing it with zeros and taking ownership,
161 regardless of the parameter @a owna). */
162 SparseMatrix(int *i, int *j, real_t *data, int m, int n, bool ownij,
163 bool owna, bool issorted);
164
165 /** @brief Create a sparse matrix in CSR format where each row has space
166 allocated for exactly @a rowsize entries. */
167 /** SetRow() can then be called or the #I, #J, #A arrays can be used
168 directly. */
169 SparseMatrix(int nrows, int ncols, int rowsize);
170
171 /// Copy constructor (deep copy).
172 /** If @a mat is finalized and @a copy_graph is false, the #I and #J arrays
173 will use a shallow copy (copy the pointers only) without transferring
174 ownership.
175 If @a mt is MemoryType::PRESERVE the memory type of the resulting
176 SparseMatrix's #I, #J, and #A arrays will be the same as @a mat,
177 otherwise the type will be @a mt for those arrays that are deep
178 copied. */
179 SparseMatrix(const SparseMatrix &mat, bool copy_graph = true,
181
182 /// Create a SparseMatrix with diagonal @a v, i.e. A = Diag(v)
183 SparseMatrix(const Vector & v);
184
185 /// @brief Sets the height and width of the matrix.
186 /** @warning This does not modify in any way the underlying CSR or LIL
187 representation of the matrix.
188
189 This function should generally be called when manually constructing the
190 CSR #I, #J, and #A arrays in conjunction with the
191 SparseMatrix::SparseMatrix() constructor. */
192 void OverrideSize(int height_, int width_);
193
194 /** @brief Runtime option to use cuSPARSE or hipSPARSE. Only valid when using
195 a CUDA or HIP backend.
196
197 @note This option is enabled by default, so typically one would use this
198 method to disable the use of cuSPARSE/hipSPARSE. */
199 void UseGPUSparse(bool useGPUSparse_ = true) { useGPUSparse = useGPUSparse_;}
200 /// Deprecated equivalent of UseGPUSparse().
201 MFEM_DEPRECATED
202 void UseCuSparse(bool useCuSparse_ = true) { UseGPUSparse(useCuSparse_); }
203
204 /// Assignment operator: deep copy
206
207 /** @brief Clear the contents of the SparseMatrix and make it a reference to
208 @a master */
209 /** After this call, the matrix will point to the same data as @a master but
210 it will not own its data. The @a master must be finalized. */
211 void MakeRef(const SparseMatrix &master);
212
213 /// For backward compatibility, define Size() to be synonym of Height().
214 int Size() const { return Height(); }
215
216 /// Clear the contents of the SparseMatrix.
217 void Clear() { Destroy(); SetEmpty(); }
218
219 /** @brief Clear the cuSPARSE/hipSPARSE descriptors.
220 This must be called after releasing the device memory of A. */
221 void ClearGPUSparse();
222 /// Deprecated equivalent of ClearGPUSparse().
223 MFEM_DEPRECATED
225
226 /// Check if the SparseMatrix is empty.
227 bool Empty() const { return A.Empty() && (Rows == NULL); }
228
229 /// Return the array #I.
230 inline int *GetI() { return I; }
231 /// Return the array #I, const version.
232 inline const int *GetI() const { return I; }
233
234 /// Return the array #J.
235 inline int *GetJ() { return J; }
236 /// Return the array #J, const version.
237 inline const int *GetJ() const { return J; }
238
239 /// Return the element data, i.e. the array #A.
240 inline real_t *GetData() { return A; }
241 /// Return the element data, i.e. the array #A, const version.
242 inline const real_t *GetData() const { return A; }
243
244 // Memory access methods for the #I array.
245 Memory<int> &GetMemoryI() { return I; }
246 const Memory<int> &GetMemoryI() const { return I; }
247 const int *ReadI(bool on_dev = true) const
248 { return mfem::Read(I, Height()+1, on_dev); }
249 int *WriteI(bool on_dev = true)
250 { return mfem::Write(I, Height()+1, on_dev); }
251 int *ReadWriteI(bool on_dev = true)
252 { return mfem::ReadWrite(I, Height()+1, on_dev); }
253 const int *HostReadI() const
254 { return mfem::Read(I, Height()+1, false); }
256 { return mfem::Write(I, Height()+1, false); }
258 { return mfem::ReadWrite(I, Height()+1, false); }
259
260 // Memory access methods for the #J array.
261 Memory<int> &GetMemoryJ() { return J; }
262 const Memory<int> &GetMemoryJ() const { return J; }
263 const int *ReadJ(bool on_dev = true) const
264 { return mfem::Read(J, J.Capacity(), on_dev); }
265 int *WriteJ(bool on_dev = true)
266 { return mfem::Write(J, J.Capacity(), on_dev); }
267 int *ReadWriteJ(bool on_dev = true)
268 { return mfem::ReadWrite(J, J.Capacity(), on_dev); }
269 const int *HostReadJ() const
270 { return mfem::Read(J, J.Capacity(), false); }
272 { return mfem::Write(J, J.Capacity(), false); }
274 { return mfem::ReadWrite(J, J.Capacity(), false); }
275
276 // Memory access methods for the #A array.
278 const Memory<real_t> &GetMemoryData() const { return A; }
279 const real_t *ReadData(bool on_dev = true) const
280 { return mfem::Read(A, A.Capacity(), on_dev); }
281 real_t *WriteData(bool on_dev = true)
282 { return mfem::Write(A, A.Capacity(), on_dev); }
283 real_t *ReadWriteData(bool on_dev = true)
284 { return mfem::ReadWrite(A, A.Capacity(), on_dev); }
285 const real_t *HostReadData() const
286 { return mfem::Read(A, A.Capacity(), false); }
288 { return mfem::Write(A, A.Capacity(), false); }
290 { return mfem::ReadWrite(A, A.Capacity(), false); }
291
292 /// Returns the number of elements in row @a i.
293 int RowSize(const int i) const;
294
295 /// Returns the maximum number of elements among all rows.
296 int MaxRowSize() const;
297
298 /// Return a pointer to the column indices in a row.
299 int *GetRowColumns(const int row);
300 /// Return a pointer to the column indices in a row, const version.
301 const int *GetRowColumns(const int row) const;
302
303 /// Return a pointer to the entries in a row.
304 real_t *GetRowEntries(const int row);
305 /// Return a pointer to the entries in a row, const version.
306 const real_t *GetRowEntries(const int row) const;
307
308 /// Change the width of a SparseMatrix.
309 /*!
310 * If width_ = -1 (DEFAULT), this routine will set the new width
311 * to the actual Width of the matrix awidth = max(J) + 1.
312 * Values 0 <= width_ < awidth are not allowed (error check in Debug Mode only)
313 *
314 * This method can be called for matrices finalized or not.
315 */
316 void SetWidth(int width_ = -1);
317
318 /// Returns the actual Width of the matrix.
319 /*! This method can be called for matrices finalized or not. */
320 int ActualWidth() const;
321
322 /// Sort the column indices corresponding to each row.
323 void SortColumnIndices();
324
325 /** @brief Move the diagonal entry to the first position in each row,
326 preserving the order of the rest of the columns. */
327 void MoveDiagonalFirst();
328
329 /// Returns reference to a_{ij}.
330 real_t &Elem(int i, int j) override;
331
332 /// Returns constant reference to a_{ij}.
333 const real_t &Elem(int i, int j) const override;
334
335 /// Returns reference to A[i][j].
336 real_t &operator()(int i, int j);
337
338 /// Returns reference to A[i][j].
339 const real_t &operator()(int i, int j) const;
340
341 /// Returns the Diagonal of A
342 void GetDiag(Vector & d) const;
343
344 /// Produces a DenseMatrix from a SparseMatrix
345 DenseMatrix *ToDenseMatrix() const;
346
347 /// Produces a DenseMatrix from a SparseMatrix
348 void ToDenseMatrix(DenseMatrix & B) const;
349
355
356 /// Matrix vector multiplication.
357 void Mult(const Vector &x, Vector &y) const override;
358
359 /// y += A * x (default) or y += a * A * x
360 void AddMult(const Vector &x, Vector &y,
361 const real_t a = 1.0) const override;
362
363 /// Multiply a vector with the transposed matrix. y = At * x
364 /** If the matrix is modified, call ResetTranspose() and optionally
365 EnsureMultTranspose() to make sure this method uses the correct updated
366 transpose. */
367 void MultTranspose(const Vector &x, Vector &y) const override;
368
369 /// y += At * x (default) or y += a * At * x
370 /** If the matrix is modified, call ResetTranspose() and optionally
371 EnsureMultTranspose() to make sure this method uses the correct updated
372 transpose. */
373 void AddMultTranspose(const Vector &x, Vector &y,
374 const real_t a = 1.0) const override;
375
376 /** @brief Build and store internally the transpose of this matrix which will
377 be used in the methods AddMultTranspose(), MultTranspose(), and
378 AbsMultTranspose(). */
379 /** If this method has been called, the internal transpose matrix will be
380 used to perform the action of the transpose matrix in AddMultTranspose(),
381 MultTranspose(), and AbsMultTranspose().
382
383 Warning: any changes in this matrix will invalidate the internal
384 transpose. To rebuild the transpose, call ResetTranspose() followed by
385 (optionally) a call to this method. If the internal transpose is already
386 built, this method has no effect.
387
388 When any non-serial-CPU backend is enabled, i.e. the call
389 Device::Allows(~ Backend::CPU_MASK) returns true, the above methods
390 require the internal transpose to be built. If that is not the case (i.e.
391 the internal transpose is not built), these methods will automatically
392 call EnsureMultTranspose(). When using any backend from
393 Backend::CPU_MASK, calling this method is optional.
394
395 This method can only be used when the sparse matrix is finalized.
396
397 @sa EnsureMultTranspose(), ResetTranspose(). */
398 void BuildTranspose() const;
399
400 /** Reset (destroy) the internal transpose matrix. See BuildTranspose() for
401 more details. */
402 void ResetTranspose() const;
403
404 /** @brief Ensures that the matrix is capable of performing MultTranspose(),
405 AddMultTranspose(), and AbsMultTranspose(). */
406 /** For non-serial-CPU backends (e.g. GPU, OpenMP), multiplying by the
407 transpose requires that the internal transpose matrix be already built.
408 When such a backend is enabled, this function will build the internal
409 transpose matrix, see BuildTranspose().
410
411 For the serial CPU backends, the internal transpose is not required, and
412 this function is a no-op. This allows for significant memory savings
413 when the internal transpose matrix is not required. */
414 void EnsureMultTranspose() const;
415
416 void PartMult(const Array<int> &rows, const Vector &x, Vector &y) const;
417 void PartAddMult(const Array<int> &rows, const Vector &x, Vector &y,
418 const real_t a=1.0) const;
419
420 /// y = A * x, treating all entries as booleans (zero=false, nonzero=true).
421 /** The actual values stored in the data array, #A, are not used - this means
422 that all entries in the sparsity pattern are considered to be true by
423 this method. */
424 void BooleanMult(const Array<int> &x, Array<int> &y) const;
425
426 /// y = At * x, treating all entries as booleans (zero=false, nonzero=true).
427 /** The actual values stored in the data array, #A, are not used - this means
428 that all entries in the sparsity pattern are considered to be true by
429 this method. */
430 void BooleanMultTranspose(const Array<int> &x, Array<int> &y) const;
431
432 /// y = |A| * x, using entry-wise absolute values of matrix A
433 void AbsMult(const Vector &x, Vector &y) const override;
434
435 /// y = |At| * x, using entry-wise absolute values of the transpose of matrix A
436 /** If the matrix is modified, call ResetTranspose() and optionally
437 EnsureMultTranspose() to make sure this method uses the correct updated
438 transpose. */
439 void AbsMultTranspose(const Vector &x, Vector &y) const override;
440
441 /// Compute y^t A x
442 real_t InnerProduct(const Vector &x, const Vector &y) const;
443
444 /// For all i compute $ x_i = \sum_j A_{ij} $
445 void GetRowSums(Vector &x) const;
446 /// For i = irow compute $ x_i = \sum_j | A_{i, j} | $
447 real_t GetRowNorml1(int irow) const;
448
449 /// This virtual method is not supported: it always returns NULL.
450 MatrixInverse *Inverse() const override;
451
452 /// Eliminates a column from the transpose matrix.
453 void EliminateRow(int row, const real_t sol, Vector &rhs);
454
455 /// Eliminates a row from the matrix.
456 /*!
457 * - If @a dpolicy = #DIAG_ZERO, all the entries in the row will be set to 0.
458 * - If @a dpolicy = #DIAG_ONE (matrix must be square), the diagonal entry
459 * will be set equal to 1 and all other entries in the row to 0.
460 * - The policy #DIAG_KEEP is not supported.
461 */
462 void EliminateRow(int row, DiagonalPolicy dpolicy = DIAG_ZERO);
463
464 /// Eliminates the column @a col from the matrix.
465 /** - If @a dpolicy = #DIAG_ZERO, all entries in the column will be set to 0.
466 - If @a dpolicy = #DIAG_ONE (matrix must be square), the diagonal entry
467 will be set equal to 1 and all other entries in the column to 0.
468 - The policy #DIAG_KEEP is not supported. */
469 void EliminateCol(int col, DiagonalPolicy dpolicy = DIAG_ZERO);
470
471 /// Eliminate all columns i for which @a cols[i] != 0.
472 /** Elimination of a column means that all entries in the column are set to
473 zero. In addition, if the pointers @a x and @a b are not NULL, the
474 eliminated matrix entries are multiplied by the corresponding solution
475 value in @a *x and subtracted from the r.h.s. vector, @a *b. */
476 void EliminateCols(const Array<int> &cols, const Vector *x = NULL,
477 Vector *b = NULL);
478
479 /** @brief Similar to EliminateCols + save the eliminated entries into
480 @a Ae so that (*this) + Ae is equal to the original matrix. */
481 void EliminateCols(const Array<int> &col_marker, SparseMatrix &Ae);
482
483 /// Eliminate row @a rc and column @a rc and modify the @a rhs using @a sol.
484 /** Eliminates the column @a rc to the @a rhs, deletes the row @a rc and
485 replaces the element (rc,rc) with 1.0; assumes that element (i,rc)
486 is assembled if and only if the element (rc,i) is assembled.
487 By default, elements (rc,rc) are set to 1.0, although this behavior
488 can be adjusted by changing the @a dpolicy parameter. */
489 void EliminateRowCol(int rc, const real_t sol, Vector &rhs,
490 DiagonalPolicy dpolicy = DIAG_ONE);
491
492 /** @brief Similar to
493 EliminateRowCol(int, const double, Vector &, DiagonalPolicy), but
494 multiple values for eliminated unknowns are accepted, and accordingly
495 multiple right-hand-sides are used. */
496 void EliminateRowColMultipleRHS(int rc, const Vector &sol,
497 DenseMatrix &rhs,
498 DiagonalPolicy dpolicy = DIAG_ONE);
499
500 /// Perform elimination and set the diagonal entry to the given value
501 void EliminateRowColDiag(int rc, real_t value);
502
503 /// Eliminate row @a rc and column @a rc.
504 void EliminateRowCol(int rc, DiagonalPolicy dpolicy = DIAG_ONE);
505
506 /** @brief Similar to EliminateRowCol(int, DiagonalPolicy) + save the
507 eliminated entries into @a Ae so that (*this) + Ae is equal to the
508 original matrix */
509 void EliminateRowCol(int rc, SparseMatrix &Ae,
510 DiagonalPolicy dpolicy = DIAG_ONE);
511
512 /** @brief Eliminate essential (Dirichlet) boundary conditions.
513
514 @param[in] ess_dofs indices of the degrees of freedom belonging to the
515 essential boundary conditions.
516 @param[in] diag_policy policy for diagonal entries. */
517 void EliminateBC(const Array<int> &ess_dofs,
518 DiagonalPolicy diag_policy);
519
520 /// If a row contains only one diag entry of zero, set it to 1.
521 void SetDiagIdentity();
522 /// If a row contains only zeros, set its diagonal to 1.
523 void EliminateZeroRows(const real_t threshold = 1e-12) override;
524
525 /// Gauss-Seidel forward and backward iterations over a vector x.
526 void Gauss_Seidel_forw(const Vector &x, Vector &y) const;
527 void Gauss_Seidel_back(const Vector &x, Vector &y) const;
528
529 /// Determine appropriate scaling for Jacobi iteration
530 real_t GetJacobiScaling() const;
531 /** One scaled Jacobi iteration for the system A x = b.
532 x1 = x0 + sc D^{-1} (b - A x0) where D is the diag of A.
533 Absolute values of D are used when use_abs_diag = true. */
534 void Jacobi(const Vector &b, const Vector &x0, Vector &x1,
535 real_t sc, bool use_abs_diag = false) const;
536
537 /// x = sc b / A_ii. When use_abs_diag = true, |A_ii| is used.
538 void DiagScale(const Vector &b, Vector &x,
539 real_t sc = 1.0, bool use_abs_diag = false) const;
540
541 /** x1 = x0 + sc D^{-1} (b - A x0) where $ D_{ii} = \sum_j |A_{ij}| $. */
542 void Jacobi2(const Vector &b, const Vector &x0, Vector &x1,
543 real_t sc = 1.0) const;
544
545 /** x1 = x0 + sc D^{-1} (b - A x0) where $ D_{ii} = \sum_j A_{ij} $. */
546 void Jacobi3(const Vector &b, const Vector &x0, Vector &x1,
547 real_t sc = 1.0) const;
548
549 /** @brief Finalize the matrix initialization, switching the storage format
550 from LIL to CSR. */
551 /** This method should be called once, after the matrix has been initialized.
552 Internally, this method converts the matrix from row-wise linked list
553 (LIL) format into CSR (compressed sparse row) format. */
554 void Finalize(int skip_zeros = 1) override { Finalize(skip_zeros, false); }
555
556 /// A slightly more general version of the Finalize(int) method.
557 void Finalize(int skip_zeros, bool fix_empty_rows);
558
559 /// Returns whether or not CSR format has been finalized.
560 bool Finalized() const { return !A.Empty(); }
561 /// Returns whether or not the columns are sorted.
562 bool ColumnsAreSorted() const { return isSorted; }
563
564 /** @brief Remove entries smaller in absolute value than a given tolerance
565 @a tol. If @a fix_empty_rows is true, a zero value is inserted in the
566 diagonal entry (for square matrices only) */
567 void Threshold(real_t tol, bool fix_empty_rows = false);
568
569 /** Split the matrix into M x N blocks of sparse matrices in CSR format.
570 The 'blocks' array is M x N (i.e. M and N are determined by its
571 dimensions) and its entries are overwritten by the new blocks. */
572 void GetBlocks(Array2D<SparseMatrix *> &blocks) const;
573
574 void GetSubMatrix(const Array<int> &rows, const Array<int> &cols,
575 DenseMatrix &subm) const;
576
577 /** @brief Initialize the SparseMatrix for fast access to the entries of the
578 given @a row which becomes the "current row". */
579 /** Fast access to the entries of the "current row" can be performed using
580 the methods: SearchRow(const int), _Add_(const int, const double),
581 _Set_(const int, const double), and _Get_(const int). */
582 inline void SetColPtr(const int row) const;
583 /** @brief Reset the "current row" set by calling SetColPtr(). This method
584 must be called between any two calls to SetColPtr(). */
585 inline void ClearColPtr() const;
586 /// Perform a fast search for an entry in the "current row". See SetColPtr().
587 /** If the matrix is not finalized and the entry is not found in the
588 SparseMatrix, it will be added to the sparsity pattern initialized with
589 zero. If the matrix is finalized and the entry is not found, an error
590 will be generated. */
591 inline real_t &SearchRow(const int col);
592 /// Add a value to an entry in the "current row". See SetColPtr().
593 inline void _Add_(const int col, const real_t a)
594 { SearchRow(col) += a; }
595 /// Set an entry in the "current row". See SetColPtr().
596 inline void _Set_(const int col, const real_t a)
597 { SearchRow(col) = a; }
598 /// Read the value of an entry in the "current row". See SetColPtr().
599 inline real_t _Get_(const int col) const;
600
601 inline real_t &SearchRow(const int row, const int col);
602 inline void _Add_(const int row, const int col, const real_t a)
603 { SearchRow(row, col) += a; }
604 inline void _Set_(const int row, const int col, const real_t a)
605 { SearchRow(row, col) = a; }
606
607 void Set(const int i, const int j, const real_t val);
608 void Add(const int i, const int j, const real_t val);
609
610 void SetSubMatrix(const Array<int> &rows, const Array<int> &cols,
611 const DenseMatrix &subm, int skip_zeros = 1);
612
613 void SetSubMatrixTranspose(const Array<int> &rows, const Array<int> &cols,
614 const DenseMatrix &subm, int skip_zeros = 1);
615
616 /** Insert the DenseMatrix into this SparseMatrix at the specified rows and
617 columns. If \c skip_zeros==0 , all entries from the DenseMatrix are
618 added including zeros. If \c skip_zeros==2 , no zeros are added to the
619 SparseMatrix regardless of their position in the matrix. Otherwise, the
620 default \c skip_zeros behavior is to omit the zero from the SparseMatrix
621 unless it would break the symmetric structure of the SparseMatrix. */
622 void AddSubMatrix(const Array<int> &rows, const Array<int> &cols,
623 const DenseMatrix &subm, int skip_zeros = 1);
624
625 bool RowIsEmpty(const int row) const;
626
627 /// Extract all column indices and values from a given row.
628 /** If the matrix is finalized (i.e. in CSR format), @a cols and @a srow will
629 simply be references to the specific portion of the #J and #A arrays.
630 As required by the AbstractSparseMatrix interface this method returns:
631 - 0, if @a cols and @a srow are copies of the values in the matrix, i.e.
632 when the matrix is open.
633 - 1, if @a cols and @a srow are views of the values in the matrix, i.e.
634 when the matrix is finalized.
635 @warning This method breaks the const-ness when the matrix is finalized
636 because it gives write access to the #J and #A arrays. */
637 int GetRow(const int row, Array<int> &cols, Vector &srow) const override;
638
639 void SetRow(const int row, const Array<int> &cols, const Vector &srow);
640 void AddRow(const int row, const Array<int> &cols, const Vector &srow);
641
642 void ScaleRow(const int row, const real_t scale);
643 /// this = diag(sl) * this;
644 void ScaleRows(const Vector & sl);
645 /// this = this * diag(sr);
646 void ScaleColumns(const Vector & sr);
647
648 /** @brief Add the sparse matrix 'B' to '*this'. This operation will cause an
649 error if '*this' is finalized and 'B' has larger sparsity pattern. */
651
652 /** @brief Add the sparse matrix 'B' scaled by the scalar 'a' into '*this'.
653 Only entries in the sparsity pattern of '*this' are added. */
654 void Add(const real_t a, const SparseMatrix &B);
655
657
659
660 /// Prints matrix to stream out.
661 /** @note The host in synchronized when the finalized matrix is on the device. */
662 void Print(std::ostream &out = mfem::out, int width_ = 4) const override;
663
664 /// Prints matrix in matlab format.
665 /** @note The host in synchronized when the finalized matrix is on the device. */
666 void PrintMatlab(std::ostream &out = mfem::out) const override;
667
668 /// Prints matrix as a SparseArray for importing into Mathematica.
669 /** The resulting file can be read into Mathematica using an expression such
670 as: myMat = Get["output_file_name"]
671 The Mathematica variable "myMat" will then be assigned to a new
672 SparseArray object containing the data from this MFEM SparseMatrix.
673
674 @note Mathematica uses 1-based indexing so the MFEM row and column
675 indices will be sifted up by one in the Mathematica output.
676
677 @note The host in synchronized when the finalized matrix is on the
678 device. */
679 virtual void PrintMathematica(std::ostream &out = mfem::out) const;
680
681 /// Prints matrix in Matrix Market sparse format.
682 /** @note The host in synchronized when the finalized matrix is on the device. */
683 void PrintMM(std::ostream &out = mfem::out) const;
684
685 /// Prints matrix to stream out in hypre_CSRMatrix format.
686 /** @note The host in synchronized when the finalized matrix is on the device. */
687 void PrintCSR(std::ostream &out) const;
688
689 /// Prints a sparse matrix to stream out in CSR format.
690 /** @note The host in synchronized when the finalized matrix is on the device. */
691 void PrintCSR2(std::ostream &out) const;
692
693 /// Print various sparse matrix statistics.
694 void PrintInfo(std::ostream &out) const;
695
696 /// Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix
697 real_t IsSymmetric() const;
698
699 /// (*this) = 1/2 ((*this) + (*this)^t)
700 void Symmetrize();
701
702 /// Returns the number of the nonzero elements in the matrix
703 int NumNonZeroElems() const override;
704
705 real_t MaxNorm() const;
706
707 /// Count the number of entries with |a_ij| <= tol.
708 int CountSmallElems(real_t tol) const;
709
710 /// Count the number of entries that are NOT finite, i.e. Inf or Nan.
711 int CheckFinite() const;
712
713 /// Set the graph ownership flag (I and J arrays).
714 void SetGraphOwner(bool ownij)
715 { I.SetHostPtrOwner(ownij); J.SetHostPtrOwner(ownij); }
716
717 /// Set the data ownership flag (A array).
718 void SetDataOwner(bool owna) { A.SetHostPtrOwner(owna); }
719
720 /// Get the graph ownership flag (I and J arrays).
721 bool OwnsGraph() const { return I.OwnsHostPtr() && J.OwnsHostPtr(); }
722
723 /// Get the data ownership flag (A array).
724 bool OwnsData() const { return A.OwnsHostPtr(); }
725
726 /// Lose the ownership of the graph (I, J) and data (A) arrays.
727 void LoseData() { SetGraphOwner(false); SetDataOwner(false); }
728
729 void Swap(SparseMatrix &other);
730
731 /// Destroys sparse matrix.
732 virtual ~SparseMatrix();
733
734 Type GetType() const { return MFEM_SPARSEMAT; }
735};
736
737inline std::ostream& operator<<(std::ostream& os, SparseMatrix const& mat)
738{
739 mat.Print(os);
740 return os;
741}
742
743/// Applies f() to each element of the matrix (after it is finalized).
744void SparseMatrixFunction(SparseMatrix &S, real_t (*f)(real_t));
745
746
747/// Transpose of a sparse matrix. A must be finalized.
748SparseMatrix *Transpose(const SparseMatrix &A);
749/// Transpose of a sparse matrix. A does not need to be a CSR matrix.
750SparseMatrix *TransposeAbstractSparseMatrix (const AbstractSparseMatrix &A,
751 int useActualWidth);
752
753/// Matrix product A.B.
754/** If @a OAB is not NULL, we assume it has the structure of A.B and store the
755 result in @a OAB. If @a OAB is NULL, we create a new SparseMatrix to store
756 the result and return a pointer to it.
757
758 All matrices must be finalized. */
759SparseMatrix *Mult(const SparseMatrix &A, const SparseMatrix &B,
760 SparseMatrix *OAB = NULL);
761
762/// C = A^T B
763SparseMatrix *TransposeMult(const SparseMatrix &A, const SparseMatrix &B);
764
765/// Matrix product of sparse matrices. A and B do not need to be CSR matrices
766SparseMatrix *MultAbstractSparseMatrix (const AbstractSparseMatrix &A,
767 const AbstractSparseMatrix &B);
768
769/// Matrix product A.B
770DenseMatrix *Mult(const SparseMatrix &A, DenseMatrix &B);
771
772/// RAP matrix product (with R=P^T)
773DenseMatrix *RAP(const SparseMatrix &A, DenseMatrix &P);
774
775/// RAP matrix product (with R=P^T)
776DenseMatrix *RAP(DenseMatrix &A, const SparseMatrix &P);
777
778/** RAP matrix product (with P=R^T). ORAP is like OAB above.
779 All matrices must be finalized. */
780SparseMatrix *RAP(const SparseMatrix &A, const SparseMatrix &R,
781 SparseMatrix *ORAP = NULL);
782
783/// General RAP with given R^T, A and P
784SparseMatrix *RAP(const SparseMatrix &Rt, const SparseMatrix &A,
785 const SparseMatrix &P);
786
787/// Matrix multiplication A^t D A. All matrices must be finalized.
788SparseMatrix *Mult_AtDA(const SparseMatrix &A, const Vector &D,
789 SparseMatrix *OAtDA = NULL);
790
791
792/// Matrix addition result = A + B.
793SparseMatrix * Add(const SparseMatrix & A, const SparseMatrix & B);
794/// Matrix addition result = a*A + b*B
795SparseMatrix * Add(real_t a, const SparseMatrix & A, real_t b,
796 const SparseMatrix & B);
797/// Matrix addition result = sum_i A_i
798SparseMatrix * Add(Array<SparseMatrix *> & Ai);
799
800/// B += alpha * A
801void Add(const SparseMatrix &A, real_t alpha, DenseMatrix &B);
802
803/// Produces a block matrix with blocks A_{ij}*B
804DenseMatrix *OuterProduct(const DenseMatrix &A, const DenseMatrix &B);
805
806/// Produces a block matrix with blocks A_{ij}*B
807SparseMatrix *OuterProduct(const DenseMatrix &A, const SparseMatrix &B);
808
809/// Produces a block matrix with blocks A_{ij}*B
810SparseMatrix *OuterProduct(const SparseMatrix &A, const DenseMatrix &B);
811
812/// Produces a block matrix with blocks A_{ij}*B
813SparseMatrix *OuterProduct(const SparseMatrix &A, const SparseMatrix &B);
814
815
816// Inline methods
817
818inline void SparseMatrix::SetColPtr(const int row) const
819{
820 if (Rows)
821 {
822 if (ColPtrNode == NULL)
823 {
824 ColPtrNode = new RowNode *[width];
825 for (int i = 0; i < width; i++)
826 {
827 ColPtrNode[i] = NULL;
828 }
829 }
830 for (RowNode *node_p = Rows[row]; node_p != NULL; node_p = node_p->Prev)
831 {
832 ColPtrNode[node_p->Column] = node_p;
833 }
834 }
835 else
836 {
837 if (ColPtrJ == NULL)
838 {
839 ColPtrJ = new int[width];
840 for (int i = 0; i < width; i++)
841 {
842 ColPtrJ[i] = -1;
843 }
844 }
845 for (int j = I[row], end = I[row+1]; j < end; j++)
846 {
847 ColPtrJ[J[j]] = j;
848 }
849 }
850 current_row = row;
851}
852
853inline void SparseMatrix::ClearColPtr() const
854{
855 if (Rows)
856 {
857 for (RowNode *node_p = Rows[current_row]; node_p != NULL;
858 node_p = node_p->Prev)
859 {
860 ColPtrNode[node_p->Column] = NULL;
861 }
862 }
863 else
864 {
865 for (int j = I[current_row], end = I[current_row+1]; j < end; j++)
866 {
867 ColPtrJ[J[j]] = -1;
868 }
869 }
870}
871
872inline real_t &SparseMatrix::SearchRow(const int col)
873{
874 if (Rows)
875 {
876 RowNode *node_p = ColPtrNode[col];
877 if (node_p == NULL)
878 {
879#ifdef MFEM_USE_MEMALLOC
880 node_p = NodesMem->Alloc();
881#else
882 node_p = new RowNode;
883#endif
884 node_p->Prev = Rows[current_row];
885 node_p->Column = col;
886 node_p->Value = 0.0;
887 Rows[current_row] = ColPtrNode[col] = node_p;
888 }
889 return node_p->Value;
890 }
891 else
892 {
893 const int j = ColPtrJ[col];
894 MFEM_VERIFY(j != -1, "Entry for column " << col << " is not allocated.");
895 return A[j];
896 }
897}
898
899inline real_t SparseMatrix::_Get_(const int col) const
900{
901 if (Rows)
902 {
903 RowNode *node_p = ColPtrNode[col];
904 return (node_p == NULL) ? 0.0 : node_p->Value;
905 }
906 else
907 {
908 const int j = ColPtrJ[col];
909 return (j == -1) ? 0.0 : A[j];
910 }
911}
912
913inline real_t &SparseMatrix::SearchRow(const int row, const int col)
914{
915 if (Rows)
916 {
917 RowNode *node_p;
918
919 for (node_p = Rows[row]; 1; node_p = node_p->Prev)
920 {
921 if (node_p == NULL)
922 {
923#ifdef MFEM_USE_MEMALLOC
924 node_p = NodesMem->Alloc();
925#else
926 node_p = new RowNode;
927#endif
928 node_p->Prev = Rows[row];
929 node_p->Column = col;
930 node_p->Value = 0.0;
931 Rows[row] = node_p;
932 break;
933 }
934 else if (node_p->Column == col)
935 {
936 break;
937 }
938 }
939 return node_p->Value;
940 }
941 else
942 {
943 int *Ip = I+row, *Jp = J;
944 for (int k = Ip[0], end = Ip[1]; k < end; k++)
945 {
946 if (Jp[k] == col)
947 {
948 return A[k];
949 }
950 }
951 MFEM_ABORT("Could not find entry for row = " << row << ", col = " << col);
952 }
953 return A[0];
954}
955
956/// Specialization of the template function Swap<> for class SparseMatrix
958{
959 a.Swap(b);
960}
961
962} // namespace mfem
963
964#endif
Abstract data type for sparse matrices.
Definition matrix.hpp:74
Dynamic 2D array using row-major layout.
Definition array.hpp:430
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
static MemoryClass GetHostMemoryClass()
Get the current Host MemoryClass. This is the MemoryClass used by most MFEM host Memory objects.
Definition device.hpp:272
static MemoryClass GetDeviceMemoryClass()
Get the current Device MemoryClass. This is the MemoryClass used by most MFEM device kernels to acces...
Definition device.hpp:285
Abstract data type for matrix inverse.
Definition matrix.hpp:63
Class used by MFEM to store pointers to host and/or device memory.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
int Capacity() const
Return the size of the allocated memory.
void Swap(Memory &other)
Swap without using move assignment, avoiding Reset() calls.
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
bool Empty() const
Return true if the Memory object is empty, see Reset().
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:28
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:66
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
Definition operator.hpp:48
@ DIAG_ONE
Set the diagonal value to one.
Definition operator.hpp:50
@ DIAG_ZERO
Set the diagonal value to zero.
Definition operator.hpp:49
Type
Enumeration defining IDs for some classes derived from Operator.
Definition operator.hpp:296
@ MFEM_SPARSEMAT
ID for class SparseMatrix.
Definition operator.hpp:298
RowNode * Prev
Definition sparsemat.hpp:45
Data type sparse matrix.
Definition sparsemat.hpp:51
int GetRow(const int row, Array< int > &cols, Vector &srow) const override
Extract all column indices and values from a given row.
void PrintCSR2(std::ostream &out) const
Prints a sparse matrix to stream out in CSR format.
real_t MaxNorm() const
const int * HostReadJ() const
void GetDiag(Vector &d) const
Returns the Diagonal of A.
int * ReadWriteI(bool on_dev=true)
real_t GetRowNorml1(int irow) const
For i = irow compute .
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
bool isSorted
Are the columns sorted already.
Definition sparsemat.hpp:88
RowNodeAlloc * NodesMem
Definition sparsemat.hpp:84
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
void Gauss_Seidel_back(const Vector &x, Vector &y) const
bool RowIsEmpty(const int row) const
void ClearColPtr() const
Reset the "current row" set by calling SetColPtr(). This method must be called between any two calls ...
MatrixInverse * Inverse() const override
This virtual method is not supported: it always returns NULL.
void Jacobi3(const Vector &b, const Vector &x0, Vector &x1, real_t sc=1.0) const
real_t * ReadWriteData(bool on_dev=true)
Memory< real_t > A
Array with size I[height], containing the actual entries of the sparse matrix, as indexed by the I ar...
Definition sparsemat.hpp:68
void EliminateRowCol(int rc, const real_t sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
void SetDataOwner(bool owna)
Set the data ownership flag (A array).
SparseMatrix & operator*=(real_t a)
void MultTranspose(const Vector &x, Vector &y) const override
Multiply a vector with the transposed matrix. y = At * x.
hipsparseDnVecDescr_t vecY_descr
void SetWidth(int width_=-1)
Change the width of a SparseMatrix.
MemAlloc< RowNode, 1024 > RowNodeAlloc
Definition sparsemat.hpp:83
bool Empty() const
Check if the SparseMatrix is empty.
static hipsparseHandle_t handle
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
SparseMatrix * At
Transpose of A. Owned. Used to perform MultTranspose() on devices.
Definition sparsemat.hpp:80
void PartAddMult(const Array< int > &rows, const Vector &x, Vector &y, const real_t a=1.0) const
const int * GetJ() const
Return the array J, const version.
void GetRowSums(Vector &x) const
For all i compute .
void AbsMult(const Vector &x, Vector &y) const override
y = |A| * x, using entry-wise absolute values of matrix A
int NumNonZeroElems() const override
Returns the number of the nonzero elements in the matrix.
cusparseMatDescr_t descr
bool Finalized() const
Returns whether or not CSR format has been finalized.
Type GetType() const
void EliminateBC(const Array< int > &ess_dofs, DiagonalPolicy diag_policy)
Eliminate essential (Dirichlet) boundary conditions.
void PrintInfo(std::ostream &out) const
Print various sparse matrix statistics.
void MoveDiagonalFirst()
Move the diagonal entry to the first position in each row, preserving the order of the rest of the co...
void Add(const int i, const int j, const real_t val)
void EliminateRowColMultipleRHS(int rc, const Vector &sol, DenseMatrix &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Similar to EliminateRowCol(int, const double, Vector &, DiagonalPolicy), but multiple values for elim...
void Jacobi(const Vector &b, const Vector &x0, Vector &x1, real_t sc, bool use_abs_diag=false) const
void SetColPtr(const int row) const
Initialize the SparseMatrix for fast access to the entries of the given row which becomes the "curren...
void SetDiagIdentity()
If a row contains only one diag entry of zero, set it to 1.
MFEM_DEPRECATED void UseCuSparse(bool useCuSparse_=true)
Deprecated equivalent of UseGPUSparse().
const Memory< int > & GetMemoryJ() const
void Gauss_Seidel_forw(const Vector &x, Vector &y) const
Gauss-Seidel forward and backward iterations over a vector x.
void MakeRef(const SparseMatrix &master)
Clear the contents of the SparseMatrix and make it a reference to master.
int CheckFinite() const
Count the number of entries that are NOT finite, i.e. Inf or Nan.
void UseGPUSparse(bool useGPUSparse_=true)
Runtime option to use cuSPARSE or hipSPARSE. Only valid when using a CUDA or HIP backend.
int * WriteJ(bool on_dev=true)
Memory< int > J
Array with size I[height], containing the column indices for all matrix entries, as indexed by the I ...
Definition sparsemat.hpp:65
cusparseMatDescr_t matA_descr
void EliminateCol(int col, DiagonalPolicy dpolicy=DIAG_ZERO)
Eliminates the column col from the matrix.
void LoseData()
Lose the ownership of the graph (I, J) and data (A) arrays.
void EnsureMultTranspose() const
Ensures that the matrix is capable of performing MultTranspose(), AddMultTranspose(),...
void Print(std::ostream &out=mfem::out, int width_=4) const override
Prints matrix to stream out.
void _Add_(const int col, const real_t a)
Add a value to an entry in the "current row". See SetColPtr().
SparseMatrix()
Create an empty SparseMatrix.
cusparseSpMatDescr_t matA_descr
real_t & Elem(int i, int j) override
Returns reference to a_{ij}.
virtual void PrintMathematica(std::ostream &out=mfem::out) const
Prints matrix as a SparseArray for importing into Mathematica.
void ClearGPUSparse()
Clear the cuSPARSE/hipSPARSE descriptors. This must be called after releasing the device memory of A.
Definition sparsemat.cpp:89
void Threshold(real_t tol, bool fix_empty_rows=false)
Remove entries smaller in absolute value than a given tolerance tol. If fix_empty_rows is true,...
Memory< int > & GetMemoryI()
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void PrintMatlab(std::ostream &out=mfem::out) const override
Prints matrix in matlab format.
const int * ReadI(bool on_dev=true) const
real_t InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
Memory< int > I
Array with size (height+1) containing the row offsets.
Definition sparsemat.hpp:62
real_t & operator()(int i, int j)
Returns reference to A[i][j].
const real_t * HostReadData() const
void PrintMM(std::ostream &out=mfem::out) const
Prints matrix in Matrix Market sparse format.
void ScaleColumns(const Vector &sr)
this = this * diag(sr);
void _Add_(const int row, const int col, const real_t a)
void PrintCSR(std::ostream &out) const
Prints matrix to stream out in hypre_CSRMatrix format.
void Swap(SparseMatrix &other)
MFEM_DEPRECATED void ClearCuSparse()
Deprecated equivalent of ClearGPUSparse().
const Memory< real_t > & GetMemoryData() const
int * ReadWriteJ(bool on_dev=true)
cusparseDnVecDescr_t vecY_descr
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
RowNode ** Rows
Array of linked lists, one for every row. This array represents the linked list (LIL) storage format.
Definition sparsemat.hpp:73
void SetGraphOwner(bool ownij)
Set the graph ownership flag (I and J arrays).
real_t & SearchRow(const int col)
Perform a fast search for an entry in the "current row". See SetColPtr().
int * WriteI(bool on_dev=true)
const Memory< int > & GetMemoryI() const
static int SparseMatrixCount
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void _Set_(const int row, const int col, const real_t a)
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
void AddMultTranspose(const Vector &x, Vector &y, const real_t a=1.0) const override
y += At * x (default) or y += a * At * x
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
real_t GetJacobiScaling() const
Determine appropriate scaling for Jacobi iteration.
RowNode ** ColPtrNode
Definition sparsemat.hpp:77
int RowSize(const int i) const
Returns the number of elements in row i.
real_t * HostReadWriteData()
int CountSmallElems(real_t tol) const
Count the number of entries with |a_ij| <= tol.
const int * ReadJ(bool on_dev=true) const
int MaxRowSize() const
Returns the maximum number of elements among all rows.
real_t _Get_(const int col) const
Read the value of an entry in the "current row". See SetColPtr().
void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const override
y += A * x (default) or y += a * A * x
virtual ~SparseMatrix()
Destroys sparse matrix.
SparseMatrix & operator=(const SparseMatrix &rhs)
Assignment operator: deep copy.
void Mult(const Vector &x, Vector &y) const override
Matrix vector multiplication.
const real_t * GetData() const
Return the element data, i.e. the array A, const version.
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
real_t * HostWriteData()
cusparseStatus_t status
static cusparseHandle_t handle
void EliminateRow(int row, const real_t sol, Vector &rhs)
Eliminates a column from the transpose matrix.
bool OwnsGraph() const
Get the graph ownership flag (I and J arrays).
hipsparseSpMatDescr_t matA_descr
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
SparseMatrix & operator+=(const SparseMatrix &B)
Add the sparse matrix 'B' to '*this'. This operation will cause an error if '*this' is finalized and ...
hipsparseStatus_t status
void Clear()
Clear the contents of the SparseMatrix.
void ResetTranspose() const
void EliminateRowColDiag(int rc, real_t value)
Perform elimination and set the diagonal entry to the given value.
real_t * GetRowEntries(const int row)
Return a pointer to the entries in a row.
void ScaleRows(const Vector &sl)
this = diag(sl) * this;
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
bool OwnsData() const
Get the data ownership flag (A array).
const int * GetI() const
Return the array I, const version.
void DiagScale(const Vector &b, Vector &x, real_t sc=1.0, bool use_abs_diag=false) const
x = sc b / A_ii. When use_abs_diag = true, |A_ii| is used.
void AbsMultTranspose(const Vector &x, Vector &y) const override
y = |At| * x, using entry-wise absolute values of the transpose of matrix A
real_t * GetData()
Return the element data, i.e. the array A.
void SetSubMatrixTranspose(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void BuildTranspose() const
Build and store internally the transpose of this matrix which will be used in the methods AddMultTran...
MemoryClass GetMemoryClass() const override
Return the MemoryClass preferred by the Operator.
void SortColumnIndices()
Sort the column indices corresponding to each row.
void Finalize(int skip_zeros=1) override
Finalize the matrix initialization, switching the storage format from LIL to CSR.
real_t IsSymmetric() const
Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix.
DenseMatrix * ToDenseMatrix() const
Produces a DenseMatrix from a SparseMatrix.
void _Set_(const int col, const real_t a)
Set an entry in the "current row". See SetColPtr().
void EliminateZeroRows(const real_t threshold=1e-12) override
If a row contains only zeros, set its diagonal to 1.
void EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
int * GetJ()
Return the array J.
Memory< int > & GetMemoryJ()
Memory< real_t > & GetMemoryData()
cusparseDnVecDescr_t vecX_descr
const real_t * ReadData(bool on_dev=true) const
void ScaleRow(const int row, const real_t scale)
real_t * WriteData(bool on_dev=true)
hipsparseDnVecDescr_t vecX_descr
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
void Jacobi2(const Vector &b, const Vector &x0, Vector &x1, real_t sc=1.0) const
int * GetI()
Return the array I.
static void * dBuffer
int ActualWidth() const
Returns the actual Width of the matrix.
const int * HostReadI() const
void Set(const int i, const int j, const real_t val)
int Size() const
For backward compatibility, define Size() to be synonym of Height().
Vector data type.
Definition vector.hpp:82
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
std::ostream & operator<<(std::ostream &os, SparseMatrix const &mat)
DenseMatrix * OuterProduct(const DenseMatrix &A, const DenseMatrix &B)
Produces a block matrix with blocks A_{ij}*B.
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:348
void Swap< SparseMatrix >(SparseMatrix &a, SparseMatrix &b)
Specialization of the template function Swap<> for class SparseMatrix.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:505
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
Definition device.hpp:365
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
Definition table.cpp:443
MemoryClass
Memory classes identify sets of memory types.
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
Definition device.hpp:382
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
SparseMatrix * MultAbstractSparseMatrix(const AbstractSparseMatrix &A, const AbstractSparseMatrix &B)
Matrix product of sparse matrices. A and B do not need to be CSR matrices.
SparseMatrix * TransposeAbstractSparseMatrix(const AbstractSparseMatrix &A, int useActualWidth)
Transpose of a sparse matrix. A does not need to be a CSR matrix.
SparseMatrix * Mult_AtDA(const SparseMatrix &A, const Vector &D, SparseMatrix *OAtDA)
Matrix multiplication A^t D A. All matrices must be finalized.
float real_t
Definition config.hpp:46
MemoryType
Memory types supported by MFEM.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
void SparseMatrixFunction(SparseMatrix &S, real_t(*f)(real_t))
Applies f() to each element of the matrix (after it is finalized).