deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
petsc_sparse_matrix.cc
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2004 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
14
15#ifdef DEAL_II_WITH_PETSC
16
22
23
24#endif // DEAL_II_WITH_PETSC
25
27
28#ifdef DEAL_II_WITH_PETSC
29
30namespace PETScWrappers
31{
33 {
34 const int m = 0, n = 0, n_nonzero_per_row = 0;
35 const PetscErrorCode ierr = MatCreateSeqAIJ(
36 PETSC_COMM_SELF, m, n, n_nonzero_per_row, nullptr, &matrix);
37 AssertThrow(ierr == 0, ExcPETScError(ierr));
38 }
39
41 : MatrixBase(A)
42 {}
43
45 const size_type n,
46 const size_type n_nonzero_per_row,
47 const bool is_symmetric)
48 {
49 do_reinit(m, n, n_nonzero_per_row, is_symmetric);
50 }
51
52
53
55 const size_type n,
56 const std::vector<size_type> &row_lengths,
57 const bool is_symmetric)
58 {
59 do_reinit(m, n, row_lengths, is_symmetric);
60 }
61
62
63
64 template <typename SparsityPatternType>
65 SparseMatrix::SparseMatrix(const SparsityPatternType &sparsity_pattern,
66 const bool preset_nonzero_locations)
67 {
68 do_reinit(sparsity_pattern, preset_nonzero_locations);
69 }
70
71
72
75 {
77 return *this;
78 }
79
80
81
82 void
84 const size_type n,
85 const size_type n_nonzero_per_row,
86 const bool is_symmetric)
87 {
88 // get rid of old matrix and generate a
89 // new one
90 const PetscErrorCode ierr = MatDestroy(&matrix);
91 AssertThrow(ierr == 0, ExcPETScError(ierr));
92
93 do_reinit(m, n, n_nonzero_per_row, is_symmetric);
94 }
95
96
97
98 void
100 const size_type n,
101 const std::vector<size_type> &row_lengths,
102 const bool is_symmetric)
103 {
104 // get rid of old matrix and generate a
105 // new one
106 const PetscErrorCode ierr = MatDestroy(&matrix);
107 AssertThrow(ierr == 0, ExcPETScError(ierr));
108
109 do_reinit(m, n, row_lengths, is_symmetric);
110 }
111
112
113
114 template <typename SparsityPatternType>
115 void
116 SparseMatrix::reinit(const SparsityPatternType &sparsity_pattern,
117 const bool preset_nonzero_locations)
118 {
119 // get rid of old matrix and generate a
120 // new one
121 const PetscErrorCode ierr = MatDestroy(&matrix);
122 AssertThrow(ierr == 0, ExcPETScError(ierr));
123
124 do_reinit(sparsity_pattern, preset_nonzero_locations);
125 }
126
127
128
129 void
131 const size_type n,
132 const size_type n_nonzero_per_row,
133 const bool is_symmetric)
134 {
135 // use the call sequence indicating only
136 // a maximal number of elements per row
137 // for all rows globally
138 const PetscErrorCode ierr = MatCreateSeqAIJ(
139 PETSC_COMM_SELF, m, n, n_nonzero_per_row, nullptr, &matrix);
140 AssertThrow(ierr == 0, ExcPETScError(ierr));
141
142 // set symmetric flag, if so requested
143 if (is_symmetric == true)
144 {
145 set_matrix_option(matrix, MAT_SYMMETRIC, PETSC_TRUE);
146 }
147 }
148
149
150
151 void
153 const size_type n,
154 const std::vector<size_type> &row_lengths,
155 const bool is_symmetric)
156 {
157 AssertDimension(row_lengths.size(), m);
158
159 for (const auto &row_length : row_lengths)
160 AssertThrowIntegerConversion(static_cast<PetscInt>(row_length),
161 row_length);
162 const std::vector<PetscInt> int_row_lengths(row_lengths.begin(),
163 row_lengths.end());
164
165 const PetscErrorCode ierr = MatCreateSeqAIJ(
166 PETSC_COMM_SELF, m, n, 0, int_row_lengths.data(), &matrix);
167 AssertThrow(ierr == 0, ExcPETScError(ierr));
168
169 // set symmetric flag, if so requested
170 if (is_symmetric == true)
171 {
172 set_matrix_option(matrix, MAT_SYMMETRIC, PETSC_TRUE);
173 }
174 }
175
176
177
178 template <typename SparsityPatternType>
179 void
180 SparseMatrix::do_reinit(const SparsityPatternType &sparsity_pattern,
181 const bool preset_nonzero_locations)
182 {
183 // If the sparsity pattern's dimensions can be converted to PetscInts then
184 // the rest of the conversions will succeed
185 AssertIntegerConversion(static_cast<PetscInt>(sparsity_pattern.n_rows()),
186 sparsity_pattern.n_rows());
187 AssertIntegerConversion(static_cast<PetscInt>(sparsity_pattern.n_cols()),
188 sparsity_pattern.n_cols());
189
190 std::vector<size_type> row_lengths(sparsity_pattern.n_rows());
191 for (size_type i = 0; i < sparsity_pattern.n_rows(); ++i)
192 row_lengths[i] = sparsity_pattern.row_length(i);
193
194 do_reinit(sparsity_pattern.n_rows(),
195 sparsity_pattern.n_cols(),
196 row_lengths,
197 false);
198
199 // next preset the exact given matrix
200 // entries with zeros, if the user
201 // requested so. this doesn't avoid any
202 // memory allocations, but it at least
203 // avoids some searches later on. the
204 // key here is that we can use the
205 // matrix set routines that set an
206 // entire row at once, not a single
207 // entry at a time
208 //
209 // for the usefulness of this option
210 // read the documentation of this
211 // class.
212 if (preset_nonzero_locations == true)
213 {
214 std::vector<PetscInt> row_entries;
215 std::vector<PetscScalar> row_values;
216 for (size_type i = 0; i < sparsity_pattern.n_rows(); ++i)
217 {
218 row_entries.resize(row_lengths[i]);
219 row_values.resize(row_lengths[i]);
220 for (size_type j = 0; j < row_lengths[i]; ++j)
221 {
222 const auto petsc_j =
223 static_cast<PetscInt>(sparsity_pattern.column_number(i, j));
224 row_entries[j] = petsc_j;
225 }
226
227 const auto petsc_i = static_cast<PetscInt>(i);
228 const PetscErrorCode ierr = MatSetValues(matrix,
229 1,
230 &petsc_i,
231 row_lengths[i],
232 row_entries.data(),
233 row_values.data(),
234 INSERT_VALUES);
235 AssertThrow(ierr == 0, ExcPETScError(ierr));
236 }
238
241 }
242 }
243
244 size_t
246 {
247 PetscInt m, n;
248 const PetscErrorCode ierr = MatGetSize(matrix, &m, &n);
249 AssertThrow(ierr == 0, ExcPETScError(ierr));
250
251 return m;
252 }
253
254 size_t
256 {
257 PetscInt m, n;
258 const PetscErrorCode ierr = MatGetSize(matrix, &m, &n);
259 AssertThrow(ierr == 0, ExcPETScError(ierr));
260
261 return n;
262 }
263
264 void
266 const SparseMatrix &B,
267 const MPI::Vector &V) const
268 {
269 // Simply forward to the protected member function of the base class
270 // that takes abstract matrix and vector arguments (to which the compiler
271 // automatically casts the arguments).
272 MatrixBase::mmult(C, B, V);
273 }
274
275 void
277 const SparseMatrix &B,
278 const MPI::Vector &V) const
279 {
280 // Simply forward to the protected member function of the base class
281 // that takes abstract matrix and vector arguments (to which the compiler
282 // automatically casts the arguments).
283 MatrixBase::Tmmult(C, B, V);
284 }
285
286# ifndef DOXYGEN
287 // Explicit instantiations
288 //
289 template SparseMatrix::SparseMatrix(const SparsityPattern &, const bool);
291 const bool);
292
293 template void
294 SparseMatrix::reinit(const SparsityPattern &, const bool);
295 template void
296 SparseMatrix::reinit(const DynamicSparsityPattern &, const bool);
297
298 template void
299 SparseMatrix::do_reinit(const SparsityPattern &, const bool);
300 template void
302# endif
303} // namespace PETScWrappers
304
305
306
307#endif // DEAL_II_WITH_PETSC
size_type row_length(const size_type row) const
void mmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
PetscBool is_symmetric(const double tolerance=1.e-12)
MatrixBase & operator=(const MatrixBase &)=delete
void Tmmult(MatrixBase &C, const MatrixBase &B, const VectorBase &V) const
void compress(const VectorOperation::values operation)
void mmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
void do_reinit(const size_type m, const size_type n, const size_type n_nonzero_per_row, const bool is_symmetric=false)
void Tmmult(SparseMatrix &C, const SparseMatrix &B, const MPI::Vector &V=MPI::Vector()) const
void reinit(const size_type m, const size_type n, const size_type n_nonzero_per_row, const bool is_symmetric=false)
SparseMatrix & operator=(const double d)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define AssertIntegerConversion(index1, index2)
#define AssertThrowIntegerConversion(index1, index2)
#define AssertDimension(dim1, dim2)
#define AssertThrow(cond, exc)
void set_keep_zero_rows(Mat &matrix)
void set_matrix_option(Mat &matrix, const MatOption option_name, const PetscBool option_value=PETSC_FALSE)
void close_matrix(Mat &matrix)